@@ -22,6 +22,7 @@ import (
22
22
"io"
23
23
"io/ioutil"
24
24
"os"
25
+ "regexp"
25
26
"time"
26
27
27
28
"github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry"
@@ -44,7 +45,10 @@ const (
44
45
maxReadLength = 10 * 1 << 20 // 10MB
45
46
)
46
47
47
- var containerRegistryUrls = []string {"*.azurecr.io" , "*.azurecr.cn" , "*.azurecr.de" , "*.azurecr.us" }
48
+ var (
49
+ containerRegistryUrls = []string {"*.azurecr.io" , "*.azurecr.cn" , "*.azurecr.de" , "*.azurecr.us" }
50
+ acrRE = regexp .MustCompile (`.*\.azurecr\.io|.*\.azurecr\.cn|.*\.azurecr\.de|.*\.azurecr\.us` )
51
+ )
48
52
49
53
// init registers the various means by which credentials may
50
54
// be resolved on Azure.
@@ -182,26 +186,16 @@ func (a *acrProvider) Enabled() bool {
182
186
}
183
187
184
188
func (a * acrProvider ) Provide (image string ) credentialprovider.DockerConfig {
189
+ klog .V (4 ).Infof ("try to provide secret for image %s" , image )
185
190
cfg := credentialprovider.DockerConfig {}
186
- ctx , cancel := getContextWithCancel ()
187
- defer cancel ()
188
191
189
192
if a .config .UseManagedIdentityExtension {
190
- klog .V (4 ).Infof ("listing registries" )
191
- result , err := a .registryClient .List (ctx )
192
- if err != nil {
193
- klog .Errorf ("Failed to list registries: %v" , err )
194
- return cfg
195
- }
196
-
197
- for ix := range result {
198
- loginServer := getLoginServer (result [ix ])
199
- klog .V (2 ).Infof ("loginServer: %s" , loginServer )
200
- cred , err := getACRDockerEntryFromARMToken (a , loginServer )
201
- if err != nil {
202
- continue
193
+ if loginServer := parseACRLoginServerFromImage (image ); loginServer == "" {
194
+ klog .V (4 ).Infof ("image(%s) is not from ACR, skip MSI authentication" , image )
195
+ } else {
196
+ if cred , err := getACRDockerEntryFromARMToken (a , loginServer ); err == nil {
197
+ cfg [loginServer ] = * cred
203
198
}
204
- cfg [loginServer ] = * cred
205
199
}
206
200
} else {
207
201
// Add our entry for each of the supported container registry URLs
@@ -229,6 +223,11 @@ func getLoginServer(registry containerregistry.Registry) string {
229
223
}
230
224
231
225
func getACRDockerEntryFromARMToken (a * acrProvider , loginServer string ) (* credentialprovider.DockerConfigEntry , error ) {
226
+ // Run EnsureFresh to make sure the token is valid and does not expire
227
+ if err := a .servicePrincipalToken .EnsureFresh (); err != nil {
228
+ klog .Errorf ("Failed to ensure fresh service principal token: %v" , err )
229
+ return nil , err
230
+ }
232
231
armAccessToken := a .servicePrincipalToken .OAuthToken ()
233
232
234
233
klog .V (4 ).Infof ("discovering auth redirects for: %s" , loginServer )
@@ -254,6 +253,16 @@ func getACRDockerEntryFromARMToken(a *acrProvider, loginServer string) (*credent
254
253
}, nil
255
254
}
256
255
256
+ // parseACRLoginServerFromImage takes image as parameter and returns login server of it.
257
+ // Parameter `image` is expected in following format: foo.azurecr.io/bar/imageName:version
258
+ // If the provided image is not an acr image, this function will return an empty string.
259
+ func parseACRLoginServerFromImage (image string ) string {
260
+ match := acrRE .FindAllString (image , - 1 )
261
+ if len (match ) == 1 {
262
+ return match [0 ]
263
+ }
264
+ return ""
265
+ }
257
266
func (a * acrProvider ) LazyProvide (image string ) * credentialprovider.DockerConfigEntry {
258
267
return nil
259
268
}
0 commit comments