diff --git a/.changes/next-release/enhancement-Migration-48043.json b/.changes/next-release/enhancement-Migration-48043.json index 562578687c30..ad42ffc841a3 100644 --- a/.changes/next-release/enhancement-Migration-48043.json +++ b/.changes/next-release/enhancement-Migration-48043.json @@ -1,5 +1,5 @@ { "type": "enhancement", "category": "Migration", - "description": "Implement a ``--migrate-v2`` flag that detects breaking changes for AWS CLI v2 for entered commands." + "description": "Implement a ``--v2-debug`` flag that detects breaking changes for AWS CLI v2 for entered commands." } diff --git a/awscli/clidriver.py b/awscli/clidriver.py index 1a798aa2c5c0..07d12131af68 100644 --- a/awscli/clidriver.py +++ b/awscli/clidriver.py @@ -41,7 +41,6 @@ ) from awscli.commands import CLICommand from awscli.compat import get_stderr_text_writer -from awscli.customizations.utils import uni_print from awscli.formatter import get_formatter from awscli.help import ( OperationHelpCommand, @@ -49,7 +48,7 @@ ServiceHelpCommand, ) from awscli.plugin import load_plugins -from awscli.utils import emit_top_level_args_parsed_event, write_exception, create_nested_client +from awscli.utils import emit_top_level_args_parsed_event, write_exception, create_nested_client, resolve_v2_debug_mode from botocore import __version__ as botocore_version from botocore import xform_name @@ -682,7 +681,7 @@ def _detect_binary_file_migration_change( # if cli_binary_format is set to raw-in-base64-out, then v2 behavior will # be the same as v1, so there is no breaking change in this case. return - if parsed_globals.v2_debug: + if resolve_v2_debug_mode(parsed_globals): parsed_args_to_check = { arg: getattr(parsed_args, arg) for arg in vars(parsed_args) if getattr(parsed_args, arg) @@ -692,19 +691,18 @@ def _detect_binary_file_migration_change( arg.py_name for arg in arg_table.values() if arg.py_name in parsed_args_to_check and arg.argument_model.type_name == 'blob' - and parsed_args_to_check[arg.py_name].startswith('file://') ] if arg_values_to_check: - uni_print( - 'AWS CLI v2 MIGRATION WARNING: When specifying a blob-type ' - 'parameter starting with `file://`, AWS CLI v2 will assume ' - 'the content of the file is already base64-encoded. To ' - 'maintain v1 behavior after upgrading to v2, set the ' - '`cli_binary_format` configuration variable to ' - '`raw-in-base64-out`. See https://docs.aws.amazon.com/cli/' - 'latest/userguide/cliv2-migration-changes.html#' - 'cliv2-migration-binaryparam.\n', - out_file=sys.stderr + print( + 'AWS CLI v2 UPGRADE WARNING: When specifying a blob-type ' + 'parameter, AWS CLI v2 will assume the parameter value is ' + 'base64-encoded. To maintain v1 behavior after upgrading ' + 'to v2, set the `cli_binary_format` configuration ' + 'variable to `raw-in-base64-out`. See ' + 'https://docs.aws.amazon.com/cli/latest/userguide' + '/cliv2-migration-changes.html' + '#cliv2-migration-binaryparam.\n', + file=sys.stderr ) diff --git a/awscli/customizations/cloudformation/deploy.py b/awscli/customizations/cloudformation/deploy.py index a734453e2e0f..e33b03a8f362 100644 --- a/awscli/customizations/cloudformation/deploy.py +++ b/awscli/customizations/cloudformation/deploy.py @@ -25,7 +25,7 @@ from awscli.customizations.commands import BasicCommand from awscli.compat import get_stdout_text_writer from awscli.customizations.utils import uni_print -from awscli.utils import create_nested_client, write_exception +from awscli.utils import create_nested_client, write_exception, resolve_v2_debug_mode LOG = logging.getLogger(__name__) @@ -317,12 +317,13 @@ def _run_main(self, parsed_args, parsed_globals): s3_uploader = None deployer = Deployer(cloudformation_client) + v2_debug = resolve_v2_debug_mode(parsed_globals) return self.deploy(deployer, stack_name, template_str, parameters, parsed_args.capabilities, parsed_args.execute_changeset, parsed_args.role_arn, parsed_args.notification_arns, s3_uploader, tags, parsed_args.fail_on_empty_changeset, - parsed_args.disable_rollback, getattr(parsed_globals, 'v2_debug', False)) + parsed_args.disable_rollback, v2_debug) def deploy(self, deployer, stack_name, template_str, parameters, capabilities, execute_changeset, role_arn, @@ -330,6 +331,18 @@ def deploy(self, deployer, stack_name, template_str, fail_on_empty_changeset=True, disable_rollback=False, v2_debug=False): try: + if v2_debug and fail_on_empty_changeset: + uni_print( + 'AWS CLI v2 UPGRADE WARNING: In AWS CLI v2, ' + 'deploying an AWS CloudFormation Template that ' + 'results in an empty changeset will NOT result in an ' + 'error. You can add the -–no-fail-on-empty-changeset ' + 'flag to migrate to v2 behavior and resolve this ' + 'warning. See https://docs.aws.amazon.com/cli/latest/' + 'userguide/cliv2-migration-changes.html' + '#cliv2-migration-cfn.\n', + out_file=sys.stderr + ) result = deployer.create_and_wait_for_changeset( stack_name=stack_name, cfn_template=template_str, @@ -342,18 +355,6 @@ def deploy(self, deployer, stack_name, template_str, ) except exceptions.ChangeEmptyError as ex: if fail_on_empty_changeset: - if v2_debug: - uni_print( - 'AWS CLI v2 MIGRATION WARNING: In AWS CLI v2, ' - 'deploying an AWS CloudFormation Template that ' - 'results in an empty changeset will NOT result in an ' - 'error. You can add the -–no-fail-on-empty-changeset ' - 'flag to migrate to v2 behavior and resolve this ' - 'warning. See https://docs.aws.amazon.com/cli/latest/' - 'userguide/cliv2-migration-changes.html' - '#cliv2-migration-cfn.\n', - out_file=sys.stderr - ) raise write_exception(ex, outfile=get_stdout_text_writer()) return 0 diff --git a/awscli/customizations/globalargs.py b/awscli/customizations/globalargs.py index 96b599ce37ea..59582ab61768 100644 --- a/awscli/customizations/globalargs.py +++ b/awscli/customizations/globalargs.py @@ -18,9 +18,12 @@ from botocore.client import Config from botocore import UNSIGNED from botocore.endpoint import DEFAULT_TIMEOUT +from botocore.useragent import register_feature_id import jmespath from awscli.compat import urlparse +from awscli.utils import resolve_v2_debug_mode + def register_parse_global_args(cli): cli.register('top-level-args-parsed', resolve_types, @@ -96,7 +99,7 @@ def resolve_cli_connect_timeout(parsed_args, session, **kwargs): _resolve_timeout(session, parsed_args, arg_name) def detect_migration_breakage(parsed_args, remaining_args, session, **kwargs): - if not parsed_args.v2_debug: + if not resolve_v2_debug_mode(parsed_args): return url_params = [ param for param in remaining_args @@ -104,14 +107,29 @@ def detect_migration_breakage(parsed_args, remaining_args, session, **kwargs): ] region = parsed_args.region or session.get_config_variable('region') s3_config = session.get_config_variable('s3') + if ( + not session.get_scoped_config().get('cli_pager', None) + == '' and 'AWS_PAGER' not in os.environ + ): + uni_print( + 'AWS CLI v2 UPGRADE WARNING: By default, the AWS CLI version 2 ' + 'returns all output through your operating system’s default pager ' + 'program. To retain AWS CLI v1 behavior after upgrading to AWS ' + 'CLI v2, set the `cli_pager` configuration setting, or the ' + '`AWS_PAGER` environment variable, to the empty string. See ' + 'https://docs.aws.amazon.com/cli/latest/userguide' + '/cliv2-migration-changes.html#cliv2-migration-output-pager.\n', + out_file=sys.stderr + ) if 'PYTHONUTF8' in os.environ or 'PYTHONIOENCODING' in os.environ: if 'AWS_CLI_FILE_ENCODING' not in os.environ: uni_print( - 'AWS CLI v2 MIGRATION WARNING: The PYTHONUTF8 and ' + 'AWS CLI v2 UPGRADE WARNING: The PYTHONUTF8 and ' 'PYTHONIOENCODING environment variables are unsupported ' - 'in AWS CLI v2. AWS CLI v2 uses AWS_CLI_FILE_ENCODING ' - 'instead, set this environment variable to resolve this. ' - 'See https://docs.aws.amazon.com/cli/latest/userguide/' + 'in AWS CLI v2. AWS CLI v2 uses the `AWS_CLI_FILE_ENCODING` ' + 'variable instead; set this environment variable to retain ' + 'AWS CLI v1 behavior after upgrading to AWS CLI v2. See ' + 'https://docs.aws.amazon.com/cli/latest/userguide/' 'cliv2-migration-changes.html' '#cliv2-migration-encodingenvvar.\n', out_file=sys.stderr @@ -129,18 +147,18 @@ def detect_migration_breakage(parsed_args, remaining_args, session, **kwargs): ) if session.get_config_variable('api_versions'): uni_print( - 'AWS CLI v2 MIGRATION WARNING: The AWS CLI v2 does not support ' + 'AWS CLI v2 UPGRADE WARNING: The AWS CLI v2 does not support ' 'calling earlier versions of AWS service APIs via the ' '`api_versions` configuration file setting. To migrate to v2 ' - 'behavior and resolve this warning, remove the `api_versions` ' - 'setting in the configuration file. See ' + 'behavior, remove the `api_versions` configuration setting, and ' + 'test against the latest API versions. See ' 'https://docs.aws.amazon.com/cli/latest/userguide/' 'cliv2-migration-changes.html#cliv2-migration-api-versions.\n', out_file = sys.stderr ) if session.full_config.get('plugins', {}): uni_print( - 'AWS CLI v2 MIGRATION WARNING: In AWS CLI v2, plugin support ' + 'AWS CLI v2 UPGRADE WARNING: In AWS CLI v2, plugin support ' 'is provisional. If you rely on plugins, be sure to lock into ' 'a particular version of the AWS CLI and test the ' 'functionality of your plugins for each upgrade. See ' @@ -151,18 +169,18 @@ def detect_migration_breakage(parsed_args, remaining_args, session, **kwargs): ) if parsed_args.command == 'ecr' and remaining_args[0] == 'get-login': uni_print( - 'AWS CLI v2 MIGRATION WARNING: The ecr get-login command has ' - 'been removed in AWS CLI v2. See https://docs.aws.amazon.com/' - 'cli/latest/userguide/cliv2-migration-changes.html' - '#cliv2-migration-ecr-get-login.\n', + 'AWS CLI v2 UPGRADE WARNING: The `ecr get-login` command has ' + 'been removed in AWS CLI v2. You must use `ecr get-login-password` ' + 'instead. See https://docs.aws.amazon.com/cli/latest/userguide/' + 'cliv2-migration-changes.html#cliv2-migration-ecr-get-login.\n', out_file=sys.stderr ) - if url_params and session.full_config.get('cli_follow_urlparam', True): + if url_params and session.get_scoped_config().get('cli_pager', None): uni_print( - 'AWS CLI v2 MIGRATION WARNING: For input parameters that have ' + 'AWS CLI v2 UPGRADE WARNING: For input parameters that have ' 'a prefix of http:// or https://, AWS CLI v2 will no longer ' 'automatically request the content of the URL for the ' - 'parameter, and the cli_follow_urlparam option has been ' + 'parameter, and the `cli_follow_urlparam` option has been ' 'removed. See https://docs.aws.amazon.com/cli/latest/' 'userguide/cliv2-migration-changes.html' '#cliv2-migration-paramfile.\n', @@ -179,27 +197,40 @@ def detect_migration_breakage(parsed_args, remaining_args, session, **kwargs): and f"--{working_param}" in remaining_args ): uni_print( - 'AWS CLI v2 MIGRATION WARNING: You have entered command ' + 'AWS CLI v2 UPGRADE WARNING: You have entered command ' 'arguments that uses at least 1 of 21 hidden aliases that ' - 'were removed in AWS CLI v2. See ' + 'were removed in AWS CLI v2. You must replace usage of the ' + 'obsolete alias with the corresponding working parameter. See ' 'https://docs.aws.amazon.com/cli/latest/userguide' '/cliv2-migration-changes.html#cliv2-migration-aliases.\n', out_file=sys.stderr ) + # Register against the provide-client-params event to ensure that the + # feature ID is registered before any API requests are made. We + # cannot register the feature ID in this function because no + # botocore context is created at this point. + session.register( + 'provide-client-params.*.*', + _register_v2_debug_feature_id + ) session.register('choose-signer.s3.*', warn_if_sigv2) + +def _register_v2_debug_feature_id(params, model, **kwargs): + register_feature_id('CLI_V1_TO_V2_MIGRATION_DEBUG_MODE') + def warn_if_east_configured_global_endpoint(request, operation_name, **kwargs): # The regional us-east-1 endpoint is used in certain cases (e.g. # FIPS/Dual-Stack is enabled). Rather than duplicating this logic # from botocore, we check the endpoint URL directly. if 's3.amazonaws.com' in request.url: uni_print( - 'AWS CLI v2 MIGRATION WARNING: When you configure AWS CLI v2 ' + 'AWS CLI v2 UPGRADE WARNING: When you configure AWS CLI v2 ' 'to use the `us-east-1` region, it uses the true regional ' - 'endpoint rather than the global endpoint. To continue using ' - 'the global endpoint on v2, configure the region to be ' - '`aws-global`. See https://docs.aws.amazon.com/cli/latest/' - 'userguide/cliv2-migration-changes.html' + 'endpoint rather than the global endpoint. To retain AWS CLI v1 ' + 'behavior after upgrading to AWS CLI v2, configure the `region` ' + 'setting to `aws-global`. See https://docs.aws.amazon.com/cli' + '/latest/userguide/cliv2-migration-changes.html' '#cliv2-migration-s3-regional-endpoint.\n', out_file=sys.stderr ) @@ -213,10 +244,10 @@ def warn_if_sigv2( ): if context.get('auth_type', None) == 'v2': uni_print( - 'AWS CLI v2 MIGRATION WARNING: The AWS CLI v2 only uses Signature ' - 'v4 to authenticate Amazon S3 requests. Run the command `aws ' - 'configure set s3.signature_version s3v4` to migrate to v4 and ' - 'resolve this.\n', + 'AWS CLI v2 UPGRADE WARNING: The AWS CLI v2 only uses Signature ' + 'v4 to authenticate Amazon S3 requests. To migrate to AWS CLI ' + 'v2 behavior, configure the Signature Version S3 setting to ' + 'version 4.\n', out_file=sys.stderr ) diff --git a/awscli/customizations/paginate.py b/awscli/customizations/paginate.py index 836b338b0fef..2d64bae611c3 100644 --- a/awscli/customizations/paginate.py +++ b/awscli/customizations/paginate.py @@ -33,7 +33,7 @@ from botocore import model from awscli.arguments import BaseCLIArgument - +from awscli.utils import resolve_v2_debug_mode logger = logging.getLogger(__name__) @@ -293,7 +293,7 @@ def check_should_enable_pagination_call_parameters( naming space and would be missed by the processing above. This function gets called on the calling-command event. """ - if parsed_globals.v2_debug: + if resolve_v2_debug_mode(parsed_globals): cli_input_json_data = session.emit_first_non_none_response( f"get-cli-input-json-data", ) @@ -304,11 +304,12 @@ def check_should_enable_pagination_call_parameters( ] if pagination_params_in_input_tokens: uni_print( - 'AWS CLI v2 MIGRATION WARNING: In AWS CLI v2, if you specify ' + 'AWS CLI v2 UPGRADE WARNING: In AWS CLI v2, if you specify ' 'pagination parameters by using a file with the ' '`--cli-input-json` parameter, automatic pagination will be ' - 'turned off. This is not the case in v1. See ' - 'https://docs.aws.amazon.com/cli/latest/userguide/' + 'turned off. To retain AWS CLI v1 behavior after upgrading to ' + 'AWS CLI v2, remove all pagination parameters from the input ' + 'JSON. See https://docs.aws.amazon.com/cli/latest/userguide/' 'cliv2-migration-changes.html' '#cliv2-migration-skeleton-paging.\n', out_file=sys.stderr diff --git a/awscli/customizations/s3/subcommands.py b/awscli/customizations/s3/subcommands.py index 665fa9ae2603..b05ae1857020 100644 --- a/awscli/customizations/s3/subcommands.py +++ b/awscli/customizations/s3/subcommands.py @@ -36,7 +36,7 @@ from awscli.customizations.s3.syncstrategy.base import MissingFileSync, \ SizeAndLastModifiedSync, NeverSync from awscli.customizations.s3 import transferconfig - +from awscli.utils import resolve_v2_debug_mode LOGGER = logging.getLogger(__name__) @@ -1060,7 +1060,7 @@ def run(self): if self.parameters['v2_debug']: if operation_name == 'copy': uni_print( - 'AWS CLI v2 MIGRATION WARNING: In AWS CLI v2, object ' + 'AWS CLI v2 UPGRADE WARNING: In AWS CLI v2, object ' 'properties will be copied from the source in multipart ' 'copies between S3 buckets. This may result in extra S3 ' 'API calls being made. Breakage may occur if the principal ' @@ -1464,7 +1464,7 @@ def add_page_size(self, parsed_args): self.parameters['page_size'] = getattr(parsed_args, 'page_size', None) def add_v2_debug(self, parsed_globals): - self.parameters['v2_debug'] = parsed_globals.v2_debug + self.parameters['v2_debug'] = resolve_v2_debug_mode(parsed_globals) def _validate_sse_c_args(self): self._validate_sse_c_arg() diff --git a/awscli/customizations/scalarparse.py b/awscli/customizations/scalarparse.py index a9c56eaa8656..c5217a0db804 100644 --- a/awscli/customizations/scalarparse.py +++ b/awscli/customizations/scalarparse.py @@ -33,6 +33,7 @@ from botocore.exceptions import ProfileNotFound from awscli.customizations.utils import uni_print +from awscli.utils import resolve_v2_debug_mode def register_scalar_parser(event_handlers): @@ -50,10 +51,18 @@ def iso_format(value): def add_timestamp_parser(session, v2_debug): factory = session.get_component('response_parser_factory') + print_v2_debug_warnings = v2_debug try: timestamp_format = session.get_scoped_config().get( 'cli_timestamp_format', - 'wire') + None) + if timestamp_format is not None: + # We do not want to print v2 debug warnings if the user explicitly + # configured the cli_timestamp_format, they would not be + # broken in that case. + print_v2_debug_warnings = False + else: + timestamp_format = 'wire' except ProfileNotFound: # If a --profile is provided that does not exist, loading # a value from get_scoped_config will crash the CLI. @@ -79,17 +88,19 @@ def identity_with_warning(x): if not encountered_timestamp: encountered_timestamp = True uni_print( - 'AWS CLI v2 MIGRATION WARNING: In AWS CLI v2, all timestamp ' + 'AWS CLI v2 UPGRADE WARNING: In AWS CLI v2, all timestamp ' 'response values are returned in the ISO 8601 format. To ' - 'migrate to v2 behavior and resolve this warning, set the ' - 'configuration variable `cli_timestamp_format` to `iso8601`. ' - 'See https://docs.aws.amazon.com/cli/latest/userguide/' - 'cliv2-migration-changes.html#cliv2-migration-timestamp.\n', + 'migrate to v2 behavior, set the configuration variable ' + '`cli_timestamp_format` to `iso8601`. See https://' + 'docs.aws.amazon.com/cli/latest/userguide/' + 'cliv2-migration-changes.html' + '#cliv2-migration-timestamp.\n', out_file=sys.stderr ) return identity(x) - timestamp_parser = identity_with_warning if v2_debug else identity + timestamp_parser = identity_with_warning \ + if print_v2_debug_warnings else identity elif timestamp_format == 'iso8601': timestamp_parser = iso_format else: @@ -101,4 +112,4 @@ def identity_with_warning(x): def add_scalar_parsers(session, parsed_args, **kwargs): factory = session.get_component('response_parser_factory') factory.set_parser_defaults(blob_parser=identity) - add_timestamp_parser(session, parsed_args.v2_debug) + add_timestamp_parser(session, resolve_v2_debug_mode(parsed_args)) diff --git a/awscli/data/cli.json b/awscli/data/cli.json index 25687399d05c..d75489e88664 100644 --- a/awscli/data/cli.json +++ b/awscli/data/cli.json @@ -69,6 +69,11 @@ "action": "store_true", "dest": "v2_debug", "help": "
Enable AWS CLI v2 migration assistance. Prints warnings if the command would face a breaking change after swapping AWS CLI v1 for AWS CLI v2 in the current environment. Prints one warning for each breaking change detected.
" + }, + "no-v2-debug": { + "action": "store_true", + "dest": "no_v2_debug", + "help": "Disable AWS CLI v2 migration assistance.
" } } } diff --git a/awscli/examples/global_options.rst b/awscli/examples/global_options.rst index d450cf0ce78a..914d070ed329 100644 --- a/awscli/examples/global_options.rst +++ b/awscli/examples/global_options.rst @@ -74,3 +74,7 @@ Enable AWS CLI v2 migration assistance. Prints warnings if the command would face a breaking change after swapping AWS CLI v1 for AWS CLI v2 in the current environment. Prints one warning for each breaking change detected. +``--no-v2-debug`` (boolean) + + Disable AWS CLI v2 migration assistance. + diff --git a/awscli/examples/global_synopsis.rst b/awscli/examples/global_synopsis.rst index 12865958a809..1d8295f550ed 100644 --- a/awscli/examples/global_synopsis.rst +++ b/awscli/examples/global_synopsis.rst @@ -13,3 +13,4 @@ [--cli-read-timeout