mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Whitelisting *.pkg.dev for the GCP credential provider
This commit is contained in:
parent
c9b4cf3d25
commit
f641ecd6f8
@ -50,7 +50,7 @@ var gceProductNameFile = "/sys/class/dmi/id/product_name"
|
|||||||
|
|
||||||
// For these urls, the parts of the host name can be glob, for example '*.gcr.io" will match
|
// For these urls, the parts of the host name can be glob, for example '*.gcr.io" will match
|
||||||
// "foo.gcr.io" and "bar.gcr.io".
|
// "foo.gcr.io" and "bar.gcr.io".
|
||||||
var containerRegistryUrls = []string{"container.cloud.google.com", "gcr.io", "*.gcr.io"}
|
var containerRegistryUrls = []string{"container.cloud.google.com", "gcr.io", "*.gcr.io", "*.pkg.dev"}
|
||||||
|
|
||||||
var metadataHeader = &http.Header{
|
var metadataHeader = &http.Header{
|
||||||
"Metadata-Flavor": []string{"Google"},
|
"Metadata-Flavor": []string{"Google"},
|
||||||
|
@ -193,86 +193,90 @@ func TestDockerKeyringFromGoogleDockerConfigMetadataUrl(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestContainerRegistryBasics(t *testing.T) {
|
func TestContainerRegistryBasics(t *testing.T) {
|
||||||
registryURL := "container.cloud.google.com"
|
registryURLs := []string{"container.cloud.google.com", "eu.gcr.io", "us-west2-docker.pkg.dev"}
|
||||||
email := "1234@project.gserviceaccount.com"
|
for _, registryURL := range registryURLs {
|
||||||
token := &tokenBlob{AccessToken: "ya26.lots-of-indiscernible-garbage"}
|
t.Run(registryURL, func(t *testing.T) {
|
||||||
|
email := "1234@project.gserviceaccount.com"
|
||||||
|
token := &tokenBlob{AccessToken: "ya26.lots-of-indiscernible-garbage"}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
serviceAccountsEndpoint = "/computeMetadata/v1/instance/service-accounts/"
|
serviceAccountsEndpoint = "/computeMetadata/v1/instance/service-accounts/"
|
||||||
defaultEndpoint = "/computeMetadata/v1/instance/service-accounts/default/"
|
defaultEndpoint = "/computeMetadata/v1/instance/service-accounts/default/"
|
||||||
scopeEndpoint = defaultEndpoint + "scopes"
|
scopeEndpoint = defaultEndpoint + "scopes"
|
||||||
emailEndpoint = defaultEndpoint + "email"
|
emailEndpoint = defaultEndpoint + "email"
|
||||||
tokenEndpoint = defaultEndpoint + "token"
|
tokenEndpoint = defaultEndpoint + "token"
|
||||||
)
|
)
|
||||||
var err error
|
var err error
|
||||||
gceProductNameFile, err = createProductNameFile()
|
gceProductNameFile, err = createProductNameFile()
|
||||||
if err != nil {
|
|
||||||
t.Errorf("failed to create gce product name file: %v", err)
|
|
||||||
}
|
|
||||||
defer os.Remove(gceProductNameFile)
|
|
||||||
|
|
||||||
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.Fprintf(w, `["%s.read_write"]`, storageScopePrefix)
|
|
||||||
} else if emailEndpoint == r.URL.Path {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
fmt.Fprint(w, email)
|
|
||||||
} else if tokenEndpoint == r.URL.Path {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
bytes, err := json.Marshal(token)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Errorf("failed to create gce product name file: %v", err)
|
||||||
}
|
}
|
||||||
fmt.Fprintln(w, string(bytes))
|
defer os.Remove(gceProductNameFile)
|
||||||
} else if serviceAccountsEndpoint == r.URL.Path {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
fmt.Fprintln(w, "default/\ncustom")
|
|
||||||
} else {
|
|
||||||
http.Error(w, "", http.StatusNotFound)
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
defer server.Close()
|
|
||||||
|
|
||||||
// Make a transport that reroutes all traffic to the example server
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
transport := utilnet.SetTransportDefaults(&http.Transport{
|
// Only serve the URL key and the value endpoint
|
||||||
Proxy: func(req *http.Request) (*url.URL, error) {
|
if scopeEndpoint == r.URL.Path {
|
||||||
return url.Parse(server.URL + req.URL.Path)
|
w.WriteHeader(http.StatusOK)
|
||||||
},
|
w.Header().Set("Content-Type", "application/json")
|
||||||
})
|
fmt.Fprintf(w, `["%s.read_write"]`, storageScopePrefix)
|
||||||
|
} else if emailEndpoint == r.URL.Path {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, email)
|
||||||
|
} else if tokenEndpoint == r.URL.Path {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
bytes, err := json.Marshal(token)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Fprintln(w, string(bytes))
|
||||||
|
} else if serviceAccountsEndpoint == r.URL.Path {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintln(w, "default/\ncustom")
|
||||||
|
} else {
|
||||||
|
http.Error(w, "", http.StatusNotFound)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
keyring := &credentialprovider.BasicDockerKeyring{}
|
// Make a transport that reroutes all traffic to the example server
|
||||||
provider := &containerRegistryProvider{
|
transport := utilnet.SetTransportDefaults(&http.Transport{
|
||||||
metadataProvider{Client: &http.Client{Transport: transport}},
|
Proxy: func(req *http.Request) (*url.URL, error) {
|
||||||
}
|
return url.Parse(server.URL + req.URL.Path)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
if !provider.Enabled() {
|
keyring := &credentialprovider.BasicDockerKeyring{}
|
||||||
t.Errorf("Provider is unexpectedly disabled")
|
provider := &containerRegistryProvider{
|
||||||
}
|
metadataProvider{Client: &http.Client{Transport: transport}},
|
||||||
|
}
|
||||||
|
|
||||||
keyring.Add(provider.Provide(""))
|
if !provider.Enabled() {
|
||||||
|
t.Errorf("Provider is unexpectedly disabled")
|
||||||
|
}
|
||||||
|
|
||||||
creds, ok := keyring.Lookup(registryURL)
|
keyring.Add(provider.Provide(""))
|
||||||
if !ok {
|
|
||||||
t.Errorf("Didn't find expected URL: %s", registryURL)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(creds) > 1 {
|
|
||||||
t.Errorf("Got more hits than expected: %s", creds)
|
|
||||||
}
|
|
||||||
val := creds[0]
|
|
||||||
|
|
||||||
if val.Username != "_token" {
|
creds, ok := keyring.Lookup(registryURL)
|
||||||
t.Errorf("Unexpected username value, want: %s, got: %s", "_token", val.Username)
|
if !ok {
|
||||||
}
|
t.Errorf("Didn't find expected URL: %s", registryURL)
|
||||||
if token.AccessToken != val.Password {
|
return
|
||||||
t.Errorf("Unexpected password value, want: %s, got: %s", token.AccessToken, val.Password)
|
}
|
||||||
}
|
if len(creds) > 1 {
|
||||||
if email != val.Email {
|
t.Errorf("Got more hits than expected: %s", creds)
|
||||||
t.Errorf("Unexpected email value, want: %s, got: %s", email, val.Email)
|
}
|
||||||
|
val := creds[0]
|
||||||
|
|
||||||
|
if val.Username != "_token" {
|
||||||
|
t.Errorf("Unexpected username value, want: %s, got: %s", "_token", val.Username)
|
||||||
|
}
|
||||||
|
if token.AccessToken != val.Password {
|
||||||
|
t.Errorf("Unexpected password value, want: %s, got: %s", token.AccessToken, val.Password)
|
||||||
|
}
|
||||||
|
if email != val.Email {
|
||||||
|
t.Errorf("Unexpected email value, want: %s, got: %s", email, val.Email)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user