vominator 0.0.1
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 +7 -0
- data/.gitignore +25 -0
- data/.rspec +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +116 -0
- data/Rakefile +12 -0
- data/bin/vominate +12 -0
- data/circle.yml +5 -0
- data/lib/ec2.rb +12 -0
- data/lib/ec2/instances.rb +362 -0
- data/lib/ec2/security_groups.rb +314 -0
- data/lib/ec2/ssm.rb +81 -0
- data/lib/vominator/aws.rb +15 -0
- data/lib/vominator/constants.rb +53 -0
- data/lib/vominator/ec2.rb +308 -0
- data/lib/vominator/instances.rb +34 -0
- data/lib/vominator/route53.rb +125 -0
- data/lib/vominator/security_groups.rb +26 -0
- data/lib/vominator/ssm.rb +57 -0
- data/lib/vominator/version.rb +3 -0
- data/lib/vominator/vominator.rb +74 -0
- data/lib/vominator/vpc.rb +82 -0
- data/lib/vpc.rb +8 -0
- data/lib/vpc/create.rb +188 -0
- data/spec/lib/instances_spec.rb +2 -0
- data/spec/lib/vominator/aws_spec.rb +6 -0
- data/spec/lib/vominator/ec2_spec.rb +783 -0
- data/spec/lib/vominator/instances_spec.rb +96 -0
- data/spec/lib/vominator/route53_spec.rb +64 -0
- data/spec/lib/vominator/ssm_spec.rb +95 -0
- data/spec/lib/vominator/vominator_spec.rb +209 -0
- data/spec/spec_helper.rb +103 -0
- data/spec/support/matchers/exit_with_code.rb +24 -0
- data/test/puke/cloud-configs/.gitkeep +0 -0
- data/test/puke/cloud-configs/cloud-config-example.erb +63 -0
- data/test/puke/config.yaml +16 -0
- data/test/puke/products/sample-api/instances.yaml +37 -0
- data/test/puke/products/sample-api/security_groups.yaml +19 -0
- data/test/vominator.yaml +7 -0
- data/vominator.gemspec +34 -0
- metadata +259 -0
@@ -0,0 +1,314 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
require 'colored'
|
4
|
+
require 'terminal-table'
|
5
|
+
require_relative '../vominator/constants'
|
6
|
+
require_relative '../vominator/aws'
|
7
|
+
require_relative '../vominator/security_groups'
|
8
|
+
require_relative '../vominator/ec2'
|
9
|
+
|
10
|
+
options = {}
|
11
|
+
|
12
|
+
OptionParser.new do |opts|
|
13
|
+
opts.banner = 'Usage: vominate ec2 security_groups [options]'.yellow
|
14
|
+
|
15
|
+
opts.on('-p PRODUCT', '--product PRODUCT', String, 'REQUIRED: The product which you want to manage security groups for') do |value|
|
16
|
+
options[:product] = value
|
17
|
+
end
|
18
|
+
|
19
|
+
opts.on('-e ENVIRONMENT', '--environment ENVIRONMENT', String, 'REQUIRED: The environment which you want to manage security groups for') do |value|
|
20
|
+
options[:environment] = value
|
21
|
+
end
|
22
|
+
|
23
|
+
opts.on('--security-groups GROUPS', Array, 'OPTIONAL: Comma Delimited list of security groups') do |value|
|
24
|
+
options[:groups] = value
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on('--delete', 'Enable Deletions. This should be used with care') do |value|
|
28
|
+
options[:delete] = value
|
29
|
+
end
|
30
|
+
opts.on('-t', '--test', 'OPTIONAL: Test run. Show what would be changed without making any actual changes') do
|
31
|
+
options[:test] = true
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on('-l', '--list', 'OPTIONAL: List out products and environments') do
|
35
|
+
options[:list] = true
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on('--verbose', 'OPTIONAL: Show all security group rules in tables') do
|
39
|
+
options[:verbose] = true
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on('-d', '--debug', 'OPTIONAL: debug output') do
|
43
|
+
options[:debug] = true
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.on_tail(:NONE, '-h', '--help', 'OPTIONAL: Display this screen') do
|
47
|
+
puts opts
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
|
51
|
+
begin
|
52
|
+
opts.parse!
|
53
|
+
throw Exception unless ((options.include? :environment) && (options.include? :product)) || options[:list]
|
54
|
+
rescue
|
55
|
+
puts opts
|
56
|
+
exit
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
TEST = options[:test]
|
61
|
+
def test?(message)
|
62
|
+
LOGGER.test(message) if TEST
|
63
|
+
TEST
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
if options[:list]
|
68
|
+
data = {}
|
69
|
+
PUKE_CONFIG.keys.each do |environment|
|
70
|
+
LOGGER.info "--#{environment}"
|
71
|
+
products = PUKE_CONFIG[environment]['products'] || Array.new
|
72
|
+
products.each do |product|
|
73
|
+
LOGGER.info " --#{product}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
exit(1)
|
77
|
+
end
|
78
|
+
|
79
|
+
puke_config = Vominator.get_puke_variables(options[:environment])
|
80
|
+
|
81
|
+
#TODO: Validate Environment and Product
|
82
|
+
LOGGER.info("Working on #{options[:product]} in #{options[:environment]}.")
|
83
|
+
|
84
|
+
|
85
|
+
unless test?('Vominator is running in test mode. It will NOT make any changes.')
|
86
|
+
LOGGER.warning('WARNING: Vominator will make changes to your environment. Please run test mode first if you are unsure.')
|
87
|
+
unless Vominator.yesno?(prompt: 'Do you wish to proceed?', default: false)
|
88
|
+
exit(1)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
if options[:groups]
|
93
|
+
puke_security_groups = Vominator::SecurityGroups.get_security_groups(options[:environment], options[:product], options[:groups])
|
94
|
+
# If the user specified a filter, barf in the event a specified security group doesnt exist in puke
|
95
|
+
invalid_security_groups = options[:groups].reject{|g| puke_security_group_names.include? g}
|
96
|
+
if invalid_security_groups.count > 0
|
97
|
+
LOGGER.fatal("Unable to find the following security groups in your puke: #{invalid_security_groups.join(',')}")
|
98
|
+
end
|
99
|
+
else
|
100
|
+
puke_security_groups = Vominator::SecurityGroups.get_security_groups(options[:environment], options[:product])
|
101
|
+
end
|
102
|
+
|
103
|
+
unless puke_security_groups
|
104
|
+
LOGGER.fatal('Unable to load security groups . Make sure the product is correctly defined for the environment you have selected and that a security_groups.yaml file exists with at least one group defined.')
|
105
|
+
end
|
106
|
+
|
107
|
+
ec2_client = Aws::EC2::Client.new(region: puke_config['region_name'])
|
108
|
+
|
109
|
+
|
110
|
+
puke_security_group_names = puke_security_groups.map{|g| g.keys[0]}
|
111
|
+
vpc_security_groups = Vominator::EC2.get_security_groups(ec2_client, puke_config['vpc_id'])
|
112
|
+
vpc_security_group_names = vpc_security_groups.map{|g| g.group_name }
|
113
|
+
|
114
|
+
new_security_group_names = puke_security_group_names.reject{|g| vpc_security_group_names.include? g}
|
115
|
+
if new_security_group_names.count > 0
|
116
|
+
unless test?("Would create the following new security groups: #{new_security_group_names.join(',')}")
|
117
|
+
new_security_group_names.each do |security_group_name|
|
118
|
+
#TODO: Automagically nuke the default outbound ACL for each security group
|
119
|
+
description = puke_security_groups.select{ |g| g.keys[0] == security_group_name}.first['description']
|
120
|
+
LOGGER.success("Successfully created #{security_group_name}") if Vominator::EC2.create_security_group(ec2_client, security_group_name, puke_config['vpc_id'], description)
|
121
|
+
end
|
122
|
+
# Sleep for just a second to allow amazon to converge
|
123
|
+
sleep(1)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
untracked_security_group_names = vpc_security_group_names.reject{|g| puke_security_group_names.include? g}
|
128
|
+
if untracked_security_group_names.count > 0
|
129
|
+
LOGGER.warning("The following security groups exist in the AWS account but are not defined in your puke: #{untracked_security_group_names.join(',')}")
|
130
|
+
end
|
131
|
+
|
132
|
+
# Refresh our list of existing security groups now that we have created ones we need.
|
133
|
+
vpc_security_groups = Vominator::EC2.get_security_groups(ec2_client, puke_config['vpc_id'])
|
134
|
+
vpc_security_groups_id_lookup = Hash[vpc_security_groups.map{|g| [g.group_name, g.group_id]}]
|
135
|
+
vpc_security_groups_name_lookup = Hash[vpc_security_groups.map{|g| [g.group_id, g.group_name]}]
|
136
|
+
|
137
|
+
puke_security_groups.each do |puke_security_group|
|
138
|
+
puke_security_group_name = puke_security_group.keys[0]
|
139
|
+
vpc_security_group = vpc_security_groups.select{|g| g.group_name == puke_security_group_name}.first
|
140
|
+
|
141
|
+
# Create empty arrays if we havent specified either ingress or egress rules.
|
142
|
+
puke_security_group['ingress'] = [] unless puke_security_group['ingress'] && puke_security_group['ingress'].count > 0
|
143
|
+
puke_security_group['egress'] = [] unless puke_security_group['egress'] && puke_security_group['egress'].count > 0
|
144
|
+
|
145
|
+
if vpc_security_group
|
146
|
+
# Update environment tag if needed
|
147
|
+
environment_tag = vpc_security_group.tags.select{|t| t.key == 'Environment'}.first
|
148
|
+
|
149
|
+
environment_tag = nil if environment_tag.value != options[:environment] if environment_tag
|
150
|
+
|
151
|
+
unless environment_tag
|
152
|
+
unless test?("Would set environment tag to #{options[:environment]} for #{puke_security_group_name}")
|
153
|
+
Vominator::EC2.tag_resource(ec2_client, vpc_security_group.group_id, [{key: 'Environment', value: options[:environment]}])
|
154
|
+
LOGGER.info("Updated tags for #{puke_security_group_name}")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Normalize the existing ingress rules for the security group.
|
159
|
+
vpc_ingress_rules = Array.new
|
160
|
+
vpc_security_group.ip_permissions.each do |rule|
|
161
|
+
#TODO: Normalize -1 to all for ip_protocol
|
162
|
+
#TODO: if -1 for ip_protocol set :from_port and to_ports
|
163
|
+
|
164
|
+
rule.ip_ranges.each do |ip_range|
|
165
|
+
vpc_ingress_rules.push({ :ip_protocol => rule.ip_protocol, :from_port => rule.from_port, :to_port => rule.to_port, :cidr_ip => ip_range.cidr_ip, :source_security_group_id => nil })
|
166
|
+
end
|
167
|
+
|
168
|
+
rule.user_id_group_pairs.each do |group|
|
169
|
+
vpc_ingress_rules.push({ :ip_protocol => rule.ip_protocol, :from_port => rule.from_port, :to_port => rule.to_port, :cidr_ip => nil, :source_security_group_id => group.group_id, :source_security_group_name => vpc_security_groups_name_lookup[group.group_id] })
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# Normalize the rules that we defined in puke for the security group.
|
174
|
+
puke_ingress_rules = Array.new
|
175
|
+
cidr_block_regex = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$/
|
176
|
+
|
177
|
+
puke_security_group['ingress'].each do |rule|
|
178
|
+
#TODO: Normalize all to -1 for ip_protocol
|
179
|
+
if rule['ports'].to_s.include?('..')
|
180
|
+
from_port = rule['ports'].split('..')[0]
|
181
|
+
to_port = rule['ports'].split('..')[1]
|
182
|
+
else
|
183
|
+
from_port = rule['ports']
|
184
|
+
to_port = rule['ports']
|
185
|
+
end
|
186
|
+
|
187
|
+
if rule['source'] =~ cidr_block_regex
|
188
|
+
puke_ingress_rules.push({ :ip_protocol => rule['protocol'], :from_port => from_port.to_i, :to_port => to_port.to_i, :cidr_ip => rule['source'], :source_security_group_id => nil})
|
189
|
+
else rule['source']
|
190
|
+
if vpc_security_groups_id_lookup[puke_security_group_name]
|
191
|
+
group_id = vpc_security_groups_id_lookup[puke_security_group_name]
|
192
|
+
puke_ingress_rules.push({ :ip_protocol => rule['protocol'], :from_port => from_port.to_i, :to_port => to_port.to_i, :cidr_ip => nil, :source_security_group_id => group_id, :source_security_group_name => vpc_security_groups_name_lookup[group_id] })
|
193
|
+
else
|
194
|
+
LOGGER.fatal("Do not recognize #{rule['source']} as a valid cidr block and was unable to resolve this to a valid security group for #{rule} in #{puke_security_group_name}")
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# Determie what new rules we need to add
|
200
|
+
ingress_to_create = puke_ingress_rules - vpc_ingress_rules
|
201
|
+
# Determine what rules we should delete
|
202
|
+
ingress_to_delete = vpc_ingress_rules - puke_ingress_rules
|
203
|
+
|
204
|
+
# Normalize the existing egress rules for the security group
|
205
|
+
vpc_egress_rules = Array.new
|
206
|
+
vpc_security_group.ip_permissions_egress.each do |rule|
|
207
|
+
#TODO: Normalize -1 to all for ip_protocol
|
208
|
+
#TODO: if -1 for ip_protocol set :from_port and to_ports
|
209
|
+
rule.ip_ranges.each do |ip_range|
|
210
|
+
vpc_egress_rules.push({ :ip_protocol => rule.ip_protocol, :from_port => rule.from_port, :to_port => rule.to_port, :cidr_ip => ip_range.cidr_ip, :source_security_group_id => nil })
|
211
|
+
end
|
212
|
+
|
213
|
+
rule.user_id_group_pairs.each do |group|
|
214
|
+
vpc_egress_rules.push({ :ip_protocol => rule.ip_protocol, :from_port => rule.from_port, :to_port => rule.to_port, :cidr_ip => nil, :source_security_group_id => group.group_id, :source_security_group_name => vpc_security_groups_name_lookup[group.group_id] })
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Normalize the rules that we defined in puke for the security group.
|
219
|
+
puke_egress_rules = Array.new
|
220
|
+
cidr_block_regex = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$/
|
221
|
+
|
222
|
+
puke_security_group['egress'].each do |rule|
|
223
|
+
#TODO: Normalize all to -1 for ip_protocol
|
224
|
+
if rule['ports'].to_s.include?('..')
|
225
|
+
from_port = rule['ports'].split('..')[0]
|
226
|
+
to_port = rule['ports'].split('..')[1]
|
227
|
+
else
|
228
|
+
from_port = rule['ports']
|
229
|
+
to_port = rule['ports']
|
230
|
+
end
|
231
|
+
|
232
|
+
if rule['source'] =~ cidr_block_regex
|
233
|
+
puke_egress_rules.push({ :ip_protocol => rule['protocol'], :from_port => from_port.to_i, :to_port => to_port.to_i, :cidr_ip => rule['source'], :source_security_group_id => nil})
|
234
|
+
else rule['source']
|
235
|
+
if vpc_security_groups_id_lookup[puke_security_group_name]
|
236
|
+
group_id = vpc_security_groups_id_lookup[puke_security_group_name]
|
237
|
+
puke_egress_rules.push({ :ip_protocol => rule['protocol'], :from_port => from_port.to_i, :to_port => to_port.to_i, :cidr_ip => nil, :source_security_group_id => group_id, :source_security_group_name => vpc_security_groups_name_lookup[group_id] })
|
238
|
+
else
|
239
|
+
LOGGER.fatal("Do not recognize #{rule['source']} as a valid cidr block and was unable to resolve this to a valid security group for #{rule} in #{puke_security_group_name}")
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
# Determine what new rules we need to add
|
245
|
+
egress_to_create = puke_egress_rules - vpc_egress_rules
|
246
|
+
# Determine what rules we should delete
|
247
|
+
egress_to_delete = vpc_egress_rules - puke_egress_rules
|
248
|
+
|
249
|
+
table = Terminal::Table.new :title => puke_security_group_name.cyan, :headings => ['Type', 'Source', 'from port', 'to_port', 'Protocol', 'Action'], :style => {:width => 125} do |t|
|
250
|
+
ingress_to_create.each do |rule|
|
251
|
+
source = rule[:cidr_ip] || rule[:source_security_group_name]
|
252
|
+
t.add_row ['Inbound'.green, source.green, rule[:from_port].to_s.green, rule[:to_port].to_s.green, rule[:ip_protocol].green, 'Create'.green]
|
253
|
+
end
|
254
|
+
|
255
|
+
ingress_to_delete.each do |rule|
|
256
|
+
source = rule[:cidr_ip] || rule[:source_security_group_name]
|
257
|
+
t.add_row ['Inbound'.red, source.red, rule[:from_port].to_s.red, rule[:to_port].to_s.red, rule[:ip_protocol].red, 'Delete'.red]
|
258
|
+
end
|
259
|
+
|
260
|
+
if options[:verbose]
|
261
|
+
((vpc_ingress_rules - ingress_to_create) - ingress_to_delete).each do |rule|
|
262
|
+
source = rule[:cidr_ip] || rule[:source_security_group_name]
|
263
|
+
t.add_row ['Inbound', source, rule[:from_port].to_s, rule[:to_port].to_s, rule[:ip_protocol], nil]
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
egress_to_create.each do |rule|
|
268
|
+
source = rule[:cidr_ip] || rule[:source_security_group_name]
|
269
|
+
t.add_row ['Outbound'.green, source.green, rule[:from_port].to_s.green, rule[:to_port].to_s.green, rule[:ip_protocol].green, 'Create'.green]
|
270
|
+
end
|
271
|
+
|
272
|
+
egress_to_delete.each do |rule|
|
273
|
+
source = rule[:cidr_ip] || rule[:source_security_group_name]
|
274
|
+
t.add_row ['Outbound'.red, source.red, rule[:from_port].to_s.red, rule[:to_port].to_s.red, rule[:ip_protocol].red, 'Delete'.red]
|
275
|
+
end
|
276
|
+
|
277
|
+
if options[:verbose]
|
278
|
+
((vpc_egress_rules - egress_to_create) - egress_to_delete).each do |rule|
|
279
|
+
source = rule[:cidr_ip] || rule[:source_security_group_name]
|
280
|
+
t.add_row ['Outbound', source, rule[:from_port].to_s, rule[:to_port].to_s, rule[:ip_protocol], nil]
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
|
286
|
+
LOGGER.info(table)
|
287
|
+
|
288
|
+
#TODO: Maybe find a way to cleanup the display output better on success
|
289
|
+
unless options[:test]
|
290
|
+
ingress_to_create.each do |rule|
|
291
|
+
Vominator::EC2.create_security_group_rule(ec2_client,'ingress',vpc_security_group.group_id,rule)
|
292
|
+
LOGGER.success("Added inbound rule to #{vpc_security_group.group_name}: #{rule}")
|
293
|
+
end
|
294
|
+
|
295
|
+
|
296
|
+
egress_to_create.each do |rule|
|
297
|
+
Vominator::EC2.create_security_group_rule(ec2_client,'egress',vpc_security_group.group_id,rule)
|
298
|
+
LOGGER.success("Added outbound rule to #{vpc_security_group.group_name}: #{rule}")
|
299
|
+
end
|
300
|
+
|
301
|
+
if options[:delete]
|
302
|
+
ingress_to_delete.each do |rule|
|
303
|
+
Vominator::EC2.delete_security_group_rule(ec2_client,'ingress',vpc_security_group.group_id,rule)
|
304
|
+
LOGGER.success("Removed inbound rule to #{vpc_security_group.group_name}: #{rule}")
|
305
|
+
end
|
306
|
+
|
307
|
+
egress_to_delete.each do |rule|
|
308
|
+
Vominator::EC2.delete_security_group_rule(ec2_client,'egress',vpc_security_group.group_id,rule)
|
309
|
+
LOGGER.success("Removed outbound rule to #{vpc_security_group.group_name}: #{rule}")
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
data/lib/ec2/ssm.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
require 'colored'
|
4
|
+
require_relative '../vominator/constants'
|
5
|
+
require_relative '../vominator/aws'
|
6
|
+
require_relative '../vominator/ssm'
|
7
|
+
|
8
|
+
options = {}
|
9
|
+
|
10
|
+
OptionParser.new do |opts|
|
11
|
+
opts.banner = 'Usage: vominate ssm [options]'.yellow
|
12
|
+
|
13
|
+
opts.on('-eENVIRONMENT', '--environment ENVIRONMENT', 'REQUIRED: The environment which you want to manage ssm for') do |value|
|
14
|
+
options[:environment] = value
|
15
|
+
end
|
16
|
+
|
17
|
+
opts.on('-t', '--test', 'OPTIONAL: Test run. Show what would be changed without making any actual changes') do
|
18
|
+
options[:test] = true
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on('-l', '--list', 'OPTIONAL: List out documents for a specific environment') do
|
22
|
+
options[:list] = true
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on('-d', '--debug', 'OPTIONAL: debug output') do
|
26
|
+
options[:debug] = true
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on_tail(:NONE, '-h', '--help', 'OPTIONAL: Display this screen') do
|
30
|
+
puts opts
|
31
|
+
exit
|
32
|
+
end
|
33
|
+
|
34
|
+
begin
|
35
|
+
opts.parse!
|
36
|
+
throw Exception unless (options.include? :environment) || options[:list]
|
37
|
+
rescue
|
38
|
+
puts opts
|
39
|
+
exit
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
TEST = options[:test]
|
44
|
+
def test?(message)
|
45
|
+
LOGGER.test(message) if TEST
|
46
|
+
TEST
|
47
|
+
end
|
48
|
+
|
49
|
+
puke_config = Vominator.get_puke_variables(options[:environment])
|
50
|
+
|
51
|
+
#TODO: Validate Environment
|
52
|
+
LOGGER.info("Working on #{options[:environment]}.")
|
53
|
+
|
54
|
+
unless test?('Vominator is running in test mode. It will NOT make any changes.')
|
55
|
+
LOGGER.warning('WARNING: Vominator will make changes to your environment. Please run test mode first if you are unsure.')
|
56
|
+
unless Vominator.yesno?(prompt: 'Do you wish to proceed?', default: false)
|
57
|
+
exit(1)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
ssm = Aws::SSM::Client.new(region: puke_config['region_name'])
|
62
|
+
|
63
|
+
aws_documents = Vominator::SSM.get_documents(ssm)
|
64
|
+
|
65
|
+
puke_config['ssm_documents'].each do |document_name|
|
66
|
+
document_data = File.read("#{VOMINATOR_CONFIG['configuration_path']}/ssm-documents/#{document_name}")
|
67
|
+
|
68
|
+
if aws_documents.include? document_name
|
69
|
+
#should we delete it?
|
70
|
+
|
71
|
+
#should we update it?
|
72
|
+
else
|
73
|
+
unless test?("Would create SSM document for #{document_name}")
|
74
|
+
if Vominator::SSM.put_document(ssm,document_name,document_data)
|
75
|
+
LOGGER.success("Succesfully created SSM document #{document_name}")
|
76
|
+
else
|
77
|
+
LOGGER.fatal("Failed to create SSM document #{document_name}")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
require_relative 'vominator'
|
3
|
+
require_relative 'constants'
|
4
|
+
|
5
|
+
Aws.config[:credentials] = Aws::Credentials.new(VOMINATOR_CONFIG['access_key_id'], VOMINATOR_CONFIG['secret_access_key'])
|
6
|
+
|
7
|
+
module Vominator
|
8
|
+
class AWS
|
9
|
+
def self.get_availability_zones(ec2_client)
|
10
|
+
resp = ec2_client.describe_availability_zones
|
11
|
+
zones = resp.availability_zones.map{|z| z['zone_name']}.sort_by{|z| z}
|
12
|
+
return zones
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative 'vominator'
|
2
|
+
|
3
|
+
LOGGER = Vominator::Logger
|
4
|
+
|
5
|
+
VOMINATOR_CONFIG ||= Vominator.get_config
|
6
|
+
PUKE_CONFIG ||= Vominator.get_puke_config(VOMINATOR_CONFIG['configuration_path'])
|
7
|
+
|
8
|
+
EC2_INSTANCE_METADATA = {
|
9
|
+
:'t1.micro' => {:ephemeral_devices => 0, :virtualization_type => 'paravirtual'},
|
10
|
+
:'t2.micro' => {:ephemeral_devices => 0, :virtualization_type => 'hvm'},
|
11
|
+
:'t2.small' => {:ephemeral_devices => 0, :virtualization_type => 'hvm'},
|
12
|
+
:'t2.medium' => {:ephemeral_devices => 0, :virtualization_type => 'hvm'},
|
13
|
+
:'m1.small' => {:ephemeral_devices => 1, :virtualization_type => 'paravirtual'},
|
14
|
+
:'m1.medium' => {:ephemeral_devices => 1, :virtualization_type => 'paravirtual'},
|
15
|
+
:'m1.large' => {:ephemeral_devices => 2, :virtualization_type => 'paravirtual'},
|
16
|
+
:'m1.xlarge' => {:ephemeral_devices => 4, :virtualization_type => 'paravirtual'},
|
17
|
+
:'m3.medium' => {:ephemeral_devices => 1, :virtualization_type => 'hvm'},
|
18
|
+
:'m3.large' => {:ephemeral_devices => 1, :virtualization_type => 'hvm'},
|
19
|
+
:'m3.xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
20
|
+
:'m3.2xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
21
|
+
:'c1.medium' => {:ephemeral_devices => 1, :virtualization_type => 'paravirtual'},
|
22
|
+
:'c1.xlarge' => {:ephemeral_devices => 4, :virtualization_type => 'paravirtual'},
|
23
|
+
:'m2.xlarge' => {:ephemeral_devices => 1, :virtualization_type => 'paravirtual'},
|
24
|
+
:'m2.2xlarge' => {:ephemeral_devices => 1, :virtualization_type => 'paravirtual'},
|
25
|
+
:'m2.4xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'paravirtual'},
|
26
|
+
:'hi1.4xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
27
|
+
:'hs1.8xlarge' => {:ephemeral_devices => 24, :virtualization_type => 'hvm'},
|
28
|
+
:'cr1.8xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
29
|
+
:'cc1.4xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
30
|
+
:'cc2.8xlarge' => {:ephemeral_devices => 4, :virtualization_type => 'hvm'},
|
31
|
+
:'cg1.4xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
32
|
+
:'c3.large' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
33
|
+
:'c3.xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
34
|
+
:'c3.2xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
35
|
+
:'c3.4xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
36
|
+
:'c3.8xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
37
|
+
:'c4.large' => {:ephemeral_devices => 0, :virtualization_type => 'hvm'},
|
38
|
+
:'c4.xlarge' => {:ephemeral_devices => 0, :virtualization_type => 'hvm'},
|
39
|
+
:'c4.2xlarge' => {:ephemeral_devices => 0, :virtualization_type => 'hvm'},
|
40
|
+
:'c4.4xlarge' => {:ephemeral_devices => 0, :virtualization_type => 'hvm'},
|
41
|
+
:'c4.8xlarge' => {:ephemeral_devices => 0, :virtualization_type => 'hvm'},
|
42
|
+
:'g2.2xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
43
|
+
:'i2.xlarge' => {:ephemeral_devices => 1, :virtualization_type => 'hvm'},
|
44
|
+
:'i2.2xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
45
|
+
:'i2.4xlarge' => {:ephemeral_devices => 4, :virtualization_type => 'hvm'},
|
46
|
+
:'i2.8xlarge' => {:ephemeral_devices => 8, :virtualization_type => 'hvm'},
|
47
|
+
:'r3.large' => {:ephemeral_devices => 1, :virtualization_type => 'hvm'},
|
48
|
+
:'r3.xlarge' => {:ephemeral_devices => 1, :virtualization_type => 'hvm'},
|
49
|
+
:'r3.2xlarge' => {:ephemeral_devices => 1, :virtualization_type => 'hvm'},
|
50
|
+
:'r3.4xlarge' => {:ephemeral_devices => 1, :virtualization_type => 'hvm'},
|
51
|
+
:'r3.8xlarge' => {:ephemeral_devices => 2, :virtualization_type => 'hvm'},
|
52
|
+
}
|
53
|
+
|