module Aws::ENI::Client
Public Instance Methods
available_addresses()
click to toggle source
retrieve a list of available addresses
# 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()
click to toggle source
lazy-load our ec2 client
# 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)
click to toggle source
retrieve a single address resource by public ip, associated private ip, allocation id, or association id
# 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)
click to toggle source
retrieve a single interface resource
# 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?()
click to toggle source
test whether we have the appropriate permissions within our AWS access credentials to perform all possible API calls
# 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)
click to toggle source
determine whether a given interface is attached or free
# File lib/aws-eni/client.rb, line 97 def interface_attached(id) describe_interface(id)[:status] == 'in-use' end
interface_private_ips(id)
click to toggle source
retrieve an array of private ips associated with the given interface
# 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
method_missing(method, *args)
click to toggle source
pass along method calls to our lazy-loaded api client
# 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.message}" rescue EC2::Errors::UnauthorizedOperation => e raise Errors::ClientPermissionError, "Operation not permitted: #{e.message}" rescue EC2::Errors::ServiceError => e error = e.class.to_s.gsub(/^.*::/, '') raise Errors::ClientOperationError, "EC2 service error (#{error}: #{e.message})" end
region()
click to toggle source
determine the region from instance metadata
# 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()
click to toggle source
determine the vpc cidr block from instance metadata
# 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