aws-eni 0.2.2 → 0.3.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: 31f890a936163bc23d0c7bec943936be043fda58
4
- data.tar.gz: 4e5d5ac127109e761af68f26ce33caff51a00121
3
+ metadata.gz: f19e4e251a90092251316683eb8f3562300422e5
4
+ data.tar.gz: eb37b04707d8d8817fd247a3d440bc44d310dae2
5
5
  SHA512:
6
- metadata.gz: f71962db0b6c220aef90fbc6cf3c4c57d2100b90177e7a34f2a33fd78f5c67bd262c2b373269f70299c325d0a5aef1891f5a79cf0a222580ca720290957f69ea
7
- data.tar.gz: 62990ff085b4609f33745d40571ec86ba3ef1b00cc568a84ba8eea2c0b5f3534d90a7960a96d673f6b77b73c0ab38a22aff9fbeb9e56cb1d58467833d0f46d2f
6
+ metadata.gz: 56f2fca8525b755a14d3a78d654bdb5e148e593e53ba74bf193ad57e18ba25955ef5a8697ab2fc83184c6e5c43a3e3c67e80bedeb268884f2fe1c6af7e255497
7
+ data.tar.gz: ae0239c63b23e14433074b71afad75f0ceda79954d5aa5adacbae4f9fcc559d577fe1280029aedf8da181777e4d11e113153cc413598926db8dedb9d3108e5ac
@@ -11,7 +11,7 @@ program_desc 'Manage and sync local network config with AWS Elastic Network Inte
11
11
  @version = Aws::ENI::VERSION
12
12
 
13
13
  autocomplete_commands true
14
- subcommand_option_handling :normal
14
+ subcommand_option_handling :legacy
15
15
  arguments :loose
16
16
  sort_help :manually
17
17
 
@@ -65,13 +65,13 @@ def parse_args(args, *accept)
65
65
  help_now! "You may only specify one private IP address." if params[:private_ip]
66
66
  params[:private_ip] = arg
67
67
  else
68
- help_now! "Invalid IP address: #{arg}"
68
+ help_now! "Invalid argument: #{arg}"
69
69
  end
70
70
  elsif accept.include?(:public_ip)
71
71
  help_now! "You may only specify one public IP address." if params[:public_ip]
72
72
  params[:public_ip] = arg
73
73
  else
74
- help_now! "Invalid IP address: #{arg}"
74
+ help_now! "Invalid argument: #{arg}"
75
75
  end
76
76
  else
77
77
  help_now! "Invalid argument: #{arg}"
@@ -82,6 +82,8 @@ end
82
82
 
83
83
  # commands
84
84
 
85
+ default_command :list
86
+
85
87
  desc 'List current interface configuration'
86
88
  long_desc %{
87
89
  List information about a set of interfaces including interface ID, interface
@@ -230,14 +232,15 @@ arg 'subnet-id', :optional
230
232
  arg 'security-groups', :optional
231
233
  arg 'ip-address', :optional
232
234
  command [:attach] do |c|
233
- c.desc 'Do not configure or enable the device after attachment (implies block)'
234
- c.switch [:n,:noconfig], negatable: false
235
+ c.desc 'Do not configure and enable the device after attachment'
236
+ c.switch [:noconfig], negatable: false
235
237
 
236
- c.desc 'Do not return until attachment is complete'
237
- c.switch [:b,:block], negatable: false
238
+ c.desc 'Do not wait for attachment to complete (implies noconfig)'
239
+ c.switch [:n,:noblock], negatable: false
238
240
 
239
241
  c.action do |global,opts,args|
240
- config = !opts[:noconfig]
242
+ block = !opts[:noblock]
243
+ config = block && !opts[:noconfig]
241
244
  if args.first =~ /^eni-/
242
245
  help_now! 'Too many arguments' if args.count > 1
243
246
  id = args.first
@@ -251,7 +254,7 @@ command [:attach] do |c|
251
254
  new_interface = true
252
255
  end
253
256
  begin
254
- device = Aws::ENI.attach_interface(id, enable: config, configure: config, block: opts[:block])
257
+ device = Aws::ENI.attach_interface(id, enable: config, configure: config, block: block)
255
258
  rescue Aws::ENI::Errors::ClientOperationError => e
256
259
  warn e.message
257
260
  if new_interface && Aws::ENI.clean_interfaces(id, safe_mode: false)
@@ -276,20 +279,25 @@ long_desc %{
276
279
  }
277
280
  arg 'interface-id OR device-name'
278
281
  command [:detach] do |c|
279
- c.desc 'Delete (or preserve) the unused ENI resource after dataching (implies block)'
280
- c.switch [:d,:delete], default_value: :not_provided # GLI behavior workaround
282
+ c.desc 'Delete the unused ENI resource after dataching (implies block)'
283
+ c.switch [:d,:delete], negatable: false
284
+
285
+ c.desc 'Do not delete the unused ENI resource after dataching'
286
+ c.switch [:p,:preserve], negatable: false
281
287
 
282
288
  c.desc 'Release any associated public IP addresses'
283
289
  c.switch [:r,:release], negatable: false
284
290
 
285
- c.desc 'Do not return until detachment is complete'
286
- c.switch [:b,:block], negatable: false
291
+ c.desc 'Do not wait until detachment is complete'
292
+ c.switch [:n,:noblock], negatable: false
287
293
 
288
294
  c.action do |global,opts,args|
289
295
  help_now! "Missing argument" if args.empty?
296
+ help_now! "--delete and --preserve flags cannot be used together" if opts[:delete] && opts[:preserve]
290
297
  params = parse_args args, :interface_id, :device_name
291
- params[:block] = opts[:block]
292
- params[:delete] = opts[:delete] unless opts[:delete] == :not_provided
298
+ params[:block] = !opts[:noblock]
299
+ params[:delete] = true if opts[:delete]
300
+ params[:delete] = false if opts[:preserve]
293
301
  params[:release] = opts[:release]
294
302
  id = params[:device_name] || params[:interface_id]
295
303
 
@@ -357,18 +365,18 @@ long_desc %{
357
365
  arg 'ip-address', :optional
358
366
  arg 'interface-id OR device-name'
359
367
  command [:assign] do |c|
360
- c.desc 'Do not configure the interface after assignment'
361
- c.switch [:n,:noconfig], negatable: false
368
+ c.desc 'Do not configure the interface after assignment (implies noblock)'
369
+ c.switch [:noconfig], negatable: false
362
370
 
363
- c.desc 'Do not return until connection is verified'
364
- c.switch [:b,:block], negatable: false
371
+ c.desc 'Do not wait for the connection to be verified'
372
+ c.switch [:n,:noblock], negatable: false
365
373
 
366
374
  c.action do |global,opts,args|
367
375
  params = parse_args args, :interface_id, :device_name, :private_ip
368
376
  device = params[:device_name] || params[:interface_id]
369
377
  help_now! "Missing argument" if device.nil?
370
378
 
371
- params.merge! configure: !opts[:noconfig], block: opts[:block]
379
+ params.merge! configure: !opts[:noconfig], block: !opts[:noblock] && !opts[:noconfig]
372
380
  Aws::ENI.assert_interface_access if params[:configure]
373
381
 
374
382
  assignment = Aws::ENI.assign_secondary_ip(device, params)
@@ -409,11 +417,15 @@ desc 'Associate a public IP address with a private IP address'
409
417
  long_desc %{
410
418
  Associate a private IP address with a new or existing public IP address.
411
419
 
412
- If no public IP or allocation ID is provided, a new Elastic IP Address will be
413
- allocated and used.
420
+ If no public IP or allocation ID is provided, an IP address will be selected
421
+ from among the unattached Elastic IP addresses available on tha account. If
422
+ no EIP is available, a new Elastic IP Address will be allocated and used.
414
423
 
415
- If no interface ID or device name provided, it will be inferred from the ip
416
- address.
424
+ If -n or the keyword "new" is uesd, it will always allocate a new address
425
+ by default rather than using one that is already available.
426
+
427
+ If no interface ID or device name provided, it will be inferred from the
428
+ private IP address provided.
417
429
  }
418
430
  arg 'private-ip'
419
431
  arg 'public-ip', :optional
@@ -421,16 +433,20 @@ arg 'allocation-id', :optional
421
433
  arg 'interface-id', :optional
422
434
  arg 'device-name', :optional
423
435
  command [:associate] do |c|
424
- c.desc 'Do not return until connection is verified'
425
- c.switch [:b,:block], negatable: false
436
+ c.desc 'Do not wait for the connection to be verified'
437
+ c.switch [:noblock], negatable: false
438
+
439
+ c.desc 'Allocate a new public IP address (can also pass "new" as a parameter)'
440
+ c.switch [:n,:new], negatable: false
426
441
 
427
442
  c.action do |global,opts,args|
428
- args.delete('new')
443
+ opts[:new] = !!args.delete('new') || opts[:new]
429
444
  params = parse_args args, :private_ip, :public_ip, :allocation_id, :interface_id, :device_name
430
- params[:block] = opts[:block]
445
+ params.merge! new: opts[:new], block: !opts[:noblock]
431
446
  help_now! "Missing argument" unless params[:private_ip]
432
447
 
433
448
  assoc = Aws::ENI.associate_elastic_ip(params[:private_ip], params)
449
+ puts "EIP #{assoc[:public_ip]} allocated as #{assoc[:allocation_id]}" if assoc[:allocated]
434
450
  puts "EIP #{assoc[:public_ip]} (#{assoc[:allocation_id]}) associated with #{assoc[:private_ip]} on #{assoc[:device_name]} (#{assoc[:interface_id]})"
435
451
  end
436
452
  end
@@ -491,13 +507,51 @@ command [:release] do |c|
491
507
  end
492
508
  end
493
509
 
494
- desc 'Test access to AWS EC2 and our machine\'s network config'
510
+ desc 'Test a LAN or WAN connection through a specific IP'
511
+ long_desc %{
512
+ Test a LAN or WAN connection with ICMP. Provide a local IP address to test
513
+ its connection to the subnet gateway, or provide a public IP address to test
514
+ its connection to 8.8.8.8.
515
+ }
516
+ arg 'private-ip OR public-ip OR allocation-id'
517
+ arg 'interface-id', :optional
518
+ arg 'device-name', :optional
519
+ command [:test] do |c|
520
+
521
+ c.desc 'How many seconds to wait for a response to the ICMP packets'
522
+ c.flag [:t,:timeout], default_value: 30, type: Integer
523
+
524
+ c.action do |global,opts,args|
525
+ params = parse_args args, :private_ip, :public_ip, :allocation_id, :association_id, :interface_id, :device_name
526
+ params[:timeout] = opts[:timeout]
527
+
528
+ if address = params[:public_ip] || params[:association_id] || params[:allocation_id]
529
+ if Aws::ENI.test_association(address, params)
530
+ puts "EIP #{address} connection successful"
531
+ else
532
+ puts "EIP #{address} failed to connect after #{opts[:timeout]} seconds"
533
+ exit! 1
534
+ end
535
+ elsif address = params[:private_ip]
536
+ if Aws::ENI.test_secondary_ip(address, params)
537
+ puts "IP #{address} connection successful"
538
+ else
539
+ puts "IP #{address} failed to connect after #{opts[:timeout]} seconds"
540
+ exit! 1
541
+ end
542
+ else
543
+ help_now! "Missing argument"
544
+ end
545
+ end
546
+ end
547
+
548
+ desc 'Check access to AWS EC2 and our machine\'s network config'
495
549
  long_desc %{
496
550
  Check for sufficient privileges to alter the local machine's network interface
497
551
  configuration and verify that the AWS access credentials include permissions
498
552
  necessary to perform all network related functions.
499
553
  }
500
- command [:test] do |c|
554
+ command [:check] do |c|
501
555
  c.action do |global,opts,args|
502
556
  help_now! "Too many arguments" if args.count > 1
503
557
 
@@ -535,5 +589,6 @@ on_error do |error|
535
589
  end
536
590
  end
537
591
 
538
- ARGV << 'ls' if ARGV.empty?
592
+ # work around GLI's odd -v option detection
593
+ exit run %w[-v help] if (ARGV & %w[-v --version]).any?
539
594
  exit run(ARGV)
@@ -98,24 +98,25 @@ module Aws
98
98
  end
99
99
 
100
100
  # attach network interface
101
- def attach_interface(id, options = {})
102
- do_enable = true unless options[:enable] == false
103
- do_config = true unless options[:configure] == false
101
+ def attach_interface(interface_id, options = {})
102
+ do_block = options[:block] != false
103
+ do_enable = options[:enable] != false
104
+ do_config = options[:configure] != false
104
105
  assert_interface_access if do_config || do_enable
105
106
 
106
107
  device = Interface[options[:device_number] || options[:name]].assert(exists: false)
107
108
 
108
109
  begin
109
110
  response = Client.attach_network_interface(
110
- network_interface_id: id,
111
+ network_interface_id: interface_id,
111
112
  instance_id: environment[:instance_id],
112
113
  device_index: device.device_number
113
114
  )
114
115
  rescue EC2::Errors::AttachmentLimitExceeded
115
- raise Errors::ClientOperationError, "Unable to attach #{id} to #{device.name} (attachment limit exceeded)"
116
+ raise Errors::ClientOperationError, "Unable to attach #{interface_id} to #{device.name} (attachment limit exceeded)"
116
117
  end
117
118
 
118
- if options[:block] || do_config || do_enable
119
+ if do_block || do_config || do_enable
119
120
  wait_for 'the interface to attach', rescue: Errors::MetaNotFound do
120
121
  device.exists? && Client.interface_attached(device.interface_id)
121
122
  end
@@ -123,7 +124,7 @@ module Aws
123
124
  device.configure if do_config
124
125
  device.enable if do_enable
125
126
  {
126
- interface_id: device.interface_id,
127
+ interface_id: interface_id,
127
128
  device_name: device.name,
128
129
  device_number: device.device_number,
129
130
  enabled: do_enable,
@@ -133,8 +134,8 @@ module Aws
133
134
  end
134
135
 
135
136
  # detach network interface
136
- def detach_interface(id, options = {})
137
- device = Interface[id].assert(
137
+ def detach_interface(selector, options = {})
138
+ device = Interface[selector].assert(
138
139
  exists: true,
139
140
  device_name: options[:device_name],
140
141
  interface_id: options[:interface_id],
@@ -142,24 +143,18 @@ module Aws
142
143
  )
143
144
  interface = Client.describe_interface(device.interface_id)
144
145
 
146
+ do_release = !!options[:release]
147
+ created_by_us = interface.tag_set.any? { |tag| tag.key == 'created by' && tag.value == owner_tag }
148
+ do_delete = options[:delete] != false && created_by_us
149
+ do_block = options[:block] != false
150
+
145
151
  if device.name == 'eth0'
146
152
  raise Errors::InvalidInterface, 'For safety, interface eth0 cannot be detached.'
147
153
  end
148
-
149
154
  unless interface[:attachment] && interface[:attachment][:instance_id] == environment[:instance_id]
150
- raise Errors::UnknownInterface, "Interface #{interface_id} is not attached to this machine"
155
+ raise Errors::InvalidInterface, "Interface #{interface_id} is not attached to this machine"
151
156
  end
152
157
 
153
- device.disable
154
- device.deconfigure
155
- Client.detach_network_interface(
156
- attachment_id: interface[:attachment][:attachment_id],
157
- force: true
158
- )
159
- created_by_us = interface.tag_set.any? { |tag| tag.key == 'created by' && tag.value == owner_tag }
160
- do_delete = options[:delete] != false && created_by_us
161
- do_release = !!options[:release]
162
-
163
158
  public_ips = []
164
159
  interface[:private_ip_addresses].each do |addr|
165
160
  if assoc = addr[:association]
@@ -171,7 +166,13 @@ module Aws
171
166
  end
172
167
  end
173
168
 
174
- if options[:block] || do_delete
169
+ device.disable
170
+ device.deconfigure
171
+ Client.detach_network_interface(
172
+ attachment_id: interface[:attachment][:attachment_id],
173
+ force: true
174
+ )
175
+ if do_block || do_delete
175
176
  wait_for 'the interface to detach', interval: 0.3 do
176
177
  !device.exists? && !Client.interface_attached(interface[:network_interface_id])
177
178
  end
@@ -193,7 +194,7 @@ module Aws
193
194
  def clean_interfaces(filter = nil, options = {})
194
195
  public_ips = []
195
196
  do_release = !!options[:release]
196
- safe_mode = true unless options[:safe_mode] == false
197
+ safe_mode = options[:safe_mode] != false
197
198
 
198
199
  filters = [
199
200
  { name: 'vpc-id', values: [environment[:vpc_id]] },
@@ -255,8 +256,14 @@ module Aws
255
256
  )
256
257
  interface_id = device.interface_id
257
258
  current_ips = Client.interface_private_ips(interface_id)
259
+ do_config = options[:configure] != false
260
+ do_block = options[:block] != false
258
261
  new_ip = options[:private_ip]
259
262
 
263
+ if do_block && !device.enabled?
264
+ raise Errors::InvalidParameter, "Interface #{device.name} is not enabled (cannot block)"
265
+ end
266
+
260
267
  if new_ip
261
268
  if current_ips.include?(new_ip)
262
269
  raise Errors::ClientOperationError, "IP #{new_ip} already assigned to #{device.name}"
@@ -283,9 +290,9 @@ module Aws
283
290
  end
284
291
  end
285
292
 
286
- unless options[:configure] == false
293
+ if do_config
287
294
  device.add_alias(new_ip)
288
- if options[:block] && !Interface.test(new_ip, target: device.gateway)
295
+ if do_block && !Interface.test(new_ip, target: device.gateway)
289
296
  raise Errors::TimeoutError, 'Timed out waiting for IP address to become active'
290
297
  end
291
298
  end
@@ -339,9 +346,27 @@ module Aws
339
346
  }
340
347
  end
341
348
 
349
+ # validate a local area connection on a secondary ip address
350
+ def test_secondary_ip(private_ip, options = {})
351
+ timeout = options[:timeout] || self.timeout
352
+
353
+ find = options[:device_name] || options[:device_number] || options[:interface_id] || private_ip
354
+ device = Interface[find].assert(
355
+ exists: true,
356
+ enabled: true,
357
+ device_name: options[:device_name],
358
+ interface_id: options[:interface_id],
359
+ device_number: options[:device_number],
360
+ private_ip: private_ip
361
+ )
362
+ Interface.test(private_ip, target: device.gateway, timeout: timeout)
363
+ end
364
+
342
365
  # associate a private ip with an elastic ip through the AWS api
343
366
  def associate_elastic_ip(private_ip, options = {})
344
367
  raise Errors::MissingInput, 'You must specify a private IP address' unless private_ip
368
+ do_alloc = !!options[:new]
369
+ do_block = options[:block] != false
345
370
 
346
371
  find = options[:device_name] || options[:device_number] || options[:interface_id] || private_ip
347
372
  device = Interface[find].assert(
@@ -353,6 +378,9 @@ module Aws
353
378
  )
354
379
  options[:public_ip] ||= options[:allocation_id]
355
380
 
381
+ if do_block && !device.enabled?
382
+ raise Errors::InvalidParameter, "Interface #{device.name} is not enabled (cannot block)"
383
+ end
356
384
  if public_ip = device.public_ips[private_ip]
357
385
  raise Errors::ClientOperationError, "IP #{private_ip} already has an associated EIP (#{public_ip})"
358
386
  end
@@ -362,7 +390,8 @@ module Aws
362
390
  if options[:allocation_id] && eip[:allocation_id] != options[:allocation_id]
363
391
  raise Errors::InvalidAddress, "EIP #{eip[:public_ip]} (#{eip[:allocation_id]}) does not match #{options[:allocation_id]}"
364
392
  end
365
- else
393
+ elsif do_alloc || !eip = Client.available_addresses.first
394
+ allocated = true
366
395
  eip = allocate_elastic_ip
367
396
  end
368
397
 
@@ -373,13 +402,14 @@ module Aws
373
402
  allow_reassociation: false
374
403
  )
375
404
 
376
- if options[:block] && !Interface.test(private_ip)
405
+ if do_block && !Interface.test(private_ip)
377
406
  raise Errors::TimeoutError, 'Timed out waiting for ip address to become active'
378
407
  end
379
408
  {
380
409
  private_ip: private_ip,
381
410
  device_name: device.name,
382
411
  interface_id: device.interface_id,
412
+ allocated: !!allocated,
383
413
  public_ip: eip[:public_ip],
384
414
  allocation_id: eip[:allocation_id],
385
415
  association_id: resp[:association_id]
@@ -444,9 +474,64 @@ module Aws
444
474
  }
445
475
  end
446
476
 
477
+ # validate an internet connection on a secondary ip address with an
478
+ # associated elastic ip
479
+ def test_association(address, options = {})
480
+ timeout = options[:timeout] || self.timeout
481
+
482
+ # assert device attributes if we've specified a device
483
+ if find = options[:device_name] || options[:device_number]
484
+ device = Interface[find].assert(
485
+ device_name: options[:device_name],
486
+ device_number: options[:device_number],
487
+ interface_id: options[:interface_id],
488
+ private_ip: options[:private_ip],
489
+ public_ip: options[:public_ip]
490
+ )
491
+ end
492
+
493
+ # get our address info
494
+ eip = Client.describe_address(address)
495
+ device ||= Interface.find { |dev| dev.interface_id == eip[:network_interface_id] }
496
+
497
+ # assert eip attributes if options provided
498
+ if options[:private_ip] && eip[:private_ip_address] != options[:private_ip]
499
+ raise Errors::InvalidAddress, "#{address} is not associated with IP #{options[:private_ip]}"
500
+ end
501
+ if options[:public_ip] && eip[:public_ip] != options[:public_ip]
502
+ raise Errors::InvalidAddress, "#{address} is not associated with public IP #{options[:public_ip]}"
503
+ end
504
+ if options[:allocation_id] && eip[:allocation_id] != options[:allocation_id]
505
+ raise Errors::InvalidAddress, "#{address} is not associated with allocation ID #{options[:allocation_id]}"
506
+ end
507
+ if options[:association_id] && eip[:association_id] != options[:association_id]
508
+ raise Errors::InvalidAddress, "#{address} is not associated with association ID #{options[:association_id]}"
509
+ end
510
+ if options[:interface_id] && eip[:network_interface_id] != options[:interface_id]
511
+ raise Errors::InvalidAddress, "#{address} is not associated with interface ID #{options[:interface_id]}"
512
+ end
513
+
514
+ # assert that this eip attached to an enabled, configured interface on this machine
515
+ unless device
516
+ raise Errors::InvalidAddress, "#{address} is not associated with an interface on this machine"
517
+ end
518
+ unless device.enabled?
519
+ raise Errors::InvalidAddress, "#{address} cannot be tested while #{device.name} is disabled"
520
+ end
521
+ unless device.local_ips.include?(eip[:private_ip_address])
522
+ raise Errors::InvalidAddress, "#{address} cannot be tested until #{device.name} is configured"
523
+ end
524
+
525
+ Interface.test(eip[:private_ip_address], timeout: timeout)
526
+ end
527
+
447
528
  # allocate a new elastic ip address
448
529
  def allocate_elastic_ip
449
530
  eip = Client.allocate_address(domain: 'vpc')
531
+ wait_for 'new elastic ip to become available', rescue: Errors::UnknownAddress do
532
+ # strangely this doesn't happen immediately in some cases
533
+ Client.describe_address(eip[:allocation_id])
534
+ end
450
535
  {
451
536
  public_ip: eip[:public_ip],
452
537
  allocation_id: eip[:allocation_id]
@@ -41,7 +41,7 @@ module Aws
41
41
 
42
42
  # retrieve a single interface resource
43
43
  def describe_interface(id)
44
- resp = describe_network_interfaces(network_interface_ids: [id])
44
+ resp = describe_network_interfaces(filters: [{ name: 'network-interface-id', values: [id] }])
45
45
  raise Errors::UnknownInterface, "Interface #{id} could not be located" if resp[:network_interfaces].empty?
46
46
  resp[:network_interfaces].first
47
47
  end
@@ -65,10 +65,16 @@ module Aws
65
65
  { name: 'domain', values: ['vpc'] },
66
66
  { name: filter_by, values: [address] }
67
67
  ])
68
- raise Errors::UnknownAddress, "IP #{address} could not be located" if resp[:addresses].empty?
68
+ raise Errors::UnknownAddress, "No EIP with #{address} could be located" if resp[:addresses].empty?
69
69
  resp[:addresses].first
70
70
  end
71
71
 
72
+ # retrieve a list of available addresses
73
+ def available_addresses
74
+ filters = [{ name: 'domain', values: ['vpc'] }]
75
+ describe_addresses(filters: filters)[:addresses].select{ |addr| !addr.association_id }
76
+ end
77
+
72
78
  # retrieve an array of private ips associated with the given interface
73
79
  def interface_private_ips(id)
74
80
  interface = describe_interface(id)
@@ -135,8 +141,7 @@ module Aws
135
141
  client.public_send(method, params.merge(dry_run: true))
136
142
  rescue EC2::Errors::DryRunOperation
137
143
  true
138
- rescue EC2::Errors::InvalidAllocationIDNotFound
139
- # release_address does not properly support dry_run
144
+ rescue EC2::Errors::InvalidAllocationIDNotFound, EC2::Errors::InvalidAssociationIDNotFound
140
145
  true
141
146
  rescue EC2::Errors::UnauthorizedOperation
142
147
  false
@@ -169,7 +169,7 @@ module Aws
169
169
  hwaddr = self.hwaddr
170
170
  unless @meta_cache && @meta_cache[:hwaddr] == hwaddr
171
171
  @meta_cache = Meta.connection do
172
- raise MetaBadResponse unless Meta.interface(hwaddr, '')
172
+ raise Errors::MetaBadResponse unless Meta.interface(hwaddr, '', not_found: nil)
173
173
  {
174
174
  hwaddr: hwaddr,
175
175
  interface_id: Meta.interface(hwaddr, 'interface-id'),
@@ -179,6 +179,8 @@ module Aws
179
179
  end
180
180
  end
181
181
  @meta_cache
182
+ rescue Errors::MetaConnectionFailed
183
+ raise Errors::InvalidInterface, "Interface #{name} could not be found in the EC2 instance meta-data"
182
184
  end
183
185
 
184
186
  def interface_id
@@ -32,7 +32,7 @@ module Aws
32
32
  when 200
33
33
  @cache[path] = response.body
34
34
  when 404
35
- raise Errors::MetaNotFound unless options[:not_found]
35
+ raise Errors::MetaNotFound unless options.has_key?(:not_found)
36
36
  options[:not_found]
37
37
  else
38
38
  raise Errors::MetaBadResponse
@@ -1,5 +1,5 @@
1
1
  module Aws
2
2
  module ENI
3
- VERSION = "0.2.2"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-eni
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Greiling
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-06 00:00:00.000000000 Z
11
+ date: 2015-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gli