stackup 0.0.3 → 0.0.4
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/Gemfile.lock +1 -1
- data/lib/stackup/stack.rb +74 -53
- data/pkg/stackup-0.0.3.gem +0 -0
- data/spec/stackup/stack_spec.rb +94 -64
- data/stackup.gemspec +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b28654577f4adc5f14d2021d5d636411175e96fb
|
4
|
+
data.tar.gz: 5f17fcfc2f449abcc5970db182de088b4d56bddb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e5d6ad207e295be6f7f09ae3eea5293c4de81406711b881542f2a3c5c574555f1506597d1e399fda006613683674163aec23a13604f6f983195330eda731c6bf
|
7
|
+
data.tar.gz: 23f066308e4247263aeb87631f801c4be6290903d74c082b859c38d063d6ecb025ac8180d3f2f3488d2d9b2b1ea51a176d0ac9fe0c3fcedc49115e40bcda3d1c
|
data/Gemfile.lock
CHANGED
data/lib/stackup/stack.rb
CHANGED
@@ -1,53 +1,74 @@
|
|
1
|
-
require "set"
|
2
|
-
|
3
|
-
module Stackup
|
4
|
-
class Stack
|
5
|
-
|
6
|
-
attr_reader :stack, :name, :cf, :monitor
|
7
|
-
SUCESS_STATES = ["CREATE_COMPLETE", "UPDATE_COMPLETE"]
|
8
|
-
FAILURE_STATES = ["CREATE_FAILED", "DELETE_COMPLETE", "DELETE_FAILED", "UPDATE_ROLLBACK_FAILED", "ROLLBACK_FAILED", "ROLLBACK_COMPLETE", "ROLLBACK_FAILED", "UPDATE_ROLLBACK_COMPLETE", "UPDATE_ROLLBACK_FAILED"]
|
9
|
-
END_STATES = SUCESS_STATES + FAILURE_STATES
|
10
|
-
|
11
|
-
def initialize(name)
|
12
|
-
@cf = Aws::CloudFormation::Client.new
|
13
|
-
@stack = Aws::CloudFormation::Stack.new(:name => name, :client => cf)
|
14
|
-
@monitor = Stackup::Monitor.new(@stack)
|
15
|
-
@name = name
|
16
|
-
end
|
17
|
-
|
18
|
-
def create(template)
|
19
|
-
response = cf.create_stack(:stack_name => name,
|
20
|
-
:template_body => template,
|
21
|
-
:disable_rollback => true)
|
22
|
-
|
23
|
-
!response[:stack_id].nil?
|
24
|
-
end
|
25
|
-
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
1
|
+
require "set"
|
2
|
+
|
3
|
+
module Stackup
|
4
|
+
class Stack
|
5
|
+
|
6
|
+
attr_reader :stack, :name, :cf, :monitor
|
7
|
+
SUCESS_STATES = ["CREATE_COMPLETE", "UPDATE_COMPLETE"]
|
8
|
+
FAILURE_STATES = ["CREATE_FAILED", "DELETE_COMPLETE", "DELETE_FAILED", "UPDATE_ROLLBACK_FAILED", "ROLLBACK_FAILED", "ROLLBACK_COMPLETE", "ROLLBACK_FAILED", "UPDATE_ROLLBACK_COMPLETE", "UPDATE_ROLLBACK_FAILED"]
|
9
|
+
END_STATES = SUCESS_STATES + FAILURE_STATES
|
10
|
+
|
11
|
+
def initialize(name)
|
12
|
+
@cf = Aws::CloudFormation::Client.new
|
13
|
+
@stack = Aws::CloudFormation::Stack.new(:name => name, :client => cf)
|
14
|
+
@monitor = Stackup::Monitor.new(@stack)
|
15
|
+
@name = name
|
16
|
+
end
|
17
|
+
|
18
|
+
def create(template)
|
19
|
+
response = cf.create_stack(:stack_name => name,
|
20
|
+
:template_body => template,
|
21
|
+
:disable_rollback => true)
|
22
|
+
wait_till_end
|
23
|
+
!response[:stack_id].nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
def deploy(template)
|
27
|
+
if deployed?
|
28
|
+
update(template)
|
29
|
+
else
|
30
|
+
create(template)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def update(template)
|
35
|
+
return false unless deployed?
|
36
|
+
response = cf.update_stack(:stack_name => name, :template_body => template)
|
37
|
+
wait_till_end
|
38
|
+
!response[:stack_id].nil?
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete
|
42
|
+
response = cf.delete_stack(:stack_name => name)
|
43
|
+
stack.wait_until(:max_attempts => 1000, :delay => 10) { |resource| display_events; END_STATES.include?(resource.stack_status) }
|
44
|
+
rescue Aws::CloudFormation::Errors::ValidationError
|
45
|
+
puts "Stack does not exist."
|
46
|
+
end
|
47
|
+
|
48
|
+
def display_events
|
49
|
+
monitor.new_events.each do |e|
|
50
|
+
ts = e.timestamp.localtime.strftime("%H:%M:%S")
|
51
|
+
fields = [e.logical_resource_id, e.resource_status, e.resource_status_reason]
|
52
|
+
puts("[#{ts}] #{fields.compact.join(' - ')}")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def deployed?
|
57
|
+
!stack.stack_status.nil?
|
58
|
+
rescue Aws::CloudFormation::Errors::ValidationError => e
|
59
|
+
false
|
60
|
+
end
|
61
|
+
|
62
|
+
def valid?(template)
|
63
|
+
response = cf.validate_template(template)
|
64
|
+
response[:code].nil?
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def wait_till_end
|
70
|
+
stack.wait_until(:max_attempts => 1000, :delay => 10) { |resource| display_events; END_STATES.include?(resource.stack_status) }
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
Binary file
|
data/spec/stackup/stack_spec.rb
CHANGED
@@ -1,64 +1,94 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Stackup::Stack do
|
4
|
-
let(:stack) { Stackup::Stack.new("stack_name") }
|
5
|
-
let(:template) { double(String) }
|
6
|
-
let(:cf_stack) { double(Aws::CloudFormation::Stack) }
|
7
|
-
let(:cf) { double(Aws::CloudFormation::Client) }
|
8
|
-
|
9
|
-
before do
|
10
|
-
allow(Aws::CloudFormation::Client).to receive(:new).and_return(cf)
|
11
|
-
allow(Aws::CloudFormation::Stack).to receive(:new).and_return(cf_stack)
|
12
|
-
end
|
13
|
-
|
14
|
-
context "
|
15
|
-
|
16
|
-
|
17
|
-
allow(
|
18
|
-
|
19
|
-
expect(stack.
|
20
|
-
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
allow(
|
34
|
-
allow(
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
allow(cf).to receive(:
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
context "
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Stackup::Stack do
|
4
|
+
let(:stack) { Stackup::Stack.new("stack_name") }
|
5
|
+
let(:template) { double(String) }
|
6
|
+
let(:cf_stack) { double(Aws::CloudFormation::Stack) }
|
7
|
+
let(:cf) { double(Aws::CloudFormation::Client) }
|
8
|
+
|
9
|
+
before do
|
10
|
+
allow(Aws::CloudFormation::Client).to receive(:new).and_return(cf)
|
11
|
+
allow(Aws::CloudFormation::Stack).to receive(:new).and_return(cf_stack)
|
12
|
+
end
|
13
|
+
|
14
|
+
context "deploy" do
|
15
|
+
|
16
|
+
it "should call create if stack is not deployed" do
|
17
|
+
allow(stack).to receive(:deployed?).and_return(false)
|
18
|
+
expect(stack).to receive(:create).and_return(true)
|
19
|
+
expect(stack.deploy(template)).to be true
|
20
|
+
end
|
21
|
+
it "should call update if stack is deployed" do
|
22
|
+
allow(stack).to receive(:deployed?).and_return(true)
|
23
|
+
expect(stack).to receive(:update).and_return(true)
|
24
|
+
expect(stack.deploy(template)).to be true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "update" do
|
29
|
+
it "should allow stack update" do
|
30
|
+
allow(cf_stack).to receive(:stack_status).and_return("1")
|
31
|
+
response = Seahorse::Client::Http::Response.new
|
32
|
+
allow(response).to receive(:[]).with(:stack_id).and_return("1")
|
33
|
+
allow(cf).to receive(:update_stack).and_return(response)
|
34
|
+
allow(cf_stack).to receive(:wait_until).and_return(true)
|
35
|
+
expect(stack.update(template)).to be true
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should not update if the stack is not deployed" do
|
39
|
+
allow(cf_stack).to receive(:stack_status).and_raise(Aws::CloudFormation::Errors::ValidationError.new("1", "2"))
|
40
|
+
expect(stack.update(template)).to be false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "delete" do
|
45
|
+
it "should delete the stack if it exists?" do
|
46
|
+
response = double(Struct)
|
47
|
+
allow(cf).to receive(:delete_stack).and_return(response)
|
48
|
+
allow(cf_stack).to receive(:wait_until).and_return(response)
|
49
|
+
expect(stack.delete).to be response
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "create" do
|
54
|
+
let(:response) { Seahorse::Client::Http::Response.new }
|
55
|
+
it "should create stack if all is well" do
|
56
|
+
allow(response).to receive(:[]).with(:stack_id).and_return("1")
|
57
|
+
allow(cf).to receive(:create_stack).and_return(response)
|
58
|
+
allow(cf_stack).to receive(:wait_until).and_return(true)
|
59
|
+
expect(stack.create(template)).to be true
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return nil if stack was not created" do
|
63
|
+
allow(response).to receive(:[]).with(:stack_id).and_return(nil)
|
64
|
+
allow(cf).to receive(:create_stack).and_return(response)
|
65
|
+
allow(cf_stack).to receive(:wait_until).and_return(false)
|
66
|
+
expect(stack.create(template)).to be false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "validate" do
|
71
|
+
it "should be valid if cf validate say so" do
|
72
|
+
allow(cf).to receive(:validate_template).and_return({})
|
73
|
+
expect(stack.valid?(template)).to be true
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should be invalid if cf validate say so" do
|
77
|
+
allow(cf).to receive(:validate_template).and_return(:code => "404")
|
78
|
+
expect(stack.valid?(template)).to be false
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
context "deployed" do
|
84
|
+
it "should be true if it is already deployed" do
|
85
|
+
allow(cf_stack).to receive(:stack_status).and_return("CREATE_COMPLETE")
|
86
|
+
expect(stack.deployed?).to be true
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should be false if it is not deployed" do
|
90
|
+
allow(cf_stack).to receive(:stack_status).and_raise(Aws::CloudFormation::Errors::ValidationError.new("1", "2"))
|
91
|
+
expect(stack.deployed?).to be false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/stackup.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
Gem::Specification.new do |spec|
|
5
5
|
|
6
6
|
spec.name = "stackup"
|
7
|
-
spec.version = "0.0.
|
7
|
+
spec.version = "0.0.4"
|
8
8
|
spec.authors = ["Arvind Kunday", "Mike Williams"]
|
9
9
|
spec.email = ["arvind.kunday@rea-group.com", "mike.williams@rea-group.com"]
|
10
10
|
spec.summary = "Tools for deployment to AWS"
|
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: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arvind Kunday
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-09-
|
12
|
+
date: 2015-09-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- lib/stackup/monitor.rb
|
59
59
|
- lib/stackup/stack.rb
|
60
60
|
- pkg/stackup-0.0.2.gem
|
61
|
+
- pkg/stackup-0.0.3.gem
|
61
62
|
- sample.json
|
62
63
|
- spec/spec_helper.rb
|
63
64
|
- spec/stackup/monitor_spec.rb
|