From e4f3cfcdfa60b770b9df4ff2c725f2bd52878664 Mon Sep 17 00:00:00 2001 From: Michal Skalski Date: Mon, 2 Sep 2024 13:17:23 +0900 Subject: [PATCH] Adjust priority of quota project sources 'GOOGLE_CLOUD_QUOTA_PROJECT' env variable should override quota project setting from credentials file. This is a behavior of previous auth code: https://github.com/googleapis/google-api-go-client/blob/main/internal/creds.go#L242-L261 --- auth/credentials/detect.go | 3 +++ auth/credentials/filetypes.go | 21 ++++++++++++++++++--- auth/internal/transport/transport.go | 1 + 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/auth/credentials/detect.go b/auth/credentials/detect.go index 010afc37c8fe..1d396f6a27b8 100644 --- a/auth/credentials/detect.go +++ b/auth/credentials/detect.go @@ -158,6 +158,9 @@ type DetectOptions struct { // The default value is "googleapis.com". This option is ignored for // authentication flows that do not support universe domain. Optional. UniverseDomain string + // QuotaProjectID allow overriding the project ID used for quota management. + // Optional. + QuotaProjectID string } func (o *DetectOptions) validate() error { diff --git a/auth/credentials/filetypes.go b/auth/credentials/filetypes.go index b426e16d2975..7c9e2dce11a2 100644 --- a/auth/credentials/filetypes.go +++ b/auth/credentials/filetypes.go @@ -17,6 +17,7 @@ package credentials import ( "errors" "fmt" + "os" "cloud.google.com/go/auth" "cloud.google.com/go/auth/credentials/internal/externalaccount" @@ -56,7 +57,7 @@ func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) { if err != nil { return nil, err } - quotaProjectID = f.QuotaProjectID + quotaProjectID = resolveQuotaProjectID(opts.QuotaProjectID, f.QuotaProjectID) universeDomain = f.UniverseDomain case credsfile.ExternalAccountKey: f, err := credsfile.ParseExternalAccount(b) @@ -67,7 +68,7 @@ func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) { if err != nil { return nil, err } - quotaProjectID = f.QuotaProjectID + quotaProjectID = resolveQuotaProjectID(opts.QuotaProjectID, f.QuotaProjectID) universeDomain = resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) case credsfile.ExternalAccountAuthorizedUserKey: f, err := credsfile.ParseExternalAccountAuthorizedUser(b) @@ -78,7 +79,7 @@ func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) { if err != nil { return nil, err } - quotaProjectID = f.QuotaProjectID + quotaProjectID = resolveQuotaProjectID(opts.QuotaProjectID, f.QuotaProjectID) universeDomain = f.UniverseDomain case credsfile.ImpersonatedServiceAccountKey: f, err := credsfile.ParseImpersonatedServiceAccount(b) @@ -126,6 +127,20 @@ func resolveUniverseDomain(optsUniverseDomain, fileUniverseDomain string) string return fileUniverseDomain } +// resolveQuotaProjectID retrieves quota project with precedence being: +// client option, environment variable, creds file. +func resolveQuotaProjectID(optsQuotaProjectID, fileQuotaProjectID string) string { + if optsQuotaProjectID != "" { + return optsQuotaProjectID + } + + if qp := os.Getenv(internalauth.QuotaProjectEnvVar); qp != "" { + return qp + } + + return fileQuotaProjectID +} + func handleServiceAccount(f *credsfile.ServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { if opts.UseSelfSignedJWT { return configureSelfSignedJWT(f, opts) diff --git a/auth/internal/transport/transport.go b/auth/internal/transport/transport.go index cc586ec5b1a5..69f05df544f6 100644 --- a/auth/internal/transport/transport.go +++ b/auth/internal/transport/transport.go @@ -45,6 +45,7 @@ func CloneDetectOptions(oldDo *credentials.DetectOptions) *credentials.DetectOpt CredentialsFile: oldDo.CredentialsFile, UseSelfSignedJWT: oldDo.UseSelfSignedJWT, UniverseDomain: oldDo.UniverseDomain, + QuotaProjectID: oldDo.QuotaProjectID, // These fields are are pointer types that we just want to use exactly // as the user set, copy the ref