mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 10:18:13 +00:00 
			
		
		
		
	Whitelisting *.pkg.dev for the GCP credential provider
This commit is contained in:
		 Yuriy Gridasov
					Yuriy Gridasov
				
			
				
					committed by
					
						 Yury Gridasov
						Yury Gridasov
					
				
			
			
				
	
			
			
			 Yury Gridasov
						Yury Gridasov
					
				
			
						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) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user