add role patch API

Signed-off-by: hongming <talonwan@yunify.com>
This commit is contained in:
hongming
2020-06-17 15:55:53 +08:00
parent 692271bb56
commit 56cf6d1028
4 changed files with 379 additions and 126 deletions

View File

@@ -22,6 +22,7 @@ import (
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/api"
@@ -52,7 +53,9 @@ type AccessManagementInterface interface {
GetWorkspaceRole(workspace string, name string) (*iamv1alpha2.WorkspaceRole, error)
CreateGlobalRoleBinding(username string, globalRole string) error
CreateOrUpdateWorkspaceRole(workspace string, workspaceRole *iamv1alpha2.WorkspaceRole) (*iamv1alpha2.WorkspaceRole, error)
PatchWorkspaceRole(workspace string, workspaceRole *iamv1alpha2.WorkspaceRole) (*iamv1alpha2.WorkspaceRole, error)
CreateOrUpdateGlobalRole(globalRole *iamv1alpha2.GlobalRole) (*iamv1alpha2.GlobalRole, error)
PatchGlobalRole(globalRole *iamv1alpha2.GlobalRole) (*iamv1alpha2.GlobalRole, error)
DeleteWorkspaceRole(workspace string, name string) error
DeleteGlobalRole(name string) error
CreateOrUpdateClusterRole(clusterRole *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error)
@@ -69,6 +72,8 @@ type AccessManagementInterface interface {
RemoveUserFromCluster(username string) error
GetControlledNamespace(devops string) (string, error)
GetControlledWorkspace(namespace string) (string, error)
PatchNamespaceRole(namespace string, role *rbacv1.Role) (*rbacv1.Role, error)
PatchClusterRole(clusterRole *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error)
}
type amOperator struct {
@@ -244,7 +249,6 @@ func (am *amOperator) ListClusterRoleBindings(username string) ([]*rbacv1.Cluste
}
result := make([]*rbacv1.ClusterRoleBinding, 0)
for _, obj := range roleBindings.Items {
roleBinding := obj.(*rbacv1.ClusterRoleBinding)
if contains(roleBinding.Subjects, username) {
@@ -334,16 +338,13 @@ func (am *amOperator) GetGlobalRole(globalRole string) (*iamv1alpha2.GlobalRole,
}
func (am *amOperator) CreateGlobalRoleBinding(username string, role string) error {
_, err := am.GetGlobalRole(role)
if err != nil {
klog.Error(err)
return err
}
roleBindings, err := am.ListGlobalRoleBindings(username)
if err != nil {
klog.Error(err)
return err
@@ -398,23 +399,18 @@ func (am *amOperator) CreateOrUpdateWorkspaceRole(workspace string, workspaceRol
var aggregateRoles []string
if err := json.Unmarshal([]byte(workspaceRole.Annotations[iamv1alpha2.AggregationRolesAnnotation]), &aggregateRoles); err == nil {
for _, roleName := range aggregateRoles {
role, err := am.GetWorkspaceRole("", roleName)
if err != nil {
klog.Error(err)
return nil, err
}
workspaceRole.Rules = append(workspaceRole.Rules, role.Rules...)
}
}
var created *iamv1alpha2.WorkspaceRole
var err error
if workspaceRole.ResourceVersion != "" {
created, err = am.ksclient.IamV1alpha2().WorkspaceRoles().Update(workspaceRole)
} else {
@@ -424,17 +420,155 @@ func (am *amOperator) CreateOrUpdateWorkspaceRole(workspace string, workspaceRol
return created, err
}
func (am *amOperator) PatchGlobalRole(globalRole *iamv1alpha2.GlobalRole) (*iamv1alpha2.GlobalRole, error) {
old, err := am.GetGlobalRole(globalRole.Name)
if err != nil {
klog.Error(err)
return nil, err
}
// rules cannot be override
globalRole.Rules = old.Rules
// aggregate roles if annotation has change
if aggregateRolesAnnotation := globalRole.Annotations[iamv1alpha2.AggregationRolesAnnotation]; aggregateRolesAnnotation != "" {
globalRole.Rules = make([]rbacv1.PolicyRule, 0)
var aggregateRoles []string
if err := json.Unmarshal([]byte(aggregateRolesAnnotation), &aggregateRoles); err == nil {
for _, roleName := range aggregateRoles {
role, err := am.GetGlobalRole(roleName)
if err != nil {
klog.Error(err)
return nil, err
}
globalRole.Rules = append(globalRole.Rules, role.Rules...)
}
}
}
data, err := json.Marshal(globalRole)
if err != nil {
return nil, err
}
return am.ksclient.IamV1alpha2().GlobalRoles().Patch(globalRole.Name, types.MergePatchType, data)
}
func (am *amOperator) PatchWorkspaceRole(workspace string, workspaceRole *iamv1alpha2.WorkspaceRole) (*iamv1alpha2.WorkspaceRole, error) {
old, err := am.GetWorkspaceRole(workspace, workspaceRole.Name)
if err != nil {
klog.Error(err)
return nil, err
}
// workspace label cannot be override
if workspaceRole.Labels[tenantv1alpha1.WorkspaceLabel] != "" {
workspaceRole.Labels[tenantv1alpha1.WorkspaceLabel] = workspace
}
// rules cannot be override
workspaceRole.Rules = old.Rules
// aggregate roles if annotation has change
if aggregateRolesAnnotation := workspaceRole.Annotations[iamv1alpha2.AggregationRolesAnnotation]; aggregateRolesAnnotation != "" {
workspaceRole.Rules = make([]rbacv1.PolicyRule, 0)
var aggregateRoles []string
if err := json.Unmarshal([]byte(aggregateRolesAnnotation), &aggregateRoles); err == nil {
for _, roleName := range aggregateRoles {
role, err := am.GetWorkspaceRole("", roleName)
if err != nil {
klog.Error(err)
return nil, err
}
workspaceRole.Rules = append(workspaceRole.Rules, role.Rules...)
}
}
}
data, err := json.Marshal(workspaceRole)
if err != nil {
return nil, err
}
return am.ksclient.IamV1alpha2().WorkspaceRoles().Patch(workspaceRole.Name, types.MergePatchType, data)
}
func (am *amOperator) PatchNamespaceRole(namespace string, role *rbacv1.Role) (*rbacv1.Role, error) {
old, err := am.GetNamespaceRole(namespace, role.Name)
if err != nil {
klog.Error(err)
return nil, err
}
// rules cannot be override
role.Rules = old.Rules
// aggregate roles if annotation has change
if aggregateRolesAnnotation := role.Annotations[iamv1alpha2.AggregationRolesAnnotation]; aggregateRolesAnnotation != "" {
role.Rules = make([]rbacv1.PolicyRule, 0)
var aggregateRoles []string
if err := json.Unmarshal([]byte(aggregateRolesAnnotation), &aggregateRoles); err == nil {
for _, roleName := range aggregateRoles {
role, err := am.GetNamespaceRole(namespace, roleName)
if err != nil {
klog.Error(err)
return nil, err
}
role.Rules = append(role.Rules, role.Rules...)
}
}
}
data, err := json.Marshal(role)
if err != nil {
return nil, err
}
return am.k8sclient.RbacV1().Roles(namespace).Patch(role.Name, types.MergePatchType, data)
}
func (am *amOperator) PatchClusterRole(clusterRole *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) {
old, err := am.GetClusterRole(clusterRole.Name)
if err != nil {
klog.Error(err)
return nil, err
}
// rules cannot be override
clusterRole.Rules = old.Rules
// aggregate roles if annotation has change
if aggregateRolesAnnotation := clusterRole.Annotations[iamv1alpha2.AggregationRolesAnnotation]; aggregateRolesAnnotation != "" {
clusterRole.Rules = make([]rbacv1.PolicyRule, 0)
var aggregateRoles []string
if err := json.Unmarshal([]byte(aggregateRolesAnnotation), &aggregateRoles); err == nil {
for _, roleName := range aggregateRoles {
role, err := am.GetClusterRole(roleName)
if err != nil {
klog.Error(err)
return nil, err
}
role.Rules = append(role.Rules, role.Rules...)
}
}
}
data, err := json.Marshal(clusterRole)
if err != nil {
return nil, err
}
return am.k8sclient.RbacV1().ClusterRoles().Patch(clusterRole.Name, types.MergePatchType, data)
}
func (am *amOperator) CreateWorkspaceRoleBinding(username string, workspace string, role string) error {
_, err := am.GetWorkspaceRole(workspace, role)
if err != nil {
klog.Error(err)
return err
}
roleBindings, err := am.ListWorkspaceRoleBindings(username, workspace)
if err != nil {
klog.Error(err)
return err
@@ -482,9 +616,7 @@ func (am *amOperator) CreateWorkspaceRoleBinding(username string, workspace stri
}
func (am *amOperator) CreateClusterRoleBinding(username string, role string) error {
_, err := am.GetClusterRole(role)
if err != nil {
klog.Error(err)
return err
@@ -540,14 +672,12 @@ func (am *amOperator) CreateClusterRoleBinding(username string, role string) err
func (am *amOperator) CreateNamespaceRoleBinding(username string, namespace string, role string) error {
_, err := am.GetNamespaceRole(namespace, role)
if err != nil {
klog.Error(err)
return err
}
roleBindings, err := am.ListRoleBindings(username, namespace)
if err != nil {
klog.Error(err)
return err
@@ -596,7 +726,6 @@ func (am *amOperator) CreateNamespaceRoleBinding(username string, namespace stri
func (am *amOperator) RemoveUserFromWorkspace(username string, workspace string) error {
roleBindings, err := am.ListWorkspaceRoleBindings(username, workspace)
if err != nil {
klog.Error(err)
return err
@@ -619,7 +748,6 @@ func (am *amOperator) RemoveUserFromWorkspace(username string, workspace string)
func (am *amOperator) RemoveUserFromNamespace(username string, namespace string) error {
roleBindings, err := am.ListRoleBindings(username, namespace)
if err != nil {
klog.Error(err)
return err
@@ -640,9 +768,7 @@ func (am *amOperator) RemoveUserFromNamespace(username string, namespace string)
}
func (am *amOperator) RemoveUserFromCluster(username string) error {
roleBindings, err := am.ListClusterRoleBindings(username)
if err != nil {
klog.Error(err)
return err
@@ -663,28 +789,22 @@ func (am *amOperator) RemoveUserFromCluster(username string) error {
}
func (am *amOperator) CreateOrUpdateGlobalRole(globalRole *iamv1alpha2.GlobalRole) (*iamv1alpha2.GlobalRole, error) {
globalRole.Rules = make([]rbacv1.PolicyRule, 0)
var aggregateRoles []string
if err := json.Unmarshal([]byte(globalRole.Annotations[iamv1alpha2.AggregationRolesAnnotation]), &aggregateRoles); err == nil {
for _, roleName := range aggregateRoles {
role, err := am.GetGlobalRole(roleName)
if err != nil {
klog.Error(err)
return nil, err
}
globalRole.Rules = append(globalRole.Rules, role.Rules...)
}
}
var created *iamv1alpha2.GlobalRole
var err error
if globalRole.ResourceVersion != "" {
created, err = am.ksclient.IamV1alpha2().GlobalRoles().Update(globalRole)
} else {
@@ -695,21 +815,15 @@ func (am *amOperator) CreateOrUpdateGlobalRole(globalRole *iamv1alpha2.GlobalRol
}
func (am *amOperator) CreateOrUpdateClusterRole(clusterRole *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) {
clusterRole.Rules = make([]rbacv1.PolicyRule, 0)
var aggregateRoles []string
if err := json.Unmarshal([]byte(clusterRole.Annotations[iamv1alpha2.AggregationRolesAnnotation]), &aggregateRoles); err == nil {
for _, roleName := range aggregateRoles {
role, err := am.GetClusterRole(roleName)
if err != nil {
klog.Error(err)
return nil, err
}
clusterRole.Rules = append(clusterRole.Rules, role.Rules...)
}
}
@@ -720,30 +834,24 @@ func (am *amOperator) CreateOrUpdateClusterRole(clusterRole *rbacv1.ClusterRole)
} else {
created, err = am.k8sclient.RbacV1().ClusterRoles().Create(clusterRole)
}
return created, err
}
func (am *amOperator) CreateOrUpdateNamespaceRole(namespace string, role *rbacv1.Role) (*rbacv1.Role, error) {
role.Rules = make([]rbacv1.PolicyRule, 0)
role.Namespace = namespace
var aggregateRoles []string
if err := json.Unmarshal([]byte(role.Annotations[iamv1alpha2.AggregationRolesAnnotation]), &aggregateRoles); err == nil {
for _, roleName := range aggregateRoles {
role, err := am.GetNamespaceRole(namespace, roleName)
if err != nil {
klog.Error(err)
return nil, err
}
role.Rules = append(role.Rules, role.Rules...)
}
}
var created *rbacv1.Role
var err error
if role.ResourceVersion != "" {