stackup 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3a76fe73e3081eb43b4b664f82ab8018f43d95e0
4
- data.tar.gz: e888b62cdd79ecb05ae03c366b5deadcee497ddb
3
+ metadata.gz: 81fb1c62bb5b074f520f74488f5e030fa6366729
4
+ data.tar.gz: ca1c7d4a8117887dacd2b5a12aeaa2184395301e
5
5
  SHA512:
6
- metadata.gz: 3d3b377393f712fe04de5ec8ce6b9a4527b8a9a1f15cef60c009483b0317d3d317f2ae453e75936e9b48f423644b63fbfa15b7c62f6b7c90ac16044c3bba17b3
7
- data.tar.gz: 6f639914a99aed8803ee9a72cc3055b0f0071e0af561519c848b032d1e3ddb0e025f79ccd5c00eb00321e2ff130148ac98538ff8b5a840d2fcc7b279d60496f8
6
+ metadata.gz: d3734548eb85b676c9092a6a9ac18e191ed50ed8d255431cffaecd80f475e0ee316c0ce3c77269db5138c4b022bc60c43fb088154129ab96d3876b22069a3b34
7
+ data.tar.gz: dfc2b36b8e57da36eadd0f36e4635fec67fa294286d74964141e89f9d6a8b36560a41cb4891777b1fed2f6e619be61d929254e464744c1d3ebd059dc7f847a16
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- stackup (0.0.4)
4
+ stackup (0.0.5)
5
5
  aws-sdk (~> 2.0)
6
6
  clamp (~> 1.0)
7
7
 
@@ -11,18 +11,16 @@ GEM
11
11
  ast (2.1.0)
12
12
  astrolabe (1.3.1)
13
13
  parser (~> 2.2)
14
- aws-sdk (2.1.21)
15
- aws-sdk-resources (= 2.1.21)
16
- aws-sdk-core (2.1.21)
14
+ aws-sdk (2.1.23)
15
+ aws-sdk-resources (= 2.1.23)
16
+ aws-sdk-core (2.1.23)
17
17
  jmespath (~> 1.0)
18
- aws-sdk-resources (2.1.21)
19
- aws-sdk-core (= 2.1.21)
18
+ aws-sdk-resources (2.1.23)
19
+ aws-sdk-core (= 2.1.23)
20
20
  byebug (6.0.2)
21
21
  clamp (1.0.0)
22
22
  diff-lcs (1.2.5)
23
- jmespath (1.0.2)
24
- multi_json (~> 1.0)
25
- multi_json (1.11.2)
23
+ jmespath (1.1.3)
26
24
  parser (2.2.2.6)
27
25
  ast (>= 1.1, < 3.0)
28
26
  powerpack (0.1.1)
data/lib/stackup/cli.rb CHANGED
@@ -1,34 +1,34 @@
1
- module Stackup
2
- class CLI < Clamp::Command
3
-
4
- subcommand ["stack"], "Manage a stack." do
5
- parameter "STACK-NAME", "Name of stack", :attribute_name => :stack_name
6
-
7
- subcommand "deploy", "Create/update the stack" do
8
- parameter "TEMPLATE", "CloudFormation template (.json)", :attribute_name => :template
9
- parameter "PARAMETERS", "CloudFormation parameters (.json)", :attribute_name => :parameters
10
-
11
- def execute
12
- params = JSON.parse(parameters)
13
- stack = Stackup::Stack.new(stack_name)
14
- stack.create(template, params)
15
- end
16
- end
17
-
18
- subcommand "delete", "Remove the stack." do
19
- def execute
20
- stack = Stackup::Stack.new(stack_name)
21
- stack.delete
22
- end
23
- end
24
-
25
- subcommand "outputs", "Stack outputs." do
26
- def execute
27
- stack = Stackup::Stack.new(stack_name)
28
- stack.outputs
29
- end
30
- end
31
- end
32
-
33
- end
34
- end
1
+ module Stackup
2
+ class CLI < Clamp::Command
3
+
4
+ subcommand ["stack"], "Manage a stack." do
5
+ parameter "STACK-NAME", "Name of stack", :attribute_name => :stack_name
6
+
7
+ subcommand "deploy", "Create/update the stack" do
8
+ parameter "TEMPLATE", "CloudFormation template (.json)", :attribute_name => :template
9
+ parameter "PARAMETERS", "CloudFormation parameters (.json)", :attribute_name => :parameters
10
+
11
+ def execute
12
+ params = JSON.parse(parameters)
13
+ stack = Stackup::Stack.new(stack_name)
14
+ stack.create(template, params)
15
+ end
16
+ end
17
+
18
+ subcommand "delete", "Remove the stack." do
19
+ def execute
20
+ stack = Stackup::Stack.new(stack_name)
21
+ stack.delete
22
+ end
23
+ end
24
+
25
+ subcommand "outputs", "Stack outputs." do
26
+ def execute
27
+ stack = Stackup::Stack.new(stack_name)
28
+ stack.outputs
29
+ end
30
+ end
31
+ end
32
+
33
+ end
34
+ end
data/lib/stackup/stack.rb CHANGED
@@ -1,81 +1,82 @@
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, parameters)
19
- response = cf.create_stack(:stack_name => name,
20
- :template_body => template,
21
- :disable_rollback => true,
22
- :parameters => parameters)
23
- wait_till_end
24
- !response[:stack_id].nil?
25
- end
26
-
27
- def deploy(template, parameters = [])
28
- if deployed?
29
- update(template, parameters)
30
- else
31
- create(template, parameters)
32
- end
33
- rescue Aws::CloudFormation::Errors::ValidationError => e
34
- puts e.message
35
- end
36
-
37
- def update(template, parameters)
38
- return false unless deployed?
39
- response = cf.update_stack(:stack_name => name, :template_body => template, :parameters => parameters)
40
- wait_till_end
41
- !response[:stack_id].nil?
42
- end
43
-
44
- def delete
45
- response = cf.delete_stack(:stack_name => name)
46
- stack.wait_until(:max_attempts => 1000, :delay => 10) { |resource| display_events; END_STATES.include?(resource.stack_status) }
47
- rescue Aws::CloudFormation::Errors::ValidationError
48
- puts "Stack does not exist."
49
- end
50
-
51
- def outputs
52
- puts stack.outputs.flat_map { |output| "#{output.output_key} - #{output.output_value}" }
53
- end
54
-
55
- def display_events
56
- monitor.new_events.each do |e|
57
- ts = e.timestamp.localtime.strftime("%H:%M:%S")
58
- fields = [e.logical_resource_id, e.resource_status, e.resource_status_reason]
59
- puts("[#{ts}] #{fields.compact.join(' - ')}")
60
- end
61
- end
62
-
63
- def deployed?
64
- !stack.stack_status.nil?
65
- rescue Aws::CloudFormation::Errors::ValidationError => e
66
- false
67
- end
68
-
69
- def valid?(template)
70
- response = cf.validate_template(template)
71
- response[:code].nil?
72
- end
73
-
74
- private
75
-
76
- def wait_till_end
77
- stack.wait_until(:max_attempts => 1000, :delay => 10) { |resource| display_events; END_STATES.include?(resource.stack_status) }
78
- end
79
-
80
- end
81
- 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, parameters)
19
+ response = cf.create_stack(:stack_name => name,
20
+ :template_body => template,
21
+ :disable_rollback => true,
22
+ :capabilities => ["CAPABILITY_IAM"],
23
+ :parameters => parameters)
24
+ wait_till_end
25
+ !response[:stack_id].nil?
26
+ end
27
+
28
+ def deploy(template, parameters = [])
29
+ if deployed?
30
+ update(template, parameters)
31
+ else
32
+ create(template, parameters)
33
+ end
34
+ rescue Aws::CloudFormation::Errors::ValidationError => e
35
+ puts e.message
36
+ end
37
+
38
+ def update(template, parameters)
39
+ return false unless deployed?
40
+ response = cf.update_stack(:stack_name => name, :template_body => template, :parameters => parameters, :capabilities => ["CAPABILITY_IAM"])
41
+ wait_till_end
42
+ !response[:stack_id].nil?
43
+ end
44
+
45
+ def delete
46
+ response = cf.delete_stack(:stack_name => name)
47
+ stack.wait_until(:max_attempts => 1000, :delay => 10) { |resource| display_events; END_STATES.include?(resource.stack_status) }
48
+ rescue Aws::CloudFormation::Errors::ValidationError
49
+ puts "Stack does not exist."
50
+ end
51
+
52
+ def outputs
53
+ puts stack.outputs.flat_map { |output| "#{output.output_key} - #{output.output_value}" }
54
+ end
55
+
56
+ def display_events
57
+ monitor.new_events.each do |e|
58
+ ts = e.timestamp.localtime.strftime("%H:%M:%S")
59
+ fields = [e.logical_resource_id, e.resource_status, e.resource_status_reason]
60
+ puts("[#{ts}] #{fields.compact.join(' - ')}")
61
+ end
62
+ end
63
+
64
+ def deployed?
65
+ !stack.stack_status.nil?
66
+ rescue Aws::CloudFormation::Errors::ValidationError => e
67
+ false
68
+ end
69
+
70
+ def valid?(template)
71
+ response = cf.validate_template(template)
72
+ response[:code].nil?
73
+ end
74
+
75
+ private
76
+
77
+ def wait_till_end
78
+ stack.wait_until(:max_attempts => 1000, :delay => 10) { |resource| display_events; END_STATES.include?(resource.stack_status) }
79
+ end
80
+
81
+ end
82
+ end
Binary file
Binary file
@@ -1,95 +1,95 @@
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
- let(:parameters) { [] }
9
-
10
- before do
11
- allow(Aws::CloudFormation::Client).to receive(:new).and_return(cf)
12
- allow(Aws::CloudFormation::Stack).to receive(:new).and_return(cf_stack)
13
- end
14
-
15
- context "deploy" do
16
-
17
- it "should call create if stack is not deployed" do
18
- allow(stack).to receive(:deployed?).and_return(false)
19
- expect(stack).to receive(:create).and_return(true)
20
- expect(stack.deploy(template, parameters)).to be true
21
- end
22
- it "should call update if stack is deployed" do
23
- allow(stack).to receive(:deployed?).and_return(true)
24
- expect(stack).to receive(:update).and_return(true)
25
- expect(stack.deploy(template, parameters)).to be true
26
- end
27
- end
28
-
29
- context "update" do
30
- it "should allow stack update" do
31
- allow(cf_stack).to receive(:stack_status).and_return("1")
32
- response = Seahorse::Client::Http::Response.new
33
- allow(response).to receive(:[]).with(:stack_id).and_return("1")
34
- allow(cf).to receive(:update_stack).and_return(response)
35
- allow(cf_stack).to receive(:wait_until).and_return(true)
36
- expect(stack.update(template, parameters)).to be true
37
- end
38
-
39
- it "should not update if the stack is not deployed" do
40
- allow(cf_stack).to receive(:stack_status).and_raise(Aws::CloudFormation::Errors::ValidationError.new("1", "2"))
41
- expect(stack.update(template, parameters)).to be false
42
- end
43
- end
44
-
45
- context "delete" do
46
- it "should delete the stack if it exists?" do
47
- response = double(Struct)
48
- allow(cf).to receive(:delete_stack).and_return(response)
49
- allow(cf_stack).to receive(:wait_until).and_return(response)
50
- expect(stack.delete).to be response
51
- end
52
- end
53
-
54
- context "create" do
55
- let(:response) { Seahorse::Client::Http::Response.new }
56
- it "should create stack if all is well" do
57
- allow(response).to receive(:[]).with(:stack_id).and_return("1")
58
- allow(cf).to receive(:create_stack).and_return(response)
59
- allow(cf_stack).to receive(:wait_until).and_return(true)
60
- expect(stack.create(template, parameters)).to be true
61
- end
62
-
63
- it "should return nil if stack was not created" do
64
- allow(response).to receive(:[]).with(:stack_id).and_return(nil)
65
- allow(cf).to receive(:create_stack).and_return(response)
66
- allow(cf_stack).to receive(:wait_until).and_return(false)
67
- expect(stack.create(template, parameters)).to be false
68
- end
69
- end
70
-
71
- context "validate" do
72
- it "should be valid if cf validate say so" do
73
- allow(cf).to receive(:validate_template).and_return({})
74
- expect(stack.valid?(template)).to be true
75
- end
76
-
77
- it "should be invalid if cf validate say so" do
78
- allow(cf).to receive(:validate_template).and_return(:code => "404")
79
- expect(stack.valid?(template)).to be false
80
- end
81
-
82
- end
83
-
84
- context "deployed" do
85
- it "should be true if it is already deployed" do
86
- allow(cf_stack).to receive(:stack_status).and_return("CREATE_COMPLETE")
87
- expect(stack.deployed?).to be true
88
- end
89
-
90
- it "should be false if it is not deployed" do
91
- allow(cf_stack).to receive(:stack_status).and_raise(Aws::CloudFormation::Errors::ValidationError.new("1", "2"))
92
- expect(stack.deployed?).to be false
93
- end
94
- end
95
- end
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
+ let(:parameters) { [] }
9
+
10
+ before do
11
+ allow(Aws::CloudFormation::Client).to receive(:new).and_return(cf)
12
+ allow(Aws::CloudFormation::Stack).to receive(:new).and_return(cf_stack)
13
+ end
14
+
15
+ context "deploy" do
16
+
17
+ it "should call create if stack is not deployed" do
18
+ allow(stack).to receive(:deployed?).and_return(false)
19
+ expect(stack).to receive(:create).and_return(true)
20
+ expect(stack.deploy(template, parameters)).to be true
21
+ end
22
+ it "should call update if stack is deployed" do
23
+ allow(stack).to receive(:deployed?).and_return(true)
24
+ expect(stack).to receive(:update).and_return(true)
25
+ expect(stack.deploy(template, parameters)).to be true
26
+ end
27
+ end
28
+
29
+ context "update" do
30
+ it "should allow stack update" do
31
+ allow(cf_stack).to receive(:stack_status).and_return("1")
32
+ response = Seahorse::Client::Http::Response.new
33
+ allow(response).to receive(:[]).with(:stack_id).and_return("1")
34
+ allow(cf).to receive(:update_stack).and_return(response)
35
+ allow(cf_stack).to receive(:wait_until).and_return(true)
36
+ expect(stack.update(template, parameters)).to be true
37
+ end
38
+
39
+ it "should not update if the stack is not deployed" do
40
+ allow(cf_stack).to receive(:stack_status).and_raise(Aws::CloudFormation::Errors::ValidationError.new("1", "2"))
41
+ expect(stack.update(template, parameters)).to be false
42
+ end
43
+ end
44
+
45
+ context "delete" do
46
+ it "should delete the stack if it exists?" do
47
+ response = double(Struct)
48
+ allow(cf).to receive(:delete_stack).and_return(response)
49
+ allow(cf_stack).to receive(:wait_until).and_return(response)
50
+ expect(stack.delete).to be response
51
+ end
52
+ end
53
+
54
+ context "create" do
55
+ let(:response) { Seahorse::Client::Http::Response.new }
56
+ it "should create stack if all is well" do
57
+ allow(response).to receive(:[]).with(:stack_id).and_return("1")
58
+ allow(cf).to receive(:create_stack).and_return(response)
59
+ allow(cf_stack).to receive(:wait_until).and_return(true)
60
+ expect(stack.create(template, parameters)).to be true
61
+ end
62
+
63
+ it "should return nil if stack was not created" do
64
+ allow(response).to receive(:[]).with(:stack_id).and_return(nil)
65
+ allow(cf).to receive(:create_stack).and_return(response)
66
+ allow(cf_stack).to receive(:wait_until).and_return(false)
67
+ expect(stack.create(template, parameters)).to be false
68
+ end
69
+ end
70
+
71
+ context "validate" do
72
+ it "should be valid if cf validate say so" do
73
+ allow(cf).to receive(:validate_template).and_return({})
74
+ expect(stack.valid?(template)).to be true
75
+ end
76
+
77
+ it "should be invalid if cf validate say so" do
78
+ allow(cf).to receive(:validate_template).and_return(:code => "404")
79
+ expect(stack.valid?(template)).to be false
80
+ end
81
+
82
+ end
83
+
84
+ context "deployed" do
85
+ it "should be true if it is already deployed" do
86
+ allow(cf_stack).to receive(:stack_status).and_return("CREATE_COMPLETE")
87
+ expect(stack.deployed?).to be true
88
+ end
89
+
90
+ it "should be false if it is not deployed" do
91
+ allow(cf_stack).to receive(:stack_status).and_raise(Aws::CloudFormation::Errors::ValidationError.new("1", "2"))
92
+ expect(stack.deployed?).to be false
93
+ end
94
+ end
95
+ end
data/stackup.gemspec CHANGED
@@ -1,21 +1,21 @@
1
- lib = File.expand_path("../lib", __FILE__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
-
4
- Gem::Specification.new do |spec|
5
-
6
- spec.name = "stackup"
7
- spec.version = "0.0.5"
8
- spec.authors = ["Arvind Kunday", "Mike Williams"]
9
- spec.email = ["arvind.kunday@rea-group.com", "mike.williams@rea-group.com"]
10
- spec.summary = "Tools for deployment to AWS"
11
- spec.homepage = "https://github.com/realestate-com-au/stackup"
12
- spec.license = "MIT"
13
-
14
- spec.files = Dir["**/*"].reject { |f| File.directory?(f) }
15
- spec.executables = spec.files.grep(/^bin/) { |f| File.basename(f) }
16
- spec.require_paths = ["lib"]
17
-
18
- spec.add_dependency "aws-sdk", "~> 2.0"
19
- spec.add_dependency "clamp", "~> 1.0"
20
-
21
- end
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ Gem::Specification.new do |spec|
5
+
6
+ spec.name = "stackup"
7
+ spec.version = "0.0.6"
8
+ spec.authors = ["Arvind Kunday", "Mike Williams"]
9
+ spec.email = ["arvind.kunday@rea-group.com", "mike.williams@rea-group.com"]
10
+ spec.summary = "Tools for deployment to AWS"
11
+ spec.homepage = "https://github.com/realestate-com-au/stackup"
12
+ spec.license = "MIT"
13
+
14
+ spec.files = Dir["**/*"].reject { |f| File.directory?(f) }
15
+ spec.executables = spec.files.grep(/^bin/) { |f| File.basename(f) }
16
+ spec.require_paths = ["lib"]
17
+
18
+ spec.add_dependency "aws-sdk", "~> 2.0"
19
+ spec.add_dependency "clamp", "~> 1.0"
20
+
21
+ end
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.5
4
+ version: 0.0.6
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-24 00:00:00.000000000 Z
12
+ date: 2015-09-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aws-sdk
@@ -61,6 +61,7 @@ files:
61
61
  - pkg/stackup-0.0.3.gem
62
62
  - pkg/stackup-0.0.4.gem
63
63
  - pkg/stackup-0.0.5.gem
64
+ - pkg/stackup-0.0.6.gem
64
65
  - sample.json
65
66
  - spec/spec_helper.rb
66
67
  - spec/stackup/monitor_spec.rb