vm_shepherd 1.5.1 → 1.5.2
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 +48 -15
- data/lib/vm_shepherd/version.rb +1 -1
- data/spec/vm_shepherd/aws_manager_spec.rb +4 -4
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1db947ff086cec29ff5a2565d8e54041203a97b1
|
4
|
+
data.tar.gz: 6caa24f8e4508aa51a0c73a72c54e738a05afb93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df565e43afea2322d0f018b4a38485ec9edea318bfa90020b605ea584771a94da433c5239db5b077e4fd9aed6d0ccf26fcf728f69c968fcaf33d2edeb4932e53
|
7
|
+
data.tar.gz: 0ac5752d872b82b6fcfbd5c3b1bbc3d55ce00d34baa77d35ebc0b0ad3496d6ef9343b7aa94b2d8e730818d1f69d259c5530e1d4b446dda79a2caaabb9cfc095b
|
@@ -9,6 +9,15 @@ module VmShepherd
|
|
9
9
|
DO_NOT_TERMINATE_TAG_KEY = 'do_not_terminate'
|
10
10
|
ELB_SECURITY_GROUP_NAME = 'ELB Security Group'
|
11
11
|
|
12
|
+
CREATE_IN_PROGRESS = 'CREATE_IN_PROGRESS'
|
13
|
+
CREATE_COMPLETE = 'CREATE_COMPLETE'
|
14
|
+
ROLLBACK_IN_PROGRESS = 'ROLLBACK_IN_PROGRESS'
|
15
|
+
ROLLBACK_COMPLETE = 'ROLLBACK_COMPLETE'
|
16
|
+
DELETE_IN_PROGRESS = 'DELETE_IN_PROGRESS'
|
17
|
+
DELETE_COMPLETE = 'DELETE_COMPLETE'
|
18
|
+
|
19
|
+
attr_writer :logger
|
20
|
+
|
12
21
|
def initialize(env_config)
|
13
22
|
AWS.config(
|
14
23
|
access_key_id: env_config.fetch(:aws_access_key),
|
@@ -16,25 +25,29 @@ module VmShepherd
|
|
16
25
|
region: env_config.fetch(:region),
|
17
26
|
)
|
18
27
|
@env_config = env_config
|
28
|
+
@logger = logger
|
19
29
|
end
|
20
30
|
|
21
31
|
def prepare_environment(cloudformation_template_file)
|
22
32
|
template = File.read(cloudformation_template_file)
|
23
33
|
|
24
34
|
cfm = AWS::CloudFormation.new
|
35
|
+
logger.info('Starting CloudFormation Stack Creation')
|
25
36
|
stack = cfm.stacks.create(env_config.fetch(:stack_name), template, parameters: env_config.fetch(:parameters), capabilities: ['CAPABILITY_IAM'])
|
26
37
|
|
38
|
+
logger.info("Waiting for status: #{CREATE_COMPLETE}")
|
27
39
|
retry_until(retry_limit: 360) do
|
28
40
|
status = stack.status
|
41
|
+
logger.info("current stack status: #{status}")
|
29
42
|
case status
|
30
|
-
when
|
43
|
+
when CREATE_COMPLETE
|
31
44
|
true
|
32
|
-
when
|
45
|
+
when CREATE_IN_PROGRESS
|
33
46
|
false
|
34
|
-
when
|
47
|
+
when ROLLBACK_IN_PROGRESS
|
35
48
|
false
|
36
49
|
else
|
37
|
-
stack.delete if status ==
|
50
|
+
stack.delete if status == ROLLBACK_COMPLETE
|
38
51
|
raise "Unexpected status for stack #{env_config.fetch(:stack_name)} : #{status}"
|
39
52
|
end
|
40
53
|
end
|
@@ -47,6 +60,7 @@ module VmShepherd
|
|
47
60
|
def deploy(ami_file_path:, vm_config:)
|
48
61
|
image_id = read_ami_id(ami_file_path)
|
49
62
|
|
63
|
+
logger.info('Starting AMI Instance creation')
|
50
64
|
instance =
|
51
65
|
retry_until do
|
52
66
|
begin
|
@@ -62,27 +76,27 @@ module VmShepherd
|
|
62
76
|
end
|
63
77
|
end
|
64
78
|
|
79
|
+
logger.info('waiting until the instance status is running')
|
65
80
|
retry_until do
|
66
81
|
begin
|
67
|
-
instance.status
|
82
|
+
status = instance.status
|
83
|
+
logger.info("current status: #{status}")
|
84
|
+
status == :running
|
68
85
|
rescue AWS::EC2::Errors::InvalidInstanceID::NotFound
|
69
86
|
false
|
70
87
|
end
|
71
88
|
end
|
72
89
|
|
90
|
+
logger.info('Creating an Elastic IP and assigning it to the instance')
|
73
91
|
elastic_ip = AWS.ec2.elastic_ips.create(vpc: true)
|
74
92
|
instance.associate_elastic_ip(elastic_ip.allocation_id)
|
75
93
|
instance.add_tag('Name', value: vm_config.fetch(:vm_name))
|
76
94
|
end
|
77
95
|
|
78
|
-
def read_ami_id(ami_file_path)
|
79
|
-
YAML.load_file(ami_file_path)[env_config.fetch(:region)]
|
80
|
-
end
|
81
|
-
|
82
96
|
def clean_environment
|
83
97
|
[:public_subnet_id, :private_subnet_id].each do |subnet_id|
|
84
|
-
|
85
|
-
clear_subnet(
|
98
|
+
aws_subnet_id = env_config.fetch(:outputs).fetch(subnet_id)
|
99
|
+
clear_subnet(aws_subnet_id) if aws_subnet_id
|
86
100
|
end
|
87
101
|
|
88
102
|
if (elb_config = env_config[:elb])
|
@@ -91,7 +105,10 @@ module VmShepherd
|
|
91
105
|
|
92
106
|
if (bucket_name = env_config.fetch(:outputs, {}).fetch(:s3_bucket_name, nil))
|
93
107
|
bucket = AWS::S3.new.buckets[bucket_name]
|
94
|
-
|
108
|
+
if bucket && bucket.exists?
|
109
|
+
logger.info("clearing bucket: #{bucket_name}")
|
110
|
+
bucket.clear!
|
111
|
+
end
|
95
112
|
end
|
96
113
|
|
97
114
|
delete_stack(env_config.fetch(:stack_name))
|
@@ -111,7 +128,7 @@ module VmShepherd
|
|
111
128
|
end
|
112
129
|
|
113
130
|
private
|
114
|
-
attr_reader :env_config
|
131
|
+
attr_reader :env_config, :logger
|
115
132
|
|
116
133
|
def subnet_id(stack, elb_config)
|
117
134
|
stack.outputs.detect { |o| o.key == elb_config[:stack_output_keys][:subnet_id] }.value
|
@@ -122,12 +139,14 @@ module VmShepherd
|
|
122
139
|
end
|
123
140
|
|
124
141
|
def clear_subnet(subnet_id)
|
142
|
+
logger.info("Clearing contents of subnet: #{subnet_id}")
|
125
143
|
subnet = AWS.ec2.subnets[subnet_id]
|
126
144
|
volumes = []
|
127
145
|
subnet.instances.each do |instance|
|
128
146
|
instance.attachments.each do |_, attachment|
|
129
147
|
volumes.push(attachment.volume) unless attachment.delete_on_termination
|
130
148
|
end
|
149
|
+
logger.info("terminating instance #{instance.id}")
|
131
150
|
instance.terminate
|
132
151
|
end
|
133
152
|
destroy_volumes(volumes)
|
@@ -136,6 +155,7 @@ module VmShepherd
|
|
136
155
|
def destroy_volumes(volumes)
|
137
156
|
volumes.each do |volume|
|
138
157
|
begin
|
158
|
+
logger.info("trying to delete volume: #{volume.id}")
|
139
159
|
volume.delete
|
140
160
|
rescue AWS::EC2::Errors::VolumeInUse
|
141
161
|
sleep 5
|
@@ -148,10 +168,13 @@ module VmShepherd
|
|
148
168
|
if (elb = AWS::ELB.new.load_balancers.find { |lb| lb.name == elb_name })
|
149
169
|
sg = elb.security_groups.first
|
150
170
|
net_interfaces = AWS.ec2.network_interfaces.select { |ni| ni.security_groups.map(&:id).include? sg.id }
|
171
|
+
logger.info("deleting elb: #{elb.name}")
|
151
172
|
elb.delete
|
173
|
+
logger.info('waiting until elb is deleted')
|
152
174
|
retry_until do
|
153
175
|
!elb.exists? && !net_interfaces.map(&:exists?).any?
|
154
176
|
end
|
177
|
+
logger.info("deleting elb security group: #{sg.id}")
|
155
178
|
sg.delete
|
156
179
|
end
|
157
180
|
end
|
@@ -172,6 +195,7 @@ module VmShepherd
|
|
172
195
|
}
|
173
196
|
end
|
174
197
|
|
198
|
+
logger.info('Creating an ELB')
|
175
199
|
elb.client.create_load_balancer(elb_params)
|
176
200
|
end
|
177
201
|
|
@@ -183,6 +207,7 @@ module VmShepherd
|
|
183
207
|
vpc_id: vpc_id,
|
184
208
|
}
|
185
209
|
|
210
|
+
logger.info('Creating a Security Group for the ELB')
|
186
211
|
security_group_response = AWS.ec2.client.create_security_group(sg_params)
|
187
212
|
|
188
213
|
AWS.ec2.security_groups[security_group_response[:group_id]].tap do |security_group|
|
@@ -195,23 +220,31 @@ module VmShepherd
|
|
195
220
|
def delete_stack(stack_name)
|
196
221
|
cfm = AWS::CloudFormation.new
|
197
222
|
stack = cfm.stacks[stack_name]
|
223
|
+
logger.info('deleting CloudFormation stack')
|
198
224
|
stack.delete
|
225
|
+
logger.info("waiting until status: #{DELETE_COMPLETE}")
|
199
226
|
retry_until(retry_limit: 360) do
|
200
227
|
begin
|
201
228
|
status = stack.status
|
229
|
+
logger.info("current stack status: #{status}")
|
202
230
|
case status
|
203
|
-
when
|
231
|
+
when DELETE_COMPLETE
|
204
232
|
true
|
205
|
-
when
|
233
|
+
when DELETE_IN_PROGRESS
|
206
234
|
false
|
207
235
|
else
|
208
236
|
raise "Unexpected status for stack #{stack_name} : #{status}"
|
209
237
|
end
|
210
238
|
rescue AWS::CloudFormation::Errors::ValidationError
|
211
239
|
raise if stack.exists?
|
240
|
+
logger.info('stack deleted successfully')
|
212
241
|
true
|
213
242
|
end
|
214
243
|
end if stack
|
215
244
|
end
|
245
|
+
|
246
|
+
def read_ami_id(ami_file_path)
|
247
|
+
YAML.load_file(ami_file_path)[env_config.fetch(:region)]
|
248
|
+
end
|
216
249
|
end
|
217
250
|
end
|
data/lib/vm_shepherd/version.rb
CHANGED
@@ -42,7 +42,7 @@ module VmShepherd
|
|
42
42
|
}
|
43
43
|
end
|
44
44
|
|
45
|
-
subject(:ami_manager) { AwsManager.new(env_config) }
|
45
|
+
subject(:ami_manager) { AwsManager.new(env_config). tap { |manager| manager.logger = Logger.new(StringIO.new) } }
|
46
46
|
|
47
47
|
before do
|
48
48
|
expect(AWS).to receive(:config).with(
|
@@ -257,15 +257,15 @@ module VmShepherd
|
|
257
257
|
let(:subnets) { instance_double(AWS::EC2::SubnetCollection) }
|
258
258
|
let(:subnet1) { instance_double(AWS::EC2::Subnet, instances: subnet1_instances) }
|
259
259
|
let(:subnet2) { instance_double(AWS::EC2::Subnet, instances: subnet2_instances) }
|
260
|
-
let(:instance1) { instance_double(AWS::EC2::Instance, tags: {}) }
|
261
|
-
let(:instance2) { instance_double(AWS::EC2::Instance, tags: {}) }
|
260
|
+
let(:instance1) { instance_double(AWS::EC2::Instance, tags: {}, id: 'instance1') }
|
261
|
+
let(:instance2) { instance_double(AWS::EC2::Instance, tags: {}, id: 'instance2') }
|
262
262
|
let(:subnet1_instances) { [instance1] }
|
263
263
|
let(:subnet2_instances) { [instance2] }
|
264
264
|
let(:cfm) { instance_double(AWS::CloudFormation, stacks: stack_collection) }
|
265
265
|
let(:stack) { instance_double(AWS::CloudFormation::Stack, status: 'DELETE_COMPLETE', delete: nil) }
|
266
266
|
let(:stack_collection) { instance_double(AWS::CloudFormation::StackCollection) }
|
267
267
|
|
268
|
-
let(:instance1_volume) { instance_double(AWS::EC2::Volume) }
|
268
|
+
let(:instance1_volume) { instance_double(AWS::EC2::Volume, id: 'volume-id') }
|
269
269
|
let(:instance1_attachment) do
|
270
270
|
instance_double(AWS::EC2::Attachment, volume: instance1_volume, delete_on_termination: true)
|
271
271
|
end
|