From 9b76b60d36c2223b64f18e62d8293fffde72663c Mon Sep 17 00:00:00 2001 From: Sedef Date: Thu, 5 Mar 2020 15:55:36 -0800 Subject: [PATCH] update kube-proxy daemonset tag --- controlplane/kubeadm/config/rbac/role.yaml | 21 ++++++- .../kubeadm_control_plane_controller.go | 61 +++++++++++++++++++ go.mod | 2 + go.sum | 5 ++ 4 files changed, 88 insertions(+), 1 deletion(-) diff --git a/controlplane/kubeadm/config/rbac/role.yaml b/controlplane/kubeadm/config/rbac/role.yaml index 481c8a77e27f..978bf45c323c 100644 --- a/controlplane/kubeadm/config/rbac/role.yaml +++ b/controlplane/kubeadm/config/rbac/role.yaml @@ -62,7 +62,17 @@ rules: - list - patch - watch - +- apiGroups: + - "apps" + resources: + - daemonsets + verbs: + - create + - get + - list + - watch + - patch + - update --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role @@ -98,3 +108,12 @@ rules: - get - list - watch +- apiGroups: + - "apps" + resources: + - daemonsets + verbs: + - create + - get + - list + - watch \ No newline at end of file diff --git a/controlplane/kubeadm/controllers/kubeadm_control_plane_controller.go b/controlplane/kubeadm/controllers/kubeadm_control_plane_controller.go index fd75ea1ab6cb..b275074b9a21 100644 --- a/controlplane/kubeadm/controllers/kubeadm_control_plane_controller.go +++ b/controlplane/kubeadm/controllers/kubeadm_control_plane_controller.go @@ -19,12 +19,15 @@ package controllers import ( "context" "fmt" + "sigs.k8s.io/cluster-api/controllers/remote" "strings" "time" "github.com/blang/semver" + "github.com/docker/distribution/reference" "github.com/go-logr/logr" "github.com/pkg/errors" + v1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -197,6 +200,39 @@ func (r *KubeadmControlPlaneReconciler) Reconcile(req ctrl.Request) (res ctrl.Re return r.reconcile(ctx, cluster, kcp) } +func (r *KubeadmControlPlaneReconciler) updateKubeProxyImage(ctx context.Context, cluster *clusterv1.Cluster, kcp *controlplanev1.KubeadmControlPlane) error { + c, err := remote.NewClusterClient(context.Background(), r.Client, util.ObjectKey(cluster), r.scheme) + // Failed to get remote cluster client: Kubeconfig secret may be missing for the cluster. + if err != nil { + return err + } + ds := &v1.DaemonSet{} + err = c.Get(ctx, client.ObjectKey{Namespace: "kube-system", Name: "kube-proxy"}, ds) + // if kube-proxy is missing, return without errors + if err != nil && apierrors.IsNotFound(err) { + return nil + } else if err != nil { + return err + } else { + newImageName, err := imageWithTagString(ds.Spec.Template.Spec.Containers[0].Image, "v"+kcp.Spec.Version) + if err != nil { + return err + } + + if len(ds.Spec.Template.Spec.Containers) > 0 && ds.Spec.Template.Spec.Containers[0].Image != newImageName{ + ds.Spec.Template.Spec.Containers[0].Image = newImageName + patchHelper, err := patch.NewHelper(ds, r.Client) + if err != nil { + return errors.Wrapf(err, "failed to create patch helper for daemonset %s", ds.Name) + } + + if err := patchHelper.Patch(ctx, ds); err != nil { + return errors.Wrapf(err, "failed to patch daemonset %s for image upgrade", ds.Name) + } + } + } + return nil +} // reconcile handles KubeadmControlPlane reconciliation. func (r *KubeadmControlPlaneReconciler) reconcile(ctx context.Context, cluster *clusterv1.Cluster, kcp *controlplanev1.KubeadmControlPlane) (res ctrl.Result, reterr error) { logger := r.Log.WithValues("namespace", kcp.Namespace, "kubeadmControlPlane", kcp.Name, "cluster", cluster.Name) @@ -258,6 +294,11 @@ func (r *KubeadmControlPlaneReconciler) reconcile(ctx context.Context, cluster * return r.upgradeControlPlane(ctx, cluster, kcp, ownedMachines, requireUpgrade) } + err = r.updateKubeProxyImage(ctx, cluster, kcp) + if err != nil{ + logger.Error(err,"failed updating kube-proxy image") + } + // If we've made it this far, we we can assume that all ownedMachines are up to date numMachines := len(ownedMachines) desiredReplicas := int(*kcp.Spec.Replicas) @@ -282,6 +323,26 @@ func (r *KubeadmControlPlaneReconciler) reconcile(ctx context.Context, cluster * return ctrl.Result{}, nil } +// imageWithTagString takes an image string, and zreturns an updated tagged image +func imageWithTagString(image string, tagName string) (string, error) { + namedRef, err := reference.ParseNormalizedNamed(image) + // return error if images use digest as version instead of tag + if _, isCanonical := namedRef.(reference.Canonical); isCanonical { + return "", errors.New("image uses digest as version, cannot update tag ") + } + namedTagged, err := reference.WithTag(namedRef, tagName) + if err != nil { + return "", errors.New("failed to update image tag") + + } + + if _, ok := namedRef.(reference.Tagged); ok { + return reference.FamiliarString(reference.TagNameOnly(namedTagged)), nil + } + + return "", errors.New("failed to update image tag") +} + func (r *KubeadmControlPlaneReconciler) updateStatus(ctx context.Context, kcp *controlplanev1.KubeadmControlPlane, cluster *clusterv1.Cluster) error { labelSelector := internal.ControlPlaneSelectorForCluster(cluster.Name) selector, err := metav1.LabelSelectorAsSelector(labelSelector) diff --git a/go.mod b/go.mod index 0e46a6a53da8..0c802197392d 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/MakeNowJust/heredoc v1.0.0 github.com/blang/semver v3.5.0+incompatible github.com/davecgh/go-spew v1.1.1 + github.com/docker/distribution v2.7.1+incompatible github.com/go-logr/logr v0.1.0 github.com/gogo/protobuf v1.3.1 github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect @@ -17,6 +18,7 @@ require ( github.com/imdario/mergo v0.3.8 // indirect github.com/onsi/ginkgo v1.11.0 github.com/onsi/gomega v1.8.1 + github.com/opencontainers/go-digest v1.0.0-rc1 // indirect github.com/pkg/errors v0.9.0 github.com/prometheus/client_golang v1.1.0 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 diff --git a/go.sum b/go.sum index 3f59b20700ef..eb769b45eb33 100644 --- a/go.sum +++ b/go.sum @@ -59,6 +59,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -96,6 +98,7 @@ github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9sn github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY= github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= @@ -259,6 +262,8 @@ github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGV github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34= github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4=