automan 2.3.6 → 2.3.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +5 -0
  5. data/Rakefile +5 -0
  6. data/automan.gemspec +3 -3
  7. data/lib/automan/base.rb +7 -3
  8. data/lib/automan/beanstalk/deployer.rb +1 -1
  9. data/lib/automan/beanstalk/package.rb +1 -1
  10. data/lib/automan/beanstalk/router.rb +1 -1
  11. data/lib/automan/cli/snapper.rb +29 -29
  12. data/lib/automan/cli/stacker.rb +19 -0
  13. data/lib/automan/cloudformation/launcher.rb +6 -3
  14. data/lib/automan/cloudformation/replacer.rb +1 -1
  15. data/lib/automan/cloudformation/terminator.rb +1 -1
  16. data/lib/automan/ec2/image.rb +3 -3
  17. data/lib/automan/elasticache/router.rb +79 -0
  18. data/lib/automan/mixins/aws_caller.rb +21 -7
  19. data/lib/automan/rds/snapshot.rb +35 -14
  20. data/lib/automan/s3/downloader.rb +10 -1
  21. data/lib/automan/version.rb +1 -1
  22. data/lib/automan.rb +1 -0
  23. data/spec/beanstalk/application_spec.rb +17 -17
  24. data/spec/beanstalk/configuration_spec.rb +24 -24
  25. data/spec/beanstalk/deployer_spec.rb +65 -65
  26. data/spec/beanstalk/router_spec.rb +18 -19
  27. data/spec/beanstalk/terminator_spec.rb +16 -16
  28. data/spec/beanstalk/uploader_spec.rb +13 -13
  29. data/spec/beanstalk/version_spec.rb +8 -10
  30. data/spec/cloudformation/launcher_spec.rb +63 -65
  31. data/spec/cloudformation/replacer_spec.rb +10 -10
  32. data/spec/cloudformation/terminator_spec.rb +23 -23
  33. data/spec/cloudformation/uploader_spec.rb +13 -13
  34. data/spec/ec2/image_spec.rb +55 -55
  35. data/spec/ec2/instance_spec.rb +17 -17
  36. data/spec/elasticache/router_spec.rb +29 -0
  37. data/spec/mixins/aws_caller_spec.rb +9 -9
  38. data/spec/mixins/utils_spec.rb +27 -28
  39. data/spec/rds/snapshot_spec.rb +44 -46
  40. data/templates/stacker/.env.example +14 -0
  41. data/templates/stacker/.gitignore +2 -0
  42. data/templates/stacker/.ruby-gemset.tt +1 -0
  43. data/templates/stacker/.ruby-version +1 -0
  44. data/templates/stacker/Gemfile +4 -0
  45. data/templates/stacker/bin/%app_name%.tt +62 -0
  46. data/templates/stacker/bin/launch_%app_name%.sh.tt +12 -0
  47. metadata +20 -7
@@ -17,30 +17,29 @@ describe Automan::Cloudformation::Launcher do
17
17
  it { should respond_to :stack_update_complete? }
18
18
 
19
19
  describe '#read_manifest' do
20
- subject(:s) do
20
+ subject() do
21
21
  AWS.stub!
22
- s = Automan::Cloudformation::Launcher.new
23
- s
22
+ Automan::Cloudformation::Launcher.new
24
23
  end
25
24
 
26
25
  it 'raises MissingManifestError if manifest does not exist' do
27
- s.stub(:manifest_exists?).and_return(false)
26
+ allow(subject).to receive(:manifest_exists?).and_return(false)
28
27
  expect {
29
- s.read_manifest
28
+ subject.read_manifest
30
29
  }.to raise_error(Automan::Cloudformation::MissingManifestError)
31
30
  end
32
31
 
33
32
  it 'merges manifest contents into parameters hash' do
34
- s.stub(:manifest_exists?).and_return(true)
35
- s.stub(:s3_read).and_return('{"foo": "bar", "big": "poppa"}')
36
- s.parameters = {'foo'=> 'baz', 'fo'=> 'shizzle'}
37
- s.read_manifest
38
- s.parameters.should eq({'foo' => 'bar', 'fo' => 'shizzle', 'big' => 'poppa'})
33
+ allow(subject).to receive(:manifest_exists?).and_return(true)
34
+ allow(subject).to receive(:s3_read).and_return('{"foo": "bar", "big": "poppa"}')
35
+ subject.parameters = {'foo'=> 'baz', 'fo'=> 'shizzle'}
36
+ subject.read_manifest
37
+ expect(subject.parameters).to eq({'foo' => 'bar', 'fo' => 'shizzle', 'big' => 'poppa'})
39
38
  end
40
39
  end
41
40
 
42
41
  describe '#parse_template_parameters' do
43
- subject(:s) do
42
+ subject() do
44
43
  AWS.stub!
45
44
  s = Automan::Cloudformation::Launcher.new
46
45
  s.cfn = AWS::CloudFormation.new
@@ -49,31 +48,30 @@ describe Automan::Cloudformation::Launcher do
49
48
  end
50
49
 
51
50
  it "returns a hash" do
52
- s.template = File.join(File.dirname(__FILE__), 'templates', 'worker_role.json')
53
- result = s.parse_template_parameters
54
- result.class.should eq(Hash)
51
+ subject.template = File.join(File.dirname(__FILE__), 'templates', 'worker_role.json')
52
+ result = subject.parse_template_parameters
53
+ expect(result.class).to eq(Hash)
55
54
  end
56
55
 
57
56
  end
58
57
 
59
58
  describe '#template_handle' do
60
- subject(:s) do
59
+ subject() do
61
60
  AWS.stub!
62
- s = Automan::Cloudformation::Launcher.new
63
- s
61
+ Automan::Cloudformation::Launcher.new
64
62
  end
65
63
 
66
64
  it "returns an s3 key if it is an s3 path" do
67
- s.template_handle("s3://foo/bar/baz").should be_a AWS::S3::S3Object
65
+ expect(subject.template_handle("s3://foo/bar/baz")).to be_a AWS::S3::S3Object
68
66
  end
69
67
 
70
68
  it "returns a string if it is a local file" do
71
- s.template_handle(__FILE__).should be_a String
69
+ expect(subject.template_handle(__FILE__)).to be_a String
72
70
  end
73
71
  end
74
72
 
75
73
  describe '#validate_parameters' do
76
- subject(:s) do
74
+ subject() do
77
75
  AWS.stub!
78
76
  s = Automan::Cloudformation::Launcher.new
79
77
  s.logger = Logger.new('/dev/null')
@@ -82,99 +80,99 @@ describe Automan::Cloudformation::Launcher do
82
80
  end
83
81
 
84
82
  it "raises error if no parameters were specified" do
85
- s.parameters = nil
83
+ subject.parameters = nil
86
84
  expect {
87
- s.validate_parameters
85
+ subject.validate_parameters
88
86
  }.to raise_error Automan::Cloudformation::MissingParametersError
89
87
  end
90
88
 
91
89
  it "raises error if the template doesn't validate" do
92
- Automan::Cloudformation::Launcher.any_instance.stub(:parse_template_parameters).and_return({code: 'foo', message: 'bar'})
90
+ allow(subject).to receive(:parse_template_parameters).and_return({code: 'foo', message: 'bar'})
93
91
  expect {
94
- s.validate_parameters
92
+ subject.validate_parameters
95
93
  }.to raise_error Automan::Cloudformation::BadTemplateError
96
94
  end
97
95
 
98
96
  it "raises error if a required parameter isn't present" do
99
- Automan::Cloudformation::Launcher.any_instance.stub(:parse_template_parameters).and_return(parameters: [{parameter_key: 'foo'}])
97
+ allow(subject).to receive(:parse_template_parameters).and_return(parameters: [{parameter_key: 'foo'}])
100
98
  expect {
101
- s.validate_parameters
99
+ subject.validate_parameters
102
100
  }.to raise_error Automan::Cloudformation::MissingParametersError
103
101
  end
104
102
 
105
103
  it "raises no error if all required parameters are present" do
106
- Automan::Cloudformation::Launcher.any_instance.stub(:parse_template_parameters).and_return(parameters: [{parameter_key: 'foo'}])
107
- s.parameters = {'foo' => 'bar'}
104
+ allow(subject).to receive(:parse_template_parameters).and_return(parameters: [{parameter_key: 'foo'}])
105
+ subject.parameters = {'foo' => 'bar'}
108
106
  expect {
109
- s.validate_parameters
107
+ subject.validate_parameters
110
108
  }.not_to raise_error
111
109
  end
112
110
 
113
111
  it "raises no error if there are no required parameters" do
114
- Automan::Cloudformation::Launcher.any_instance.stub(:parse_template_parameters).and_return(parameters: [{parameter_key: 'foo', default_value: 'bar'}])
112
+ allow(subject).to receive(:parse_template_parameters).and_return(parameters: [{parameter_key: 'foo', default_value: 'bar'}])
115
113
  expect {
116
- s.validate_parameters
114
+ subject.validate_parameters
117
115
  }.not_to raise_error
118
116
  end
119
117
  end
120
118
 
121
119
  describe '#update' do
122
- subject(:s) do
120
+ subject() do
123
121
  AWS.stub!
124
122
  s = Automan::Cloudformation::Launcher.new
125
123
  s.logger = Logger.new('/dev/null')
126
- s.stub(:template_handle).and_return('foo')
124
+ allow(s).to receive(:template_handle).and_return('foo')
127
125
  s
128
126
  end
129
127
 
130
128
  it "ignores AWS::CloudFormation::Errors::ValidationError when no updates are to be performed" do
131
- s.stub(:update_stack).and_raise AWS::CloudFormation::Errors::ValidationError.new("No updates are to be performed.")
129
+ allow(subject).to receive(:update_stack).and_raise AWS::CloudFormation::Errors::ValidationError.new("No updates are to be performed.")
132
130
  expect {
133
- s.update
131
+ subject.update
134
132
  }.to_not raise_error
135
133
  end
136
134
 
137
135
  it 're-raises any other ValidationError' do
138
- s.stub(:update_stack).and_raise AWS::CloudFormation::Errors::ValidationError.new("foo")
136
+ allow(subject).to receive(:update_stack).and_raise AWS::CloudFormation::Errors::ValidationError.new("foo")
139
137
  expect {
140
- s.update
138
+ subject.update
141
139
  }.to raise_error AWS::CloudFormation::Errors::ValidationError
142
140
  end
143
141
  end
144
142
 
145
143
  describe '#launch_or_update' do
146
- subject(:s) do
144
+ subject() do
147
145
  AWS.stub!
148
146
  s = Automan::Cloudformation::Launcher.new
149
147
  s.logger = Logger.new('/dev/null')
150
- s.stub(:validate_parameters)
148
+ allow(s).to receive(:validate_parameters)
151
149
  s
152
150
  end
153
151
 
154
152
  it "launches a new stack if it does not exist" do
155
- s.stub(:stack_exists?).and_return(false)
156
- s.should_receive(:launch)
157
- s.launch_or_update
153
+ allow(subject).to receive(:stack_exists?).and_return(false)
154
+ expect(subject).to receive(:launch)
155
+ subject.launch_or_update
158
156
  end
159
157
 
160
158
  it "updates an existing stack if update is enabled" do
161
- s.stub(:stack_exists?).and_return(true)
162
- s.stub(:enable_update).and_return(true)
163
- s.should_receive(:update)
164
- s.launch_or_update
159
+ allow(subject).to receive(:stack_exists?).and_return(true)
160
+ allow(subject).to receive(:enable_update).and_return(true)
161
+ expect(subject).to receive(:update)
162
+ subject.launch_or_update
165
163
  end
166
164
 
167
165
  it "raises an error when updating an existing stack w/o update enabled" do
168
- s.stub(:stack_exists?).and_return(true)
169
- s.stub(:enable_update).and_return(false)
166
+ allow(subject).to receive(:stack_exists?).and_return(true)
167
+ allow(subject).to receive(:enable_update).and_return(false)
170
168
  expect {
171
- s.launch_or_update
169
+ subject.launch_or_update
172
170
  }.to raise_error Automan::Cloudformation::StackExistsError
173
171
  end
174
172
  end
175
173
 
176
174
  describe '#stack_launch_complete?' do
177
- subject(:s) do
175
+ subject() do
178
176
  AWS.stub!
179
177
  s = Automan::Cloudformation::Launcher.new
180
178
  s.logger = Logger.new('/dev/null')
@@ -182,35 +180,35 @@ describe Automan::Cloudformation::Launcher do
182
180
  end
183
181
 
184
182
  it 'returns true when the stack completes' do
185
- s.stub(:stack_status).and_return('CREATE_COMPLETE')
186
- s.stack_launch_complete?.should be_true
183
+ allow(subject).to receive(:stack_status).and_return('CREATE_COMPLETE')
184
+ expect(subject.stack_launch_complete?).to be_truthy
187
185
  end
188
186
 
189
187
  it 'raises an error when the stack fails' do
190
- s.stub(:stack_status).and_return('CREATE_FAILED')
188
+ allow(subject).to receive(:stack_status).and_return('CREATE_FAILED')
191
189
  expect {
192
- s.stack_launch_complete?
190
+ subject.stack_launch_complete?
193
191
  }.to raise_error Automan::Cloudformation::StackCreationError
194
192
  end
195
193
 
196
194
  rollback_states = %w[ROLLBACK_COMPLETE ROLLBACK_FAILED ROLLBACK_IN_PROGRESS]
197
195
  rollback_states.each do |state|
198
196
  it "raises an error when the stack goes into #{state} state" do
199
- s.stub(:stack_status).and_return(state)
197
+ allow(subject).to receive(:stack_status).and_return(state)
200
198
  expect {
201
- s.stack_launch_complete?
199
+ subject.stack_launch_complete?
202
200
  }.to raise_error Automan::Cloudformation::StackCreationError
203
201
  end
204
202
  end
205
203
 
206
204
  it 'returns false for any other state' do
207
- s.stub(:stack_status).and_return('foo')
208
- s.stack_launch_complete?.should be_false
205
+ allow(subject).to receive(:stack_status).and_return('foo')
206
+ expect(subject.stack_launch_complete?).to be_falsey
209
207
  end
210
208
  end
211
209
 
212
210
  describe '#stack_update_complete?' do
213
- subject(:s) do
211
+ subject() do
214
212
  AWS.stub!
215
213
  s = Automan::Cloudformation::Launcher.new
216
214
  s.logger = Logger.new('/dev/null')
@@ -218,23 +216,23 @@ describe Automan::Cloudformation::Launcher do
218
216
  end
219
217
 
220
218
  it 'returns true when the stack completes' do
221
- s.stub(:stack_status).and_return('UPDATE_COMPLETE')
222
- s.stack_update_complete?.should be_true
219
+ allow(subject).to receive(:stack_status).and_return('UPDATE_COMPLETE')
220
+ expect(subject.stack_update_complete?).to be_truthy
223
221
  end
224
222
 
225
223
  rollback_states = %w[UPDATE_ROLLBACK_COMPLETE UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS UPDATE_ROLLBACK_FAILED UPDATE_ROLLBACK_IN_PROGRESS]
226
224
  rollback_states.each do |state|
227
225
  it "raises an error when the stack enters #{state} state" do
228
- s.stub(:stack_status).and_return(state)
226
+ allow(subject).to receive(:stack_status).and_return(state)
229
227
  expect {
230
- s.stack_update_complete?
228
+ subject.stack_update_complete?
231
229
  }.to raise_error Automan::Cloudformation::StackUpdateError
232
230
  end
233
231
  end
234
232
 
235
233
  it 'returns false for any other state' do
236
- s.stub(:stack_status).and_return('foo')
237
- s.stack_update_complete?.should be_false
234
+ allow(subject).to receive(:stack_status).and_return('foo')
235
+ expect(subject.stack_update_complete?).to be_falsey
238
236
  end
239
237
  end
240
238
  end
@@ -1,15 +1,15 @@
1
1
  require 'automan'
2
2
 
3
3
  describe Automan::Cloudformation::Replacer do
4
- it { should respond_to :name }
5
- it { should respond_to :replace_instances }
6
- it { should respond_to :ok_to_replace_instances? }
7
- it { should respond_to :stack_exists? }
4
+ it { is_expected.to respond_to :name }
5
+ it { is_expected.to respond_to :replace_instances }
6
+ it { is_expected.to respond_to :ok_to_replace_instances? }
7
+ it { is_expected.to respond_to :stack_exists? }
8
8
 
9
9
  describe '#ok_to_replace_instances?' do
10
- subject(:r) do
10
+ subject() do
11
11
  AWS.stub!
12
- r = Automan::Cloudformation::Replacer.new
12
+ Automan::Cloudformation::Replacer.new
13
13
  end
14
14
 
15
15
  good_states = %w[UPDATE_COMPLETE]
@@ -30,28 +30,28 @@ describe Automan::Cloudformation::Replacer do
30
30
 
31
31
  good_states.each do |state|
32
32
  it "returns true when stack is in the right state (state: #{state})" do
33
- r.ok_to_replace_instances?(state, Time.now).should be_true
33
+ expect(subject.ok_to_replace_instances?(state, Time.now)).to be_truthy
34
34
  end
35
35
  end
36
36
 
37
37
  good_states.each do |state|
38
38
  it "returns false when stack is in the right state but has not been updated in the last 5m" do
39
39
  last_updated = Time.now - (5 * 60 + 1)
40
- r.ok_to_replace_instances?(state, last_updated).should be_false
40
+ expect(subject.ok_to_replace_instances?(state, last_updated)).to be_falsey
41
41
  end
42
42
  end
43
43
 
44
44
  bad_states.each do |state|
45
45
  it "raises error when stack is borked (state: #{state})" do
46
46
  expect {
47
- r.ok_to_replace_instances?(state, Time.now)
47
+ subject.ok_to_replace_instances?(state, Time.now)
48
48
  }.to raise_error Automan::Cloudformation::StackBrokenError
49
49
  end
50
50
  end
51
51
 
52
52
  wait_states.each do |state|
53
53
  it "returns false when it is not yet ok to replace (state: #{state})" do
54
- r.ok_to_replace_instances?(state, Time.now).should be_false
54
+ expect(subject.ok_to_replace_instances?(state, Time.now)).to be_falsey
55
55
  end
56
56
  end
57
57
  end
@@ -1,15 +1,15 @@
1
1
  require 'automan'
2
2
 
3
3
  describe Automan::Cloudformation::Terminator do
4
- it { should respond_to :name }
5
- it { should respond_to :terminate }
6
- it { should respond_to :stack_exists? }
7
- it { should respond_to :stack_deleted? }
8
- it { should respond_to :delete_stack }
9
- it { should respond_to :wait_for_completion }
4
+ it { is_expected.to respond_to :name }
5
+ it { is_expected.to respond_to :terminate }
6
+ it { is_expected.to respond_to :stack_exists? }
7
+ it { is_expected.to respond_to :stack_deleted? }
8
+ it { is_expected.to respond_to :delete_stack }
9
+ it { is_expected.to respond_to :wait_for_completion }
10
10
 
11
11
  describe '#terminate' do
12
- subject(:t) do
12
+ subject() do
13
13
  AWS.stub!
14
14
  t = Automan::Cloudformation::Terminator.new
15
15
  t.logger = Logger.new('/dev/null')
@@ -17,20 +17,20 @@ describe Automan::Cloudformation::Terminator do
17
17
  end
18
18
 
19
19
  it 'should call #delete_stack if the stack exists' do
20
- t.stub(:stack_exists?).and_return(true)
21
- t.should_receive :delete_stack
22
- t.terminate
20
+ allow(subject).to receive(:stack_exists?).and_return(true)
21
+ expect(subject).to receive :delete_stack
22
+ subject.terminate
23
23
  end
24
24
 
25
25
  it 'should not call #delete_stack if the stack does not exist' do
26
- t.stub(:stack_exists?).and_return(false)
27
- t.should_not_receive :delete_stack
28
- t.terminate
26
+ allow(subject).to receive(:stack_exists?).and_return(false)
27
+ expect(subject).to_not receive :delete_stack
28
+ subject.terminate
29
29
  end
30
30
  end
31
31
 
32
32
  describe '#stack_deleted?' do
33
- subject(:t) do
33
+ subject() do
34
34
  AWS.stub!
35
35
  t = Automan::Cloudformation::Terminator.new
36
36
  t.logger = Logger.new('/dev/null')
@@ -38,26 +38,26 @@ describe Automan::Cloudformation::Terminator do
38
38
  end
39
39
 
40
40
  it 'returns true if the stack does not exist' do
41
- t.stub(:stack_exists?).and_return(false)
42
- t.stub(:stack_status).and_raise StandardError
43
- t.stack_deleted?('foo').should be_true
41
+ allow(subject).to receive(:stack_exists?).and_return(false)
42
+ allow(subject).to receive(:stack_status).and_raise StandardError
43
+ expect(subject.stack_deleted?('foo')).to be_truthy
44
44
  end
45
45
 
46
46
  it 'returns true when status is DELETE_COMPLETE' do
47
- t.stub(:stack_status).and_return('DELETE_COMPLETE')
48
- t.stack_deleted?('foo').should be_true
47
+ allow(subject).to receive(:stack_status).and_return('DELETE_COMPLETE')
48
+ expect(subject.stack_deleted?('foo')).to be_truthy
49
49
  end
50
50
 
51
51
  it 'raises an error when the delete fails' do
52
- t.stub(:stack_status).and_return('DELETE_FAILED')
52
+ allow(subject).to receive(:stack_status).and_return('DELETE_FAILED')
53
53
  expect {
54
- t.stack_deleted?('foo')
54
+ subject.stack_deleted?('foo')
55
55
  }.to raise_error Automan::Cloudformation::StackDeletionError
56
56
  end
57
57
 
58
58
  it 'returns false for any other status' do
59
- t.stub(:stack_status).and_return('foo')
60
- t.stack_deleted?('foo').should be_false
59
+ allow(subject).to receive(:stack_status).and_return('foo')
60
+ expect(subject.stack_deleted?('foo')).to be_falsey
61
61
  end
62
62
  end
63
63
  end
@@ -1,11 +1,11 @@
1
1
  require 'automan'
2
2
 
3
3
  describe Automan::Cloudformation::Uploader do
4
- subject(:u) do
4
+ subject() do
5
5
  AWS.stub!
6
6
  u = Automan::Cloudformation::Uploader.new
7
7
  u.logger = Logger.new('/dev/null')
8
- u.stub(:templates).and_return(%w[a b c])
8
+ allow(u).to receive(:templates).and_return(%w[a b c])
9
9
  u
10
10
  end
11
11
 
@@ -16,35 +16,35 @@ describe Automan::Cloudformation::Uploader do
16
16
 
17
17
  describe '#all_templates_valid?' do
18
18
  it "raises error if there are no templates" do
19
- u.stub(:templates).and_return([])
19
+ allow(subject).to receive(:templates).and_return([])
20
20
  expect {
21
- u.all_templates_valid?
21
+ subject.all_templates_valid?
22
22
  }.to raise_error Automan::Cloudformation::NoTemplatesError
23
23
  end
24
24
 
25
25
  it 'returns true if templates are valid' do
26
- u.should_receive(:template_valid?).exactly(3).times.and_return(true)
27
- u.all_templates_valid?.should be_true
26
+ expect(subject).to receive(:template_valid?).exactly(3).times.and_return(true)
27
+ expect(subject.all_templates_valid?).to be_truthy
28
28
  end
29
29
 
30
30
  it 'returns false if any templates are invalid' do
31
- u.stub(:template_valid?).and_return(false)
32
- u.all_templates_valid?.should be_false
31
+ allow(subject).to receive(:template_valid?).and_return(false)
32
+ expect(subject.all_templates_valid?).to be_falsey
33
33
  end
34
34
  end
35
35
 
36
36
  describe '#upload_templates' do
37
37
  it 'raises error if any template fails validation' do
38
- u.stub(:all_templates_valid?).and_return(false)
38
+ allow(subject).to receive(:all_templates_valid?).and_return(false)
39
39
  expect {
40
- u.upload_templates
40
+ subject.upload_templates
41
41
  }.to raise_error(Automan::Cloudformation::InvalidTemplateError)
42
42
  end
43
43
 
44
44
  it 'uploads files if all are valid' do
45
- u.stub(:all_templates_valid?).and_return(true)
46
- u.should_receive(:upload_file).exactly(3).times
47
- u.upload_templates
45
+ allow(subject).to receive(:all_templates_valid?).and_return(true)
46
+ expect(subject).to receive(:upload_file).exactly(3).times
47
+ subject.upload_templates
48
48
  end
49
49
  end
50
50
  end