class Google::Cloud::Env::ComputeMetadata


A client for the Google metadata service.
#

def access_token_lifetime data

Other tags:
    Private: -
def access_token_lifetime data
  json = JSON.parse data rescue nil
  return 0 unless json.respond_to?(:key?) && json.key?("expires_in")
  lifetime = json["expires_in"].to_i - TOKEN_EXPIRY_BUFFER
  lifetime = 0 if lifetime.negative?
  lifetime
end

def canonicalize_query query

Other tags:
    Private: -
def canonicalize_query query
  query&.transform_keys(&:to_s)
end

def check_existence open_timeout: nil,

Returns:
  • (:confirmed) - if we have a confirmed response from metadata.
  • (:unconfirmed) - if we believe metadata should be present but we
  • (:no) - if we know the metadata server is not present

Parameters:
  • retry_timeout (Numeric, nil) -- Total timeout for retries. A value
  • retry_count (Integer, nil) -- Number of times to retry. A value of
  • request_timeout (Numeric) -- Timeout for entire http requests.
  • open_timeout (Numeric) -- Timeout for opening http connections.
def check_existence open_timeout: nil,
                    request_timeout: nil,
                    retry_count: :default,
                    retry_timeout: :default
  current = @existence
  return current if [:no, :confirmed].include? @existence
  begin
    lookup nil,
           open_timeout: open_timeout,
           request_timeout: request_timeout,
           retry_count: retry_count,
           retry_timeout: retry_timeout
  rescue MetadataServerNotResponding
    # Do nothing
  end
  @existence
end

def create_cache

Other tags:
    Private: -
def create_cache
  retries = proc do
    Google::Cloud::Env::Retries.new max_tries: nil,
                                    initial_delay: retry_interval,
                                    delay_includes_time_elapsed: true
  end
  Google::Cloud::Env::LazyDict.new retries: retries do |(path, query), open_timeout, request_timeout|
    internal_lookup path, query, open_timeout, request_timeout
  end
end

def determine_data_lifetime path, data

Other tags:
    Private: -
def determine_data_lifetime path, data
  case path
  when %r{instance/service-accounts/[^/]+/token}
    access_token_lifetime data
  when %r{instance/service-accounts/[^/]+/identity}
    identity_token_lifetime data
  end
end

def ensure_existence timeout: nil

Raises:
  • (MetadataServerNotResponding) - if we were unable to confirm

Returns:
  • (:confirmed) - if we were able to confirm connection.

Parameters:
  • timeout (Numeric, nil) -- a timeout in seconds, or nil to wait
def ensure_existence timeout: nil
  timeout ||= @startup_time + warmup_time - Process.clock_gettime(Process::CLOCK_MONOTONIC)
  timeout = 1.0 if timeout < 1.0
  check_existence retry_count: nil, retry_timeout: timeout
  raise MetadataServerNotResponding unless @existence == :confirmed
  @existence
end

def existence_immediate

Returns:
  • (:confirmed) - if we have a confirmed response from metadata.
  • (:unconfirmed) - if we believe metadata should be present but we
  • (:no) - if we know the metadata server is not present
  • (nil) - if we have no information at all yet
def existence_immediate
  @existence
end

def expiration_time_of path, query: nil

Returns:
  • (Numeric, nil, false) -
def expiration_time_of path, query: nil
  state = @cache.internal_state [path, query]
  return false unless state[0] == :success
  state[2]
end

def gce_check

Other tags:
    Private: -
def gce_check
  if @existence.nil?
    @mutex.synchronize do
      @existence ||=
        if @compute_smbios.google_compute? || maybe_gcf || maybe_gcr || maybe_gae
          :unconfirmed
        else
          :no
        end
    end
  end
  @existence != :no
end

def host= new_host

Parameters:
  • new_host (String) --
def host= new_host
  new_host ||= @variables["GCE_METADATA_HOST"] || DEFAULT_HOST
  new_host = "http://#{new_host}" unless new_host.start_with? "http://"
  @host = new_host
end

def identity_token_lifetime data

Other tags:
    Private: -
def identity_token_lifetime data
  return 0 unless data =~ /^[\w=-]+\.([\w=-]+)\.[\w=-]+$/
  base64 = Base64.urlsafe_decode64 Regexp.last_match[1]
  json = JSON.parse base64 rescue nil
  return 0 unless json.respond_to?(:key?) && json&.key?("exp")
  lifetime = json["exp"].to_i - Time.now.to_i - TOKEN_EXPIRY_BUFFER
  lifetime = 0 if lifetime.negative?
  lifetime
end

def initialize variables: nil,

Parameters:
  • compute_smbios (Google::Cloud::Env::ComputeSMBIOS) -- Access
  • variables (Google::Cloud::Env::Variables) -- Access object for
def initialize variables: nil,
               compute_smbios: nil
  @variables = variables || Variables.new
  @compute_smbios = compute_smbios || ComputeSMBIOS.new
  # This mutex protects the overrides and existence settings.
  # Those values won't change within a synchronize block.
  @mutex = Thread::Mutex.new
  reset!
end

def internal_lookup path, query, open_timeout, request_timeout

Other tags:
    Private: -
def internal_lookup path, query, open_timeout, request_timeout
  full_path = path ? "#{PATH_BASE}/#{path}" : ""
  http_response = connection.get full_path do |req|
    req.params = query if query
    req.headers = FLAVOR_HEADER
    req.options.timeout = request_timeout if request_timeout
    req.options.open_timeout = open_timeout if open_timeout
  end
  response = Response.new http_response.status, http_response.body, http_response.headers
  if path.nil?
    post_update_existence(response.status == 200 && response.google_flavor?, response.retrieval_monotonic_time)
  elsif response.google_flavor?
    post_update_existence true, response.retrieval_monotonic_time
  end
  lifetime = determine_data_lifetime path, response.body.strip
  LazyValue.expiring_value lifetime, response
rescue *TRANSIENT_EXCEPTIONS
  post_update_existence false
  raise MetadataServerNotResponding
end

def lookup path,

Raises:
  • (MetadataServerNotResponding) - if the Metadata Server is not

Returns:
  • (nil) - if the key is not present
  • (String) - the data from the metadata server

Parameters:
  • retry_timeout (Numeric, nil) -- Total timeout for retries. A value
  • retry_count (Integer, nil) -- Number of times to retry. A value of
  • request_timeout (Numeric) -- Timeout for entire http requests.
  • open_timeout (Numeric) -- Timeout for opening http connections.
  • query (Hash{String => String}) -- Any additional query parameters
  • path (String) -- The key path (e.g. `project/project-id`)
def lookup path,
           query: nil,
           open_timeout: nil,
           request_timeout: nil,
           retry_count: :default,
           retry_timeout: :default
  response = lookup_response path,
                             query: query,
                             open_timeout: open_timeout,
                             request_timeout: request_timeout,
                             retry_count: retry_count,
                             retry_timeout: retry_timeout
  return nil unless response.status == 200 && response.google_flavor?
  response.body
end

def lookup_override path, query

Other tags:
    Private: -
def lookup_override path, query
  if @overrides.empty?
    @existence = :no
    raise MetadataServerNotResponding
  end
  @existence = :confirmed
  result = @overrides.lookup path, query: query
  result ||= Response.new 404, "Not found", FLAVOR_HEADER
  result
end

def lookup_response path,

Raises:
  • (MetadataServerNotResponding) - if the Metadata Server is not

Returns:
  • (Response) - the data from the metadata server

Parameters:
  • retry_timeout (Numeric, nil) -- Total timeout for retries. A value
  • retry_count (Integer, nil) -- Number of times to retry. A value of
  • request_timeout (Numeric) -- Timeout for entire http requests.
  • open_timeout (Numeric) -- Timeout for opening http connections.
  • query (Hash{String => String}) -- Any additional query parameters
  • path (String) -- The key path (e.g. `project/project-id`)
def lookup_response path,
                    query: nil,
                    open_timeout: nil,
                    request_timeout: nil,
                    retry_count: :default,
                    retry_timeout: :default
  query = canonicalize_query query
  if @overrides
    @mutex.synchronize do
      return lookup_override path, query if @overrides
    end
  end
  raise MetadataServerNotResponding unless gce_check
  retry_count = self.retry_count if retry_count == :default
  retry_count += 1 if retry_count
  retry_timeout = self.retry_timeout if retry_timeout == :default
  @cache.await [path, query], open_timeout, request_timeout,
               transient_errors: [MetadataServerNotResponding],
               max_tries: retry_count,
               max_time: retry_timeout
end

def maybe_gae

Other tags:
    Private: -
def maybe_gae
  @variables["GAE_SERVICE"] && @variables["GAE_RUNTIME"]
end

def maybe_gcf

Other tags:
    Private: -
def maybe_gcf
  @variables["K_SERVICE"] && @variables["K_REVISION"] && @variables["GAE_RUNTIME"]
end

def maybe_gcr

Other tags:
    Private: -
def maybe_gcr
  @variables["K_SERVICE"] && @variables["K_REVISION"] && @variables["K_CONFIGURATION"]
end

def open_timeout

Returns:
  • (Numeric) -
def open_timeout
  connection.options.open_timeout
end

def open_timeout= timeout

Parameters:
  • timeout (Numeric) --
def open_timeout= timeout
  connection.options[:open_timeout] = timeout
end

def overrides= new_overrides

Parameters:
  • new_overrides (Overrides, nil) --
def overrides= new_overrides
  @mutex.synchronize do
    @existence = nil
    @overrides = new_overrides
  end
end

def post_update_existence success, current_time = nil

Other tags:
    Private: -
def post_update_existence success, current_time = nil
  return if @existence == :confirmed
  @mutex.synchronize do
    if success
      @existence = :confirmed
    elsif @existence != :confirmed
      current_time ||= Process.clock_gettime Process::CLOCK_MONOTONIC
      @existence = :no if current_time > @startup_time + warmup_time
    end
  end
end

def request_timeout

Returns:
  • (Numeric) -
def request_timeout
  connection.options.timeout
end

def request_timeout= timeout

Parameters:
  • timeout (Numeric) --
def request_timeout= timeout
  connection.options[:timeout] = timeout
end

def reset!

Other tags:
    Private: -
def reset!
  @mutex.synchronize do
    self.host = nil
    @connection = Faraday.new url: host
    self.open_timeout = DEFAULT_OPEN_TIMEOUT
    self.request_timeout = DEFAULT_REQUEST_TIMEOUT
    self.retry_count = DEFAULT_RETRY_COUNT
    self.retry_timeout = DEFAULT_RETRY_TIMEOUT
    self.retry_interval = DEFAULT_RETRY_INTERVAL
    self.warmup_time = DEFAULT_WARMUP_TIME
    @cache = create_cache
    @overrides = nil
  end
  reset_existence!
end

def reset_existence!

Other tags:
    Private: -
def reset_existence!
  @mutex.synchronize do
    @existence = nil
    @startup_time = Process.clock_gettime Process::CLOCK_MONOTONIC
  end
  self
end

def with_overrides temp_overrides

Parameters:
  • temp_overrides (Overrides, nil) --
def with_overrides temp_overrides
  old_overrides, old_existence = @mutex.synchronize do
    [@overrides, @existence]
  end
  begin
    @mutex.synchronize do
      @existence = nil
      @overrides = temp_overrides
    end
    yield
  ensure
    @mutex.synchronize do
      @existence = old_existence
      @overrides = old_overrides
    end
  end
end