Class: Google::Auth::GCECredentials

Inherits:
Signet::OAuth2::Client show all
Extended by:
Memoist
Defined in:
lib/googleauth/compute_engine.rb

Overview

Extends Signet::OAuth2::Client so that the auth token is obtained from the GCE metadata server.

Constant Summary collapse

COMPUTE_AUTH_TOKEN_URI =

The IP Address is used in the URIs to speed up failures on non-GCE systems.

'http://169.254.169.254/computeMetadata/v1/'\
'instance/service-accounts/default/token'
COMPUTE_CHECK_URI =
'http://169.254.169.254'

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Signet::OAuth2::Client

#apply, #apply!, #updater_proc

Class Method Details

.on_gce?(options = {}) ⇒ Boolean

Detect if this appear to be a GCE instance, by checking if metadata is available

Returns:

  • (Boolean)


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/googleauth/compute_engine.rb', line 63

def on_gce?(options = {})
  c = options[:connection] || Faraday.default_connection
  resp = c.get(COMPUTE_CHECK_URI) do |req|
    # Comment from: oauth2client/client.py
    #
    # Note: the explicit `timeout` below is a workaround. The underlying
    # issue is that resolving an unknown host on some networks will take
    # 20-30 seconds; making this timeout short fixes the issue, but
    # could lead to false negatives in the event that we are on GCE, but
    # the metadata resolution was particularly slow. The latter case is
    # "unlikely".
    req.options.timeout = 0.1
  end
  return false unless resp.status == 200
  return false unless resp.headers.key?('Metadata-Flavor')
  return resp.headers['Metadata-Flavor'] == 'Google'
rescue Faraday::TimeoutError, Faraday::ConnectionFailed
  return false
end

Instance Method Details

#fetch_access_token(options = {}) ⇒ Object

Overrides the super class method to change how access tokens are fetched.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/googleauth/compute_engine.rb', line 88

def fetch_access_token(options = {})
  c = options[:connection] || Faraday.default_connection
  c.headers = { 'Metadata-Flavor' => 'Google' }
  resp = c.get(COMPUTE_AUTH_TOKEN_URI)
  case resp.status
  when 200
    Signet::OAuth2.parse_credentials(resp.body,
                                     resp.headers['content-type'])
  when 404
    fail(Signet::AuthorizationError, NO_METADATA_SERVER_ERROR)
  else
    msg = "Unexpected error code #{resp.status}" + UNEXPECTED_ERROR_SUFFIX
    fail(Signet::AuthorizationError, msg)
  end
end