diff --git a/src/azure-cli/azure/cli/command_modules/appservice/_help.py b/src/azure-cli/azure/cli/command_modules/appservice/_help.py index e0dad92e98c..1a65dfbbf42 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/_help.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/_help.py @@ -1570,9 +1570,10 @@ type: command short-summary: Get a web app's connection strings. examples: - - name: Get a web app's connection strings. (autogenerated) + - name: Get a web app's connection strings. text: az webapp config connection-string list --name MyWebapp --resource-group MyResourceGroup - crafted: true + - name: Get a web app's connection strings using a resource ID. + text: az webapp config connection-string list --ids /subscriptions/{SubID}/resourceGroups/{ResourceGroup}/providers/Microsoft.Web/sites/{WebApp} """ helps['webapp config connection-string set'] = """ @@ -1778,6 +1779,53 @@ text: az webapp config ssl create --resource-group MyResourceGroup --name MyWebapp --hostname cname.mycustomdomain.com """ +helps['webapp config public-cert'] = """ +type: group +short-summary: Manage public certificates for a web app. +""" + +helps['webapp config public-cert upload'] = """ +type: command +short-summary: Upload a public certificate (.cer or .crt) to a web app. +long-summary: > + Public certificates are used to allow the web app to make outbound calls to services that + require certificate-based authentication. Unlike SSL certificates, public certificates do not + bind to a hostname. +examples: + - name: Upload a public certificate to a web app. + text: > + az webapp config public-cert upload -g MyResourceGroup -n MyWebapp + --public-certificate-name MyCert --certificate-file /path/to/cert.cer + - name: Upload a public certificate to a deployment slot. + text: > + az webapp config public-cert upload -g MyResourceGroup -n MyWebapp --slot staging + --public-certificate-name MyCert --certificate-file /path/to/cert.cer +""" + +helps['webapp config public-cert list'] = """ +type: command +short-summary: List public certificates for a web app. +examples: + - name: List public certificates for a web app. + text: az webapp config public-cert list -g MyResourceGroup -n MyWebapp +""" + +helps['webapp config public-cert show'] = """ +type: command +short-summary: Show the details of a public certificate for a web app. +examples: + - name: Show a public certificate. + text: az webapp config public-cert show -g MyResourceGroup -n MyWebapp --public-certificate-name MyCert +""" + +helps['webapp config public-cert delete'] = """ +type: command +short-summary: Delete a public certificate from a web app. +examples: + - name: Delete a public certificate from a web app. + text: az webapp config public-cert delete -g MyResourceGroup -n MyWebapp --public-certificate-name MyCert +""" + helps['webapp config storage-account'] = """ type: group short-summary: Manage a web app's Azure storage account configurations. @@ -2285,13 +2333,20 @@ helps['webapp log config'] = """ type: command short-summary: Configure logging for a web app. +long-summary: > + Use this command to turn on or off application logging, web server logging, and docker container logging. + For Linux and custom container web apps, --docker-container-logging controls whether STDOUT and STDERR + from the container are collected. Use 'filesystem' to enable (logs viewable via `az webapp log tail` or + downloadable via `az webapp log download`) or 'off' to disable. examples: - - name: Configure logging for a web app. (autogenerated) + - name: Turn off web server logging. text: az webapp log config --name MyWebapp --resource-group MyResourceGroup --web-server-logging off - crafted: true - - name: Configure logging for a web app. (autogenerated) + - name: Disable docker container logging for a Linux/container web app. text: az webapp log config --docker-container-logging off --name MyWebapp --resource-group MyResourceGroup - crafted: true + - name: Enable docker container logging (write to filesystem) for a Linux/container web app. + text: az webapp log config --docker-container-logging filesystem --name MyWebapp --resource-group MyResourceGroup + - name: Configure application logging to write to the filesystem. + text: az webapp log config --application-logging filesystem --name MyWebapp --resource-group MyResourceGroup """ helps['webapp log download'] = """ diff --git a/src/azure-cli/azure/cli/command_modules/appservice/_params.py b/src/azure-cli/azure/cli/command_modules/appservice/_params.py index bd4dc0b7ea5..dd2b71f38bd 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/_params.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/_params.py @@ -308,7 +308,7 @@ def load_arguments(self, _): c.argument('startup_file', help="Linux only. The web's startup file") c.argument('sitecontainers_app', help="If true, a webapp which supports sitecontainers will be created", arg_type=get_three_state_flag()) c.argument('deployment_container_image_name', options_list=['--deployment-container-image-name', '-i'], help='Container image name from container registry, e.g. publisher/image-name:tag', deprecate_info=c.deprecate(target='--deployment-container-image-name')) - c.argument('container_registry_url', options_list=['--container-registry-url'], help='The container registry server url') + c.argument('container_registry_url', options_list=['--container-registry-url', c.deprecate(target='--docker-registry-server-url', redirect='--container-registry-url')], help='The container registry server url') c.argument('container_image_name', options_list=['--container-image-name', '-c'], help='The container custom image name and optionally the tag name (e.g., `/:`)') c.argument('container_registry_user', options_list=['--container-registry-user', '-s', c.deprecate(target='--docker-registry-server-user', redirect='--container-registry-user')], help='The container registry server username') @@ -521,6 +521,21 @@ def load_arguments(self, _): c.argument('hostname', help='The custom domain name') c.argument('name', options_list=['--name', '-n'], help='Name of the web app.') c.argument('resource-group', options_list=['--resource-group', '-g'], help='Name of resource group.') + with self.argument_context(scope + ' config public-cert') as c: + c.argument('public_certificate_name', options_list=['--public-certificate-name'], + help='The name of the public certificate.') + c.argument('slot', options_list=['--slot', '-s'], + help='The name of the slot. Default to the productions slot if not specified') + with self.argument_context(scope + ' config public-cert upload') as c: + c.argument('certificate_file', type=file_type, + help='The filepath for the .cer or .crt public certificate file') + c.argument('public_certificate_location', options_list=['--certificate-location'], + help='Location (certificate store) for the public certificate', + arg_type=get_enum_type(['CurrentUserMy', 'LocalMachineMy', 'Unknown']), + default='CurrentUserMy') + with self.argument_context(scope + ' config public-cert list') as c: + c.argument('name', arg_type=(webapp_name_arg_type if scope == 'webapp' else functionapp_name_arg_type), + id_part=None) with self.argument_context(scope + ' config hostname') as c: c.argument('hostname', completer=get_hostname_completion_list, help="hostname assigned to the site, such as custom domains", id_part='child_name_1') @@ -682,7 +697,7 @@ def load_arguments(self, _): c.argument('settings', nargs='+', help="space-separated configuration for the number of pre-allocated instances in the format `=`") with self.argument_context('webapp config connection-string list') as c: - c.argument('name', arg_type=webapp_name_arg_type, id_part=None) + c.argument('name', arg_type=webapp_name_arg_type) with self.argument_context('webapp config storage-account list') as c: c.argument('name', arg_type=webapp_name_arg_type, id_part=None) @@ -751,7 +766,12 @@ def load_arguments(self, _): arg_type=get_enum_type(['error', 'warning', 'information', 'verbose'])) c.argument('web_server_logging', help='configure Web server logging', arg_type=get_enum_type(['off', 'filesystem'])) - c.argument('docker_container_logging', help='configure gathering STDOUT and STDERR output from container', + c.argument('docker_container_logging', + help="Configure gathering STDOUT and STDERR output from container. " + "'filesystem' enables collection and storage on the web app's file system " + "(accessible via log stream and log download). " + "'off' disables container output collection. " + "Applies to Linux web apps and Windows container web apps.", arg_type=get_enum_type(['off', 'filesystem'])) with self.argument_context('webapp log tail') as c: @@ -795,14 +815,6 @@ def load_arguments(self, _): with self.argument_context('webapp config connection-string') as c: c.argument('connection_string_type', options_list=['--connection-string-type', '-t'], help='connection string type', arg_type=get_enum_type(ConnectionStringType)) - c.argument('ids', options_list=['--ids'], - help="One or more resource IDs (space delimited). If provided no other 'Resource Id' arguments should be specified.", - required=True) - c.argument('resource_group', options_list=['--resource-group', '-g'], - help='Name of resource group. You can configure the default group using `az configure --default-group=`. If `--ids` is provided this should NOT be specified.') - c.argument('name', options_list=['--name', '-n'], - help='Name of the web app. You can configure the default using `az configure --defaults web=`. If `--ids` is provided this should NOT be specified.', - local_context_attribute=LocalContextAttribute(name='web_name', actions=[LocalContextAction.GET])) with self.argument_context('webapp config storage-account') as c: c.argument('custom_id', options_list=['--custom-id', '-i'], help='name of the share configured within the web app') diff --git a/src/azure-cli/azure/cli/command_modules/appservice/commands.py b/src/azure-cli/azure/cli/command_modules/appservice/commands.py index 47536f5a1df..bc32acfc33b 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/commands.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/commands.py @@ -203,6 +203,12 @@ def load_command_table(self, _): g.custom_command('import', 'import_ssl_cert', exception_handler=ex_handler_factory()) g.custom_command('create', 'create_managed_ssl_cert', exception_handler=ex_handler_factory(), is_preview=True) + with self.command_group('webapp config public-cert') as g: + g.custom_command('upload', 'upload_public_cert') + g.custom_command('list', 'list_public_certs') + g.custom_show_command('show', 'show_public_cert') + g.custom_command('delete', 'delete_public_cert', confirmation=True) + with self.command_group('webapp config backup') as g: g.custom_command('list', 'list_backups') g.custom_show_command('show', 'show_backup_configuration') diff --git a/src/azure-cli/azure/cli/command_modules/appservice/custom.py b/src/azure-cli/azure/cli/command_modules/appservice/custom.py index 386ba088608..f3fd100c8cf 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/custom.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/custom.py @@ -284,6 +284,15 @@ def create_webapp(cmd, resource_group_name, name, plan, runtime=None, startup_fi if name_validation.name_available: site_config.app_settings.append(NameValuePair(name="WEBSITES_ENABLE_APP_SERVICE_STORAGE", value="false")) + if container_registry_url: + site_config.app_settings.append(NameValuePair(name="DOCKER_REGISTRY_SERVER_URL", + value=container_registry_url)) + if container_registry_user: + site_config.app_settings.append(NameValuePair(name="DOCKER_REGISTRY_SERVER_USERNAME", + value=container_registry_user)) + if container_registry_password: + site_config.app_settings.append(NameValuePair(name="DOCKER_REGISTRY_SERVER_PASSWORD", + value=container_registry_password)) elif multicontainer_config_type and multicontainer_config_file: encoded_config_file = _get_linux_multicontainer_encoded_config_from_file(multicontainer_config_file) site_config.linux_fx_version = _format_fx_version(encoded_config_file, multicontainer_config_type) @@ -5877,6 +5886,51 @@ def delete_ssl_cert(cmd, resource_group_name, certificate_thumbprint): raise ResourceNotFoundError("Certificate for thumbprint '{}' not found".format(certificate_thumbprint)) +def upload_public_cert(cmd, resource_group_name, name, public_certificate_name, + certificate_file, slot=None, + public_certificate_location='CurrentUserMy'): + PublicCertificate = cmd.get_models('PublicCertificate') + client = web_client_factory(cmd.cli_ctx) + with open(certificate_file, 'rb') as f: + cert_contents = f.read() + import base64 + cert_blob = base64.b64encode(cert_contents) + public_cert = PublicCertificate( + blob=cert_blob, + public_certificate_location=public_certificate_location + ) + if slot: + return client.web_apps.create_or_update_public_certificate_slot( + resource_group_name, name, public_certificate_name, public_cert, slot) + return client.web_apps.create_or_update_public_certificate( + resource_group_name, name, public_certificate_name, public_cert) + + +def list_public_certs(cmd, resource_group_name, name, slot=None): + client = web_client_factory(cmd.cli_ctx) + if slot: + return client.web_apps.list_public_certificates_slot(resource_group_name, name, slot) + return client.web_apps.list_public_certificates(resource_group_name, name) + + +def delete_public_cert(cmd, resource_group_name, name, public_certificate_name, slot=None): + client = web_client_factory(cmd.cli_ctx) + if slot: + return client.web_apps.delete_public_certificate_slot( + resource_group_name, name, public_certificate_name, slot) + return client.web_apps.delete_public_certificate( + resource_group_name, name, public_certificate_name) + + +def show_public_cert(cmd, resource_group_name, name, public_certificate_name, slot=None): + client = web_client_factory(cmd.cli_ctx) + if slot: + return client.web_apps.get_public_certificate_slot( + resource_group_name, name, public_certificate_name, slot) + return client.web_apps.get_public_certificate( + resource_group_name, name, public_certificate_name) + + def import_ssl_cert(cmd, resource_group_name, key_vault, key_vault_certificate_name, name=None, certificate_name=None): Certificate = cmd.get_models('Certificate') client = web_client_factory(cmd.cli_ctx)