Skip to content

Commit ecff70a

Browse files
authored
Merge pull request kubernetes-sigs#2807 from benmoss/update-image-repo
🐛 KCP should update Kubeadm config map when setting `imageRepository`
2 parents 1be9d30 + bedda68 commit ecff70a

File tree

4 files changed

+122
-8
lines changed

4 files changed

+122
-8
lines changed

controlplane/kubeadm/controllers/upgrade.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ func (r *KubeadmControlPlaneReconciler) upgradeControlPlane(
6464
return ctrl.Result{}, errors.Wrap(err, "failed to update the kubernetes version in the kubeadm config map")
6565
}
6666

67+
if kcp.Spec.KubeadmConfigSpec.ClusterConfiguration != nil {
68+
imageRepository := kcp.Spec.KubeadmConfigSpec.ClusterConfiguration.ImageRepository
69+
if err := workloadCluster.UpdateImageRepositoryInKubeadmConfigMap(ctx, imageRepository); err != nil {
70+
return ctrl.Result{}, errors.Wrap(err, "failed to update the image repository in the kubeadm config map")
71+
}
72+
}
73+
6774
if kcp.Spec.KubeadmConfigSpec.ClusterConfiguration != nil && kcp.Spec.KubeadmConfigSpec.ClusterConfiguration.Etcd.Local != nil {
6875
meta := kcp.Spec.KubeadmConfigSpec.ClusterConfiguration.Etcd.Local.ImageMeta
6976
if err := workloadCluster.UpdateEtcdVersionInKubeadmConfigMap(ctx, meta.ImageRepository, meta.ImageTag); err != nil {

controlplane/kubeadm/internal/kubeadm_config_map.go

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@ import (
2727
)
2828

2929
const (
30-
clusterStatusKey = "ClusterStatus"
31-
clusterConfigurationKey = "ClusterConfiguration"
32-
statusAPIEndpointsKey = "apiEndpoints"
33-
configVersionKey = "kubernetesVersion"
34-
dnsKey = "dns"
35-
dnsTypeKey = "type"
36-
dnsImageRepositoryKey = "imageRepository"
37-
dnsImageTagKey = "imageTag"
30+
clusterStatusKey = "ClusterStatus"
31+
clusterConfigurationKey = "ClusterConfiguration"
32+
statusAPIEndpointsKey = "apiEndpoints"
33+
configVersionKey = "kubernetesVersion"
34+
dnsKey = "dns"
35+
dnsTypeKey = "type"
36+
dnsImageRepositoryKey = "imageRepository"
37+
dnsImageTagKey = "imageTag"
38+
configImageRepositoryKey = "imageRepository"
3839
)
3940

4041
// kubeadmConfig wraps up interactions necessary for modifying the kubeadm config during an upgrade.
@@ -89,6 +90,30 @@ func (k *kubeadmConfig) UpdateKubernetesVersion(version string) error {
8990
return nil
9091
}
9192

93+
// UpdateImageRepository changes the image repository found in the kubeadm config map
94+
func (k *kubeadmConfig) UpdateImageRepository(imageRepository string) error {
95+
if imageRepository == "" {
96+
return nil
97+
}
98+
data, ok := k.ConfigMap.Data[clusterConfigurationKey]
99+
if !ok {
100+
return errors.Errorf("unable to find %q key in kubeadm ConfigMap", clusterConfigurationKey)
101+
}
102+
configuration, err := yamlToUnstructured([]byte(data))
103+
if err != nil {
104+
return errors.Wrapf(err, "unable to decode kubeadm ConfigMap's %q to Unstructured object", clusterConfigurationKey)
105+
}
106+
if err := unstructured.SetNestedField(configuration.UnstructuredContent(), imageRepository, configImageRepositoryKey); err != nil {
107+
return errors.Wrapf(err, "unable to update %q on kubeadm ConfigMap's %q", imageRepository, clusterConfigurationKey)
108+
}
109+
updated, err := yaml.Marshal(configuration)
110+
if err != nil {
111+
return errors.Wrapf(err, "unable to encode kubeadm ConfigMap's %q to YAML", clusterConfigurationKey)
112+
}
113+
k.ConfigMap.Data[clusterConfigurationKey] = string(updated)
114+
return nil
115+
}
116+
92117
// UpdateEtcdMeta sets the local etcd's configuration's image repository and image tag
93118
func (k *kubeadmConfig) UpdateEtcdMeta(imageRepository, imageTag string) (bool, error) {
94119
data, ok := k.ConfigMap.Data[clusterConfigurationKey]

controlplane/kubeadm/internal/kubeadm_config_map_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,3 +307,67 @@ scheduler: {}`,
307307
})
308308
}
309309
}
310+
311+
func TestUpdateImageRepository(t *testing.T) {
312+
313+
tests := []struct {
314+
name string
315+
clusterConfigurationValue string
316+
imageRepository string
317+
expected string
318+
expectErr error
319+
}{
320+
{
321+
name: "it should set the values, if they were empty",
322+
clusterConfigurationValue: `
323+
apiVersion: kubeadm.k8s.io/v1beta2
324+
kind: ClusterConfiguration
325+
imageRepository: k8s.gcr.io
326+
`,
327+
imageRepository: "example.com/k8s",
328+
expected: "example.com/k8s",
329+
},
330+
{
331+
name: "it shouldn't write empty strings",
332+
clusterConfigurationValue: `
333+
apiVersion: kubeadm.k8s.io/v1beta2
334+
kind: ClusterConfiguration
335+
imageRepository: k8s.gcr.io
336+
`,
337+
imageRepository: "",
338+
expected: "k8s.gcr.io",
339+
},
340+
{
341+
name: "it should error if it's not a valid k8s object",
342+
clusterConfigurationValue: `
343+
imageRepository: "cool"
344+
`,
345+
imageRepository: "example.com/k8s",
346+
expectErr: errors.New("Object 'Kind' is missing"),
347+
},
348+
}
349+
350+
for _, test := range tests {
351+
t.Run(test.name, func(t *testing.T) {
352+
g := NewWithT(t)
353+
354+
kconfig := &kubeadmConfig{
355+
ConfigMap: &corev1.ConfigMap{
356+
Data: map[string]string{
357+
clusterConfigurationKey: test.clusterConfigurationValue,
358+
},
359+
},
360+
}
361+
362+
err := kconfig.UpdateImageRepository(test.imageRepository)
363+
if test.expectErr == nil {
364+
g.Expect(err).ToNot(HaveOccurred())
365+
} else {
366+
g.Expect(err).To(HaveOccurred())
367+
g.Expect(err.Error()).To(ContainSubstring(test.expectErr.Error()))
368+
}
369+
370+
g.Expect(kconfig.ConfigMap.Data[clusterConfigurationKey]).To(ContainSubstring(test.expected))
371+
})
372+
}
373+
}

controlplane/kubeadm/internal/workload_cluster.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ type WorkloadCluster interface {
6868
ReconcileKubeletRBACBinding(ctx context.Context, version semver.Version) error
6969
ReconcileKubeletRBACRole(ctx context.Context, version semver.Version) error
7070
UpdateKubernetesVersionInKubeadmConfigMap(ctx context.Context, version semver.Version) error
71+
UpdateImageRepositoryInKubeadmConfigMap(ctx context.Context, imageRepository string) error
7172
UpdateEtcdVersionInKubeadmConfigMap(ctx context.Context, imageRepository, imageTag string) error
7273
UpdateKubeletConfigMap(ctx context.Context, version semver.Version) error
7374
UpdateKubeProxyImageInfo(ctx context.Context, kcp *controlplanev1.KubeadmControlPlane) error
@@ -308,6 +309,23 @@ func (w *Workload) UpdateEtcdVersionInKubeadmConfigMap(ctx context.Context, imag
308309
return nil
309310
}
310311

312+
// UpdateKubernetesVersionInKubeadmConfigMap updates the kubernetes version in the kubeadm config map.
313+
func (w *Workload) UpdateImageRepositoryInKubeadmConfigMap(ctx context.Context, imageRepository string) error {
314+
configMapKey := ctrlclient.ObjectKey{Name: "kubeadm-config", Namespace: metav1.NamespaceSystem}
315+
kubeadmConfigMap, err := w.getConfigMap(ctx, configMapKey)
316+
if err != nil {
317+
return err
318+
}
319+
config := &kubeadmConfig{ConfigMap: kubeadmConfigMap}
320+
if err := config.UpdateImageRepository(imageRepository); err != nil {
321+
return err
322+
}
323+
if err := w.Client.Update(ctx, config.ConfigMap); err != nil {
324+
return errors.Wrap(err, "error updating kubeadm ConfigMap")
325+
}
326+
return nil
327+
}
328+
311329
// UpdateKubernetesVersionInKubeadmConfigMap updates the kubernetes version in the kubeadm config map.
312330
func (w *Workload) UpdateKubernetesVersionInKubeadmConfigMap(ctx context.Context, version semver.Version) error {
313331
configMapKey := ctrlclient.ObjectKey{Name: "kubeadm-config", Namespace: metav1.NamespaceSystem}

0 commit comments

Comments
 (0)