File: //proc/self/root/usr/lib/ruby/site_ruby/1.8/facter/gce/metadata.rb
require 'open-uri'
module Facter
module GCE
# @api private
class Metadata
CONNECTION_ERRORS = [
OpenURI::HTTPError,
Errno::EHOSTDOWN,
Errno::EHOSTUNREACH,
Errno::ENETUNREACH,
Errno::ECONNABORTED,
Errno::ECONNREFUSED,
Errno::ECONNRESET,
Errno::ETIMEDOUT,
Timeout::Error,
]
METADATA_URL = "http://metadata/computeMetadata/v1beta1/?recursive=true&alt=json"
def initialize(url = METADATA_URL)
@url = url
end
def fetch
with_metadata_server do |body|
# This will only be reached if the confine associated with this class
# was true which means that JSON was required, but it's a bit
# questionable that we're relying on JSON being loaded as a side
# effect of that.
hash = ::JSON.parse(body)
transform_metadata!(hash)
hash
end
end
private
def with_metadata_server
retry_limit = 3
timeout = 0.05
body = nil
attempts = 0
begin
Timeout.timeout(timeout) do
body = open(@url).read
end
rescue *CONNECTION_ERRORS => e
attempts = attempts + 1
if attempts < retry_limit
retry
else
Facter.log_exception(e, "Unable to fetch metadata from #{@url}: #{e.message}")
return nil
end
end
if body
yield body
end
end
# @return [void]
def transform_metadata!(data)
case data
when Hash
data.keys.each do |key|
value = data[key]
if ["image", "machineType", "zone", "network"].include? key
data[key] = value.split('/').last
elsif key == "sshKeys"
data['sshKeys'] = value.split("\n")
end
transform_metadata!(value)
end
when Array
data.each do |value|
transform_metadata!(value)
end
end
nil
end
end
end
end