diff --git a/src/azure-cli/azure/cli/command_modules/acr/_breaking_change.py b/src/azure-cli/azure/cli/command_modules/acr/_breaking_change.py index b96d1654675..a4a84f262d9 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_breaking_change.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_breaking_change.py @@ -5,8 +5,7 @@ from azure.cli.core.breaking_change import ( register_argument_deprecate, - register_command_group_deprecate, - register_logic_breaking_change + register_command_group_deprecate ) helm_bc_msg = 'In November 2020, Helm 2 reached end of life. ' \ @@ -33,16 +32,6 @@ register_command_group_deprecate(command_group='acr config content-trust', message=content_trust_bc_msg) -register_logic_breaking_change('acr check-health', 'Remove Notary client version validation', - detail='The Notary client version check will no longer be performed as part of the ' - 'check-health command due to Docker Content Trust deprecation.', - doc_link='https://aka.ms/acr/dctdeprecation') - -register_logic_breaking_change('acr config content-trust update', 'Remove content-trust enabled configuration', - detail='The `--status enabled` parameter will no longer be accepted and will result in ' - 'an error due to Docker Content Trust deprecation.', - doc_link='https://aka.ms/acr/dctdeprecation') - register_argument_deprecate('acr replication create', '--region-endpoint-enabled', redirect='--global-endpoint-routing') register_argument_deprecate('acr replication update', '--region-endpoint-enabled', diff --git a/src/azure-cli/azure/cli/command_modules/acr/_errors.py b/src/azure-cli/azure/cli/command_modules/acr/_errors.py index a582d779fc7..34d1b2a30c1 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_errors.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_errors.py @@ -69,18 +69,6 @@ def format_error_message(self, *args): ) -# NOTARY ERRORS -NOTARY_COMMAND_ERROR = ErrorClass( - "NOTARY_COMMAND_ERROR", - "Please verify if notary is installed." -) - -NOTARY_VERSION_ERROR = ErrorClass( - "NOTARY_VERSION_ERROR", - "An error occurred while retrieving notary version. Please make sure that you have the latest Azure CLI version, and that you are using the recommended notary version." -) - - # CONNECTIVITY ERRORS CONNECTIVITY_DNS_ERROR = ErrorClass( "CONNECTIVITY_DNS_ERROR", diff --git a/src/azure-cli/azure/cli/command_modules/acr/_help.py b/src/azure-cli/azure/cli/command_modules/acr/_help.py index 2bafa530bfe..aa56ad42f47 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_help.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_help.py @@ -71,6 +71,7 @@ short-summary: Configure policies for Azure Container Registries. """ +# To be deprecated helps['acr config content-trust'] = """ type: group short-summary: Manage content-trust policy for Azure Container Registries. @@ -102,6 +103,7 @@ az acr config authentication-as-arm update -r myregistry --status Enabled """ +# To be deprecated helps['acr config content-trust show'] = """ type: command short-summary: Show the configured content-trust policy for an Azure Container Registry. @@ -111,6 +113,7 @@ az acr config content-trust show -r myregistry """ +# To be deprecated helps['acr config content-trust update'] = """ type: command short-summary: Update content-trust policy for an Azure Container Registry. diff --git a/src/azure-cli/azure/cli/command_modules/acr/_params.py b/src/azure-cli/azure/cli/command_modules/acr/_params.py index 27f8cd3d591..f71a03186c2 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_params.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_params.py @@ -156,6 +156,9 @@ def load_arguments(self, _): # pylint: disable=too-many-statements c.argument('registry_name', options_list=['--registry', '-r', c.deprecate(target='-n', redirect='-r', hide=True), c.deprecate(target='--name', redirect='--registry', hide=True)]) c.argument('status', help="Indicate whether authentication-as-arm is enabled.", arg_type=get_enum_type(PolicyStatus)) + with self.argument_context('acr config content-trust update') as c: + c.argument('status', help="Indicates whether content-trust is enabled. Only 'disabled' is allowed.", arg_type=get_enum_type([PolicyStatus.disabled])) + with self.argument_context('acr config content-trust') as c: c.argument('registry_name', options_list=['--registry', '-r', c.deprecate(target='-n', redirect='-r', hide=True), c.deprecate(target='--name', redirect='--registry', hide=True)]) c.argument('status', help="Indicates whether content-trust is enabled.", arg_type=get_enum_type(PolicyStatus)) diff --git a/src/azure-cli/azure/cli/command_modules/acr/check_health.py b/src/azure-cli/azure/cli/command_modules/acr/check_health.py index fed78bd47c4..023f2e75a29 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/check_health.py +++ b/src/azure-cli/azure/cli/command_modules/acr/check_health.py @@ -24,8 +24,6 @@ MIN_HELM_VERSION = "2.11.0" HELM_VERSION_REGEX = re.compile(r'(SemVer|Version):"v([.\d]+)"') ACR_CHECK_HEALTH_MSG = "Try running 'az acr check-health -n {} --yes' to diagnose this issue." -RECOMMENDED_NOTARY_VERSION = "0.6.0" -NOTARY_VERSION_REGEX = re.compile(r'Version:\s+([.\d]+)') DOCKER_PULL_WRONG_PLATFORM = 'cannot be used on this platform' @@ -181,46 +179,6 @@ def _get_helm_version(ignore_errors): _handle_error(obsolete_ver_error, ignore_errors) -def _get_notary_version(ignore_errors): - from ._errors import NOTARY_VERSION_ERROR - from .notary import get_notary_command - from packaging.version import parse # pylint: disable=import-error,no-name-in-module - - # Notary command check - notary_command, error = get_notary_command(is_diagnostics_context=True) - - if error: - _handle_error(error, ignore_errors) - return - - # Notary version check - output, warning, stderr, succeeded = _subprocess_communicate([notary_command, "version"]) - - if not succeeded: - _handle_error(NOTARY_VERSION_ERROR.append_error_message(stderr), ignore_errors) - return - - if warning: - logger.warning(warning) - - # Retrieve the notary version if regex pattern is found - match_obj = NOTARY_VERSION_REGEX.search(output) - if match_obj: - output = match_obj.group(1) - - logger.warning("Notary version: %s", output) - - # Display error if the current version does not match the recommended version - if match_obj and parse(output) != parse(RECOMMENDED_NOTARY_VERSION): - version_msg = "upgrade" - if parse(output) > parse(RECOMMENDED_NOTARY_VERSION): - version_msg = "downgrade" - obsolete_ver_error = NOTARY_VERSION_ERROR.set_error_message( - "Current notary version is not recommended. Please {} your notary client to version {}." - .format(version_msg, RECOMMENDED_NOTARY_VERSION)) - _handle_error(obsolete_ver_error, ignore_errors) - - # Checks for the connectivity # Check DNS lookup and access to challenge endpoint def _get_registry_status(login_server, registry_name, ignore_errors): @@ -481,6 +439,5 @@ def acr_check_health(cmd, # pylint: disable useless-return if not in_cloud_console: _get_helm_version(ignore_errors) - _get_notary_version(ignore_errors) logger.warning(FAQ_MESSAGE) diff --git a/src/azure-cli/azure/cli/command_modules/acr/commands.py b/src/azure-cli/azure/cli/command_modules/acr/commands.py index a65d677c4a7..4148c2d5f51 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/commands.py +++ b/src/azure-cli/azure/cli/command_modules/acr/commands.py @@ -342,7 +342,14 @@ def load_command_table(self, _): g.command('logs', 'acr_taskrun_logs', client_factory=cf_acr_runs, table_transformer=None) - with self.command_group('acr config content-trust', acr_policy_util) as g: + def _dct_deprecate_message(self): + msg = "This {} has been deprecated and will be removed in a future release.".format(self.object_type) + msg += " Learn more about the transition from Docker Content Trust to the Notary Project: " + msg += "https://aka.ms/acr/dctdeprecation" + return msg + + with self.command_group('acr config content-trust', acr_policy_util, + deprecate_info=self.deprecate(message_func=_dct_deprecate_message, hide=False)) as g: g.show_command('show', 'acr_config_content_trust_show') g.command('update', 'acr_config_content_trust_update') diff --git a/src/azure-cli/azure/cli/command_modules/acr/notary.py b/src/azure-cli/azure/cli/command_modules/acr/notary.py deleted file mode 100644 index e320f120ccd..00000000000 --- a/src/azure-cli/azure/cli/command_modules/acr/notary.py +++ /dev/null @@ -1,36 +0,0 @@ -# -------------------------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# -------------------------------------------------------------------------------------------- - -from knack.util import CLIError -from knack.log import get_logger - -logger = get_logger(__name__) - - -def get_notary_command(is_diagnostics_context=False): - from ._errors import NOTARY_COMMAND_ERROR - from subprocess import PIPE, Popen - from platform import system - - if system() == "Windows": - notary_command = "notary.exe" - else: - notary_command = "notary" - - try: - p = Popen([notary_command, "--help"], stdout=PIPE, stderr=PIPE) - _, stderr = p.communicate() - except OSError as e: - logger.debug("Could not run '%s' command. Exception: %s", notary_command, str(e)) - if is_diagnostics_context: - return None, NOTARY_COMMAND_ERROR - raise CLIError(NOTARY_COMMAND_ERROR.get_error_message()) - - if stderr: - if is_diagnostics_context: - return None, NOTARY_COMMAND_ERROR.append_error_message(stderr.decode()) - raise CLIError(NOTARY_COMMAND_ERROR.append_error_message(stderr.decode()).get_error_message()) - - return notary_command, None diff --git a/src/azure-cli/azure/cli/command_modules/acr/policy.py b/src/azure-cli/azure/cli/command_modules/acr/policy.py index 4615909a97d..97a2ffd8885 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/policy.py +++ b/src/azure-cli/azure/cli/command_modules/acr/policy.py @@ -34,10 +34,20 @@ def acr_config_content_trust_update(cmd, client, registry_name, status=None, - resource_group_name=None): + resource_group_name=None, + yes=False): registry, resource_group_name = validate_premium_registry( cmd, registry_name, resource_group_name, POLICIES_NOT_SUPPORTED) + warning_message = ( + "Content Trust is being deprecated and will be completely removed on March 31, 2028. " + "It cannot be enabled once disabled. Please submit a support ticket if you wish to " + "disable and subsequently re-enable this feature. When disabled, your images will " + "remain in the registry, but all your signatures will be deleted permanently. " + "Are you sure you want to disable content trust?" + ) + user_confirmation(warning_message, yes) + policies = registry.policies if status: diff --git a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands.py b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands.py index 303c122cb2e..a721fe70677 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands.py +++ b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_commands.py @@ -45,12 +45,15 @@ def _core_registry_scenario(self, registry_name, resource_group, location): checks=[self.check('status', "enabled"), self.check('days', 30)]) - # test content-trust - self.cmd('acr config content-trust update -n {} --status enabled'.format(registry_name), - checks=[self.check('status', "enabled")]) + # test content-trust - 'enabled' is no longer a valid value for --status due to DCT deprecation + with self.assertRaises(SystemExit): + self.cmd('acr config content-trust update -n {} --status enabled'.format(registry_name)) + + self.cmd('acr config content-trust update -n {} --status disabled --yes'.format(registry_name), + checks=[self.check('status', "disabled")]) self.cmd('acr config content-trust show -n {}'.format(registry_name), - checks=[self.check('status', "enabled")]) + checks=[self.check('status', "disabled")]) # test soft-delete self.cmd('acr config soft-delete update -r {} --status enabled --days 30 --yes'.format(registry_name),