Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Temporarily disable universe domain query from GCE metadata server #493

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ AllCops:
- "integration/**/*"
- "spec/**/*"
- "test/**/*"
Metrics/ClassLength:
Max: 200
Metrics/ModuleLength:
Max: 110
Metrics/BlockLength:
Exclude:
- "googleauth.gemspec"
Metrics/ClassLength:
Max: 200
Metrics/CyclomaticComplexity:
Max: 15
Metrics/ModuleLength:
Max: 200
Metrics/PerceivedComplexity:
Max: 15
45 changes: 31 additions & 14 deletions lib/googleauth/compute_engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,16 @@ def reset_cache
alias unmemoize_all reset_cache
end

# @private Temporary; remove when universe domain metadata endpoint is stable (see b/349488459).
attr_accessor :disable_universe_domain_check

# Construct a GCECredentials
def initialize options = {}
# Override the constructor to remember whether the universe domain was
# overridden by a constructor argument.
@universe_domain_overridden = options["universe_domain"] || options[:universe_domain] ? true : false
# TODO: Remove when universe domain metadata endpoint is stable (see b/349488459).
@disable_universe_domain_check = true
super options
end

Expand Down Expand Up @@ -127,20 +132,8 @@ def build_token_hash body, content_type, retrieval_time
else
Signet::OAuth2.parse_credentials body, content_type
end
unless @universe_domain_overridden
universe_domain = Google::Cloud.env.lookup_metadata "universe", "universe_domain"
universe_domain = "googleapis.com" if !universe_domain || universe_domain.empty?
hash["universe_domain"] = universe_domain.strip
end
# The response might have been cached, which means expires_in might be
# stale. Update it based on the time since the data was retrieved.
# We also ensure expires_in is conservative; subtracting at least 1
# second to offset any skew from metadata server latency.
if hash["expires_in"].is_a? Numeric
offset = 1 + (Process.clock_gettime(Process::CLOCK_MONOTONIC) - retrieval_time).round
hash["expires_in"] -= offset if offset.positive?
hash["expires_in"] = 0 if hash["expires_in"].negative?
end
add_universe_domain_to hash
adjust_for_stale_expires_in hash, retrieval_time
hash
end

Expand All @@ -152,6 +145,30 @@ def parse_encoded_token body
end
hash
end

def add_universe_domain_to hash
return if @universe_domain_overridden
universe_domain =
if disable_universe_domain_check
# TODO: Remove when universe domain metadata endpoint is stable (see b/349488459).
"googleapis.com"
else
Google::Cloud.env.lookup_metadata "universe", "universe_domain"
end
universe_domain = "googleapis.com" if !universe_domain || universe_domain.empty?
hash["universe_domain"] = universe_domain.strip
end

# The response might have been cached, which means expires_in might be
# stale. Update it based on the time since the data was retrieved.
# We also ensure expires_in is conservative; subtracting at least 1
# second to offset any skew from metadata server latency.
def adjust_for_stale_expires_in hash, retrieval_time
return unless hash["expires_in"].is_a? Numeric
offset = 1 + (Process.clock_gettime(Process::CLOCK_MONOTONIC) - retrieval_time).round
hash["expires_in"] -= offset if offset.positive?
hash["expires_in"] = 0 if hash["expires_in"].negative?
end
end
end
end
6 changes: 6 additions & 0 deletions lib/googleauth/credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,12 @@ def self.lookup_local_constant name
#
attr_reader :quota_project_id

# @private Temporary; remove when universe domain metadata endpoint is stable (see b/349488459).
def disable_universe_domain_check
return false unless @client.respond_to? :disable_universe_domain_check
@client.disable_universe_domain_check
end

# @private Delegate client methods to the client object.
extend Forwardable

Expand Down
135 changes: 78 additions & 57 deletions spec/googleauth/compute_engine_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,86 +69,107 @@ def make_auth_stubs opts
end
end

context "default universe due to 404 from MDS" do
context "when metadata query is disabled" do
before :example do
@universe_domain = StandardError
end

it_behaves_like "apply/apply! are OK"

it "sets the universe" do
it "leaves universe as googleapis.com and does not call the MDS" do
make_auth_stubs access_token: "1/abcde"
@client.fetch_access_token!
expect(@client.universe_domain).to eq("googleapis.com")
end

it "returns a consistent expiry using cached data" do
make_auth_stubs access_token: "1/abcde"
@client.fetch_access_token!
expiry = @client.expires_at
sleep 1
@client.fetch_access_token!
expect(@client.expires_at.to_f).to be_within(0.2).of(expiry.to_f)
end
end

context "default universe due to empty data from MDS" do
context "when metadata query is enabled" do
before :example do
@universe_domain = ""
@client.disable_universe_domain_check = false
end

it_behaves_like "apply/apply! are OK"
context "default universe due to 404 from MDS" do
it_behaves_like "apply/apply! are OK"

it "sets the universe" do
make_auth_stubs access_token: "1/abcde"
@client.fetch_access_token!
expect(@client.universe_domain).to eq("googleapis.com")
end
it "sets the universe" do
make_auth_stubs access_token: "1/abcde"
@client.fetch_access_token!
expect(@client.universe_domain).to eq("googleapis.com")
end

it "returns a consistent expiry using cached data" do
make_auth_stubs access_token: "1/abcde"
@client.fetch_access_token!
expiry = @client.expires_at
sleep 1
@client.fetch_access_token!
expect(@client.expires_at.to_f).to be_within(0.2).of(expiry.to_f)
it "returns a consistent expiry using cached data" do
make_auth_stubs access_token: "1/abcde"
@client.fetch_access_token!
expiry1 = @client.expires_at.to_f
sleep 3
@client.fetch_access_token!
expiry2 = @client.expires_at.to_f
expect(expiry2).to be_within(1.0).of(expiry1)
end
end
end

context "custom universe" do
before :example do
@universe_domain = "myuniverse.com"
end
context "default universe due to empty data from MDS" do
before :example do
@universe_domain = ""
end

it_behaves_like "apply/apply! are OK"
it_behaves_like "apply/apply! are OK"

it "sets the universe" do
make_auth_stubs access_token: "1/abcde"
@client.fetch_access_token!
expect(@client.universe_domain).to eq("myuniverse.com")
end
it "sets the universe" do
make_auth_stubs access_token: "1/abcde"
@client.fetch_access_token!
expect(@client.universe_domain).to eq("googleapis.com")
end

it "supports updating the universe_domain" do
make_auth_stubs access_token: "1/abcde"
@client.fetch_access_token!
@client.universe_domain = "anotheruniverse.com"
expect(@client.universe_domain).to eq("anotheruniverse.com")
it "returns a consistent expiry using cached data" do
make_auth_stubs access_token: "1/abcde"
@client.fetch_access_token!
expiry = @client.expires_at
sleep 3
@client.fetch_access_token!
expect(@client.expires_at.to_f).to be_within(1.0).of(expiry.to_f)
end
end

it "prioritizes argument-specified universe domain" do
make_auth_stubs access_token: "1/abcde"
custom_client = GCECredentials.new universe_domain: "override-universe.com"
custom_client.fetch_access_token!
expect(custom_client.access_token).to eq("1/abcde")
expect(custom_client.universe_domain).to eq("override-universe.com")
end
end
context "custom universe" do
before :example do
@universe_domain = "myuniverse.com"
end

context "error in universe_domain" do
before :example do
@universe_domain = Errno::EHOSTDOWN
it_behaves_like "apply/apply! are OK"

it "sets the universe" do
make_auth_stubs access_token: "1/abcde"
@client.fetch_access_token!
expect(@client.universe_domain).to eq("myuniverse.com")
end

it "supports updating the universe_domain" do
make_auth_stubs access_token: "1/abcde"
@client.fetch_access_token!
@client.universe_domain = "anotheruniverse.com"
expect(@client.universe_domain).to eq("anotheruniverse.com")
end

it "prioritizes argument-specified universe domain" do
make_auth_stubs access_token: "1/abcde"
custom_client = GCECredentials.new universe_domain: "override-universe.com"
custom_client.fetch_access_token!
expect(custom_client.access_token).to eq("1/abcde")
expect(custom_client.universe_domain).to eq("override-universe.com")
end
end

it "results in an error" do
make_auth_stubs access_token: "1/abcde"
expect { @client.fetch_access_token! }
.to raise_error Signet::AuthorizationError
context "error in universe_domain" do
before :example do
@universe_domain = Errno::EHOSTDOWN
end

it "results in an error" do
make_auth_stubs access_token: "1/abcde"
expect { @client.fetch_access_token! }
.to raise_error Signet::AuthorizationError
end
end
end

Expand Down