From d6c43b0606dbebfeec7829291da8cc418b7ea56a Mon Sep 17 00:00:00 2001 From: Vanya Tarasov Date: Tue, 1 Sep 2015 15:41:32 -0700 Subject: [PATCH] Recognize cloud-platform scope on GCP GCP credential provider currently requires presence of 'devstorage.*' scope, however it fails to recognize 'cloud-platform' scope that implies it. --- pkg/credentialprovider/gcp/metadata.go | 20 +++++++------ pkg/credentialprovider/gcp/metadata_test.go | 33 +++++++++++++++++++++ 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/pkg/credentialprovider/gcp/metadata.go b/pkg/credentialprovider/gcp/metadata.go index 60c771955ab..8ab929315f1 100644 --- a/pkg/credentialprovider/gcp/metadata.go +++ b/pkg/credentialprovider/gcp/metadata.go @@ -27,14 +27,15 @@ import ( ) const ( - metadataUrl = "http://metadata.google.internal./computeMetadata/v1/" - metadataAttributes = metadataUrl + "instance/attributes/" - dockerConfigKey = metadataAttributes + "google-dockercfg" - dockerConfigUrlKey = metadataAttributes + "google-dockercfg-url" - metadataScopes = metadataUrl + "instance/service-accounts/default/scopes" - metadataToken = metadataUrl + "instance/service-accounts/default/token" - metadataEmail = metadataUrl + "instance/service-accounts/default/email" - storageScopePrefix = "https://www.googleapis.com/auth/devstorage" + metadataUrl = "http://metadata.google.internal./computeMetadata/v1/" + metadataAttributes = metadataUrl + "instance/attributes/" + dockerConfigKey = metadataAttributes + "google-dockercfg" + dockerConfigUrlKey = metadataAttributes + "google-dockercfg-url" + metadataScopes = metadataUrl + "instance/service-accounts/default/scopes" + metadataToken = metadataUrl + "instance/service-accounts/default/token" + metadataEmail = metadataUrl + "instance/service-accounts/default/email" + storageScopePrefix = "https://www.googleapis.com/auth/devstorage" + cloudPlatformScopePrefix = "https://www.googleapis.com/auth/cloud-platform" ) // For these urls, the parts of the host name can be glob, for example '*.gcr.io" will match @@ -150,7 +151,8 @@ func (g *containerRegistryProvider) Enabled() bool { } for _, v := range scopes { - if strings.HasPrefix(v, storageScopePrefix) { + // cloudPlatformScope implies storage scope. + if strings.HasPrefix(v, storageScopePrefix) || strings.HasPrefix(v, cloudPlatformScopePrefix) { return true } } diff --git a/pkg/credentialprovider/gcp/metadata_test.go b/pkg/credentialprovider/gcp/metadata_test.go index 0187700e1c6..fbcbdd2f1fd 100644 --- a/pkg/credentialprovider/gcp/metadata_test.go +++ b/pkg/credentialprovider/gcp/metadata_test.go @@ -275,6 +275,39 @@ func TestContainerRegistryNoStorageScope(t *testing.T) { } } +func TestComputePlatformScopeSubstitutesStorageScope(t *testing.T) { + const ( + defaultEndpoint = "/computeMetadata/v1/instance/service-accounts/default/" + scopeEndpoint = defaultEndpoint + "scopes" + ) + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Only serve the URL key and the value endpoint + if scopeEndpoint == r.URL.Path { + w.WriteHeader(http.StatusOK) + w.Header().Set("Content-Type", "application/json") + fmt.Fprint(w, `["https://www.googleapis.com/auth/compute.read_write","https://www.googleapis.com/auth/cloud-platform.read-only"]`) + } else { + w.WriteHeader(http.StatusNotFound) + } + })) + defer server.Close() + + // Make a transport that reroutes all traffic to the example server + transport := &http.Transport{ + Proxy: func(req *http.Request) (*url.URL, error) { + return url.Parse(server.URL + req.URL.Path) + }, + } + + provider := &containerRegistryProvider{ + metadataProvider{Client: &http.Client{Transport: transport}}, + } + + if !provider.Enabled() { + t.Errorf("Provider is unexpectedly disabled") + } +} + func TestAllProvidersNoMetadata(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound)