aws-eni 0.4.1 → 0.5.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: 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