From 25357ee5b4e612db2a9e82a875f8f2b4fa27918e Mon Sep 17 00:00:00 2001 From: chaosi-zju Date: Fri, 20 Sep 2024 15:32:28 +0800 Subject: [PATCH] authorize system:admin to proxy member clusters during installation Signed-off-by: chaosi-zju --- operator/pkg/karmadaresource/rbac/manifest.go | 28 ++++++++++++++++ operator/pkg/karmadaresource/rbac/rbac.go | 33 +++++++++++++++---- operator/pkg/util/apiclient/idempotency.go | 26 +++++++++++++++ 3 files changed, 81 insertions(+), 6 deletions(-) diff --git a/operator/pkg/karmadaresource/rbac/manifest.go b/operator/pkg/karmadaresource/rbac/manifest.go index 66eff933c..4c25dca6c 100644 --- a/operator/pkg/karmadaresource/rbac/manifest.go +++ b/operator/pkg/karmadaresource/rbac/manifest.go @@ -166,5 +166,33 @@ rules: - deletecollection - patch - update +` + // ClusterProxyAdminClusterRole role to proxy member clusters + ClusterProxyAdminClusterRole = ` +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cluster-proxy-admin +rules: +- apiGroups: + - 'cluster.karmada.io' + resources: + - clusters/proxy + verbs: + - '*' +` + // ClusterProxyAdminClusterRoleBinding authorize system:admin to proxy member clusters + ClusterProxyAdminClusterRoleBinding = ` +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cluster-proxy-admin +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-proxy-admin +subjects: + - kind: User + name: "system:admin" ` ) diff --git a/operator/pkg/karmadaresource/rbac/rbac.go b/operator/pkg/karmadaresource/rbac/rbac.go index 2e82b382e..3ca2d1866 100644 --- a/operator/pkg/karmadaresource/rbac/rbac.go +++ b/operator/pkg/karmadaresource/rbac/rbac.go @@ -30,25 +30,46 @@ import ( // EnsureKarmadaRBAC create karmada resource view and edit clusterrole func EnsureKarmadaRBAC(client clientset.Interface) error { - if err := grantKarmadaResourceViewClusterrole(client); err != nil { + if err := grantClusterProxyAdminRBAC(client); err != nil { return err } - return grantKarmadaResourceEditClusterrole(client) + if err := grantKarmadaResourceViewClusterRole(client); err != nil { + return err + } + return grantKarmadaResourceEditClusterRole(client) } -func grantKarmadaResourceViewClusterrole(client clientset.Interface) error { +func grantClusterProxyAdminRBAC(client clientset.Interface) error { + role := &rbacv1.ClusterRole{} + if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(ClusterProxyAdminClusterRole), role); err != nil { + return fmt.Errorf("err when decoding ClusterProxyAdmin ClusterRole: %w", err) + } + util.MergeLabel(role, util.KarmadaSystemLabel, util.KarmadaSystemLabelValue) + if err := apiclient.CreateOrUpdateClusterRole(client, role); err != nil { + return fmt.Errorf("failed to create or update ClusterRole: %w", err) + } + + roleBinding := &rbacv1.ClusterRoleBinding{} + if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(ClusterProxyAdminClusterRoleBinding), roleBinding); err != nil { + return fmt.Errorf("err when decoding ClusterProxyAdmin ClusterRoleBinding: %w", err) + } + util.MergeLabel(role, util.KarmadaSystemLabel, util.KarmadaSystemLabelValue) + return apiclient.CreateOrUpdateClusterRoleBinding(client, roleBinding) +} + +func grantKarmadaResourceViewClusterRole(client clientset.Interface) error { role := &rbacv1.ClusterRole{} if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(KarmadaResourceViewClusterRole), role); err != nil { - return fmt.Errorf("err when decoding Karmada view Clusterrole: %w", err) + return fmt.Errorf("err when decoding Karmada view ClusterRole: %w", err) } util.MergeLabel(role, util.KarmadaSystemLabel, util.KarmadaSystemLabelValue) return apiclient.CreateOrUpdateClusterRole(client, role) } -func grantKarmadaResourceEditClusterrole(client clientset.Interface) error { +func grantKarmadaResourceEditClusterRole(client clientset.Interface) error { role := &rbacv1.ClusterRole{} if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(KarmadaResourceEditClusterRole), role); err != nil { - return fmt.Errorf("err when decoding Karmada edit Clusterrole: %w", err) + return fmt.Errorf("err when decoding Karmada edit ClusterRole: %w", err) } util.MergeLabel(role, util.KarmadaSystemLabel, util.KarmadaSystemLabelValue) return apiclient.CreateOrUpdateClusterRole(client, role) diff --git a/operator/pkg/util/apiclient/idempotency.go b/operator/pkg/util/apiclient/idempotency.go index 81f28a6ca..f95e9a191 100644 --- a/operator/pkg/util/apiclient/idempotency.go +++ b/operator/pkg/util/apiclient/idempotency.go @@ -281,6 +281,32 @@ func CreateOrUpdateClusterRole(client clientset.Interface, clusterrole *rbacv1.C return nil } +// CreateOrUpdateClusterRoleBinding creates a Clusterrolebinding if the target resource doesn't exist. +// If the resource exists already, this function will update the resource instead. +func CreateOrUpdateClusterRoleBinding(client clientset.Interface, clusterrolebinding *rbacv1.ClusterRoleBinding) error { + _, err := client.RbacV1().ClusterRoleBindings().Create(context.TODO(), clusterrolebinding, metav1.CreateOptions{}) + + if err != nil { + if !apierrors.IsAlreadyExists(err) { + return err + } + + older, err := client.RbacV1().ClusterRoleBindings().Get(context.TODO(), clusterrolebinding.GetName(), metav1.GetOptions{}) + if err != nil { + return err + } + + clusterrolebinding.ResourceVersion = older.ResourceVersion + _, err = client.RbacV1().ClusterRoleBindings().Update(context.TODO(), clusterrolebinding, metav1.UpdateOptions{}) + if err != nil { + return err + } + } + + klog.V(4).InfoS("Successfully created or updated clusterrolebinding", "clusterrolebinding", clusterrolebinding.GetName()) + return nil +} + // DeleteDeploymentIfHasLabels deletes a Deployment that exists the given labels. func DeleteDeploymentIfHasLabels(client clientset.Interface, name, namespace string, ls labels.Set) error { deployment, err := client.AppsV1().Deployments(namespace).Get(context.TODO(), name, metav1.GetOptions{})