Skip to content

Commit 981f675

Browse files
authored
Merge pull request kubernetes#92330 from andyzhangx/msi-cred-issue
fix: don't use docker config cache if it's empty
2 parents 79a7088 + fe873af commit 981f675

File tree

4 files changed

+62
-11
lines changed

4 files changed

+62
-11
lines changed

pkg/credentialprovider/azure/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ go_test(
3434
"//vendor/github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2019-05-01/containerregistry:go_default_library",
3535
"//vendor/github.com/Azure/go-autorest/autorest/azure:go_default_library",
3636
"//vendor/github.com/Azure/go-autorest/autorest/to:go_default_library",
37+
"//vendor/github.com/stretchr/testify/assert:go_default_library",
3738
],
3839
)
3940

pkg/credentialprovider/azure/azure_credentials.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ var (
5656
func init() {
5757
credentialprovider.RegisterCredentialProvider("azure",
5858
&credentialprovider.CachingDockerConfigProvider{
59-
Provider: NewACRProvider(flagConfigFile),
60-
Lifetime: 1 * time.Minute,
59+
Provider: NewACRProvider(flagConfigFile),
60+
Lifetime: 1 * time.Minute,
61+
ShouldCache: func(d credentialprovider.DockerConfig) bool { return len(d) > 0 },
6162
})
6263
}
6364

@@ -186,13 +187,21 @@ func (a *acrProvider) Provide(image string) credentialprovider.DockerConfig {
186187
klog.V(4).Infof("try to provide secret for image %s", image)
187188
cfg := credentialprovider.DockerConfig{}
188189

190+
defaultConfigEntry := credentialprovider.DockerConfigEntry{
191+
Username: "",
192+
Password: "",
193+
Email: dummyRegistryEmail,
194+
}
195+
189196
if a.config.UseManagedIdentityExtension {
190197
if loginServer := a.parseACRLoginServerFromImage(image); loginServer == "" {
191198
klog.V(4).Infof("image(%s) is not from ACR, skip MSI authentication", image)
192199
} else {
193200
if cred, err := getACRDockerEntryFromARMToken(a, loginServer); err == nil {
194201
cfg[loginServer] = *cred
195202
}
203+
// add ACR anonymous repo support: use empty username and password for anonymous access
204+
cfg["*.azurecr.*"] = defaultConfigEntry
196205
}
197206
} else {
198207
// Add our entry for each of the supported container registry URLs
@@ -226,13 +235,9 @@ func (a *acrProvider) Provide(image string) credentialprovider.DockerConfig {
226235
cfg[customAcrSuffix] = *cred
227236
}
228237
}
229-
}
230238

231-
// add ACR anonymous repo support: use empty username and password for anonymous access
232-
cfg["*.azurecr.*"] = credentialprovider.DockerConfigEntry{
233-
Username: "",
234-
Password: "",
235-
Email: dummyRegistryEmail,
239+
// add ACR anonymous repo support: use empty username and password for anonymous access
240+
cfg["*.azurecr.*"] = defaultConfigEntry
236241
}
237242
return cfg
238243
}

pkg/credentialprovider/azure/azure_credentials_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import (
2424
"github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2019-05-01/containerregistry"
2525
"github.com/Azure/go-autorest/autorest/azure"
2626
"github.com/Azure/go-autorest/autorest/to"
27+
28+
"github.com/stretchr/testify/assert"
2729
)
2830

2931
type fakeClient struct {
@@ -96,6 +98,42 @@ func Test(t *testing.T) {
9698
}
9799
}
98100

101+
func TestProvide(t *testing.T) {
102+
testCases := []struct {
103+
desc string
104+
configStr string
105+
expectedCredsLength int
106+
}{
107+
{
108+
desc: "return multiple credentials using Service Principal",
109+
configStr: `
110+
{
111+
"aadClientId": "foo",
112+
"aadClientSecret": "bar"
113+
}`,
114+
expectedCredsLength: 5,
115+
},
116+
{
117+
desc: "retuen 0 credential for non-ACR image using Managed Identity",
118+
configStr: `
119+
{
120+
"UseManagedIdentityExtension": true
121+
}`,
122+
expectedCredsLength: 0,
123+
},
124+
}
125+
126+
for i, test := range testCases {
127+
provider := &acrProvider{
128+
registryClient: &fakeClient{},
129+
}
130+
provider.loadConfig(bytes.NewBufferString(test.configStr))
131+
132+
creds := provider.Provide("busybox")
133+
assert.Equal(t, test.expectedCredsLength, len(creds), "TestCase[%d]: %s", i, test.desc)
134+
}
135+
}
136+
99137
func TestParseACRLoginServerFromImage(t *testing.T) {
100138
configStr := `
101139
{

pkg/credentialprovider/provider.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ type CachingDockerConfigProvider struct {
5858
Provider DockerConfigProvider
5959
Lifetime time.Duration
6060

61+
// ShouldCache is an optional function that returns true if the specific config should be cached.
62+
// If nil, all configs are treated as cacheable.
63+
ShouldCache func(DockerConfig) bool
64+
6165
// cache fields
6266
cacheDockerConfig DockerConfig
6367
expiration time.Time
@@ -96,7 +100,10 @@ func (d *CachingDockerConfigProvider) Provide(image string) DockerConfig {
96100
}
97101

98102
klog.V(2).Infof("Refreshing cache for provider: %v", reflect.TypeOf(d.Provider).String())
99-
d.cacheDockerConfig = d.Provider.Provide(image)
100-
d.expiration = time.Now().Add(d.Lifetime)
101-
return d.cacheDockerConfig
103+
config := d.Provider.Provide(image)
104+
if d.ShouldCache == nil || d.ShouldCache(config) {
105+
d.cacheDockerConfig = config
106+
d.expiration = time.Now().Add(d.Lifetime)
107+
}
108+
return config
102109
}

0 commit comments

Comments
 (0)