stackup 1.4.5 → 1.7.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/CHANGES.md +20 -0
- data/README.md +39 -7
- data/bin/stackup +2 -535
- data/lib/stackup/change_set.rb +10 -2
- data/lib/stackup/main_command.rb +561 -0
- data/lib/stackup/source.rb +1 -1
- data/lib/stackup/stack.rb +19 -8
- data/lib/stackup/version.rb +1 -1
- data/spec/stackup/main_command_spec.rb +56 -0
- data/spec/stackup/rake_tasks_spec.rb +3 -3
- data/spec/stackup/source_spec.rb +10 -0
- data/spec/stackup/stack_spec.rb +69 -0
- metadata +5 -2
data/lib/stackup/source.rb
CHANGED
data/lib/stackup/stack.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "aws-sdk-cloudformation"
|
2
4
|
require "logger"
|
3
5
|
require "multi_json"
|
@@ -16,10 +18,10 @@ module Stackup
|
|
16
18
|
DEFAULT_WAIT_POLL_INTERVAL = 5 # seconds
|
17
19
|
|
18
20
|
def initialize(name, client = {}, options = {})
|
19
|
-
client
|
20
|
-
@name
|
21
|
+
client = Aws::CloudFormation::Client.new(client) if client.is_a?(Hash)
|
22
|
+
@name = name
|
21
23
|
@cf_client = client
|
22
|
-
@wait
|
24
|
+
@wait = true
|
23
25
|
options.each do |key, value|
|
24
26
|
public_send("#{key}=", value)
|
25
27
|
end
|
@@ -117,6 +119,9 @@ module Stackup
|
|
117
119
|
if (template_data = options.delete(:template))
|
118
120
|
options[:template_body] = MultiJson.dump(template_data)
|
119
121
|
end
|
122
|
+
# optionally override template_body with the original template to preserve formatting (& comments in YAML)
|
123
|
+
template_orig = options.delete(:template_orig)
|
124
|
+
options[:template_body] = template_orig if options.delete(:preserve)
|
120
125
|
if (parameters = options[:parameters])
|
121
126
|
options[:parameters] = Parameters.new(parameters).to_a
|
122
127
|
end
|
@@ -282,7 +287,7 @@ module Stackup
|
|
282
287
|
end
|
283
288
|
|
284
289
|
def create(options)
|
285
|
-
options
|
290
|
+
options = options.dup
|
286
291
|
options[:stack_name] = name
|
287
292
|
options.delete(:stack_policy_during_update_body)
|
288
293
|
options.delete(:stack_policy_during_update_url)
|
@@ -312,7 +317,7 @@ module Stackup
|
|
312
317
|
def event_handler
|
313
318
|
@event_handler ||= lambda do |e|
|
314
319
|
fields = [e.logical_resource_id, e.resource_status, e.resource_status_reason]
|
315
|
-
time
|
320
|
+
time = e.timestamp.localtime.strftime("%H:%M:%S")
|
316
321
|
logger.info("[#{time}] #{fields.compact.join(' - ')}")
|
317
322
|
end
|
318
323
|
end
|
@@ -369,7 +374,13 @@ module Stackup
|
|
369
374
|
{ :key => key, :value => value.to_s }
|
370
375
|
end
|
371
376
|
else
|
372
|
-
tags
|
377
|
+
tags.map do |tag|
|
378
|
+
if tag.key?("Key")
|
379
|
+
{ :key => tag["Key"], :value => tag["Value"].to_s }
|
380
|
+
else
|
381
|
+
{ :key => tag[:key], :value => tag[:value].to_s }
|
382
|
+
end
|
383
|
+
end
|
373
384
|
end
|
374
385
|
end
|
375
386
|
|
@@ -384,8 +395,8 @@ module Stackup
|
|
384
395
|
handling_cf_errors do
|
385
396
|
{}.tap do |result|
|
386
397
|
cf_stack.public_send(collection_name).each do |item|
|
387
|
-
key
|
388
|
-
value
|
398
|
+
key = item.public_send(key_name)
|
399
|
+
value = item.public_send(value_name)
|
389
400
|
result[key] = value
|
390
401
|
end
|
391
402
|
end
|
data/lib/stackup/version.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
require "stackup/main_command"
|
2
|
+
|
3
|
+
describe Stackup::MainCommand do
|
4
|
+
|
5
|
+
let(:mock_change_set) { double() }
|
6
|
+
|
7
|
+
before(:example) do
|
8
|
+
mock_stackup = double()
|
9
|
+
mock_stack = double()
|
10
|
+
allow_any_instance_of(Stackup::MainCommand).to receive(:Stackup).and_return(mock_stackup)
|
11
|
+
allow(mock_stackup).to receive(:stack).and_return(mock_stack)
|
12
|
+
allow(mock_stack).to receive(:change_set).and_return(mock_change_set)
|
13
|
+
end
|
14
|
+
|
15
|
+
context "change-set create --service-role-arn" do
|
16
|
+
it "invokes stack.change_set.create with role arn passed through" do
|
17
|
+
expected_args = {
|
18
|
+
role_arn: "arn:aws:iam::000000000000:role/example"
|
19
|
+
}
|
20
|
+
expect(mock_change_set).to receive(:create).with(hash_including(expected_args))
|
21
|
+
|
22
|
+
Stackup::MainCommand.run("stackup", [
|
23
|
+
"STACK-NAME", "change-set", "create",
|
24
|
+
"--template", "examples/template.yml",
|
25
|
+
"--service-role-arn", "arn:aws:iam::000000000000:role/example"])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "change-set create" do
|
30
|
+
it "invokes stack.change_set.create with allow_empty_change_set nil" do
|
31
|
+
expected_args = {
|
32
|
+
allow_empty_change_set: nil
|
33
|
+
}
|
34
|
+
expect(mock_change_set).to receive(:create).with(hash_including(expected_args))
|
35
|
+
|
36
|
+
Stackup::MainCommand.run("stackup", [
|
37
|
+
"STACK-NAME", "change-set", "create",
|
38
|
+
"--template", "examples/template.yml"])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "change-set create --no-fail-on-empty-change-set" do
|
43
|
+
it "invokes stack.change_set.create with allow_empty_change_set true" do
|
44
|
+
expected_args = {
|
45
|
+
allow_empty_change_set: true
|
46
|
+
}
|
47
|
+
expect(mock_change_set).to receive(:create).with(hash_including(expected_args))
|
48
|
+
|
49
|
+
Stackup::MainCommand.run("stackup", [
|
50
|
+
"STACK-NAME", "change-set", "create",
|
51
|
+
"--template", "examples/template.yml",
|
52
|
+
"--no-fail-on-empty-change-set"])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/spec/stackup/source_spec.rb
CHANGED
@@ -124,6 +124,16 @@ describe Stackup::Source do
|
|
124
124
|
|
125
125
|
end
|
126
126
|
|
127
|
+
context "with dot separated bucket and region" do
|
128
|
+
|
129
|
+
let(:s3_url) { "https://bucket.s3.us-east-1.amazonaws.com/cfn/template.yml" }
|
130
|
+
|
131
|
+
it "is S3" do
|
132
|
+
expect(subject).to be_s3
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
127
137
|
end
|
128
138
|
|
129
139
|
end
|
data/spec/stackup/stack_spec.rb
CHANGED
@@ -260,6 +260,26 @@ describe Stackup::Stack do
|
|
260
260
|
|
261
261
|
end
|
262
262
|
|
263
|
+
context "with :tags in SDK form as they arrive from file" do
|
264
|
+
|
265
|
+
before do
|
266
|
+
options[:tags] = [
|
267
|
+
{ "Key" => "foo", "Value" => "bar" }
|
268
|
+
]
|
269
|
+
end
|
270
|
+
|
271
|
+
it "converts them to an Array, that uses symbols as keys" do
|
272
|
+
expected_tags = [
|
273
|
+
{ :key => "foo", :value => "bar" }
|
274
|
+
]
|
275
|
+
create_or_update
|
276
|
+
expect(cf_client).to have_received(:create_stack) do |options|
|
277
|
+
expect(options[:tags]).to eq(expected_tags)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
end
|
282
|
+
|
263
283
|
context "with :tags in SDK form" do
|
264
284
|
|
265
285
|
before do
|
@@ -322,6 +342,23 @@ describe Stackup::Stack do
|
|
322
342
|
.with(hash_including(expected_args))
|
323
343
|
end
|
324
344
|
|
345
|
+
it "passes options through to :create_change_set" do
|
346
|
+
options = {
|
347
|
+
:template_body => template,
|
348
|
+
:role_arn => "service role arn"
|
349
|
+
}
|
350
|
+
expected_args = {
|
351
|
+
:stack_name => stack_name,
|
352
|
+
:change_set_name => change_set_name,
|
353
|
+
:change_set_type => "CREATE",
|
354
|
+
:template_body => template,
|
355
|
+
:role_arn => "service role arn"
|
356
|
+
}
|
357
|
+
stack.change_set(change_set_name).create(options)
|
358
|
+
expect(cf_client).to have_received(:create_change_set)
|
359
|
+
.with(hash_including(expected_args))
|
360
|
+
end
|
361
|
+
|
325
362
|
context "with :template as data" do
|
326
363
|
|
327
364
|
let(:options) do
|
@@ -392,6 +429,38 @@ describe Stackup::Stack do
|
|
392
429
|
|
393
430
|
end
|
394
431
|
|
432
|
+
context "when allow_empty_change_set is nil and there are no changes" do
|
433
|
+
it "raises an exception" do
|
434
|
+
cf_client.stub_responses(:describe_change_set, [{
|
435
|
+
status: "FAILED",
|
436
|
+
status_reason: "The submitted information didn't contain changes. Submit different information to create a change set."
|
437
|
+
}])
|
438
|
+
expect { create_change_set }.to raise_error(Stackup::StackUpdateError)
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
context "when allow_empty_change_set is true and there are no changes" do
|
443
|
+
it "does not raise an exception" do
|
444
|
+
cf_client.stub_responses(:describe_change_set, [{
|
445
|
+
status: "FAILED",
|
446
|
+
status_reason: "The submitted information didn't contain changes. Submit different information to create a change set."
|
447
|
+
}])
|
448
|
+
options[:allow_empty_change_set] = true
|
449
|
+
expect { create_change_set }.not_to raise_error
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
context "when allow_empty_change_set is true and there is some other failure" do
|
454
|
+
it "raises an exception" do
|
455
|
+
cf_client.stub_responses(:describe_change_set, [{
|
456
|
+
status: "FAILED",
|
457
|
+
status_reason: "some other failure message"
|
458
|
+
}])
|
459
|
+
options[:allow_empty_change_set] = true
|
460
|
+
expect { create_change_set }.to raise_error(Stackup::StackUpdateError)
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
395
464
|
end
|
396
465
|
|
397
466
|
describe "#change_set#execute" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stackup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Williams
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-11-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk-cloudformation
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- lib/stackup/differ.rb
|
100
100
|
- lib/stackup/error_handling.rb
|
101
101
|
- lib/stackup/errors.rb
|
102
|
+
- lib/stackup/main_command.rb
|
102
103
|
- lib/stackup/parameters.rb
|
103
104
|
- lib/stackup/rake_tasks.rb
|
104
105
|
- lib/stackup/service.rb
|
@@ -109,6 +110,7 @@ files:
|
|
109
110
|
- lib/stackup/version.rb
|
110
111
|
- lib/stackup/yaml.rb
|
111
112
|
- spec/spec_helper.rb
|
113
|
+
- spec/stackup/main_command_spec.rb
|
112
114
|
- spec/stackup/parameters_spec.rb
|
113
115
|
- spec/stackup/rake_tasks_spec.rb
|
114
116
|
- spec/stackup/source_spec.rb
|
@@ -141,6 +143,7 @@ specification_version: 4
|
|
141
143
|
summary: Manage CloudFormation stacks
|
142
144
|
test_files:
|
143
145
|
- spec/spec_helper.rb
|
146
|
+
- spec/stackup/main_command_spec.rb
|
144
147
|
- spec/stackup/parameters_spec.rb
|
145
148
|
- spec/stackup/rake_tasks_spec.rb
|
146
149
|
- spec/stackup/source_spec.rb
|