Skip to content

Commit d0e617c

Browse files
quartzmogopherbot
authored andcommitted
google: add Credentials.UniverseDomainProvider
* move MDS universe retrieval within Compute credentials Change-Id: I847d2075ca11bde998a06220307626e902230c23 Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/575936 Reviewed-by: Cody Oss <[email protected]> Auto-Submit: Cody Oss <[email protected]> Run-TryBot: Cody Oss <[email protected]> TryBot-Result: Gopher Robot <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 3c9c1f6 commit d0e617c

File tree

2 files changed

+58
-41
lines changed

2 files changed

+58
-41
lines changed

google/default.go

+38-36
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ type Credentials struct {
4242
// running on Google Cloud Platform.
4343
JSON []byte
4444

45+
// UniverseDomainProvider returns the default service domain for a given
46+
// Cloud universe. Optional.
47+
//
48+
// On GCE, UniverseDomainProvider should return the universe domain value
49+
// from Google Compute Engine (GCE)'s metadata server. See also [The attached service
50+
// account](https://cloud.google.com/docs/authentication/application-default-credentials#attached-sa).
51+
// If the GCE metadata server returns a 404 error, the default universe
52+
// domain value should be returned. If the GCE metadata server returns an
53+
// error other than 404, the error should be returned.
54+
UniverseDomainProvider func() (string, error)
55+
4556
udMu sync.Mutex // guards universeDomain
4657
// universeDomain is the default service domain for a given Cloud universe.
4758
universeDomain string
@@ -64,54 +75,32 @@ func (c *Credentials) UniverseDomain() string {
6475
}
6576

6677
// GetUniverseDomain returns the default service domain for a given Cloud
67-
// universe.
78+
// universe. If present, UniverseDomainProvider will be invoked and its return
79+
// value will be cached.
6880
//
6981
// The default value is "googleapis.com".
70-
//
71-
// It obtains the universe domain from the attached service account on GCE when
72-
// authenticating via the GCE metadata server. See also [The attached service
73-
// account](https://cloud.google.com/docs/authentication/application-default-credentials#attached-sa).
74-
// If the GCE metadata server returns a 404 error, the default value is
75-
// returned. If the GCE metadata server returns an error other than 404, the
76-
// error is returned.
7782
func (c *Credentials) GetUniverseDomain() (string, error) {
7883
c.udMu.Lock()
7984
defer c.udMu.Unlock()
80-
if c.universeDomain == "" && metadata.OnGCE() {
81-
// If we're on Google Compute Engine, an App Engine standard second
82-
// generation runtime, or App Engine flexible, use the metadata server.
83-
err := c.computeUniverseDomain()
85+
if c.universeDomain == "" && c.UniverseDomainProvider != nil {
86+
// On Google Compute Engine, an App Engine standard second generation
87+
// runtime, or App Engine flexible, use an externally provided function
88+
// to request the universe domain from the metadata server.
89+
ud, err := c.UniverseDomainProvider()
8490
if err != nil {
8591
return "", err
8692
}
93+
c.universeDomain = ud
8794
}
88-
// If not on Google Compute Engine, or in case of any non-error path in
89-
// computeUniverseDomain that did not set universeDomain, set the default
90-
// universe domain.
95+
// If no UniverseDomainProvider (meaning not on Google Compute Engine), or
96+
// in case of any (non-error) empty return value from
97+
// UniverseDomainProvider, set the default universe domain.
9198
if c.universeDomain == "" {
9299
c.universeDomain = defaultUniverseDomain
93100
}
94101
return c.universeDomain, nil
95102
}
96103

97-
// computeUniverseDomain fetches the default service domain for a given Cloud
98-
// universe from Google Compute Engine (GCE)'s metadata server. It's only valid
99-
// to use this method if your program is running on a GCE instance.
100-
func (c *Credentials) computeUniverseDomain() error {
101-
var err error
102-
c.universeDomain, err = metadata.Get("universe/universe_domain")
103-
if err != nil {
104-
if _, ok := err.(metadata.NotDefinedError); ok {
105-
// http.StatusNotFound (404)
106-
c.universeDomain = defaultUniverseDomain
107-
return nil
108-
} else {
109-
return err
110-
}
111-
}
112-
return nil
113-
}
114-
115104
// DefaultCredentials is the old name of Credentials.
116105
//
117106
// Deprecated: use Credentials instead.
@@ -226,10 +215,23 @@ func FindDefaultCredentialsWithParams(ctx context.Context, params CredentialsPar
226215
// or App Engine flexible, use the metadata server.
227216
if metadata.OnGCE() {
228217
id, _ := metadata.ProjectID()
218+
universeDomainProvider := func() (string, error) {
219+
universeDomain, err := metadata.Get("universe/universe_domain")
220+
if err != nil {
221+
if _, ok := err.(metadata.NotDefinedError); ok {
222+
// http.StatusNotFound (404)
223+
return defaultUniverseDomain, nil
224+
} else {
225+
return "", err
226+
}
227+
}
228+
return universeDomain, nil
229+
}
229230
return &Credentials{
230-
ProjectID: id,
231-
TokenSource: computeTokenSource("", params.EarlyTokenRefresh, params.Scopes...),
232-
universeDomain: params.UniverseDomain,
231+
ProjectID: id,
232+
TokenSource: computeTokenSource("", params.EarlyTokenRefresh, params.Scopes...),
233+
UniverseDomainProvider: universeDomainProvider,
234+
universeDomain: params.UniverseDomain,
233235
}, nil
234236
}
235237

google/default_test.go

+20-5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"net/http/httptest"
1111
"strings"
1212
"testing"
13+
14+
"cloud.google.com/go/compute/metadata"
1315
)
1416

1517
var saJSONJWT = []byte(`{
@@ -255,9 +257,14 @@ func TestCredentialsFromJSONWithParams_User_UniverseDomain_Params_UniverseDomain
255257
func TestComputeUniverseDomain(t *testing.T) {
256258
universeDomainPath := "/computeMetadata/v1/universe/universe_domain"
257259
universeDomainResponseBody := "example.com"
260+
var requests int
258261
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
262+
requests++
259263
if r.URL.Path != universeDomainPath {
260-
t.Errorf("got %s, want %s", r.URL.Path, universeDomainPath)
264+
t.Errorf("bad path, got %s, want %s", r.URL.Path, universeDomainPath)
265+
}
266+
if requests > 1 {
267+
t.Errorf("too many requests, got %d, want 1", requests)
261268
}
262269
w.Write([]byte(universeDomainResponseBody))
263270
}))
@@ -268,11 +275,19 @@ func TestComputeUniverseDomain(t *testing.T) {
268275
params := CredentialsParams{
269276
Scopes: []string{scope},
270277
}
278+
universeDomainProvider := func() (string, error) {
279+
universeDomain, err := metadata.Get("universe/universe_domain")
280+
if err != nil {
281+
return "", err
282+
}
283+
return universeDomain, nil
284+
}
271285
// Copied from FindDefaultCredentialsWithParams, metadata.OnGCE() = true block
272286
creds := &Credentials{
273-
ProjectID: "fake_project",
274-
TokenSource: computeTokenSource("", params.EarlyTokenRefresh, params.Scopes...),
275-
universeDomain: params.UniverseDomain, // empty
287+
ProjectID: "fake_project",
288+
TokenSource: computeTokenSource("", params.EarlyTokenRefresh, params.Scopes...),
289+
UniverseDomainProvider: universeDomainProvider,
290+
universeDomain: params.UniverseDomain, // empty
276291
}
277292
c := make(chan bool)
278293
go func() {
@@ -285,7 +300,7 @@ func TestComputeUniverseDomain(t *testing.T) {
285300
}
286301
c <- true
287302
}()
288-
got, err := creds.GetUniverseDomain() // Second conflicting access.
303+
got, err := creds.GetUniverseDomain() // Second conflicting (and potentially uncached) access.
289304
<-c
290305
if err != nil {
291306
t.Error(err)

0 commit comments

Comments
 (0)