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 } // CreateOrUpdateRole creates a Role if the target resource doesn't exist. If the resource exists already, this function will update the resource instead. func CreateOrUpdateRole(clientSet *kubernetes.Clientset, role *rbacv1.Role) error { if _, err := clientSet.RbacV1().Roles(role.ObjectMeta.Namespace).Create(context.TODO(), role, metav1.CreateOptions{}); err != nil { if !apierrors.IsAlreadyExists(err) { return fmt.Errorf("unable to create RBAC role: %v", err) } if _, err := clientSet.RbacV1().Roles(role.ObjectMeta.Namespace).Update(context.TODO(), role, metav1.UpdateOptions{}); err != nil { return fmt.Errorf("unable to update RBAC role: %v", err) } } klog.Infof("Role %s%s has been created or updated.", role.ObjectMeta.Namespace, role.ObjectMeta.Name) return nil } // CreateOrUpdateRoleBinding creates a RoleBinding if the target resource doesn't exist. If the resource exists already, this function will update the resource instead. func CreateOrUpdateRoleBinding(clientSet *kubernetes.Clientset, roleBinding *rbacv1.RoleBinding) error { if _, err := clientSet.RbacV1().RoleBindings(roleBinding.ObjectMeta.Namespace).Create(context.TODO(), roleBinding, metav1.CreateOptions{}); err != nil { if !apierrors.IsAlreadyExists(err) { return fmt.Errorf("unable to create RBAC rolebinding: %v", err) } if _, err := clientSet.RbacV1().RoleBindings(roleBinding.ObjectMeta.Namespace).Update(context.TODO(), roleBinding, metav1.UpdateOptions{}); err != nil { return fmt.Errorf("unable to update RBAC rolebinding: %v", err) } } klog.Infof("RoleBinding %s/%s has been created or updated.", roleBinding.ObjectMeta.Namespace, roleBinding.ObjectMeta.Name) return nil }