Class: Google::Auth::GCECredentials

Inherits:
Signet::OAuth2::Client show all
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

DEFAULT_METADATA_HOST =

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

"169.254.169.254".freeze

Constants included from BaseClient

BaseClient::AUTH_METADATA_KEY

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Signet::OAuth2::Client

#build_default_connection, #configure_connection, #fetch_access_token!, #orig_fetch_access_token!, #retry_with_error, #token_type

Methods included from BaseClient

#apply, #apply!, #expires_within?, #needs_access_token?, #notify_refresh_listeners, #on_refresh, #updater_proc

Class Method Details

.compute_auth_token_uriObject



60
61
62
# File 'lib/googleauth/compute_engine.rb', line 60

def compute_auth_token_uri
  "#{compute_check_uri}/computeMetadata/v1/instance/service-accounts/default/token".freeze
end

.compute_check_uriObject



56
57
58
# File 'lib/googleauth/compute_engine.rb', line 56

def compute_check_uri
  "http://#{}".freeze
end

.compute_id_token_uriObject



64
65
66
# File 'lib/googleauth/compute_engine.rb', line 64

def compute_id_token_uri
  "#{compute_check_uri}/computeMetadata/v1/instance/service-accounts/default/identity".freeze
end

.metadata_hostObject



52
53
54
# File 'lib/googleauth/compute_engine.rb', line 52

def 
  ENV.fetch "GCE_METADATA_HOST", DEFAULT_METADATA_HOST
end

.on_gce?(options = {}, reload = false) ⇒ Boolean

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

Returns:

  • (Boolean)


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/googleauth/compute_engine.rb', line 70

def on_gce? options = {}, reload = false # rubocop:disable Style/OptionalBooleanParameter
  # We can follow OptionalBooleanParameter here because it's a public interface, we can't change it.
  @on_gce_cache.delete options if reload
  @on_gce_cache.fetch options do
    @on_gce_cache[options] = begin
      # TODO: This should use google-cloud-env instead.
      c = options[:connection] || Faraday.default_connection
      headers = { "Metadata-Flavor" => "Google" }
      resp = c.get compute_check_uri, nil, headers do |req|
        req.options.timeout = 1.0
        req.options.open_timeout = 0.1
      end
      return false unless resp.status == 200
      resp.headers["Metadata-Flavor"] == "Google"
    rescue Faraday::TimeoutError, Faraday::ConnectionFailed
      false
    end
  end
end

.reset_cacheObject Also known as: unmemoize_all



90
91
92
# File 'lib/googleauth/compute_engine.rb', line 90

def reset_cache
  @on_gce_cache.clear
end

Instance Method Details

#fetch_access_token(options = {}) ⇒ Object

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



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/googleauth/compute_engine.rb', line 98

def fetch_access_token options = {}
  c = options[:connection] || Faraday.default_connection
  retry_with_error do
    uri = target_audience ? GCECredentials.compute_id_token_uri : GCECredentials.compute_auth_token_uri
    query = target_audience ? { "audience" => target_audience, "format" => "full" } : {}
    query[:scopes] = Array(scope).join "," if scope
    resp = c.get uri, query, "Metadata-Flavor" => "Google"
    case resp.status
    when 200
      content_type = resp.headers["content-type"]
      if ["text/html", "application/text"].include? content_type
        { (target_audience ? "id_token" : "access_token") => resp.body }
      else
        Signet::OAuth2.parse_credentials resp.body, content_type
      end
    when 403, 500
      msg = "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
      raise Signet::UnexpectedStatusError, msg
    when 404
      raise Signet::AuthorizationError, NO_METADATA_SERVER_ERROR
    else
      msg = "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
      raise Signet::AuthorizationError, msg
    end
  end
end