vm_shepherd 3.0.4 → 3.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/vm_shepherd/aws_manager.rb +40 -31
- data/lib/vm_shepherd/version.rb +1 -1
- data/spec/vm_shepherd/aws_manager_spec.rb +81 -62
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66180f53e136f3ed2f438bc830ac0b81e72e9981
|
4
|
+
data.tar.gz: 53a28aa4ac6738c43490c19f8f6ea75f41cf6c66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94d07d4851ee5f95c27e2955e15da9160f40636177f4e12f33b3ada3be01a2bc835e16de85d82bada775c1a2f83489a02d9a72f26a89efed4e596a66d5c6279f
|
7
|
+
data.tar.gz: 2a9da981e0d32cbb622170c4d42dc44a6d4ff829aaa08da3473e2ca2132017adc0e8bf22a59230f9901f3b17c5284219ff8d80a24cc44aa80583085e63cfdb2d
|
@@ -8,24 +8,24 @@ module VmShepherd
|
|
8
8
|
include VmShepherd::RetryHelper
|
9
9
|
|
10
10
|
OPS_MANAGER_INSTANCE_TYPE = 'm3.medium'
|
11
|
-
DO_NOT_TERMINATE_TAG_KEY
|
12
|
-
ELB_SECURITY_GROUP_NAME
|
11
|
+
DO_NOT_TERMINATE_TAG_KEY = 'do_not_terminate'
|
12
|
+
ELB_SECURITY_GROUP_NAME = 'ELB Security Group'
|
13
13
|
|
14
|
-
CREATE_IN_PROGRESS
|
15
|
-
CREATE_COMPLETE
|
14
|
+
CREATE_IN_PROGRESS = 'CREATE_IN_PROGRESS'
|
15
|
+
CREATE_COMPLETE = 'CREATE_COMPLETE'
|
16
16
|
ROLLBACK_IN_PROGRESS = 'ROLLBACK_IN_PROGRESS'
|
17
|
-
ROLLBACK_COMPLETE
|
18
|
-
DELETE_IN_PROGRESS
|
19
|
-
DELETE_COMPLETE
|
17
|
+
ROLLBACK_COMPLETE = 'ROLLBACK_COMPLETE'
|
18
|
+
DELETE_IN_PROGRESS = 'DELETE_IN_PROGRESS'
|
19
|
+
DELETE_COMPLETE = 'DELETE_COMPLETE'
|
20
20
|
|
21
21
|
def initialize(env_config:, logger:)
|
22
22
|
AWS.config(
|
23
|
-
access_key_id:
|
23
|
+
access_key_id: env_config.fetch('aws_access_key'),
|
24
24
|
secret_access_key: env_config.fetch('aws_secret_key'),
|
25
|
-
region:
|
25
|
+
region: env_config.fetch('region'),
|
26
26
|
)
|
27
27
|
@env_config = env_config
|
28
|
-
@logger
|
28
|
+
@logger = logger
|
29
29
|
end
|
30
30
|
|
31
31
|
def prepare_environment(cloudformation_template_file)
|
@@ -58,19 +58,11 @@ module VmShepherd
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def deploy(ami_file_path:, vm_config:)
|
61
|
-
image_id = read_ami_id(ami_file_path)
|
62
|
-
|
63
61
|
logger.info('Starting AMI Instance creation')
|
64
62
|
instance =
|
65
63
|
retry_until do
|
66
64
|
begin
|
67
|
-
AWS.ec2.instances.create(
|
68
|
-
image_id: image_id,
|
69
|
-
key_name: env_config.fetch('outputs').fetch('ssh_key_name'),
|
70
|
-
security_group_ids: [env_config.fetch('outputs').fetch('security_group')],
|
71
|
-
subnet: env_config.fetch('outputs').fetch('public_subnet_id'),
|
72
|
-
instance_type: OPS_MANAGER_INSTANCE_TYPE
|
73
|
-
)
|
65
|
+
AWS.ec2.instances.create(instance_create_params(ami_file_path))
|
74
66
|
rescue AWS::EC2::Errors::InvalidIPAddress::InUse
|
75
67
|
false
|
76
68
|
end
|
@@ -128,7 +120,7 @@ module VmShepherd
|
|
128
120
|
AWS.ec2.instances.each do |instance|
|
129
121
|
if instance.tags.to_h['Name'] == vm_config.fetch('vm_name')
|
130
122
|
vm_ip_address = vm_config.fetch('vm_ip_address', nil)
|
131
|
-
elastic_ip
|
123
|
+
elastic_ip = instance.elastic_ip unless vm_ip_address
|
132
124
|
if elastic_ip
|
133
125
|
elastic_ip.disassociate
|
134
126
|
elastic_ip.delete
|
@@ -141,6 +133,23 @@ module VmShepherd
|
|
141
133
|
private
|
142
134
|
attr_reader :env_config, :logger
|
143
135
|
|
136
|
+
def instance_create_params(ami_file_path)
|
137
|
+
create_params =
|
138
|
+
{
|
139
|
+
image_id: read_ami_id(ami_file_path),
|
140
|
+
key_name: env_config.fetch('outputs').fetch('ssh_key_name'),
|
141
|
+
security_group_ids: [env_config.fetch('outputs').fetch('security_group')],
|
142
|
+
subnet: env_config.fetch('outputs').fetch('public_subnet_id'),
|
143
|
+
instance_type: OPS_MANAGER_INSTANCE_TYPE
|
144
|
+
}
|
145
|
+
|
146
|
+
if (instance_profile = env_config.fetch('outputs').fetch('instance_profile'))
|
147
|
+
create_params.merge!(iam_instance_profile: instance_profile)
|
148
|
+
end
|
149
|
+
|
150
|
+
create_params
|
151
|
+
end
|
152
|
+
|
144
153
|
def subnet_id(stack, elb_config)
|
145
154
|
stack.outputs.detect { |o| o.key == elb_config.dig('stack_output_keys', 'subnet_id') }.value
|
146
155
|
end
|
@@ -151,7 +160,7 @@ module VmShepherd
|
|
151
160
|
|
152
161
|
def clear_subnet(subnet_id)
|
153
162
|
logger.info("Clearing contents of subnet: #{subnet_id}")
|
154
|
-
subnet
|
163
|
+
subnet = AWS.ec2.subnets[subnet_id]
|
155
164
|
volumes = []
|
156
165
|
subnet.instances.each do |instance|
|
157
166
|
instance.attachments.each do |_, attachment|
|
@@ -177,7 +186,7 @@ module VmShepherd
|
|
177
186
|
|
178
187
|
def delete_elb(elb_name)
|
179
188
|
if (elb = AWS::ELB.new.load_balancers.find { |lb| lb.name == elb_name })
|
180
|
-
sg
|
189
|
+
sg = elb.security_groups.first
|
181
190
|
net_interfaces = AWS.ec2.network_interfaces.select do |ni|
|
182
191
|
begin
|
183
192
|
ni.security_groups.map(&:id).include? sg.id
|
@@ -197,17 +206,17 @@ module VmShepherd
|
|
197
206
|
end
|
198
207
|
|
199
208
|
def create_elb(stack, elb_config)
|
200
|
-
elb
|
209
|
+
elb = AWS::ELB.new
|
201
210
|
elb_params = {
|
202
211
|
load_balancer_name: elb_config['name'],
|
203
|
-
listeners:
|
204
|
-
subnets:
|
205
|
-
security_groups:
|
212
|
+
listeners: [],
|
213
|
+
subnets: [subnet_id(stack, elb_config)],
|
214
|
+
security_groups: [create_security_group(stack, elb_config).security_group_id]
|
206
215
|
}
|
207
216
|
|
208
217
|
elb_config['port_mappings'].each do |port_mapping|
|
209
218
|
elb_params[:listeners] << {
|
210
|
-
protocol:
|
219
|
+
protocol: 'TCP', load_balancer_port: port_mapping[0],
|
211
220
|
instance_protocol: 'TCP', instance_port: port_mapping[1]
|
212
221
|
}
|
213
222
|
end
|
@@ -217,11 +226,11 @@ module VmShepherd
|
|
217
226
|
end
|
218
227
|
|
219
228
|
def create_security_group(stack, elb_config)
|
220
|
-
vpc_id
|
229
|
+
vpc_id = vpc_id(stack, elb_config)
|
221
230
|
sg_params = {
|
222
|
-
group_name:
|
231
|
+
group_name: [stack.name, elb_config['name']].join('_'),
|
223
232
|
description: 'ELB Security Group',
|
224
|
-
vpc_id:
|
233
|
+
vpc_id: vpc_id,
|
225
234
|
}
|
226
235
|
|
227
236
|
logger.info('Creating a Security Group for the ELB')
|
@@ -235,7 +244,7 @@ module VmShepherd
|
|
235
244
|
end
|
236
245
|
|
237
246
|
def delete_stack(stack_name)
|
238
|
-
cfm
|
247
|
+
cfm = AWS::CloudFormation.new
|
239
248
|
stack = cfm.stacks[stack_name]
|
240
249
|
logger.info('deleting CloudFormation stack')
|
241
250
|
stack.delete
|
data/lib/vm_shepherd/version.rb
CHANGED
@@ -16,19 +16,20 @@ module VmShepherd
|
|
16
16
|
|
17
17
|
let(:env_config) do
|
18
18
|
{
|
19
|
-
'stack_name'
|
19
|
+
'stack_name' => 'aws-stack-name',
|
20
20
|
'aws_access_key' => 'aws-access-key',
|
21
21
|
'aws_secret_key' => 'aws-secret-key',
|
22
|
-
'region'
|
23
|
-
'json_file'
|
24
|
-
'parameters'
|
22
|
+
'region' => 'us-east-1',
|
23
|
+
'json_file' => 'cloudformation.json',
|
24
|
+
'parameters' => {
|
25
25
|
'some_parameter' => 'some-answer',
|
26
26
|
},
|
27
|
-
'outputs'
|
28
|
-
'subnets'
|
29
|
-
'ssh_key_name'
|
30
|
-
'security_group'
|
31
|
-
'public_subnet_id'
|
27
|
+
'outputs' => {
|
28
|
+
'subnets' => ['public-subnet-id', 'private-subnet-id'],
|
29
|
+
'ssh_key_name' => 'ssh-key-name',
|
30
|
+
'security_group' => 'security-group-id',
|
31
|
+
'public_subnet_id' => 'public-subnet-id',
|
32
|
+
'instance_profile' => nil,
|
32
33
|
}.merge(extra_outputs),
|
33
34
|
}.merge(extra_configs)
|
34
35
|
end
|
@@ -47,9 +48,9 @@ module VmShepherd
|
|
47
48
|
|
48
49
|
before do
|
49
50
|
expect(AWS).to receive(:config).with(
|
50
|
-
access_key_id:
|
51
|
+
access_key_id: env_config.fetch('aws_access_key'),
|
51
52
|
secret_access_key: env_config.fetch('aws_secret_key'),
|
52
|
-
region:
|
53
|
+
region: env_config.fetch('region'),
|
53
54
|
)
|
54
55
|
|
55
56
|
allow(AWS).to receive(:ec2).and_return(ec2)
|
@@ -81,7 +82,7 @@ module VmShepherd
|
|
81
82
|
expect(stack_collection).to receive(:create).with(
|
82
83
|
'aws-stack-name',
|
83
84
|
'{}',
|
84
|
-
parameters:
|
85
|
+
parameters: {
|
85
86
|
'some_parameter' => 'some-answer',
|
86
87
|
},
|
87
88
|
capabilities: ['CAPABILITY_IAM']
|
@@ -116,18 +117,18 @@ module VmShepherd
|
|
116
117
|
{
|
117
118
|
'elbs' => [
|
118
119
|
{
|
119
|
-
'name'
|
120
|
-
'port_mappings'
|
120
|
+
'name' => 'elb-1-name',
|
121
|
+
'port_mappings' => [[1111, 11]],
|
121
122
|
'stack_output_keys' => {
|
122
|
-
'vpc_id'
|
123
|
+
'vpc_id' => 'vpc_id',
|
123
124
|
'subnet_id' => 'private_subnet',
|
124
125
|
},
|
125
126
|
},
|
126
127
|
{
|
127
|
-
'name'
|
128
|
-
'port_mappings'
|
128
|
+
'name' => 'elb-2-name',
|
129
|
+
'port_mappings' => [[2222, 22]],
|
129
130
|
'stack_output_keys' => {
|
130
|
-
'vpc_id'
|
131
|
+
'vpc_id' => 'vpc_id',
|
131
132
|
'subnet_id' => 'private_subnet',
|
132
133
|
},
|
133
134
|
}
|
@@ -136,10 +137,10 @@ module VmShepherd
|
|
136
137
|
end
|
137
138
|
let(:stack) do
|
138
139
|
instance_double(AWS::CloudFormation::Stack,
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
140
|
+
name: 'fake-stack-name',
|
141
|
+
creation_time: Time.utc(2015, 5, 29),
|
142
|
+
status: 'CREATE_COMPLETE',
|
143
|
+
outputs: stack_outputs
|
143
144
|
)
|
144
145
|
end
|
145
146
|
let(:stack_outputs) do
|
@@ -178,17 +179,17 @@ module VmShepherd
|
|
178
179
|
|
179
180
|
it 'creates and attaches a security group for the ELBs' do
|
180
181
|
elb_1_security_group_args = {
|
181
|
-
group_name:
|
182
|
+
group_name: 'fake-stack-name_elb-1-name',
|
182
183
|
description: 'ELB Security Group',
|
183
|
-
vpc_id:
|
184
|
+
vpc_id: 'fake-vpc-id',
|
184
185
|
}
|
185
186
|
expect(ec2_client).to receive(:create_security_group).with(elb_1_security_group_args).and_return(create_security_group_response_1)
|
186
187
|
expect(elb_1_security_group).to receive(:authorize_ingress).with(:tcp, 1111, '0.0.0.0/0')
|
187
188
|
|
188
189
|
elb_2_security_group_args = {
|
189
|
-
group_name:
|
190
|
+
group_name: 'fake-stack-name_elb-2-name',
|
190
191
|
description: 'ELB Security Group',
|
191
|
-
vpc_id:
|
192
|
+
vpc_id: 'fake-vpc-id',
|
192
193
|
}
|
193
194
|
expect(ec2_client).to receive(:create_security_group).with(elb_2_security_group_args).and_return(create_security_group_response_2)
|
194
195
|
expect(elb_2_security_group).to receive(:authorize_ingress).with(:tcp, 2222, '0.0.0.0/0')
|
@@ -199,16 +200,16 @@ module VmShepherd
|
|
199
200
|
it 'attaches an elb with the name of the stack for the ELBs' do
|
200
201
|
elb_1_params = {
|
201
202
|
load_balancer_name: 'elb-1-name',
|
202
|
-
listeners:
|
203
|
-
subnets:
|
204
|
-
security_groups:
|
203
|
+
listeners: [{protocol: 'TCP', load_balancer_port: 1111, instance_protocol: 'TCP', instance_port: 11}],
|
204
|
+
subnets: ['fake-subnet-id'],
|
205
|
+
security_groups: ['elb-1-security-group-id']
|
205
206
|
}
|
206
207
|
expect(elb_client).to receive(:create_load_balancer).with(elb_1_params)
|
207
208
|
elb_2_params = {
|
208
209
|
load_balancer_name: 'elb-2-name',
|
209
|
-
listeners:
|
210
|
-
subnets:
|
211
|
-
security_groups:
|
210
|
+
listeners: [{protocol: 'TCP', load_balancer_port: 2222, instance_protocol: 'TCP', instance_port: 22}],
|
211
|
+
subnets: ['fake-subnet-id'],
|
212
|
+
security_groups: ['elb-2-security-group-id']
|
212
213
|
}
|
213
214
|
expect(elb_client).to receive(:create_load_balancer).with(elb_2_params)
|
214
215
|
|
@@ -229,15 +230,33 @@ module VmShepherd
|
|
229
230
|
allow(elastic_ip).to receive(:exists?).and_return(true)
|
230
231
|
end
|
231
232
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
233
|
+
context 'when no IAM Profile is present' do
|
234
|
+
it 'creates an instance' do
|
235
|
+
expect(ec2).to receive_message_chain(:instances, :create).with(
|
236
|
+
image_id: ami_id,
|
237
|
+
key_name: 'ssh-key-name',
|
238
|
+
security_group_ids: ['security-group-id'],
|
239
|
+
subnet: 'public-subnet-id',
|
240
|
+
instance_type: 'm3.medium').and_return(instance)
|
239
241
|
|
240
|
-
|
242
|
+
ami_manager.deploy(ami_file_path: ami_file_path, vm_config: vm_config)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context 'when IAM Profile is present' do
|
247
|
+
let(:extra_outputs) { {'instance_profile' => 'FAKE_INSTANCE_PROFILE'} }
|
248
|
+
|
249
|
+
it 'creates an instance passing the IAM Instance Profile' do
|
250
|
+
expect(ec2).to receive_message_chain(:instances, :create).with(
|
251
|
+
image_id: ami_id,
|
252
|
+
key_name: 'ssh-key-name',
|
253
|
+
security_group_ids: ['security-group-id'],
|
254
|
+
subnet: 'public-subnet-id',
|
255
|
+
iam_instance_profile: 'FAKE_INSTANCE_PROFILE',
|
256
|
+
instance_type: 'm3.medium').and_return(instance)
|
257
|
+
|
258
|
+
ami_manager.deploy(ami_file_path: ami_file_path, vm_config: vm_config)
|
259
|
+
end
|
241
260
|
end
|
242
261
|
|
243
262
|
context 'when the ip address is in use' do
|
@@ -307,7 +326,7 @@ module VmShepherd
|
|
307
326
|
context 'vm configuration contains an elastic IP' do
|
308
327
|
let(:vm_config) do
|
309
328
|
{
|
310
|
-
'vm_name'
|
329
|
+
'vm_name' => 'some-vm-name',
|
311
330
|
'vm_ip_address' => 'some-ip-address'
|
312
331
|
}
|
313
332
|
end
|
@@ -454,18 +473,18 @@ module VmShepherd
|
|
454
473
|
{
|
455
474
|
'elbs' => [
|
456
475
|
{
|
457
|
-
'name'
|
458
|
-
'port_mappings'
|
476
|
+
'name' => 'elb-1-name',
|
477
|
+
'port_mappings' => [[1111, 11]],
|
459
478
|
'stack_output_keys' => {
|
460
|
-
'vpc_id'
|
479
|
+
'vpc_id' => 'vpc_id',
|
461
480
|
'subnet_id' => 'private_subnet',
|
462
481
|
},
|
463
482
|
},
|
464
483
|
{
|
465
|
-
'name'
|
466
|
-
'port_mappings'
|
484
|
+
'name' => 'elb-2-name',
|
485
|
+
'port_mappings' => [[2222, 22]],
|
467
486
|
'stack_output_keys' => {
|
468
|
-
'vpc_id'
|
487
|
+
'vpc_id' => 'vpc_id',
|
469
488
|
'subnet_id' => 'private_subnet',
|
470
489
|
},
|
471
490
|
}
|
@@ -476,16 +495,16 @@ module VmShepherd
|
|
476
495
|
let(:elb) { instance_double(AWS::ELB, load_balancers: [load_balancer_1_to_delete, load_balancer_2_to_delete, other_load_balancer]) }
|
477
496
|
let(:load_balancer_1_to_delete) do
|
478
497
|
instance_double(AWS::ELB::LoadBalancer,
|
479
|
-
|
480
|
-
|
481
|
-
|
498
|
+
name: 'elb-1-name',
|
499
|
+
security_groups: [elb_1_security_group],
|
500
|
+
exists?: false,
|
482
501
|
)
|
483
502
|
end
|
484
503
|
let(:load_balancer_2_to_delete) do
|
485
504
|
instance_double(AWS::ELB::LoadBalancer,
|
486
|
-
|
487
|
-
|
488
|
-
|
505
|
+
name: 'elb-2-name',
|
506
|
+
security_groups: [elb_2_security_group],
|
507
|
+
exists?: false,
|
489
508
|
)
|
490
509
|
end
|
491
510
|
let(:other_load_balancer) { instance_double(AWS::ELB::LoadBalancer, name: 'other-elb-name') }
|
@@ -493,26 +512,26 @@ module VmShepherd
|
|
493
512
|
let(:elb_2_security_group) { instance_double(AWS::EC2::SecurityGroup, name: 'elb-2-security-group', id: 'sg-elb-2-id') }
|
494
513
|
let(:network_interface_1_elb_1) do
|
495
514
|
instance_double(AWS::EC2::NetworkInterface,
|
496
|
-
|
497
|
-
|
515
|
+
security_groups: [elb_1_security_group],
|
516
|
+
exists?: false,
|
498
517
|
)
|
499
518
|
end
|
500
519
|
let(:network_interface_2_elb_1) do
|
501
520
|
instance_double(AWS::EC2::NetworkInterface,
|
502
|
-
|
503
|
-
|
521
|
+
security_groups: [elb_1_security_group],
|
522
|
+
exists?: false,
|
504
523
|
)
|
505
524
|
end
|
506
525
|
let(:network_interface_1_elb_2) do
|
507
526
|
instance_double(AWS::EC2::NetworkInterface,
|
508
|
-
|
509
|
-
|
527
|
+
security_groups: [elb_2_security_group],
|
528
|
+
exists?: false,
|
510
529
|
)
|
511
530
|
end
|
512
531
|
let(:network_interface_2_elb_2) do
|
513
532
|
instance_double(AWS::EC2::NetworkInterface,
|
514
|
-
|
515
|
-
|
533
|
+
security_groups: [elb_2_security_group],
|
534
|
+
exists?: false,
|
516
535
|
)
|
517
536
|
end
|
518
537
|
|
@@ -755,7 +774,7 @@ module VmShepherd
|
|
755
774
|
let(:elastic_ip) { instance_double(AWS::EC2::ElasticIp) }
|
756
775
|
let(:vm_config) do
|
757
776
|
{
|
758
|
-
'vm_name'
|
777
|
+
'vm_name' => 'some-vm-name',
|
759
778
|
'vm_ip_address' => 'some-ip-address'
|
760
779
|
}
|
761
780
|
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: 3.0.
|
4
|
+
version: 3.0.5
|
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-02-
|
11
|
+
date: 2016-02-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-v1
|