Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aws
GitHub Repository: aws/aws-cli
Path: blob/develop/awscli/customizations/cloudformation/package.py
1567 views
1
# Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License"). You
4
# may not use this file except in compliance with the License. A copy of
5
# the License is located at
6
#
7
# http://aws.amazon.com/apache2.0/
8
#
9
# or in the "license" file accompanying this file. This file is
10
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
# ANY KIND, either express or implied. See the License for the specific
12
# language governing permissions and limitations under the License.
13
14
import os
15
import logging
16
import sys
17
18
import json
19
20
from botocore.client import Config
21
22
from awscli.customizations.cloudformation.artifact_exporter import Template
23
from awscli.customizations.cloudformation.yamlhelper import yaml_dump
24
from awscli.customizations.cloudformation import exceptions
25
from awscli.customizations.commands import BasicCommand
26
from awscli.customizations.s3uploader import S3Uploader
27
from awscli.utils import create_nested_client
28
29
LOG = logging.getLogger(__name__)
30
31
32
class PackageCommand(BasicCommand):
33
34
MSG_PACKAGED_TEMPLATE_WRITTEN = (
35
"Successfully packaged artifacts and wrote output template "
36
"to file {output_file_name}."
37
"\n"
38
"Execute the following command to deploy the packaged template"
39
"\n"
40
"aws cloudformation deploy --template-file {output_file_path} "
41
"--stack-name <YOUR STACK NAME>"
42
"\n")
43
44
NAME = "package"
45
46
DESCRIPTION = BasicCommand.FROM_FILE("cloudformation",
47
"_package_description.rst")
48
49
ARG_TABLE = [
50
{
51
'name': 'template-file',
52
'required': True,
53
'help_text': (
54
'The path where your AWS CloudFormation'
55
' template is located.'
56
)
57
},
58
59
{
60
'name': 's3-bucket',
61
'required': True,
62
'help_text': (
63
'The name of the S3 bucket where this command uploads'
64
' the artifacts that are referenced in your template.'
65
)
66
},
67
68
{
69
'name': 's3-prefix',
70
'help_text': (
71
'A prefix name that the command adds to the'
72
' artifacts\' name when it uploads them to the S3 bucket.'
73
' The prefix name is a path name (folder name) for'
74
' the S3 bucket.'
75
)
76
},
77
78
{
79
'name': 'kms-key-id',
80
'help_text': (
81
'The ID of an AWS KMS key that the command uses'
82
' to encrypt artifacts that are at rest in the S3 bucket.'
83
)
84
},
85
86
{
87
"name": "output-template-file",
88
"help_text": (
89
"The path to the file where the command writes the"
90
" output AWS CloudFormation template. If you don't specify"
91
" a path, the command writes the template to the standard"
92
" output."
93
)
94
},
95
96
{
97
"name": "use-json",
98
"action": "store_true",
99
"help_text": (
100
"Indicates whether to use JSON as the format for the output AWS"
101
" CloudFormation template. YAML is used by default."
102
)
103
},
104
105
{
106
"name": "force-upload",
107
"action": "store_true",
108
"help_text": (
109
'Indicates whether to override existing files in the S3 bucket.'
110
' Specify this flag to upload artifacts even if they '
111
' match existing artifacts in the S3 bucket.'
112
)
113
},
114
{
115
"name": "metadata",
116
"cli_type_name": "map",
117
"schema": {
118
"type": "map",
119
"key": {"type": "string"},
120
"value": {"type": "string"}
121
},
122
"help_text": "A map of metadata to attach to *ALL* the artifacts that"
123
" are referenced in your template."
124
}
125
]
126
127
def _run_main(self, parsed_args, parsed_globals):
128
s3_client = create_nested_client(
129
self._session, "s3",
130
config=Config(signature_version='s3v4'),
131
region_name=parsed_globals.region,
132
verify=parsed_globals.verify_ssl)
133
134
template_path = parsed_args.template_file
135
if not os.path.isfile(template_path):
136
raise exceptions.InvalidTemplatePathError(
137
template_path=template_path)
138
139
bucket = parsed_args.s3_bucket
140
141
self.s3_uploader = S3Uploader(s3_client,
142
bucket,
143
parsed_args.s3_prefix,
144
parsed_args.kms_key_id,
145
parsed_args.force_upload)
146
# attach the given metadata to the artifacts to be uploaded
147
self.s3_uploader.artifact_metadata = parsed_args.metadata
148
149
output_file = parsed_args.output_template_file
150
use_json = parsed_args.use_json
151
exported_str = self._export(template_path, use_json)
152
153
sys.stdout.write("\n")
154
self.write_output(output_file, exported_str)
155
156
if output_file:
157
msg = self.MSG_PACKAGED_TEMPLATE_WRITTEN.format(
158
output_file_name=output_file,
159
output_file_path=os.path.abspath(output_file))
160
sys.stdout.write(msg)
161
162
sys.stdout.flush()
163
return 0
164
165
def _export(self, template_path, use_json):
166
template = Template(template_path, os.getcwd(), self.s3_uploader)
167
exported_template = template.export()
168
169
if use_json:
170
exported_str = json.dumps(exported_template, indent=4, ensure_ascii=False)
171
else:
172
exported_str = yaml_dump(exported_template)
173
174
return exported_str
175
176
def write_output(self, output_file_name, data):
177
if output_file_name is None:
178
sys.stdout.write(data)
179
return
180
181
with open(output_file_name, "w") as fp:
182
fp.write(data)
183
184