Path: blob/develop/awscli/customizations/cloudformation/package.py
1567 views
# Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.1#2# Licensed under the Apache License, Version 2.0 (the "License"). You3# may not use this file except in compliance with the License. A copy of4# the License is located at5#6# http://aws.amazon.com/apache2.0/7#8# or in the "license" file accompanying this file. This file is9# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF10# ANY KIND, either express or implied. See the License for the specific11# language governing permissions and limitations under the License.1213import os14import logging15import sys1617import json1819from botocore.client import Config2021from awscli.customizations.cloudformation.artifact_exporter import Template22from awscli.customizations.cloudformation.yamlhelper import yaml_dump23from awscli.customizations.cloudformation import exceptions24from awscli.customizations.commands import BasicCommand25from awscli.customizations.s3uploader import S3Uploader26from awscli.utils import create_nested_client2728LOG = logging.getLogger(__name__)293031class PackageCommand(BasicCommand):3233MSG_PACKAGED_TEMPLATE_WRITTEN = (34"Successfully packaged artifacts and wrote output template "35"to file {output_file_name}."36"\n"37"Execute the following command to deploy the packaged template"38"\n"39"aws cloudformation deploy --template-file {output_file_path} "40"--stack-name <YOUR STACK NAME>"41"\n")4243NAME = "package"4445DESCRIPTION = BasicCommand.FROM_FILE("cloudformation",46"_package_description.rst")4748ARG_TABLE = [49{50'name': 'template-file',51'required': True,52'help_text': (53'The path where your AWS CloudFormation'54' template is located.'55)56},5758{59'name': 's3-bucket',60'required': True,61'help_text': (62'The name of the S3 bucket where this command uploads'63' the artifacts that are referenced in your template.'64)65},6667{68'name': 's3-prefix',69'help_text': (70'A prefix name that the command adds to the'71' artifacts\' name when it uploads them to the S3 bucket.'72' The prefix name is a path name (folder name) for'73' the S3 bucket.'74)75},7677{78'name': 'kms-key-id',79'help_text': (80'The ID of an AWS KMS key that the command uses'81' to encrypt artifacts that are at rest in the S3 bucket.'82)83},8485{86"name": "output-template-file",87"help_text": (88"The path to the file where the command writes the"89" output AWS CloudFormation template. If you don't specify"90" a path, the command writes the template to the standard"91" output."92)93},9495{96"name": "use-json",97"action": "store_true",98"help_text": (99"Indicates whether to use JSON as the format for the output AWS"100" CloudFormation template. YAML is used by default."101)102},103104{105"name": "force-upload",106"action": "store_true",107"help_text": (108'Indicates whether to override existing files in the S3 bucket.'109' Specify this flag to upload artifacts even if they '110' match existing artifacts in the S3 bucket.'111)112},113{114"name": "metadata",115"cli_type_name": "map",116"schema": {117"type": "map",118"key": {"type": "string"},119"value": {"type": "string"}120},121"help_text": "A map of metadata to attach to *ALL* the artifacts that"122" are referenced in your template."123}124]125126def _run_main(self, parsed_args, parsed_globals):127s3_client = create_nested_client(128self._session, "s3",129config=Config(signature_version='s3v4'),130region_name=parsed_globals.region,131verify=parsed_globals.verify_ssl)132133template_path = parsed_args.template_file134if not os.path.isfile(template_path):135raise exceptions.InvalidTemplatePathError(136template_path=template_path)137138bucket = parsed_args.s3_bucket139140self.s3_uploader = S3Uploader(s3_client,141bucket,142parsed_args.s3_prefix,143parsed_args.kms_key_id,144parsed_args.force_upload)145# attach the given metadata to the artifacts to be uploaded146self.s3_uploader.artifact_metadata = parsed_args.metadata147148output_file = parsed_args.output_template_file149use_json = parsed_args.use_json150exported_str = self._export(template_path, use_json)151152sys.stdout.write("\n")153self.write_output(output_file, exported_str)154155if output_file:156msg = self.MSG_PACKAGED_TEMPLATE_WRITTEN.format(157output_file_name=output_file,158output_file_path=os.path.abspath(output_file))159sys.stdout.write(msg)160161sys.stdout.flush()162return 0163164def _export(self, template_path, use_json):165template = Template(template_path, os.getcwd(), self.s3_uploader)166exported_template = template.export()167168if use_json:169exported_str = json.dumps(exported_template, indent=4, ensure_ascii=False)170else:171exported_str = yaml_dump(exported_template)172173return exported_str174175def write_output(self, output_file_name, data):176if output_file_name is None:177sys.stdout.write(data)178return179180with open(output_file_name, "w") as fp:181fp.write(data)182183184