Skip to content

Commit 64f9a83

Browse files
committed
fix: Correctly configure dynamic credential provider
It is only allowed for a single configuration per provider binary so match up the image hosts per binary in the config.
1 parent fe93e85 commit 64f9a83

File tree

4 files changed

+86
-48
lines changed

4 files changed

+86
-48
lines changed

make/dev.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ dev.update-webhook-image-on-kind:
3232
kind load docker-image --name $(KIND_CLUSTER_NAME) \
3333
ko.local/cluster-api-runtime-extensions-nutanix:$(SNAPSHOT_VERSION)
3434
kubectl set image deployment \
35-
cluster-api-runtime-extensions-nutanix webhook=ko.local/cluster-api-runtime-extensions-nutanix:$(SNAPSHOT_VERSION)
35+
cluster-api-runtime-extensions-nutanix manager=ko.local/cluster-api-runtime-extensions-nutanix:$(SNAPSHOT_VERSION)
3636
kubectl rollout restart deployment cluster-api-runtime-extensions-nutanix
3737
kubectl rollout status deployment cluster-api-runtime-extensions-nutanix
3838

pkg/handlers/generic/mutation/imageregistries/credentials/credential_provider_config_files.go

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import (
99
"fmt"
1010
"net/url"
1111
"path"
12+
"sort"
1213
"text/template"
1314

15+
"github.com/samber/lo"
1416
corev1 "k8s.io/api/core/v1"
1517
credentialproviderv1 "k8s.io/kubelet/pkg/apis/credentialprovider/v1"
1618
cabpkv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
@@ -165,41 +167,65 @@ func templateKubeletCredentialProviderConfig(
165167
func templateDynamicCredentialProviderConfig(
166168
configs []providerConfig,
167169
) (*cabpkv1.File, error) {
168-
type templateInput struct {
169-
RegistryHost string
170+
type providerConfig struct {
171+
RegistryHosts []string
170172
ProviderBinary string
171173
ProviderArgs []string
172174
ProviderAPIVersion string
173-
Mirror bool
175+
}
176+
type templateInput struct {
177+
Mirror string
178+
ProviderConfigs []*providerConfig
174179
}
175180

176-
inputs := make([]templateInput, 0, len(configs))
181+
binaryToProviderConfigMap := map[string]*providerConfig{}
177182

183+
mirror := ""
178184
for _, config := range configs {
179185
registryHostWithPath, err := config.registryHostWithPath()
180186
if err != nil {
181187
return nil, err
182188
}
183189

190+
if config.Mirror {
191+
mirror = registryHostWithPath
192+
}
193+
184194
providerBinary, providerArgs, providerAPIVersion, err := dynamicCredentialProvider(
185195
registryHostWithPath,
186196
)
187197
if err != nil {
188198
return nil, err
189199
}
190200

191-
inputs = append(inputs, templateInput{
192-
RegistryHost: registryHostWithPath,
193-
ProviderBinary: providerBinary,
194-
ProviderArgs: providerArgs,
195-
ProviderAPIVersion: providerAPIVersion,
196-
Mirror: config.Mirror,
197-
})
201+
input, ok := binaryToProviderConfigMap[providerBinary]
202+
if !ok {
203+
input = &providerConfig{
204+
ProviderBinary: providerBinary,
205+
ProviderArgs: providerArgs,
206+
ProviderAPIVersion: providerAPIVersion,
207+
}
208+
binaryToProviderConfigMap[providerBinary] = input
209+
}
210+
211+
input.RegistryHosts = append(input.RegistryHosts, registryHostWithPath)
212+
}
213+
214+
// Make sure the output is deterministic to avoid unnecessary rollouts.
215+
providerConfigs := lo.Values(binaryToProviderConfigMap)
216+
for _, cfg := range providerConfigs {
217+
sort.Strings(cfg.RegistryHosts)
198218
}
219+
sort.SliceStable(providerConfigs, func(i, j int) bool {
220+
return providerConfigs[i].ProviderBinary < providerConfigs[j].ProviderBinary
221+
})
199222

200223
return fileFromTemplate(
201224
dynamicCredentialProviderConfigPatchTemplate,
202-
inputs,
225+
templateInput{
226+
Mirror: mirror,
227+
ProviderConfigs: providerConfigs,
228+
},
203229
kubeletDynamicCredentialProviderConfigOnRemote,
204230
)
205231
}

pkg/handlers/generic/mutation/imageregistries/credentials/credential_provider_config_files_test.go

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,45 @@ providers:
118118
- "*.*.*.*.*.*"
119119
defaultCacheDuration: "0s"
120120
apiVersion: credentialprovider.kubelet.k8s.io/v1
121+
`,
122+
},
123+
},
124+
{
125+
name: "multiple image registries with static config",
126+
credentials: []providerConfig{{
127+
URL: "https://myregistry.com:5000/myproject",
128+
Username: "myuser",
129+
Password: "mypassword",
130+
}, {
131+
URL: "https://myotherregistry.com:5000/myproject",
132+
Username: "otheruser",
133+
Password: "otherpassword",
134+
}},
135+
want: &cabpkv1.File{
136+
Path: "/etc/kubernetes/image-credential-provider-config.yaml",
137+
Owner: "",
138+
Permissions: "0600",
139+
Encoding: "",
140+
Append: false,
141+
Content: `apiVersion: kubelet.config.k8s.io/v1
142+
kind: CredentialProviderConfig
143+
providers:
144+
- name: dynamic-credential-provider
145+
args:
146+
- get-credentials
147+
- -c
148+
- /etc/kubernetes/dynamic-credential-provider-config.yaml
149+
matchImages:
150+
- "myregistry.com:5000/myproject"
151+
- "myotherregistry.com:5000/myproject"
152+
- "*"
153+
- "*.*"
154+
- "*.*.*"
155+
- "*.*.*.*"
156+
- "*.*.*.*.*"
157+
- "*.*.*.*.*.*"
158+
defaultCacheDuration: "0s"
159+
apiVersion: credentialprovider.kubelet.k8s.io/v1
121160
`,
122161
},
123162
},
@@ -261,21 +300,6 @@ credentialProviders:
261300
apiVersion: kubelet.config.k8s.io/v1
262301
kind: CredentialProviderConfig
263302
providers:
264-
- name: static-credential-provider
265-
args:
266-
- /etc/kubernetes/static-image-credentials.json
267-
matchImages:
268-
- "registry-1.docker.io"
269-
- "docker.io"
270-
defaultCacheDuration: "0s"
271-
apiVersion: credentialprovider.kubelet.k8s.io/v1
272-
- name: static-credential-provider
273-
args:
274-
- /etc/kubernetes/static-image-credentials.json
275-
matchImages:
276-
- "myregistry.com"
277-
defaultCacheDuration: "0s"
278-
apiVersion: credentialprovider.kubelet.k8s.io/v1
279303
- name: ecr-credential-provider
280304
args:
281305
- get-credentials
@@ -288,6 +312,9 @@ credentialProviders:
288312
- /etc/kubernetes/static-image-credentials.json
289313
matchImages:
290314
- "anotherregistry.com"
315+
- "myregistry.com"
316+
- "registry-1.docker.io"
317+
- "docker.io"
291318
defaultCacheDuration: "0s"
292319
apiVersion: credentialprovider.kubelet.k8s.io/v1
293320
`,
@@ -325,12 +352,6 @@ credentialProviders:
325352
- get-credentials
326353
matchImages:
327354
- "123456789.dkr.ecr.us-east-1.amazonaws.com"
328-
defaultCacheDuration: "0s"
329-
apiVersion: credentialprovider.kubelet.k8s.io/v1
330-
- name: ecr-credential-provider
331-
args:
332-
- get-credentials
333-
matchImages:
334355
- "98765432.dkr.ecr.us-east-1.amazonaws.com"
335356
defaultCacheDuration: "0s"
336357
apiVersion: credentialprovider.kubelet.k8s.io/v1
@@ -368,18 +389,12 @@ credentialProviders:
368389
apiVersion: kubelet.config.k8s.io/v1
369390
kind: CredentialProviderConfig
370391
providers:
371-
- name: static-credential-provider
372-
args:
373-
- /etc/kubernetes/static-image-credentials.json
374-
matchImages:
375-
- "myregistry.com"
376-
defaultCacheDuration: "0s"
377-
apiVersion: credentialprovider.kubelet.k8s.io/v1
378392
- name: static-credential-provider
379393
args:
380394
- /etc/kubernetes/static-image-credentials.json
381395
matchImages:
382396
- "mymirror.com"
397+
- "myregistry.com"
383398
defaultCacheDuration: "0s"
384399
apiVersion: credentialprovider.kubelet.k8s.io/v1
385400
`,

pkg/handlers/generic/mutation/imageregistries/credentials/templates/dynamic-credential-provider-config.yaml.gotmpl

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
apiVersion: credentialprovider.d2iq.com/v1alpha1
22
kind: DynamicCredentialProviderConfig
3-
{{- range .}}
4-
{{- if .Mirror }}
3+
{{- with .Mirror }}
54
mirror:
6-
endpoint: {{ .RegistryHost }}
5+
endpoint: {{ . }}
76
credentialsStrategy: MirrorCredentialsFirst
8-
{{- break }}
9-
{{- end }}
107
{{- end }}
118
credentialProviderPluginBinDir: /etc/kubernetes/image-credential-provider/
129
credentialProviders:
1310
apiVersion: kubelet.config.k8s.io/v1
1411
kind: CredentialProviderConfig
1512
providers:
16-
{{- range . }}
13+
{{- range .ProviderConfigs }}
1714
- name: {{ .ProviderBinary }}
1815
{{- with .ProviderArgs }}
1916
args:
@@ -22,7 +19,7 @@ credentialProviders:
2219
{{- end }}
2320
{{- end }}
2421
matchImages:
25-
{{- with .RegistryHost }}
22+
{{- range .RegistryHosts }}
2623
- {{ printf "%q" . }}
2724
{{- if eq . "registry-1.docker.io" }}
2825
- "docker.io"

0 commit comments

Comments
 (0)