未验证 提交 df36ae5c 编写于 作者: K KubeSphere CI Bot 提交者: GitHub

Merge pull request #2191 from wansir/tenant-api

add tenant resource API
此差异已折叠。
......@@ -103,25 +103,25 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf
Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{iamv1alpha2.User{}}}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/workspaces/{workspace}/users").
ws.Route(ws.GET("/workspaces/{workspace}/workspacemembers").
To(handler.ListWorkspaceMembers).
Doc("List all members in the specified workspace.").
Param(ws.PathParameter("workspace", "workspace name")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/workspaces/{workspace}/users/{user}").
ws.Route(ws.GET("/workspaces/{workspace}/workspacemembers/{workspacemember}").
To(handler.DescribeWorkspaceMember).
Doc("Retrieve workspace member details.").
Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.POST("/workspaces/{workspace}/users").
ws.Route(ws.POST("/workspaces/{workspace}/workspacemembers").
To(handler.CreateWorkspaceMembers).
Doc("Batch add workspace members.").
Reads([]Member{}).
Returns(http.StatusOK, api.StatusOK, errors.None).
Param(ws.PathParameter("workspace", "workspace name")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.PUT("/workspaces/{workspace}/users/{user}").
ws.Route(ws.PUT("/workspaces/{workspace}/workspacemembers/{workspacemember}").
To(handler.UpdateWorkspaceMember).
Doc("Update member in workspace.").
Reads(Member{}).
......@@ -129,32 +129,32 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf
Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.DELETE("/workspaces/{workspace}/users/{user}").
ws.Route(ws.DELETE("/workspaces/{workspace}/workspacemembers/{workspacemember}").
To(handler.RemoveWorkspaceMember).
Doc("Remove member in workspace.").
Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/namespaces/{namespace}/users").
ws.Route(ws.GET("/namespaces/{namespace}/members").
To(handler.ListNamespaceMembers).
Doc("List all members in the specified namespace.").
Param(ws.PathParameter("namespace", "namespace")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/namespaces/{namespace}/users/{user}").
ws.Route(ws.GET("/namespaces/{namespace}/members/{member}").
To(handler.DescribeNamespaceMember).
Doc("Retrieve namespace member details.").
Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.POST("/namespaces/{namespace}/users").
ws.Route(ws.POST("/namespaces/{namespace}/members").
To(handler.CreateNamespaceMembers).
Doc("Batch add namespace members.").
Reads([]Member{}).
Returns(http.StatusOK, api.StatusOK, errors.None).
Param(ws.PathParameter("namespace", "namespace")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.PUT("/namespaces/{namespace}/users/{user}").
ws.Route(ws.PUT("/namespaces/{namespace}/members/{member}").
To(handler.UpdateNamespaceMember).
Doc("Update member in namespace.").
Reads(Member{}).
......@@ -162,44 +162,44 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf
Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.DELETE("/namespaces/{namespace}/users/{user}").
ws.Route(ws.DELETE("/namespaces/{namespace}/members/{member}").
To(handler.RemoveNamespaceMember).
Doc("Remove member in namespace.").
Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/devops/{devops}/users").
ws.Route(ws.GET("/devops/{devops}/members").
To(handler.ListNamespaceMembers).
Doc("List all members in the specified namespace.").
Param(ws.PathParameter("namespace", "namespace")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/devops/{devops}/users/{user}").
ws.Route(ws.GET("/devops/{devops}/members/{member}").
To(handler.DescribeNamespaceMember).
Doc("Retrieve namespace member details.").
Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.POST("/devops/{devops}/users").
ws.Route(ws.POST("/devops/{devops}/members").
To(handler.CreateNamespaceMembers).
Doc("Batch add namespace members.").
Reads([]Member{}).
Returns(http.StatusOK, api.StatusOK, errors.None).
Param(ws.PathParameter("namespace", "namespace")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.PUT("/devops/{devops}/users/{user}").
ws.Route(ws.PUT("/devops/{devops}/members/{member}").
To(handler.UpdateNamespaceMember).
Doc("Update member in namespace.").
Reads(Member{}).
Returns(http.StatusOK, api.StatusOK, errors.None).
Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")).
Param(ws.PathParameter("member", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.DELETE("/devops/{devops}/users/{user}").
ws.Route(ws.DELETE("/devops/{devops}/members/{member}").
To(handler.RemoveNamespaceMember).
Doc("Remove member in namespace.").
Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")).
Param(ws.PathParameter("member", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
// globalroles
......@@ -375,27 +375,27 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf
Param(ws.PathParameter("user", "username")).
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.GlobalRole{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/users/{user}/clusterroles").
ws.Route(ws.GET("/clustermembers/{clustermember}/clusterroles").
To(handler.RetrieveMemberRoleTemplates).
Doc("Retrieve user's role templates in cluster.").
Param(ws.PathParameter("user", "username")).
Returns(http.StatusOK, api.StatusOK, rbacv1.ClusterRole{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/workspaces/{workspace}/users/{user}/workspaceroles").
ws.Route(ws.GET("/workspaces/{workspace}/workspacemembers/{workspacemember}/workspaceroles").
To(handler.RetrieveMemberRoleTemplates).
Doc("Retrieve member's role templates in workspace.").
Param(ws.PathParameter("workspace", "workspace")).
Param(ws.PathParameter("user", "username")).
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.WorkspaceRole{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/namespaces/{namespace}/users/{user}/roles").
ws.Route(ws.GET("/namespaces/{namespace}/members/{member}/roles").
To(handler.RetrieveMemberRoleTemplates).
Doc("Retrieve member's role templates in namespace.").
Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")).
Returns(http.StatusOK, api.StatusOK, rbacv1.Role{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/devops/{devops}/users/{user}/roles").
ws.Route(ws.GET("/devops/{devops}/members/{member}/roles").
To(handler.RetrieveMemberRoleTemplates).
Doc("Retrieve member's role templates in devops project.").
Param(ws.PathParameter("namespace", "namespace")).
......
......@@ -185,7 +185,6 @@ func (h *tenantHandler) UpdateWorkspace(request *restful.Request, response *rest
}
response.WriteEntity(updated)
}
func (h *tenantHandler) DescribeWorkspace(request *restful.Request, response *restful.Response) {
......@@ -310,3 +309,151 @@ func (h *tenantHandler) Auditing(req *restful.Request, resp *restful.Response) {
_ = resp.WriteEntity(result)
}
func (h *tenantHandler) DescribeNamespace(request *restful.Request, response *restful.Response) {
workspaceName := request.PathParameter("workspace")
namespaceName := request.PathParameter("namespace")
ns, err := h.tenant.DescribeNamespace(workspaceName, namespaceName)
if err != nil {
if errors.IsNotFound(err) {
api.HandleNotFound(response, request, err)
return
}
api.HandleInternalError(response, request, err)
return
}
response.WriteEntity(ns)
}
func (h *tenantHandler) DeleteNamespace(request *restful.Request, response *restful.Response) {
workspaceName := request.PathParameter("workspace")
namespaceName := request.PathParameter("namespace")
err := h.tenant.DeleteNamespace(workspaceName, namespaceName)
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 *tenantHandler) UpdateNamespace(request *restful.Request, response *restful.Response) {
workspaceName := request.PathParameter("workspace")
namespaceName := request.PathParameter("namespace")
var namespace corev1.Namespace
err := request.ReadEntity(&namespace)
if err != nil {
klog.Error(err)
api.HandleBadRequest(response, request, err)
return
}
if namespaceName != namespace.Name {
err := fmt.Errorf("the name of the object (%s) does not match the name on the URL (%s)", namespace.Name, namespaceName)
klog.Errorf("%+v", err)
api.HandleBadRequest(response, request, err)
return
}
updated, err := h.tenant.UpdateNamespace(workspaceName, &namespace)
if err != nil {
klog.Error(err)
if errors.IsNotFound(err) {
api.HandleNotFound(response, request, err)
return
}
if errors.IsBadRequest(err) {
api.HandleBadRequest(response, request, err)
return
}
api.HandleInternalError(response, request, err)
return
}
response.WriteEntity(updated)
}
func (h *tenantHandler) PatchNamespace(request *restful.Request, response *restful.Response) {
workspaceName := request.PathParameter("workspace")
namespaceName := request.PathParameter("namespace")
var namespace corev1.Namespace
err := request.ReadEntity(&namespace)
if err != nil {
klog.Error(err)
api.HandleBadRequest(response, request, err)
return
}
if namespaceName != namespace.Name {
err := fmt.Errorf("the name of the object (%s) does not match the name on the URL (%s)", namespace.Name, namespaceName)
klog.Errorf("%+v", err)
api.HandleBadRequest(response, request, err)
return
}
patched, err := h.tenant.PatchNamespace(workspaceName, &namespace)
if err != nil {
klog.Error(err)
if errors.IsNotFound(err) {
api.HandleNotFound(response, request, err)
return
}
if errors.IsBadRequest(err) {
api.HandleBadRequest(response, request, err)
return
}
api.HandleInternalError(response, request, err)
return
}
response.WriteEntity(patched)
}
func (h *tenantHandler) PatchWorkspace(request *restful.Request, response *restful.Response) {
workspaceName := request.PathParameter("workspace")
var workspace tenantv1alpha2.WorkspaceTemplate
err := request.ReadEntity(&workspace)
if err != nil {
klog.Error(err)
api.HandleBadRequest(response, request, err)
return
}
if workspaceName != workspace.Name {
err := fmt.Errorf("the name of the object (%s) does not match the name on the URL (%s)", workspace.Name, workspaceName)
klog.Errorf("%+v", err)
api.HandleBadRequest(response, request, err)
return
}
patched, err := h.tenant.PatchWorkspace(&workspace)
if err != nil {
klog.Error(err)
if errors.IsNotFound(err) {
api.HandleNotFound(response, request, err)
return
}
if errors.IsBadRequest(err) {
api.HandleBadRequest(response, request, err)
return
}
api.HandleInternalError(response, request, err)
return
}
response.WriteEntity(patched)
}
......@@ -46,6 +46,8 @@ const (
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8sclient kubernetes.Interface, ksclient kubesphere.Interface, evtsClient events.Client, loggingClient logging.Interface, auditingclient auditing.Client) error {
mimePatch := []string{restful.MIME_JSON, runtime.MimeMergePatchJson, runtime.MimeJsonPatchJson}
ws := runtime.NewWebService(GroupVersion)
handler := newTenantHandler(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient)
......@@ -66,6 +68,13 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s
Returns(http.StatusOK, api.StatusOK, tenantv1alpha2.WorkspaceTemplate{}).
Doc("Update workspace.").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag}))
ws.Route(ws.PATCH("/workspaces/{workspace}").
To(handler.PatchWorkspace).
Consumes(mimePatch...).
Reads(tenantv1alpha2.WorkspaceTemplate{}).
Returns(http.StatusOK, api.StatusOK, tenantv1alpha2.WorkspaceTemplate{}).
Doc("Update workspace.").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag}))
ws.Route(ws.GET("/workspaces").
To(handler.ListWorkspaces).
Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}).
......@@ -94,6 +103,18 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s
Doc("List the namespaces of the specified workspace for the current user").
Returns(http.StatusOK, api.StatusOK, []corev1.Namespace{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag}))
ws.Route(ws.GET("/workspaces/{workspace}/namespaces/{namespace}").
To(handler.DescribeNamespace).
Param(ws.PathParameter("workspace", "workspace name")).
Doc("Retrieve namespace details.").
Returns(http.StatusOK, api.StatusOK, []corev1.Namespace{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag}))
ws.Route(ws.DELETE("/workspaces/{workspace}/namespaces/{namespace}").
To(handler.DeleteNamespace).
Param(ws.PathParameter("workspace", "workspace name")).
Doc("Delete namespace.").
Returns(http.StatusOK, api.StatusOK, errors.None).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag}))
ws.Route(ws.POST("/workspaces/{workspace}/namespaces").
To(handler.CreateNamespace).
Param(ws.PathParameter("workspace", "workspace name")).
......@@ -101,6 +122,19 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s
Reads(corev1.Namespace{}).
Returns(http.StatusOK, api.StatusOK, []corev1.Namespace{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag}))
ws.Route(ws.PUT("/workspaces/{workspace}/namespaces/{namespace}").
To(handler.UpdateNamespace).
Param(ws.PathParameter("workspace", "workspace name")).
Reads(corev1.Namespace{}).
Returns(http.StatusOK, api.StatusOK, []corev1.Namespace{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag}))
ws.Route(ws.PATCH("/workspaces/{workspace}/namespaces/{namespace}").
To(handler.PatchNamespace).
Consumes(mimePatch...).
Param(ws.PathParameter("workspace", "workspace name")).
Reads(corev1.Namespace{}).
Returns(http.StatusOK, api.StatusOK, []corev1.Namespace{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag}))
ws.Route(ws.GET("/events").
To(handler.Events).
......
......@@ -32,7 +32,6 @@ import (
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"kubesphere.io/kubesphere/pkg/informers"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"net/http"
)
type AccessManagementInterface interface {
......@@ -44,16 +43,14 @@ type AccessManagementInterface interface {
ListClusterRoles(query *query.Query) (*api.ListResult, error)
ListWorkspaceRoles(query *query.Query) (*api.ListResult, error)
ListGlobalRoles(query *query.Query) (*api.ListResult, error)
ListGlobalRoleBindings(username string) ([]*iamv1alpha2.GlobalRoleBinding, error)
ListClusterRoleBindings(username string) ([]*rbacv1.ClusterRoleBinding, error)
ListWorkspaceRoleBindings(username, workspace string) ([]*iamv1alpha2.WorkspaceRoleBinding, error)
ListRoleBindings(username, namespace string) ([]*rbacv1.RoleBinding, error)
GetRoleReferenceRules(roleRef rbacv1.RoleRef, namespace string) (string, []rbacv1.PolicyRule, error)
GetGlobalRole(globalRole string) (*iamv1alpha2.GlobalRole, error)
GetWorkspaceRole(workspace string, name string) (*iamv1alpha2.WorkspaceRole, error)
CreateOrUpdateGlobalRoleBinding(username string, globalRole string) error
CreateGlobalRoleBinding(username string, globalRole string) error
CreateOrUpdateWorkspaceRole(workspace string, workspaceRole *iamv1alpha2.WorkspaceRole) (*iamv1alpha2.WorkspaceRole, error)
CreateOrUpdateGlobalRole(globalRole *iamv1alpha2.GlobalRole) (*iamv1alpha2.GlobalRole, error)
DeleteWorkspaceRole(workspace string, name string) error
......@@ -64,11 +61,11 @@ type AccessManagementInterface interface {
GetNamespaceRole(namespace string, name string) (*rbacv1.Role, error)
CreateOrUpdateNamespaceRole(namespace string, role *rbacv1.Role) (*rbacv1.Role, error)
DeleteNamespaceRole(namespace string, name string) error
CreateOrUpdateWorkspaceRoleBinding(username string, workspace string, role string) error
CreateWorkspaceRoleBinding(username string, workspace string, role string) error
RemoveUserFromWorkspace(username string, workspace string) error
CreateOrUpdateNamespaceRoleBinding(username string, namespace string, role string) error
CreateNamespaceRoleBinding(username string, namespace string, role string) error
RemoveUserFromNamespace(username string, namespace string) error
CreateOrUpdateClusterRoleBinding(username string, role string) error
CreateClusterRoleBinding(username string, role string) error
RemoveUserFromCluster(username string) error
GetControlledNamespace(devops string) (string, error)
GetControlledWorkspace(namespace string) (string, error)
......@@ -116,17 +113,8 @@ func (am *amOperator) GetGlobalRoleOfUser(username string) (*iamv1alpha2.GlobalR
return out, nil
}
err = &errors.StatusError{ErrStatus: metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusNotFound,
Reason: metav1.StatusReasonNotFound,
Details: &metav1.StatusDetails{
Group: iamv1alpha2.SchemeGroupVersion.Group,
Kind: iamv1alpha2.ResourceKindGlobalRoleBinding,
},
Message: fmt.Sprintf("global role binding not found for %s", username),
}}
err = errors.NewNotFound(iamv1alpha2.Resource(iamv1alpha2.ResourcesSingularGlobalRoleBinding), username)
klog.Error(err)
return nil, err
}
......@@ -159,17 +147,8 @@ func (am *amOperator) GetWorkspaceRoleOfUser(username, workspace string) (*iamv1
return out, nil
}
err = &errors.StatusError{ErrStatus: metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusNotFound,
Reason: metav1.StatusReasonNotFound,
Details: &metav1.StatusDetails{
Group: iamv1alpha2.SchemeGroupVersion.Group,
Kind: iamv1alpha2.ResourceKindWorkspaceRoleBinding,
},
Message: fmt.Sprintf("workspace role binding not found for %s", username),
}}
err = errors.NewNotFound(iamv1alpha2.Resource(iamv1alpha2.ResourcesSingularWorkspaceRoleBinding), username)
klog.Error(err)
return nil, err
}
......@@ -199,17 +178,8 @@ func (am *amOperator) GetNamespaceRoleOfUser(username, namespace string) (*rbacv
return out, nil
}
err = &errors.StatusError{ErrStatus: metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusNotFound,
Reason: metav1.StatusReasonNotFound,
Details: &metav1.StatusDetails{
Group: rbacv1.SchemeGroupVersion.Group,
Kind: iamv1alpha2.ResourceKindRoleBinding,
},
Message: fmt.Sprintf("role binding not found for %s in %s", username, namespace),
}}
err = errors.NewNotFound(iamv1alpha2.Resource(iamv1alpha2.ResourcesSingularRoleBinding), username)
klog.Error(err)
return nil, err
}
......@@ -239,17 +209,9 @@ func (am *amOperator) GetClusterRoleOfUser(username string) (*rbacv1.ClusterRole
out.Annotations[iamv1alpha2.ClusterRoleAnnotation] = role.Name
return out, nil
}
err = &errors.StatusError{ErrStatus: metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusNotFound,
Reason: metav1.StatusReasonNotFound,
Details: &metav1.StatusDetails{
Group: rbacv1.SchemeGroupVersion.Group,
Kind: "ClusterRoleBinding",
},
Message: fmt.Sprintf("cluster role binding not found for %s", username),
}}
err = errors.NewNotFound(iamv1alpha2.Resource(iamv1alpha2.ResourcesSingularClusterRoleBinding), username)
klog.Error(err)
return nil, err
}
......@@ -371,7 +333,7 @@ func (am *amOperator) GetGlobalRole(globalRole string) (*iamv1alpha2.GlobalRole,
return obj.(*iamv1alpha2.GlobalRole), nil
}
func (am *amOperator) CreateOrUpdateGlobalRoleBinding(username string, globalRole string) error {
func (am *amOperator) CreateGlobalRoleBinding(username string, globalRole string) error {
_, err := am.GetGlobalRole(globalRole)
......@@ -428,11 +390,9 @@ func (am *amOperator) CreateOrUpdateGlobalRoleBinding(username string, globalRol
}
func (am *amOperator) CreateOrUpdateWorkspaceRole(workspace string, workspaceRole *iamv1alpha2.WorkspaceRole) (*iamv1alpha2.WorkspaceRole, error) {
if workspaceRole.Labels == nil {
workspaceRole.Labels = make(map[string]string, 0)
}
workspaceRole.Labels[tenantv1alpha1.WorkspaceLabel] = workspace
workspaceRole.Rules = make([]rbacv1.PolicyRule, 0)
......@@ -452,15 +412,10 @@ func (am *amOperator) CreateOrUpdateWorkspaceRole(workspace string, workspaceRol
}
}
old, err := am.GetWorkspaceRole("", workspaceRole.Name)
if err != nil && !errors.IsNotFound(err) {
klog.Error(err)
return nil, err
}
var created *iamv1alpha2.WorkspaceRole
if old != nil {
var err error
if workspaceRole.ResourceVersion != "" {
created, err = am.ksclient.IamV1alpha2().WorkspaceRoles().Update(workspaceRole)
} else {
created, err = am.ksclient.IamV1alpha2().WorkspaceRoles().Create(workspaceRole)
......@@ -469,7 +424,7 @@ func (am *amOperator) CreateOrUpdateWorkspaceRole(workspace string, workspaceRol
return created, err
}
func (am *amOperator) CreateOrUpdateWorkspaceRoleBinding(username string, workspace string, role string) error {
func (am *amOperator) CreateWorkspaceRoleBinding(username string, workspace string, role string) error {
_, err := am.GetWorkspaceRole(workspace, role)
......@@ -526,7 +481,7 @@ func (am *amOperator) CreateOrUpdateWorkspaceRoleBinding(username string, worksp
return nil
}
func (am *amOperator) CreateOrUpdateClusterRoleBinding(username string, role string) error {
func (am *amOperator) CreateClusterRoleBinding(username string, role string) error {
_, err := am.GetClusterRole(role)
......@@ -582,7 +537,7 @@ func (am *amOperator) CreateOrUpdateClusterRoleBinding(username string, role str
return nil
}
func (am *amOperator) CreateOrUpdateNamespaceRoleBinding(username string, namespace string, role string) error {
func (am *amOperator) CreateNamespaceRoleBinding(username string, namespace string, role string) error {
_, err := am.GetNamespaceRole(namespace, role)
......@@ -727,15 +682,10 @@ func (am *amOperator) CreateOrUpdateGlobalRole(globalRole *iamv1alpha2.GlobalRol
}
}
old, err := am.GetGlobalRole(globalRole.Name)
if err != nil && !errors.IsNotFound(err) {
klog.Error(err)
return nil, err
}
var created *iamv1alpha2.GlobalRole
if old != nil {
var err error
if globalRole.ResourceVersion != "" {
created, err = am.ksclient.IamV1alpha2().GlobalRoles().Update(globalRole)
} else {
created, err = am.ksclient.IamV1alpha2().GlobalRoles().Create(globalRole)
......@@ -763,16 +713,9 @@ func (am *amOperator) CreateOrUpdateClusterRole(clusterRole *rbacv1.ClusterRole)
clusterRole.Rules = append(clusterRole.Rules, role.Rules...)
}
}
old, err := am.GetClusterRole(clusterRole.Name)
if err != nil && !errors.IsNotFound(err) {
klog.Error(err)
return nil, err
}
var created *rbacv1.ClusterRole
if old != nil {
var err error
if clusterRole.ResourceVersion != "" {
created, err = am.k8sclient.RbacV1().ClusterRoles().Update(clusterRole)
} else {
created, err = am.k8sclient.RbacV1().ClusterRoles().Create(clusterRole)
......@@ -801,16 +744,9 @@ func (am *amOperator) CreateOrUpdateNamespaceRole(namespace string, role *rbacv1
role.Rules = append(role.Rules, role.Rules...)
}
}
old, err := am.GetNamespaceRole(namespace, role.Name)
if err != nil && !errors.IsNotFound(err) {
klog.Error(err)
return nil, err
}
var created *rbacv1.Role
if old != nil {
var err error
if role.ResourceVersion != "" {
created, err = am.k8sclient.RbacV1().Roles(namespace).Update(role)
} else {
created, err = am.k8sclient.RbacV1().Roles(namespace).Create(role)
......
......@@ -17,12 +17,14 @@ limitations under the License.
package tenant
import (
"encoding/json"
"fmt"
"io"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/client-go/kubernetes"
"k8s.io/klog"
......@@ -36,6 +38,7 @@ import (
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizerfactory"
"kubesphere.io/kubesphere/pkg/apiserver/query"
"kubesphere.io/kubesphere/pkg/apiserver/request"
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/auditing"
......@@ -61,11 +64,15 @@ type Interface interface {
UpdateWorkspace(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error)
DescribeWorkspace(workspace string) (*tenantv1alpha2.WorkspaceTemplate, error)
ListWorkspaceClusters(workspace string) (*api.ListResult, error)
Events(user user.Info, queryParam *eventsv1alpha1.Query) (*eventsv1alpha1.APIResponse, error)
QueryLogs(user user.Info, query *loggingv1alpha2.Query) (*loggingv1alpha2.APIResponse, error)
ExportLogs(user user.Info, query *loggingv1alpha2.Query, writer io.Writer) error
Auditing(user user.Info, queryParam *auditingv1alpha1.Query) (*auditingv1alpha1.APIResponse, error)
DescribeNamespace(workspace, namespace string) (*corev1.Namespace, error)
DeleteNamespace(workspace, namespace string) error
UpdateNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error)
PatchNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error)
PatchWorkspace(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error)
}
type tenantOperator struct {
......@@ -99,10 +106,10 @@ func (t *tenantOperator) ListWorkspaces(user user.Info, queryParam *query.Query)
listWS := authorizer.AttributesRecord{
User: user,
Verb: "list",
APIGroup: "tenant.kubesphere.io",
APIVersion: "v1alpha2",
APIGroup: "*",
Resource: "workspaces",
ResourceRequest: true,
ResourceScope: request.GlobalScope,
}
decision, _, err := t.authorizer.Authorize(listWS)
......@@ -154,9 +161,9 @@ func (t *tenantOperator) ListWorkspaces(user user.Info, queryParam *query.Query)
}
result := resources.DefaultList(workspaces, queryParam, func(left runtime.Object, right runtime.Object, field query.Field) bool {
return resources.DefaultObjectMetaCompare(left.(*tenantv1alpha1.Workspace).ObjectMeta, right.(*tenantv1alpha1.Workspace).ObjectMeta, field)
return resources.DefaultObjectMetaCompare(left.(*tenantv1alpha2.WorkspaceTemplate).ObjectMeta, right.(*tenantv1alpha2.WorkspaceTemplate).ObjectMeta, field)
}, func(workspace runtime.Object, filter query.Filter) bool {
return resources.DefaultObjectMetaFilter(workspace.(*tenantv1alpha1.Workspace).ObjectMeta, filter)
return resources.DefaultObjectMetaFilter(workspace.(*tenantv1alpha2.WorkspaceTemplate).ObjectMeta, filter)
})
return result, nil
......@@ -167,11 +174,10 @@ func (t *tenantOperator) ListNamespaces(user user.Info, workspace string, queryP
listNSInWS := authorizer.AttributesRecord{
User: user,
Verb: "list",
APIGroup: "",
APIVersion: "v1",
Workspace: workspace,
Resource: "namespaces",
ResourceRequest: true,
ResourceScope: request.WorkspaceScope,
}
decision, _, err := t.authorizer.Authorize(listNSInWS)
......@@ -238,20 +244,78 @@ func (t *tenantOperator) ListNamespaces(user user.Info, workspace string, queryP
}
func (t *tenantOperator) CreateNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error) {
_, err := t.resourceGetter.Get(tenantv1alpha1.ResourcePluralWorkspace, "", workspace)
if err != nil {
return nil, err
}
namespace = appendWorkspaceLabel(namespace, workspace)
return t.k8sclient.CoreV1().Namespaces().Create(namespace)
}
func appendWorkspaceLabel(namespace *corev1.Namespace, workspace string) *corev1.Namespace {
if namespace.Labels == nil {
namespace.Labels = make(map[string]string, 0)
}
namespace.Labels[tenantv1alpha1.WorkspaceLabel] = workspace
return namespace
}
func (t *tenantOperator) DescribeNamespace(workspace, namespace string) (*corev1.Namespace, error) {
obj, err := t.resourceGetter.Get("namespaces", "", namespace)
if err != nil {
return nil, err
}
ns := obj.(*corev1.Namespace)
if ns.Labels[tenantv1alpha1.WorkspaceLabel] != workspace {
err := errors.NewNotFound(corev1.Resource("namespace"), namespace)
klog.Error(err)
return nil, err
}
return ns, nil
}
if namespace.Annotations == nil {
namespace.Annotations = make(map[string]string, 0)
func (t *tenantOperator) DeleteNamespace(workspace, namespace string) error {
_, err := t.DescribeNamespace(workspace, namespace)
if err != nil {
return err
}
return t.k8sclient.CoreV1().Namespaces().Delete(namespace, metav1.NewDeleteOptions(0))
}
namespace.Annotations[tenantv1alpha1.WorkspaceLabel] = workspace
func (t *tenantOperator) UpdateNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error) {
_, err := t.DescribeNamespace(workspace, namespace.Name)
if err != nil {
return nil, err
}
namespace = appendWorkspaceLabel(namespace, workspace)
return t.k8sclient.CoreV1().Namespaces().Update(namespace)
}
return t.k8sclient.CoreV1().Namespaces().Create(namespace)
func (t *tenantOperator) PatchNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error) {
_, err := t.DescribeNamespace(workspace, namespace.Name)
if err != nil {
return nil, err
}
if namespace.Labels != nil {
namespace.Labels[tenantv1alpha1.WorkspaceLabel] = workspace
}
data, err := json.Marshal(namespace)
if err != nil {
return nil, err
}
return t.k8sclient.CoreV1().Namespaces().Patch(namespace.Name, types.MergePatchType, data)
}
func (t *tenantOperator) PatchWorkspace(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error) {
_, err := t.DescribeWorkspace(workspace.Name)
if err != nil {
return nil, err
}
data, err := json.Marshal(workspace)
if err != nil {
return nil, err
}
return t.ksclient.TenantV1alpha2().WorkspaceTemplates().Patch(workspace.Name, types.MergePatchType, data)
}
func (t *tenantOperator) CreateWorkspace(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error) {
......
......@@ -22,7 +22,9 @@ import (
fakeistio "istio.io/client-go/pkg/clientset/versioned/fake"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/authentication/user"
fakek8s "k8s.io/client-go/kubernetes/fake"
"kubesphere.io/kubesphere/pkg/api"
......@@ -32,47 +34,45 @@ import (
"kubesphere.io/kubesphere/pkg/apiserver/query"
fakeks "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
"kubesphere.io/kubesphere/pkg/informers"
"reflect"
"testing"
)
func TestTenantOperator_ListWorkspaces(t *testing.T) {
tenantOperator := prepare()
tests := []struct {
name string
result *api.ListResult
username string
expectError error
}{
{
name: "list workspace",
username: "admin",
username: admin.Name,
result: &api.ListResult{
Items: workspaces,
TotalItems: len(workspaces),
Items: workspaceTemplates,
TotalItems: len(workspaceTemplates),
},
},
{
name: "list workspaces",
username: "regular",
username: tester2.Name,
result: &api.ListResult{
Items: []interface{}{workspaceBar},
Items: []interface{}{systemWorkspaceTmpl},
TotalItems: 1,
},
},
}
for _, test := range tests {
for i, test := range tests {
result, err := tenantOperator.ListWorkspaces(&user.DefaultInfo{Name: test.username}, query.New())
if err != nil {
if test.expectError != err {
t.Error(err)
if !reflect.DeepEqual(err, test.expectError) {
t.Errorf("got %#v, expected %#v", err, test.expectError)
}
continue
}
if diff := cmp.Diff(result, test.result); diff != "" {
t.Error(diff)
t.Errorf("case %d,%s", i, diff)
}
}
}
......@@ -80,47 +80,245 @@ func TestTenantOperator_ListWorkspaces(t *testing.T) {
func TestTenantOperator_ListNamespaces(t *testing.T) {
tenantOperator := prepare()
tests := []struct {
name string
result *api.ListResult
username string
workspace string
expectError error
}{
{
name: "list namespaces",
workspace: "foo",
username: "admin",
workspace: systemWorkspace.Name,
username: admin.Name,
result: &api.ListResult{
Items: []interface{}{foo2, foo1},
Items: []interface{}{kubesphereSystem, defaultNamespace},
TotalItems: 2,
},
},
{
name: "list namespaces",
workspace: "foo",
username: "regular",
workspace: systemWorkspace.Name,
username: tester1.Name,
result: &api.ListResult{
Items: []interface{}{},
TotalItems: 0,
},
},
{
name: "list namespaces",
workspace: "bar",
username: "regular",
workspace: testWorkspace.Name,
username: tester2.Name,
result: &api.ListResult{
Items: []interface{}{bar1},
Items: []interface{}{testNamespace},
TotalItems: 1,
},
},
}
for _, test := range tests {
for i, test := range tests {
result, err := tenantOperator.ListNamespaces(&user.DefaultInfo{Name: test.username}, test.workspace, query.New())
if err != nil {
if test.expectError != err {
t.Error(err)
if !reflect.DeepEqual(err, test.expectError) {
t.Errorf("got %#v, expected %#v", err, test.expectError)
}
continue
}
if diff := cmp.Diff(result, test.result); diff != "" {
t.Errorf("case %d, %s", i, diff)
}
}
}
func TestTenantOperator_DescribeNamespace(t *testing.T) {
tenantOperator := prepare()
tests := []struct {
result *corev1.Namespace
username string
workspace string
namespace string
expectError error
}{
{
result: testNamespace,
username: tester2.Name,
workspace: testWorkspace.Name,
namespace: testNamespace.Name,
expectError: nil,
},
{
result: testNamespace,
username: tester2.Name,
workspace: systemWorkspace.Name,
namespace: testNamespace.Name,
expectError: errors.NewNotFound(corev1.Resource("namespace"), testNamespace.Name),
},
}
for _, test := range tests {
result, err := tenantOperator.DescribeNamespace(test.workspace, test.namespace)
if err != nil {
if !reflect.DeepEqual(err, test.expectError) {
t.Errorf("got %#v, expected %#v", err, test.expectError)
}
continue
}
if diff := cmp.Diff(result, test.result); diff != "" {
t.Error(diff)
}
}
}
func TestTenantOperator_CreateNamespace(t *testing.T) {
tenantOperator := prepare()
tests := []struct {
result *corev1.Namespace
workspace string
namespace *corev1.Namespace
expectError error
}{
{
result: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: testWorkspace.Name},
},
},
workspace: testWorkspace.Name,
namespace: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
},
expectError: nil,
},
}
for i, test := range tests {
result, err := tenantOperator.CreateNamespace(test.workspace, test.namespace)
if err != nil {
if !reflect.DeepEqual(err, test.expectError) {
t.Errorf("case %d, got %#v, expected %#v", i, err, test.expectError)
}
continue
}
if diff := cmp.Diff(result, test.result); diff != "" {
t.Error(diff)
}
}
}
func TestTenantOperator_DeleteNamespace(t *testing.T) {
tenantOperator := prepare()
tests := []struct {
workspace string
namespace string
expectError error
}{
{
workspace: testWorkspace.Name,
namespace: kubesphereSystem.Name,
expectError: errors.NewNotFound(corev1.Resource("namespace"), kubesphereSystem.Name),
},
{
workspace: testWorkspace.Name,
namespace: testNamespace.Name,
expectError: nil,
},
}
for i, test := range tests {
err := tenantOperator.DeleteNamespace(test.workspace, test.namespace)
if err != nil {
if test.expectError != nil && test.expectError.Error() == err.Error() {
continue
} else {
if !reflect.DeepEqual(err, test.expectError) {
t.Errorf("case %d, got %#v, expected %#v", i, err, test.expectError)
}
}
}
}
}
func TestTenantOperator_UpdateNamespace(t *testing.T) {
tenantOperator := prepare()
tests := []struct {
result *corev1.Namespace
workspace string
namespace *corev1.Namespace
expectError error
}{
{
result: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test-namespace",
Annotations: map[string]string{"test": "test"},
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: testWorkspace.Name},
},
},
workspace: testWorkspace.Name,
namespace: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test-namespace",
Annotations: map[string]string{"test": "test"},
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: testWorkspace.Name},
},
},
expectError: nil,
},
}
for i, test := range tests {
result, err := tenantOperator.UpdateNamespace(test.workspace, test.namespace)
if err != nil {
if !reflect.DeepEqual(err, test.expectError) {
t.Errorf("case %d, got %#v, expected %#v", i, err, test.expectError)
}
continue
}
if diff := cmp.Diff(result, test.result); diff != "" {
t.Error(diff)
}
}
}
func TestTenantOperator_PatchNamespace(t *testing.T) {
tenantOperator := prepare()
tests := []struct {
result *corev1.Namespace
workspace string
patch *corev1.Namespace
expectError error
}{
{
result: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test-namespace",
Annotations: map[string]string{"test": "test2"},
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: testWorkspace.Name},
},
},
workspace: testWorkspace.Name,
patch: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test-namespace",
Annotations: map[string]string{"test": "test2"},
},
},
expectError: nil,
},
}
for i, test := range tests {
result, err := tenantOperator.PatchNamespace(test.workspace, test.patch)
if err != nil {
if !reflect.DeepEqual(err, test.expectError) {
t.Errorf("case %d, got %#v, expected %#v", i, err, test.expectError)
}
continue
}
......@@ -132,28 +330,56 @@ func TestTenantOperator_ListNamespaces(t *testing.T) {
}
var (
foo1 = &corev1.Namespace{
admin = user.DefaultInfo{
Name: "admin",
}
tester1 = user.DefaultInfo{
Name: "tester1",
}
tester2 = user.DefaultInfo{
Name: "tester2",
}
systemWorkspaceTmpl = &tenantv1alpha2.WorkspaceTemplate{
ObjectMeta: metav1.ObjectMeta{
Name: "foo1",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: "foo"},
Name: "system-workspace",
},
}
foo2 = &corev1.Namespace{
testWorkspaceTmpl = &tenantv1alpha2.WorkspaceTemplate{
ObjectMeta: metav1.ObjectMeta{
Name: "test-workspace",
},
}
systemWorkspace = &tenantv1alpha1.Workspace{
ObjectMeta: metav1.ObjectMeta{
Name: "system-workspace",
},
}
testWorkspace = &tenantv1alpha1.Workspace{
ObjectMeta: metav1.ObjectMeta{
Name: "test-workspace",
},
}
kubesphereSystem = &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "kubesphere-system",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: systemWorkspace.Name},
},
}
defaultNamespace = &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "foo2",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: "foo"},
Name: "default",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: systemWorkspace.Name},
},
}
bar1 = &corev1.Namespace{
testNamespace = &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "bar1",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: "bar"},
Name: "test-namespace",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: testWorkspace.Name},
},
}
adminGlobalRole = &iamv1alpha2.GlobalRole{
platformAdmin = &iamv1alpha2.GlobalRole{
ObjectMeta: metav1.ObjectMeta{
Name: "global-admin",
Name: "platform-admin",
},
Rules: []rbacv1.PolicyRule{
{
......@@ -163,79 +389,67 @@ var (
},
},
}
regularGlobalRole = &iamv1alpha2.GlobalRole{
platformRegular = &iamv1alpha2.GlobalRole{
ObjectMeta: metav1.ObjectMeta{
Name: "regular",
},
Rules: []rbacv1.PolicyRule{
{
Verbs: []string{},
APIGroups: []string{},
Resources: []string{},
},
Name: "platform-regular",
},
Rules: []rbacv1.PolicyRule{},
}
reguarWorksapceRole = &iamv1alpha2.WorkspaceRole{
systemWorkspaceRegular = &iamv1alpha2.WorkspaceRole{
ObjectMeta: metav1.ObjectMeta{
Name: "workspace-regular",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: "bar"},
},
Rules: []rbacv1.PolicyRule{
{
Verbs: []string{},
APIGroups: []string{},
Resources: []string{},
},
Name: "system-workspace-regular",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: systemWorkspace.Name},
},
Rules: []rbacv1.PolicyRule{},
}
adminGlobalRoleBinding = &iamv1alpha2.GlobalRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "global-admin",
Name: admin.Name + "-" + platformAdmin.Name,
},
Subjects: []rbacv1.Subject{{
Kind: "User",
Name: "admin",
Name: admin.Name,
}},
RoleRef: rbacv1.RoleRef{
APIGroup: iamv1alpha2.SchemeGroupVersion.String(),
Kind: iamv1alpha2.ResourceKindGlobalRole,
Name: "global-admin",
Name: platformAdmin.Name,
},
}
regularGlobalRoleBinding = &iamv1alpha2.GlobalRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "regular",
Name: tester1.Name + "-" + platformRegular.Name,
},
Subjects: []rbacv1.Subject{{
Kind: "User",
Name: "regular",
Name: tester1.Name,
}},
RoleRef: rbacv1.RoleRef{
APIGroup: iamv1alpha2.SchemeGroupVersion.String(),
Kind: iamv1alpha2.ResourceKindGlobalRole,
Name: "regular",
Name: platformRegular.Name,
},
}
regularWorkspaceRoleBinding = &iamv1alpha2.WorkspaceRoleBinding{
systemWorkspaceRegularRoleBinding = &iamv1alpha2.WorkspaceRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "workspace-regular",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: "bar"},
Name: tester2.Name + "-" + systemWorkspaceRegular.Name,
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: systemWorkspace.Name},
},
Subjects: []rbacv1.Subject{{
Kind: "User",
Name: "regular",
Name: tester2.Name,
}},
RoleRef: rbacv1.RoleRef{
APIGroup: iamv1alpha2.SchemeGroupVersion.String(),
Kind: iamv1alpha2.ResourceKindGlobalRole,
Name: "workspace-regular",
Name: systemWorkspaceRegular.Name,
},
}
bar1NamespaceRole = &rbacv1.Role{
testNamespaceAdmin = &rbacv1.Role{
ObjectMeta: metav1.ObjectMeta{
Name: "admin",
Namespace: "bar1",
Namespace: testNamespace.Name,
},
Rules: []rbacv1.PolicyRule{
{
......@@ -245,52 +459,48 @@ var (
},
},
}
bar1NamespaceRoleBinding = &rbacv1.RoleBinding{
testNamespaceAdminRoleBinding = &rbacv1.RoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "admin",
Namespace: "bar1",
Namespace: testNamespace.Name,
},
Subjects: []rbacv1.Subject{{
Kind: "User",
Name: "regular",
Name: tester2.Name,
}},
RoleRef: rbacv1.RoleRef{
APIGroup: rbacv1.SchemeGroupVersion.String(),
Kind: "Role",
Name: "admin",
},
}
workspaceFoo = &tenantv1alpha2.WorkspaceTemplate{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
}
workspaceBar = &tenantv1alpha2.WorkspaceTemplate{
ObjectMeta: metav1.ObjectMeta{
Name: "bar",
Name: testNamespaceAdmin.Name,
},
}
workspaces = []interface{}{workspaceFoo, workspaceBar}
namespaces = []interface{}{foo1, foo2, bar1}
globalRoles = []interface{}{adminGlobalRole, regularGlobalRole}
workspaces = []interface{}{systemWorkspace, testWorkspace}
workspaceTemplates = []interface{}{testWorkspaceTmpl, systemWorkspaceTmpl}
namespaces = []interface{}{kubesphereSystem, defaultNamespace, testNamespace}
globalRoles = []interface{}{platformAdmin, platformRegular}
globalRoleBindings = []interface{}{adminGlobalRoleBinding, regularGlobalRoleBinding}
workspaceRoles = []interface{}{regularGlobalRole}
workspaceRoleBindings = []interface{}{regularWorkspaceRoleBinding}
namespaceRoles = []interface{}{bar1NamespaceRole}
namespaceRoleBindings = []interface{}{bar1NamespaceRoleBinding}
workspaceRoles = []interface{}{systemWorkspaceRegular}
workspaceRoleBindings = []interface{}{systemWorkspaceRegularRoleBinding}
namespaceRoles = []interface{}{testNamespaceAdmin}
namespaceRoleBindings = []interface{}{testNamespaceAdminRoleBinding}
)
func prepare() Interface {
ksClient := fakeks.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset()
ksClient := fakeks.NewSimpleClientset([]runtime.Object{testWorkspace, systemWorkspace}...)
k8sClient := fakek8s.NewSimpleClientset([]runtime.Object{testNamespace, kubesphereSystem}...)
istioClient := fakeistio.NewSimpleClientset()
appClient := fakeapp.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, appClient, nil, nil)
for _, workspace := range workspaces {
fakeInformerFactory.KubeSphereSharedInformerFactory().Tenant().V1alpha1().
Workspaces().Informer().GetIndexer().Add(workspace)
}
for _, workspaceTmpl := range workspaceTemplates {
fakeInformerFactory.KubeSphereSharedInformerFactory().Tenant().V1alpha2().
WorkspaceTemplates().Informer().GetIndexer().Add(workspace)
WorkspaceTemplates().Informer().GetIndexer().Add(workspaceTmpl)
}
for _, namespace := range namespaces {
......@@ -328,5 +538,5 @@ func prepare() Interface {
RoleBindings().Informer().GetIndexer().Add(roleBinding)
}
return New(fakeInformerFactory, nil, nil, nil, nil, nil)
return New(fakeInformerFactory, k8sClient, ksClient, nil, nil, nil)
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册