Skip to content

Commit 187304d

Browse files
committed
fix: Correctly configgure dynamic credential provider
Only allowed a single configuration per provider binary so match up the image hosts per binary in the config. Tested and works well, including in conjunction with the CA config in the previous PR.
1 parent 2fd79d3 commit 187304d

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)