stackup 0.0.5 → 0.0.6

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 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