stackr 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/stackr/cli.rb +116 -0
- data/lib/stackr/cloudformation.rb +100 -2
- data/lib/stackr/errors.rb +4 -2
- data/lib/stackr/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5400276137168449771e71adbdd0c18da5c21e0f
|
4
|
+
data.tar.gz: 59e07af064f309b0b2940ea191514642e6ff71bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db02fba0dbceca816d2ffda2b2ed7aa6ff366210f3737194a7b9a2d7d77b4b30f249ebe97c05d7e0d0a5dc988d308e6d3821c869d3382abac36452da8d1a52f2
|
7
|
+
data.tar.gz: c779134b35dff120b7237b59c431725f5eec360bf1431e02611aa63450e491495252ffec9eb8561c137f986a48a200893faa1fc35ed35e7b3b266dc4d2e457cc
|
data/lib/stackr/cli.rb
CHANGED
@@ -189,5 +189,121 @@ module Stackr
|
|
189
189
|
print_table rows
|
190
190
|
end
|
191
191
|
|
192
|
+
## create-change-set
|
193
|
+
desc 'create-change-set TEMPLATE', 'create a change set'
|
194
|
+
option :change_set_name,
|
195
|
+
aliases: '-c',
|
196
|
+
desc: 'Change set name, defaults to "new-TEMPLATE"'
|
197
|
+
|
198
|
+
option :stack_name,
|
199
|
+
aliases: '-s',
|
200
|
+
desc: 'Stack name, defaults to TEMPLATE'
|
201
|
+
|
202
|
+
def create_change_set(template_name)
|
203
|
+
return if !validate_template(template_name)
|
204
|
+
|
205
|
+
template = load_template(template_name)
|
206
|
+
if !template
|
207
|
+
say "There is no template named \'#{template_name}\'."
|
208
|
+
return
|
209
|
+
end
|
210
|
+
|
211
|
+
change_set_name = options[:change_set_name] || "new-#{template.name}"
|
212
|
+
stack_name = options[:stack_name] || template.name
|
213
|
+
launcher = Stackr::CloudFormation.new
|
214
|
+
say "Creating CloudFormation stack change set #{change_set_name} from template #{template.name} for stack #{stack_name}\n"
|
215
|
+
begin
|
216
|
+
sets = launcher.create_change_set(stack_name, template, change_set_name, options)
|
217
|
+
rescue Stackr::StackMissingError => e
|
218
|
+
say e.message
|
219
|
+
rescue Stackr::StackUpdateNotRequiredError => e
|
220
|
+
say e.message
|
221
|
+
rescue Stackr::InsufficientCapabilitiesError => e
|
222
|
+
say e.message
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
desc 'list-change-sets STACK', 'list all change sets for STACK'
|
228
|
+
def list_change_sets(stack_name)
|
229
|
+
launcher = Stackr::CloudFormation.new
|
230
|
+
begin
|
231
|
+
sets = launcher.list_change_sets(stack_name)
|
232
|
+
rescue Stackr::StackMissingError => e
|
233
|
+
say e.message
|
234
|
+
return
|
235
|
+
end
|
236
|
+
rows = []
|
237
|
+
sets.each do |set|
|
238
|
+
rows << [
|
239
|
+
set.change_set_name,
|
240
|
+
set.creation_time,
|
241
|
+
set.execution_status,
|
242
|
+
set.status
|
243
|
+
]
|
244
|
+
end
|
245
|
+
print_table rows
|
246
|
+
end
|
247
|
+
|
248
|
+
desc 'show-change-set CHANGESET', 'show json details of CHANGESET'
|
249
|
+
option :stack_name,
|
250
|
+
aliases: '-s',
|
251
|
+
desc: 'Stack name, required if CHANGESET is not an ARN'
|
252
|
+
|
253
|
+
def show_change_set(change_set_name)
|
254
|
+
launcher = Stackr::CloudFormation.new
|
255
|
+
stack_name = options[:stack_name]
|
256
|
+
begin
|
257
|
+
set = launcher.show_change_set(change_set_name, stack_name)
|
258
|
+
rescue Stackr::ChangeSetMissingError => e
|
259
|
+
say e.message
|
260
|
+
return
|
261
|
+
rescue Stackr::StackNameMissingError => e
|
262
|
+
say e.message
|
263
|
+
return
|
264
|
+
end
|
265
|
+
require 'json'
|
266
|
+
say JSON.pretty_generate(set)
|
267
|
+
end
|
268
|
+
|
269
|
+
desc 'delete-change-set CHANGESET', 'delete CHANGESET'
|
270
|
+
option :stack_name,
|
271
|
+
aliases: '-s',
|
272
|
+
desc: 'Stack name, required if CHANGESET is not an ARN'
|
273
|
+
|
274
|
+
def delete_change_set(change_set_name)
|
275
|
+
launcher = Stackr::CloudFormation.new
|
276
|
+
stack_name = options[:stack_name]
|
277
|
+
begin
|
278
|
+
launcher.delete_change_set(change_set_name, stack_name)
|
279
|
+
rescue Stackr::ChangeSetMissingError => e
|
280
|
+
say e.message
|
281
|
+
return
|
282
|
+
rescue Stackr::StackNameMissingError => e
|
283
|
+
say e.message
|
284
|
+
return
|
285
|
+
end
|
286
|
+
say "Change set #{change_set_name} deleted."
|
287
|
+
end
|
288
|
+
|
289
|
+
desc 'execute-change-set CHANGESET', 'execute CHANGESET'
|
290
|
+
option :stack_name,
|
291
|
+
aliases: '-s',
|
292
|
+
desc: 'Stack name, required if CHANGESET is not an ARN'
|
293
|
+
|
294
|
+
def execute_change_set(change_set_name)
|
295
|
+
launcher = Stackr::CloudFormation.new
|
296
|
+
stack_name = options[:stack_name]
|
297
|
+
begin
|
298
|
+
launcher.execute_change_set(change_set_name, stack_name)
|
299
|
+
rescue Stackr::ChangeSetMissingError => e
|
300
|
+
say e.message
|
301
|
+
return
|
302
|
+
rescue Stackr::StackNameMissingError => e
|
303
|
+
say e.message
|
304
|
+
return
|
305
|
+
end
|
306
|
+
say "Change set #{change_set_name} executed"
|
307
|
+
end
|
192
308
|
end
|
193
309
|
end
|
@@ -22,7 +22,7 @@ module Stackr
|
|
22
22
|
def upload_to_s3(template_str, name)
|
23
23
|
s3 = Aws::S3::Resource.new
|
24
24
|
if ENV['TEMPLATE_BUCKET'].nil?
|
25
|
-
raise Stackr::
|
25
|
+
raise Stackr::TemplateBucketMissingError, 'Please set TEMPLATE_BUCKET environment variable before uploading templates to S3.'
|
26
26
|
end
|
27
27
|
bucket = s3.bucket(ENV['TEMPLATE_BUCKET'])
|
28
28
|
key = "#{name}.json"
|
@@ -81,7 +81,7 @@ module Stackr
|
|
81
81
|
env_var = template.parameter_map[param_name]
|
82
82
|
|
83
83
|
if param[:default_value].nil? && ENV[env_var].nil?
|
84
|
-
raise Stackr::
|
84
|
+
raise Stackr::ParameterMissingError, "Required parameter #{param_name} (#{env_var}) not specified."
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|
@@ -156,5 +156,103 @@ module Stackr
|
|
156
156
|
cfn = Aws::CloudFormation::Resource.new
|
157
157
|
cfn.stacks
|
158
158
|
end
|
159
|
+
|
160
|
+
# template is a Stackr::Template
|
161
|
+
def create_change_set(stack_name, template, change_set_name, options)
|
162
|
+
cfn = Aws::CloudFormation::Resource.new
|
163
|
+
stack = cfn.stack(stack_name)
|
164
|
+
if !stack
|
165
|
+
raise Stackr::StackMissingError, "Stack #{stack_name} does not exist."
|
166
|
+
end
|
167
|
+
|
168
|
+
opts = {
|
169
|
+
stack_name: stack_name,
|
170
|
+
change_set_name: change_set_name,
|
171
|
+
parameters: stack_parameters(template.parameter_map),
|
172
|
+
capabilities: template.capabilities
|
173
|
+
}
|
174
|
+
|
175
|
+
# are we using template_body or template_url?
|
176
|
+
opts.merge!( template_argument(template) )
|
177
|
+
|
178
|
+
begin
|
179
|
+
# stack.update(opts)
|
180
|
+
resp = cfn.client.create_change_set(opts)
|
181
|
+
rescue Aws::CloudFormation::Errors::ValidationError => e
|
182
|
+
case e.message
|
183
|
+
when 'No updates are to be performed.'
|
184
|
+
raise Stackr::StackUpdateNotRequiredError, "Stack [#{stack_name}] requires no updates."
|
185
|
+
when "Stack [#{stack_name}] does not exist"
|
186
|
+
raise Stackr::StackMissingError, e.message
|
187
|
+
else
|
188
|
+
raise e
|
189
|
+
end
|
190
|
+
rescue Aws::CloudFormation::Errors::InsufficientCapabilitiesException => e
|
191
|
+
raise Stackr::InsufficientCapabilitiesError, "#{e.message}\nPlease add them to your template and run update again."
|
192
|
+
end
|
193
|
+
say "Change set #{change_set_name}, id: #{resp.id}"
|
194
|
+
end
|
195
|
+
|
196
|
+
def list_change_sets(stack_name)
|
197
|
+
cfn = Aws::CloudFormation::Resource.new
|
198
|
+
stack = cfn.stack(stack_name)
|
199
|
+
if !stack
|
200
|
+
raise Stackr::StackMissingError, "Stack #{stack_name} does not exist."
|
201
|
+
end
|
202
|
+
resp = cfn.client.list_change_sets({stack_name: stack_name})
|
203
|
+
return resp.summaries
|
204
|
+
end
|
205
|
+
|
206
|
+
def show_change_set(change_set_name, stack_name)
|
207
|
+
if stack_name.nil? && !change_set_name.start_with?('arn')
|
208
|
+
raise Stackr::StackNameMissingError, "If change_set_name is not an ARN, you must specify stack_name"
|
209
|
+
end
|
210
|
+
|
211
|
+
cfn = Aws::CloudFormation::Client.new
|
212
|
+
opts = {
|
213
|
+
change_set_name: change_set_name,
|
214
|
+
stack_name: stack_name
|
215
|
+
}
|
216
|
+
begin
|
217
|
+
resp = cfn.describe_change_set(opts)
|
218
|
+
rescue Aws::CloudFormation::Errors::ChangeSetNotFound => e
|
219
|
+
raise Stackr::ChangeSetMissingError, e.message
|
220
|
+
end
|
221
|
+
return resp.data
|
222
|
+
end
|
223
|
+
|
224
|
+
def delete_change_set(change_set_name, stack_name)
|
225
|
+
if stack_name.nil? && !change_set_name.start_with?('arn')
|
226
|
+
raise Stackr::StackNameMissingError, "If change_set_name is not an ARN, you must specify stack_name"
|
227
|
+
end
|
228
|
+
|
229
|
+
cfn = Aws::CloudFormation::Client.new
|
230
|
+
opts = {
|
231
|
+
change_set_name: change_set_name,
|
232
|
+
stack_name: stack_name
|
233
|
+
}
|
234
|
+
begin
|
235
|
+
resp = cfn.delete_change_set(opts)
|
236
|
+
rescue Aws::CloudFormation::Errors::ChangeSetNotFound => e
|
237
|
+
raise Stackr::ChangeSetMissingError, e.message
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def execute_change_set(change_set_name, stack_name)
|
242
|
+
if stack_name.nil? && !change_set_name.start_with?('arn')
|
243
|
+
raise Stackr::StackNameMissingError, "If change_set_name is not an ARN, you must specify stack_name"
|
244
|
+
end
|
245
|
+
|
246
|
+
cfn = Aws::CloudFormation::Client.new
|
247
|
+
opts = {
|
248
|
+
change_set_name: change_set_name,
|
249
|
+
stack_name: stack_name
|
250
|
+
}
|
251
|
+
begin
|
252
|
+
cfn.execute_change_set(opts)
|
253
|
+
rescue Aws::CloudFormation::Errors::ChangeSetNotFound => e
|
254
|
+
raise Stackr::ChangeSetMissingError, e.message
|
255
|
+
end
|
256
|
+
end
|
159
257
|
end
|
160
258
|
end
|
data/lib/stackr/errors.rb
CHANGED
@@ -4,7 +4,9 @@ module Stackr
|
|
4
4
|
class StackUpdateNotRequiredError < StandardError; end
|
5
5
|
class InsufficientCapabilitiesError < StandardError; end
|
6
6
|
class TemplateValidationError < StandardError; end
|
7
|
-
class
|
7
|
+
class ParameterMissingError < StandardError; end
|
8
8
|
class TemplateTooBigError < StandardError; end
|
9
|
-
class
|
9
|
+
class TemplateMissingBucketError < StandardError; end
|
10
|
+
class StackNameMissingError < StandardError; end
|
11
|
+
class ChangeSetMissingError < StandardError; end
|
10
12
|
end
|
data/lib/stackr/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stackr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Chalfant
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|