From d4e164ee2712b711521600e39fce23d77021a5d3 Mon Sep 17 00:00:00 2001 From: Calvin Chan Date: Mon, 21 Mar 2022 12:30:29 -0700 Subject: [PATCH 1/3] Add linter exclusions --- linter_exclusions.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/linter_exclusions.yml b/linter_exclusions.yml index dc6a952ebf4..6054be4859c 100644 --- a/linter_exclusions.yml +++ b/linter_exclusions.yml @@ -300,6 +300,28 @@ codespace plan create: default_sku_name: rule_exclusions: - option_length_too_long +containerapp env create: + parameters: + infrastructure_subnet_resource_id: + rule_exclusions: + - option_length_too_long + instrumentation_key: + rule_exclusions: + - option_length_too_long + platform_reserved_dns_ip: + rule_exclusions: + - option_length_too_long +containerapp github-action add: + parameters: + service_principal_client_id: + rule_exclusions: + - option_length_too_long + service_principal_client_secret: + rule_exclusions: + - option_length_too_long + service_principal_tenant_id: + rule_exclusions: + - option_length_too_long costmanagement export create: parameters: definition_dataset_configuration: From 75f49f07fbb810874baf8e06b66268f6867c91a6 Mon Sep 17 00:00:00 2001 From: Calvin Chan Date: Mon, 21 Mar 2022 12:38:28 -0700 Subject: [PATCH 2/3] Fix polling on delete containerapp --- .../azext_containerapp/_clients.py | 27 ++++++++++++++++--- .../azext_containerapp/commands.py | 2 +- src/containerapp/azext_containerapp/custom.py | 4 +-- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/containerapp/azext_containerapp/_clients.py b/src/containerapp/azext_containerapp/_clients.py index 2dc138a6031..ada66cacf0d 100644 --- a/src/containerapp/azext_containerapp/_clients.py +++ b/src/containerapp/azext_containerapp/_clients.py @@ -63,7 +63,9 @@ def poll(cmd, request_url, poll_if_status): # pylint: disable=inconsistent-retu except Exception as e: # pylint: disable=broad-except animation.flush() - if not poll_if_status == "scheduledfordelete": # Catch "not found" errors if polling for delete + delete_statuses = ["scheduledfordelete", "cancelled"] + + if poll_if_status not in delete_statuses: # Catch "not found" errors if polling for delete raise e @@ -127,7 +129,7 @@ def update(cls, cmd, resource_group_name, name, container_app_envelope, no_wait= return r.json() @classmethod - def delete(cls, cmd, resource_group_name, name): + def delete(cls, cmd, resource_group_name, name, no_wait=False): management_hostname = cmd.cli_ctx.cloud.endpoints.resource_manager api_version = NEW_API_VERSION sub_id = get_subscription_id(cmd.cli_ctx) @@ -141,8 +143,25 @@ def delete(cls, cmd, resource_group_name, name): r = send_raw_request(cmd.cli_ctx, "DELETE", request_url) - if r.status_code == 202: - logger.warning('Containerapp successfully deleted') + if no_wait: + return # API doesn't return JSON (it returns no content) + elif r.status_code in [200, 201, 202, 204]: + url_fmt = "{}/subscriptions/{}/resourceGroups/{}/providers/Microsoft.App/containerApps/{}?api-version={}" + request_url = url_fmt.format( + management_hostname.strip('/'), + sub_id, + resource_group_name, + name, + api_version) + + if r.status_code == 202: + from azure.cli.core.azclierror import ResourceNotFoundError + try: + poll(cmd, request_url, "cancelled") + except ResourceNotFoundError: + pass + logger.warning('Containerapp successfully deleted') + @classmethod def show(cls, cmd, resource_group_name, name): diff --git a/src/containerapp/azext_containerapp/commands.py b/src/containerapp/azext_containerapp/commands.py index 4cff20cf47e..bdc2b14cb1b 100644 --- a/src/containerapp/azext_containerapp/commands.py +++ b/src/containerapp/azext_containerapp/commands.py @@ -48,7 +48,7 @@ def load_command_table(self, _): g.custom_command('list', 'list_containerapp', table_transformer=transform_containerapp_list_output) g.custom_command('create', 'create_containerapp', supports_no_wait=True, exception_handler=ex_handler_factory()) g.custom_command('update', 'update_containerapp', supports_no_wait=True, exception_handler=ex_handler_factory()) - g.custom_command('delete', 'delete_containerapp', confirmation=True, exception_handler=ex_handler_factory()) + g.custom_command('delete', 'delete_containerapp', supports_no_wait=True, confirmation=True, exception_handler=ex_handler_factory()) with self.command_group('containerapp env') as g: g.custom_show_command('show', 'show_managed_environment') diff --git a/src/containerapp/azext_containerapp/custom.py b/src/containerapp/azext_containerapp/custom.py index 06a9c922c3b..aadaccde746 100644 --- a/src/containerapp/azext_containerapp/custom.py +++ b/src/containerapp/azext_containerapp/custom.py @@ -713,11 +713,11 @@ def list_containerapp(cmd, resource_group_name=None): handle_raw_exception(e) -def delete_containerapp(cmd, name, resource_group_name): +def delete_containerapp(cmd, name, resource_group_name, no_wait=False): _validate_subscription_registered(cmd, "Microsoft.App") try: - return ContainerAppClient.delete(cmd=cmd, name=name, resource_group_name=resource_group_name) + return ContainerAppClient.delete(cmd=cmd, name=name, resource_group_name=resource_group_name, no_wait=no_wait) except CLIInternalError as e: handle_raw_exception(e) From 6b9c8c70ffd7e23797d78a22cc5216a43045b351 Mon Sep 17 00:00:00 2001 From: Calvin Chan Date: Mon, 21 Mar 2022 12:52:44 -0700 Subject: [PATCH 3/3] Fix error handling --- src/containerapp/azext_containerapp/custom.py | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/containerapp/azext_containerapp/custom.py b/src/containerapp/azext_containerapp/custom.py index aadaccde746..ae119aa5c92 100644 --- a/src/containerapp/azext_containerapp/custom.py +++ b/src/containerapp/azext_containerapp/custom.py @@ -6,7 +6,13 @@ from urllib.parse import urlparse from azure.cli.command_modules.appservice.custom import (_get_acr_cred) -from azure.cli.core.azclierror import (RequiredArgumentMissingError, ValidationError, ResourceNotFoundError, CLIInternalError, InvalidArgumentValueError) +from azure.cli.core.azclierror import ( + RequiredArgumentMissingError, + ValidationError, + ResourceNotFoundError, + CLIError, + CLIInternalError, + InvalidArgumentValueError) from azure.cli.core.commands.client_factory import get_subscription_id from knack.log import get_logger @@ -122,7 +128,7 @@ def update_containerapp_yaml(cmd, name, resource_group_name, file_name, from_rev if from_revision: try: r = ContainerAppClient.show_revision(cmd=cmd, resource_group_name=resource_group_name, container_app_name=name, name=from_revision) - except CLIInternalError as e: + except CLIError as e: handle_raw_exception(e) _update_revision_env_secretrefs(r["properties"]["template"]["containers"], name) current_containerapp_def["properties"]["template"] = r["properties"]["template"] @@ -694,7 +700,7 @@ def show_containerapp(cmd, name, resource_group_name): try: return ContainerAppClient.show(cmd=cmd, resource_group_name=resource_group_name, name=name) - except CLIInternalError as e: + except CLIError as e: handle_raw_exception(e) @@ -709,7 +715,7 @@ def list_containerapp(cmd, resource_group_name=None): containerapps = ContainerAppClient.list_by_resource_group(cmd=cmd, resource_group_name=resource_group_name) return containerapps - except CLIInternalError as e: + except CLIError as e: handle_raw_exception(e) @@ -718,7 +724,7 @@ def delete_containerapp(cmd, name, resource_group_name, no_wait=False): try: return ContainerAppClient.delete(cmd=cmd, name=name, resource_group_name=resource_group_name, no_wait=no_wait) - except CLIInternalError as e: + except CLIError as e: handle_raw_exception(e) @@ -809,7 +815,7 @@ def show_managed_environment(cmd, name, resource_group_name): try: return ManagedEnvironmentClient.show(cmd=cmd, resource_group_name=resource_group_name, name=name) - except CLIInternalError as e: + except CLIError as e: handle_raw_exception(e) @@ -824,7 +830,7 @@ def list_managed_environments(cmd, resource_group_name=None): managed_envs = ManagedEnvironmentClient.list_by_resource_group(cmd=cmd, resource_group_name=resource_group_name) return managed_envs - except CLIInternalError as e: + except CLIError as e: handle_raw_exception(e) @@ -833,7 +839,7 @@ def delete_managed_environment(cmd, name, resource_group_name, no_wait=False): try: return ManagedEnvironmentClient.delete(cmd=cmd, name=name, resource_group_name=resource_group_name, no_wait=no_wait) - except CLIInternalError as e: + except CLIError as e: handle_raw_exception(e) @@ -994,7 +1000,7 @@ def show_managed_identity(cmd, name, resource_group_name): try: r = ContainerAppClient.show(cmd=cmd, resource_group_name=resource_group_name, name=name) - except CLIInternalError as e: + except CLIError as e: handle_raw_exception(e) try: @@ -1061,7 +1067,7 @@ def create_or_update_github_action(cmd, if e.data and e.data['message']: error_msg += " Error: {}".format(e.data['message']) raise CLIInternalError(error_msg) from e - except CLIInternalError as clierror: + except CLIError as clierror: raise clierror except Exception: # If exception due to github package missing, etc just continue without validating the repo and rely on api validation @@ -1179,7 +1185,7 @@ def delete_github_action(cmd, name, resource_group_name, token=None, login_with_ if e.data and e.data['message']: error_msg += " Error: {}".format(e.data['message']) raise CLIInternalError(error_msg) from e - except CLIInternalError as clierror: + except CLIError as clierror: raise clierror except Exception: # If exception due to github package missing, etc just continue without validating the repo and rely on api validation @@ -1196,7 +1202,7 @@ def delete_github_action(cmd, name, resource_group_name, token=None, login_with_ def list_revisions(cmd, name, resource_group_name): try: return ContainerAppClient.list_revisions(cmd=cmd, resource_group_name=resource_group_name, name=name) - except CLIInternalError as e: + except CLIError as e: handle_raw_exception(e) @@ -1206,7 +1212,7 @@ def show_revision(cmd, resource_group_name, revision_name, name=None): try: return ContainerAppClient.show_revision(cmd=cmd, resource_group_name=resource_group_name, container_app_name=name, name=revision_name) - except CLIInternalError as e: + except CLIError as e: handle_raw_exception(e) @@ -1216,7 +1222,7 @@ def restart_revision(cmd, resource_group_name, revision_name, name=None): try: return ContainerAppClient.restart_revision(cmd=cmd, resource_group_name=resource_group_name, container_app_name=name, name=revision_name) - except CLIInternalError as e: + except CLIError as e: handle_raw_exception(e) @@ -1226,7 +1232,7 @@ def activate_revision(cmd, resource_group_name, revision_name, name=None): try: return ContainerAppClient.activate_revision(cmd=cmd, resource_group_name=resource_group_name, container_app_name=name, name=revision_name) - except CLIInternalError as e: + except CLIError as e: handle_raw_exception(e) @@ -1236,7 +1242,7 @@ def deactivate_revision(cmd, resource_group_name, revision_name, name=None): try: return ContainerAppClient.deactivate_revision(cmd=cmd, resource_group_name=resource_group_name, container_app_name=name, name=revision_name) - except CLIInternalError as e: + except CLIError as e: handle_raw_exception(e) @@ -1289,7 +1295,7 @@ def copy_revision(cmd, if from_revision: try: r = ContainerAppClient.show_revision(cmd=cmd, resource_group_name=resource_group_name, container_app_name=name, name=from_revision) - except CLIInternalError as e: + except CLIError as e: # Error handle the case where revision not found? handle_raw_exception(e)