cf_deployer 1.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +29 -0
  3. data/ChangeLog.md +16 -0
  4. data/DETAILS.md +268 -0
  5. data/FAQ.md +61 -0
  6. data/Gemfile +10 -0
  7. data/Gemfile.lock +51 -0
  8. data/LICENSE +22 -0
  9. data/QUICKSTART.md +96 -0
  10. data/README.md +36 -0
  11. data/Rakefile +32 -0
  12. data/bin/cf_deploy +10 -0
  13. data/cf_deployer.gemspec +23 -0
  14. data/lib/cf_deployer/application.rb +74 -0
  15. data/lib/cf_deployer/application_error.rb +4 -0
  16. data/lib/cf_deployer/aws_constants.rb +3 -0
  17. data/lib/cf_deployer/cli.rb +111 -0
  18. data/lib/cf_deployer/component.rb +103 -0
  19. data/lib/cf_deployer/config_loader.rb +189 -0
  20. data/lib/cf_deployer/config_validation.rb +138 -0
  21. data/lib/cf_deployer/defaults.rb +10 -0
  22. data/lib/cf_deployer/deployment_strategy/auto_scaling_group_swap.rb +102 -0
  23. data/lib/cf_deployer/deployment_strategy/base.rb +88 -0
  24. data/lib/cf_deployer/deployment_strategy/blue_green.rb +70 -0
  25. data/lib/cf_deployer/deployment_strategy/cname_swap.rb +108 -0
  26. data/lib/cf_deployer/deployment_strategy/create_or_update.rb +57 -0
  27. data/lib/cf_deployer/driver/auto_scaling_group.rb +86 -0
  28. data/lib/cf_deployer/driver/cloud_formation_driver.rb +85 -0
  29. data/lib/cf_deployer/driver/dry_run.rb +27 -0
  30. data/lib/cf_deployer/driver/elb_driver.rb +17 -0
  31. data/lib/cf_deployer/driver/instance.rb +29 -0
  32. data/lib/cf_deployer/driver/route53_driver.rb +79 -0
  33. data/lib/cf_deployer/driver/verisign_driver.rb +21 -0
  34. data/lib/cf_deployer/hook.rb +32 -0
  35. data/lib/cf_deployer/logger.rb +34 -0
  36. data/lib/cf_deployer/stack.rb +154 -0
  37. data/lib/cf_deployer/status_presenter.rb +195 -0
  38. data/lib/cf_deployer/version.rb +3 -0
  39. data/lib/cf_deployer.rb +97 -0
  40. data/spec/fakes/instance.rb +32 -0
  41. data/spec/fakes/route53_client.rb +23 -0
  42. data/spec/fakes/stack.rb +65 -0
  43. data/spec/functional/deploy_spec.rb +73 -0
  44. data/spec/functional/kill_inactive_spec.rb +57 -0
  45. data/spec/functional_spec_helper.rb +3 -0
  46. data/spec/spec_helper.rb +8 -0
  47. data/spec/unit/application_spec.rb +191 -0
  48. data/spec/unit/component_spec.rb +142 -0
  49. data/spec/unit/config_loader_spec.rb +356 -0
  50. data/spec/unit/config_validation_spec.rb +480 -0
  51. data/spec/unit/deployment_strategy/auto_scaling_group_swap_spec.rb +435 -0
  52. data/spec/unit/deployment_strategy/base_spec.rb +44 -0
  53. data/spec/unit/deployment_strategy/cname_swap_spec.rb +294 -0
  54. data/spec/unit/deployment_strategy/create_or_update_spec.rb +113 -0
  55. data/spec/unit/deployment_strategy/deployment_strategy_spec.rb +29 -0
  56. data/spec/unit/driver/auto_scaling_group_spec.rb +127 -0
  57. data/spec/unit/driver/cloud_formation_spec.rb +32 -0
  58. data/spec/unit/driver/elb_spec.rb +11 -0
  59. data/spec/unit/driver/instance_spec.rb +30 -0
  60. data/spec/unit/driver/route53_spec.rb +85 -0
  61. data/spec/unit/driver/verisign_spec.rb +18 -0
  62. data/spec/unit/hook_spec.rb +64 -0
  63. data/spec/unit/stack_spec.rb +150 -0
  64. data/spec/unit/status_presenter_spec.rb +108 -0
  65. metadata +197 -0
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe CfDeployer::Driver::Route53 do
4
+ subject { CfDeployer::Driver::Route53.new }
5
+
6
+ describe ".find_alias_target" do
7
+ it "should raise an error when the target zone cannot be found" do
8
+ route53 = double('route53')
9
+ allow(AWS::Route53).to receive(:new) { route53 }
10
+
11
+ allow(route53).to receive(:hosted_zones) { [] }
12
+
13
+ expect { subject.find_alias_target('abc.com', 'foo') }.to raise_error('Target zone not found!')
14
+ end
15
+
16
+ it "should get empty alias target when the target host cannot be found" do
17
+ zone = double('zone')
18
+ allow(zone).to receive(:name) { 'target.com.' }
19
+ allow(zone).to receive(:resource_record_sets) { [] }
20
+
21
+ route53 = double('route53')
22
+ allow(AWS::Route53).to receive(:new) { route53 }
23
+ allow(route53).to receive(:hosted_zones) { [zone] }
24
+
25
+ subject.find_alias_target('target.com', 'foo').should be_nil
26
+ end
27
+
28
+ it "should get alias target" do
29
+ host = double('host', :name => 'foo.target.com.', :alias_target => { :dns_name => 'abc.com.'})
30
+ zone = double('zone', :name => 'target.com.', :resource_record_sets => [host])
31
+ route53 = double('route53', :hosted_zones => [zone])
32
+ allow(AWS::Route53).to receive(:new) { route53 }
33
+
34
+ subject.find_alias_target('Target.com', 'Foo.target.com').should eq('abc.com')
35
+ end
36
+
37
+ it "should get a nil alias target when the record exists but has no alias target" do
38
+ host = double('host', :name => 'foo.target.com.', :alias_target => nil)
39
+ zone = double('zone', :name => 'target.com.', :resource_record_sets => [host])
40
+ route53 = double('route53', :hosted_zones => [zone])
41
+ allow(AWS::Route53).to receive(:new) { route53 }
42
+
43
+ subject.find_alias_target('target.com', 'foo.target.com').should be_nil
44
+ end
45
+
46
+ it "should get alias target when zone and host name having trailing dot" do
47
+ host = double('host', :name => 'foo.target.com.', :alias_target => { :dns_name => 'abc.com.'})
48
+ zone = double('zone', :name => 'target.com.', :resource_record_sets => [host])
49
+ route53 = double('route53', :hosted_zones => [zone])
50
+ allow(AWS::Route53).to receive(:new) { route53 }
51
+
52
+ subject.find_alias_target('target.com.', 'foo.target.com.').should eq('abc.com')
53
+ end
54
+
55
+ end
56
+
57
+ describe ".set_alias_target" do
58
+ it "should raise an error when the target-zone cannot be found" do
59
+ route53 = double('route53')
60
+ allow(AWS::Route53).to receive(:new) { route53 }
61
+
62
+ allow(route53).to receive(:hosted_zones) { [] }
63
+
64
+ expect { subject.set_alias_target('abc.com', 'foo', 'abc', 'def') }.to raise_error('Target zone not found!')
65
+ end
66
+
67
+ it "should attempt multiple times" do
68
+ failing_route53 = Fakes::AWSRoute53.new(times_to_fail: 5, hosted_zones: [double(name: 'abc.com.', path: '')])
69
+ route53_driver = CfDeployer::Driver::Route53.new(failing_route53)
70
+
71
+ allow(route53_driver).to receive(:sleep)
72
+ route53_driver.set_alias_target('abc.com', 'foo', 'abc', 'def')
73
+
74
+ expect(failing_route53.client.fail_counter).to eq(6)
75
+ end
76
+
77
+ it "should raise an exception when failing more than 20 times" do
78
+ failing_route53 = Fakes::AWSRoute53.new(times_to_fail: 21, hosted_zones: [double(name: 'abc.com.', path: '')])
79
+ route53_driver = CfDeployer::Driver::Route53.new(failing_route53)
80
+
81
+ allow(route53_driver).to receive(:sleep)
82
+ expect { route53_driver.set_alias_target('abc.com', 'foo', 'abc', 'def') }.to raise_error('Failed to update Route53 alias target record!')
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe CfDeployer::Driver::Verisign do
4
+ subject { CfDeployer::Driver::Verisign.new }
5
+
6
+ describe ".find_alias_target" do
7
+ it "should raise an error because it's not implemented yet" do
8
+ expect { subject.find_alias_target('abc.com', 'foo') }.to raise_error('Not Implemented')
9
+ end
10
+ end
11
+
12
+ describe ".set_alias_target" do
13
+ it "should raise an error because it's not implemented yet" do
14
+ expect { subject.set_alias_target('abc.com', 'foo', 'abc', 'def') }.to raise_error('Not Implemented')
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe CfDeployer::Hook do
4
+ before :all do
5
+ @file = File.expand_path("../../../tmp/test_code.rb", __FILE__)
6
+ end
7
+ it 'should eval string as hook' do
8
+ $result = nil
9
+ context = { app: 'myApp'}
10
+ CfDeployer::Hook.new('MyHook', "$result = context[:app]").run(context)
11
+ expect($result).to eq('myApp')
12
+ end
13
+
14
+ it 'should log the hook name ' do
15
+ context = { app: 'myApp'}
16
+ expect(CfDeployer::Log).to receive(:info).with(/My Hook/)
17
+ CfDeployer::Hook.new('My Hook', "$result = context[:app]").run(context)
18
+ end
19
+
20
+ it 'should duplicate context in hook' do
21
+ $result = nil
22
+ context = { app: 'myApp'}
23
+ CfDeployer::Hook.new('MyHook', "context[:app] = 'app2'").run(context)
24
+ expect(context[:app]).to eq('myApp')
25
+ end
26
+
27
+ it 'should timeout when executing hook in a string takes too long time' do
28
+ $result = nil
29
+ stub_const("CfDeployer::Defaults::Timeout", 10/1000.0)
30
+ context = { app: 'myApp'}
31
+ expect{CfDeployer::Hook.new('MyHook', "sleep 40/1000.0").run(context)}.to raise_error(Timeout::Error)
32
+ end
33
+
34
+ it 'should timeout when executing hook in a string takes too longer time than given timeout' do
35
+ $result = nil
36
+ context = { app: 'myApp'}
37
+ expect{CfDeployer::Hook.new('MyHook', {code: "sleep 40/1000.0", timeout: 20/1000.0}).run(context)}.to raise_error(Timeout::Error)
38
+ end
39
+
40
+ it 'should excute code in a file' do
41
+ code = <<-eos
42
+ $result = context[:app]
43
+ eos
44
+ File.open(@file, 'w') {|f| f.write(code) }
45
+ $result = nil
46
+ config_dir = File.expand_path('../../samples', __FILE__)
47
+ context = { app: 'myApp', config_dir: config_dir}
48
+ CfDeployer::Hook.new('MyHook', {file: '../../tmp/test_code.rb'}).run(context)
49
+ expect($result).to eq('myApp')
50
+ end
51
+
52
+ it 'should timeout when excuting code in a file takes too long time' do
53
+ file = File.expand_path("../../tmp/test_code.rb", __FILE__)
54
+ code = <<-eos
55
+ sleep 40/1000.0
56
+ $result = context[:app]
57
+ eos
58
+ File.open(@file, 'w') {|f| f.write(code) }
59
+ $result = nil
60
+ config_dir = File.expand_path('../../samples', __FILE__)
61
+ context = { app: 'myApp', config_dir: config_dir}
62
+ expect{CfDeployer::Hook.new('MyHook', {file: '../../tmp/test_code.rb', timeout: 20/1000.0}).run(context)}.to raise_error(Timeout::Error)
63
+ end
64
+ end
@@ -0,0 +1,150 @@
1
+ require 'spec_helper'
2
+
3
+ describe CfDeployer::Stack do
4
+ before do
5
+ @cf_driver = double CfDeployer::Driver::CloudFormation
6
+ @stack = CfDeployer::Stack.new('test', 'web', {:cf_driver => @cf_driver})
7
+ end
8
+
9
+ context '#deploy' do
10
+ it 'should call CfDeployer::ConfigLoader.component_json to get the JSON for the stack' do
11
+ config = { :inputs => { :foo => 'foo' },
12
+ :defined_parameters => { :bar => 'bar' },
13
+ :cf_driver => @cf_driver }
14
+ CfDeployer::ConfigLoader.should_receive(:component_json).with('web', config)
15
+ allow(@cf_driver).to receive(:stack_exists?) { false }
16
+ allow(@cf_driver).to receive(:stack_status) { :create_complete }
17
+ stack = CfDeployer::Stack.new('test','web', config)
18
+ allow(stack).to receive(:create_stack)
19
+ stack.deploy
20
+ end
21
+ end
22
+
23
+ context '#parameters' do
24
+ it "should get parameters" do
25
+ parameters = double('parameters')
26
+ allow(@cf_driver).to receive(:parameters){ parameters }
27
+ allow(@cf_driver).to receive(:stack_status) { :create_complete }
28
+ expect(@stack.parameters).to eq(parameters)
29
+ end
30
+
31
+ it "should get empty hash if stack is not ready" do
32
+ allow(@cf_driver).to receive(:stack_status) { :create_inprogress }
33
+ expect(@stack.parameters).to eq({})
34
+ end
35
+ end
36
+
37
+ context '#outputs' do
38
+ it "should get outputs" do
39
+ outputs = double('outputs')
40
+ allow(@cf_driver).to receive(:outputs){ outputs }
41
+ allow(@cf_driver).to receive(:stack_status) { :create_complete }
42
+ expect(@stack.outputs).to eq(outputs)
43
+ end
44
+
45
+ it "should get empty hash if stack is not ready" do
46
+ outputs = double('outputs')
47
+ allow(@cf_driver).to receive(:stack_status) { :create_inprogress }
48
+ expect(@stack.outputs).to eq({})
49
+ end
50
+ end
51
+
52
+ context "#ready?" do
53
+
54
+ CfDeployer::Stack::READY_STATS.each do |status|
55
+ it "should be ready when in #{status} status" do
56
+ allow(@cf_driver).to receive(:stack_status) { status }
57
+ expect(@stack).to be_ready
58
+ end
59
+ end
60
+
61
+ it "should not be ready when not in a ready status" do
62
+ allow(@cf_driver).to receive(:stack_status) { :my_fake_status }
63
+ expect(@stack).not_to be_ready
64
+ end
65
+
66
+ it "should get error if output is empty" do
67
+ expect(@cf_driver).to receive(:query_output).with('mykey'){ nil }
68
+ expect{@stack.output('mykey')}.to raise_error("'mykey' is empty from stack test output")
69
+ end
70
+
71
+ it "should get output value" do
72
+ expect(@cf_driver).to receive(:query_output).with('mykey'){ 'myvalue'}
73
+ @stack.output('mykey').should eq('myvalue')
74
+ end
75
+ end
76
+
77
+ describe '#delete' do
78
+ it 'should delete the stack' do
79
+ allow(@stack).to receive(:exists?).and_return(true, false)
80
+ expect(@cf_driver).to receive(:delete_stack)
81
+ @stack.delete
82
+ end
83
+
84
+ it 'should not delete the stack if it does not exist' do
85
+ allow(@stack).to receive(:exists?) { false }
86
+ expect(@cf_driver).not_to receive(:delete_stack)
87
+ @stack.delete
88
+ end
89
+
90
+ it 'should be fine to get not exist error after deletion' do
91
+ allow(@stack).to receive(:exists?).and_return(true, true)
92
+ allow(@stack).to receive(:stack_status).and_raise(AWS::CloudFormation::Errors::ValidationError.new('the stack does not exist'))
93
+ expect(@cf_driver).to receive(:delete_stack)
94
+ expect {@stack.delete}.not_to raise_error
95
+ end
96
+
97
+ it 'should raise an error if a validation error is thrown not about stack does not exist' do
98
+ allow(@stack).to receive(:exists?).and_return(true, true)
99
+ allow(@stack).to receive(:stack_status).and_raise(AWS::CloudFormation::Errors::ValidationError.new('I am an error'))
100
+ expect(@cf_driver).to receive(:delete_stack)
101
+ expect {@stack.delete}.to raise_error
102
+ end
103
+ end
104
+
105
+ describe '#status' do
106
+ it "should be :ready if the stack is ready" do
107
+ allow(@stack).to receive(:exists?) { true }
108
+ allow(@stack).to receive(:ready?) { true }
109
+ expect(@stack.status).to eq(:ready)
110
+ end
111
+
112
+ it 'should be :exists if it exists but is not ready' do
113
+ allow(@stack).to receive(:exists?) { true }
114
+ allow(@stack).to receive(:ready?) { false }
115
+ expect(@stack.status).to eq(:exists)
116
+ end
117
+
118
+ it 'should be :does_not_exist if it does not exist' do
119
+ allow(@stack).to receive(:exists?) { false }
120
+ expect(@stack.status).to eq(:does_not_exist)
121
+ end
122
+ end
123
+
124
+ describe '#resource_statuses' do
125
+ it 'should get resource_statuses from the CF driver' do
126
+ rs = { :something => :some_status }
127
+ expect(@cf_driver).to receive(:resource_statuses) { rs }
128
+ expect(@stack.resource_statuses[:something]).to eq(:some_status)
129
+ end
130
+
131
+ it 'should add instance status info for instances in ASGs' do
132
+ asg = double CfDeployer::Driver::AutoScalingGroup
133
+ rs = { 'AWS::AutoScaling::AutoScalingGroup' => { 'ASG123' => :some_status } }
134
+ expect(@cf_driver).to receive(:resource_statuses) { rs }
135
+ expect(asg).to receive(:instance_statuses) { { 'i-abcd1234' => { :status => :some_status } } }
136
+ expect(CfDeployer::Driver::AutoScalingGroup).to receive(:new).with('ASG123') { asg }
137
+ expect(@stack.resource_statuses[:asg_instances]['ASG123']['i-abcd1234'][:status]).to eq(:some_status)
138
+ end
139
+
140
+ it 'should add instance status info for instances NOT in ASGs' do
141
+ instance = double CfDeployer::Driver::Instance
142
+ rs = { 'AWS::EC2::Instance' => { 'i-abcd1234' => :some_status } }
143
+ expect(@cf_driver).to receive(:resource_statuses) { rs }
144
+ expect(CfDeployer::Driver::Instance).to receive(:new).with('i-abcd1234') { instance }
145
+ expect(instance).to receive(:status) { { :status => :some_status } }
146
+ expect(@stack.resource_statuses[:instances]['i-abcd1234'][:status]).to eq(:some_status)
147
+ end
148
+ end
149
+
150
+ end
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+
3
+ describe "status_presenter" do
4
+
5
+ before do
6
+ @presenter = CfDeployer::StatusPresenter.new({}, 'all')
7
+ end
8
+
9
+ context "#filter_for_verbosity" do
10
+ it "should filter out all resources if the verbosity is 'stacks'" do
11
+ info = {
12
+ :web => {
13
+ :stack1 => {
14
+ :status => :ready,
15
+ :resources => { :some_resource_type => [ :resource_1, :resource_2 ] }
16
+ }
17
+ }
18
+ }
19
+
20
+ stacks_presenter = CfDeployer::StatusPresenter.new({}, 'stacks')
21
+ filtered_info = stacks_presenter.send :filter_for_verbosity, info
22
+
23
+ expect(filtered_info[:resources]).to eq(nil)
24
+ end
25
+
26
+ it "should only keep :instances and :asg_instances when verbosity is 'instances'" do
27
+ info = {
28
+ :web => {
29
+ :stack1 => {
30
+ :status => :ready,
31
+ :resources => {
32
+ :instances => [ :instance_1 ],
33
+ :asg_instances => [ :asg_instance_1 ],
34
+ :some_other_resource => [ :other_resource ]
35
+ }
36
+ }
37
+ }
38
+ }
39
+
40
+ instances__presenter = CfDeployer::StatusPresenter.new({}, 'instances')
41
+ filtered_info = instances__presenter.send :filter_for_verbosity, info
42
+
43
+ expect(filtered_info[:web][:stack1][:resources][:instances]).to eq(info[:web][:stack1][:resources][:instances])
44
+ expect(filtered_info[:web][:stack1][:resources][:asg_instances]).to eq(info[:web][:stack1][:resources][:asg_instances])
45
+ expect(filtered_info[:web][:stack1][:resources][:some_other_resource]).to eq(nil)
46
+ end
47
+ end
48
+
49
+ context "#tableize" do
50
+ before do
51
+ @table_data = [
52
+ [ 'r1c1',
53
+ 'r2c1',
54
+ 'r3c1'
55
+ ],
56
+ [ 'r1c2',
57
+ 'r2c2'
58
+ ]
59
+ ]
60
+
61
+ @table_output = @presenter.send :tableize, @table_data
62
+ end
63
+
64
+ it "should have one more row than the max of each column's number of rows" do
65
+ expect(@table_output.size).to eq(4)
66
+ end
67
+
68
+ it "should have a table seperator as the last row" do
69
+ expect(@table_output.last).to eq(@presenter.send :table_seperator)
70
+ end
71
+
72
+ it "should draw a column seperator and pad the left column" do
73
+ expected_pad = ' ' * (CfDeployer::StatusPresenter::UNPADDED_TABLE_CELL_WIDTH - CfDeployer::StatusPresenter::PAD.size)
74
+ expected_row = @table_data[0][0] + expected_pad + '|' + @table_data[1][0]
75
+ expect(@table_output.first).to eq(expected_row)
76
+ end
77
+ end
78
+
79
+ context "#middle_truncate_ljust" do
80
+ it "should replace the middle of a long string with an elipsis" do
81
+ long_str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
82
+ truncated_str = @presenter.send :middle_truncate_ljust, long_str, 40
83
+ expect(truncated_str).to eq('abcdefghijklmnopq...GHIJKLMNOPQRSTUVWXYZ')
84
+ expect(truncated_str.size).to eq(40)
85
+ end
86
+ end
87
+
88
+ context "#visible_length" do
89
+ it "should return the length of the string without ANSI color code characters" do
90
+ colored_string = "a \e[31mcolored\e[0m string"
91
+ expect(@presenter.send(:visible_length, colored_string)).to eq(16)
92
+ end
93
+ end
94
+
95
+ context "#invisible_length" do
96
+ it "should return the length of the ANSI color code characters" do
97
+ colored_string = "a \e[31mcolored\e[0m string"
98
+ expect(@presenter.send(:invisible_length, colored_string)).to eq(9)
99
+ end
100
+ end
101
+
102
+ context "#centered" do
103
+ it "should rjust a string to the center of the table" do
104
+ expect(@presenter.send(:centered, 'Some String')).to eq(' Some String')
105
+ end
106
+ end
107
+
108
+ end
metadata ADDED
@@ -0,0 +1,197 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cf_deployer
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.8
5
+ platform: ruby
6
+ authors:
7
+ - Jame Brechtel
8
+ - Peter Zhao
9
+ - Patrick McFadden
10
+ - Rob Sweet
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2014-06-25 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: aws-sdk
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: log4r
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ - !ruby/object:Gem::Dependency
45
+ name: thor
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ - !ruby/object:Gem::Dependency
59
+ name: rainbow
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ type: :runtime
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ description: For automatic blue green deployment flow on CloudFormation.
73
+ email:
74
+ - jbrechtel@gmail.com
75
+ - peter.qs.zhao@gmail.com
76
+ - pemcfadden@gmail.com
77
+ - rob@ldg.net
78
+ executables:
79
+ - cf_deploy
80
+ extensions: []
81
+ extra_rdoc_files: []
82
+ files:
83
+ - .gitignore
84
+ - ChangeLog.md
85
+ - DETAILS.md
86
+ - FAQ.md
87
+ - Gemfile
88
+ - Gemfile.lock
89
+ - LICENSE
90
+ - QUICKSTART.md
91
+ - README.md
92
+ - Rakefile
93
+ - bin/cf_deploy
94
+ - cf_deployer.gemspec
95
+ - lib/cf_deployer.rb
96
+ - lib/cf_deployer/application.rb
97
+ - lib/cf_deployer/application_error.rb
98
+ - lib/cf_deployer/aws_constants.rb
99
+ - lib/cf_deployer/cli.rb
100
+ - lib/cf_deployer/component.rb
101
+ - lib/cf_deployer/config_loader.rb
102
+ - lib/cf_deployer/config_validation.rb
103
+ - lib/cf_deployer/defaults.rb
104
+ - lib/cf_deployer/deployment_strategy/auto_scaling_group_swap.rb
105
+ - lib/cf_deployer/deployment_strategy/base.rb
106
+ - lib/cf_deployer/deployment_strategy/blue_green.rb
107
+ - lib/cf_deployer/deployment_strategy/cname_swap.rb
108
+ - lib/cf_deployer/deployment_strategy/create_or_update.rb
109
+ - lib/cf_deployer/driver/auto_scaling_group.rb
110
+ - lib/cf_deployer/driver/cloud_formation_driver.rb
111
+ - lib/cf_deployer/driver/dry_run.rb
112
+ - lib/cf_deployer/driver/elb_driver.rb
113
+ - lib/cf_deployer/driver/instance.rb
114
+ - lib/cf_deployer/driver/route53_driver.rb
115
+ - lib/cf_deployer/driver/verisign_driver.rb
116
+ - lib/cf_deployer/hook.rb
117
+ - lib/cf_deployer/logger.rb
118
+ - lib/cf_deployer/stack.rb
119
+ - lib/cf_deployer/status_presenter.rb
120
+ - lib/cf_deployer/version.rb
121
+ - spec/fakes/instance.rb
122
+ - spec/fakes/route53_client.rb
123
+ - spec/fakes/stack.rb
124
+ - spec/functional/deploy_spec.rb
125
+ - spec/functional/kill_inactive_spec.rb
126
+ - spec/functional_spec_helper.rb
127
+ - spec/spec_helper.rb
128
+ - spec/unit/application_spec.rb
129
+ - spec/unit/component_spec.rb
130
+ - spec/unit/config_loader_spec.rb
131
+ - spec/unit/config_validation_spec.rb
132
+ - spec/unit/deployment_strategy/auto_scaling_group_swap_spec.rb
133
+ - spec/unit/deployment_strategy/base_spec.rb
134
+ - spec/unit/deployment_strategy/cname_swap_spec.rb
135
+ - spec/unit/deployment_strategy/create_or_update_spec.rb
136
+ - spec/unit/deployment_strategy/deployment_strategy_spec.rb
137
+ - spec/unit/driver/auto_scaling_group_spec.rb
138
+ - spec/unit/driver/cloud_formation_spec.rb
139
+ - spec/unit/driver/elb_spec.rb
140
+ - spec/unit/driver/instance_spec.rb
141
+ - spec/unit/driver/route53_spec.rb
142
+ - spec/unit/driver/verisign_spec.rb
143
+ - spec/unit/hook_spec.rb
144
+ - spec/unit/stack_spec.rb
145
+ - spec/unit/status_presenter_spec.rb
146
+ homepage: http://github.com/manheim/cf_deployer
147
+ licenses:
148
+ - MIT
149
+ metadata: {}
150
+ post_install_message:
151
+ rdoc_options: []
152
+ require_paths:
153
+ - lib
154
+ required_ruby_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ requirements: []
165
+ rubyforge_project:
166
+ rubygems_version: 2.0.3
167
+ signing_key:
168
+ specification_version: 4
169
+ summary: Support multiple components deployment using CloudFormation templates with
170
+ multiple blue green strategies.
171
+ test_files:
172
+ - spec/fakes/instance.rb
173
+ - spec/fakes/route53_client.rb
174
+ - spec/fakes/stack.rb
175
+ - spec/functional/deploy_spec.rb
176
+ - spec/functional/kill_inactive_spec.rb
177
+ - spec/functional_spec_helper.rb
178
+ - spec/spec_helper.rb
179
+ - spec/unit/application_spec.rb
180
+ - spec/unit/component_spec.rb
181
+ - spec/unit/config_loader_spec.rb
182
+ - spec/unit/config_validation_spec.rb
183
+ - spec/unit/deployment_strategy/auto_scaling_group_swap_spec.rb
184
+ - spec/unit/deployment_strategy/base_spec.rb
185
+ - spec/unit/deployment_strategy/cname_swap_spec.rb
186
+ - spec/unit/deployment_strategy/create_or_update_spec.rb
187
+ - spec/unit/deployment_strategy/deployment_strategy_spec.rb
188
+ - spec/unit/driver/auto_scaling_group_spec.rb
189
+ - spec/unit/driver/cloud_formation_spec.rb
190
+ - spec/unit/driver/elb_spec.rb
191
+ - spec/unit/driver/instance_spec.rb
192
+ - spec/unit/driver/route53_spec.rb
193
+ - spec/unit/driver/verisign_spec.rb
194
+ - spec/unit/hook_spec.rb
195
+ - spec/unit/stack_spec.rb
196
+ - spec/unit/status_presenter_spec.rb
197
+ has_rdoc: