1# -------------------------------------------------------------------------------------------- 2# Copyright (c) Microsoft Corporation. All rights reserved. 3# Licensed under the MIT License. See License.txt in the project root for license information. 4# -------------------------------------------------------------------------------------------- 5 6# pylint: disable=line-too-long 7from azure.cli.core.commands import CliCommandType 8from azure.cli.core.util import empty_on_404 9 10from ._client_factory import cf_web_client, cf_plans, cf_webapps 11from ._validators import validate_onedeploy_params 12 13 14def output_slots_in_table(slots): 15 return [{'name': s['name'], 'status': s['state'], 'plan': s['appServicePlan']} for s in slots] 16 17 18def transform_list_location_output(result): 19 return [{'name': x.name} for x in result] 20 21 22def transform_web_output(web): 23 props = ['name', 'state', 'location', 'resourceGroup', 'defaultHostName', 'appServicePlanId', 'ftpPublishingUrl'] 24 result = {k: web[k] for k in web if k in props} 25 # to get width under control, also the plan usually is in the same RG 26 result['appServicePlan'] = result.pop('appServicePlanId').split('/')[-1] 27 return result 28 29 30def transform_web_list_output(webs): 31 return [transform_web_output(w) for w in webs] 32 33 34def ex_handler_factory(creating_plan=False): 35 def _ex_handler(ex): 36 ex = _polish_bad_errors(ex, creating_plan) 37 raise ex 38 return _ex_handler 39 40 41def update_function_ex_handler_factory(): 42 from azure.cli.core.azclierror import ClientRequestError 43 44 def _ex_handler(ex): 45 http_error_response = False 46 if hasattr(ex, 'response'): 47 http_error_response = True 48 ex = _polish_bad_errors(ex, False) 49 # only include if an update was attempted and failed on the backend 50 if http_error_response: 51 try: 52 detail = ('If using \'--plan\', a consumption plan may be unable to migrate ' 53 'to a given premium plan. Please confirm that the premium plan ' 54 'exists in the same resource group and region. Note: Not all ' 55 'functionapp plans support premium instances. If you have verified ' 56 'your resource group and region and are still unable to migrate, ' 57 'please redeploy on a premium functionapp plan.') 58 ex = ClientRequestError(ex.args[0] + '\n\n' + detail) 59 except Exception: # pylint: disable=broad-except 60 pass 61 raise ex 62 return _ex_handler 63 64 65def _polish_bad_errors(ex, creating_plan): 66 import json 67 from knack.util import CLIError 68 try: 69 if 'text/plain' in ex.response.headers['Content-Type']: # HTML Response 70 detail = ex.response.text 71 else: 72 detail = json.loads(ex.response.text)['Message'] 73 if creating_plan: 74 if 'Requested features are not supported in region' in detail: 75 detail = ("Plan with linux worker is not supported in current region. For " + 76 "supported regions, please refer to https://docs.microsoft.com/" 77 "azure/app-service-web/app-service-linux-intro") 78 elif 'Not enough available reserved instance servers to satisfy' in detail: 79 detail = ("Plan with Linux worker can only be created in a group " + 80 "which has never contained a Windows worker, and vice versa. " + 81 "Please use a new resource group. Original error:" + detail) 82 ex = CLIError(detail) 83 except Exception: # pylint: disable=broad-except 84 pass 85 return ex 86 87 88# pylint: disable=too-many-statements 89def load_command_table(self, _): 90 webclient_sdk = CliCommandType( 91 operations_tmpl='azure.mgmt.web.operations#WebSiteManagementClientOperationsMixin.{}', 92 client_factory=cf_web_client 93 ) 94 appservice_plan_sdk = CliCommandType( 95 operations_tmpl='azure.mgmt.web.operations#AppServicePlansOperations.{}', 96 client_factory=cf_plans 97 ) 98 webapp_sdk = CliCommandType( 99 operations_tmpl='azure.mgmt.web.operations#WebAppsOperations.{}', 100 client_factory=cf_webapps 101 ) 102 103 appservice_custom = CliCommandType(operations_tmpl='azure.cli.command_modules.appservice.custom#{}') 104 105 webapp_access_restrictions = CliCommandType(operations_tmpl='azure.cli.command_modules.appservice.access_restrictions#{}') 106 107 appservice_environment = CliCommandType(operations_tmpl='azure.cli.command_modules.appservice.appservice_environment#{}') 108 109 staticsite_sdk = CliCommandType(operations_tmpl='azure.cli.command_modules.appservice.static_sites#{}') 110 111 appservice_domains = CliCommandType(operations_tmpl='azure.cli.command_modules.appservice.appservice_domains#{}') 112 113 logicapp_custom = CliCommandType(operations_tmpl='azure.cli.command_modules.appservice.logicapp.custom#{}') 114 115 with self.command_group('webapp', webapp_sdk) as g: 116 g.custom_command('create', 'create_webapp', exception_handler=ex_handler_factory()) 117 g.custom_command('up', 'webapp_up', exception_handler=ex_handler_factory()) 118 g.custom_command('ssh', 'ssh_webapp', exception_handler=ex_handler_factory(), is_preview=True) 119 g.custom_command('list', 'list_webapp', table_transformer=transform_web_list_output) 120 g.custom_show_command('show', 'show_webapp', table_transformer=transform_web_output) 121 g.custom_command('delete', 'delete_webapp') 122 g.custom_command('stop', 'stop_webapp') 123 g.custom_command('start', 'start_webapp') 124 g.custom_command('restart', 'restart_webapp') 125 g.custom_command('browse', 'view_in_browser') 126 g.custom_command('list-instances', 'list_instances') 127 # TO DO: Move back to using list_runtimes function once Available Stacks API is updated (it's updated with Antares deployments) 128 g.custom_command('list-runtimes', 'list_runtimes_hardcoded') 129 g.custom_command('identity assign', 'assign_identity') 130 g.custom_show_command('identity show', 'show_identity') 131 g.custom_command('identity remove', 'remove_identity') 132 g.custom_command('create-remote-connection', 'create_tunnel', exception_handler=ex_handler_factory()) 133 g.custom_command('deploy', 'perform_onedeploy', validator=validate_onedeploy_params, is_preview=True) 134 g.generic_update_command('update', getter_name='get_webapp', setter_name='set_webapp', custom_func_name='update_webapp', command_type=appservice_custom) 135 136 with self.command_group('webapp traffic-routing') as g: 137 g.custom_command('set', 'set_traffic_routing') 138 g.custom_show_command('show', 'show_traffic_routing') 139 g.custom_command('clear', 'clear_traffic_routing') 140 141 with self.command_group('webapp cors') as g: 142 g.custom_command('add', 'add_cors') 143 g.custom_command('remove', 'remove_cors') 144 g.custom_show_command('show', 'show_cors') 145 146 with self.command_group('webapp config') as g: 147 g.custom_command('set', 'update_site_configs') 148 g.custom_show_command('show', 'get_site_configs') 149 150 with self.command_group('webapp config appsettings') as g: 151 g.custom_command('list', 'get_app_settings', exception_handler=empty_on_404) 152 g.custom_command('set', 'update_app_settings') 153 g.custom_command('delete', 'delete_app_settings') 154 155 with self.command_group('webapp config connection-string') as g: 156 g.custom_command('list', 'get_connection_strings', exception_handler=empty_on_404) 157 g.custom_command('set', 'update_connection_strings') 158 g.custom_command('delete', 'delete_connection_strings') 159 160 with self.command_group('webapp config storage-account') as g: 161 g.custom_command('list', 'get_azure_storage_accounts', exception_handler=empty_on_404) 162 g.custom_command('add', 'add_azure_storage_account') 163 g.custom_command('update', 'update_azure_storage_account') 164 g.custom_command('delete', 'delete_azure_storage_accounts') 165 166 with self.command_group('webapp config hostname') as g: 167 g.custom_command('add', 'add_hostname', exception_handler=ex_handler_factory()) 168 g.custom_command('list', 'list_hostnames') 169 g.custom_command('delete', 'delete_hostname') 170 g.custom_command('get-external-ip', 'get_external_ip') 171 172 with self.command_group('webapp config container') as g: 173 g.custom_command('set', 'update_container_settings') 174 g.custom_command('delete', 'delete_container_settings') 175 g.custom_show_command('show', 'show_container_settings') 176 177 with self.command_group('webapp config ssl') as g: 178 g.custom_command('upload', 'upload_ssl_cert') 179 g.custom_command('list', 'list_ssl_certs', exception_handler=ex_handler_factory()) 180 g.custom_show_command('show', 'show_ssl_cert', exception_handler=ex_handler_factory()) 181 g.custom_command('bind', 'bind_ssl_cert', exception_handler=ex_handler_factory()) 182 g.custom_command('unbind', 'unbind_ssl_cert') 183 g.custom_command('delete', 'delete_ssl_cert', exception_handler=ex_handler_factory()) 184 g.custom_command('import', 'import_ssl_cert', exception_handler=ex_handler_factory()) 185 g.custom_command('create', 'create_managed_ssl_cert', exception_handler=ex_handler_factory(), is_preview=True) 186 187 with self.command_group('webapp config backup') as g: 188 g.custom_command('list', 'list_backups') 189 g.custom_show_command('show', 'show_backup_configuration') 190 g.custom_command('create', 'create_backup', exception_handler=ex_handler_factory()) 191 g.custom_command('update', 'update_backup_schedule', exception_handler=ex_handler_factory()) 192 g.custom_command('restore', 'restore_backup', exception_handler=ex_handler_factory()) 193 194 with self.command_group('webapp config snapshot') as g: 195 g.custom_command('list', 'list_snapshots') 196 g.custom_command('restore', 'restore_snapshot') 197 198 with self.command_group('webapp webjob continuous') as g: 199 g.custom_command('list', 'list_continuous_webjobs', exception_handler=ex_handler_factory()) 200 g.custom_command('remove', 'remove_continuous_webjob', exception_handler=ex_handler_factory()) 201 g.custom_command('start', 'start_continuous_webjob', exception_handler=ex_handler_factory()) 202 g.custom_command('stop', 'stop_continuous_webjob', exception_handler=ex_handler_factory()) 203 204 with self.command_group('webapp webjob triggered') as g: 205 g.custom_command('list', 'list_triggered_webjobs', exception_handler=ex_handler_factory()) 206 g.custom_command('remove', 'remove_triggered_webjob', exception_handler=ex_handler_factory()) 207 g.custom_command('run', 'run_triggered_webjob', exception_handler=ex_handler_factory()) 208 g.custom_command('log', 'get_history_triggered_webjob', exception_handler=ex_handler_factory()) 209 210 with self.command_group('webapp deployment source') as g: 211 g.custom_command('config-local-git', 'enable_local_git') 212 g.custom_command('config-zip', 'enable_zip_deploy_webapp') 213 g.custom_command('config', 'config_source_control', exception_handler=ex_handler_factory()) 214 g.custom_command('sync', 'sync_site_repo', exception_handler=ex_handler_factory()) 215 g.custom_show_command('show', 'show_source_control') 216 g.custom_command('delete', 'delete_source_control') 217 g.custom_command('update-token', 'update_git_token', exception_handler=ex_handler_factory()) 218 219 with self.command_group('webapp log') as g: 220 g.custom_command('tail', 'get_streaming_log') 221 g.custom_command('download', 'download_historical_logs') 222 g.custom_command('config', 'config_diagnostics') 223 g.custom_show_command('show', 'show_diagnostic_settings') 224 225 with self.command_group('webapp log deployment', is_preview=True) as g: 226 g.custom_show_command('show', 'show_deployment_log') 227 g.custom_command('list', 'list_deployment_logs') 228 229 with self.command_group('functionapp log deployment', is_preview=True) as g: 230 g.custom_show_command('show', 'show_deployment_log') 231 g.custom_command('list', 'list_deployment_logs') 232 233 with self.command_group('webapp deployment slot') as g: 234 g.custom_command('list', 'list_slots', table_transformer=output_slots_in_table) 235 g.custom_command('delete', 'delete_slot') 236 g.custom_command('auto-swap', 'config_slot_auto_swap') 237 g.custom_command('swap', 'swap_slot', exception_handler=ex_handler_factory()) 238 g.custom_command('create', 'create_webapp_slot', exception_handler=ex_handler_factory()) 239 240 with self.command_group('webapp deployment') as g: 241 g.custom_command('list-publishing-profiles', 'list_publish_profiles') 242 g.custom_command('list-publishing-credentials', 'list_publishing_credentials') 243 244 with self.command_group('webapp deployment user', webclient_sdk) as g: 245 g.custom_show_command('show', 'get_publishing_user') 246 g.custom_command('set', 'set_deployment_user', exception_handler=ex_handler_factory()) 247 248 with self.command_group('webapp deployment container') as g: 249 g.custom_command('config', 'enable_cd') 250 g.custom_command('show-cd-url', 'show_container_cd_url') 251 252 with self.command_group('webapp deployment github-actions', is_preview=True) as g: 253 g.custom_command('add', 'add_github_actions') 254 g.custom_command('remove', 'remove_github_actions') 255 256 with self.command_group('webapp auth') as g: 257 g.custom_show_command('show', 'get_auth_settings') 258 g.custom_command('update', 'update_auth_settings') 259 260 with self.command_group('webapp deleted', is_preview=True) as g: 261 g.custom_command('list', 'list_deleted_webapp') 262 g.custom_command('restore', 'restore_deleted_webapp') 263 264 with self.command_group('webapp hybrid-connection') as g: 265 g.custom_command('list', 'list_hc') 266 g.custom_command('add', 'add_hc') 267 g.custom_command('remove', 'remove_hc') 268 269 with self.command_group('functionapp hybrid-connection') as g: 270 g.custom_command('list', 'list_hc') 271 g.custom_command('add', 'add_hc') 272 g.custom_command('remove', 'remove_hc') 273 274 with self.command_group('appservice hybrid-connection') as g: 275 g.custom_command('set-key', 'set_hc_key') 276 277 with self.command_group('webapp vnet-integration') as g: 278 g.custom_command('add', 'add_vnet_integration') 279 g.custom_command('list', 'list_vnet_integration') 280 g.custom_command('remove', 'remove_vnet_integration') 281 282 with self.command_group('functionapp vnet-integration') as g: 283 g.custom_command('add', 'add_vnet_integration') 284 g.custom_command('list', 'list_vnet_integration') 285 g.custom_command('remove', 'remove_vnet_integration') 286 287 with self.command_group('appservice plan', appservice_plan_sdk) as g: 288 g.custom_command('create', 'create_app_service_plan', supports_no_wait=True, 289 exception_handler=ex_handler_factory(creating_plan=True)) 290 g.command('delete', 'delete', confirmation=True) 291 g.custom_command('list', 'list_app_service_plans') 292 g.custom_show_command('show', 'show_plan') 293 g.generic_update_command('update', setter_name='begin_create_or_update', custom_func_name='update_app_service_plan', 294 setter_arg_name='app_service_plan', supports_no_wait=True, 295 exception_handler=ex_handler_factory()) 296 297 with self.command_group('appservice') as g: 298 g.custom_command('list-locations', 'list_locations', transform=transform_list_location_output) 299 300 with self.command_group('appservice vnet-integration') as g: 301 g.custom_command('list', 'appservice_list_vnet') 302 303 with self.command_group('functionapp') as g: 304 g.custom_command('create', 'create_function', exception_handler=ex_handler_factory()) 305 g.custom_command('list', 'list_function_app', table_transformer=transform_web_list_output) 306 g.custom_show_command('show', 'show_functionapp', table_transformer=transform_web_output) 307 g.custom_command('delete', 'delete_function_app') 308 g.custom_command('stop', 'stop_webapp') 309 g.custom_command('start', 'start_webapp') 310 g.custom_command('restart', 'restart_webapp') 311 g.custom_command('list-consumption-locations', 'list_consumption_locations') 312 g.custom_command('identity assign', 'assign_identity') 313 g.custom_show_command('identity show', 'show_identity') 314 g.custom_command('identity remove', 'remove_identity') 315 g.custom_command('deploy', 'perform_onedeploy', validator=validate_onedeploy_params, is_preview=True) 316 g.generic_update_command('update', getter_name="get_functionapp", setter_name='set_functionapp', exception_handler=update_function_ex_handler_factory(), 317 custom_func_name='update_functionapp', getter_type=appservice_custom, setter_type=appservice_custom, command_type=webapp_sdk) 318 319 with self.command_group('functionapp config') as g: 320 g.custom_command('set', 'update_site_configs') 321 g.custom_show_command('show', 'get_site_configs') 322 323 with self.command_group('functionapp config appsettings') as g: 324 g.custom_command('list', 'get_app_settings', exception_handler=empty_on_404) 325 g.custom_command('set', 'update_app_settings', exception_handler=ex_handler_factory()) 326 g.custom_command('delete', 'delete_app_settings', exception_handler=ex_handler_factory()) 327 328 with self.command_group('functionapp config hostname') as g: 329 g.custom_command('add', 'add_hostname', exception_handler=ex_handler_factory()) 330 g.custom_command('list', 'list_hostnames') 331 g.custom_command('delete', 'delete_hostname') 332 g.custom_command('get-external-ip', 'get_external_ip') 333 334 with self.command_group('functionapp config ssl') as g: 335 g.custom_command('upload', 'upload_ssl_cert', exception_handler=ex_handler_factory()) 336 g.custom_command('list', 'list_ssl_certs') 337 g.custom_show_command('show', 'show_ssl_cert') 338 g.custom_command('bind', 'bind_ssl_cert', exception_handler=ex_handler_factory()) 339 g.custom_command('unbind', 'unbind_ssl_cert') 340 g.custom_command('delete', 'delete_ssl_cert') 341 g.custom_command('import', 'import_ssl_cert', exception_handler=ex_handler_factory()) 342 g.custom_command('create', 'create_managed_ssl_cert', exception_handler=ex_handler_factory(), is_preview=True) 343 344 with self.command_group('functionapp deployment source') as g: 345 g.custom_command('config-local-git', 'enable_local_git') 346 g.custom_command('config-zip', 'enable_zip_deploy_functionapp') 347 g.custom_command('config', 'config_source_control', exception_handler=ex_handler_factory()) 348 g.custom_command('sync', 'sync_site_repo') 349 g.custom_show_command('show', 'show_source_control') 350 g.custom_command('delete', 'delete_source_control') 351 g.custom_command('update-token', 'update_git_token', exception_handler=ex_handler_factory()) 352 353 with self.command_group('functionapp deployment user', webclient_sdk) as g: 354 g.custom_command('set', 'set_deployment_user', exception_handler=ex_handler_factory()) 355 g.show_command('show', 'get_publishing_user') 356 357 with self.command_group('functionapp deployment') as g: 358 g.custom_command('list-publishing-profiles', 'list_publish_profiles') 359 g.custom_command('list-publishing-credentials', 'list_publishing_credentials') 360 361 with self.command_group('functionapp cors') as g: 362 g.custom_command('add', 'add_cors') 363 g.custom_command('remove', 'remove_cors') 364 g.custom_show_command('show', 'show_cors') 365 366 with self.command_group('functionapp plan', appservice_plan_sdk) as g: 367 g.custom_command('create', 'create_functionapp_app_service_plan', exception_handler=ex_handler_factory()) 368 g.generic_update_command('update', setter_name='begin_create_or_update', 369 custom_func_name='update_functionapp_app_service_plan', 370 setter_arg_name='app_service_plan', exception_handler=ex_handler_factory()) 371 g.command('delete', 'delete', confirmation=True) 372 g.custom_command('list', 'list_app_service_plans') 373 g.show_command('show', 'get') 374 375 with self.command_group('functionapp deployment container') as g: 376 g.custom_command('config', 'enable_cd') 377 g.custom_command('show-cd-url', 'show_container_cd_url') 378 379 with self.command_group('functionapp config container') as g: 380 g.custom_command('set', 'update_container_settings_functionapp') 381 g.custom_command('delete', 'delete_container_settings') 382 g.custom_show_command('show', 'show_container_settings_functionapp') 383 384 with self.command_group('functionapp devops-pipeline') as g: 385 g.custom_command('create', 'create_devops_pipeline') 386 387 with self.command_group('functionapp deployment slot') as g: 388 g.custom_command('list', 'list_slots', table_transformer=output_slots_in_table) 389 g.custom_command('delete', 'delete_slot') 390 g.custom_command('auto-swap', 'config_slot_auto_swap') 391 g.custom_command('swap', 'swap_slot', exception_handler=ex_handler_factory()) 392 g.custom_command('create', 'create_functionapp_slot', exception_handler=ex_handler_factory()) 393 394 with self.command_group('functionapp keys') as g: 395 g.custom_command('set', 'update_host_key') 396 g.custom_command('list', 'list_host_keys') 397 g.custom_command('delete', 'delete_host_key') 398 399 with self.command_group('functionapp function') as g: 400 g.custom_command('show', 'show_function') # pylint: disable=show-command 401 g.custom_command('delete', 'delete_function') 402 403 with self.command_group('functionapp function keys') as g: 404 g.custom_command('set', 'update_function_key') 405 g.custom_command('list', 'list_function_keys') 406 g.custom_command('delete', 'delete_function_key') 407 408 with self.command_group('webapp config access-restriction', custom_command_type=webapp_access_restrictions) as g: 409 g.custom_show_command('show', 'show_webapp_access_restrictions') 410 g.custom_command('add', 'add_webapp_access_restriction') 411 g.custom_command('remove', 'remove_webapp_access_restriction') 412 g.custom_command('set', 'set_webapp_access_restriction') 413 414 with self.command_group('functionapp config access-restriction', custom_command_type=webapp_access_restrictions) as g: 415 g.custom_show_command('show', 'show_webapp_access_restrictions') 416 g.custom_command('add', 'add_webapp_access_restriction') 417 g.custom_command('remove', 'remove_webapp_access_restriction') 418 g.custom_command('set', 'set_webapp_access_restriction') 419 420 with self.command_group('appservice ase', custom_command_type=appservice_environment) as g: 421 g.custom_command('list', 'list_appserviceenvironments') 422 g.custom_command('list-addresses', 'list_appserviceenvironment_addresses') 423 g.custom_command('list-plans', 'list_appserviceenvironment_plans') 424 g.custom_show_command('show', 'show_appserviceenvironment') 425 g.custom_command('create', 'create_appserviceenvironment_arm', supports_no_wait=True) 426 g.custom_command('update', 'update_appserviceenvironment', supports_no_wait=True) 427 g.custom_command('delete', 'delete_appserviceenvironment', supports_no_wait=True, confirmation=True) 428 g.custom_command('create-inbound-services', 'create_ase_inbound_services', is_preview=True) 429 430 with self.command_group('appservice domain', custom_command_type=appservice_domains, is_preview=True) as g: 431 g.custom_command('create', 'create_domain') 432 g.custom_command('show-terms', 'show_domain_purchase_terms') 433 434 with self.command_group('staticwebapp', custom_command_type=staticsite_sdk) as g: 435 g.custom_command('list', 'list_staticsites') 436 g.custom_show_command('show', 'show_staticsite') 437 g.custom_command('create', 'create_staticsites', supports_no_wait=True) 438 g.custom_command('delete', 'delete_staticsite', supports_no_wait=True, confirmation=True) 439 g.custom_command('disconnect', 'disconnect_staticsite', supports_no_wait=True) 440 g.custom_command('reconnect', 'reconnect_staticsite', supports_no_wait=True) 441 g.custom_command('update', 'update_staticsite', supports_no_wait=True) 442 443 with self.command_group('staticwebapp environment', custom_command_type=staticsite_sdk) as g: 444 g.custom_command('list', 'list_staticsite_environments') 445 g.custom_show_command('show', 'show_staticsite_environment') 446 g.custom_command('functions', 'list_staticsite_functions') 447 g.custom_command('delete', 'delete_staticsite_environment', confirmation=True) 448 449 with self.command_group('staticwebapp hostname', custom_command_type=staticsite_sdk) as g: 450 g.custom_command('list', 'list_staticsite_domains') 451 g.custom_command('set', 'set_staticsite_domain', supports_no_wait=True) 452 g.custom_command('delete', 'delete_staticsite_domain', supports_no_wait=True, confirmation=True) 453 454 with self.command_group('staticwebapp appsettings', custom_command_type=staticsite_sdk) as g: 455 g.custom_command('list', 'list_staticsite_function_app_settings') 456 g.custom_command('set', 'set_staticsite_function_app_settings') 457 g.custom_command('delete', 'delete_staticsite_function_app_settings') 458 459 with self.command_group('staticwebapp users', custom_command_type=staticsite_sdk) as g: 460 g.custom_command('list', 'list_staticsite_users') 461 g.custom_command('invite', 'invite_staticsite_users') 462 g.custom_command('update', 'update_staticsite_users') 463 464 with self.command_group('staticwebapp secrets', custom_command_type=staticsite_sdk) as g: 465 g.custom_command('list', 'list_staticsite_secrets') 466 g.custom_command('reset-api-key', 'reset_staticsite_api_key', supports_no_wait=True) 467 468 with self.command_group('logicapp') as g: 469 g.custom_command('delete', 'delete_function_app', confirmation=True) 470 g.custom_command('stop', 'stop_webapp') 471 g.custom_command('start', 'start_webapp') 472 g.custom_command('restart', 'restart_webapp') 473 474 with self.command_group('logicapp', custom_command_type=logicapp_custom) as g: 475 g.custom_command('create', 'create_logicapp', exception_handler=ex_handler_factory()) 476 g.custom_command('list', 'list_logicapp', table_transformer=transform_web_list_output) 477 g.custom_show_command('show', 'show_logicapp', table_transformer=transform_web_output) 478