@@ -167,7 +167,7 @@ func (h *iamHandler) RetrieveMemberRoleTemplates(request *restful.Request, respo
|
|||||||
api.HandleInternalError(response, request, err)
|
api.HandleInternalError(response, request, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
templateRoles := make(map[string]*rbacv1.Role)
|
templateRoles := make(map[string]*iamv1alpha2.WorkspaceRole)
|
||||||
for _, role := range workspaceRoles {
|
for _, role := range workspaceRoles {
|
||||||
// merge template Role
|
// merge template Role
|
||||||
result, err := h.am.ListWorkspaceRoles(&query.Query{
|
result, err := h.am.ListWorkspaceRoles(&query.Query{
|
||||||
@@ -183,12 +183,12 @@ func (h *iamHandler) RetrieveMemberRoleTemplates(request *restful.Request, respo
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, obj := range result.Items {
|
for _, obj := range result.Items {
|
||||||
templateRole := obj.(*rbacv1.Role)
|
templateRole := obj.(*iamv1alpha2.WorkspaceRole)
|
||||||
templateRoles[templateRole.Name] = templateRole
|
templateRoles[templateRole.Name] = templateRole
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
results := make([]*rbacv1.Role, 0, len(templateRoles))
|
results := make([]*iamv1alpha2.WorkspaceRole, 0, len(templateRoles))
|
||||||
for _, value := range templateRoles {
|
for _, value := range templateRoles {
|
||||||
results = append(results, value)
|
results = append(results, value)
|
||||||
}
|
}
|
||||||
@@ -1494,12 +1494,131 @@ func (h *iamHandler) ListGroupBindings(request *restful.Request, response *restf
|
|||||||
response.WriteEntity(result)
|
response.WriteEntity(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *iamHandler) ListGroupsRoleBinding(request *restful.Request, response *restful.Response) {
|
func (h *iamHandler) ListGroupRoleBindings(request *restful.Request, response *restful.Response) {
|
||||||
//todo
|
workspaceName := request.PathParameter("workspace")
|
||||||
|
groupName := request.PathParameter("group")
|
||||||
|
result, err := h.am.ListGroupRoleBindings(workspaceName, groupName)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
klog.Error(err)
|
||||||
|
api.HandleInternalError(response, request, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
response.WriteEntity(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *iamHandler) ListGroupsWorkspaceRoleBinding(request *restful.Request, response *restful.Response) {
|
func (h *iamHandler) ListGroupDevOpsRoleBindings(request *restful.Request, response *restful.Response) {
|
||||||
//todo
|
workspaceName := request.PathParameter("workspace")
|
||||||
|
groupName := request.PathParameter("group")
|
||||||
|
result, err := h.am.ListGroupDevOpsRoleBindings(workspaceName, groupName)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
klog.Error(err)
|
||||||
|
api.HandleInternalError(response, request, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
response.WriteEntity(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *iamHandler) CreateRoleBinding(request *restful.Request, response *restful.Response) {
|
||||||
|
namespace := request.PathParameter("namespace")
|
||||||
|
var roleBindings []rbacv1.RoleBinding
|
||||||
|
err := request.ReadEntity(&roleBindings)
|
||||||
|
if err != nil {
|
||||||
|
klog.Error(err)
|
||||||
|
api.HandleBadRequest(response, request, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
results := []rbacv1.RoleBinding{}
|
||||||
|
for _, item := range roleBindings {
|
||||||
|
r, err := h.am.CreateRoleBindings(namespace, &item)
|
||||||
|
if err != nil {
|
||||||
|
klog.Error(err)
|
||||||
|
handleError(request, response, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
results = append(results, *r)
|
||||||
|
}
|
||||||
|
|
||||||
|
response.WriteEntity(results)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *iamHandler) DeleteRoleBinding(request *restful.Request, response *restful.Response) {
|
||||||
|
name := request.PathParameter("rolebinding")
|
||||||
|
namespace := request.PathParameter("namespace")
|
||||||
|
|
||||||
|
err := h.am.DeleteRoleBindings(namespace, name)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if errors.IsNotFound(err) {
|
||||||
|
api.HandleNotFound(response, request, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
api.HandleInternalError(response, request, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
response.WriteEntity(servererr.None)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
klog.Error(err)
|
||||||
|
api.HandleInternalError(response, request, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
response.WriteEntity(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *iamHandler) CreateWorkspaceRoleBinding(request *restful.Request, response *restful.Response) {
|
||||||
|
workspaceName := request.PathParameter("workspace")
|
||||||
|
|
||||||
|
var roleBindings []iamv1alpha2.WorkspaceRoleBinding
|
||||||
|
err := request.ReadEntity(&roleBindings)
|
||||||
|
if err != nil {
|
||||||
|
klog.Error(err)
|
||||||
|
api.HandleBadRequest(response, request, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
results := []iamv1alpha2.WorkspaceRoleBinding{}
|
||||||
|
for _, item := range roleBindings {
|
||||||
|
r, err := h.am.CreateWorkspaceRoleBindings(workspaceName, &item)
|
||||||
|
if err != nil {
|
||||||
|
klog.Error(err)
|
||||||
|
handleError(request, response, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
results = append(results, *r)
|
||||||
|
}
|
||||||
|
|
||||||
|
response.WriteEntity(results)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *iamHandler) DeleteWorkspaceRoleBinding(request *restful.Request, response *restful.Response) {
|
||||||
|
workspaceName := request.PathParameter("workspace")
|
||||||
|
name := request.PathParameter("rolebinding")
|
||||||
|
|
||||||
|
err := h.am.DeleteWorkspaceRoleBindings(workspaceName, name)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if errors.IsNotFound(err) {
|
||||||
|
api.HandleNotFound(response, request, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
api.HandleInternalError(response, request, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
response.WriteEntity(servererr.None)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *iamHandler) CreateGroupBinding(request *restful.Request, response *restful.Response) {
|
func (h *iamHandler) CreateGroupBinding(request *restful.Request, response *restful.Response) {
|
||||||
@@ -1514,16 +1633,19 @@ func (h *iamHandler) CreateGroupBinding(request *restful.Request, response *rest
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
results := []iamv1alpha2.GroupBinding{}
|
||||||
|
|
||||||
for _, item := range members {
|
for _, item := range members {
|
||||||
err := h.group.CreateGroupBinding(workspace, item.GroupName, item.UserName)
|
b, err := h.group.CreateGroupBinding(workspace, item.GroupName, item.UserName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Error(err)
|
klog.Error(err)
|
||||||
handleError(request, response, err)
|
handleError(request, response, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
results = append(results, *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
response.WriteEntity(members)
|
response.WriteEntity(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *iamHandler) DeleteGroupBinding(request *restful.Request, response *restful.Response) {
|
func (h *iamHandler) DeleteGroupBinding(request *restful.Request, response *restful.Response) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/emicklei/go-restful"
|
"github.com/emicklei/go-restful"
|
||||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||||
rbacv1 "k8s.io/api/rbac/v1"
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
|
v1 "k8s.io/api/rbac/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"kubesphere.io/kubesphere/pkg/api"
|
"kubesphere.io/kubesphere/pkg/api"
|
||||||
"kubesphere.io/kubesphere/pkg/api/iam"
|
"kubesphere.io/kubesphere/pkg/api/iam"
|
||||||
@@ -527,21 +528,29 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf
|
|||||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag}))
|
Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag}))
|
||||||
|
|
||||||
ws.Route(ws.GET("/workspaces/{workspace}/groups/{group}/rolebindings").
|
ws.Route(ws.GET("/workspaces/{workspace}/groups/{group}/rolebindings").
|
||||||
To(handler.ListGroupsRoleBinding).
|
To(handler.ListGroupRoleBindings).
|
||||||
Param(ws.PathParameter("workspace", "workspace name")).
|
Param(ws.PathParameter("workspace", "workspace name")).
|
||||||
Param(ws.PathParameter("group", "group name")).
|
Param(ws.PathParameter("group", "group name")).
|
||||||
Doc("Retrieve group's rolebindings of all projects in the workspace.").
|
Doc("Retrieve group's rolebindings of all projects in the workspace.").
|
||||||
Returns(http.StatusOK, api.StatusOK, api.ListResult{}).
|
Returns(http.StatusOK, api.StatusOK, api.ListResult{}).
|
||||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag}))
|
Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag}))
|
||||||
|
|
||||||
ws.Route(ws.GET("/workspaces/{workspace}/groups/{group}/workspacerolebinding").
|
ws.Route(ws.GET("/workspaces/{workspace}/groups/{group}/workspacerolebindings").
|
||||||
To(handler.ListGroupsWorkspaceRoleBinding).
|
To(handler.ListGroupWorkspaceRoleBindings).
|
||||||
Param(ws.PathParameter("workspace", "workspace name")).
|
Param(ws.PathParameter("workspace", "workspace name")).
|
||||||
Param(ws.PathParameter("group", "group name")).
|
Param(ws.PathParameter("group", "group name")).
|
||||||
Doc("Retrieve group's workspacerolebindings of the workspace.").
|
Doc("Retrieve group's workspacerolebindings of the workspace.").
|
||||||
Returns(http.StatusOK, api.StatusOK, api.ListResult{}).
|
Returns(http.StatusOK, api.StatusOK, api.ListResult{}).
|
||||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag}))
|
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}").
|
ws.Route(ws.DELETE("/workspaces/{workspace}/groupbindings/{groupbinding}").
|
||||||
To(handler.DeleteGroupBinding).
|
To(handler.DeleteGroupBinding).
|
||||||
Param(ws.PathParameter("workspace", "workspace name")).
|
Param(ws.PathParameter("workspace", "workspace name")).
|
||||||
@@ -558,6 +567,41 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf
|
|||||||
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.GroupBinding{}).
|
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.GroupBinding{}).
|
||||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag}))
|
Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag}))
|
||||||
|
|
||||||
|
// namespace rolebinding
|
||||||
|
ws.Route(ws.POST("/namespaces/{namespace}/rolebindings").
|
||||||
|
To(handler.CreateRoleBinding).
|
||||||
|
Doc("Create rolebinding in the specified namespace.").
|
||||||
|
Reads([]v1.RoleBinding{}).
|
||||||
|
Param(ws.PathParameter("namespace", "namespace")).
|
||||||
|
Returns(http.StatusOK, api.StatusOK, []v1.RoleBinding{}).
|
||||||
|
Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceRoleTag}))
|
||||||
|
|
||||||
|
ws.Route(ws.DELETE("/namespace/{namespace}/rolebindings/{rolebinding}").
|
||||||
|
To(handler.DeleteRoleBinding).
|
||||||
|
Param(ws.PathParameter("workspace", "workspace name")).
|
||||||
|
Param(ws.PathParameter("namespace", "groupbinding name")).
|
||||||
|
Param(ws.PathParameter("rolebinding", "groupbinding name")).
|
||||||
|
Doc("Delete rolebinding under namespace.").
|
||||||
|
Returns(http.StatusOK, api.StatusOK, errors.None).
|
||||||
|
Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag}))
|
||||||
|
|
||||||
|
// workspace rolebinding
|
||||||
|
ws.Route(ws.POST("/workspaces/{workspace}/workspacerolebindings").
|
||||||
|
To(handler.CreateWorkspaceRoleBinding).
|
||||||
|
Param(ws.PathParameter("workspace", "workspace name")).
|
||||||
|
Reads([]iamv1alpha2.WorkspaceRoleBinding{}).
|
||||||
|
Doc("Create group's workspacerolebindings of the workspace.").
|
||||||
|
Returns(http.StatusOK, api.StatusOK, []iamv1alpha2.WorkspaceRoleBinding{}).
|
||||||
|
Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag}))
|
||||||
|
|
||||||
|
ws.Route(ws.DELETE("/workspaces/{workspace}/workspacerolebindings/{rolebinding}").
|
||||||
|
To(handler.DeleteWorkspaceRoleBinding).
|
||||||
|
Param(ws.PathParameter("workspace", "workspace name")).
|
||||||
|
Param(ws.PathParameter("rolebinding", "groupbinding name")).
|
||||||
|
Doc("Delete workspacerolebinding.").
|
||||||
|
Returns(http.StatusOK, api.StatusOK, errors.None).
|
||||||
|
Metadata(restfulspec.KeyOpenAPITags, []string{constants.GroupTag}))
|
||||||
|
|
||||||
container.Add(ws)
|
container.Add(ws)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,13 @@ type AccessManagementInterface interface {
|
|||||||
GetDevOpsControlledWorkspace(devops string) (string, error)
|
GetDevOpsControlledWorkspace(devops string) (string, error)
|
||||||
PatchNamespaceRole(namespace string, role *rbacv1.Role) (*rbacv1.Role, error)
|
PatchNamespaceRole(namespace string, role *rbacv1.Role) (*rbacv1.Role, error)
|
||||||
PatchClusterRole(clusterRole *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error)
|
PatchClusterRole(clusterRole *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error)
|
||||||
|
ListGroupRoleBindings(workspace, group string) ([]*rbacv1.RoleBinding, error)
|
||||||
|
ListGroupDevOpsRoleBindings(workspace, group string) ([]*rbacv1.RoleBinding, error)
|
||||||
|
CreateRoleBindings(namespace string, roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error)
|
||||||
|
DeleteRoleBindings(namespace, name string) error
|
||||||
|
ListGroupWorkspaceRoleBindings(group string, workspace string) ([]*iamv1alpha2.WorkspaceRoleBinding, error)
|
||||||
|
CreateWorkspaceRoleBindings(workspace string, roleBinding *iamv1alpha2.WorkspaceRoleBinding) (*iamv1alpha2.WorkspaceRoleBinding, error)
|
||||||
|
DeleteWorkspaceRoleBindings(workspaceName, name string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type amOperator struct {
|
type amOperator struct {
|
||||||
@@ -998,3 +1005,155 @@ func (am *amOperator) GetNamespaceControlledWorkspace(namespace string) (string,
|
|||||||
ns := obj.(*corev1.Namespace)
|
ns := obj.(*corev1.Namespace)
|
||||||
return ns.Labels[tenantv1alpha1.WorkspaceLabel], nil
|
return ns.Labels[tenantv1alpha1.WorkspaceLabel], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (am *amOperator) ListGroupWorkspaceRoleBindings(workspace, group string) ([]*iamv1alpha2.WorkspaceRoleBinding, error) {
|
||||||
|
q := workspaceQuery(workspace)
|
||||||
|
roleBindings, err := am.resourceGetter.List(iamv1alpha2.ResourcesPluralWorkspaceRoleBinding, "", q)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func (am *amOperator) CreateWorkspaceRoleBindings(workspace string, roleBinding *iamv1alpha2.WorkspaceRoleBinding) (*iamv1alpha2.WorkspaceRoleBinding, error) {
|
||||||
|
|
||||||
|
_, err := am.GetWorkspaceRole(workspace, roleBinding.RoleRef.Name)
|
||||||
|
if err != nil {
|
||||||
|
klog.Error(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(roleBinding.Subjects) == 0 {
|
||||||
|
err := errors.NewNotFound(iamv1alpha2.Resource(iamv1alpha2.ResourcesPluralUser), "")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
roleBinding.GenerateName = fmt.Sprintf("%s-%s-", roleBinding.Subjects[0].Name, roleBinding.RoleRef.Name)
|
||||||
|
|
||||||
|
if roleBinding.Labels == nil {
|
||||||
|
roleBinding.Labels = map[string]string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if roleBinding.Subjects[0].Kind == rbacv1.GroupKind {
|
||||||
|
roleBinding.Labels[iamv1alpha2.GroupReferenceLabel] = roleBinding.RoleRef.Name
|
||||||
|
} else if roleBinding.Subjects[0].Kind == rbacv1.UserKind {
|
||||||
|
roleBinding.Labels[iamv1alpha2.UserReferenceLabel] = roleBinding.RoleRef.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
roleBinding.Labels[tenantv1alpha1.WorkspaceLabel] = workspace
|
||||||
|
|
||||||
|
return am.ksclient.IamV1alpha2().WorkspaceRoleBindings().Create(roleBinding)
|
||||||
|
|
||||||
|
}
|
||||||
|
func (am *amOperator) DeleteWorkspaceRoleBindings(workspaceName, name string) error {
|
||||||
|
return am.ksclient.IamV1alpha2().WorkspaceRoleBindings().Delete(name, metav1.NewDeleteOptions(0))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (am *amOperator) ListGroupRoleBindings(workspace, group string) ([]*rbacv1.RoleBinding, error) {
|
||||||
|
q := workspaceQuery(workspace)
|
||||||
|
namespaces, err := am.resourceGetter.List("namespaces", "", q)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result := make([]*rbacv1.RoleBinding, 0)
|
||||||
|
for _, ns := range namespaces.Items {
|
||||||
|
namespace := ns.(*corev1.Namespace)
|
||||||
|
roleBindings, err := am.resourceGetter.List(iamv1alpha2.ResourcesPluralRoleBinding, namespace.Name, query.New())
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (am *amOperator) ListGroupDevOpsRoleBindings(workspace, group string) ([]*rbacv1.RoleBinding, error) {
|
||||||
|
q := workspaceQuery(workspace)
|
||||||
|
namespaces, err := am.resourceGetter.List(devopsv1alpha3.ResourcePluralDevOpsProject, "", q)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result := make([]*rbacv1.RoleBinding, 0)
|
||||||
|
for _, ns := range namespaces.Items {
|
||||||
|
namespace := ns.(*devopsv1alpha3.DevOpsProject)
|
||||||
|
roleBindings, err := am.resourceGetter.List(iamv1alpha2.ResourcesPluralRoleBinding, namespace.Name, query.New())
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (am *amOperator) CreateRoleBindings(namespace string, roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) {
|
||||||
|
|
||||||
|
_, err := am.GetNamespaceRole(namespace, roleBinding.RoleRef.Name)
|
||||||
|
if err != nil {
|
||||||
|
klog.Error(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(roleBinding.Subjects) == 0 {
|
||||||
|
err := errors.NewNotFound(iamv1alpha2.Resource(iamv1alpha2.ResourcesPluralUser), "")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
roleBinding.GenerateName = fmt.Sprintf("%s-%s-", roleBinding.Subjects[0].Name, roleBinding.RoleRef.Name)
|
||||||
|
|
||||||
|
if roleBinding.Labels == nil {
|
||||||
|
roleBinding.Labels = map[string]string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if roleBinding.Subjects[0].Kind == rbacv1.GroupKind {
|
||||||
|
roleBinding.Labels[iamv1alpha2.GroupReferenceLabel] = roleBinding.Subjects[0].Name
|
||||||
|
} else if roleBinding.Subjects[0].Kind == rbacv1.UserKind {
|
||||||
|
roleBinding.Labels[iamv1alpha2.UserReferenceLabel] = roleBinding.Subjects[0].Name
|
||||||
|
}
|
||||||
|
|
||||||
|
return am.k8sclient.RbacV1().RoleBindings(namespace).Create(roleBinding)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (am *amOperator) DeleteRoleBindings(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
|
||||||
|
}
|
||||||
|
|
||||||
|
func workspaceQuery(workspace string) *query.Query {
|
||||||
|
q := query.New()
|
||||||
|
q.Filters[query.FieldLabel] = query.Value(fmt.Sprintf("%s=%s", tenantv1alpha1.WorkspaceLabel, workspace))
|
||||||
|
return q
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
"kubesphere.io/kubesphere/pkg/api"
|
"kubesphere.io/kubesphere/pkg/api"
|
||||||
@@ -43,7 +44,7 @@ type GroupOperator interface {
|
|||||||
UpdateGroup(workspace string, group *iamv1alpha2.Group) (*iamv1alpha2.Group, error)
|
UpdateGroup(workspace string, group *iamv1alpha2.Group) (*iamv1alpha2.Group, error)
|
||||||
PatchGroup(workspace string, group *iamv1alpha2.Group) (*iamv1alpha2.Group, error)
|
PatchGroup(workspace string, group *iamv1alpha2.Group) (*iamv1alpha2.Group, error)
|
||||||
DeleteGroupBinding(workspace, name string) error
|
DeleteGroupBinding(workspace, name string) error
|
||||||
CreateGroupBinding(workspace, groupName, userName string) error
|
CreateGroupBinding(workspace, groupName, userName string) (*iamv1alpha2.GroupBinding, error)
|
||||||
ListGroupBindings(workspace, group string, queryParam *query.Query) (*api.ListResult, error)
|
ListGroupBindings(workspace, group string, queryParam *query.Query) (*api.ListResult, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,8 +78,43 @@ func (t *groupOperator) ListGroups(workspace string, queryParam *query.Query) (*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateGroup adds a workspace label to group which indicates group is under the workspace
|
// CreateGroup adds a workspace label to group which indicates group is under the workspace
|
||||||
func (t *groupOperator) CreateGroup(workspace string, namespace *iamv1alpha2.Group) (*iamv1alpha2.Group, error) {
|
func (t *groupOperator) CreateGroup(workspace string, group *iamv1alpha2.Group) (*iamv1alpha2.Group, error) {
|
||||||
return t.ksclient.IamV1alpha2().Groups().Create(labelGroupWithWorkspaceName(namespace, workspace))
|
|
||||||
|
if group.GenerateName == "" {
|
||||||
|
err := errors.NewInvalid(iamv1alpha2.SchemeGroupVersion.WithKind(iamv1alpha2.ResourcePluralGroup).GroupKind(),
|
||||||
|
"", []*field.Error{field.Required(field.NewPath("metadata.generateName"), "generateName is required")})
|
||||||
|
klog.Error(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// generateName is used as displayName
|
||||||
|
// ensure generateName is unique in workspace scope
|
||||||
|
if unique, err := t.isGenerateNameUnique(workspace, group.GenerateName); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if !unique {
|
||||||
|
err = errors.NewConflict(iamv1alpha2.Resource(iamv1alpha2.ResourcePluralGroup),
|
||||||
|
group.GenerateName, fmt.Errorf("a group named %s already exists in the workspace", group.GenerateName))
|
||||||
|
klog.Error(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.ksclient.IamV1alpha2().Groups().Create(labelGroupWithWorkspaceName(group, workspace))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *groupOperator) isGenerateNameUnique(workspace, generateName string) (bool, error) {
|
||||||
|
|
||||||
|
result, err := t.ListGroups(workspace, query.New())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
klog.Error(err)
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
for _, obj := range result.Items {
|
||||||
|
g := obj.(*iamv1alpha2.Group)
|
||||||
|
if g.GenerateName == generateName {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *groupOperator) DescribeGroup(workspace, group string) (*iamv1alpha2.Group, error) {
|
func (t *groupOperator) DescribeGroup(workspace, group string) (*iamv1alpha2.Group, error) {
|
||||||
@@ -142,11 +178,11 @@ func (t *groupOperator) DeleteGroupBinding(workspace, name string) error {
|
|||||||
return t.ksclient.IamV1alpha2().GroupBindings().Delete(name, metav1.NewDeleteOptions(0))
|
return t.ksclient.IamV1alpha2().GroupBindings().Delete(name, metav1.NewDeleteOptions(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *groupOperator) CreateGroupBinding(workspace, groupName, userName string) error {
|
func (t *groupOperator) CreateGroupBinding(workspace, groupName, userName string) (*iamv1alpha2.GroupBinding, error) {
|
||||||
|
|
||||||
groupBinding := iamv1alpha2.GroupBinding{
|
groupBinding := iamv1alpha2.GroupBinding{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: fmt.Sprintf("%s-%s", groupName, userName),
|
GenerateName: fmt.Sprintf("%s-%s-", groupName, userName),
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
iamv1alpha2.UserReferenceLabel: userName,
|
iamv1alpha2.UserReferenceLabel: userName,
|
||||||
iamv1alpha2.GroupReferenceLabel: groupName,
|
iamv1alpha2.GroupReferenceLabel: groupName,
|
||||||
@@ -161,11 +197,7 @@ func (t *groupOperator) CreateGroupBinding(workspace, groupName, userName string
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := t.ksclient.IamV1alpha2().GroupBindings().Create(&groupBinding); err != nil {
|
return t.ksclient.IamV1alpha2().GroupBindings().Create(&groupBinding)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *groupOperator) ListGroupBindings(workspace, group string, queryParam *query.Query) (*api.ListResult, error) {
|
func (t *groupOperator) ListGroupBindings(workspace, group string, queryParam *query.Query) (*api.ListResult, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user