Skip to content

Commit

Permalink
Add function to patch coredns deployment
Browse files Browse the repository at this point in the history
Rename UpdateCoreDNS to UpdateCoreDNSCorefile
  • Loading branch information
Warren Fernandes committed Mar 7, 2020
1 parent 5d4fe51 commit 1bdac44
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 21 deletions.
40 changes: 26 additions & 14 deletions controlplane/kubeadm/internal/workload_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,27 +312,24 @@ func (w *Workload) UpdateCoreDNSImageInfoInKubeadmConfigMap(ctx context.Context,
return nil
}

// TODO: Add description
// TODO: Where are the logs? Can we have logs?
// TODO: Make sure you import the migrator and hook it up with WorkloadCluster
func (w *Workload) UpdateCoreDNS(ctx context.Context, dns *kubeadmv1.DNS) error {
// UpdateCoreDNSCorefile migrates the coredns corefile if there is an increase
// in version number. It also creates a corefile backup and patches the
// deployment to point to the backup corefile before migrating.
func (w *Workload) UpdateCoreDNSCorefile(ctx context.Context, dns *kubeadmv1.DNS) error {
if dns.Type != kubeadmv1.CoreDNS {
// do nothing if it is not CoreDNS
return nil
}

currentCoreDNSVersion, currentCoreDNSCorefile, err := w.getCoreDNSInfo(ctx)
_ = err
toCoreDNSVersion := dns.ImageTag
if err != nil {
return err
}

// TODO: might not need to do this since migrations.Migrate will check
// curVer, err := semver.Parse(currentCoreDNSVersion)
// toVer, err := semver.Parse(toCoreDNSVersion)
// if curVer.Compare(toVer) > 0 {
// // TODO return error since we don't want to migrate down
// }
toCoreDNSVersion := dns.ImageTag

// TODO: Backup corefile and patch coredns deployment.
if err := w.Client.Update(ctx, &v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "coredns",
Expand All @@ -346,7 +343,8 @@ func (w *Workload) UpdateCoreDNS(ctx context.Context, dns *kubeadmv1.DNS) error
return errors.Wrap(err, "unable to update CoreDNS config map with backup Corefile")
}

if err := w.patchCoreDNSDeploymentVolume(ctx, corefileBackupKey); err != nil {
patchJSON := fmt.Sprintf(`{"spec":{"template":{"spec":{"volumes":[{"name": "config-volume", "configMap":{"name": "coredns", "items":[{"key": "%[1]s", "path": "%[1]s"}]}}]}}}}`, corefileBackupKey)
if err := w.patchCoreDNSDeployment(ctx, patchJSON); err != nil {
return errors.Wrapf(err, "unable to patch coredns deployment with corefile: %s", corefileBackupKey)
}

Expand All @@ -370,13 +368,27 @@ func (w *Workload) UpdateCoreDNS(ctx context.Context, dns *kubeadmv1.DNS) error
return nil
}

func (w *Workload) patchCoreDNSDeploymentVolume(ctx context.Context, key string) error {
// UpdateCoreDNSDeployment will patch the deployment image to the
// imageRepo:imageTag in the KCP dns. It will also ensure the volume of the
// deployment uses the Corefile key of the coredns configmap.
func (w *Workload) UpdateCoreDNSDeployment(ctx context.Context, dns *kubeadmv1.DNS) error {
image := fmt.Sprintf("%s:%s", dns.ImageRepository, dns.ImageTag)
patchJSON := fmt.Sprintf(
`{"spec":{"template":{"spec":{"containers":[{"name": "coredns", "image":"%s"}],"volumes":[{"name": "config-volume", "configMap":{"name": "coredns", "items":[{"key": "%[2]s", "path": "%[2]s"}]}}]}}}}`,
image,
corefileKey,
)
w.patchCoreDNSDeployment(ctx, patchJSON)

return nil
}

func (w *Workload) patchCoreDNSDeployment(ctx context.Context, patchJSON string) error {
corednsKey := ctrlclient.ObjectKey{Name: coreDNSKey, Namespace: metav1.NamespaceSystem}
orig := &appsv1.Deployment{}
if err := w.Client.Get(ctx, corednsKey, orig); err != nil {
return errors.Wrapf(err, "unable to get %s deployment from target cluster", corednsKey.String())
}
patchJSON := fmt.Sprintf(`{"spec":{"template":{"spec":{"volumes":[{"name": "config-volume", "configMap":{"name": "coredns", "items":[{"key": "%[1]s", "path": "%[1]s"}]}}]}}}}`, key)
patch := ctrlclient.RawPatch(types.StrategicMergePatchType, []byte(patchJSON))

if err := w.Client.Patch(ctx, orig, patch); err != nil {
Expand Down
97 changes: 90 additions & 7 deletions controlplane/kubeadm/internal/workload_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func (m *fakeMigrator) Migrate(current, to, corefile string, deprecations bool)
return m.migratedCorefile, nil
}

func TestUpdateCoreDNS(t *testing.T) {
func TestUpdateCoreDNSCorefile(t *testing.T) {
currentImageTag := "1.6.2"
originalCorefile := "some-coredns-core-file"
depl := &appsv1.Deployment{
Expand Down Expand Up @@ -188,7 +188,7 @@ func TestUpdateCoreDNS(t *testing.T) {
Type: kubeadmv1.KubeDNS,
}

err := w.UpdateCoreDNS(context.TODO(), dns)
err := w.UpdateCoreDNSCorefile(context.TODO(), dns)
g.Expect(err).ToNot(HaveOccurred())
g.Expect(fakeMigrator.migrateCalled).To(BeFalse())

Expand All @@ -215,7 +215,7 @@ func TestUpdateCoreDNS(t *testing.T) {
},
}

err := w.UpdateCoreDNS(context.TODO(), dns)
err := w.UpdateCoreDNSCorefile(context.TODO(), dns)
g.Expect(err).To(HaveOccurred())
g.Expect(fakeMigrator.migrateCalled).To(BeTrue())
})
Expand Down Expand Up @@ -243,7 +243,7 @@ func TestUpdateCoreDNS(t *testing.T) {
},
}

err := w.UpdateCoreDNS(context.TODO(), dns)
err := w.UpdateCoreDNSCorefile(context.TODO(), dns)
g.Expect(err).To(HaveOccurred())

var expectedConfigMap corev1.ConfigMap
Expand Down Expand Up @@ -276,7 +276,7 @@ func TestUpdateCoreDNS(t *testing.T) {
},
}

err := w.UpdateCoreDNS(context.TODO(), dns)
err := w.UpdateCoreDNSCorefile(context.TODO(), dns)
g.Expect(err).To(HaveOccurred())

expectedVolume := corev1.Volume{
Expand Down Expand Up @@ -320,7 +320,7 @@ func TestUpdateCoreDNS(t *testing.T) {
},
}

err := w.UpdateCoreDNS(context.TODO(), dns)
err := w.UpdateCoreDNSCorefile(context.TODO(), dns)
g.Expect(err).ToNot(HaveOccurred())

var expectedConfigMap corev1.ConfigMap
Expand All @@ -329,7 +329,6 @@ func TestUpdateCoreDNS(t *testing.T) {
g.Expect(expectedConfigMap.Data).To(HaveKeyWithValue("Corefile", "updated-core-file"))
g.Expect(expectedConfigMap.Data).To(HaveKeyWithValue("Corefile-backup", originalCorefile))
})

}

func TestGetCoreDNSInfo(t *testing.T) {
Expand Down Expand Up @@ -542,3 +541,87 @@ scheduler: {}`,
}

}

func TestUpdateCoreDNSDeployment(t *testing.T) {
depl := &appsv1.Deployment{
ObjectMeta: v1.ObjectMeta{
Name: coreDNSKey,
Namespace: metav1.NamespaceSystem,
},
Spec: appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{
ObjectMeta: v1.ObjectMeta{
Name: coreDNSKey,
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{{
Name: coreDNSKey,
Image: "k8s.gcr.io/coredns:1.6.2",
Args: []string{"-conf", "/etc/coredns/Corefile"},
}},
Volumes: []corev1.Volume{{
Name: "config-volume",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: coreDNSKey,
},
Items: []corev1.KeyToPath{{
Key: corefileBackupKey,
Path: corefileBackupKey,
}},
},
},
}},
},
},
},
}

g := gomega.NewWithT(t)
objs := []runtime.Object{depl}
fakeClient := fake.NewFakeClientWithScheme(scheme.Scheme, objs...)
fakeMigrator := &fakeMigrator{
migratedCorefile: "updated-core-file",
}

w := &Workload{
Client: fakeClient,
Migrator: fakeMigrator,
}

dns := &kubeadmv1.DNS{
Type: kubeadmv1.CoreDNS,
ImageMeta: kubeadmv1.ImageMeta{
ImageRepository: "k8s.gcr.io/coredns",
ImageTag: "1.7.2",
},
}

err := w.UpdateCoreDNSDeployment(context.TODO(), dns)
g.Expect(err).ToNot(HaveOccurred())

expectedVolume := corev1.Volume{
Name: "config-volume",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: coreDNSKey,
},
Items: []corev1.KeyToPath{{
Key: corefileKey,
Path: corefileKey,
}},
},
},
}

var actualDeployment appsv1.Deployment
g.Expect(fakeClient.Get(context.TODO(), ctrlclient.ObjectKey{Name: "coredns", Namespace: metav1.NamespaceSystem}, &actualDeployment)).To(Succeed())
// ensure the image is updated and the volumes point to the corefile
g.Expect(actualDeployment.Spec.Template.Spec.Containers[0].Image).To(Equal("k8s.gcr.io/coredns:1.7.2"))
g.Expect(actualDeployment.Spec.Template.Spec.Volumes).To(ConsistOf(expectedVolume))

}

// TODO: A full update core dns test which ensures

0 comments on commit 1bdac44

Please sign in to comment.