Module: Aws::ENI::Client
Instance Method Summary collapse
-
#available_addresses ⇒ Object
retrieve a list of available addresses.
-
#client ⇒ Object
lazy-load our ec2 client.
-
#describe_address(address) ⇒ Object
retrieve a single address resource by public ip, associated private ip, allocation id, or association id.
-
#describe_interface(id) ⇒ Object
retrieve a single interface resource.
-
#has_access? ⇒ Boolean
test whether we have the appropriate permissions within our AWS access credentials to perform all possible API calls.
-
#interface_attached(id) ⇒ Object
determine whether a given interface is attached or free.
-
#interface_private_ips(id) ⇒ Object
retrieve an array of private ips associated with the given interface.
-
#method_missing(method, *args) ⇒ Object
pass along method calls to our lazy-loaded api client.
-
#region ⇒ Object
determine the region from instance metadata.
-
#vpc_cidr ⇒ Object
determine the vpc cidr block from instance metadata.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
pass along method calls to our lazy-loaded api client
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/aws-eni/client.rb', line 35 def method_missing(method, *args) client.public_send(method, *args) rescue EC2::Errors::AttachmentLimitExceeded, EC2::Errors::PrivateIpAddressLimitExceeded, EC2::Errors::AddressLimitExceeded => e raise Errors::LimitExceeded, "Limit exceeded: #{e.}" rescue EC2::Errors::UnauthorizedOperation => e raise Errors::ClientPermissionError, "Operation not permitted: #{e.}" rescue EC2::Errors::ServiceError => e error = e.class.to_s.gsub(/^.*::/, '') raise Errors::ClientOperationError, "EC2 service error (#{error}: #{e.})" end |
Instance Method Details
#available_addresses ⇒ Object
retrieve a list of available addresses
79 80 81 82 |
# File 'lib/aws-eni/client.rb', line 79 def available_addresses filters = [{ name: 'domain', values: ['vpc'] }] describe_addresses(filters: filters)[:addresses].select{ |addr| !addr.association_id } end |
#client ⇒ Object
lazy-load our ec2 client
26 27 28 29 30 31 32 |
# File 'lib/aws-eni/client.rb', line 26 def client @client ||= EC2::Client.new(region: region) rescue Errors::ServiceError raise rescue raise Errors::EnvironmentError, 'Unable to initialize EC2 client' end |
#describe_address(address) ⇒ Object
retrieve a single address resource by public ip, associated private ip, allocation id, or association id
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/aws-eni/client.rb', line 55 def describe_address(address) filter_by = case address when /^eipalloc-/ 'allocation-id' when /^eipassoc-/ 'association-id' else if IPAddr.new(vpc_cidr) === IPAddr.new(address) 'private-ip-address' else 'public-ip' end end resp = describe_addresses(filters: [ { name: 'domain', values: ['vpc'] }, { name: filter_by, values: [address] } ]) raise Errors::UnknownAddress, "No EIP with #{address} could be located" if resp[:addresses].empty? resp[:addresses].first rescue IPAddr::InvalidAddressError raise Errors::InvalidAddress, "Invalid address: #{address}" end |
#describe_interface(id) ⇒ Object
retrieve a single interface resource
47 48 49 50 51 |
# File 'lib/aws-eni/client.rb', line 47 def describe_interface(id) resp = describe_network_interfaces(filters: [{ name: 'network-interface-id', values: [id] }]) raise Errors::UnknownInterface, "Interface #{id} could not be located" if resp[:network_interfaces].empty? resp[:network_interfaces].first end |
#has_access? ⇒ Boolean
test whether we have the appropriate permissions within our AWS access credentials to perform all possible API calls
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/aws-eni/client.rb', line 103 def has_access? test_methods = { describe_network_interfaces: {}, create_network_interface: { subnet_id: 'subnet-abcd1234' }, attach_network_interface: { network_interface_id: 'eni-abcd1234', instance_id: 'i-abcd1234', device_index: 0 }, detach_network_interface: { attachment_id: 'eni-attach-abcd1234' }, delete_network_interface: { network_interface_id: 'eni-abcd1234' }, create_tags: { resources: ['eni-abcd1234'], tags: [] }, describe_addresses: {}, allocate_address: {}, release_address: { allocation_id: 'eipalloc-abcd1234' }, associate_address: { allocation_id: 'eipalloc-abcd1234', network_interface_id: 'eni-abcd1234' }, disassociate_address: { association_id: 'eipassoc-abcd1234' } # these have no dry_run method # assign_private_ip_addresses: { # network_interface_id: 'eni-abcd1234' # } # unassign_private_ip_addresses: { # network_interface_id: 'eni-abcd1234', # private_ip_addresses: ['0.0.0.0'] # } } test_methods.all? do |method, params| begin client.public_send(method, params.merge(dry_run: true)) rescue EC2::Errors::DryRunOperation true rescue EC2::Errors::InvalidAllocationIDNotFound, EC2::Errors::InvalidAssociationIDNotFound true rescue EC2::Errors::UnauthorizedOperation false rescue EC2::Errors::ServiceError # raise Errors::ClientOperationError, 'Unexpected behavior while testing EC2 client permissions' true else raise Errors::ClientOperationError, 'Unexpected behavior while testing EC2 client permissions' end end end |
#interface_attached(id) ⇒ Object
determine whether a given interface is attached or free
97 98 99 |
# File 'lib/aws-eni/client.rb', line 97 def interface_attached(id) describe_interface(id)[:status] == 'in-use' end |
#interface_private_ips(id) ⇒ Object
retrieve an array of private ips associated with the given interface
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/aws-eni/client.rb', line 85 def interface_private_ips(id) interface = describe_interface(id) if interface[:private_ip_addresses] primary = interface[:private_ip_addresses].find { |ip| ip[:primary] } interface[:private_ip_addresses].map { |ip| ip[:private_ip_address] }.tap do |ips| # ensure primary ip is first in the list ips.unshift(*ips.delete(primary[:private_ip_address])) if primary end end end |
#region ⇒ Object
determine the region from instance metadata
11 12 13 14 15 |
# File 'lib/aws-eni/client.rb', line 11 def region Meta.instance('placement/availability-zone').sub(/^(.*)[a-z]$/,'\1') rescue Errors::MetaConnectionFailed raise Errors::EnvironmentError, 'Unable to load EC2 meta-data' end |
#vpc_cidr ⇒ Object
determine the vpc cidr block from instance metadata
18 19 20 21 22 23 |
# File 'lib/aws-eni/client.rb', line 18 def vpc_cidr hwaddr = Meta.instance('network/interfaces/macs/').lines.first.strip.chomp('/') Meta.interface(hwaddr, 'vpc-ipv4-cidr-block') rescue Errors::MetaConnectionFailed, Errors::MetaNotFound raise Errors::EnvironmentError, 'Unable to load EC2 meta-data' end |