vm_shepherd 1.2.0 → 1.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: 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