""" Utilities for sam deploy command """ import copy import json import textwrap import click def print_deploy_args( stack_name, s3_bucket, image_repository, region, capabilities, parameter_overrides, confirm_changeset, signing_profiles, use_changeset, disable_rollback, ): """ Print a table of the values that are used during a sam deploy. Irrespective of if a image_repository is provided or not, the template is always uploaded to the s3 bucket. Example below: Deploying with following values =============================== Stack name : sam-app Region : us-east-1 Confirm changeset : False Disable rollback : False Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-abcdef Capabilities : ["CAPABILITY_IAM"] Parameter overrides : {'MyParamater': '***', 'Parameter2': 'dd'} Signing Profiles : {'MyFunction': 'ProfileName:ProfileOwner'} :param stack_name: Name of the stack used during sam deploy :param s3_bucket: Name of s3 bucket used for packaging code artifacts. :param image_repository: Name of image repository used for packaging artifacts as container images. :param region: Name of region to which the current sam/cloudformation stack will be deployed to. :param capabilities: Corresponding IAM capabilities to be used during the stack deploy. :param parameter_overrides: Cloudformation parameter overrides to be supplied based on the stack's template :param confirm_changeset: Prompt for changeset to be confirmed before going ahead with the deploy. :param signing_profiles: Signing profile details which will be used to sign functions/layers :param use_changeset: Flag to use or skip the usage of changesets :param disable_rollback: Preserve the state of previously provisioned resources when an operation fails. """ _parameters = parameter_overrides.copy() capabilities_string = json.dumps(capabilities) _signing_profiles = {} if signing_profiles: for key, value in signing_profiles.items(): _signing_profiles[key] = f"{value['profile_name']}:{value['profile_owner']}" image_repository_format_text = ( json.dumps(image_repository, indent=4) if isinstance(image_repository, dict) else image_repository ) parameter_overrides_format_text = json.dumps(_parameters) signing_profiles_format_text = json.dumps(signing_profiles) click.secho("\n\tDeploying with following values\n\t===============================", fg="yellow") click.echo(f"\tStack name : {stack_name}") click.echo(f"\tRegion : {region}") if use_changeset: click.echo(f"\tConfirm changeset : {confirm_changeset}") click.echo(f"\tDisable rollback : {disable_rollback}") if image_repository: msg = "Deployment image repository : " # NOTE(sriram-mv): tab length is 8 spaces. prefix_length = len(msg) + 8 click.echo(f"\t{msg}") click.echo(f"{textwrap.indent(image_repository_format_text, prefix=' ' * prefix_length)}") click.echo(f"\tDeployment s3 bucket : {s3_bucket}") click.echo(f"\tCapabilities : {capabilities_string}") click.echo(f"\tParameter overrides : {parameter_overrides_format_text}") click.echo(f"\tSigning Profiles : {signing_profiles_format_text}") click.secho("\nInitiating deployment\n=====================\n", fg="yellow") def sanitize_parameter_overrides(parameter_overrides): """ Get sanitized parameter override values based on if the workflow went via a guided deploy to set the parameter overrides for deployment. If a guided deploy was followed the parameter overrides consists of additional information such as if a given parameter's value is hidden or not. :param parameter_overrides: dictionary of parameter key values. :return: """ return {key: value.get("Value") if isinstance(value, dict) else value for key, value in parameter_overrides.items()} def hide_noecho_parameter_overrides(template_parameters, parameter_overrides): hidden_params = copy.deepcopy(parameter_overrides) params = template_parameters.get("Parameters", None) for key, value in hidden_params.items(): if isinstance(params, dict) and key in params and isinstance(params[key], dict): is_hidden = params[key].get("NoEcho", False) hidden_params[key] = value if not is_hidden else "*" * 5 return hidden_params