google: add Credentials.GetUniverseDomain with GCE MDS support

* Deprecate Credentials.UniverseDomain

Change-Id: I1cbc842fbfce35540c8dff99fec09e036b9e2cdf
Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/554215
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cody Oss <codyoss@google.com>
Auto-Submit: Cody Oss <codyoss@google.com>
Reviewed-by: Cody Oss <codyoss@google.com>
Reviewed-by: Viacheslav Rostovtsev <virost@google.com>
This commit is contained in:
Chris Smith
2023-12-26 15:08:10 -07:00
committed by Gopher Robot
parent 1e6999b1be
commit 4ce7bbb2ff
3 changed files with 173 additions and 0 deletions

View File

@@ -12,6 +12,7 @@ import (
"os"
"path/filepath"
"runtime"
"sync"
"time"
"cloud.google.com/go/compute/metadata"
@@ -41,12 +42,20 @@ type Credentials struct {
// running on Google Cloud Platform.
JSON []byte
udMu sync.Mutex // guards universeDomain
// universeDomain is the default service domain for a given Cloud universe.
universeDomain string
}
// UniverseDomain returns the default service domain for a given Cloud universe.
//
// The default value is "googleapis.com".
//
// Deprecated: Use instead (*Credentials).GetUniverseDomain(), which supports
// obtaining the universe domain when authenticating via the GCE metadata server.
// Unlike GetUniverseDomain, this method, UniverseDomain, will always return the
// default value when authenticating via the GCE metadata server.
// See also [The attached service account](https://cloud.google.com/docs/authentication/application-default-credentials#attached-sa).
func (c *Credentials) UniverseDomain() string {
if c.universeDomain == "" {
return universeDomainDefault
@@ -54,6 +63,55 @@ func (c *Credentials) UniverseDomain() string {
return c.universeDomain
}
// GetUniverseDomain returns the default service domain for a given Cloud
// universe.
//
// The default value is "googleapis.com".
//
// It obtains the universe domain from the attached service account on GCE when
// authenticating via the GCE metadata server. See also [The attached service
// account](https://cloud.google.com/docs/authentication/application-default-credentials#attached-sa).
// If the GCE metadata server returns a 404 error, the default value is
// returned. If the GCE metadata server returns an error other than 404, the
// error is returned.
func (c *Credentials) GetUniverseDomain() (string, error) {
c.udMu.Lock()
defer c.udMu.Unlock()
if c.universeDomain == "" && metadata.OnGCE() {
// If we're on Google Compute Engine, an App Engine standard second
// generation runtime, or App Engine flexible, use the metadata server.
err := c.computeUniverseDomain()
if err != nil {
return "", err
}
}
// If not on Google Compute Engine, or in case of any non-error path in
// computeUniverseDomain that did not set universeDomain, set the default
// universe domain.
if c.universeDomain == "" {
c.universeDomain = universeDomainDefault
}
return c.universeDomain, nil
}
// computeUniverseDomain fetches the default service domain for a given Cloud
// universe from Google Compute Engine (GCE)'s metadata server. It's only valid
// to use this method if your program is running on a GCE instance.
func (c *Credentials) computeUniverseDomain() error {
var err error
c.universeDomain, err = metadata.Get("universe/universe_domain")
if err != nil {
if _, ok := err.(metadata.NotDefinedError); ok {
// http.StatusNotFound (404)
c.universeDomain = universeDomainDefault
return nil
} else {
return err
}
}
return nil
}
// DefaultCredentials is the old name of Credentials.
//
// Deprecated: use Credentials instead.