diff --git a/pkg/credentialprovider/aws/aws_credentials.go b/pkg/credentialprovider/aws/aws_credentials.go index 7e8955e9c0c..d889cbf1fa8 100644 --- a/pkg/credentialprovider/aws/aws_credentials.go +++ b/pkg/credentialprovider/aws/aws_credentials.go @@ -30,7 +30,10 @@ import ( "k8s.io/kubernetes/pkg/credentialprovider" ) -const registryURLTemplate = "*.dkr.ecr.%s.amazonaws.com" +const awsChinaRegionPrefix = "cn-" +const awsStandardDNSSuffix = "amazonaws.com" +const awsChinaDNSSuffix = "amazonaws.com.cn" +const registryURLTemplate = "*.dkr.ecr.%s.%s" // awsHandlerLogger is a handler that logs all AWS SDK requests // Copied from pkg/cloudprovider/providers/aws/log_handler.go @@ -80,6 +83,16 @@ type ecrProvider struct { var _ credentialprovider.DockerConfigProvider = &ecrProvider{} +// registryURL has different suffix in AWS China region +func registryURL(region string) string { + dnsSuffix := awsStandardDNSSuffix + // deal with aws none standard regions + if strings.HasPrefix(region, awsChinaRegionPrefix) { + dnsSuffix = awsChinaDNSSuffix + } + return fmt.Sprintf(registryURLTemplate, region, dnsSuffix) +} + // RegisterCredentialsProvider registers a credential provider for the specified region. // It creates a lazy provider for each AWS region, in order to support // cross-region ECR access. They have to be lazy because it's unlikely, but not @@ -92,7 +105,7 @@ func RegisterCredentialsProvider(region string) { credentialprovider.RegisterCredentialProvider("aws-ecr-"+region, &lazyEcrProvider{ region: region, - regionURL: fmt.Sprintf(registryURLTemplate, region), + regionURL: registryURL(region), }) } @@ -136,7 +149,7 @@ func (p *lazyEcrProvider) Provide() credentialprovider.DockerConfig { func newEcrProvider(region string, getter tokenGetter) *ecrProvider { return &ecrProvider{ region: region, - regionURL: fmt.Sprintf(registryURLTemplate, region), + regionURL: registryURL(region), getter: getter, } } diff --git a/pkg/credentialprovider/aws/aws_credentials_test.go b/pkg/credentialprovider/aws/aws_credentials_test.go index 7299c85ce57..499af17b78b 100644 --- a/pkg/credentialprovider/aws/aws_credentials_test.go +++ b/pkg/credentialprovider/aws/aws_credentials_test.go @@ -59,6 +59,7 @@ func (p *testTokenGetter) GetAuthorizationToken(input *ecr.GetAuthorizationToken func TestEcrProvide(t *testing.T) { registry := "123456789012.dkr.ecr.lala-land-1.amazonaws.com" otherRegistries := []string{ + "123456789012.dkr.ecr.cn-foo-1.amazonaws.com.cn", "private.registry.com", "gcr.io", } @@ -107,3 +108,56 @@ func TestEcrProvide(t *testing.T) { } } } + +func TestChinaEcrProvide(t *testing.T) { + registry := "123456789012.dkr.ecr.cn-foo-1.amazonaws.com.cn" + otherRegistries := []string{ + "123456789012.dkr.ecr.lala-land-1.amazonaws.com", + "private.registry.com", + "gcr.io", + } + image := "foo/bar" + + provider := newEcrProvider("cn-foo-1", + &testTokenGetter{ + user: user, + password: password, + endpoint: registry, + }) + + keyring := &credentialprovider.BasicDockerKeyring{} + keyring.Add(provider.Provide()) + + // Verify that we get the expected username/password combo for + // an ECR image name. + fullImage := path.Join(registry, image) + creds, ok := keyring.Lookup(fullImage) + if !ok { + t.Errorf("Didn't find expected URL: %s", fullImage) + return + } + if len(creds) > 1 { + t.Errorf("Got more hits than expected: %s", creds) + } + val := creds[0] + + if user != val.Username { + t.Errorf("Unexpected username value, want: _token, got: %s", val.Username) + } + if password != val.Password { + t.Errorf("Unexpected password value, want: %s, got: %s", password, val.Password) + } + if email != val.Email { + t.Errorf("Unexpected email value, want: %s, got: %s", email, val.Email) + } + + // Verify that we get an error for other images. + for _, otherRegistry := range otherRegistries { + fullImage = path.Join(otherRegistry, image) + creds, ok = keyring.Lookup(fullImage) + if ok { + t.Errorf("Unexpectedly found image: %s", fullImage) + return + } + } +}