vm_shepherd 3.0.4 → 3.0.5
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 +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
|