Merge pull request #1550 from AllenZMC/karmadactl

karmadactl init: add cluster proxy rbac for admin when deploy Karmada  control plane
This commit is contained in:
karmada-bot 2022-03-31 19:41:02 +08:00 committed by GitHub
commit 9cbe962748
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 160 additions and 90 deletions

View File

@ -26,8 +26,13 @@ import (
"github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils"
)
const (
clusterProxyAdminRole = "cluster-proxy-admin"
clusterProxyAdminUser = "system:admin"
)
// InitKarmadaResources Initialize karmada resource
func InitKarmadaResources(dir, caBase64 string, systemNamespace string) error {
func InitKarmadaResources(dir, caBase64, systemNamespace string) error {
restConfig, err := utils.RestConfig(filepath.Join(dir, options.KarmadaKubeConfigName))
if err != nil {
return err
@ -93,6 +98,11 @@ func InitKarmadaResources(dir, caBase64 string, systemNamespace string) error {
klog.Exitln(err)
}
// grant proxy permission to "system:admin".
if err := grantProxyPermissionToAdmin(clientSet); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,36 @@
package karmada
import (
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/client-go/kubernetes"
"github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils"
)
// grantProxyPermissionToAdmin grants the proxy permission to "system:admin"
func grantProxyPermissionToAdmin(clientSet *kubernetes.Clientset) error {
proxyAdminClusterRole := utils.ClusterRoleFromRules(clusterProxyAdminRole, []rbacv1.PolicyRule{
{
APIGroups: []string{"cluster.karmada.io"},
Resources: []string{"clusters/proxy"},
Verbs: []string{"*"},
},
}, nil)
err := utils.CreateIfNotExistClusterRole(clientSet, proxyAdminClusterRole)
if err != nil {
return err
}
proxyAdminClusterRoleBinding := utils.ClusterRoleBindingFromSubjects(clusterProxyAdminRole, clusterProxyAdminRole,
[]rbacv1.Subject{
{
Kind: "User",
Name: clusterProxyAdminUser,
}}, nil)
err = utils.CreateIfNotExistClusterRoleBinding(clientSet, proxyAdminClusterRoleBinding)
if err != nil {
return err
}
return nil
}

View File

@ -418,8 +418,8 @@ func (i *CommandInitOption) RunInit(_ io.Writer, parentCommand string) error {
}
// Create karmada-controller-manager ClusterRole and ClusterRoleBinding
if err := i.CreateClusterRole(); err != nil {
klog.Exitln(err)
if err := i.CreateControllerManagerRBAC(); err != nil {
return err
}
// Create Secrets

View File

@ -36,6 +36,8 @@ const (
webhookTargetPort = 8443
webhookPort = 443
karmadaAggregatedAPIServerDeploymentAndServiceName = "karmada-aggregated-apiserver"
karmadaBootstrappingLabelKey = "karmada.io/bootstrapping"
karmadaBootstrappingLabelValue = "rbac-defaults"
)
var (

View File

@ -1,60 +1,16 @@
package kubernetes
import (
"context"
"fmt"
"github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
)
// ClusterRoleFromSpec ClusterRole spec
func (i *CommandInitOption) ClusterRoleFromSpec(name string, rules []rbacv1.PolicyRule) *rbacv1.ClusterRole {
return &rbacv1.ClusterRole{
TypeMeta: metav1.TypeMeta{
APIVersion: "rbac.authorization.k8s.io/v1",
Kind: "ClusterRole",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: i.Namespace,
Labels: map[string]string{"karmada.io/bootstrapping": "rbac-defaults"},
},
Rules: rules,
}
}
// ClusterRoleBindingFromSpec ClusterRoleBinding spec
func (i *CommandInitOption) ClusterRoleBindingFromSpec(clusterRoleBindingName, clusterRoleName, saName string) *rbacv1.ClusterRoleBinding {
return &rbacv1.ClusterRoleBinding{
TypeMeta: metav1.TypeMeta{
APIVersion: "rbac.authorization.k8s.io/v1",
Kind: "ClusterRoleBinding",
},
ObjectMeta: metav1.ObjectMeta{
Name: clusterRoleBindingName,
Namespace: i.Namespace,
Labels: map[string]string{"karmada.io/bootstrapping": "rbac-defaults"},
},
RoleRef: rbacv1.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "ClusterRole",
Name: clusterRoleName,
},
Subjects: []rbacv1.Subject{
{
Kind: "ServiceAccount",
Name: saName,
Namespace: i.Namespace,
},
},
}
}
// CreateClusterRole receive ClusterRoleFromSpec ClusterRole
func (i *CommandInitOption) CreateClusterRole() error {
clusterRole := i.ClusterRoleFromSpec(kubeControllerManagerClusterRoleAndDeploymentAndServiceName, []rbacv1.PolicyRule{
// CreateControllerManagerRBAC karmada-controller-manager ClusterRole and ClusterRoleBinding
func (i *CommandInitOption) CreateControllerManagerRBAC() error {
labels := map[string]string{karmadaBootstrappingLabelKey: karmadaBootstrappingLabelValue}
// ClusterRole
clusterRole := utils.ClusterRoleFromRules(controllerManagerDeploymentAndServiceName, []rbacv1.PolicyRule{
{
APIGroups: []string{"*"},
Resources: []string{"*"},
@ -64,48 +20,25 @@ func (i *CommandInitOption) CreateClusterRole() error {
NonResourceURLs: []string{"*"},
Verbs: []string{"get"},
},
})
clusterRoleClient := i.KubeClientSet.RbacV1().ClusterRoles()
clusterRoleList, err := clusterRoleClient.List(context.TODO(), metav1.ListOptions{})
}, labels)
err := utils.CreateIfNotExistClusterRole(i.KubeClientSet, clusterRole)
if err != nil {
return err
}
for _, v := range clusterRoleList.Items {
if clusterRole.Name == v.Name {
klog.Warningf("ClusterRole %s already exists.", clusterRole.Name)
return nil
}
// ClusterRoleBinding
clusterRoleBinding := utils.ClusterRoleBindingFromSubjects(controllerManagerDeploymentAndServiceName, controllerManagerDeploymentAndServiceName,
[]rbacv1.Subject{
{
Kind: "ServiceAccount",
Name: controllerManagerDeploymentAndServiceName,
Namespace: i.Namespace,
},
}, labels)
err = utils.CreateIfNotExistClusterRoleBinding(i.KubeClientSet, clusterRoleBinding)
if err != nil {
return err
}
_, err = clusterRoleClient.Create(context.TODO(), clusterRole, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("create ClusterRole %s failed: %v", clusterRole.Name, err)
}
return nil
}
// CreateClusterRoleBinding receive ClusterRoleBindingFromSpec ClusterRoleBinding
func (i *CommandInitOption) CreateClusterRoleBinding(clusterRole *rbacv1.ClusterRoleBinding) error {
crbClient := i.KubeClientSet.RbacV1().ClusterRoleBindings()
crbList, err := crbClient.List(context.TODO(), metav1.ListOptions{})
if err != nil {
return err
}
for _, v := range crbList.Items {
if clusterRole.Name == v.Name {
klog.Infof("CreateClusterRoleBinding %s already exists.", clusterRole.Name)
return nil
}
}
_, err = crbClient.Create(context.TODO(), clusterRole, metav1.CreateOptions{})
if err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,89 @@
package utils
import (
"context"
"fmt"
rbacv1 "k8s.io/api/rbac/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
// ClusterRoleFromRules ClusterRole Rules
func ClusterRoleFromRules(name string, rules []rbacv1.PolicyRule, labels map[string]string) *rbacv1.ClusterRole {
return &rbacv1.ClusterRole{
TypeMeta: metav1.TypeMeta{
APIVersion: "rbac.authorization.k8s.io/v1",
Kind: "ClusterRole",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: labels,
},
Rules: rules,
}
}
// ClusterRoleBindingFromSubjects ClusterRoleBinding Subjects
func ClusterRoleBindingFromSubjects(clusterRoleBindingName, clusterRoleName string, sub []rbacv1.Subject, labels map[string]string) *rbacv1.ClusterRoleBinding {
return &rbacv1.ClusterRoleBinding{
TypeMeta: metav1.TypeMeta{
APIVersion: "rbac.authorization.k8s.io/v1",
Kind: "ClusterRoleBinding",
},
ObjectMeta: metav1.ObjectMeta{
Name: clusterRoleBindingName,
Labels: labels,
},
RoleRef: rbacv1.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "ClusterRole",
Name: clusterRoleName,
},
Subjects: sub,
}
}
// CreateIfNotExistClusterRole create ClusterRole when it doesn't exist
func CreateIfNotExistClusterRole(clientSet *kubernetes.Clientset, role *rbacv1.ClusterRole) error {
clusterRoleClient := clientSet.RbacV1().ClusterRoles()
_, err := clusterRoleClient.Get(context.TODO(), role.Name, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
_, err = clusterRoleClient.Create(context.TODO(), role, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("create ClusterRole %s failed: %v", role.Name, err)
}
klog.Infof("CreateClusterRole %s success.", role.Name)
return nil
}
return fmt.Errorf("get ClusterRole %s failed: %v", role.Name, err)
}
klog.Infof("CreateClusterRole %s already exists.", role.Name)
return nil
}
// CreateIfNotExistClusterRoleBinding create ClusterRoleBinding when it doesn't exist
func CreateIfNotExistClusterRoleBinding(clientSet *kubernetes.Clientset, binding *rbacv1.ClusterRoleBinding) error {
crbClient := clientSet.RbacV1().ClusterRoleBindings()
_, err := crbClient.Get(context.TODO(), binding.Name, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
_, err = crbClient.Create(context.TODO(), binding, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("create ClusterRoleBinding %s failed: %v", binding.Name, err)
}
klog.Infof("CreateClusterRoleBinding %s success.", binding.Name)
return nil
}
return fmt.Errorf("get ClusterRoleBinding %s failed: %v", binding.Name, err)
}
klog.Infof("CreateClusterRoleBinding %s already exists.", binding.Name)
return nil
}