ec2ex 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6fd690807cff2f0f5be2b942621f1efe62ff96de
4
- data.tar.gz: 7ef5ca48952371e67172a80caa92c372b1751144
3
+ metadata.gz: 5755c9dc27c67e067cb6813e6e130a830ab2b320
4
+ data.tar.gz: a3eb2fe48d2cbec37f45dbf310222f6e22891e34
5
5
  SHA512:
6
- metadata.gz: 81c2592526c7d51688a431c99167abe994b3f1a940c22b38ec7ad56909238efc4b841e78df317ecf27d2a66692cfec228115994d44c6f0e32e0d498f56ff8cde
7
- data.tar.gz: 5ba6cbfc97e284c35de7f77e9125f4c48c0fabe740dc91a2b076803095865425d3c071d98df36ec73cd8b94666ed08d7274ed03dbf698692ff2c65768537d4ac
6
+ metadata.gz: 689bd524c9c9a9f77d77cb3c3e85d1e588d49cc9e89422e6497a7b0b1881d764995589cd778d9065146a8cf22d36a2ba2369f788f980c3eddbc0b57acc99cd74
7
+ data.tar.gz: 432de3ba88dc99d2dbae99d36e7371257eb85f6cd1454c41d50629b907d7cf4e04424c919710d04c970d1a1e17441b7da192aac1870f89dae49a51f7c8118ecf
data/README.md CHANGED
@@ -1,19 +1,67 @@
1
1
  # ec2ex [![Build Status](https://secure.travis-ci.org/toyama0919/ec2ex.png?branch=master)](http://travis-ci.org/toyama0919/ec2ex)
2
2
 
3
- TODO: Summary
3
+ ## Examples
4
4
 
5
- TODO: Description
5
+ ### Search Instance
6
6
 
7
- ## Examples
7
+ ```
8
+ $ ec2ex -s 'stgweb01'
9
+ ```
10
+
11
+ ### Copy Instance
12
+
13
+ ```
14
+ $ ec2ex copy -n "stgembulk01" -t Name:stgembulk02 --public_ip_address auto --instance_count 3
15
+ ```
16
+
17
+ ### Copy Spot Instance
18
+
19
+ ```
20
+ $ ec2ex spot -n "web01" --price 0.5 --private_ip_address 10.0.0.100 -t Name:web02
21
+ ```
22
+
23
+ ### Deployment Instance
24
+
25
+ ```
26
+ $ ec2ex run_spot -n "stgembulk01" --price 0.5
27
+ ```
28
+
29
+ ### Connect ELB Instance
30
+
31
+ ```
32
+ $ ec2ex connect_elb -n "web01" -l elbname
33
+ ```
34
+
35
+ ### Disconnect ELB Instance
36
+
37
+ ```
38
+ $ ec2ex disconnect_elb -n "web02" -l elbname
39
+ ```
40
+
41
+ ### Terminate Instance
42
+
43
+ ```
44
+ $ ec2ex terminate -n web01
45
+ ```
46
+
47
+ ### Renew Instance
48
+
49
+ ```
50
+ $ ec2ex renew -n "presto01" --private-ip-address 10.0.81.201 -p '{iam_instance_profile: { name: "iap-role"} }'
51
+ ```
52
+
53
+ ### Create AMI with tag
54
+
55
+ ```
56
+ $ ec2 create_image -n "presto01"
57
+ ```
8
58
 
9
- $ ec2ex sample
10
- #=> hoge
11
59
 
12
60
  ## Installation
13
61
 
14
62
  Add this line to your application's Gemfile:
15
63
 
16
- gem 'ec2ex'
64
+ gem 'ec2ex', github: 'ipros-team/ec2ex'
17
65
 
18
66
  And then execute:
19
67
 
@@ -21,7 +69,7 @@ And then execute:
21
69
 
22
70
  Or install it yourself as:
23
71
 
24
- $ gem install ec2ex
72
+ $ gem specific_install -l https://github.com/ipros-team/ec2ex
25
73
 
26
74
  ## Contributing
27
75
 
@@ -20,10 +20,12 @@ Gem::Specification.new do |gem|
20
20
  gem.add_dependency 'thor'
21
21
  gem.add_dependency 'hashie'
22
22
  gem.add_dependency 'ipaddress'
23
- gem.add_dependency 'aws-sdk', '~> 2.0.11.pre'
23
+ gem.add_dependency 'aws-sdk'
24
24
  gem.add_dependency 'activesupport'
25
+ gem.add_dependency 'parallel'
26
+ gem.add_dependency 'net-ping'
25
27
 
26
- gem.add_development_dependency 'bundler', '~> 1.7.2'
28
+ gem.add_development_dependency 'bundler'
27
29
  gem.add_development_dependency 'pry', '~> 0.10.1'
28
30
  gem.add_development_dependency 'rake', '~> 10.3.2'
29
31
  gem.add_development_dependency 'rspec', '~> 2.4'
@@ -1,8 +1,7 @@
1
1
  require 'thor'
2
2
  require 'json'
3
3
  require 'pp'
4
- require 'hashie'
5
- require 'aws-sdk'
4
+ require 'parallel'
6
5
  require 'active_support/core_ext/hash'
7
6
 
8
7
  module Ec2ex
@@ -19,15 +18,16 @@ module Ec2ex
19
18
  super(args, options, config)
20
19
  @global_options = config[:shell].base.options
21
20
  @core = Core.new
22
- @ec2 = Aws::EC2::Client.new
23
- @elb = Aws::ElasticLoadBalancing::Client.new
21
+ @ec2 = @core.client
22
+ @elb = @core.elb_client
23
+ @logger = @core.logger
24
24
  end
25
25
 
26
26
  desc 'search', 'search instance'
27
27
  option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
28
28
  option :running_only, aliases: '--ro', type: :boolean, default: true, desc: 'grouping key'
29
- def search(name = options['name'])
30
- results = @core.instances_hash({ Name: name }, options['running_only'])
29
+ def search(name = options[:name])
30
+ results = @core.instances_hash({ Name: name }, options[:running_only])
31
31
  puts_json results
32
32
  end
33
33
 
@@ -35,7 +35,7 @@ module Ec2ex
35
35
  option :condition, aliases: '-c', type: :hash, default: {}, desc: 'grouping key'
36
36
  option :running_only, aliases: '--ro', type: :boolean, default: true, desc: 'grouping key'
37
37
  def search_by_tags
38
- puts_json @core.instances_hash(options['condition'], options['running_only'])
38
+ puts_json @core.instances_hash(options[:condition], options[:running_only])
39
39
  end
40
40
 
41
41
  desc 'reserved', 'reserved instance'
@@ -50,7 +50,7 @@ module Ec2ex
50
50
  list = @core.instances_hash({}, true).select { |instance| instance[:instance_lifecycle].nil? }
51
51
  list = list.map{ |_instance|
52
52
  ['instance_type', 'placement.availability_zone'].map do |key|
53
- eval("instance.#{key} ")
53
+ eval("_instance.#{key} ")
54
54
  end.join('_')
55
55
  }
56
56
  result = {}
@@ -66,22 +66,64 @@ module Ec2ex
66
66
  end
67
67
 
68
68
  desc 'create_image', 'create image'
69
- option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
69
+ option :name, aliases: '-n', type: :string, required: true, desc: 'name tag'
70
+ option :proc, type: :numeric, default: Parallel.processor_count, desc: 'Number of parallel'
71
+ option :region, aliases: '-r', type: :string, required: false, default: nil, desc: 'region'
70
72
  def create_image
71
- results = @core.instances_hash({ Name: options['name'] }, false)
72
- results.each do |instance|
73
- @core.create_image_with_instance(instance)
73
+ results = @core.instances_hash({ Name: options[:name] }, false)
74
+ Parallel.map(results, in_threads: options[:proc]) do |instance|
75
+ begin
76
+ @core.create_image_with_instance(instance, options[:region])
77
+ rescue => e
78
+ @logger.info "\n#{e.message}\n#{e.backtrace.join("\n")}"
79
+ end
80
+ end
81
+ end
82
+
83
+ desc 'deregister_image', 'deregister image'
84
+ option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
85
+ option :older_than, aliases: '--older_than', type: :numeric, default: 30, desc: 'older than count.'
86
+ def deregister_image
87
+ @core.get_old_images(options[:name], options[:older_than]).each do |image|
88
+ image_id = image[:image_id]
89
+ @logger.info "delete AMI #{image_id} [#{image[:name]}]"
90
+ @ec2.deregister_image({image_id: image_id})
91
+ snapshot_ids = image[:block_device_mappings]
92
+ .select{ |block_device_mapping| block_device_mapping[:ebs] != nil }
93
+ .map{ |block_device_mapping| block_device_mapping[:ebs][:snapshot_id] }
94
+
95
+ snapshot_ids.each do |snapshot_id|
96
+ @logger.info "delete snapshot #{snapshot_id}"
97
+ @ec2.delete_snapshot({snapshot_id: snapshot_id})
98
+ end
74
99
  end
75
100
  end
76
101
 
102
+ desc 'deregister_image', 'deregister image'
103
+ option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
104
+ option :older_than, aliases: '--older_than', type: :numeric, default: 30, desc: 'older than count.'
105
+ def old_images
106
+ puts_json(@core.get_old_images(options[:name], options[:older_than]))
107
+ end
108
+
109
+ desc 'deregister_snapshot_no_related', 'AMI not related snapshot basis delete all'
110
+ option :owner_id, type: :string, required: true, desc: 'owner_id'
111
+ def deregister_snapshot_no_related
112
+ @core.deregister_snapshot_no_related(options[:owner_id])
113
+ end
114
+
77
115
  desc 'copy', 'copy instance'
78
116
  option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
79
117
  option :params, aliases: '-p', type: :string, default: '{}', desc: 'params'
80
118
  option :tag, aliases: '-t', type: :hash, default: {}, desc: 'name tag'
119
+ option :private_ip_address, type: :string, default: nil, desc: 'private_ip_address'
120
+ option :public_ip_address, type: :string, default: nil, desc: 'public_ip_address'
121
+ option :instance_count, type: :numeric, default: 1, desc: 'instance_count'
81
122
  def copy
82
- results = @core.instances_hash({ Name: options['name'] }, true)
83
- results.each do |instance|
84
- image_id = @core.create_image_with_instance(instance)
123
+ instance = @core.instances_hash_first_result({ Name: options[:name] }, true)
124
+ image_id = @core.create_image_with_instance(instance)
125
+ instance_count = options[:instance_count]
126
+ Parallel.map(instance_count.times.to_a, in_threads: Parallel.processor_count) do |server_index|
85
127
  security_group_ids = instance.security_groups.map { |security_group| security_group.group_id }
86
128
  request = {
87
129
  image_id: image_id,
@@ -89,43 +131,61 @@ module Ec2ex
89
131
  max_count: 1,
90
132
  security_group_ids: security_group_ids,
91
133
  instance_type: instance.instance_type,
92
- placement: instance.placement.to_hash,
93
- subnet_id: instance.subnet_id,
94
- private_ip_address: instance.private_ip_address
134
+ placement: instance.placement.to_hash
95
135
  }
96
- unless instance.iam_instance_profile.nil?
136
+ request[:private_ip_address] = options[:private_ip_address] if options[:private_ip_address]
137
+ if instance.iam_instance_profile
97
138
  request[:iam_instance_profile] = { name: instance.iam_instance_profile.arn.split('/').last }
98
139
  end
99
- request.merge!(eval(options['params']))
100
- request[:subnet_id] = @core.get_subnet(request[:private_ip_address]).subnet_id
140
+ if instance.key_name
141
+ request[:key_name] = instance.key_name
142
+ end
143
+
144
+ request.merge!(eval(options[:params]))
145
+ request[:subnet_id] = if request[:private_ip_address]
146
+ @core.get_subnet(request[:private_ip_address]).subnet_id
147
+ else
148
+ instance.subnet_id
149
+ end
101
150
 
102
151
  response = @ec2.run_instances(request)
103
152
  instance_id = response.instances.first.instance_id
104
153
  @ec2.wait_until(:instance_running, instance_ids: [instance_id])
105
154
  @ec2.create_tags(resources: [instance_id], tags: instance.tags)
106
- unless options['tag'].nil?
107
- @ec2.create_tags(resources: [instance_id], tags: @core.format_tag(options['tag']))
155
+ @ec2.create_tags(resources: [instance_id], tags: [{ key: 'InstanceIndex', value: "#{server_index}" }])
156
+ @ec2.create_tags(resources: [instance_id], tags: [{ key: 'InstanceCount', value: "#{instance_count}" }])
157
+ unless options[:tag].nil?
158
+ @ec2.create_tags(
159
+ resources: [instance_id],
160
+ tags: @core.format_tag(
161
+ options[:tag],
162
+ @core.get_tag_hash_from_id(instance_id)
163
+ )
164
+ )
108
165
  end
166
+ public_ip_address = get_public_ip_address(options[:public_ip_address], instance.public_ip_address, false)
167
+ @core.associate_address(instance_id, public_ip_address)
168
+ @logger.info("created instance => #{instance_id}")
109
169
  end
110
170
  end
111
171
 
112
172
  desc 'renew', 'renew instance'
113
173
  option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
114
174
  option :stop, type: :boolean, default: true, desc: 'stop'
115
- option :params, aliases: '-p', type: :string, default: nil, desc: 'params'
175
+ option :params, aliases: '-p', type: :string, default: '{}', desc: 'params'
116
176
  def renew
117
- params = eval(options['params'])
118
- results = @core.instances_hash({ Name: options['name'] }, false)
177
+ params = eval(options[:params])
178
+ results = @core.instances_hash({ Name: options[:name] }, false)
119
179
  results.each do |instance|
120
180
  tags = instance.tags
121
181
  tag_hash = @core.get_tag_hash(tags)
122
- if options['stop']
182
+ if options[:stop]
123
183
  @core.stop_instance(instance.instance_id)
124
184
  end
125
185
 
126
186
  image_id = @core.create_image_with_instance(instance)
127
187
 
128
- @core.terminate_instance(instance.instance_id)
188
+ @core.terminate_instance(instance)
129
189
  security_group_ids = instance.security_groups.map { |security_group| security_group.group_id }
130
190
  request = {
131
191
  image_id: image_id,
@@ -136,9 +196,13 @@ module Ec2ex
136
196
  placement: instance.placement.to_hash,
137
197
  private_ip_address: instance.private_ip_address
138
198
  }
139
- unless instance.iam_instance_profile.nil?
199
+ if instance.iam_instance_profile
140
200
  request[:iam_instance_profile] = { name: instance.iam_instance_profile.arn.split('/').last }
141
201
  end
202
+
203
+ if instance.key_name
204
+ request[:key_name] = instance.key_name
205
+ end
142
206
  request.merge!(params)
143
207
  request[:subnet_id] = @core.get_subnet(request[:private_ip_address]).subnet_id
144
208
 
@@ -157,18 +221,26 @@ module Ec2ex
157
221
  option :price, type: :string, required: true, desc: 'price'
158
222
  option :private_ip_address, type: :string, default: nil, desc: 'private_ip_address'
159
223
  option :public_ip_address, type: :string, default: nil, desc: 'public_ip_address'
224
+ option :block_duration_minutes, type: :numeric, default: nil, desc: 'block_duration_minutes'
160
225
  option :params, aliases: '-p', type: :string, default: '{}', desc: 'params'
161
226
  option :tag, aliases: '-t', type: :hash, default: {}, desc: 'name tag'
162
227
  option :renew, aliases: '-r', type: :boolean, default: false, desc: 'renew instance'
163
228
  option :persistent, type: :boolean, default: false, desc: 'persistent request'
229
+ option :stop, type: :boolean, default: false, desc: 'stop'
230
+ option :instance_count, type: :numeric, default: 1, desc: 'instance_count'
164
231
  def spot
165
- results = @core.instances_hash({ Name: options['name'] }, true)
166
- results.each do |instance|
167
- image_id = @core.create_image_with_instance(instance)
232
+ instance = @core.instances_hash_first_result({ Name: options[:name] }, true)
233
+ if options[:stop]
234
+ @core.stop_instance(instance.instance_id)
235
+ end
236
+ image_id = @core.create_image_with_instance(instance)
237
+
238
+ instance_count = options[:instance_count]
239
+ Parallel.map(instance_count.times.to_a, in_threads: Parallel.processor_count) do |server_index|
168
240
  security_group_ids = instance.security_groups.map { |security_group| security_group.group_id }
169
241
  option = {
170
242
  instance_count: 1,
171
- spot_price: options['price'],
243
+ spot_price: options[:price],
172
244
  launch_specification: {
173
245
  image_id: image_id,
174
246
  instance_type: instance.instance_type,
@@ -176,52 +248,61 @@ module Ec2ex
176
248
  subnet_id: instance.subnet_id
177
249
  },
178
250
  }
179
- option[:type] = 'persistent' if options['persistent']
251
+ option[:type] = 'persistent' if options[:persistent]
252
+ option[:block_duration_minutes] = options[:block_duration_minutes] if options[:block_duration_minutes]
180
253
 
181
- unless instance.iam_instance_profile.nil?
254
+ if instance.iam_instance_profile
182
255
  option[:launch_specification][:iam_instance_profile] = { name: instance.iam_instance_profile.arn.split('/').last }
183
256
  end
184
257
 
185
- option[:launch_specification].merge!(eval(options['params']))
258
+ if instance.key_name
259
+ option[:launch_specification][:key_name] = instance.key_name
260
+ end
261
+
262
+ option[:launch_specification].merge!(eval(options[:params]))
186
263
 
187
264
  private_ip_address = nil
188
- if options['private_ip_address'].nil?
189
- private_ip_address = instance.private_ip_address if options['renew']
265
+ if options[:private_ip_address].nil?
266
+ private_ip_address = instance.private_ip_address if options[:renew]
190
267
  else
191
- private_ip_address = options['private_ip_address']
268
+ private_ip_address = options[:private_ip_address]
192
269
  end
193
270
 
194
- unless private_ip_address.nil?
271
+ if private_ip_address
195
272
  network_interface = {
196
273
  device_index: 0,
197
274
  subnet_id: @core.get_subnet(private_ip_address).subnet_id,
198
- groups: security_group_ids,
275
+ groups: option[:launch_specification][:security_group_ids],
199
276
  private_ip_addresses: [{ private_ip_address: private_ip_address, primary: true }]
200
277
  }
201
278
  option[:launch_specification][:network_interfaces] = [network_interface]
202
279
  option[:launch_specification].delete(:security_group_ids)
203
280
  option[:launch_specification].delete(:subnet_id)
204
281
  end
205
- @core.terminate_instance(instance.instance_id) if options['renew']
282
+ @core.terminate_instance(instance) if options[:renew]
206
283
 
207
284
  response = @ec2.request_spot_instances(option)
208
285
  spot_instance_request_id = response.spot_instance_requests.first.spot_instance_request_id
209
286
  sleep 5
210
287
  instance_id = @core.wait_spot_running(spot_instance_request_id)
288
+ @core.set_delete_on_termination(@core.instances_hash_with_id(instance_id))
211
289
 
212
290
  @ec2.create_tags(resources: [instance_id], tags: instance.tags)
213
291
  @ec2.create_tags(resources: [instance_id], tags: [{ key: 'Spot', value: 'true' }])
214
-
215
- unless options['tag'].empty?
216
- @ec2.create_tags(resources: [instance_id], tags: @core.format_tag(options['tag']))
292
+ @ec2.create_tags(resources: [instance_id], tags: [{ key: 'InstanceIndex', value: "#{server_index}" }])
293
+ @ec2.create_tags(resources: [instance_id], tags: [{ key: 'InstanceCount', value: "#{instance_count}" }])
294
+
295
+ unless options[:tag].empty?
296
+ @ec2.create_tags(
297
+ resources: [instance_id],
298
+ tags: @core.format_tag(
299
+ options[:tag],
300
+ @core.get_tag_hash_from_id(instance_id)
301
+ )
302
+ )
217
303
  end
218
304
 
219
- public_ip_address = nil
220
- if options['public_ip_address'].nil?
221
- public_ip_address = instance.public_ip_address if options['renew']
222
- else
223
- public_ip_address = options['public_ip_address']
224
- end
305
+ public_ip_address = get_public_ip_address(options[:public_ip_address], instance.public_ip_address, options[:renew])
225
306
  @core.associate_address(instance_id, public_ip_address)
226
307
  end
227
308
  end
@@ -229,34 +310,49 @@ module Ec2ex
229
310
  desc 'run_spot', 'run_spot latest image'
230
311
  option :name, aliases: '-n', type: :string, required: true, desc: 'name tag'
231
312
  option :price, type: :string, required: true, desc: 'price'
313
+ option :private_ip_address, type: :string, default: nil, desc: 'private_ip_address'
314
+ option :params, aliases: '-p', type: :string, default: '{}', desc: 'params'
315
+ option :block_duration_minutes, type: :numeric, default: nil, desc: 'block_duration_minutes'
232
316
  def run_spot
233
- image = @core.latest_image_with_name(options['name'])
317
+ image = @core.latest_image_with_name(options[:name])
318
+
234
319
  tag_hash = @core.get_tag_hash(image[:tags])
320
+ private_ip_address = options[:private_ip_address] || tag_hash.private_ip_address
321
+ exit 0 if @core.ping?(private_ip_address)
322
+
235
323
  option = {
236
324
  instance_count: 1,
237
- spot_price: options['price'],
325
+ spot_price: options[:price],
238
326
  launch_specification: {
239
327
  image_id: image[:image_id],
240
328
  instance_type: tag_hash.instance_type
241
329
  },
242
330
  }
243
331
 
332
+ option[:block_duration_minutes] = options[:block_duration_minutes] if options[:block_duration_minutes]
333
+
244
334
  if tag_hash.iam_instance_profile
245
335
  option[:launch_specification][:iam_instance_profile] = { name: tag_hash.iam_instance_profile }
246
336
  end
247
337
 
338
+ if tag_hash.key_name
339
+ option[:launch_specification][:key_name] = tag_hash.key_name
340
+ end
341
+
248
342
  network_interface = {
249
343
  device_index: 0,
250
- subnet_id: @core.get_subnet(tag_hash.private_ip_address).subnet_id,
344
+ subnet_id: @core.get_subnet(private_ip_address).subnet_id,
251
345
  groups: JSON.parse(tag_hash.security_groups),
252
- private_ip_addresses: [{ private_ip_address: tag_hash.private_ip_address, primary: true }]
346
+ private_ip_addresses: [{ private_ip_address: private_ip_address, primary: true }]
253
347
  }
254
348
  option[:launch_specification][:network_interfaces] = [network_interface]
349
+ option[:launch_specification].merge!(eval(options[:params]))
255
350
 
256
351
  response = @ec2.request_spot_instances(option)
257
352
  spot_instance_request_id = response.spot_instance_requests.first.spot_instance_request_id
258
353
  sleep 5
259
354
  instance_id = @core.wait_spot_running(spot_instance_request_id)
355
+ @core.set_delete_on_termination(@core.instances_hash_with_id(instance_id))
260
356
  @ec2.create_tags(resources: [instance_id], tags: JSON.parse(tag_hash[:tags]))
261
357
 
262
358
  if tag_hash.public_ip_address
@@ -268,7 +364,7 @@ module Ec2ex
268
364
  option :acl_id, type: :string, default: '', required: true, desc: 'name tag'
269
365
  option :ip_address, type: :string, default: '', required: true, desc: 'name tag'
270
366
  def regist_deny_acl
271
- acls = @ec2.describe_network_acls(network_acl_ids: [options['acl_id']])
367
+ acls = @ec2.describe_network_acls(network_acl_ids: [options[:acl_id]])
272
368
 
273
369
  allow_any_rule_number = acls.network_acls.first.entries.select {|r|
274
370
  !r.egress && r.cidr_block == '0.0.0.0/0' && r.rule_action == 'allow'
@@ -280,13 +376,13 @@ module Ec2ex
280
376
 
281
377
  next_rule_number = deny_rules.empty? ? 1 : deny_rules.last.rule_number + 1
282
378
 
283
- unless deny_rules.any? { |r| r.cidr_block == "#{options['ip_address']}/32" }
379
+ unless deny_rules.any? { |r| r.cidr_block == "#{options[:ip_address]}/32" }
284
380
  option = {
285
- network_acl_id: options['acl_id'],
381
+ network_acl_id: options[:acl_id],
286
382
  rule_number: next_rule_number,
287
383
  rule_action: 'deny',
288
384
  protocol: '-1',
289
- cidr_block: "#{options['ip_address']}/32",
385
+ cidr_block: "#{options[:ip_address]}/32",
290
386
  egress: false
291
387
  }
292
388
  @ec2.create_network_acl_entry(option)
@@ -296,7 +392,7 @@ module Ec2ex
296
392
  desc 'delete_deny_acl_all', 'delete deny acl'
297
393
  option :acl_id, type: :string, required: true, desc: 'name tag'
298
394
  def delete_deny_acl_all
299
- acls = @ec2.describe_network_acls(network_acl_ids: [options['acl_id']])
395
+ acls = @ec2.describe_network_acls(network_acl_ids: [options[:acl_id]])
300
396
 
301
397
  allow_any_rule_number = acls.network_acl_set.first.entries.select {|r|
302
398
  !r.egress && r.cidr_block == '0.0.0.0/0' && r.rule_action == 'allow'
@@ -308,7 +404,7 @@ module Ec2ex
308
404
 
309
405
  deny_rules.each do |deny_rule|
310
406
  option = {
311
- network_acl_id: options['acl_id'],
407
+ network_acl_id: options[:acl_id],
312
408
  rule_number: deny_rule.rule_number,
313
409
  egress: false
314
410
  }
@@ -334,25 +430,34 @@ module Ec2ex
334
430
  desc 'copy_tag', 'request spot instances'
335
431
  option :source, aliases: '--src', type: :string, default: nil, required: true, desc: 'name tag'
336
432
  option :dest, aliases: '--dest', type: :string, default: nil, required: true, desc: 'name tag'
337
- def copy_tag(_name = options['name'])
338
- source = @core.instances_hash({ Name: options['source'] }, true)
339
- dest = @core.instances_hash({ Name: options['dest'] }, true)
433
+ def copy_tag(_name = options[:name])
434
+ source = @core.instances_hash({ Name: options[:source] }, true)
435
+ dest = @core.instances_hash({ Name: options[:dest] }, true)
340
436
  @ec2.create_tags(resources: dest.map { |instance| instance.instance_id }, tags: source.first.tags)
341
- @ec2.create_tags(resources: dest.map { |instance| instance.instance_id }, tags: [{ key: 'Name', value: options['dest'] }])
437
+ @ec2.create_tags(resources: dest.map { |instance| instance.instance_id }, tags: [{ key: 'Name', value: options[:dest] }])
342
438
  end
343
439
 
344
440
  desc 'set_tag', 'set tag'
345
441
  option :name, aliases: '-n', type: :string, required: true, desc: 'name tag'
346
442
  option :tag, aliases: '-t', type: :hash, required: true, desc: 'name tag'
347
443
  def set_tag
348
- instances = @core.instances_hash({ Name: options['name'] }, true)
349
- tags = @core.format_tag(options['tag'])
444
+ instances = @core.instances_hash({ Name: options[:name] }, true)
445
+ tags = @core.format_tag(options[:tag])
350
446
  @ec2.create_tags(resources: instances.map { |instance| instance.instance_id }, tags: tags)
351
447
  end
352
448
 
449
+ desc 'set_delete_on_termination', 'set delete on termination instance'
450
+ option :name, aliases: '-n', type: :string, required: true, desc: 'name tag'
451
+ def set_delete_on_termination
452
+ @core.instances_hash({ Name: options[:name] }, true).each do |instance|
453
+ @core.set_delete_on_termination(instance)
454
+ @logger.info "set delete on termination => #{instance.instance_id}"
455
+ end
456
+ end
457
+
353
458
  desc 'search_images', 'search images'
354
459
  option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
355
- def search_images(name = options['name'])
460
+ def search_images(name = options[:name])
356
461
  puts_json @core.images(name)
357
462
  end
358
463
 
@@ -361,8 +466,8 @@ module Ec2ex
361
466
  option :key, aliases: '-k', type: :array, required: true, desc: 'grouping key'
362
467
  option :running_only, aliases: '--ro', type: :boolean, default: true, desc: 'grouping key'
363
468
  def aggregate
364
- list = @core.instances_hash(options['condition'], options['running_only']).map do |_instance|
365
- options['key'].map do |key|
469
+ list = @core.instances_hash(options[:condition], options[:running_only]).map do |instance|
470
+ options[:key].map do |key|
366
471
  eval("instance.#{key} ")
367
472
  end.join('_')
368
473
  end
@@ -372,7 +477,7 @@ module Ec2ex
372
477
  desc 'reboot', 'reboot instance'
373
478
  option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
374
479
  def reboot
375
- @core.instances_hash({ Name: options['name'] }, true).each do |instance|
480
+ @core.instances_hash({ Name: options[:name] }, true).each do |instance|
376
481
  @ec2.reboot_instances(instance_ids: [instance.instance_id])
377
482
  sleep 5
378
483
  @ec2.wait_until(:instance_running, instance_ids: [instance.instance_id])
@@ -382,13 +487,13 @@ module Ec2ex
382
487
  desc 'stop_start', 'stop after start instance'
383
488
  option :names, aliases: '-n', type: :array, default: [], required: true, desc: 'name tag'
384
489
  def stop_start
385
- options['names'].each do |name|
490
+ options[:names].each do |name|
386
491
  @core.instances_hash({ Name: name }, true).each do |instance|
387
492
  instance.stop
388
493
  @ec2.wait_until(:instance_stopped, instance_ids: [instance.instance_id])
389
494
  instance.start
390
495
  @ec2.wait_until(:instance_running, instance_ids: [instance.instance_id])
391
- puts "#{instance.tags['Name']} restart complete!"
496
+ @logger.info "#{instance.tags['Name']} restart complete!"
392
497
  end
393
498
  end
394
499
  end
@@ -396,25 +501,34 @@ module Ec2ex
396
501
  desc 'terminate', 'terminate instance'
397
502
  option :name, aliases: '-n', type: :string, required: true, desc: 'name tag'
398
503
  def terminate
399
- @core.instances_hash({ Name: options['name'] }, false).each do |instance|
400
- @core.terminate_instance(instance.instance_id)
504
+ instances = @core.instances_hash({ Name: options[:name] }, false)
505
+ Parallel.map(instances, in_threads: Parallel.processor_count) do |instance|
506
+ @core.terminate_instance(instance)
401
507
  end
402
508
  end
403
509
 
404
- desc 'terminate', 'terminate instance'
510
+ desc 'start', 'start instance'
405
511
  option :name, aliases: '-n', type: :string, required: true, desc: 'name tag'
406
512
  def start
407
- @core.instances_hash({ Name: options['name'] }, false).each do |instance|
513
+ @core.instances_hash({ Name: options[:name] }, false).each do |instance|
408
514
  @core.start_instance(instance.instance_id)
409
515
  end
410
516
  end
411
517
 
518
+ desc 'stop', 'stop instance'
519
+ option :name, aliases: '-n', type: :string, required: true, desc: 'name tag'
520
+ def stop
521
+ @core.instances_hash({ Name: options[:name] }, false).each do |instance|
522
+ @core.stop_instance(instance.instance_id)
523
+ end
524
+ end
525
+
412
526
  desc 'connect elb', 'connect elb'
413
527
  option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
414
528
  option :load_balancer_name, aliases: '-l', type: :string, default: '', required: true, desc: 'name tag'
415
- def connect_elb(_name = options['name'])
416
- @core.instances_hash({ Name: options['name'] }, true).each do |instance|
417
- option = { load_balancer_name: options['load_balancer_name'], instances: [instance_id: instance.instance_id] }
529
+ def connect_elb(_name = options[:name])
530
+ @core.instances_hash({ Name: options[:name] }, true).each do |instance|
531
+ option = { load_balancer_name: options[:load_balancer_name], instances: [instance_id: instance.instance_id] }
418
532
  @elb.deregister_instances_from_load_balancer(option)
419
533
  @elb.register_instances_with_load_balancer(option)
420
534
  print 'connecting ELB...'
@@ -426,6 +540,16 @@ module Ec2ex
426
540
  end
427
541
  end
428
542
 
543
+ desc 'disconnect elb', 'disconnect elb'
544
+ option :name, aliases: '-n', type: :string, default: '', required: true, desc: 'name tag'
545
+ option :load_balancer_name, aliases: '-l', type: :string, default: '', required: true, desc: 'name tag'
546
+ def disconnect_elb
547
+ @core.instances_hash({ Name: options[:name] }, true).each do |instance|
548
+ option = { load_balancer_name: options[:load_balancer_name], instances: [instance_id: instance.instance_id] }
549
+ @elb.deregister_instances_from_load_balancer(option)
550
+ end
551
+ end
552
+
429
553
  desc 'elbs', 'show elbs'
430
554
  def elbs
431
555
  puts_json @elb.describe_load_balancers.data.to_h[:load_balancer_descriptions]
@@ -452,25 +576,56 @@ module Ec2ex
452
576
  desc 'latest_image', 'show elbs'
453
577
  option :name, aliases: '-n', type: :string, required: true, desc: 'name tag'
454
578
  def latest_image
455
- puts_json @core.latest_image_with_name(options['name'])
579
+ puts_json @core.latest_image_with_name(options[:name])
456
580
  end
457
581
 
458
582
  desc 'allocate_address', 'allocate address'
459
- def allocate_address
460
- response = @ec2.allocate_address(domain: 'vpc')
583
+ def allocate_address_vpc
584
+ response = @core.allocate_address_vpc
585
+ puts response.data
586
+ end
587
+
588
+ desc 'instance_metadata', 'instance metadata'
589
+ option :path, type: :string, required: true, desc: 'path'
590
+ def instance_metadata
591
+ response = @core.get_metadata(options[:path])
461
592
  puts response
462
593
  end
463
594
 
595
+ desc 'own_tag', 'own tag'
596
+ option :key, type: :string, desc: 'key'
597
+ def own_tag
598
+ response = @core.own_tag
599
+ if options[:key]
600
+ puts response[options[:key]]
601
+ else
602
+ puts_json response
603
+ end
604
+ end
605
+
464
606
  private
465
607
  def instances(name, _running_only = true)
466
608
  @ec2.instances.with_tag('Name', "#{name}")
467
609
  end
468
610
 
469
611
  def puts_json(data)
470
- unless @global_options['fields'].nil?
471
- data = @core.extract_fields(data, @global_options['fields'])
612
+ unless @global_options[:fields].nil?
613
+ data = @core.extract_fields(data, @global_options[:fields])
472
614
  end
473
615
  puts JSON.pretty_generate(data)
474
616
  end
617
+
618
+ def get_public_ip_address(define_public_ip_address, instance_public_ip_address, renew)
619
+ public_ip_address = nil
620
+ if define_public_ip_address == 'auto'
621
+ allocate_address_result = @core.allocate_address_vpc
622
+ public_ip_address = allocate_address_result.public_ip
623
+ elsif define_public_ip_address.nil?
624
+ public_ip_address = instance_public_ip_address if renew
625
+ else
626
+ public_ip_address = define_public_ip_address
627
+ end
628
+ public_ip_address
629
+ end
475
630
  end
476
631
  end
@@ -1,10 +1,47 @@
1
1
  require 'aws-sdk'
2
2
  require 'ipaddress'
3
+ require 'open-uri'
4
+ require "logger"
5
+ require 'hashie'
6
+ require 'net/ping'
3
7
 
8
+ TIME_OUT = 3
4
9
  module Ec2ex
5
10
  class Core
6
11
  def initialize
12
+ ENV['AWS_REGION'] = ENV['AWS_REGION'] || get_document['region']
7
13
  @ec2 = Aws::EC2::Client.new
14
+ @elb = Aws::ElasticLoadBalancing::Client.new
15
+ @logger = Logger.new(STDOUT);
16
+ end
17
+
18
+ def client
19
+ @ec2
20
+ end
21
+
22
+ def logger
23
+ @logger
24
+ end
25
+
26
+ def get_document
27
+ JSON.parse(get_metadata('/latest/dynamic/instance-identity/document/'))
28
+ end
29
+
30
+ def get_metadata(path)
31
+ begin
32
+ result = {}
33
+ ::Timeout.timeout(TIME_OUT) {
34
+ body = open('http://169.254.169.254' + path).read
35
+ return body
36
+ }
37
+ return result
38
+ rescue TimeoutError => e
39
+ raise "not EC2 instance"
40
+ end
41
+ end
42
+
43
+ def elb_client
44
+ @elb
8
45
  end
9
46
 
10
47
  def extract_fields(data, fields)
@@ -24,10 +61,11 @@ module Ec2ex
24
61
  Hash[list.group_by { |e| e }.map { |k, v| [k, v.length] }]
25
62
  end
26
63
 
27
- def format_tag(tag)
64
+ def format_tag(tag, preset_tag_hash = {})
28
65
  tags = []
29
66
  tag.each do |k, v|
30
- tags << { key: k, value: v }
67
+ value = v ? ERB.new(v.gsub(/\$\{([^}]+)\}/, "<%=preset_tag_hash['" + '\1' + "'] %>")).result(binding) : ''
68
+ tags << { key: k, value: value }
31
69
  end
32
70
  tags
33
71
  end
@@ -40,6 +78,14 @@ module Ec2ex
40
78
  Hashie::Mash.new(result)
41
79
  end
42
80
 
81
+ def get_tag_hash_from_id(instance_id)
82
+ preset_tag = {}
83
+ @ec2.describe_tags(filters: [{ name: 'resource-id', values: [instance_id] }]).tags.each do |tag|
84
+ preset_tag[tag.key] = tag.value
85
+ end
86
+ preset_tag
87
+ end
88
+
43
89
  def instances_hash(condition, running_only = true)
44
90
  filter = []
45
91
  condition.each do |key, value|
@@ -55,66 +101,113 @@ module Ec2ex
55
101
  ).data.to_h[:reservations].map { |instance| Hashie::Mash.new(instance[:instances].first) }
56
102
  end
57
103
 
58
- def images(name)
59
- filter = [{ name: 'is-public', values: ['false'] }]
60
- filter << { name: 'name', values: ["#{name}"] }
61
- @ec2.describe_images(
62
- filters: filter
63
- ).data.to_h[:images]
104
+ def instances_hash_first_result(condition, running_only = true)
105
+ results = instances_hash(condition, running_only)
106
+ instance = results.first
107
+ unless instance
108
+ @logger.warn("not match instance => #{condition}")
109
+ exit 1
110
+ end
111
+ instance
64
112
  end
65
113
 
66
- def create_image_with_instance(instance)
67
- puts 'image creating...'
68
- tags = get_tag_hash(instance.tags)
69
- snapshot = {
114
+ def instances_hash_with_id(instance_id)
115
+ @ec2.describe_instances(
116
+ instance_ids: [instance_id]
117
+ ).data.to_h[:reservations].map { |instance| Hashie::Mash.new(instance[:instances].first) }.first
118
+ end
119
+
120
+ def own_tag
121
+ get_tag_hash(instances_hash_with_id(get_metadata('/latest/meta-data/instance-id')).tags)
122
+ end
123
+
124
+ def get_ami_tag_hash(instance, tags)
125
+ ami_tag_hash = {
70
126
  'created' => Time.now.strftime('%Y%m%d%H%M%S'),
71
127
  'tags' => instance.tags.map(&:to_hash).to_json,
72
128
  'Name' => tags['Name']
73
129
  }
74
- snapshot['security_groups'] = instance.security_groups.map(&:group_id).to_json
75
- snapshot['private_ip_address'] = instance.private_ip_address
130
+ ami_tag_hash['security_groups'] = instance.security_groups.map(&:group_id).to_json
131
+ ami_tag_hash['private_ip_address'] = instance.private_ip_address
76
132
  unless instance.public_ip_address.nil?
77
- snapshot['public_ip_address'] = instance.public_ip_address
133
+ ami_tag_hash['public_ip_address'] = instance.public_ip_address
78
134
  end
79
- snapshot['instance_type'] = instance.instance_type
80
- snapshot['placement'] = instance.placement.to_hash.to_json
135
+ ami_tag_hash['instance_type'] = instance.instance_type
136
+ ami_tag_hash['placement'] = instance.placement.to_hash.to_json
81
137
  unless instance.iam_instance_profile.nil?
82
- snapshot['iam_instance_profile'] = instance.iam_instance_profile.arn.split('/').last
138
+ ami_tag_hash['iam_instance_profile'] = instance.iam_instance_profile.arn.split('/').last
83
139
  end
140
+ unless instance.key_name.nil?
141
+ ami_tag_hash['key_name'] = instance.key_name
142
+ end
143
+ ami_tag_hash
144
+ end
84
145
 
146
+ def create_image_with_instance(instance, region = nil)
147
+ tags = get_tag_hash(instance.tags)
148
+ @logger.info "#{tags['Name']} image creating..."
149
+
150
+ image_name = tags['Name'] + ".#{Time.now.strftime('%Y%m%d%H%M%S')}"
85
151
  image_response = @ec2.create_image(
86
152
  instance_id: instance.instance_id,
87
- name: tags['Name'] + ".#{Time.now.strftime('%Y%m%d%H%M%S')}",
153
+ name: image_name,
88
154
  no_reboot: true
89
155
  )
90
156
  sleep 10
91
157
  @ec2.wait_until(:image_available, image_ids: [image_response.image_id]) do |w|
92
158
  w.interval = 15
93
- w.max_attempts = 720
159
+ w.max_attempts = 1440
94
160
  end
95
- puts "image create complete! image_id => [#{image_response.image_id}]"
161
+ @logger.info "image create complete #{tags['Name']}! image_id => [#{image_response.image_id}]"
96
162
 
97
- ami_tag = format_tag(snapshot)
163
+ ami_tag = format_tag(get_ami_tag_hash(instance, tags))
98
164
  @ec2.create_tags(resources: [image_response.image_id], tags: ami_tag)
165
+
166
+ if region
167
+ @logger.info "copying another region... [#{ENV['AWS_REGION']}] => [#{region}]"
168
+ dest_ec2 = Aws::EC2::Client.new(region: region)
169
+ copy_image_response = dest_ec2.copy_image(
170
+ source_region: ENV['AWS_REGION'],
171
+ source_image_id: image_response.image_id,
172
+ name: image_name
173
+ )
174
+ dest_ec2.create_tags(resources: [copy_image_response.image_id], tags: ami_tag)
175
+ end
176
+
99
177
  image_response.image_id
100
178
  end
101
179
 
102
180
  def wait_spot_running(spot_instance_request_id)
103
- puts 'spot instance creating...'
181
+ @logger.info 'spot instance creating...'
104
182
  instance_id = nil
105
183
  while true
106
184
  spot_instance_request = @ec2.describe_spot_instance_requests(spot_instance_request_ids: [spot_instance_request_id]).spot_instance_requests.first
107
185
  if spot_instance_request.state == 'active'
108
186
  instance_id = spot_instance_request.instance_id
109
187
  break
188
+ elsif spot_instance_request.state == 'failed'
189
+ @logger.info spot_instance_request.fault.code
190
+ @ec2.cancel_spot_instance_requests({ spot_instance_request_ids: [spot_instance_request_id] })
191
+ raise spot_instance_request.fault.message
110
192
  end
111
193
  sleep 10
112
194
  end
113
195
  @ec2.wait_until(:instance_running, instance_ids: [instance_id])
114
- puts "spot instance create complete! instance_id => [#{instance_id}]"
196
+ @logger.info "spot instance create complete! instance_id => [#{instance_id}]"
115
197
  instance_id
116
198
  end
117
199
 
200
+ def set_delete_on_termination(instance)
201
+ block_device_mappings = instance.block_device_mappings.map{ |block_device_mapping|
202
+ ebs = block_device_mapping.ebs
203
+ {
204
+ device_name: block_device_mapping.device_name,
205
+ ebs: { volume_id: block_device_mapping.ebs.volume_id, delete_on_termination: true }
206
+ }
207
+ }
208
+ @ec2.modify_instance_attribute({instance_id: instance.instance_id, block_device_mappings: block_device_mappings})
209
+ end
210
+
118
211
  def get_allocation(public_ip_address)
119
212
  @ec2.describe_addresses(public_ips: [public_ip_address]).addresses.first
120
213
  end
@@ -128,29 +221,30 @@ module Ec2ex
128
221
  end
129
222
 
130
223
  def stop_instance(instance_id)
131
- puts 'stopping...'
224
+ @logger.info 'stopping...'
132
225
  @ec2.stop_instances(
133
226
  instance_ids: [instance_id],
134
227
  force: true
135
228
  )
136
229
  @ec2.wait_until(:instance_stopped, instance_ids: [instance_id])
137
- puts "stop instance complete! instance_id => [#{instance_id}]"
230
+ @logger.info "stop instance complete! instance_id => [#{instance_id}]"
138
231
  end
139
232
 
140
233
  def start_instance(instance_id)
141
- puts 'starting...'
234
+ @logger.info 'starting...'
142
235
  @ec2.start_instances(
143
236
  instance_ids: [instance_id]
144
237
  )
145
238
  @ec2.wait_until(:instance_running, instance_ids: [instance_id])
146
- puts "start instance complete! instance_id => [#{instance_id}]"
239
+ @logger.info "start instance complete! instance_id => [#{instance_id}]"
147
240
  end
148
241
 
149
- def terminate_instance(instance_id)
150
- puts 'terminating...'
242
+ def terminate_instance(instance)
243
+ instance_id = instance.instance_id
244
+ @logger.info 'terminating...'
151
245
  @ec2.terminate_instances(instance_ids: [instance_id])
152
246
  @ec2.wait_until(:instance_terminated, instance_ids: [instance_id])
153
- puts "terminate instance complete! instance_id => [#{instance_id}]"
247
+ @logger.info "terminate instance complete! instance_id => [#{instance_id}]"
154
248
  end
155
249
 
156
250
  def associate_address(instance_id, public_ip_address)
@@ -161,16 +255,84 @@ module Ec2ex
161
255
  end
162
256
 
163
257
  def latest_image_with_name(name)
164
- filter = [{ name: 'is-public', values: ['false'] }]
165
- filter << { name: 'tag:Name', values: [name] }
166
- result = @ec2.describe_images(
167
- filters: filter
168
- ).data.to_h[:images]
258
+ result = search_image_with_name(name)
169
259
  result = result.sort_by{ |image|
170
260
  tag_hash = get_tag_hash(image[:tags])
171
261
  tag_hash['created'].nil? ? '' : tag_hash['created']
172
262
  }
173
263
  result.empty? ? {} : result.last
174
264
  end
265
+
266
+ def get_old_images(name, num = 10)
267
+ result = search_image_with_name(name)
268
+ return [] if result.empty?
269
+ map = Hash.new{|h,k| h[k] = []}
270
+ result = result.each{ |image|
271
+ tag_hash = get_tag_hash(image[:tags])
272
+ next if tag_hash['Name'].nil? || tag_hash['created'].nil?
273
+ map[tag_hash['Name']] << image
274
+ }
275
+ old_images = []
276
+ map.each do |name, images|
277
+ sorted_images = images.sort_by{ |image|
278
+ tag_hash = get_tag_hash(image[:tags])
279
+ Time.parse(tag_hash['created'])
280
+ }
281
+ newly_images = sorted_images.last(num)
282
+ old_images = old_images + (sorted_images - newly_images)
283
+ end
284
+ old_images
285
+ end
286
+
287
+ def images(name)
288
+ filter = [{ name: 'is-public', values: ['false'] }]
289
+ filter << { name: 'name', values: [name] }
290
+ @ec2.describe_images(
291
+ filters: filter
292
+ ).data.to_h[:images]
293
+ end
294
+
295
+ def search_image_with_name(name)
296
+ filter = [{ name: 'is-public', values: ['false'] }]
297
+ filter << { name: 'tag:Name', values: [name] }
298
+ @ec2.describe_images(
299
+ filters: filter
300
+ ).data.to_h[:images]
301
+ end
302
+
303
+ def deregister_snapshot_no_related(owner_id)
304
+ enable_snapshot_ids = []
305
+ images('*').each do |image|
306
+ image_id = image[:image_id]
307
+ snapshot_ids = image[:block_device_mappings]
308
+ .select{ |block_device_mapping| block_device_mapping[:ebs] != nil }
309
+ .map{ |block_device_mapping| block_device_mapping[:ebs][:snapshot_id] }
310
+ enable_snapshot_ids.concat(snapshot_ids)
311
+ end
312
+ filter = [{ name: 'owner-id', values: [owner_id] }]
313
+ all_snapshot_ids = @ec2.describe_snapshots(
314
+ filters: filter
315
+ ).data.to_h[:snapshots].map{ |snapshot| snapshot[:snapshot_id] }
316
+ disable_snapshot_ids = (all_snapshot_ids - enable_snapshot_ids)
317
+ disable_snapshot_ids.each do |disable_snapshot_id|
318
+ @ec2.delete_snapshot({snapshot_id: disable_snapshot_id})
319
+ @logger.info "delete snapshot #{disable_snapshot_id}"
320
+ end
321
+ end
322
+
323
+ def ping?(private_ip_address)
324
+ if private_ip_address
325
+ pinger = Net::Ping::External.new(private_ip_address)
326
+ if pinger.ping?
327
+ @logger.info "already exists private_ip_address => #{private_ip_address}"
328
+ return true
329
+ end
330
+ end
331
+ return false
332
+ end
333
+
334
+ def allocate_address_vpc
335
+ @ec2.allocate_address(domain: 'vpc').data
336
+ end
175
337
  end
176
338
  end
@@ -1,4 +1,4 @@
1
1
  module Ec2ex
2
2
  # ec2ex version
3
- VERSION = '0.1.0'
3
+ VERSION = '0.2.0'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ec2ex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiroshi Toyama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-14 00:00:00.000000000 Z
11
+ date: 2016-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -56,16 +56,16 @@ dependencies:
56
56
  name: aws-sdk
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 2.0.11.pre
61
+ version: '0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 2.0.11.pre
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: activesupport
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,20 +80,48 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: parallel
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: net-ping
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: bundler
85
113
  requirement: !ruby/object:Gem::Requirement
86
114
  requirements:
87
- - - "~>"
115
+ - - ">="
88
116
  - !ruby/object:Gem::Version
89
- version: 1.7.2
117
+ version: '0'
90
118
  type: :development
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
93
121
  requirements:
94
- - - "~>"
122
+ - - ">="
95
123
  - !ruby/object:Gem::Version
96
- version: 1.7.2
124
+ version: '0'
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: pry
99
127
  requirement: !ruby/object:Gem::Requirement
@@ -225,7 +253,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
253
  version: '0'
226
254
  requirements: []
227
255
  rubyforge_project:
228
- rubygems_version: 2.4.2
256
+ rubygems_version: 2.5.1
229
257
  signing_key:
230
258
  specification_version: 4
231
259
  summary: ec2 expand command line