vm_shepherd 3.2.1 → 3.3.0

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: c93104a5569a16a2bec5d35a2861429a229c2deb
4
- data.tar.gz: 7495d0600e7d4f2a4a7bee91826182eb245d4529
3
+ metadata.gz: 244e9c4bff360b11b78a561dc70c60501a32cf54
4
+ data.tar.gz: cf11ae1030f1c9b6e2c1ab1e0eb60f938e429825
5
5
  SHA512:
6
- metadata.gz: 3456e991ed128fa9ec34b0556809f36e55a32d048751510dfd4134e57dac113c44da66145d17d5df63f7270522b1c297a616eb91169b8de52a80430c55b3cd45
7
- data.tar.gz: fde39b5b95888111acf5a79a2b39589a369632e77757f357380ea046daa441f882d4c885c8cbf781f71b2bd5f481a9269445f717269f77441aedcbfeffdfa7d3
6
+ metadata.gz: 72acaa44c186bd8508b27534b1e1440738ba94b20ecce4e5cd42d31ef716cac19fb42ffc96b2b5ba3f6fed65f1db58184cc9862583f3b8ec07b33e92aa809dec
7
+ data.tar.gz: e2cc0d3804d5e70e146181092fffc9907b90c67ad716d715bf75c215f4884e5c509eb7f679e16d215aea81e28ef3523d860fb0f58bfd31347d0aacaf47225fe3
@@ -13,6 +13,9 @@ module VmShepherd
13
13
 
14
14
  CREATE_IN_PROGRESS = 'CREATE_IN_PROGRESS'
15
15
  CREATE_COMPLETE = 'CREATE_COMPLETE'
16
+ UPDATE_IN_PROGRESS = 'UPDATE_IN_PROGRESS'
17
+ UPDATE_COMPLETE = 'UPDATE_COMPLETE'
18
+ UPDATE_COMPLETE_CLEANUP_IN_PROGRESS = 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS'
16
19
  ROLLBACK_IN_PROGRESS = 'ROLLBACK_IN_PROGRESS'
17
20
  ROLLBACK_COMPLETE = 'ROLLBACK_COMPLETE'
18
21
  DELETE_IN_PROGRESS = 'DELETE_IN_PROGRESS'
@@ -33,18 +36,35 @@ module VmShepherd
33
36
  template = File.read(cloudformation_template_file)
34
37
 
35
38
  cfm = AWS::CloudFormation.new
36
- logger.info('Starting CloudFormation Stack Creation')
37
- stack = cfm.stacks.create(env_config.fetch('stack_name'), template, parameters: env_config.fetch('parameters'), capabilities: ['CAPABILITY_IAM'])
39
+ stack_name = env_config.fetch('stack_name')
38
40
 
39
- logger.info("Waiting for status: #{CREATE_COMPLETE}")
41
+ stack = cfm.stacks[stack_name]
42
+
43
+ if stack and env_config.fetch('update_existing', false)
44
+ logger.info('Found existing stack - upgrading it')
45
+ stack.update(:template => template, parameters: env_config.fetch('parameters'), capabilities: ['CAPABILITY_IAM'])
46
+ waiting_for_status = UPDATE_COMPLETE
47
+ else
48
+ logger.info('Starting CloudFormation Stack Creation')
49
+ stack = cfm.stacks.create(stack_name, template, parameters: env_config.fetch('parameters'), capabilities: ['CAPABILITY_IAM'])
50
+ waiting_for_status = CREATE_COMPLETE
51
+ end
52
+
53
+ logger.info("Waiting for status [#{waiting_for_status}] on stack [#{stack.name}]")
40
54
  retry_until(retry_limit: 80, retry_interval: 30) do
41
55
  status = stack.status
42
56
  logger.info("current stack status: #{status}")
43
57
  case status
44
58
  when CREATE_COMPLETE
45
59
  true
60
+ when UPDATE_COMPLETE
61
+ true
46
62
  when CREATE_IN_PROGRESS
47
63
  false
64
+ when UPDATE_IN_PROGRESS
65
+ false
66
+ when UPDATE_COMPLETE_CLEANUP_IN_PROGRESS
67
+ false
48
68
  when ROLLBACK_IN_PROGRESS
49
69
  false
50
70
  else
@@ -207,13 +207,14 @@ module VmShepherd
207
207
  @ami_manager ||=
208
208
  VmShepherd::AwsManager.new(
209
209
  env_config: {
210
- 'stack_name' => @env_config.dig('stack_name'),
211
- 'aws_access_key' => @env_config.dig('aws_access_key'),
212
- 'aws_secret_key' => @env_config.dig('aws_secret_key'),
213
- 'region' => @env_config.dig('region'),
214
- 'json_file' => @env_config.dig('json_file'),
215
- 'parameters' => @env_config.dig('parameters'),
216
- 'outputs' => @env_config.dig('outputs'),
210
+ 'stack_name' => @env_config.dig('stack_name'),
211
+ 'aws_access_key' => @env_config.dig('aws_access_key'),
212
+ 'aws_secret_key' => @env_config.dig('aws_secret_key'),
213
+ 'region' => @env_config.dig('region'),
214
+ 'json_file' => @env_config.dig('json_file'),
215
+ 'parameters' => @env_config.dig('parameters'),
216
+ 'outputs' => @env_config.dig('outputs'),
217
+ 'update_existing' => true == @env_config.dig('update_existing'),
217
218
  }.merge(ami_elb_config),
218
219
  logger: stdout_logger,
219
220
  )
@@ -1,3 +1,3 @@
1
1
  module VmShepherd
2
- VERSION = '3.2.1'.freeze
2
+ VERSION = '3.3.0'.freeze
3
3
  end
@@ -58,176 +58,223 @@ module VmShepherd
58
58
 
59
59
  describe '#prepare_environment' do
60
60
  let(:cloudformation_template_file) { Tempfile.new('cloudformation_template_file').tap { |f| f.write('{}'); f.close } }
61
- let(:cfm) { instance_double(AWS::CloudFormation, stacks: stack_collection) }
62
- let(:stack) { instance_double(AWS::CloudFormation::Stack, status: 'CREATE_COMPLETE') }
61
+ let(:cfn) { instance_double(AWS::CloudFormation, stacks: stack_collection) }
62
+ let(:stack) { instance_double(AWS::CloudFormation::Stack, status: 'CREATE_COMPLETE', update: true, name: 'sample-stack') }
63
+
63
64
  let(:stack_collection) { instance_double(AWS::CloudFormation::StackCollection) }
64
65
  let(:elb) { instance_double(AWS::ELB, load_balancers: load_balancers) }
65
66
  let(:load_balancers) { instance_double(AWS::ELB::LoadBalancerCollection) }
66
67
 
67
68
  before do
68
- allow(AWS::CloudFormation).to receive(:new).and_return(cfm)
69
+ allow(AWS::CloudFormation).to receive(:new).and_return(cfn)
69
70
  allow(AWS::ELB).to receive(:new).and_return(elb)
70
- allow(stack_collection).to receive(:create).and_return(stack)
71
+ allow(stack_collection).to receive(:[]).and_return(nil)
71
72
  end
72
73
 
73
- describe 'cloudformation' do
74
- it 'polls the status every 30 seconds' do
75
- expect(ami_manager).to receive(:retry_until).with(retry_limit: 80, retry_interval: 30)
76
-
77
- ami_manager.prepare_environment(cloudformation_template_file.path)
74
+ context 'when a stack already exists' do
75
+ before do
76
+ allow(stack_collection).to receive(:[]).with('aws-stack-name').and_return(stack)
78
77
  end
79
78
 
80
- it 'creates the stack with the correct parameters' do
81
- expect(stack_collection).to receive(:create).with(
82
- 'aws-stack-name',
83
- '{}',
84
- parameters: {
85
- 'some_parameter' => 'some-answer',
86
- },
87
- capabilities: ['CAPABILITY_IAM']
88
- )
89
- ami_manager.prepare_environment(cloudformation_template_file.path)
90
- end
79
+ context 'when update_existing is enabled' do
91
80
 
92
- it 'waits for the stack to finish creating' do
93
- expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_COMPLETE')
81
+ let(:extra_configs) { {'update_existing' => true} }
82
+ let(:stack) { instance_double(AWS::CloudFormation::Stack, status: 'UPDATE_COMPLETE', update: true, name: 'stack-fails-to-update') }
94
83
 
95
- ami_manager.prepare_environment(cloudformation_template_file.path)
96
- end
84
+ it 'upgrades the existing stack with the provided template' do
85
+ ami_manager.prepare_environment(cloudformation_template_file.path)
97
86
 
98
- it 'stops retrying after 80 times' do
99
- expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS').
100
- exactly(80).times
87
+ expect(stack).to have_received(:update)
88
+ end
101
89
 
102
- expect { ami_manager.prepare_environment(cloudformation_template_file.path) }.to raise_error(AwsManager::RetryLimitExceeded)
90
+ it 'aborts if stack fails to update' do
91
+ expect(stack).to receive(:status).and_return('UPDATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_COMPLETE').ordered
92
+ expect(stack).to receive(:delete)
93
+ expect(stack).to receive(:events).and_return([])
94
+ expect {
95
+ ami_manager.prepare_environment(cloudformation_template_file.path)
96
+ }.to raise_error('Unexpected status for stack aws-stack-name : ROLLBACK_COMPLETE')
97
+ end
103
98
  end
104
99
 
105
- it 'aborts if stack fails to create' do
106
- expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_COMPLETE').ordered
107
- expect(stack).to receive(:delete)
108
- expect(stack).to receive(:name).and_return('dummy')
109
- expect(stack).to receive(:events).and_return([])
110
- expect {
100
+ context 'when update_existing is disabled' do
101
+ let(:extra_configs) { {'update_existing' => false} }
102
+
103
+ it 'errors out due to the stack already existing' do
104
+ allow(stack_collection).to receive(:create).and_return(stack)
105
+
111
106
  ami_manager.prepare_environment(cloudformation_template_file.path)
112
- }.to raise_error('Unexpected status for stack aws-stack-name : ROLLBACK_COMPLETE')
107
+
108
+ expect(stack).not_to have_received(:update)
109
+ end
113
110
  end
114
111
  end
115
112
 
116
- context 'when the elb setting is present' do
117
- let(:extra_configs) do
118
- {
119
- 'elbs' => [
120
- {
121
- 'name' => 'elb-1-name',
122
- 'port_mappings' => [[1111, 11]],
123
- 'health_check' => {
124
- 'ping_target' => 'TCP:1234',
125
- },
126
- 'stack_output_keys' => {
127
- 'vpc_id' => 'vpc_id',
128
- 'subnet_id' => 'private_subnet',
129
- },
130
- },
131
- {
132
- 'name' => 'elb-2-name',
133
- 'port_mappings' => [[2222, 22]],
134
- 'stack_output_keys' => {
135
- 'vpc_id' => 'vpc_id',
136
- 'subnet_id' => 'private_subnet',
137
- },
138
- }
139
- ],
140
- }
141
- end
142
- let(:stack) do
143
- instance_double(AWS::CloudFormation::Stack,
144
- name: 'fake-stack-name',
145
- creation_time: Time.utc(2015, 5, 29),
146
- status: 'CREATE_COMPLETE',
147
- outputs: stack_outputs
148
- )
149
- end
150
- let(:stack_outputs) do
151
- [
152
- instance_double(AWS::CloudFormation::StackOutput, key: 'private_subnet', value: 'fake-subnet-id'),
153
- instance_double(AWS::CloudFormation::StackOutput, key: 'vpc_id', value: 'fake-vpc-id'),
154
- ]
155
- end
156
- let(:ec2_client) { double(AWS::EC2::Client) }
157
- let(:create_security_group_response_1) do
158
- {group_id: 'elb-1-security-group'}
159
- end
160
- let(:create_security_group_response_2) do
161
- {group_id: 'elb-2-security-group'}
162
- end
163
- let(:security_groups) do
164
- {
165
- 'elb-1-security-group' => elb_1_security_group,
166
- 'elb-2-security-group' => elb_2_security_group,
167
- }
113
+ context 'when the stack does not yet exist' do
114
+ before do
115
+ allow(stack_collection).to receive(:[]).and_return([])
116
+ allow(stack_collection).to receive(:create).and_return(stack)
168
117
  end
169
- let(:elb_1_security_group) { instance_double(AWS::EC2::SecurityGroup, security_group_id: 'elb-1-security-group-id') }
170
- let(:elb_2_security_group) { instance_double(AWS::EC2::SecurityGroup, security_group_id: 'elb-2-security-group-id') }
171
118
 
172
- let(:elb_1) { instance_double(AWS::ELB::LoadBalancer, configure_health_check: nil) }
173
- let(:elb_2) { instance_double(AWS::ELB::LoadBalancer) }
119
+ describe 'cloudformation' do
120
+ it 'polls the status every 30 seconds' do
121
+ expect(ami_manager).to receive(:retry_until).with(retry_limit: 80, retry_interval: 30)
174
122
 
175
- before do
176
- allow(ec2).to receive(:client).and_return(ec2_client)
177
- allow(ec2_client).to receive(:create_security_group).with(hash_including(group_name: 'fake-stack-name_elb-1-name')).
178
- and_return(create_security_group_response_1)
179
- allow(ec2_client).to receive(:create_security_group).with(hash_including(group_name: 'fake-stack-name_elb-2-name')).
180
- and_return(create_security_group_response_2)
181
- allow(ec2).to receive(:security_groups).and_return(security_groups)
182
- allow(elb_1_security_group).to receive(:authorize_ingress)
183
- allow(elb_2_security_group).to receive(:authorize_ingress)
184
- allow(load_balancers).to receive(:create).and_return(elb_1)
185
- end
186
-
187
- it 'creates and attaches a security group for the ELBs' do
188
- elb_1_security_group_args = {
189
- group_name: 'fake-stack-name_elb-1-name',
190
- description: 'ELB Security Group',
191
- vpc_id: 'fake-vpc-id',
192
- }
193
- expect(ec2_client).to receive(:create_security_group).with(elb_1_security_group_args).and_return(create_security_group_response_1)
194
- expect(elb_1_security_group).to receive(:authorize_ingress).with(:tcp, 1111, '0.0.0.0/0')
123
+ ami_manager.prepare_environment(cloudformation_template_file.path)
124
+ end
195
125
 
196
- elb_2_security_group_args = {
197
- group_name: 'fake-stack-name_elb-2-name',
198
- description: 'ELB Security Group',
199
- vpc_id: 'fake-vpc-id',
200
- }
201
- expect(ec2_client).to receive(:create_security_group).with(elb_2_security_group_args).and_return(create_security_group_response_2)
202
- expect(elb_2_security_group).to receive(:authorize_ingress).with(:tcp, 2222, '0.0.0.0/0')
126
+ it 'creates the stack with the correct parameters' do
127
+ expect(stack_collection).to receive(:create).with(
128
+ 'aws-stack-name',
129
+ '{}',
130
+ parameters: {
131
+ 'some_parameter' => 'some-answer',
132
+ },
133
+ capabilities: ['CAPABILITY_IAM']
134
+ )
135
+ ami_manager.prepare_environment(cloudformation_template_file.path)
136
+ end
137
+
138
+ it 'waits for the stack to finish creating' do
139
+ expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_COMPLETE')
203
140
 
204
- ami_manager.prepare_environment(cloudformation_template_file.path)
141
+ ami_manager.prepare_environment(cloudformation_template_file.path)
142
+ end
143
+
144
+ it 'stops retrying after 80 times' do
145
+ expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS').
146
+ exactly(80).times
147
+
148
+ expect { ami_manager.prepare_environment(cloudformation_template_file.path) }.to raise_error(AwsManager::RetryLimitExceeded)
149
+ end
150
+
151
+ it 'aborts if stack fails to create' do
152
+ expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_COMPLETE').ordered
153
+ expect(stack).to receive(:delete)
154
+ expect(stack).to receive(:name).and_return('dummy')
155
+ expect(stack).to receive(:events).and_return([])
156
+ expect {
157
+ ami_manager.prepare_environment(cloudformation_template_file.path)
158
+ }.to raise_error('Unexpected status for stack aws-stack-name : ROLLBACK_COMPLETE')
159
+ end
205
160
  end
206
161
 
207
- it 'attaches an elb with the name of the stack for the ELBs' do
208
- health_check_params = {
209
- healthy_threshold: 2,
210
- unhealthy_threshold: 5,
211
- interval: 5,
212
- timeout: 2,
213
- }
214
- elb_1_params = {
215
- listeners: [{protocol: 'TCP', load_balancer_port: 1111, instance_protocol: 'TCP', instance_port: 11}],
216
- subnets: ['fake-subnet-id'],
217
- security_groups: ['elb-1-security-group-id']
218
- }
219
- expect(load_balancers).to receive(:create).with('elb-1-name', elb_1_params).and_return(elb_1)
220
- expect(elb_1).to receive(:configure_health_check).with(
221
- health_check_params.merge(target: 'TCP:1234')
222
- )
223
- elb_2_params = {
224
- listeners: [{protocol: 'TCP', load_balancer_port: 2222, instance_protocol: 'TCP', instance_port: 22}],
225
- subnets: ['fake-subnet-id'],
226
- security_groups: ['elb-2-security-group-id']
227
- }
228
- expect(load_balancers).to receive(:create).with('elb-2-name', elb_2_params).and_return(elb_2)
229
- expect(elb_2).not_to receive(:configure_health_check)
230
- ami_manager.prepare_environment(cloudformation_template_file.path)
162
+ context 'when the elb setting is present' do
163
+ let(:extra_configs) do
164
+ {
165
+ 'elbs' => [
166
+ {
167
+ 'name' => 'elb-1-name',
168
+ 'port_mappings' => [[1111, 11]],
169
+ 'health_check' => {
170
+ 'ping_target' => 'TCP:1234',
171
+ },
172
+ 'stack_output_keys' => {
173
+ 'vpc_id' => 'vpc_id',
174
+ 'subnet_id' => 'private_subnet',
175
+ },
176
+ },
177
+ {
178
+ 'name' => 'elb-2-name',
179
+ 'port_mappings' => [[2222, 22]],
180
+ 'stack_output_keys' => {
181
+ 'vpc_id' => 'vpc_id',
182
+ 'subnet_id' => 'private_subnet',
183
+ },
184
+ }
185
+ ],
186
+ }
187
+ end
188
+ let(:stack) do
189
+ instance_double(AWS::CloudFormation::Stack,
190
+ name: 'fake-stack-name',
191
+ creation_time: Time.utc(2015, 5, 29),
192
+ status: 'CREATE_COMPLETE',
193
+ outputs: stack_outputs
194
+ )
195
+ end
196
+ let(:stack_outputs) do
197
+ [
198
+ instance_double(AWS::CloudFormation::StackOutput, key: 'private_subnet', value: 'fake-subnet-id'),
199
+ instance_double(AWS::CloudFormation::StackOutput, key: 'vpc_id', value: 'fake-vpc-id'),
200
+ ]
201
+ end
202
+ let(:ec2_client) { double(AWS::EC2::Client) }
203
+ let(:create_security_group_response_1) do
204
+ {group_id: 'elb-1-security-group'}
205
+ end
206
+ let(:create_security_group_response_2) do
207
+ {group_id: 'elb-2-security-group'}
208
+ end
209
+ let(:security_groups) do
210
+ {
211
+ 'elb-1-security-group' => elb_1_security_group,
212
+ 'elb-2-security-group' => elb_2_security_group,
213
+ }
214
+ end
215
+ let(:elb_1_security_group) { instance_double(AWS::EC2::SecurityGroup, security_group_id: 'elb-1-security-group-id') }
216
+ let(:elb_2_security_group) { instance_double(AWS::EC2::SecurityGroup, security_group_id: 'elb-2-security-group-id') }
217
+
218
+ let(:elb_1) { instance_double(AWS::ELB::LoadBalancer, configure_health_check: nil) }
219
+ let(:elb_2) { instance_double(AWS::ELB::LoadBalancer) }
220
+
221
+ before do
222
+ allow(ec2).to receive(:client).and_return(ec2_client)
223
+ allow(ec2_client).to receive(:create_security_group).with(hash_including(group_name: 'fake-stack-name_elb-1-name')).
224
+ and_return(create_security_group_response_1)
225
+ allow(ec2_client).to receive(:create_security_group).with(hash_including(group_name: 'fake-stack-name_elb-2-name')).
226
+ and_return(create_security_group_response_2)
227
+ allow(ec2).to receive(:security_groups).and_return(security_groups)
228
+ allow(elb_1_security_group).to receive(:authorize_ingress)
229
+ allow(elb_2_security_group).to receive(:authorize_ingress)
230
+ allow(load_balancers).to receive(:create).and_return(elb_1)
231
+ end
232
+
233
+ it 'creates and attaches a security group for the ELBs' do
234
+ elb_1_security_group_args = {
235
+ group_name: 'fake-stack-name_elb-1-name',
236
+ description: 'ELB Security Group',
237
+ vpc_id: 'fake-vpc-id',
238
+ }
239
+ expect(ec2_client).to receive(:create_security_group).with(elb_1_security_group_args).and_return(create_security_group_response_1)
240
+ expect(elb_1_security_group).to receive(:authorize_ingress).with(:tcp, 1111, '0.0.0.0/0')
241
+
242
+ elb_2_security_group_args = {
243
+ group_name: 'fake-stack-name_elb-2-name',
244
+ description: 'ELB Security Group',
245
+ vpc_id: 'fake-vpc-id',
246
+ }
247
+ expect(ec2_client).to receive(:create_security_group).with(elb_2_security_group_args).and_return(create_security_group_response_2)
248
+ expect(elb_2_security_group).to receive(:authorize_ingress).with(:tcp, 2222, '0.0.0.0/0')
249
+
250
+ ami_manager.prepare_environment(cloudformation_template_file.path)
251
+ end
252
+
253
+ it 'attaches an elb with the name of the stack for the ELBs' do
254
+ health_check_params = {
255
+ healthy_threshold: 2,
256
+ unhealthy_threshold: 5,
257
+ interval: 5,
258
+ timeout: 2,
259
+ }
260
+ elb_1_params = {
261
+ listeners: [{protocol: 'TCP', load_balancer_port: 1111, instance_protocol: 'TCP', instance_port: 11}],
262
+ subnets: ['fake-subnet-id'],
263
+ security_groups: ['elb-1-security-group-id']
264
+ }
265
+ expect(load_balancers).to receive(:create).with('elb-1-name', elb_1_params).and_return(elb_1)
266
+ expect(elb_1).to receive(:configure_health_check).with(
267
+ health_check_params.merge(target: 'TCP:1234')
268
+ )
269
+ elb_2_params = {
270
+ listeners: [{protocol: 'TCP', load_balancer_port: 2222, instance_protocol: 'TCP', instance_port: 22}],
271
+ subnets: ['fake-subnet-id'],
272
+ security_groups: ['elb-2-security-group-id']
273
+ }
274
+ expect(load_balancers).to receive(:create).with('elb-2-name', elb_2_params).and_return(elb_2)
275
+ expect(elb_2).not_to receive(:configure_health_check)
276
+ ami_manager.prepare_environment(cloudformation_template_file.path)
277
+ end
231
278
  end
232
279
  end
233
280
  end
@@ -369,7 +416,7 @@ module VmShepherd
369
416
  let(:instance2) { instance_double(AWS::EC2::Instance, tags: {}, id: 'instance2') }
370
417
  let(:subnet1_instances) { [instance1] }
371
418
  let(:subnet2_instances) { [instance2] }
372
- let(:cfm) { instance_double(AWS::CloudFormation, stacks: stack_collection) }
419
+ let(:cfn) { instance_double(AWS::CloudFormation, stacks: stack_collection) }
373
420
  let(:stack) { instance_double(AWS::CloudFormation::Stack, status: 'DELETE_COMPLETE', delete: nil) }
374
421
  let(:stack_collection) { instance_double(AWS::CloudFormation::StackCollection) }
375
422
 
@@ -382,7 +429,7 @@ module VmShepherd
382
429
  let(:s3_client) { instance_double(AWS::S3, buckets: buckets) }
383
430
 
384
431
  before do
385
- allow(AWS::CloudFormation).to receive(:new).and_return(cfm)
432
+ allow(AWS::CloudFormation).to receive(:new).and_return(cfn)
386
433
  allow(stack_collection).to receive(:[]).and_return(stack)
387
434
 
388
435
  allow(ec2).to receive(:subnets).and_return(subnets)
@@ -16,6 +16,7 @@ module VmShepherd
16
16
  'aws_secret_key' => 'aws-secret-key',
17
17
  'region' => 'aws-region',
18
18
  'json_file' => 'cloudformation.json',
19
+ 'update_existing' => false,
19
20
  'parameters' => {
20
21
  'key_pair_name' => 'key_pair_name'
21
22
  },
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vm_shepherd
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.1
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ops Manager Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-29 00:00:00.000000000 Z
11
+ date: 2016-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-v1