aws-eni 0.4.1 → 0.5.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c19de93aff68758d1c59c46801a7ad707350aa7b
4
- data.tar.gz: 6fb377899c3f4c1f894d82a195768e699388cfec
3
+ metadata.gz: 4ac27064fd3f98202092c5328017e064dadf2aeb
4
+ data.tar.gz: 524ff66d382280f6a2e453eb26c43e8380b311fa
5
5
  SHA512:
6
- metadata.gz: ef384ea2c14806ba12a499563639b8c1f4b9d63ee7c4b4f081c3cb6368813d625003204fccee7c68d9220f63741de189020b19c471ed8ee408cb1319298cb085
7
- data.tar.gz: d3e0e7595785be73265394aa356457f343001033b03ef32336e41c6cd58909ecf83f8b1d2ad7f1ebe9f4d404b5306ea44da5fcae619508573eff6f3d856e0cba
6
+ metadata.gz: 0f3f68fde457610edc205c8eabfd18fe87ee81c40da35e42ee5bc1dd034de94e05e8d0492e4f59f360eabcbb7f1012cd781f4e4295d1ce4b257a92a92610983a
7
+ data.tar.gz: f869c4491ca2989a2dfb7a4fde3b4096eefe9fb85385d0fbec7f93f363ed84aa3526ce6e06d3c70df8c75aa4c387dd2dd82fe8c6429b1d342bf8e6f4ba71b0bd
data/README.md CHANGED
@@ -110,6 +110,43 @@ if Aws::ENI.test_association(assoc[:public_ip])
110
110
  else
111
111
  ```
112
112
 
113
+ ## AWS Policy
114
+
115
+ To use this utility, you will need to create and apply the following policy document.
116
+
117
+ Name it something like "AmazonEC2ElasticNetworkInterfaceAccess" and attach it to your IAM instance role or IAM user.
118
+
119
+ ```json
120
+ {
121
+ "Version": "2012-10-17",
122
+ "Statement": [
123
+ {
124
+ "Effect": "Allow",
125
+ "Action": [
126
+ "ec2:AllocateAddress",
127
+ "ec2:AssignPrivateIpAddresses",
128
+ "ec2:AssociateAddress",
129
+ "ec2:AttachNetworkInterface",
130
+ "ec2:CreateNetworkInterface",
131
+ "ec2:CreateTags",
132
+ "ec2:DeleteNetworkInterface",
133
+ "ec2:DescribeAddresses",
134
+ "ec2:DescribeAvailabilityZones",
135
+ "ec2:DescribeInternetGateways",
136
+ "ec2:DescribeNetworkInterfaces",
137
+ "ec2:DescribeSecurityGroups",
138
+ "ec2:DescribeSubnets",
139
+ "ec2:DetachNetworkInterface",
140
+ "ec2:DisassociateAddress",
141
+ "ec2:ModifyNetworkInterfaceAttribute",
142
+ "ec2:ReleaseAddress",
143
+ "ec2:UnassignPrivateIpAddresses"
144
+ ],
145
+ "Resource": "*"
146
+ }
147
+ ]
148
+ }
149
+ ```
113
150
 
114
151
  ## Contributing
115
152
 
@@ -255,7 +255,7 @@ command [:attach] do |c|
255
255
  end
256
256
  begin
257
257
  device = Aws::ENI.attach_interface(id, enable: config, configure: config, block: block)
258
- rescue Aws::ENI::Errors::ClientOperationError => e
258
+ rescue Aws::ENI::Errors::LimitExceeded => e
259
259
  warn e.message
260
260
  if new_interface && Aws::ENI.clean_interfaces(id, safe_mode: false)
261
261
  puts "interface #{id} deleted"
@@ -18,6 +18,7 @@ module Aws
18
18
  hwaddr = Meta.instance('network/interfaces/macs/').lines.first.strip.chomp('/')
19
19
  {
20
20
  instance_id: Meta.instance('instance-id'),
21
+ instance_type: Meta.instance('instance-type'),
21
22
  availability_zone: Meta.instance('placement/availability-zone'),
22
23
  region: Meta.instance('placement/availability-zone').sub(/^(.*)[a-z]$/,'\1'),
23
24
  vpc_id: Meta.interface(hwaddr, 'vpc-id'),
@@ -111,16 +112,15 @@ module Aws
111
112
 
112
113
  device = Interface[options[:device_number] || options[:name]].assert(exists: false)
113
114
 
114
- begin
115
- response = Client.attach_network_interface(
116
- network_interface_id: interface_id,
117
- instance_id: environment[:instance_id],
118
- device_index: device.device_number
119
- )
120
- rescue EC2::Errors::AttachmentLimitExceeded
121
- raise Errors::ClientOperationError, "Unable to attach #{interface_id} to #{device.name} (attachment limit exceeded)"
115
+ if Interface.count >= interface_limit
116
+ raise Errors::LimitExceeded, "Unable to attach #{interface_id} to #{device.name} (attachment limit exceeded)"
122
117
  end
123
118
 
119
+ response = Client.attach_network_interface(
120
+ network_interface_id: interface_id,
121
+ instance_id: environment[:instance_id],
122
+ device_index: device.device_number
123
+ )
124
124
  if do_block || do_config || do_enable
125
125
  wait_for 'the interface to attach', rescue: Errors::InvalidInterface do
126
126
  device.exists? && Client.interface_attached(device.interface_id)
@@ -265,6 +265,10 @@ module Aws
265
265
  do_block = options[:block] != false
266
266
  new_ip = options[:private_ip]
267
267
 
268
+ if current_ips.count >= interface_ip_limit
269
+ raise Errors::LimitExceeded, "Unable to assign #{new_ip || 'new IP'} to #{interface_id} (assignment limit exceeded)"
270
+ end
271
+
268
272
  if do_block && !device.enabled?
269
273
  raise Errors::InvalidParameter, "Interface #{device.name} is not enabled (cannot test connection)"
270
274
  end
@@ -625,5 +629,65 @@ module Aws
625
629
  end
626
630
  raise Errors::TimeoutError, "Timed out waiting for #{task}" unless timeout > 0
627
631
  end
632
+
633
+ # aws interface and private ip address limits for each instance type
634
+ # transcribed from: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html
635
+ RESOURCE_LIMITS = {
636
+ 'c1.medium' => [2, 6],
637
+ 'c1.xlarge' => [4, 15],
638
+ 'c3.large' => [3, 10],
639
+ 'c3.xlarge' => [4, 15],
640
+ 'c3.2xlarge' => [4, 15],
641
+ 'c3.4xlarge' => [8, 30],
642
+ 'c3.8xlarge' => [8, 30],
643
+ 'c4.large' => [3, 10],
644
+ 'c4.xlarge' => [4, 15],
645
+ 'c4.2xlarge' => [4, 15],
646
+ 'c4.4xlarge' => [8, 30],
647
+ 'c4.8xlarge' => [8, 30],
648
+ 'cc2.8xlarge' => [8, 30],
649
+ 'cg1.4xlarge' => [8, 30],
650
+ 'cr1.8xlarge' => [8, 30],
651
+ 'd2.xlarge' => [4, 15],
652
+ 'd2.2xlarge' => [4, 15],
653
+ 'd2.4xlarge' => [8, 30],
654
+ 'd2.8xlarge' => [8, 30],
655
+ 'g2.2xlarge' => [4, 15],
656
+ 'g2.8xlarge' => [8, 30],
657
+ 'hi1.4xlarge' => [8, 30],
658
+ 'hs1.8xlarge' => [8, 30],
659
+ 'i2.xlarge' => [4, 15],
660
+ 'i2.2xlarge' => [4, 15],
661
+ 'i2.4xlarge' => [8, 30],
662
+ 'i2.8xlarge' => [8, 30],
663
+ 'm1.small' => [2, 4],
664
+ 'm1.medium' => [2, 6],
665
+ 'm1.large' => [3, 10],
666
+ 'm1.xlarge' => [4, 15],
667
+ 'm2.xlarge' => [4, 15],
668
+ 'm2.2xlarge' => [4, 30],
669
+ 'm2.4xlarge' => [8, 30],
670
+ 'm3.medium' => [2, 6],
671
+ 'm3.large' => [3, 10],
672
+ 'm3.xlarge' => [4, 15],
673
+ 'm3.2xlarge' => [4, 30],
674
+ 'r3.large' => [3, 10],
675
+ 'r3.xlarge' => [4, 15],
676
+ 'r3.2xlarge' => [4, 15],
677
+ 'r3.4xlarge' => [8, 30],
678
+ 'r3.8xlarge' => [8, 30],
679
+ 't1.micro' => [2, 2],
680
+ 't2.micro' => [2, 2],
681
+ 't2.small' => [2, 4],
682
+ 't2.medium' => [3, 6]
683
+ }.freeze
684
+
685
+ def interface_limit
686
+ Array(RESOURCE_LIMITS[environment[:instance_type]]).first || 8
687
+ end
688
+
689
+ def interface_ip_limit
690
+ Array(RESOURCE_LIMITS[environment[:instance_type]]).last || 30
691
+ end
628
692
  end
629
693
  end
@@ -34,6 +34,8 @@ module Aws
34
34
  # pass along method calls to our lazy-loaded api client
35
35
  def method_missing(method, *args)
36
36
  client.public_send(method, *args)
37
+ rescue EC2::Errors::AttachmentLimitExceeded, EC2::Errors::PrivateIpAddressLimitExceeded, EC2::Errors::AddressLimitExceeded => e
38
+ raise Errors::LimitExceeded, "Limit exceeded: #{e.message}"
37
39
  rescue EC2::Errors::UnauthorizedOperation => e
38
40
  raise Errors::ClientPermissionError, "Operation not permitted: #{e.message}"
39
41
  rescue EC2::Errors::ServiceError => e
@@ -69,6 +71,8 @@ module Aws
69
71
  ])
70
72
  raise Errors::UnknownAddress, "No EIP with #{address} could be located" if resp[:addresses].empty?
71
73
  resp[:addresses].first
74
+ rescue IPAddr::InvalidAddressError
75
+ raise Errors::InvalidAddress, "Invalid address: #{address}"
72
76
  end
73
77
 
74
78
  # retrieve a list of available addresses
@@ -24,6 +24,8 @@ module Aws
24
24
 
25
25
  class UnknownAddress < ServiceError; end
26
26
  class InvalidAddress < ServiceError; end
27
+
28
+ class LimitExceeded < ServiceError; end
27
29
  end
28
30
  end
29
31
  end
@@ -1,5 +1,5 @@
1
1
  module Aws
2
2
  module ENI
3
- VERSION = "0.4.1"
3
+ VERSION = "0.5.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.4.1
4
+ version: 0.5.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-14 00:00:00.000000000 Z
11
+ date: 2015-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gli