migrate legacy API

Signed-off-by: hongming <talonwan@yunify.com>
This commit is contained in:
hongming
2020-04-20 07:01:43 +08:00
parent 3f89eaef7e
commit 7db2ba662c
103 changed files with 5962 additions and 2363 deletions

View File

@@ -1,14 +1,20 @@
package v1alpha2
import (
"fmt"
"github.com/emicklei/go-restful"
"k8s.io/apimachinery/pkg/apis/meta/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/api"
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
authoptions "kubesphere.io/kubesphere/pkg/apiserver/authentication/options"
"kubesphere.io/kubesphere/pkg/apiserver/query"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/im"
"strings"
resources "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
)
type iamHandler struct {
@@ -23,18 +29,6 @@ func newIAMHandler(im im.IdentityManagementInterface, am am.AccessManagementInte
}
}
func (h *iamHandler) CreateUser(req *restful.Request, resp *restful.Response) {
panic("implement me")
}
func (h *iamHandler) DeleteUser(req *restful.Request, resp *restful.Response) {
panic("implement me")
}
func (h *iamHandler) ModifyUser(request *restful.Request, response *restful.Response) {
panic("implement me")
}
func (h *iamHandler) DescribeUser(req *restful.Request, resp *restful.Response) {
username := req.PathParameter("user")
user, err := h.im.DescribeUser(username)
@@ -43,108 +37,198 @@ func (h *iamHandler) DescribeUser(req *restful.Request, resp *restful.Response)
return
}
globalRole, err := h.am.GetRoleOfUserInTargetScope(iamv1alpha2.GlobalScope, "", username)
globalRole, err := h.am.GetGlobalRoleOfUser(username)
if err != nil {
api.HandleInternalError(resp, req, err)
return
}
result := iamv1alpha2.UserDetail{User: user, GlobalRole: globalRole}
resp.WriteEntity(result)
}
func (h *iamHandler) ListUsers(req *restful.Request, resp *restful.Response) {
panic("implement me")
}
func (h *iamHandler) ListUserRoles(req *restful.Request, resp *restful.Response) {
panic("implement me")
}
func (h *iamHandler) ListRoles(req *restful.Request, resp *restful.Response) {
panic("implement me")
}
func (h *iamHandler) ListRolesOfUser(req *restful.Request, resp *restful.Response) {
username := req.PathParameter("user")
var roles []iamv1alpha2.Role
var err error
if strings.HasSuffix(req.Request.URL.Path, "workspaceroles") {
roles, err = h.am.ListRolesOfUser(iamv1alpha2.WorkspaceScope, username)
} else if strings.HasSuffix(req.Request.URL.Path, "clusterroles") {
roles, err = h.am.ListRolesOfUser(iamv1alpha2.ClusterScope, username)
} else if strings.HasSuffix(req.Request.URL.Path, "namespaceroles") {
roles, err = h.am.ListRolesOfUser(iamv1alpha2.NamespaceScope, username)
}
queryParam := query.ParseQueryParameter(req)
result, err := h.im.ListUsers(queryParam)
if err != nil {
api.HandleInternalError(resp, req, err)
return
}
for i, item := range result.Items {
user := item.(*iamv1alpha2.User)
user = user.DeepCopy()
role, err := h.am.GetGlobalRoleOfUser(user.Name)
if err != nil && !errors.IsNotFound(err) {
klog.Error(err)
api.HandleInternalError(resp, req, err)
return
}
result := iamv1alpha2.RoleList{
TypeMeta: v1.TypeMeta{
Kind: "List",
APIVersion: "v1",
},
ListMeta: v1.ListMeta{},
Items: roles,
if user.Annotations == nil {
user.Annotations = make(map[string]string, 0)
}
if role != nil {
user.Annotations["iam.kubesphere.io/global-role"] = role.Name
} else {
user.Annotations["iam.kubesphere.io/global-role"] = ""
}
result.Items[i] = user
}
resp.WriteEntity(result)
}
func (h *iamHandler) ListRoles(req *restful.Request, resp *restful.Response) {
namespace := req.PathParameter("namespace")
queryParam := query.ParseQueryParameter(req)
result, err := h.am.ListRoles(namespace, queryParam)
if err != nil {
api.HandleInternalError(resp, req, err)
return
}
resp.WriteEntity(result)
}
func (h *iamHandler) ListClusterRoles(req *restful.Request, resp *restful.Response) {
panic("implement me")
queryParam := query.ParseQueryParameter(req)
result, err := h.am.ListClusterRoles(queryParam)
if err != nil {
api.HandleInternalError(resp, req, err)
return
}
resp.WriteEntity(result)
}
func (h *iamHandler) ListGlobalRoles(req *restful.Request, resp *restful.Response) {
queryParam := query.ParseQueryParameter(req)
result, err := h.am.ListGlobalRoles(queryParam)
if err != nil {
api.HandleInternalError(resp, req, err)
return
}
resp.WriteEntity(result)
}
func (h *iamHandler) ListRoleUsers(req *restful.Request, resp *restful.Response) {
panic("implement me")
}
// List users by namespace
func (h *iamHandler) ListNamespaceUsers(req *restful.Request, resp *restful.Response) {
panic("implement me")
}
queryParam := query.ParseQueryParameter(req)
namespace := req.PathParameter("namespace")
func (h *iamHandler) ListClusterRoleUsers(req *restful.Request, resp *restful.Response) {
panic("implement me")
}
roleBindings, err := h.am.ListRoleBindings("", namespace)
func (h *iamHandler) ListClusterRoleRules(req *restful.Request, resp *restful.Response) {
panic("implement me")
}
if err != nil {
api.HandleInternalError(resp, req, err)
return
}
func (h *iamHandler) ListRoleRules(req *restful.Request, resp *restful.Response) {
panic("implement me")
users := make([]runtime.Object, 0)
for _, roleBinding := range roleBindings {
for _, subject := range roleBinding.Subjects {
if subject.Kind == iamv1alpha2.ResourceKindUser {
user, err := h.im.DescribeUser(subject.Name)
if errors.IsNotFound(err) {
klog.Errorf("orphan subject: %+v", subject)
continue
}
if err != nil {
api.HandleInternalError(resp, req, err)
return
}
user = user.DeepCopy()
if user.Annotations == nil {
user.Annotations = make(map[string]string, 0)
}
user.Annotations["iam.kubesphere.io/role"] = roleBinding.RoleRef.Name
users = append(users, user)
}
}
}
result := resources.DefaultList(users, queryParam, func(left runtime.Object, right runtime.Object, field query.Field) bool {
return resources.DefaultObjectMetaCompare(left.(*corev1.Namespace).ObjectMeta, right.(*corev1.Namespace).ObjectMeta, field)
}, func(object runtime.Object, filter query.Filter) bool {
user := object.(*iamv1alpha2.User).ObjectMeta
return resources.DefaultObjectMetaFilter(user, filter)
})
resp.WriteEntity(result)
}
func (h *iamHandler) ListWorkspaceRoles(request *restful.Request, response *restful.Response) {
panic("implement me")
}
queryParam := query.ParseQueryParameter(request)
workspace := request.PathParameter("workspace")
queryParam.Filters[query.FieldLabel] = query.Value(fmt.Sprintf("%s:%s", tenantv1alpha1.WorkspaceLabel, workspace))
func (h *iamHandler) DescribeWorkspaceRole(request *restful.Request, response *restful.Response) {
panic("implement me")
}
func (h *iamHandler) ListWorkspaceRoleRules(request *restful.Request, response *restful.Response) {
panic("implement me")
result, err := h.am.ListWorkspaceRoles(queryParam)
if err != nil {
api.HandleInternalError(response, request, err)
return
}
response.WriteEntity(result)
}
func (h *iamHandler) ListWorkspaceUsers(request *restful.Request, response *restful.Response) {
panic("implement me")
}
queryParam := query.ParseQueryParameter(request)
workspace := request.PathParameter("workspace")
func (h *iamHandler) InviteUser(request *restful.Request, response *restful.Response) {
panic("implement me")
}
roleBindings, err := h.am.ListWorkspaceRoleBindings("", workspace)
func (h *iamHandler) RemoveUser(request *restful.Request, response *restful.Response) {
panic("implement me")
}
if err != nil {
api.HandleInternalError(response, request, err)
return
}
func (h *iamHandler) DescribeWorkspaceUser(request *restful.Request, response *restful.Response) {
panic("implement me")
users := make([]runtime.Object, 0)
for _, roleBinding := range roleBindings {
for _, subject := range roleBinding.Subjects {
if subject.Kind == iamv1alpha2.ResourceKindUser {
user, err := h.im.DescribeUser(subject.Name)
if errors.IsNotFound(err) {
klog.Errorf("orphan subject: %+v", subject)
continue
}
if err != nil {
api.HandleInternalError(response, request, err)
return
}
user = user.DeepCopy()
if user.Annotations == nil {
user.Annotations = make(map[string]string, 0)
}
user.Annotations["iam.kubesphere.io/workspace-role"] = roleBinding.RoleRef.Name
users = append(users, user)
}
}
}
result := resources.DefaultList(users, queryParam, func(left runtime.Object, right runtime.Object, field query.Field) bool {
return resources.DefaultObjectMetaCompare(left.(*corev1.Namespace).ObjectMeta, right.(*corev1.Namespace).ObjectMeta, field)
}, func(object runtime.Object, filter query.Filter) bool {
user := object.(*iamv1alpha2.User).ObjectMeta
return resources.DefaultObjectMetaFilter(user, filter)
})
response.WriteEntity(result)
}

View File

@@ -29,97 +29,70 @@ import (
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/im"
"kubesphere.io/kubesphere/pkg/server/errors"
"net/http"
)
const groupName = "iam.kubesphere.io"
const (
GroupName = "iam.kubesphere.io"
)
var GroupVersion = schema.GroupVersion{Group: groupName, Version: "v1alpha2"}
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
func AddToContainer(container *restful.Container, im im.IdentityManagementInterface, am am.AccessManagementInterface, options *authoptions.AuthenticationOptions) error {
ws := runtime.NewWebService(GroupVersion)
handler := newIAMHandler(im, am, options)
// global resource
ws.Route(ws.GET("/users").
To(handler.ListUsers).
Doc("List all users.").
Param(ws.PathParameter("user", "username")).
Returns(http.StatusOK, api.StatusOK, api.ListResult{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
// global resource
ws.Route(ws.GET("/users/{user}").
To(handler.DescribeUser).
Doc("Retrieve user details.").
Param(ws.PathParameter("user", "username")).
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.UserDetail{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/users/{user}/workspaceroles").
To(handler.ListRolesOfUser).
Doc("Retrieve user roles in workspaces.").
Param(ws.PathParameter("user", "username")).
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.RoleList{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/users/{user}/clusterroles").
To(handler.ListRolesOfUser).
Doc("Retrieve user roles in clusters.").
Param(ws.PathParameter("user", "username")).
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.RoleList{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/users/{user}/namespaceroles").
To(handler.ListRolesOfUser).
Doc("Retrieve user roles in namespaces.").
Param(ws.PathParameter("user", "username")).
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.RoleList{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/namespaces/{namespace}/roles").
To(handler.ListRoles).
Doc("Retrieve the roles that are assigned to the user in the specified namespace.").
Param(ws.PathParameter("namespace", "kubernetes namespace")).
// global resource
ws.Route(ws.GET("/globalroles").
To(handler.ListGlobalRoles).
Doc("List all cluster roles.").
Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/clusterroles").
To(handler.ListClusterRoles).
Doc("List all cluster roles.").
Doc("List cluster roles.").
Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
// TODO merge
//ws.Route(ws.GET("/namespaces/{namespace}/roles/{role}/users"))
ws.Route(ws.GET("/namespaces/{namespace}/users").
To(handler.ListNamespaceUsers).
Doc("List all users in the specified namespace.").
Param(ws.PathParameter("namespace", "kubernetes namespace")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/clusterroles/{clusterrole}/users").
To(handler.ListClusterRoleUsers).
Doc("List all users that are bound to the specified cluster role.").
Param(ws.PathParameter("clusterrole", "cluster role name")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/workspaces/{workspace}/roles").
To(handler.ListWorkspaceRoles).
Doc("List all workspace roles.").
Param(ws.PathParameter("workspace", "workspace name")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/workspaces/{workspace}/members").
ws.Route(ws.GET("/workspaces/{workspace}/users").
To(handler.ListWorkspaceUsers).
Doc("List all members in the specified workspace.").
Param(ws.PathParameter("workspace", "workspace name")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
// TODO re-design
ws.Route(ws.POST("/workspaces/{workspace}/members").
To(handler.InviteUser).
Doc("Invite a member to the specified workspace.").
ws.Route(ws.GET("/workspaces/{workspace}/workspaceroles").
To(handler.ListWorkspaceRoles).
Doc("List all workspace roles.").
Param(ws.PathParameter("workspace", "workspace name")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.DELETE("/workspaces/{workspace}/members/{member}").
To(handler.RemoveUser).
Doc("Remove the specified member from the workspace.").
Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("member", "username")).
Returns(http.StatusOK, api.StatusOK, errors.Error{}).
ws.Route(ws.GET("/namespaces/{namespace}/users").
To(handler.ListNamespaceUsers).
Doc("List all users in the specified namespace.").
Param(ws.PathParameter("namespace", "kubernetes namespace")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
ws.Route(ws.GET("/namespaces/{namespace}/roles").
To(handler.ListRoles).
Doc("List all roles in the specified namespace.").
Param(ws.PathParameter("namespace", "namespace")).
Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
container.Add(ws)