From 3cdb5a8de7dfeeded3c83f4a24a7e3bd96120b2f Mon Sep 17 00:00:00 2001 From: Daniel Azuma Date: Fri, 9 Oct 2020 09:32:26 -0700 Subject: [PATCH] feat: Honor GCE_METADATA_HOST environment variable --- lib/googleauth/compute_engine.rb | 25 +++++++++++++++++++++++-- spec/googleauth/compute_engine_spec.rb | 14 ++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/googleauth/compute_engine.rb b/lib/googleauth/compute_engine.rb index a775ea0..28654a3 100644 --- a/lib/googleauth/compute_engine.rb +++ b/lib/googleauth/compute_engine.rb @@ -51,22 +51,43 @@ module Google class GCECredentials < Signet::OAuth2::Client # The IP Address is used in the URIs to speed up failures on non-GCE # systems. + DEFAULT_METADATA_HOST = "169.254.169.254".freeze + + # @private Unused and deprecated COMPUTE_AUTH_TOKEN_URI = "http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token".freeze + # @private Unused and deprecated COMPUTE_ID_TOKEN_URI = "http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/identity".freeze + # @private Unused and deprecated COMPUTE_CHECK_URI = "http://169.254.169.254".freeze class << self extend Memoist + def metadata_host + ENV.fetch "GCE_METADATA_HOST", DEFAULT_METADATA_HOST + end + + def compute_check_uri + "http://#{metadata_host}".freeze + end + + def compute_auth_token_uri + "#{compute_check_uri}/computeMetadata/v1/instance/service-accounts/default/token".freeze + end + + def compute_id_token_uri + "#{compute_check_uri}/computeMetadata/v1/instance/service-accounts/default/identity".freeze + end + # Detect if this appear to be a GCE instance, by checking if metadata # is available. def on_gce? options = {} # 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| + resp = c.get compute_check_uri, nil, headers do |req| req.options.timeout = 1.0 req.options.open_timeout = 0.1 end @@ -84,7 +105,7 @@ module Google def fetch_access_token options = {} c = options[:connection] || Faraday.default_connection retry_with_error do - uri = target_audience ? COMPUTE_ID_TOKEN_URI : COMPUTE_AUTH_TOKEN_URI + 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 headers = { "Metadata-Flavor" => "Google" } diff --git a/spec/googleauth/compute_engine_spec.rb b/spec/googleauth/compute_engine_spec.rb index aee3936..2058981 100644 --- a/spec/googleauth/compute_engine_spec.rb +++ b/spec/googleauth/compute_engine_spec.rb @@ -142,5 +142,19 @@ describe Google::Auth::GCECredentials do expect(GCECredentials.on_gce?({}, true)).to eq(false) expect(stub).to have_been_requested end + + it "should honor GCE_METADATA_HOST environment variable" do + ENV["GCE_METADATA_HOST"] = "mymetadata.example.com" + begin + stub = stub_request(:get, "http://mymetadata.example.com") + .with(headers: { "Metadata-Flavor" => "Google" }) + .to_return(status: 200, + headers: { "Metadata-Flavor" => "Google" }) + expect(GCECredentials.on_gce?({}, true)).to eq(true) + expect(stub).to have_been_requested + ensure + ENV.delete "GCE_METADATA_HOST" + end + end end end