Skip to content

Commit e3a2f4e

Browse files
seligj95Copilot
andcommitted
[App Service] Fix #15647, #17674, #29760, #12391: connection-string IDs, docker create params, log help, public certs
- #15647: Enable --ids support for 'az webapp config connection-string list' by removing id_part=None override and cleaning up incorrect explicit --ids arg with required=True on the connection-string argument context. - #17674: Add --docker-registry-server-url deprecated alias to 'webapp create' container_registry_url param. Also set DOCKER_REGISTRY_SERVER_* app settings during Linux container creation (previously only set for Windows containers). - #29760: Improve --docker-container-logging help text in _params.py and _help.py. Clarify 'filesystem' vs 'off' values and add long-summary to 'webapp log config'. - #12391: Add 'az webapp config public-cert' command group with upload, list, show, and delete subcommands for managing public certificates (.cer/.crt) on web apps via the PublicCertificate REST API. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent dc9fdb3 commit e3a2f4e

4 files changed

Lines changed: 144 additions & 17 deletions

File tree

src/azure-cli/azure/cli/command_modules/appservice/_help.py

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,9 +1570,10 @@
15701570
type: command
15711571
short-summary: Get a web app's connection strings.
15721572
examples:
1573-
- name: Get a web app's connection strings. (autogenerated)
1573+
- name: Get a web app's connection strings.
15741574
text: az webapp config connection-string list --name MyWebapp --resource-group MyResourceGroup
1575-
crafted: true
1575+
- name: Get a web app's connection strings using a resource ID.
1576+
text: az webapp config connection-string list --ids /subscriptions/{SubID}/resourceGroups/{ResourceGroup}/providers/Microsoft.Web/sites/{WebApp}
15761577
"""
15771578

15781579
helps['webapp config connection-string set'] = """
@@ -1778,6 +1779,53 @@
17781779
text: az webapp config ssl create --resource-group MyResourceGroup --name MyWebapp --hostname cname.mycustomdomain.com
17791780
"""
17801781

1782+
helps['webapp config public-cert'] = """
1783+
type: group
1784+
short-summary: Manage public certificates for a web app.
1785+
"""
1786+
1787+
helps['webapp config public-cert upload'] = """
1788+
type: command
1789+
short-summary: Upload a public certificate (.cer or .crt) to a web app.
1790+
long-summary: >
1791+
Public certificates are used to allow the web app to make outbound calls to services that
1792+
require certificate-based authentication. Unlike SSL certificates, public certificates do not
1793+
bind to a hostname.
1794+
examples:
1795+
- name: Upload a public certificate to a web app.
1796+
text: >
1797+
az webapp config public-cert upload -g MyResourceGroup -n MyWebapp
1798+
--public-certificate-name MyCert --certificate-file /path/to/cert.cer
1799+
- name: Upload a public certificate to a deployment slot.
1800+
text: >
1801+
az webapp config public-cert upload -g MyResourceGroup -n MyWebapp --slot staging
1802+
--public-certificate-name MyCert --certificate-file /path/to/cert.cer
1803+
"""
1804+
1805+
helps['webapp config public-cert list'] = """
1806+
type: command
1807+
short-summary: List public certificates for a web app.
1808+
examples:
1809+
- name: List public certificates for a web app.
1810+
text: az webapp config public-cert list -g MyResourceGroup -n MyWebapp
1811+
"""
1812+
1813+
helps['webapp config public-cert show'] = """
1814+
type: command
1815+
short-summary: Show the details of a public certificate for a web app.
1816+
examples:
1817+
- name: Show a public certificate.
1818+
text: az webapp config public-cert show -g MyResourceGroup -n MyWebapp --public-certificate-name MyCert
1819+
"""
1820+
1821+
helps['webapp config public-cert delete'] = """
1822+
type: command
1823+
short-summary: Delete a public certificate from a web app.
1824+
examples:
1825+
- name: Delete a public certificate from a web app.
1826+
text: az webapp config public-cert delete -g MyResourceGroup -n MyWebapp --public-certificate-name MyCert
1827+
"""
1828+
17811829
helps['webapp config storage-account'] = """
17821830
type: group
17831831
short-summary: Manage a web app's Azure storage account configurations.
@@ -2285,13 +2333,20 @@
22852333
helps['webapp log config'] = """
22862334
type: command
22872335
short-summary: Configure logging for a web app.
2336+
long-summary: >
2337+
Use this command to turn on or off application logging, web server logging, and docker container logging.
2338+
For Linux and custom container web apps, --docker-container-logging controls whether STDOUT and STDERR
2339+
from the container are collected. Use 'filesystem' to enable (logs viewable via `az webapp log tail` or
2340+
downloadable via `az webapp log download`) or 'off' to disable.
22882341
examples:
2289-
- name: Configure logging for a web app. (autogenerated)
2342+
- name: Turn off web server logging.
22902343
text: az webapp log config --name MyWebapp --resource-group MyResourceGroup --web-server-logging off
2291-
crafted: true
2292-
- name: Configure logging for a web app. (autogenerated)
2344+
- name: Disable docker container logging for a Linux/container web app.
22932345
text: az webapp log config --docker-container-logging off --name MyWebapp --resource-group MyResourceGroup
2294-
crafted: true
2346+
- name: Enable docker container logging (write to filesystem) for a Linux/container web app.
2347+
text: az webapp log config --docker-container-logging filesystem --name MyWebapp --resource-group MyResourceGroup
2348+
- name: Configure application logging to write to the filesystem.
2349+
text: az webapp log config --application-logging filesystem --name MyWebapp --resource-group MyResourceGroup
22952350
"""
22962351

22972352
helps['webapp log download'] = """

src/azure-cli/azure/cli/command_modules/appservice/_params.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ def load_arguments(self, _):
308308
c.argument('startup_file', help="Linux only. The web's startup file")
309309
c.argument('sitecontainers_app', help="If true, a webapp which supports sitecontainers will be created", arg_type=get_three_state_flag())
310310
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'))
311-
c.argument('container_registry_url', options_list=['--container-registry-url'], help='The container registry server url')
311+
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')
312312
c.argument('container_image_name', options_list=['--container-image-name', '-c'],
313313
help='The container custom image name and optionally the tag name (e.g., `<registry-name>/<image-name>:<tag>`)')
314314
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, _):
521521
c.argument('hostname', help='The custom domain name')
522522
c.argument('name', options_list=['--name', '-n'], help='Name of the web app.')
523523
c.argument('resource-group', options_list=['--resource-group', '-g'], help='Name of resource group.')
524+
with self.argument_context(scope + ' config public-cert') as c:
525+
c.argument('public_certificate_name', options_list=['--public-certificate-name'],
526+
help='The name of the public certificate.')
527+
c.argument('slot', options_list=['--slot', '-s'],
528+
help='The name of the slot. Default to the productions slot if not specified')
529+
with self.argument_context(scope + ' config public-cert upload') as c:
530+
c.argument('certificate_file', type=file_type,
531+
help='The filepath for the .cer or .crt public certificate file')
532+
c.argument('public_certificate_location', options_list=['--certificate-location'],
533+
help='Location (certificate store) for the public certificate',
534+
arg_type=get_enum_type(['CurrentUserMy', 'LocalMachineMy', 'Unknown']),
535+
default='CurrentUserMy')
536+
with self.argument_context(scope + ' config public-cert list') as c:
537+
c.argument('name', arg_type=(webapp_name_arg_type if scope == 'webapp' else functionapp_name_arg_type),
538+
id_part=None)
524539
with self.argument_context(scope + ' config hostname') as c:
525540
c.argument('hostname', completer=get_hostname_completion_list,
526541
help="hostname assigned to the site, such as custom domains", id_part='child_name_1')
@@ -682,7 +697,7 @@ def load_arguments(self, _):
682697
c.argument('settings', nargs='+', help="space-separated configuration for the number of pre-allocated instances in the format `<name>=<value>`")
683698

684699
with self.argument_context('webapp config connection-string list') as c:
685-
c.argument('name', arg_type=webapp_name_arg_type, id_part=None)
700+
c.argument('name', arg_type=webapp_name_arg_type)
686701

687702
with self.argument_context('webapp config storage-account list') as c:
688703
c.argument('name', arg_type=webapp_name_arg_type, id_part=None)
@@ -751,7 +766,12 @@ def load_arguments(self, _):
751766
arg_type=get_enum_type(['error', 'warning', 'information', 'verbose']))
752767
c.argument('web_server_logging', help='configure Web server logging',
753768
arg_type=get_enum_type(['off', 'filesystem']))
754-
c.argument('docker_container_logging', help='configure gathering STDOUT and STDERR output from container',
769+
c.argument('docker_container_logging',
770+
help="Configure gathering STDOUT and STDERR output from container. "
771+
"'filesystem' enables collection and storage on the web app's file system "
772+
"(accessible via log stream and log download). "
773+
"'off' disables container output collection. "
774+
"Applies to Linux web apps and Windows container web apps.",
755775
arg_type=get_enum_type(['off', 'filesystem']))
756776

757777
with self.argument_context('webapp log tail') as c:
@@ -795,14 +815,6 @@ def load_arguments(self, _):
795815
with self.argument_context('webapp config connection-string') as c:
796816
c.argument('connection_string_type', options_list=['--connection-string-type', '-t'],
797817
help='connection string type', arg_type=get_enum_type(ConnectionStringType))
798-
c.argument('ids', options_list=['--ids'],
799-
help="One or more resource IDs (space delimited). If provided no other 'Resource Id' arguments should be specified.",
800-
required=True)
801-
c.argument('resource_group', options_list=['--resource-group', '-g'],
802-
help='Name of resource group. You can configure the default group using `az configure --default-group=<name>`. If `--ids` is provided this should NOT be specified.')
803-
c.argument('name', options_list=['--name', '-n'],
804-
help='Name of the web app. You can configure the default using `az configure --defaults web=<name>`. If `--ids` is provided this should NOT be specified.',
805-
local_context_attribute=LocalContextAttribute(name='web_name', actions=[LocalContextAction.GET]))
806818

807819
with self.argument_context('webapp config storage-account') as c:
808820
c.argument('custom_id', options_list=['--custom-id', '-i'], help='name of the share configured within the web app')

src/azure-cli/azure/cli/command_modules/appservice/commands.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,12 @@ def load_command_table(self, _):
203203
g.custom_command('import', 'import_ssl_cert', exception_handler=ex_handler_factory())
204204
g.custom_command('create', 'create_managed_ssl_cert', exception_handler=ex_handler_factory(), is_preview=True)
205205

206+
with self.command_group('webapp config public-cert') as g:
207+
g.custom_command('upload', 'upload_public_cert')
208+
g.custom_command('list', 'list_public_certs')
209+
g.custom_show_command('show', 'show_public_cert')
210+
g.custom_command('delete', 'delete_public_cert', confirmation=True)
211+
206212
with self.command_group('webapp config backup') as g:
207213
g.custom_command('list', 'list_backups')
208214
g.custom_show_command('show', 'show_backup_configuration')

src/azure-cli/azure/cli/command_modules/appservice/custom.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,15 @@ def create_webapp(cmd, resource_group_name, name, plan, runtime=None, startup_fi
284284
if name_validation.name_available:
285285
site_config.app_settings.append(NameValuePair(name="WEBSITES_ENABLE_APP_SERVICE_STORAGE",
286286
value="false"))
287+
if container_registry_url:
288+
site_config.app_settings.append(NameValuePair(name="DOCKER_REGISTRY_SERVER_URL",
289+
value=container_registry_url))
290+
if container_registry_user:
291+
site_config.app_settings.append(NameValuePair(name="DOCKER_REGISTRY_SERVER_USERNAME",
292+
value=container_registry_user))
293+
if container_registry_password:
294+
site_config.app_settings.append(NameValuePair(name="DOCKER_REGISTRY_SERVER_PASSWORD",
295+
value=container_registry_password))
287296
elif multicontainer_config_type and multicontainer_config_file:
288297
encoded_config_file = _get_linux_multicontainer_encoded_config_from_file(multicontainer_config_file)
289298
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):
58775886
raise ResourceNotFoundError("Certificate for thumbprint '{}' not found".format(certificate_thumbprint))
58785887

58795888

5889+
def upload_public_cert(cmd, resource_group_name, name, public_certificate_name,
5890+
certificate_file, slot=None,
5891+
public_certificate_location='CurrentUserMy'):
5892+
PublicCertificate = cmd.get_models('PublicCertificate')
5893+
client = web_client_factory(cmd.cli_ctx)
5894+
with open(certificate_file, 'rb') as f:
5895+
cert_contents = f.read()
5896+
import base64
5897+
cert_blob = base64.b64encode(cert_contents)
5898+
public_cert = PublicCertificate(
5899+
blob=cert_blob,
5900+
public_certificate_location=public_certificate_location
5901+
)
5902+
if slot:
5903+
return client.web_apps.create_or_update_public_certificate_slot(
5904+
resource_group_name, name, public_certificate_name, public_cert, slot)
5905+
return client.web_apps.create_or_update_public_certificate(
5906+
resource_group_name, name, public_certificate_name, public_cert)
5907+
5908+
5909+
def list_public_certs(cmd, resource_group_name, name, slot=None):
5910+
client = web_client_factory(cmd.cli_ctx)
5911+
if slot:
5912+
return client.web_apps.list_public_certificates_slot(resource_group_name, name, slot)
5913+
return client.web_apps.list_public_certificates(resource_group_name, name)
5914+
5915+
5916+
def delete_public_cert(cmd, resource_group_name, name, public_certificate_name, slot=None):
5917+
client = web_client_factory(cmd.cli_ctx)
5918+
if slot:
5919+
return client.web_apps.delete_public_certificate_slot(
5920+
resource_group_name, name, public_certificate_name, slot)
5921+
return client.web_apps.delete_public_certificate(
5922+
resource_group_name, name, public_certificate_name)
5923+
5924+
5925+
def show_public_cert(cmd, resource_group_name, name, public_certificate_name, slot=None):
5926+
client = web_client_factory(cmd.cli_ctx)
5927+
if slot:
5928+
return client.web_apps.get_public_certificate_slot(
5929+
resource_group_name, name, public_certificate_name, slot)
5930+
return client.web_apps.get_public_certificate(
5931+
resource_group_name, name, public_certificate_name)
5932+
5933+
58805934
def import_ssl_cert(cmd, resource_group_name, key_vault, key_vault_certificate_name, name=None, certificate_name=None):
58815935
Certificate = cmd.get_models('Certificate')
58825936
client = web_client_factory(cmd.cli_ctx)

0 commit comments

Comments
 (0)