add test case

Signed-off-by: hongming <talonwan@yunify.com>
This commit is contained in:
hongming
2020-06-11 11:55:11 +08:00
parent bafeecfee6
commit b1d996f4a7
5 changed files with 362 additions and 190 deletions

View File

@@ -61,9 +61,10 @@ func (h *iamHandler) DescribeUser(request *restful.Request, response *restful.Re
} }
func (h *iamHandler) RetrieveMemberRoleTemplates(request *restful.Request, response *restful.Response) { func (h *iamHandler) RetrieveMemberRoleTemplates(request *restful.Request, response *restful.Response) {
username := request.PathParameter("user")
if strings.HasSuffix(request.Request.URL.Path, iamv1alpha2.ResourcesPluralGlobalRole) { if strings.HasSuffix(request.Request.URL.Path, iamv1alpha2.ResourcesPluralGlobalRole) {
username := request.PathParameter("user")
globalRole, err := h.am.GetGlobalRoleOfUser(username) globalRole, err := h.am.GetGlobalRoleOfUser(username)
if err != nil { if err != nil {
@@ -93,8 +94,8 @@ func (h *iamHandler) RetrieveMemberRoleTemplates(request *restful.Request, respo
} }
if strings.HasSuffix(request.Request.URL.Path, iamv1alpha2.ResourcesPluralClusterRole) { if strings.HasSuffix(request.Request.URL.Path, iamv1alpha2.ResourcesPluralClusterRole) {
username := request.PathParameter("clustermember")
clusterRole, err := h.am.GetClusterRoleOfUser(username) clusterRole, err := h.am.GetClusterRoleOfUser(username)
if err != nil { if err != nil {
// if role binding not exist return empty list // if role binding not exist return empty list
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
@@ -111,7 +112,6 @@ func (h *iamHandler) RetrieveMemberRoleTemplates(request *restful.Request, respo
Ascending: false, Ascending: false,
Filters: map[query.Field]query.Value{iamv1alpha2.AggregateTo: query.Value(clusterRole.Name)}, Filters: map[query.Field]query.Value{iamv1alpha2.AggregateTo: query.Value(clusterRole.Name)},
}) })
if err != nil { if err != nil {
api.HandleInternalError(response, request, err) api.HandleInternalError(response, request, err)
return return
@@ -123,9 +123,8 @@ func (h *iamHandler) RetrieveMemberRoleTemplates(request *restful.Request, respo
if strings.HasSuffix(request.Request.URL.Path, iamv1alpha2.ResourcesPluralWorkspaceRole) { if strings.HasSuffix(request.Request.URL.Path, iamv1alpha2.ResourcesPluralWorkspaceRole) {
workspace := request.PathParameter("workspace") workspace := request.PathParameter("workspace")
username := request.PathParameter("workspacemember")
workspaceRole, err := h.am.GetWorkspaceRoleOfUser(username, workspace) workspaceRole, err := h.am.GetWorkspaceRoleOfUser(username, workspace)
if err != nil { if err != nil {
// if role binding not exist return empty list // if role binding not exist return empty list
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
@@ -142,7 +141,6 @@ func (h *iamHandler) RetrieveMemberRoleTemplates(request *restful.Request, respo
Ascending: false, Ascending: false,
Filters: map[query.Field]query.Value{iamv1alpha2.AggregateTo: query.Value(workspaceRole.Name)}, Filters: map[query.Field]query.Value{iamv1alpha2.AggregateTo: query.Value(workspaceRole.Name)},
}) })
if err != nil { if err != nil {
api.HandleInternalError(response, request, err) api.HandleInternalError(response, request, err)
return return
@@ -154,7 +152,7 @@ func (h *iamHandler) RetrieveMemberRoleTemplates(request *restful.Request, respo
if strings.HasSuffix(request.Request.URL.Path, iamv1alpha2.ResourcesPluralRole) { if strings.HasSuffix(request.Request.URL.Path, iamv1alpha2.ResourcesPluralRole) {
namespace, err := h.resolveNamespace(request.PathParameter("namespace"), request.PathParameter("devops")) namespace, err := h.resolveNamespace(request.PathParameter("namespace"), request.PathParameter("devops"))
username := request.PathParameter("member")
if err != nil { if err != nil {
api.HandleInternalError(response, request, err) api.HandleInternalError(response, request, err)
return return
@@ -280,7 +278,7 @@ func (h *iamHandler) ListNamespaceMembers(request *restful.Request, response *re
} }
func (h *iamHandler) DescribeNamespaceMember(request *restful.Request, response *restful.Response) { func (h *iamHandler) DescribeNamespaceMember(request *restful.Request, response *restful.Response) {
username := request.PathParameter("user") username := request.PathParameter("member")
namespace, err := h.resolveNamespace(request.PathParameter("namespace"), request.PathParameter("devops")) namespace, err := h.resolveNamespace(request.PathParameter("namespace"), request.PathParameter("devops"))
if err != nil { if err != nil {
@@ -347,7 +345,7 @@ func (h *iamHandler) ListWorkspaceMembers(request *restful.Request, response *re
func (h *iamHandler) DescribeWorkspaceMember(request *restful.Request, response *restful.Response) { func (h *iamHandler) DescribeWorkspaceMember(request *restful.Request, response *restful.Response) {
workspace := request.PathParameter("workspace") workspace := request.PathParameter("workspace")
username := request.PathParameter("user") username := request.PathParameter("workspacemember")
queryParam := query.New() queryParam := query.New()
queryParam.Filters[query.FieldName] = query.Value(username) queryParam.Filters[query.FieldName] = query.Value(username)
@@ -828,7 +826,7 @@ func (h *iamHandler) CreateWorkspaceMembers(request *restful.Request, response *
func (h *iamHandler) RemoveWorkspaceMember(request *restful.Request, response *restful.Response) { func (h *iamHandler) RemoveWorkspaceMember(request *restful.Request, response *restful.Response) {
workspace := request.PathParameter("workspace") workspace := request.PathParameter("workspace")
username := request.PathParameter("user") username := request.PathParameter("workspacemember")
err := h.am.RemoveUserFromWorkspace(username, workspace) err := h.am.RemoveUserFromWorkspace(username, workspace)
@@ -843,7 +841,7 @@ func (h *iamHandler) RemoveWorkspaceMember(request *restful.Request, response *r
func (h *iamHandler) UpdateWorkspaceMember(request *restful.Request, response *restful.Response) { func (h *iamHandler) UpdateWorkspaceMember(request *restful.Request, response *restful.Response) {
workspace := request.PathParameter("workspace") workspace := request.PathParameter("workspace")
username := request.PathParameter("user") username := request.PathParameter("workspacemember")
var member Member var member Member
@@ -905,7 +903,7 @@ func (h *iamHandler) CreateNamespaceMembers(request *restful.Request, response *
} }
func (h *iamHandler) UpdateNamespaceMember(request *restful.Request, response *restful.Response) { func (h *iamHandler) UpdateNamespaceMember(request *restful.Request, response *restful.Response) {
username := request.PathParameter("user") username := request.PathParameter("member")
namespace, err := h.resolveNamespace(request.PathParameter("namespace"), request.PathParameter("devops")) namespace, err := h.resolveNamespace(request.PathParameter("namespace"), request.PathParameter("devops"))
if err != nil { if err != nil {
@@ -942,7 +940,7 @@ func (h *iamHandler) UpdateNamespaceMember(request *restful.Request, response *r
} }
func (h *iamHandler) RemoveNamespaceMember(request *restful.Request, response *restful.Response) { func (h *iamHandler) RemoveNamespaceMember(request *restful.Request, response *restful.Response) {
username := request.PathParameter("user") username := request.PathParameter("member")
namespace, err := h.resolveNamespace(request.PathParameter("namespace"), request.PathParameter("devops")) namespace, err := h.resolveNamespace(request.PathParameter("namespace"), request.PathParameter("devops"))
if err != nil { if err != nil {

View File

@@ -103,25 +103,25 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf
Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{iamv1alpha2.User{}}}). Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{iamv1alpha2.User{}}}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/workspaces/{workspace}/users"). ws.Route(ws.GET("/workspaces/{workspace}/workspacemembers").
To(handler.ListWorkspaceMembers). To(handler.ListWorkspaceMembers).
Doc("List all members in the specified workspace."). Doc("List all members in the specified workspace.").
Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("workspace", "workspace name")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) 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). To(handler.DescribeWorkspaceMember).
Doc("Retrieve workspace member details."). Doc("Retrieve workspace member details.").
Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("user", "username")). Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.POST("/workspaces/{workspace}/users"). ws.Route(ws.POST("/workspaces/{workspace}/workspacemembers").
To(handler.CreateWorkspaceMembers). To(handler.CreateWorkspaceMembers).
Doc("Batch add workspace members."). Doc("Batch add workspace members.").
Reads([]Member{}). Reads([]Member{}).
Returns(http.StatusOK, api.StatusOK, errors.None). Returns(http.StatusOK, api.StatusOK, errors.None).
Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("workspace", "workspace name")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) 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). To(handler.UpdateWorkspaceMember).
Doc("Update member in workspace."). Doc("Update member in workspace.").
Reads(Member{}). Reads(Member{}).
@@ -129,32 +129,32 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf
Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("user", "username")). Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) 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). To(handler.RemoveWorkspaceMember).
Doc("Remove member in workspace."). Doc("Remove member in workspace.").
Param(ws.PathParameter("workspace", "workspace name")). Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("user", "username")). Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/namespaces/{namespace}/users"). ws.Route(ws.GET("/namespaces/{namespace}/members").
To(handler.ListNamespaceMembers). To(handler.ListNamespaceMembers).
Doc("List all members in the specified namespace."). Doc("List all members in the specified namespace.").
Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("namespace", "namespace")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) 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). To(handler.DescribeNamespaceMember).
Doc("Retrieve namespace member details."). Doc("Retrieve namespace member details.").
Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")). Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.POST("/namespaces/{namespace}/users"). ws.Route(ws.POST("/namespaces/{namespace}/members").
To(handler.CreateNamespaceMembers). To(handler.CreateNamespaceMembers).
Doc("Batch add namespace members."). Doc("Batch add namespace members.").
Reads([]Member{}). Reads([]Member{}).
Returns(http.StatusOK, api.StatusOK, errors.None). Returns(http.StatusOK, api.StatusOK, errors.None).
Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("namespace", "namespace")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) 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). To(handler.UpdateNamespaceMember).
Doc("Update member in namespace."). Doc("Update member in namespace.").
Reads(Member{}). Reads(Member{}).
@@ -162,44 +162,44 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf
Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")). Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) 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). To(handler.RemoveNamespaceMember).
Doc("Remove member in namespace."). Doc("Remove member in namespace.").
Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")). Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/devops/{devops}/users"). ws.Route(ws.GET("/devops/{devops}/members").
To(handler.ListNamespaceMembers). To(handler.ListNamespaceMembers).
Doc("List all members in the specified namespace."). Doc("List all members in the specified namespace.").
Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("namespace", "namespace")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) 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). To(handler.DescribeNamespaceMember).
Doc("Retrieve namespace member details."). Doc("Retrieve namespace member details.").
Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")). Param(ws.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.POST("/devops/{devops}/users"). ws.Route(ws.POST("/devops/{devops}/members").
To(handler.CreateNamespaceMembers). To(handler.CreateNamespaceMembers).
Doc("Batch add namespace members."). Doc("Batch add namespace members.").
Reads([]Member{}). Reads([]Member{}).
Returns(http.StatusOK, api.StatusOK, errors.None). Returns(http.StatusOK, api.StatusOK, errors.None).
Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("namespace", "namespace")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) 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). To(handler.UpdateNamespaceMember).
Doc("Update member in namespace."). Doc("Update member in namespace.").
Reads(Member{}). Reads(Member{}).
Returns(http.StatusOK, api.StatusOK, errors.None). Returns(http.StatusOK, api.StatusOK, errors.None).
Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")). Param(ws.PathParameter("member", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) 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). To(handler.RemoveNamespaceMember).
Doc("Remove member in namespace."). Doc("Remove member in namespace.").
Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")). Param(ws.PathParameter("member", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
// globalroles // globalroles
@@ -375,27 +375,27 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf
Param(ws.PathParameter("user", "username")). Param(ws.PathParameter("user", "username")).
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.GlobalRole{}). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.GlobalRole{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/users/{user}/clusterroles"). ws.Route(ws.GET("/clustermembers/{clustermember}/clusterroles").
To(handler.RetrieveMemberRoleTemplates). To(handler.RetrieveMemberRoleTemplates).
Doc("Retrieve user's role templates in cluster."). Doc("Retrieve user's role templates in cluster.").
Param(ws.PathParameter("user", "username")). Param(ws.PathParameter("user", "username")).
Returns(http.StatusOK, api.StatusOK, rbacv1.ClusterRole{}). Returns(http.StatusOK, api.StatusOK, rbacv1.ClusterRole{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) 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). To(handler.RetrieveMemberRoleTemplates).
Doc("Retrieve member's role templates in workspace."). Doc("Retrieve member's role templates in workspace.").
Param(ws.PathParameter("workspace", "workspace")). Param(ws.PathParameter("workspace", "workspace")).
Param(ws.PathParameter("user", "username")). Param(ws.PathParameter("user", "username")).
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.WorkspaceRole{}). Returns(http.StatusOK, api.StatusOK, iamv1alpha2.WorkspaceRole{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) 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). To(handler.RetrieveMemberRoleTemplates).
Doc("Retrieve member's role templates in namespace."). Doc("Retrieve member's role templates in namespace.").
Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("user", "username")). Param(ws.PathParameter("user", "username")).
Returns(http.StatusOK, api.StatusOK, rbacv1.Role{}). Returns(http.StatusOK, api.StatusOK, rbacv1.Role{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) 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). To(handler.RetrieveMemberRoleTemplates).
Doc("Retrieve member's role templates in devops project."). Doc("Retrieve member's role templates in devops project.").
Param(ws.PathParameter("namespace", "namespace")). Param(ws.PathParameter("namespace", "namespace")).

View File

@@ -32,7 +32,6 @@ import (
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned" kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource" resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"net/http"
) )
type AccessManagementInterface interface { type AccessManagementInterface interface {
@@ -114,17 +113,8 @@ func (am *amOperator) GetGlobalRoleOfUser(username string) (*iamv1alpha2.GlobalR
return out, nil return out, nil
} }
err = &errors.StatusError{ErrStatus: metav1.Status{ err = errors.NewNotFound(iamv1alpha2.Resource(iamv1alpha2.ResourcesSingularGlobalRoleBinding), username)
Status: metav1.StatusFailure, klog.Error(err)
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),
}}
return nil, err return nil, err
} }
@@ -157,17 +147,8 @@ func (am *amOperator) GetWorkspaceRoleOfUser(username, workspace string) (*iamv1
return out, nil return out, nil
} }
err = &errors.StatusError{ErrStatus: metav1.Status{ err = errors.NewNotFound(iamv1alpha2.Resource(iamv1alpha2.ResourcesSingularWorkspaceRoleBinding), username)
Status: metav1.StatusFailure, klog.Error(err)
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),
}}
return nil, err return nil, err
} }
@@ -197,17 +178,8 @@ func (am *amOperator) GetNamespaceRoleOfUser(username, namespace string) (*rbacv
return out, nil return out, nil
} }
err = &errors.StatusError{ErrStatus: metav1.Status{ err = errors.NewNotFound(iamv1alpha2.Resource(iamv1alpha2.ResourcesSingularRoleBinding), username)
Status: metav1.StatusFailure, klog.Error(err)
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),
}}
return nil, err return nil, err
} }
@@ -237,17 +209,9 @@ func (am *amOperator) GetClusterRoleOfUser(username string) (*rbacv1.ClusterRole
out.Annotations[iamv1alpha2.ClusterRoleAnnotation] = role.Name out.Annotations[iamv1alpha2.ClusterRoleAnnotation] = role.Name
return out, nil 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 return nil, err
} }

View File

@@ -283,7 +283,7 @@ func (t *tenantOperator) DeleteNamespace(workspace, namespace string) error {
} }
func (t *tenantOperator) UpdateNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error) { func (t *tenantOperator) UpdateNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error) {
_, err := t.DescribeNamespace(workspace, namespace.Namespace) _, err := t.DescribeNamespace(workspace, namespace.Name)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -22,7 +22,9 @@ import (
fakeistio "istio.io/client-go/pkg/clientset/versioned/fake" fakeistio "istio.io/client-go/pkg/clientset/versioned/fake"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1" rbacv1 "k8s.io/api/rbac/v1"
"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/runtime"
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
fakek8s "k8s.io/client-go/kubernetes/fake" fakek8s "k8s.io/client-go/kubernetes/fake"
"kubesphere.io/kubesphere/pkg/api" "kubesphere.io/kubesphere/pkg/api"
@@ -32,41 +34,130 @@ import (
"kubesphere.io/kubesphere/pkg/apiserver/query" "kubesphere.io/kubesphere/pkg/apiserver/query"
fakeks "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake" fakeks "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
"reflect"
"testing" "testing"
) )
func TestTenantOperator_ListWorkspaces(t *testing.T) { func TestTenantOperator_ListWorkspaces(t *testing.T) {
tenantOperator := prepare() tenantOperator := prepare()
tests := []struct { tests := []struct {
name string
result *api.ListResult result *api.ListResult
username string username string
expectError error expectError error
}{ }{
{ {
name: "list workspace", username: admin.Name,
username: "admin",
result: &api.ListResult{ result: &api.ListResult{
Items: workspaces, Items: workspaceTemplates,
TotalItems: len(workspaces), TotalItems: len(workspaceTemplates),
}, },
}, },
{ {
name: "list workspaces", username: tester2.Name,
username: "regular",
result: &api.ListResult{ result: &api.ListResult{
Items: []interface{}{workspaceBar}, Items: []interface{}{systemWorkspaceTmpl},
TotalItems: 1, TotalItems: 1,
}, },
}, },
} }
for _, test := range tests { for i, test := range tests {
result, err := tenantOperator.ListWorkspaces(&user.DefaultInfo{Name: test.username}, query.New()) result, err := tenantOperator.ListWorkspaces(&user.DefaultInfo{Name: test.username}, query.New())
if err != nil { if err != nil {
if test.expectError != err { if !reflect.DeepEqual(err, test.expectError) {
t.Error(err) 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_ListNamespaces(t *testing.T) {
tenantOperator := prepare()
tests := []struct {
result *api.ListResult
username string
workspace string
expectError error
}{
{
workspace: systemWorkspace.Name,
username: admin.Name,
result: &api.ListResult{
Items: []interface{}{kubesphereSystem, defaultNamespace},
TotalItems: 2,
},
},
{
workspace: systemWorkspace.Name,
username: tester1.Name,
result: &api.ListResult{
Items: []interface{}{},
TotalItems: 0,
},
},
{
workspace: testWorkspace.Name,
username: tester2.Name,
result: &api.ListResult{
Items: []interface{}{testNamespace},
TotalItems: 1,
},
},
}
for i, test := range tests {
result, err := tenantOperator.ListNamespaces(&user.DefaultInfo{Name: test.username}, test.workspace, query.New())
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.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 continue
} }
@@ -77,50 +168,157 @@ func TestTenantOperator_ListWorkspaces(t *testing.T) {
} }
} }
func TestTenantOperator_ListNamespaces(t *testing.T) { func TestTenantOperator_CreateNamespace(t *testing.T) {
tenantOperator := prepare() tenantOperator := prepare()
tests := []struct { tests := []struct {
name string result *corev1.Namespace
result *api.ListResult
username string
workspace string workspace string
namespace *corev1.Namespace
expectError error expectError error
}{ }{
{ {
name: "list namespaces", result: &corev1.Namespace{
workspace: "foo", ObjectMeta: metav1.ObjectMeta{
username: "admin", Name: "test",
result: &api.ListResult{ Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: testWorkspace.Name},
Items: []interface{}{foo2, foo1}, },
TotalItems: 2,
}, },
}, workspace: testWorkspace.Name,
{ namespace: &corev1.Namespace{
name: "list namespaces", ObjectMeta: metav1.ObjectMeta{
workspace: "foo", Name: "test",
username: "regular", },
result: &api.ListResult{
Items: []interface{}{},
TotalItems: 0,
},
},
{
name: "list namespaces",
workspace: "bar",
username: "regular",
result: &api.ListResult{
Items: []interface{}{bar1},
TotalItems: 1,
}, },
expectError: nil,
}, },
} }
for _, test := range tests { for i, test := range tests {
result, err := tenantOperator.ListNamespaces(&user.DefaultInfo{Name: test.username}, test.workspace, query.New()) result, err := tenantOperator.CreateNamespace(test.workspace, test.namespace)
if err != nil { if err != nil {
if test.expectError != err { if !reflect.DeepEqual(err, test.expectError) {
t.Error(err) 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 continue
} }
@@ -132,28 +330,56 @@ func TestTenantOperator_ListNamespaces(t *testing.T) {
} }
var ( 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{ ObjectMeta: metav1.ObjectMeta{
Name: "foo1", Name: "system-workspace",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: "foo"},
}, },
} }
testWorkspaceTmpl = &tenantv1alpha2.WorkspaceTemplate{
foo2 = &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "foo2", Name: "test-workspace",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: "foo"},
}, },
} }
bar1 = &corev1.Namespace{ systemWorkspace = &tenantv1alpha1.Workspace{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "bar1", Name: "system-workspace",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: "bar"},
}, },
} }
adminGlobalRole = &iamv1alpha2.GlobalRole{ testWorkspace = &tenantv1alpha1.Workspace{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "global-admin", 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: "default",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: systemWorkspace.Name},
},
}
testNamespace = &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test-namespace",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: testWorkspace.Name},
},
}
platformAdmin = &iamv1alpha2.GlobalRole{
ObjectMeta: metav1.ObjectMeta{
Name: "platform-admin",
}, },
Rules: []rbacv1.PolicyRule{ Rules: []rbacv1.PolicyRule{
{ {
@@ -163,79 +389,67 @@ var (
}, },
}, },
} }
regularGlobalRole = &iamv1alpha2.GlobalRole{ platformRegular = &iamv1alpha2.GlobalRole{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "regular", Name: "platform-regular",
},
Rules: []rbacv1.PolicyRule{
{
Verbs: []string{},
APIGroups: []string{},
Resources: []string{},
},
}, },
Rules: []rbacv1.PolicyRule{},
} }
reguarWorksapceRole = &iamv1alpha2.WorkspaceRole{ systemWorkspaceRegular = &iamv1alpha2.WorkspaceRole{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "workspace-regular", Name: "system-workspace-regular",
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: "bar"}, Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: systemWorkspace.Name},
},
Rules: []rbacv1.PolicyRule{
{
Verbs: []string{},
APIGroups: []string{},
Resources: []string{},
},
}, },
Rules: []rbacv1.PolicyRule{},
} }
adminGlobalRoleBinding = &iamv1alpha2.GlobalRoleBinding{ adminGlobalRoleBinding = &iamv1alpha2.GlobalRoleBinding{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "global-admin", Name: admin.Name + "-" + platformAdmin.Name,
}, },
Subjects: []rbacv1.Subject{{ Subjects: []rbacv1.Subject{{
Kind: "User", Kind: "User",
Name: "admin", Name: admin.Name,
}}, }},
RoleRef: rbacv1.RoleRef{ RoleRef: rbacv1.RoleRef{
APIGroup: iamv1alpha2.SchemeGroupVersion.String(), APIGroup: iamv1alpha2.SchemeGroupVersion.String(),
Kind: iamv1alpha2.ResourceKindGlobalRole, Kind: iamv1alpha2.ResourceKindGlobalRole,
Name: "global-admin", Name: platformAdmin.Name,
}, },
} }
regularGlobalRoleBinding = &iamv1alpha2.GlobalRoleBinding{ regularGlobalRoleBinding = &iamv1alpha2.GlobalRoleBinding{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "regular", Name: tester1.Name + "-" + platformRegular.Name,
}, },
Subjects: []rbacv1.Subject{{ Subjects: []rbacv1.Subject{{
Kind: "User", Kind: "User",
Name: "regular", Name: tester1.Name,
}}, }},
RoleRef: rbacv1.RoleRef{ RoleRef: rbacv1.RoleRef{
APIGroup: iamv1alpha2.SchemeGroupVersion.String(), APIGroup: iamv1alpha2.SchemeGroupVersion.String(),
Kind: iamv1alpha2.ResourceKindGlobalRole, Kind: iamv1alpha2.ResourceKindGlobalRole,
Name: "regular", Name: platformRegular.Name,
}, },
} }
regularWorkspaceRoleBinding = &iamv1alpha2.WorkspaceRoleBinding{ systemWorkspaceRegularRoleBinding = &iamv1alpha2.WorkspaceRoleBinding{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "workspace-regular", Name: tester2.Name + "-" + systemWorkspaceRegular.Name,
Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: "bar"}, Labels: map[string]string{tenantv1alpha1.WorkspaceLabel: systemWorkspace.Name},
}, },
Subjects: []rbacv1.Subject{{ Subjects: []rbacv1.Subject{{
Kind: "User", Kind: "User",
Name: "regular", Name: tester2.Name,
}}, }},
RoleRef: rbacv1.RoleRef{ RoleRef: rbacv1.RoleRef{
APIGroup: iamv1alpha2.SchemeGroupVersion.String(), APIGroup: iamv1alpha2.SchemeGroupVersion.String(),
Kind: iamv1alpha2.ResourceKindGlobalRole, Kind: iamv1alpha2.ResourceKindGlobalRole,
Name: "workspace-regular", Name: systemWorkspaceRegular.Name,
}, },
} }
bar1NamespaceRole = &rbacv1.Role{ testNamespaceAdmin = &rbacv1.Role{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "admin", Name: "admin",
Namespace: "bar1", Namespace: testNamespace.Name,
}, },
Rules: []rbacv1.PolicyRule{ Rules: []rbacv1.PolicyRule{
{ {
@@ -245,52 +459,48 @@ var (
}, },
}, },
} }
bar1NamespaceRoleBinding = &rbacv1.RoleBinding{ testNamespaceAdminRoleBinding = &rbacv1.RoleBinding{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "admin", Name: "admin",
Namespace: "bar1", Namespace: testNamespace.Name,
}, },
Subjects: []rbacv1.Subject{{ Subjects: []rbacv1.Subject{{
Kind: "User", Kind: "User",
Name: "regular", Name: tester2.Name,
}}, }},
RoleRef: rbacv1.RoleRef{ RoleRef: rbacv1.RoleRef{
APIGroup: rbacv1.SchemeGroupVersion.String(), APIGroup: rbacv1.SchemeGroupVersion.String(),
Kind: "Role", Kind: "Role",
Name: "admin", Name: testNamespaceAdmin.Name,
},
}
workspaceFoo = &tenantv1alpha2.WorkspaceTemplate{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
}
workspaceBar = &tenantv1alpha2.WorkspaceTemplate{
ObjectMeta: metav1.ObjectMeta{
Name: "bar",
}, },
} }
workspaces = []interface{}{workspaceFoo, workspaceBar} workspaces = []interface{}{systemWorkspace, testWorkspace}
namespaces = []interface{}{foo1, foo2, bar1} workspaceTemplates = []interface{}{testWorkspaceTmpl, systemWorkspaceTmpl}
globalRoles = []interface{}{adminGlobalRole, regularGlobalRole} namespaces = []interface{}{kubesphereSystem, defaultNamespace, testNamespace}
globalRoles = []interface{}{platformAdmin, platformRegular}
globalRoleBindings = []interface{}{adminGlobalRoleBinding, regularGlobalRoleBinding} globalRoleBindings = []interface{}{adminGlobalRoleBinding, regularGlobalRoleBinding}
workspaceRoles = []interface{}{regularGlobalRole} workspaceRoles = []interface{}{systemWorkspaceRegular}
workspaceRoleBindings = []interface{}{regularWorkspaceRoleBinding} workspaceRoleBindings = []interface{}{systemWorkspaceRegularRoleBinding}
namespaceRoles = []interface{}{bar1NamespaceRole} namespaceRoles = []interface{}{testNamespaceAdmin}
namespaceRoleBindings = []interface{}{bar1NamespaceRoleBinding} namespaceRoleBindings = []interface{}{testNamespaceAdminRoleBinding}
) )
func prepare() Interface { func prepare() Interface {
ksClient := fakeks.NewSimpleClientset() ksClient := fakeks.NewSimpleClientset([]runtime.Object{testWorkspace, systemWorkspace}...)
k8sClient := fakek8s.NewSimpleClientset() k8sClient := fakek8s.NewSimpleClientset([]runtime.Object{testNamespace, kubesphereSystem}...)
istioClient := fakeistio.NewSimpleClientset() istioClient := fakeistio.NewSimpleClientset()
appClient := fakeapp.NewSimpleClientset() appClient := fakeapp.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, appClient, nil, nil) fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, appClient, nil, nil)
for _, workspace := range workspaces { for _, workspace := range workspaces {
fakeInformerFactory.KubeSphereSharedInformerFactory().Tenant().V1alpha1().
Workspaces().Informer().GetIndexer().Add(workspace)
}
for _, workspaceTmpl := range workspaceTemplates {
fakeInformerFactory.KubeSphereSharedInformerFactory().Tenant().V1alpha2(). fakeInformerFactory.KubeSphereSharedInformerFactory().Tenant().V1alpha2().
WorkspaceTemplates().Informer().GetIndexer().Add(workspace) WorkspaceTemplates().Informer().GetIndexer().Add(workspaceTmpl)
} }
for _, namespace := range namespaces { for _, namespace := range namespaces {
@@ -328,5 +538,5 @@ func prepare() Interface {
RoleBindings().Informer().GetIndexer().Add(roleBinding) RoleBindings().Informer().GetIndexer().Add(roleBinding)
} }
return New(fakeInformerFactory, nil, nil, nil, nil, nil) return New(fakeInformerFactory, k8sClient, ksClient, nil, nil, nil)
} }