From f48b33e5c053c8d4a7b56d0bf0ec9e6061a59c9b Mon Sep 17 00:00:00 2001 From: killianmuldoon Date: Tue, 7 Nov 2023 11:21:57 +0000 Subject: [PATCH] Support super-admin config for Kubeadm v1.29 Signed-off-by: killianmuldoon --- .../internal/controllers/fakes_test.go | 4 ++ .../kubeadm/internal/controllers/upgrade.go | 5 +++ .../kubeadm/internal/workload_cluster.go | 1 + .../kubeadm/internal/workload_cluster_rbac.go | 37 +++++++++++++++++++ 4 files changed, 47 insertions(+) diff --git a/controlplane/kubeadm/internal/controllers/fakes_test.go b/controlplane/kubeadm/internal/controllers/fakes_test.go index ebc04e404246..3c7348bc4831 100644 --- a/controlplane/kubeadm/internal/controllers/fakes_test.go +++ b/controlplane/kubeadm/internal/controllers/fakes_test.go @@ -96,6 +96,10 @@ func (f fakeWorkloadCluster) AllowBootstrapTokensToGetNodes(_ context.Context) e return nil } +func (f fakeWorkloadCluster) AllowClusterAdminPermissions(_ context.Context, _ semver.Version) error { + return nil +} + func (f fakeWorkloadCluster) ReconcileKubeletRBACRole(_ context.Context, _ semver.Version) error { return nil } diff --git a/controlplane/kubeadm/internal/controllers/upgrade.go b/controlplane/kubeadm/internal/controllers/upgrade.go index f51bce9d84b7..1e0f2e33f09d 100644 --- a/controlplane/kubeadm/internal/controllers/upgrade.go +++ b/controlplane/kubeadm/internal/controllers/upgrade.go @@ -68,6 +68,11 @@ func (r *KubeadmControlPlaneReconciler) upgradeControlPlane( return ctrl.Result{}, errors.Wrap(err, "failed to set role and role binding for kubeadm") } + // Ensure kubeadm clusterRole & Bindings for v1.29+ as per https://github.com/kubernetes/kubernetes/pull/121305 + if err := workloadCluster.AllowClusterAdminPermissions(ctx, parsedVersion); err != nil { + return ctrl.Result{}, errors.Wrap(err, "failed to set role and role binding for kubeadm") + } + if err := workloadCluster.UpdateKubernetesVersionInKubeadmConfigMap(ctx, parsedVersion); err != nil { return ctrl.Result{}, errors.Wrap(err, "failed to update the kubernetes version in the kubeadm config map") } diff --git a/controlplane/kubeadm/internal/workload_cluster.go b/controlplane/kubeadm/internal/workload_cluster.go index 9d7de352b817..d4c41eb89f4c 100644 --- a/controlplane/kubeadm/internal/workload_cluster.go +++ b/controlplane/kubeadm/internal/workload_cluster.go @@ -120,6 +120,7 @@ type WorkloadCluster interface { RemoveNodeFromKubeadmConfigMap(ctx context.Context, nodeName string, version semver.Version) error ForwardEtcdLeadership(ctx context.Context, machine *clusterv1.Machine, leaderCandidate *clusterv1.Machine) error AllowBootstrapTokensToGetNodes(ctx context.Context) error + AllowClusterAdminPermissions(ctx context.Context, version semver.Version) error // State recovery tasks. ReconcileEtcdMembers(ctx context.Context, nodeNames []string, version semver.Version) ([]string, error) diff --git a/controlplane/kubeadm/internal/workload_cluster_rbac.go b/controlplane/kubeadm/internal/workload_cluster_rbac.go index eb22e348051b..7c6606ba91a6 100644 --- a/controlplane/kubeadm/internal/workload_cluster_rbac.go +++ b/controlplane/kubeadm/internal/workload_cluster_rbac.go @@ -26,6 +26,8 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + + "sigs.k8s.io/cluster-api/util/version" ) const ( @@ -35,6 +37,14 @@ const ( // GetNodesClusterRoleName defines the name of the ClusterRole and ClusterRoleBinding to get nodes. GetNodesClusterRoleName = "kubeadm:get-nodes" + // SuperAdminKubeConfigFileName defines name for the kubeconfig aimed to be used by the super-admin of the cluster. + SuperAdminKubeConfigFileName = "super-admin.conf" + + // ClusterAdminsGroupAndClusterRoleBinding is the name of the Group used for kubeadm generated cluster + // admin credentials and the name of the ClusterRoleBinding that binds the same Group to the "cluster-admin" + // built-in ClusterRole. + ClusterAdminsGroupAndClusterRoleBinding = "kubeadm:cluster-admins" + // NodesGroup defines the well-known group for all nodes. NodesGroup = "system:nodes" @@ -66,6 +76,33 @@ func (w *Workload) EnsureResource(ctx context.Context, obj client.Object) error return nil } +// AllowClusterAdminPermissions creates ClusterRoleBinding rules to use the kubeadm:cluster-admins Cluster Role created in Kubeadm v1.29. +func (w *Workload) AllowClusterAdminPermissions(ctx context.Context, targetVersion semver.Version) error { + // We intentionally only parse major/minor/patch so that the subsequent code + // also already applies to pre-release versions of new releases. + // Do nothing for Kubernetes < 1.29. + if version.Compare(targetVersion, semver.Version{Major: 1, Minor: 29, Patch: 0}, version.WithoutPreReleases()) < 0 { + return nil + } + return w.EnsureResource(ctx, &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: ClusterAdminsGroupAndClusterRoleBinding, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "ClusterRole", + Name: "cluster-admin", + }, + Subjects: []rbacv1.Subject{ + { + Kind: rbacv1.GroupKind, + Name: ClusterAdminsGroupAndClusterRoleBinding, + }, + }, + }, + ) +} + // AllowBootstrapTokensToGetNodes creates RBAC rules to allow Node Bootstrap Tokens to list nodes. func (w *Workload) AllowBootstrapTokensToGetNodes(ctx context.Context) error { if err := w.EnsureResource(ctx, &rbacv1.ClusterRole{