From bec38d7e0fd6c5030f2749a6d29b3cb2bffd8bcf Mon Sep 17 00:00:00 2001 From: "Roland.Ma" Date: Thu, 24 Dec 2020 09:27:59 +0000 Subject: [PATCH] add group api Signed-off-by: Roland.Ma --- pkg/kapis/iam/v1alpha2/handler.go | 26 ++++---------- pkg/kapis/iam/v1alpha2/register.go | 25 ++++++------- pkg/models/iam/am/am.go | 57 +++++++++--------------------- pkg/models/iam/group/group.go | 17 +++++---- 4 files changed, 47 insertions(+), 78 deletions(-) diff --git a/pkg/kapis/iam/v1alpha2/handler.go b/pkg/kapis/iam/v1alpha2/handler.go index 0461198d7..ac58cbec1 100644 --- a/pkg/kapis/iam/v1alpha2/handler.go +++ b/pkg/kapis/iam/v1alpha2/handler.go @@ -18,10 +18,11 @@ package v1alpha2 import ( "fmt" + "strings" + authuser "k8s.io/apiserver/pkg/authentication/user" "kubesphere.io/kubesphere/pkg/apiserver/request" "kubesphere.io/kubesphere/pkg/models/auth" - "strings" "github.com/emicklei/go-restful" rbacv1 "k8s.io/api/rbac/v1" @@ -1344,9 +1345,8 @@ func (h *iamHandler) PatchGroup(request *restful.Request, response *restful.Resp func (h *iamHandler) ListGroupBindings(request *restful.Request, response *restful.Response) { workspaceName := request.PathParameter("workspace") - groupName := request.PathParameter("group") queryParam := query.ParseQueryParameter(request) - result, err := h.group.ListGroupBindings(workspaceName, groupName, queryParam) + result, err := h.group.ListGroupBindings(workspaceName, queryParam) if err != nil { api.HandleError(response, request, err) return @@ -1357,20 +1357,8 @@ func (h *iamHandler) ListGroupBindings(request *restful.Request, response *restf func (h *iamHandler) ListGroupRoleBindings(request *restful.Request, response *restful.Response) { workspaceName := request.PathParameter("workspace") - groupName := request.PathParameter("group") - result, err := h.am.ListGroupRoleBindings(workspaceName, groupName) - if err != nil { - api.HandleInternalError(response, request, err) - return - } - - response.WriteEntity(result) -} - -func (h *iamHandler) ListGroupDevOpsRoleBindings(request *restful.Request, response *restful.Response) { - workspaceName := request.PathParameter("workspace") - groupName := request.PathParameter("group") - result, err := h.am.ListGroupDevOpsRoleBindings(workspaceName, groupName) + queryParam := query.ParseQueryParameter(request) + result, err := h.am.ListGroupRoleBindings(workspaceName, queryParam) if err != nil { api.HandleInternalError(response, request, err) return @@ -1416,8 +1404,8 @@ func (h *iamHandler) DeleteRoleBinding(request *restful.Request, response *restf func (h *iamHandler) ListGroupWorkspaceRoleBindings(request *restful.Request, response *restful.Response) { workspaceName := request.PathParameter("workspace") - groupName := request.PathParameter("group") - result, err := h.am.ListGroupWorkspaceRoleBindings(workspaceName, groupName) + queryParam := query.ParseQueryParameter(request) + result, err := h.am.ListGroupWorkspaceRoleBindings(workspaceName, queryParam) if err != nil { api.HandleInternalError(response, request, err) return diff --git a/pkg/kapis/iam/v1alpha2/register.go b/pkg/kapis/iam/v1alpha2/register.go index 6643cefcb..acf8404f8 100644 --- a/pkg/kapis/iam/v1alpha2/register.go +++ b/pkg/kapis/iam/v1alpha2/register.go @@ -17,9 +17,10 @@ limitations under the License. package v1alpha2 import ( - "kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer" "net/http" + "kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer" + "github.com/emicklei/go-restful" restfulspec "github.com/emicklei/go-restful-openapi" rbacv1 "k8s.io/api/rbac/v1" @@ -518,7 +519,15 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf Returns(http.StatusOK, api.StatusOK, iamv1alpha2.Group{}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag})) - ws.Route(ws.GET("/workspaces/{workspace}/groups/{group}/groupbindings"). + ws.Route(ws.PATCH("/workspaces/{workspace}/groups/{group}/"). + To(handler.PatchGroup). + Param(ws.PathParameter("workspace", "workspace name")). + Doc("Patch Group"). + Reads(iamv1alpha2.Group{}). + Returns(http.StatusOK, api.StatusOK, iamv1alpha2.Group{}). + Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag})) + + ws.Route(ws.GET("/workspaces/{workspace}/groupbindings"). To(handler.ListGroupBindings). Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("group", "group name")). @@ -526,7 +535,7 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf Returns(http.StatusOK, api.StatusOK, api.ListResult{}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag})) - ws.Route(ws.GET("/workspaces/{workspace}/groups/{group}/rolebindings"). + ws.Route(ws.GET("/workspaces/{workspace}/rolebindings"). To(handler.ListGroupRoleBindings). Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("group", "group name")). @@ -534,7 +543,7 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf Returns(http.StatusOK, api.StatusOK, api.ListResult{}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag})) - ws.Route(ws.GET("/workspaces/{workspace}/groups/{group}/workspacerolebindings"). + ws.Route(ws.GET("/workspaces/{workspace}/workspacerolebindings"). To(handler.ListGroupWorkspaceRoleBindings). Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("group", "group name")). @@ -542,14 +551,6 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf Returns(http.StatusOK, api.StatusOK, api.ListResult{}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag})) - ws.Route(ws.GET("/workspaces/{workspace}/groups/{group}/devopsrolebindings"). - To(handler.ListGroupDevOpsRoleBindings). - Param(ws.PathParameter("workspace", "workspace name")). - Param(ws.PathParameter("group", "group name")). - Doc("Retrieve group's rolebindings of all devops projects in the workspace."). - Returns(http.StatusOK, api.StatusOK, api.ListResult{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag})) - ws.Route(ws.DELETE("/workspaces/{workspace}/groupbindings/{groupbinding}"). To(handler.DeleteGroupBinding). Param(ws.PathParameter("workspace", "workspace name")). diff --git a/pkg/models/iam/am/am.go b/pkg/models/iam/am/am.go index 76524d837..eacbb5aa3 100644 --- a/pkg/models/iam/am/am.go +++ b/pkg/models/iam/am/am.go @@ -18,6 +18,7 @@ package am import ( "encoding/json" "fmt" + rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -85,11 +86,10 @@ type AccessManagementInterface interface { GetDevOpsControlledWorkspace(devops string) (string, error) PatchNamespaceRole(namespace string, role *rbacv1.Role) (*rbacv1.Role, error) PatchClusterRole(clusterRole *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) - ListGroupRoleBindings(workspace, group string) ([]*rbacv1.RoleBinding, error) - ListGroupDevOpsRoleBindings(workspace, group string) ([]*rbacv1.RoleBinding, error) + ListGroupRoleBindings(workspace string, query *query.Query) ([]*rbacv1.RoleBinding, error) CreateRoleBinding(namespace string, roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) DeleteRoleBinding(namespace, name string) error - ListGroupWorkspaceRoleBindings(group string, workspace string) ([]*iamv1alpha2.WorkspaceRoleBinding, error) + ListGroupWorkspaceRoleBindings(workspace string, query *query.Query) (*api.ListResult, error) CreateWorkspaceRoleBinding(workspace string, roleBinding *iamv1alpha2.WorkspaceRoleBinding) (*iamv1alpha2.WorkspaceRoleBinding, error) DeleteWorkspaceRoleBinding(workspaceName, name string) error } @@ -1017,24 +1017,17 @@ func (am *amOperator) GetNamespaceControlledWorkspace(namespace string) (string, return ns.Labels[tenantv1alpha1.WorkspaceLabel], nil } -func (am *amOperator) ListGroupWorkspaceRoleBindings(workspace, group string) ([]*iamv1alpha2.WorkspaceRoleBinding, error) { - queryParam := query.New() - queryParam.LabelSelector = labels.FormatLabels(map[string]string{tenantv1alpha1.WorkspaceLabel: workspace}) - roleBindings, err := am.workspaceRoleBindingGetter.List("", queryParam) +func (am *amOperator) ListGroupWorkspaceRoleBindings(workspace string, query *query.Query) (*api.ListResult, error) { + + lableSelector, err := labels.ConvertSelectorToLabelsMap(query.LabelSelector) if err != nil { + klog.Error(err) return nil, err } - - result := make([]*iamv1alpha2.WorkspaceRoleBinding, 0) - for _, obj := range roleBindings.Items { - roleBinding := obj.(*iamv1alpha2.WorkspaceRoleBinding) - inSpecifiedWorkspace := workspace == "" || roleBinding.Labels[tenantv1alpha1.WorkspaceLabel] == workspace - if containsGroup(roleBinding.Subjects, group) && inSpecifiedWorkspace { - result = append(result, roleBinding) - } - } - - return result, nil + // workspace resources must be filtered by workspace + wsSelector := labels.Set{tenantv1alpha1.WorkspaceLabel: workspace} + query.LabelSelector = labels.Merge(lableSelector, wsSelector).String() + return am.workspaceRoleBindingGetter.List("", query) } func (am *amOperator) CreateWorkspaceRoleBinding(workspace string, roleBinding *iamv1alpha2.WorkspaceRoleBinding) (*iamv1alpha2.WorkspaceRoleBinding, error) { @@ -1071,14 +1064,14 @@ func (am *amOperator) DeleteWorkspaceRoleBinding(workspaceName, name string) err return am.ksclient.IamV1alpha2().WorkspaceRoleBindings().Delete(name, metav1.NewDeleteOptions(0)) } -func (am *amOperator) ListGroupRoleBindings(workspace, group string) ([]*rbacv1.RoleBinding, error) { +func (am *amOperator) ListGroupRoleBindings(workspace string, query *query.Query) ([]*rbacv1.RoleBinding, error) { namespaces, err := am.namespaceLister.List(labels.SelectorFromSet(labels.Set{tenantv1alpha1.WorkspaceLabel: workspace})) if err != nil { return nil, err } result := make([]*rbacv1.RoleBinding, 0) for _, namespace := range namespaces { - roleBindings, err := am.roleBindingGetter.List(namespace.Name, query.New()) + roleBindings, err := am.roleBindingGetter.List(namespace.Name, query) if err != nil { klog.Error(err) return nil, err @@ -1086,31 +1079,22 @@ func (am *amOperator) ListGroupRoleBindings(workspace, group string) ([]*rbacv1. for _, obj := range roleBindings.Items { roleBinding := obj.(*rbacv1.RoleBinding) - if containsGroup(roleBinding.Subjects, group) { - result = append(result, roleBinding) - } + result = append(result, roleBinding) } } - return result, nil -} - -func (am *amOperator) ListGroupDevOpsRoleBindings(workspace, group string) ([]*rbacv1.RoleBinding, error) { devOpsProjects, err := am.devopsProjectLister.List(labels.SelectorFromSet(labels.Set{tenantv1alpha1.WorkspaceLabel: workspace})) if err != nil { return nil, err } - result := make([]*rbacv1.RoleBinding, 0) for _, devOpsProject := range devOpsProjects { - roleBindings, err := am.roleBindingGetter.List(devOpsProject.Name, query.New()) + roleBindings, err := am.roleBindingGetter.List(devOpsProject.Name, query) if err != nil { klog.Error(err) return nil, err } for _, obj := range roleBindings.Items { roleBinding := obj.(*rbacv1.RoleBinding) - if containsGroup(roleBinding.Subjects, group) { - result = append(result, roleBinding) - } + result = append(result, roleBinding) } } return result, nil @@ -1147,12 +1131,3 @@ func (am *amOperator) CreateRoleBinding(namespace string, roleBinding *rbacv1.Ro func (am *amOperator) DeleteRoleBinding(namespace, name string) error { return am.k8sclient.RbacV1().RoleBindings(namespace).Delete(name, metav1.NewDeleteOptions(0)) } - -func containsGroup(subjects []rbacv1.Subject, group string) bool { - for _, subject := range subjects { - if subject.Kind == rbacv1.GroupKind && subject.Name == group { - return true - } - } - return false -} diff --git a/pkg/models/iam/group/group.go b/pkg/models/iam/group/group.go index 2e357fa6e..b71c58100 100644 --- a/pkg/models/iam/group/group.go +++ b/pkg/models/iam/group/group.go @@ -23,6 +23,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/client-go/kubernetes" @@ -45,7 +46,7 @@ type GroupOperator interface { PatchGroup(workspace string, group *iamv1alpha2.Group) (*iamv1alpha2.Group, error) DeleteGroupBinding(workspace, name string) error CreateGroupBinding(workspace, groupName, userName string) (*iamv1alpha2.GroupBinding, error) - ListGroupBindings(workspace, group string, queryParam *query.Query) (*api.ListResult, error) + ListGroupBindings(workspace string, queryParam *query.Query) (*api.ListResult, error) } type groupOperator struct { @@ -200,14 +201,18 @@ func (t *groupOperator) CreateGroupBinding(workspace, groupName, userName string return t.ksclient.IamV1alpha2().GroupBindings().Create(&groupBinding) } -func (t *groupOperator) ListGroupBindings(workspace, group string, queryParam *query.Query) (*api.ListResult, error) { +func (t *groupOperator) ListGroupBindings(workspace string, query *query.Query) (*api.ListResult, error) { - if group != "" && workspace != "" { - // filter by group - queryParam.Filters[query.FieldLabel] = query.Value(fmt.Sprintf("%s=%s", iamv1alpha2.GroupReferenceLabel, group)) + lableSelector, err := labels.ConvertSelectorToLabelsMap(query.LabelSelector) + if err != nil { + klog.Error(err) + return nil, err } + // workspace resources must be filtered by workspace + wsSelector := labels.Set{tenantv1alpha1.WorkspaceLabel: workspace} + query.LabelSelector = labels.Merge(lableSelector, wsSelector).String() - result, err := t.resourceGetter.List("groupbindings", "", queryParam) + result, err := t.resourceGetter.List("groupbindings", "", query) if err != nil { klog.Error(err) return nil, err