diff --git a/pkg/controller/loginrecord/loginrecord_controller_test.go b/pkg/controller/loginrecord/loginrecord_controller_test.go index 2c8d5768525284976241002d7891030f4b744a6c..20ced44a8b3e279634e4f81f9ac0cefb325e7123 100644 --- a/pkg/controller/loginrecord/loginrecord_controller_test.go +++ b/pkg/controller/loginrecord/loginrecord_controller_test.go @@ -18,6 +18,10 @@ package loginrecord import ( "fmt" + "reflect" + "testing" + "time" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/diff" @@ -29,9 +33,6 @@ import ( iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake" ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions" - "reflect" - "testing" - "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -228,6 +229,12 @@ func checkAction(expected, actual core.Action, t *testing.T) { func filterInformerActions(actions []core.Action) []core.Action { var ret []core.Action for _, action := range actions { + if len(action.GetNamespace()) == 0 && + (action.Matches("list", "users") || + action.Matches("watch", "users") || + action.Matches("get", "users")) { + continue + } ret = append(ret, action) } diff --git a/pkg/kapis/iam/v1alpha2/handler.go b/pkg/kapis/iam/v1alpha2/handler.go index 0461198d7058659fc7003094248cb86e2af8997b..ac58cbec11eb0dae4fc5bdb97fa4812e6a9a4083 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 6643cefcb0ed3b94913445749aeb61fe05b58ad1..acf8404f8dd7320fef4151530438a08c6dc24e32 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 76524d83795f69e57756c9e98823900d9ff8a73c..eacbb5aa32f4ef2625efa0e9ffbd78830f8453d7 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 2e357fa6e64738d797afa9ac1247eabca7b056e5..b71c581004fb61d55e836f45dace387e87a3f86d 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