@@ -12,6 +12,7 @@ import (
12
12
"os"
13
13
"path/filepath"
14
14
"runtime"
15
+ "sync"
15
16
"time"
16
17
17
18
"cloud.google.com/go/compute/metadata"
@@ -41,19 +42,76 @@ type Credentials struct {
41
42
// running on Google Cloud Platform.
42
43
JSON []byte
43
44
45
+ udMu sync.Mutex // guards universeDomain
44
46
// universeDomain is the default service domain for a given Cloud universe.
45
47
universeDomain string
46
48
}
47
49
48
50
// UniverseDomain returns the default service domain for a given Cloud universe.
51
+ //
49
52
// The default value is "googleapis.com".
53
+ //
54
+ // Deprecated: Use instead (*Credentials).GetUniverseDomain(), which supports
55
+ // obtaining the universe domain when authenticating via the GCE metadata server.
56
+ // Unlike GetUniverseDomain, this method, UniverseDomain, will always return the
57
+ // default value when authenticating via the GCE metadata server.
58
+ // See also [The attached service account](https://cloud.google.com/docs/authentication/application-default-credentials#attached-sa).
50
59
func (c * Credentials ) UniverseDomain () string {
51
60
if c .universeDomain == "" {
52
61
return universeDomainDefault
53
62
}
54
63
return c .universeDomain
55
64
}
56
65
66
+ // GetUniverseDomain returns the default service domain for a given Cloud
67
+ // universe.
68
+ //
69
+ // 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.
77
+ func (c * Credentials ) GetUniverseDomain () (string , error ) {
78
+ c .udMu .Lock ()
79
+ 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 ()
84
+ if err != nil {
85
+ return "" , err
86
+ }
87
+ }
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.
91
+ if c .universeDomain == "" {
92
+ c .universeDomain = universeDomainDefault
93
+ }
94
+ return c .universeDomain , nil
95
+ }
96
+
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 = universeDomainDefault
107
+ return nil
108
+ } else {
109
+ return err
110
+ }
111
+ }
112
+ return nil
113
+ }
114
+
57
115
// DefaultCredentials is the old name of Credentials.
58
116
//
59
117
// Deprecated: use Credentials instead.
@@ -91,6 +149,12 @@ type CredentialsParams struct {
91
149
// Note: This option is currently only respected when using credentials
92
150
// fetched from the GCE metadata server.
93
151
EarlyTokenRefresh time.Duration
152
+
153
+ // UniverseDomain is the default service domain for a given Cloud universe.
154
+ // Only supported in authentication flows that support universe domains.
155
+ // This value takes precedence over a universe domain explicitly specified
156
+ // in a credentials config file or by the GCE metadata server. Optional.
157
+ UniverseDomain string
94
158
}
95
159
96
160
func (params CredentialsParams ) deepCopy () CredentialsParams {
@@ -175,8 +239,9 @@ func FindDefaultCredentialsWithParams(ctx context.Context, params CredentialsPar
175
239
if metadata .OnGCE () {
176
240
id , _ := metadata .ProjectID ()
177
241
return & Credentials {
178
- ProjectID : id ,
179
- TokenSource : computeTokenSource ("" , params .EarlyTokenRefresh , params .Scopes ... ),
242
+ ProjectID : id ,
243
+ TokenSource : computeTokenSource ("" , params .EarlyTokenRefresh , params .Scopes ... ),
244
+ universeDomain : params .UniverseDomain ,
180
245
}, nil
181
246
}
182
247
@@ -217,6 +282,9 @@ func CredentialsFromJSONWithParams(ctx context.Context, jsonData []byte, params
217
282
}
218
283
219
284
universeDomain := f .UniverseDomain
285
+ if params .UniverseDomain != "" {
286
+ universeDomain = params .UniverseDomain
287
+ }
220
288
// Authorized user credentials are only supported in the googleapis.com universe.
221
289
if f .Type == userCredentialsKey {
222
290
universeDomain = universeDomainDefault
0 commit comments