Module: Aws::ENI::Meta

Extended by:
Meta
Included in:
Meta
Defined in:
lib/aws-eni/meta.rb

Constant Summary collapse

FAILURES =

These are the errors we trap when attempting to talk to the instance metadata service. Any of these imply the service is not present, not responding or some other non-recoverable error.

[
  Errno::EHOSTUNREACH,
  Errno::ECONNREFUSED,
  Errno::EHOSTDOWN,
  Errno::ENETUNREACH,
  Timeout::Error,
  SocketError,
  Errors::MetaBadResponse,
]

Instance Method Summary collapse

Instance Method Details

#connection(options = {}) ⇒ Object

Open a connection and attempt to execute the block ‘retries` times. Can specify open and read timeouts in addition to the number of retries.

Raises:

  • (ArgumentError)


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/aws-eni/meta.rb', line 62

def connection(options = {})
  raise ArgumentError, 'Must be called with a block' unless block_given?
  attempts = 0
  retries = options[:retries] || 5

  if (http = @connections[Thread.current]) && http.active?
    yield(http)
  else
    begin
      http = Net::HTTP.new('169.254.169.254', '80', nil)
      http.open_timeout = options[:open_timeout] || 5
      http.read_timeout = options[:read_timeout] || 5

      @connections[Thread.current] = http.start
      yield(http)
    rescue *FAILURES => e
      if attempts < retries
        # increasing cooldown time on each attempt
        Kernel.sleep(1.2 ** attempts)
        attempts += 1
        retry
      else
        raise Errors::MetaConnectionFailed, "EC2 Metadata request failed after #{retries} retries."
      end
    ensure
      http = @connections.delete(Thread.current)
      http.finish if http && http.active?
    end
  end
end

#get(path, options = {}) ⇒ Object

Perform a GET request on an open HTTP connection to the EC2 instance meta-data and return the body of any 200 response.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/aws-eni/meta.rb', line 28

def get(path, options = {})
  @cache ||= {}
  if @cache[path] && options[:cache] != false
    @cache[path]
  else
    connection(options) do |http|
      response = http.request(Net::HTTP::Get.new(path))
      case response.code.to_i
      when 200
        @cache[path] = response.body
      when 404
        raise Errors::MetaNotFound unless options.has_key?(:not_found)
        options[:not_found]
      else
        raise Errors::MetaBadResponse
      end
    end
  end
end

#instance(path, options = {}) ⇒ Object

Perform a GET request on the instance metadata and return the body of any 200 response.



50
51
52
# File 'lib/aws-eni/meta.rb', line 50

def instance(path, options = {})
  get("/latest/meta-data/#{path}", options)
end

#interface(hwaddr, path, options = {}) ⇒ Object

Perform a GET request on the interface metadata and return the body of any 200 response.



56
57
58
# File 'lib/aws-eni/meta.rb', line 56

def interface(hwaddr, path, options = {})
  instance("network/interfaces/macs/#{hwaddr}/#{path}", options)
end