1. Remove ks-iam standalone binary, move it to ks-apiserver 2. Generate all devops apis inside kubesphere repository, no need to import s2ioperator. 3. Reorganize ldap code, make it more flexible to use.
607 lines
20 KiB
Go
607 lines
20 KiB
Go
/*
|
|
|
|
Copyright 2019 The KubeSphere Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
*/
|
|
package iam
|
|
|
|
import (
|
|
rbacv1 "k8s.io/api/rbac/v1"
|
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/labels"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"k8s.io/client-go/informers"
|
|
"k8s.io/client-go/kubernetes"
|
|
"k8s.io/klog"
|
|
"kubesphere.io/kubesphere/pkg/constants"
|
|
"kubesphere.io/kubesphere/pkg/models"
|
|
"kubesphere.io/kubesphere/pkg/models/iam/policy"
|
|
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
|
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/clusterrole"
|
|
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/resource"
|
|
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/role"
|
|
"kubesphere.io/kubesphere/pkg/server/params"
|
|
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
|
|
)
|
|
|
|
const (
|
|
ClusterRoleKind = "ClusterRole"
|
|
NamespaceAdminRoleBindName = "admin"
|
|
NamespaceViewerRoleBindName = "viewer"
|
|
)
|
|
|
|
type AccessManagementInterface interface {
|
|
GetClusterRole(username string) (*rbacv1.ClusterRole, error)
|
|
UnBindAllRoles(username string) error
|
|
ListRoleBindings(namespace string, role string) ([]*rbacv1.RoleBinding, error)
|
|
CreateClusterRoleBinding(username string, clusterRole string) error
|
|
ListRoles(namespace string, conditions *params.Conditions, orderBy string, reverse bool, limit int, offset int) (*models.PageableResponse, error)
|
|
ListClusterRoles(conditions *params.Conditions, orderBy string, reverse bool, limit int, offset int) (*models.PageableResponse, error)
|
|
ListClusterRoleBindings(clusterRole string) ([]*rbacv1.ClusterRoleBinding, error)
|
|
GetClusterRoleSimpleRules(clusterRole string) ([]policy.SimpleRule, error)
|
|
GetRoleSimpleRules(namespace string, role string) ([]policy.SimpleRule, error)
|
|
GetRoles(namespace, username string) ([]*rbacv1.Role, error)
|
|
GetClusterPolicyRules(username string) ([]rbacv1.PolicyRule, error)
|
|
GetPolicyRules(namespace, username string) ([]rbacv1.PolicyRule, error)
|
|
GetWorkspaceRoleSimpleRules(workspace, roleName string) []policy.SimpleRule
|
|
GetWorkspaceRole(workspace, username string) (*rbacv1.ClusterRole, error)
|
|
GetWorkspaceRoleMap(username string) (map[string]string, error)
|
|
}
|
|
|
|
type amOperator struct {
|
|
informers informers.SharedInformerFactory
|
|
resources resource.ResourceGetter
|
|
kubeClient kubernetes.Interface
|
|
}
|
|
|
|
func (am *amOperator) ListClusterRoleBindings(clusterRole string) ([]*rbacv1.ClusterRoleBinding, error) {
|
|
panic("implement me")
|
|
}
|
|
|
|
func (am *amOperator) GetRoles(namespace, username string) ([]*rbacv1.Role, error) {
|
|
panic("implement me")
|
|
}
|
|
|
|
func (am *amOperator) GetClusterPolicyRules(username string) ([]rbacv1.PolicyRule, error) {
|
|
panic("implement me")
|
|
}
|
|
|
|
func (am *amOperator) GetPolicyRules(namespace, username string) ([]rbacv1.PolicyRule, error) {
|
|
panic("implement me")
|
|
}
|
|
|
|
func (am *amOperator) GetWorkspaceRole(workspace, username string) (*rbacv1.ClusterRole, error) {
|
|
panic("implement me")
|
|
}
|
|
|
|
func (am *amOperator) UnBindAllRoles(username string) error {
|
|
panic("implement me")
|
|
}
|
|
|
|
func NewAMOperator(kubeClient kubernetes.Interface, informers informers.SharedInformerFactory) *amOperator {
|
|
resourceGetter := resource.ResourceGetter{}
|
|
resourceGetter.Add(v1alpha2.Role, role.NewRoleSearcher(informers))
|
|
resourceGetter.Add(v1alpha2.ClusterRoles, clusterrole.NewClusterRoleSearcher(informers))
|
|
return &amOperator{
|
|
informers: informers,
|
|
resources: resourceGetter,
|
|
kubeClient: kubeClient,
|
|
}
|
|
}
|
|
|
|
func (am *amOperator) GetDevopsRoleSimpleRules(role string) []policy.SimpleRule {
|
|
var rules []policy.SimpleRule
|
|
|
|
switch role {
|
|
case "developer":
|
|
rules = []policy.SimpleRule{
|
|
{Name: "pipelines", Actions: []string{"view", "trigger"}},
|
|
{Name: "roles", Actions: []string{"view"}},
|
|
{Name: "members", Actions: []string{"view"}},
|
|
{Name: "devops", Actions: []string{"view"}},
|
|
}
|
|
break
|
|
case "owner":
|
|
rules = []policy.SimpleRule{
|
|
{Name: "pipelines", Actions: []string{"create", "edit", "view", "delete", "trigger"}},
|
|
{Name: "roles", Actions: []string{"view"}},
|
|
{Name: "members", Actions: []string{"create", "edit", "view", "delete"}},
|
|
{Name: "credentials", Actions: []string{"create", "edit", "view", "delete"}},
|
|
{Name: "devops", Actions: []string{"edit", "view", "delete"}},
|
|
}
|
|
break
|
|
case "maintainer":
|
|
rules = []policy.SimpleRule{
|
|
{Name: "pipelines", Actions: []string{"create", "edit", "view", "delete", "trigger"}},
|
|
{Name: "roles", Actions: []string{"view"}},
|
|
{Name: "members", Actions: []string{"view"}},
|
|
{Name: "credentials", Actions: []string{"create", "edit", "view", "delete"}},
|
|
{Name: "devops", Actions: []string{"view"}},
|
|
}
|
|
break
|
|
case "reporter":
|
|
fallthrough
|
|
default:
|
|
rules = []policy.SimpleRule{
|
|
{Name: "pipelines", Actions: []string{"view"}},
|
|
{Name: "roles", Actions: []string{"view"}},
|
|
{Name: "members", Actions: []string{"view"}},
|
|
{Name: "devops", Actions: []string{"view"}},
|
|
}
|
|
break
|
|
}
|
|
return rules
|
|
}
|
|
|
|
// Get user roles in namespace
|
|
func (am *amOperator) GetUserRoles(namespace, username string) ([]*rbacv1.Role, error) {
|
|
clusterRoleLister := am.informers.Rbac().V1().ClusterRoles().Lister()
|
|
roleBindingLister := am.informers.Rbac().V1().RoleBindings().Lister()
|
|
roleLister := am.informers.Rbac().V1().Roles().Lister()
|
|
roleBindings, err := roleBindingLister.RoleBindings(namespace).List(labels.Everything())
|
|
|
|
if err != nil {
|
|
klog.Errorln(err)
|
|
return nil, err
|
|
}
|
|
|
|
roles := make([]*rbacv1.Role, 0)
|
|
|
|
for _, roleBinding := range roleBindings {
|
|
if ContainsUser(roleBinding.Subjects, username) {
|
|
if roleBinding.RoleRef.Kind == ClusterRoleKind {
|
|
clusterRole, err := clusterRoleLister.Get(roleBinding.RoleRef.Name)
|
|
if err != nil {
|
|
if apierrors.IsNotFound(err) {
|
|
klog.Warningf("cluster role %s not found but bind user %s in namespace %s", roleBinding.RoleRef.Name, username, namespace)
|
|
continue
|
|
} else {
|
|
klog.Errorln(err)
|
|
return nil, err
|
|
}
|
|
}
|
|
role := rbacv1.Role{}
|
|
role.TypeMeta = clusterRole.TypeMeta
|
|
role.ObjectMeta = clusterRole.ObjectMeta
|
|
role.Rules = clusterRole.Rules
|
|
role.Namespace = roleBinding.Namespace
|
|
roles = append(roles, &role)
|
|
} else {
|
|
role, err := roleLister.Roles(roleBinding.Namespace).Get(roleBinding.RoleRef.Name)
|
|
|
|
if err != nil {
|
|
if apierrors.IsNotFound(err) {
|
|
klog.Warningf("namespace %s role %s not found, but bind user %s", namespace, roleBinding.RoleRef.Name, username)
|
|
continue
|
|
} else {
|
|
klog.Errorln(err)
|
|
return nil, err
|
|
}
|
|
}
|
|
roles = append(roles, role)
|
|
}
|
|
}
|
|
}
|
|
|
|
return roles, nil
|
|
}
|
|
|
|
func (am *amOperator) GetUserClusterRoles(username string) (*rbacv1.ClusterRole, []*rbacv1.ClusterRole, error) {
|
|
clusterRoleLister := am.informers.Rbac().V1().ClusterRoles().Lister()
|
|
clusterRoleBindingLister := am.informers.Rbac().V1().ClusterRoleBindings().Lister()
|
|
clusterRoleBindings, err := clusterRoleBindingLister.List(labels.Everything())
|
|
|
|
if err != nil {
|
|
klog.Errorln(err)
|
|
return nil, nil, err
|
|
}
|
|
|
|
clusterRoles := make([]*rbacv1.ClusterRole, 0)
|
|
userFacingClusterRole := &rbacv1.ClusterRole{}
|
|
for _, clusterRoleBinding := range clusterRoleBindings {
|
|
if ContainsUser(clusterRoleBinding.Subjects, username) {
|
|
clusterRole, err := clusterRoleLister.Get(clusterRoleBinding.RoleRef.Name)
|
|
if err != nil {
|
|
if apierrors.IsNotFound(err) {
|
|
klog.Warningf("cluster role %s not found but bind user %s", clusterRoleBinding.RoleRef.Name, username)
|
|
continue
|
|
} else {
|
|
klog.Errorln(err)
|
|
return nil, nil, err
|
|
}
|
|
}
|
|
if clusterRoleBinding.Name == username {
|
|
userFacingClusterRole = clusterRole
|
|
}
|
|
clusterRoles = append(clusterRoles, clusterRole)
|
|
}
|
|
}
|
|
|
|
return userFacingClusterRole, clusterRoles, nil
|
|
}
|
|
|
|
func (am *amOperator) GetClusterRole(username string) (*rbacv1.ClusterRole, error) {
|
|
userFacingClusterRole, _, err := am.GetUserClusterRoles(username)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return userFacingClusterRole, nil
|
|
}
|
|
|
|
func (am *amOperator) GetUserClusterRules(username string) ([]rbacv1.PolicyRule, error) {
|
|
_, clusterRoles, err := am.GetUserClusterRoles(username)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rules := make([]rbacv1.PolicyRule, 0)
|
|
for _, clusterRole := range clusterRoles {
|
|
rules = append(rules, clusterRole.Rules...)
|
|
}
|
|
|
|
return rules, nil
|
|
}
|
|
|
|
func (am *amOperator) GetUserRules(namespace, username string) ([]rbacv1.PolicyRule, error) {
|
|
roles, err := am.GetUserRoles(namespace, username)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rules := make([]rbacv1.PolicyRule, 0)
|
|
for _, role := range roles {
|
|
rules = append(rules, role.Rules...)
|
|
}
|
|
|
|
return rules, nil
|
|
}
|
|
|
|
func (am *amOperator) GetWorkspaceRoleBindings(workspace string) ([]*rbacv1.ClusterRoleBinding, error) {
|
|
|
|
clusterRoleBindings, err := am.informers.Rbac().V1().ClusterRoleBindings().Lister().List(labels.Everything())
|
|
|
|
if err != nil {
|
|
klog.Errorln("get cluster role bindings", err)
|
|
return nil, err
|
|
}
|
|
|
|
result := make([]*rbacv1.ClusterRoleBinding, 0)
|
|
|
|
for _, roleBinding := range clusterRoleBindings {
|
|
if k8sutil.IsControlledBy(roleBinding.OwnerReferences, "Workspace", workspace) {
|
|
result = append(result, roleBinding)
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
//func (am *amOperator) GetWorkspaceRole(workspace, role string) (*rbacv1.ClusterRole, error) {
|
|
// if !sliceutil.HasString(constants.WorkSpaceRoles, role) {
|
|
// return nil, apierrors.NewNotFound(schema.GroupResource{Resource: "workspace role"}, role)
|
|
// }
|
|
// role = fmt.Sprintf("workspace:%s:%s", workspace, strings.TrimPrefix(role, "workspace-"))
|
|
// return am.informers.Rbac().V1().ClusterRoles().Lister().Get(role)
|
|
//}
|
|
|
|
func (am *amOperator) GetWorkspaceRoleMap(username string) (map[string]string, error) {
|
|
|
|
clusterRoleBindings, err := am.informers.Rbac().V1().ClusterRoleBindings().Lister().List(labels.Everything())
|
|
|
|
if err != nil {
|
|
klog.Errorln("get cluster role bindings", err)
|
|
return nil, err
|
|
}
|
|
|
|
result := make(map[string]string, 0)
|
|
|
|
for _, roleBinding := range clusterRoleBindings {
|
|
if workspace := k8sutil.GetControlledWorkspace(roleBinding.OwnerReferences); workspace != "" &&
|
|
ContainsUser(roleBinding.Subjects, username) {
|
|
result[workspace] = roleBinding.RoleRef.Name
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func (am *amOperator) GetUserWorkspaceRole(workspace, username string) (*rbacv1.ClusterRole, error) {
|
|
workspaceRoleMap, err := am.GetWorkspaceRoleMap(username)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if workspaceRole := workspaceRoleMap[workspace]; workspaceRole != "" {
|
|
return am.informers.Rbac().V1().ClusterRoles().Lister().Get(workspaceRole)
|
|
}
|
|
|
|
return nil, apierrors.NewNotFound(schema.GroupResource{Resource: "workspace user"}, username)
|
|
}
|
|
|
|
func (am *amOperator) GetRoleBindings(namespace string, roleName string) ([]*rbacv1.RoleBinding, error) {
|
|
roleBindingLister := am.informers.Rbac().V1().RoleBindings().Lister()
|
|
roleBindings, err := roleBindingLister.RoleBindings(namespace).List(labels.Everything())
|
|
|
|
if err != nil {
|
|
klog.Errorln(err)
|
|
return nil, err
|
|
}
|
|
|
|
items := make([]*rbacv1.RoleBinding, 0)
|
|
|
|
for _, roleBinding := range roleBindings {
|
|
if roleName == "" {
|
|
items = append(items, roleBinding)
|
|
} else if roleBinding.RoleRef.Name == roleName {
|
|
items = append(items, roleBinding)
|
|
}
|
|
}
|
|
|
|
return items, nil
|
|
}
|
|
|
|
func (am *amOperator) GetClusterRoleBindings(clusterRoleName string) ([]*rbacv1.ClusterRoleBinding, error) {
|
|
clusterRoleBindingLister := am.informers.Rbac().V1().ClusterRoleBindings().Lister()
|
|
roleBindings, err := clusterRoleBindingLister.List(labels.Everything())
|
|
|
|
if err != nil {
|
|
klog.Errorln(err)
|
|
return nil, err
|
|
}
|
|
|
|
items := make([]*rbacv1.ClusterRoleBinding, 0)
|
|
|
|
for _, roleBinding := range roleBindings {
|
|
if roleBinding.RoleRef.Name == clusterRoleName {
|
|
items = append(items, roleBinding)
|
|
}
|
|
}
|
|
|
|
return items, nil
|
|
}
|
|
|
|
func (am *amOperator) ListRoles(namespace string, conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error) {
|
|
return am.resources.ListResources(namespace, v1alpha2.Roles, conditions, orderBy, reverse, limit, offset)
|
|
}
|
|
|
|
func (am *amOperator) ListRoleBindings(namespace string, role string) ([]*rbacv1.RoleBinding, error) {
|
|
rbs, err := am.informers.Rbac().V1().RoleBindings().Lister().RoleBindings(namespace).List(labels.Everything())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result := make([]*rbacv1.RoleBinding, 0)
|
|
for _, rb := range rbs {
|
|
if rb.RoleRef.Name == role {
|
|
result = append(result, rb.DeepCopy())
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (am *amOperator) ListWorkspaceRoles(workspace string, conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error) {
|
|
conditions.Match[v1alpha2.OwnerName] = workspace
|
|
conditions.Match[v1alpha2.OwnerKind] = "Workspace"
|
|
result, err := am.resources.ListResources("", v1alpha2.ClusterRoles, conditions, orderBy, reverse, limit, offset)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for i, item := range result.Items {
|
|
if role, ok := item.(*rbacv1.ClusterRole); ok {
|
|
role = role.DeepCopy()
|
|
role.Name = role.Annotations[constants.DisplayNameAnnotationKey]
|
|
result.Items[i] = role
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (am *amOperator) ListClusterRoles(conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error) {
|
|
return am.resources.ListResources("", v1alpha2.ClusterRoles, conditions, orderBy, reverse, limit, offset)
|
|
}
|
|
|
|
func (am *amOperator) GetWorkspaceRoleSimpleRules(workspace, roleName string) []policy.SimpleRule {
|
|
|
|
workspaceRules := make([]policy.SimpleRule, 0)
|
|
|
|
switch roleName {
|
|
case constants.WorkspaceAdmin:
|
|
workspaceRules = []policy.SimpleRule{
|
|
{Name: "workspaces", Actions: []string{"edit", "delete", "view"}},
|
|
{Name: "members", Actions: []string{"edit", "delete", "create", "view"}},
|
|
{Name: "devops", Actions: []string{"edit", "delete", "create", "view"}},
|
|
{Name: "projects", Actions: []string{"edit", "delete", "create", "view"}},
|
|
{Name: "roles", Actions: []string{"view"}},
|
|
{Name: "apps", Actions: []string{"view", "create", "manage"}},
|
|
{Name: "repos", Actions: []string{"view", "manage"}},
|
|
}
|
|
case constants.WorkspaceRegular:
|
|
workspaceRules = []policy.SimpleRule{
|
|
{Name: "members", Actions: []string{"view"}},
|
|
{Name: "devops", Actions: []string{"view", "create"}},
|
|
{Name: "projects", Actions: []string{"view", "create"}},
|
|
{Name: "apps", Actions: []string{"view", "create"}},
|
|
{Name: "repos", Actions: []string{"view"}},
|
|
}
|
|
case constants.WorkspaceViewer:
|
|
workspaceRules = []policy.SimpleRule{
|
|
{Name: "workspaces", Actions: []string{"view"}},
|
|
{Name: "members", Actions: []string{"view"}},
|
|
{Name: "devops", Actions: []string{"view"}},
|
|
{Name: "projects", Actions: []string{"view"}},
|
|
{Name: "roles", Actions: []string{"view"}},
|
|
{Name: "apps", Actions: []string{"view"}},
|
|
{Name: "repos", Actions: []string{"view"}},
|
|
}
|
|
case constants.WorkspacesManager:
|
|
workspaceRules = []policy.SimpleRule{
|
|
{Name: "workspaces", Actions: []string{"edit", "delete", "view"}},
|
|
{Name: "members", Actions: []string{"edit", "delete", "create", "view"}},
|
|
{Name: "roles", Actions: []string{"view"}},
|
|
}
|
|
}
|
|
|
|
return workspaceRules
|
|
}
|
|
|
|
// Convert cluster role to rules
|
|
func (am *amOperator) GetClusterRoleSimpleRules(clusterRoleName string) ([]policy.SimpleRule, error) {
|
|
|
|
clusterRoleLister := am.informers.Rbac().V1().ClusterRoles().Lister()
|
|
clusterRole, err := clusterRoleLister.Get(clusterRoleName)
|
|
|
|
if err != nil {
|
|
klog.Errorln(err)
|
|
return nil, err
|
|
}
|
|
|
|
return getClusterSimpleRule(clusterRole.Rules), nil
|
|
}
|
|
|
|
func (am *amOperator) GetUserClusterSimpleRules(username string) ([]policy.SimpleRule, error) {
|
|
clusterRules, err := am.GetUserClusterRules(username)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return getClusterSimpleRule(clusterRules), nil
|
|
}
|
|
|
|
// Convert roles to rules
|
|
func (am *amOperator) GetRoleSimpleRules(namespace string, roleName string) ([]policy.SimpleRule, error) {
|
|
|
|
roleLister := am.informers.Rbac().V1().Roles().Lister()
|
|
role, err := roleLister.Roles(namespace).Get(roleName)
|
|
|
|
if err != nil {
|
|
klog.Errorln(err)
|
|
return nil, err
|
|
}
|
|
|
|
return ConvertToSimpleRule(role.Rules), nil
|
|
}
|
|
|
|
func getClusterSimpleRule(policyRules []rbacv1.PolicyRule) []policy.SimpleRule {
|
|
rules := make([]policy.SimpleRule, 0)
|
|
|
|
for i := 0; i < len(policy.ClusterRoleRuleMapping); i++ {
|
|
validActions := make([]string, 0)
|
|
for j := 0; j < (len(policy.ClusterRoleRuleMapping[i].Actions)); j++ {
|
|
if rulesMatchesAction(policyRules, policy.ClusterRoleRuleMapping[i].Actions[j]) {
|
|
validActions = append(validActions, policy.ClusterRoleRuleMapping[i].Actions[j].Name)
|
|
}
|
|
}
|
|
if len(validActions) > 0 {
|
|
rules = append(rules, policy.SimpleRule{Name: policy.ClusterRoleRuleMapping[i].Name, Actions: validActions})
|
|
}
|
|
}
|
|
|
|
return rules
|
|
}
|
|
|
|
func ConvertToSimpleRule(policyRules []rbacv1.PolicyRule) []policy.SimpleRule {
|
|
simpleRules := make([]policy.SimpleRule, 0)
|
|
for i := 0; i < len(policy.RoleRuleMapping); i++ {
|
|
rule := policy.SimpleRule{Name: policy.RoleRuleMapping[i].Name}
|
|
rule.Actions = make([]string, 0)
|
|
for j := 0; j < len(policy.RoleRuleMapping[i].Actions); j++ {
|
|
if rulesMatchesAction(policyRules, policy.RoleRuleMapping[i].Actions[j]) {
|
|
rule.Actions = append(rule.Actions, policy.RoleRuleMapping[i].Actions[j].Name)
|
|
}
|
|
}
|
|
if len(rule.Actions) > 0 {
|
|
simpleRules = append(simpleRules, rule)
|
|
}
|
|
}
|
|
return simpleRules
|
|
}
|
|
|
|
func (am *amOperator) CreateClusterRoleBinding(username string, clusterRoleName string) error {
|
|
clusterRoleLister := am.informers.Rbac().V1().ClusterRoles().Lister()
|
|
|
|
_, err := clusterRoleLister.Get(clusterRoleName)
|
|
|
|
if err != nil {
|
|
klog.Errorln(err)
|
|
return err
|
|
}
|
|
|
|
// TODO move to user controller
|
|
if clusterRoleName == constants.ClusterAdmin {
|
|
// create kubectl pod if cluster role is cluster-admin
|
|
//if err := kubectl.CreateKubectlDeploy(username); err != nil {
|
|
// klog.Error("create user terminal pod failed", username, err)
|
|
//}
|
|
|
|
} else {
|
|
// delete kubectl pod if cluster role is not cluster-admin, whether it exists or not
|
|
//if err := kubectl.DelKubectlDeploy(username); err != nil {
|
|
// klog.Error("delete user terminal pod failed", username, err)
|
|
//}
|
|
}
|
|
|
|
clusterRoleBinding := &rbacv1.ClusterRoleBinding{}
|
|
clusterRoleBinding.Name = username
|
|
clusterRoleBinding.RoleRef = rbacv1.RoleRef{Name: clusterRoleName, Kind: ClusterRoleKind}
|
|
clusterRoleBinding.Subjects = []rbacv1.Subject{{Kind: rbacv1.UserKind, Name: username}}
|
|
|
|
clusterRoleBindingLister := am.informers.Rbac().V1().ClusterRoleBindings().Lister()
|
|
found, err := clusterRoleBindingLister.Get(username)
|
|
|
|
if apierrors.IsNotFound(err) {
|
|
_, err = am.kubeClient.RbacV1().ClusterRoleBindings().Create(clusterRoleBinding)
|
|
if err != nil {
|
|
klog.Errorln("create cluster role binding", err)
|
|
return err
|
|
}
|
|
return nil
|
|
} else if err != nil {
|
|
return err
|
|
}
|
|
|
|
// cluster role changed
|
|
if found.RoleRef.Name != clusterRoleName {
|
|
deletePolicy := metav1.DeletePropagationBackground
|
|
gracePeriodSeconds := int64(0)
|
|
deleteOption := &metav1.DeleteOptions{PropagationPolicy: &deletePolicy, GracePeriodSeconds: &gracePeriodSeconds}
|
|
err = am.kubeClient.RbacV1().ClusterRoleBindings().Delete(found.Name, deleteOption)
|
|
if err != nil {
|
|
klog.Errorln(err)
|
|
return err
|
|
}
|
|
_, err = am.kubeClient.RbacV1().ClusterRoleBindings().Create(clusterRoleBinding)
|
|
if err != nil {
|
|
klog.Errorln(err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
if !ContainsUser(found.Subjects, username) {
|
|
found.Subjects = clusterRoleBinding.Subjects
|
|
_, err = am.kubeClient.RbacV1().ClusterRoleBindings().Update(found)
|
|
if err != nil {
|
|
klog.Errorln("update cluster role binding", err)
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|