vm_shepherd 1.2.0 → 1.3.0

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: d4efffe61b1dadc42e8b80ea6418891f27123a06
4
- data.tar.gz: 7939d7f0d8dfb2f0adb5cf189fb548e214e9f55b
3
+ metadata.gz: 80b5490aee5b7e2b0432d36155d4e6b201692246
4
+ data.tar.gz: c7e60bc1d890dcb7f568c35f5d65306c4e269671
5
5
  SHA512:
6
- metadata.gz: f3051aeb00de1e9af855be8b5613304586e598cfc60e4b303f4f0207ec0c83c3c0ccde5059f1c0eb34e790afb719fdea8502614d612d5b009c7238365441834a
7
- data.tar.gz: 3a5b21ce773494d42dd0fcd93454d93621e6982a759905167c32991a7d4c471adca20099783ff702d322b24bf0e74e75c77c8cee2c0012b92b8d716362ac8dad
6
+ metadata.gz: 7af47b2d7345668ef156e44bd9cabd60f15a561e66529f2ae7467af085725da385cae0126d81eee46ef8deab5d4f268e131b81eaea5d49ea9492a415838a38a2
7
+ data.tar.gz: 488c4b9d8393ce2ad2f93e5076820f9a57f8debb3ebeef571a306d1a8f5db4707f57517af700c4e4138bb1276d77b6c614c40ec4f8186f8e2b6c331910bb211c
@@ -8,6 +8,7 @@ module VmShepherd
8
8
  AWS_REGION = 'us-east-1'
9
9
  OPS_MANAGER_INSTANCE_TYPE = 'm3.medium'
10
10
  DO_NOT_TERMINATE_TAG_KEY = 'do_not_terminate'
11
+ ELB_SECURITY_GROUP_NAME = 'ELB Security Group'
11
12
 
12
13
  def initialize(env_config)
13
14
  AWS.config(
@@ -22,7 +23,7 @@ module VmShepherd
22
23
  template = File.read(cloudformation_template_file)
23
24
 
24
25
  cfm = AWS::CloudFormation.new
25
- stack = cfm.stacks.create(env_config.fetch(:stack_name), template, :parameters => env_config.fetch(:parameters), capabilities: ['CAPABILITY_IAM'])
26
+ stack = cfm.stacks.create(env_config.fetch(:stack_name), template, parameters: env_config.fetch(:parameters), capabilities: ['CAPABILITY_IAM'])
26
27
 
27
28
  retry_until(retry_limit: 360) do
28
29
  status = stack.status
@@ -38,6 +39,10 @@ module VmShepherd
38
39
  raise "Unexpected status for stack #{env_config.fetch(:stack_name)} : #{status}"
39
40
  end
40
41
  end
42
+
43
+ if (elb_config = env_config[:elb])
44
+ create_elb(stack, elb_config)
45
+ end
41
46
  end
42
47
 
43
48
  def deploy(ami_file_path:, vm_config:)
@@ -72,40 +77,21 @@ module VmShepherd
72
77
  end
73
78
 
74
79
  def clean_environment
75
- subnets = []
76
- subnets << AWS.ec2.subnets[env_config.fetch(:outputs).fetch(:public_subnet_id)] if env_config.fetch(:outputs).fetch(:public_subnet_id)
77
- subnets << AWS.ec2.subnets[env_config.fetch(:outputs).fetch(:private_subnet_id)] if env_config.fetch(:outputs).fetch(:private_subnet_id)
80
+ [:public_subnet_id, :private_subnet_id].each do |subnet_id|
81
+ subnet_id = env_config.fetch(:outputs).fetch(subnet_id)
82
+ clear_subnet(subnet_id)
83
+ end
78
84
 
79
- volumes = []
80
- subnets.each do |subnet|
81
- subnet.instances.each do |instance|
82
- instance.attachments.each do |_, attachment|
83
- volumes.push(attachment.volume) unless attachment.delete_on_termination
84
- end
85
- instance.terminate
86
- end
85
+ if (elb_config = env_config[:elb])
86
+ delete_elb(elb_config[:name])
87
87
  end
88
- destroy_volumes(volumes)
89
88
 
90
- cfm = AWS::CloudFormation.new
91
- stack = cfm.stacks[env_config.fetch(:stack_name)]
92
- stack.delete
93
- retry_until(retry_limit: 360) do
94
- begin
95
- status = stack.status
96
- case status
97
- when 'DELETE_COMPLETE'
98
- true
99
- when 'DELETE_IN_PROGRESS'
100
- false
101
- else
102
- raise "Unexpected status for stack #{env_config.fetch(:stack_name)} : #{status}"
103
- end
104
- rescue AWS::CloudFormation::Errors::ValidationError
105
- raise if stack.exists?
106
- true
107
- end
108
- end if stack
89
+ if (bucket_name = env_config.fetch(:outputs, {}).fetch(:s3_bucket_name, nil))
90
+ bucket = AWS::S3.new.buckets[bucket_name]
91
+ bucket.clear! if bucket && bucket.exists?
92
+ end
93
+
94
+ delete_stack(env_config.fetch(:stack_name))
109
95
  end
110
96
 
111
97
  def destroy(vm_config)
@@ -124,6 +110,26 @@ module VmShepherd
124
110
  private
125
111
  attr_reader :env_config
126
112
 
113
+ def subnet_id(stack, elb_config)
114
+ stack.outputs.detect { |o| o.key == elb_config[:stack_output_keys][:subnet_id] }.value
115
+ end
116
+
117
+ def vpc_id(stack, elb_config)
118
+ stack.outputs.detect { |o| o.key == elb_config[:stack_output_keys][:vpc_id] }.value
119
+ end
120
+
121
+ def clear_subnet(subnet_id)
122
+ subnet = AWS.ec2.subnets[subnet_id]
123
+ volumes = []
124
+ subnet.instances.each do |instance|
125
+ instance.attachments.each do |_, attachment|
126
+ volumes.push(attachment.volume) unless attachment.delete_on_termination
127
+ end
128
+ instance.terminate
129
+ end
130
+ destroy_volumes(volumes)
131
+ end
132
+
127
133
  def destroy_volumes(volumes)
128
134
  volumes.each do |volume|
129
135
  begin
@@ -134,5 +140,75 @@ module VmShepherd
134
140
  end
135
141
  end
136
142
  end
143
+
144
+ def delete_elb(elb_name)
145
+ if (elb = AWS::ELB.new.load_balancers.find { |lb| lb.name == elb_name })
146
+ sg = elb.security_groups.first
147
+ net_interfaces = AWS.ec2.network_interfaces.select { |ni| ni.security_groups.map(&:id).include? sg.id }
148
+ elb.delete
149
+ retry_until do
150
+ !elb.exists? && !net_interfaces.map(&:exists?).any?
151
+ end
152
+ sg.delete
153
+ end
154
+ end
155
+
156
+ def create_elb(stack, elb_config)
157
+ elb = AWS::ELB.new
158
+ elb_params = {
159
+ load_balancer_name: elb_config[:name],
160
+ listeners: [],
161
+ subnets: [subnet_id(stack, elb_config)],
162
+ security_groups: [create_security_group(stack, elb_config).security_group_id]
163
+ }
164
+
165
+ elb_config[:port_mappings].each do |port_mapping|
166
+ elb_params[:listeners] << {
167
+ protocol: 'TCP', load_balancer_port: port_mapping[0],
168
+ instance_protocol: 'TCP', instance_port: port_mapping[1]
169
+ }
170
+ end
171
+
172
+ elb.client.create_load_balancer(elb_params)
173
+ end
174
+
175
+ def create_security_group(stack, elb_config)
176
+ vpc_id = vpc_id(stack, elb_config)
177
+ sg_params = {
178
+ group_name: stack.name,
179
+ description: 'ELB Security Group',
180
+ vpc_id: vpc_id,
181
+ }
182
+
183
+ security_group_response = AWS.ec2.client.create_security_group(sg_params)
184
+
185
+ AWS.ec2.security_groups[security_group_response[:group_id]].tap do |security_group|
186
+ elb_config[:port_mappings].each do |port_mapping|
187
+ security_group.authorize_ingress(:tcp, port_mapping[0], '0.0.0.0/0')
188
+ end
189
+ end
190
+ end
191
+
192
+ def delete_stack(stack_name)
193
+ cfm = AWS::CloudFormation.new
194
+ stack = cfm.stacks[stack_name]
195
+ stack.delete
196
+ retry_until(retry_limit: 360) do
197
+ begin
198
+ status = stack.status
199
+ case status
200
+ when 'DELETE_COMPLETE'
201
+ true
202
+ when 'DELETE_IN_PROGRESS'
203
+ false
204
+ else
205
+ raise "Unexpected status for stack #{stack_name} : #{status}"
206
+ end
207
+ rescue AWS::CloudFormation::Errors::ValidationError
208
+ raise if stack.exists?
209
+ true
210
+ end
211
+ end if stack
212
+ end
137
213
  end
138
214
  end
@@ -202,7 +202,12 @@ module VmShepherd
202
202
  aws_secret_key: settings.vm_shepherd.env_config.aws_secret_key,
203
203
  json_file: settings.vm_shepherd.env_config.json_file,
204
204
  parameters: settings.vm_shepherd.env_config.parameters_as_a_hash,
205
- outputs: settings.vm_shepherd.env_config.outputs.to_h
205
+ outputs: settings.vm_shepherd.env_config.outputs.to_h,
206
+ elb: {
207
+ name: settings.vm_shepherd.env_config.elb.name,
208
+ port_mappings: settings.vm_shepherd.env_config.elb.port_mappings,
209
+ stack_output_keys: settings.vm_shepherd.env_config.elb.stack_output_keys.to_h,
210
+ },
206
211
  }
207
212
  )
208
213
  end
@@ -1,3 +1,3 @@
1
1
  module VmShepherd
2
- VERSION = '1.2.0'.freeze
2
+ VERSION = '1.3.0'.freeze
3
3
  end
@@ -13,6 +13,13 @@ vm_shepherd:
13
13
  security_group: security-group-id
14
14
  public_subnet_id: public-subnet-id
15
15
  private_subnet_id: private-subnet-id
16
+ s3_bucket_name: bucket-name
17
+ elb:
18
+ name: some-elb-name
19
+ port_mappings: [[1111,11]]
20
+ stack_output_keys:
21
+ vpc_id: CloudFormationVpcIdOutputKey
22
+ subnet_id: CloudFormationSubnetIdOutputKey
16
23
  vm_configs:
17
24
  - vm_name: vm-name
18
25
  - vm_name: vm-name-2
@@ -23,10 +23,13 @@ module VmShepherd
23
23
  security_group: 'security-group-id',
24
24
  public_subnet_id: 'public-subnet-id',
25
25
  private_subnet_id: 'private-subnet-id',
26
- },
27
- }
26
+ }.merge(extra_outputs),
27
+ }.merge(extra_configs)
28
28
  end
29
29
 
30
+ let(:extra_outputs) { {} }
31
+ let(:extra_configs) { {} }
32
+
30
33
  let(:vm_config) do
31
34
  {
32
35
  vm_name: 'some-vm-name',
@@ -51,43 +54,121 @@ module VmShepherd
51
54
  let(:cfm) { instance_double(AWS::CloudFormation, stacks: stack_collection) }
52
55
  let(:stack) { instance_double(AWS::CloudFormation::Stack, status: 'CREATE_COMPLETE') }
53
56
  let(:stack_collection) { instance_double(AWS::CloudFormation::StackCollection) }
57
+ let(:elb) { instance_double(AWS::ELB, client: elb_client) }
58
+ let(:elb_client) { double(AWS::ELB::Client) }
54
59
 
55
60
  before do
56
61
  allow(AWS::CloudFormation).to receive(:new).and_return(cfm)
62
+ allow(AWS::ELB).to receive(:new).and_return(elb)
57
63
  allow(stack_collection).to receive(:create).and_return(stack)
58
64
  end
59
65
 
60
- it 'creates the stack with the correct parameters' do
61
- expect(stack_collection).to receive(:create).with(
62
- 'aws-stack-name',
63
- '{}',
64
- parameters: {
65
- 'some_parameter' => 'some-answer',
66
+ describe 'cloudformation' do
67
+ it 'creates the stack with the correct parameters' do
68
+ expect(stack_collection).to receive(:create).with(
69
+ 'aws-stack-name',
70
+ '{}',
71
+ parameters: {
72
+ 'some_parameter' => 'some-answer',
73
+ },
74
+ capabilities: ['CAPABILITY_IAM']
75
+ )
76
+ ami_manager.prepare_environment(cloudformation_template_file.path)
77
+ end
78
+
79
+ it 'waits for the stack to finish creating' do
80
+ expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_COMPLETE')
81
+
82
+ ami_manager.prepare_environment(cloudformation_template_file.path)
83
+ end
84
+
85
+ it 'stops retrying after 360 times' do
86
+ expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS').
87
+ exactly(360).times
88
+
89
+ expect { ami_manager.prepare_environment(cloudformation_template_file.path) }.to raise_error(AwsManager::RetryLimitExceeded)
90
+ end
91
+
92
+ it 'aborts if stack fails to create' do
93
+ expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_COMPLETE').ordered
94
+ expect(stack).to receive(:delete)
95
+ expect {
96
+ ami_manager.prepare_environment(cloudformation_template_file.path)
97
+ }.to raise_error('Unexpected status for stack aws-stack-name : ROLLBACK_COMPLETE')
98
+ end
99
+ end
100
+
101
+ context 'when the elb setting is present' do
102
+ let(:extra_configs) do
103
+ {
104
+ elb: {
105
+ name: 'elb-name',
106
+ port_mappings: [[1111, 11]],
107
+ stack_output_keys: {
108
+ vpc_id: 'vpc_id',
109
+ subnet_id: 'private_subnet',
110
+ },
66
111
  },
67
- capabilities: ['CAPABILITY_IAM']
112
+ }
113
+ end
114
+ let(:stack) do
115
+ instance_double(AWS::CloudFormation::Stack,
116
+ name: 'fake-stack-name',
117
+ creation_time: Time.utc(2015, 5, 29),
118
+ status: 'CREATE_COMPLETE',
119
+ outputs: stack_outputs
68
120
  )
69
- ami_manager.prepare_environment(cloudformation_template_file.path)
70
- end
121
+ end
122
+ let(:stack_outputs) do
123
+ [
124
+ instance_double(AWS::CloudFormation::StackOutput, key: 'private_subnet', value: 'fake-subnet-id'),
125
+ instance_double(AWS::CloudFormation::StackOutput, key: 'vpc_id', value: 'fake-vpc-id'),
126
+ ]
127
+ end
128
+ let(:ec2_client) { double(AWS::EC2::Client) }
129
+ let(:create_security_group_response) do
130
+ {:group_id => 'elb-security-group'}
131
+ end
132
+ let(:security_groups) do
133
+ {
134
+ 'elb-security-group' => elb_security_group,
135
+ }
136
+ end
137
+ let(:elb_security_group) { instance_double(AWS::EC2::SecurityGroup, security_group_id: 'elb-security-group-id') }
71
138
 
72
- it 'waits for the stack to finish creating' do
73
- expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_COMPLETE')
139
+ before do
140
+ allow(ec2).to receive(:client).and_return(ec2_client)
141
+ allow(ec2_client).to receive(:create_security_group).and_return(create_security_group_response)
142
+ allow(ec2).to receive(:security_groups).and_return(security_groups)
143
+ allow(elb_security_group).to receive(:authorize_ingress)
144
+ allow(elb_client).to receive(:create_load_balancer)
145
+ end
74
146
 
75
- ami_manager.prepare_environment(cloudformation_template_file.path)
76
- end
147
+ it 'creates and attaches a security group' do
148
+ security_group_args = {
149
+ group_name: 'fake-stack-name',
150
+ description: 'ELB Security Group',
151
+ vpc_id: 'fake-vpc-id',
152
+ }
153
+ expect(ec2_client).to receive(:create_security_group).with(security_group_args).and_return(create_security_group_response)
154
+ expect(elb_security_group).to receive(:authorize_ingress).with(:tcp, 1111, '0.0.0.0/0')
77
155
 
78
- it 'stops retrying after 360 times' do
79
- expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS').
80
- exactly(360).times
156
+ ami_manager.prepare_environment(cloudformation_template_file.path)
157
+ end
81
158
 
82
- expect { ami_manager.prepare_environment(cloudformation_template_file.path) }.to raise_error(AwsManager::RetryLimitExceeded)
83
- end
159
+ it 'attaches an elb with the name of the stack' do
160
+ elb_params = {
161
+ load_balancer_name: 'elb-name',
162
+ listeners: [
163
+ {protocol: 'TCP', load_balancer_port: 1111, instance_protocol: 'TCP', instance_port: 11},
164
+ ],
165
+ subnets: ['fake-subnet-id'],
166
+ security_groups: ['elb-security-group-id']
167
+ }
168
+ expect(elb_client).to receive(:create_load_balancer).with(elb_params)
84
169
 
85
- it 'aborts if stack fails to create' do
86
- expect(stack).to receive(:status).and_return('CREATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_COMPLETE').ordered
87
- expect(stack).to receive(:delete)
88
- expect {
89
170
  ami_manager.prepare_environment(cloudformation_template_file.path)
90
- }.to raise_error('Unexpected status for stack aws-stack-name : ROLLBACK_COMPLETE')
171
+ end
91
172
  end
92
173
  end
93
174
 
@@ -183,6 +264,9 @@ module VmShepherd
183
264
  instance_double(AWS::EC2::Attachment, volume: instance1_volume, delete_on_termination: true)
184
265
  end
185
266
 
267
+ let(:buckets) { instance_double(AWS::S3::BucketCollection) }
268
+ let(:s3_client) { instance_double(AWS::S3, buckets: buckets) }
269
+
186
270
  before do
187
271
  allow(AWS::CloudFormation).to receive(:new).and_return(cfm)
188
272
  allow(stack_collection).to receive(:[]).and_return(stack)
@@ -196,6 +280,9 @@ module VmShepherd
196
280
 
197
281
  allow(instance1).to receive(:terminate)
198
282
  allow(instance2).to receive(:terminate)
283
+
284
+ allow(AWS::S3).to receive(:new).and_return(s3_client)
285
+ allow(buckets).to receive(:[]).and_return(instance_double(AWS::S3::Bucket, exists?: false))
199
286
  end
200
287
 
201
288
  it 'terminates all VMs in the subnet' do
@@ -247,6 +334,118 @@ module VmShepherd
247
334
  }.not_to raise_error
248
335
  end
249
336
 
337
+ it 'when an elb is not configured' do
338
+ expect(AWS::ELB).not_to receive(:new)
339
+ ami_manager.clean_environment
340
+ end
341
+
342
+ it 'when there is no s3 bucket configuration' do
343
+ expect_any_instance_of(AWS::S3::Bucket).not_to receive(:clear!)
344
+ ami_manager.clean_environment
345
+ end
346
+
347
+ it 'does not look up buckets when there is no name' do
348
+ expect(buckets).to_not receive(:[])
349
+ ami_manager.clean_environment
350
+ end
351
+
352
+ context 'when a subnet is not provided' do
353
+ #the sdk never returns nil when looking up a subnet and its instances
354
+ let(:subnet2) { instance_double(AWS::EC2::Subnet, instances: []) }
355
+
356
+ it 'only deletes instance 1' do
357
+ expect(instance1).to receive(:terminate)
358
+ expect(instance2).not_to receive(:terminate)
359
+
360
+ ami_manager.clean_environment
361
+ end
362
+ end
363
+
364
+ context 'when an elb is configured' do
365
+ let(:extra_configs) do
366
+ {
367
+ elb: {
368
+ name: 'elb-name',
369
+ stack_output_keys: {
370
+ subnet_id: 'private_subnet',
371
+ },
372
+ },
373
+ }
374
+ end
375
+
376
+ let(:elb) { instance_double(AWS::ELB, load_balancers: [load_balancer_to_delete, other_load_balancer]) }
377
+ let(:load_balancer_to_delete) do
378
+ instance_double(AWS::ELB::LoadBalancer,
379
+ name: 'elb-name',
380
+ security_groups: [elb_security_group],
381
+ exists?: false,
382
+ )
383
+ end
384
+ let(:other_load_balancer) { instance_double(AWS::ELB::LoadBalancer, name: 'other-elb-name') }
385
+ let(:elb_security_group) { instance_double(AWS::EC2::SecurityGroup, name: 'elb-security-group', id: 'sg-id') }
386
+ let(:network_interface_1) do
387
+ instance_double(AWS::EC2::NetworkInterface,
388
+ security_groups: [elb_security_group],
389
+ exists?: false,
390
+ )
391
+ end
392
+ let(:network_interface_2) do
393
+ instance_double(AWS::EC2::NetworkInterface,
394
+ security_groups: [elb_security_group],
395
+ exists?: false,
396
+ )
397
+ end
398
+
399
+ before do
400
+ allow(AWS::ELB).to receive(:new).and_return(elb)
401
+ allow(ec2).to receive(:network_interfaces).and_return([network_interface_1, network_interface_2])
402
+ allow(load_balancer_to_delete).to receive(:delete)
403
+ allow(elb_security_group).to receive(:delete)
404
+ end
405
+
406
+ it 'waits for the elb to be deleted' do
407
+ expect(load_balancer_to_delete).to receive(:exists?).and_return(true).
408
+ exactly(60).times
409
+
410
+ expect(elb_security_group).not_to receive(:delete).ordered
411
+ expect { ami_manager.clean_environment }.to raise_error(AwsManager::RetryLimitExceeded)
412
+ end
413
+
414
+ it 'waits for the network interfaces to be deleted' do
415
+ allow(load_balancer_to_delete).to receive(:exists?).and_return(false)
416
+
417
+ expect(network_interface_1).to receive(:exists?).and_return(false).
418
+ exactly(60).times
419
+
420
+ expect(network_interface_2).to receive(:exists?).and_return(true).
421
+ exactly(60).times
422
+
423
+ expect(elb_security_group).not_to receive(:delete).ordered
424
+ expect { ami_manager.clean_environment }.to raise_error(AwsManager::RetryLimitExceeded)
425
+ end
426
+
427
+ it 'terminates the ELB then removes the security group' do
428
+ expect(load_balancer_to_delete).to receive(:delete).ordered
429
+ expect(elb_security_group).to receive(:delete).ordered
430
+
431
+ ami_manager.clean_environment
432
+ end
433
+
434
+ it 'leaves unknown ELBs alone' do
435
+ expect(other_load_balancer).not_to receive(:delete)
436
+
437
+ ami_manager.clean_environment
438
+ end
439
+
440
+ context 'when the ELB does not exist' do
441
+ let(:elb) { instance_double(AWS::ELB, load_balancers: []) }
442
+
443
+ it 'does not throw an error' do
444
+ expect { ami_manager.clean_environment }.not_to raise_error
445
+ end
446
+ end
447
+ end
448
+
250
449
  context 'when the instance has volumes that are NOT delete_on_termination' do
251
450
  let(:instance1_attachment) do
252
451
  instance_double(AWS::EC2::Attachment, volume: instance1_volume, delete_on_termination: false)
@@ -267,7 +466,6 @@ module VmShepherd
267
466
  before do
268
467
  expect(instance1_volume).to receive(:delete).and_raise(AWS::EC2::Errors::VolumeInUse)
269
468
  expect(instance1_volume).to receive(:delete).and_return(nil)
270
- allow(ami_manager).to receive(:sleep)
271
469
  end
272
470
 
273
471
  it 'retries the delete' do
@@ -275,6 +473,32 @@ module VmShepherd
275
473
  end
276
474
  end
277
475
  end
476
+
477
+ context 'when there is an s3 bucket configuration' do
478
+ let(:bucket) { instance_double(AWS::S3::Bucket) }
479
+ let(:extra_outputs) { {s3_bucket_name: bucket_name} }
480
+ let(:bucket_name) { 'bucket-name' }
481
+
482
+ before { allow(buckets).to receive(:[]).with(bucket_name).and_return(bucket) }
483
+
484
+ context 'and the bucket does exist' do
485
+ before { allow(bucket).to receive(:exists?).and_return(true) }
486
+
487
+ it 'clears the bucket' do
488
+ expect(bucket).to receive(:clear!)
489
+ ami_manager.clean_environment
490
+ end
491
+ end
492
+
493
+ context 'and the bucket does not exist' do
494
+ before { allow(bucket).to receive(:exists?).and_return(false) }
495
+
496
+ it 'fails silently' do
497
+ expect(bucket).not_to receive(:clear!)
498
+ ami_manager.clean_environment
499
+ end
500
+ end
501
+ end
278
502
  end
279
503
 
280
504
  describe '#destroy' do
@@ -9,7 +9,7 @@ module VmShepherd
9
9
  let(:settings) do
10
10
  RecursiveOpenStruct.new(YAML.load_file(File.join(SPEC_ROOT, 'fixtures', 'shepherd', settings_fixture_name)), recurse_over_arrays: true)
11
11
  end
12
- let(:env_config) do
12
+ let(:aws_env_config) do
13
13
  {
14
14
  stack_name: 'aws-stack-name',
15
15
  aws_access_key: 'aws-access-key',
@@ -22,8 +22,17 @@ module VmShepherd
22
22
  ssh_key_name: 'ssh-key-name',
23
23
  security_group: 'security-group-id',
24
24
  public_subnet_id: 'public-subnet-id',
25
- private_subnet_id: 'private-subnet-id'
26
- }
25
+ private_subnet_id: 'private-subnet-id',
26
+ s3_bucket_name: 'bucket-name',
27
+ },
28
+ elb: {
29
+ name: 'some-elb-name',
30
+ port_mappings: [[1111, 11]],
31
+ stack_output_keys: {
32
+ vpc_id: 'CloudFormationVpcIdOutputKey',
33
+ subnet_id: 'CloudFormationSubnetIdOutputKey',
34
+ },
35
+ },
27
36
  }
28
37
  end
29
38
 
@@ -168,7 +177,7 @@ module VmShepherd
168
177
  let(:last_aws_options) { {vm_name: 'vm-name-2'} }
169
178
 
170
179
  it 'uses AwsManager to launch a VM' do
171
- expect(AwsManager).to receive(:new).with(env_config).and_return(aws_manager)
180
+ expect(AwsManager).to receive(:new).with(aws_env_config).and_return(aws_manager)
172
181
  expect(aws_manager).to receive(:deploy).with(ami_file_path: first_ami_file_path, vm_config: first_aws_options)
173
182
  expect(aws_manager).to receive(:deploy).with(ami_file_path: last_ami_file_path, vm_config: last_aws_options)
174
183
 
@@ -333,7 +342,7 @@ module VmShepherd
333
342
  let(:last_ami_options) { {vm_name: 'vm-name-2'} }
334
343
 
335
344
  it 'uses AwsManager to destroy a VM' do
336
- expect(AwsManager).to receive(:new).with(env_config).and_return(aws_manager)
345
+ expect(AwsManager).to receive(:new).with(aws_env_config).and_return(aws_manager)
337
346
  expect(aws_manager).to receive(:destroy).with(first_ami_options)
338
347
  expect(aws_manager).to receive(:destroy).with(last_ami_options)
339
348
 
@@ -500,7 +509,7 @@ module VmShepherd
500
509
  let(:aws_manager) { instance_double(AwsManager) }
501
510
 
502
511
  it 'uses AwsManager to destroy a VM' do
503
- expect(AwsManager).to receive(:new).with(env_config).and_return(aws_manager)
512
+ expect(AwsManager).to receive(:new).with(aws_env_config).and_return(aws_manager)
504
513
  expect(aws_manager).to receive(:clean_environment)
505
514
  manager.clean_environment
506
515
  end
@@ -552,7 +561,7 @@ module VmShepherd
552
561
  let(:ams_manager) { instance_double(AwsManager) }
553
562
 
554
563
  it 'uses AwsManager to create an environment' do
555
- expect(AwsManager).to receive(:new).with(env_config).and_return(ams_manager)
564
+ expect(AwsManager).to receive(:new).with(aws_env_config).and_return(ams_manager)
556
565
  expect(ams_manager).to receive(:prepare_environment).with('cloudformation.json')
557
566
  manager.prepare_environment
558
567
  end
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: 1.2.0
4
+ version: 1.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: 2015-05-28 00:00:00.000000000 Z
11
+ date: 2015-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-v1