Refactor workspace API and introduced tenant v1alpha3 version

This commit is contained in:
Xinzhao Xu
2022-03-08 17:50:53 +08:00
parent f018a23023
commit 6a3e1ac099
9 changed files with 316 additions and 50 deletions

View File

@@ -65,7 +65,7 @@ import (
alertingv2alpha1 "kubesphere.io/kubesphere/pkg/kapis/alerting/v2alpha1"
clusterkapisv1alpha1 "kubesphere.io/kubesphere/pkg/kapis/cluster/v1alpha1"
configv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/config/v1alpha2"
crd "kubesphere.io/kubesphere/pkg/kapis/crd"
"kubesphere.io/kubesphere/pkg/kapis/crd"
kapisdevops "kubesphere.io/kubesphere/pkg/kapis/devops"
edgeruntimev1alpha1 "kubesphere.io/kubesphere/pkg/kapis/edgeruntime/v1alpha1"
gatewayv1alpha1 "kubesphere.io/kubesphere/pkg/kapis/gateway/v1alpha1"
@@ -85,6 +85,7 @@ import (
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/kapis/resources/v1alpha3"
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/servicemesh/metrics/v1alpha2"
tenantv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/tenant/v1alpha2"
tenantv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/tenant/v1alpha3"
terminalv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/terminal/v1alpha2"
"kubesphere.io/kubesphere/pkg/kapis/version"
"kubesphere.io/kubesphere/pkg/models/auth"
@@ -225,6 +226,8 @@ func (s *APIServer) installKubeSphereAPIs(stopCh <-chan struct{}) {
s.KubernetesClient.Master()))
urlruntime.Must(tenantv1alpha2.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.Kubernetes(),
s.KubernetesClient.KubeSphere(), s.EventsClient, s.LoggingClient, s.AuditingClient, amOperator, rbacAuthorizer, s.MonitoringClient, s.RuntimeCache, s.Config.MeteringOptions, stopCh))
urlruntime.Must(tenantv1alpha3.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.Kubernetes(),
s.KubernetesClient.KubeSphere(), s.EventsClient, s.LoggingClient, s.AuditingClient, amOperator, rbacAuthorizer, s.MonitoringClient, s.RuntimeCache, s.Config.MeteringOptions, stopCh))
urlruntime.Must(terminalv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), rbacAuthorizer, s.KubernetesClient.Config(), s.Config.TerminalOptions))
urlruntime.Must(clusterkapisv1alpha1.AddToContainer(s.container,
s.KubernetesClient.KubeSphere(),
@@ -263,7 +266,7 @@ func (s *APIServer) installKubeSphereAPIs(stopCh <-chan struct{}) {
// installCRDAPIs Install CRDs to the KAPIs with List and Get options
func (s *APIServer) installCRDAPIs() {
crds := &extv1.CustomResourceDefinitionList{}
//TODO Maybe we need a better label name
// TODO Maybe we need a better label name
urlruntime.Must(s.RuntimeClient.List(context.TODO(), crds, runtimeclient.MatchingLabels{"kubesphere.io/resource-served": "true"}))
urlruntime.Must(crd.AddToContainer(s.container, s.RuntimeClient, s.RuntimeCache, crds))
}

View File

@@ -56,7 +56,7 @@ type tenantHandler struct {
meteringOptions *meteringclient.Options
}
func newTenantHandler(factory informers.InformerFactory, k8sclient kubernetes.Interface, ksclient kubesphere.Interface,
func NewTenantHandler(factory informers.InformerFactory, k8sclient kubernetes.Interface, ksclient kubesphere.Interface,
evtsClient events.Client, loggingClient logging.Client, auditingclient auditing.Client,
am am.AccessManagementInterface, authorizer authorizer.Authorizer,
monitoringclient monitoringclient.Interface, resourceGetter *resourcev1alpha3.ResourceGetter,
@@ -72,7 +72,7 @@ func newTenantHandler(factory informers.InformerFactory, k8sclient kubernetes.In
}
}
func (h *tenantHandler) ListWorkspaces(req *restful.Request, resp *restful.Response) {
func (h *tenantHandler) ListWorkspaceTemplates(req *restful.Request, resp *restful.Response) {
user, ok := request.UserFrom(req.Request.Context())
queryParam := query.ParseQueryParameter(req)
@@ -83,7 +83,7 @@ func (h *tenantHandler) ListWorkspaces(req *restful.Request, resp *restful.Respo
return
}
result, err := h.tenant.ListWorkspaces(user, queryParam)
result, err := h.tenant.ListWorkspaceTemplates(user, queryParam)
if err != nil {
api.HandleInternalError(resp, nil, err)
@@ -200,7 +200,7 @@ func (h *tenantHandler) CreateNamespace(request *restful.Request, response *rest
response.WriteEntity(created)
}
func (h *tenantHandler) CreateWorkspace(request *restful.Request, response *restful.Response) {
func (h *tenantHandler) CreateWorkspaceTemplate(request *restful.Request, response *restful.Response) {
var workspace tenantv1alpha2.WorkspaceTemplate
err := request.ReadEntity(&workspace)
@@ -211,7 +211,7 @@ func (h *tenantHandler) CreateWorkspace(request *restful.Request, response *rest
return
}
created, err := h.tenant.CreateWorkspace(&workspace)
created, err := h.tenant.CreateWorkspaceTemplate(&workspace)
if err != nil {
klog.Error(err)
@@ -226,7 +226,7 @@ func (h *tenantHandler) CreateWorkspace(request *restful.Request, response *rest
response.WriteEntity(created)
}
func (h *tenantHandler) DeleteWorkspace(request *restful.Request, response *restful.Response) {
func (h *tenantHandler) DeleteWorkspaceTemplate(request *restful.Request, response *restful.Response) {
workspace := request.PathParameter("workspace")
opts := metav1.DeleteOptions{}
@@ -236,7 +236,7 @@ func (h *tenantHandler) DeleteWorkspace(request *restful.Request, response *rest
opts = *metav1.NewDeleteOptions(0)
}
err = h.tenant.DeleteWorkspace(workspace, opts)
err = h.tenant.DeleteWorkspaceTemplate(workspace, opts)
if err != nil {
klog.Error(err)
@@ -251,7 +251,7 @@ func (h *tenantHandler) DeleteWorkspace(request *restful.Request, response *rest
response.WriteEntity(servererr.None)
}
func (h *tenantHandler) UpdateWorkspace(request *restful.Request, response *restful.Response) {
func (h *tenantHandler) UpdateWorkspaceTemplate(request *restful.Request, response *restful.Response) {
workspaceName := request.PathParameter("workspace")
var workspace tenantv1alpha2.WorkspaceTemplate
@@ -270,7 +270,7 @@ func (h *tenantHandler) UpdateWorkspace(request *restful.Request, response *rest
return
}
updated, err := h.tenant.UpdateWorkspace(&workspace)
updated, err := h.tenant.UpdateWorkspaceTemplate(&workspace)
if err != nil {
klog.Error(err)
@@ -289,10 +289,10 @@ func (h *tenantHandler) UpdateWorkspace(request *restful.Request, response *rest
response.WriteEntity(updated)
}
func (h *tenantHandler) DescribeWorkspace(request *restful.Request, response *restful.Response) {
func (h *tenantHandler) DescribeWorkspaceTemplate(request *restful.Request, response *restful.Response) {
workspaceName := request.PathParameter("workspace")
workspace, err := h.tenant.DescribeWorkspace(workspaceName)
workspace, err := h.tenant.DescribeWorkspaceTemplate(workspaceName)
if err != nil {
klog.Error(err)
@@ -518,7 +518,7 @@ func (h *tenantHandler) PatchNamespace(request *restful.Request, response *restf
response.WriteEntity(patched)
}
func (h *tenantHandler) PatchWorkspace(request *restful.Request, response *restful.Response) {
func (h *tenantHandler) PatchWorkspaceTemplate(request *restful.Request, response *restful.Response) {
workspaceName := request.PathParameter("workspace")
var data json.RawMessage
err := request.ReadEntity(&data)
@@ -528,7 +528,7 @@ func (h *tenantHandler) PatchWorkspace(request *restful.Request, response *restf
return
}
patched, err := h.tenant.PatchWorkspace(workspaceName, data)
patched, err := h.tenant.PatchWorkspaceTemplate(workspaceName, data)
if err != nil {
klog.Error(err)

View File

@@ -19,15 +19,12 @@ package v1alpha2
import (
"net/http"
"sigs.k8s.io/controller-runtime/pkg/cache"
"kubesphere.io/kubesphere/pkg/models/metering"
"github.com/emicklei/go-restful"
restfulspec "github.com/emicklei/go-restful-openapi"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/cache"
quotav1alpha2 "kubesphere.io/api/quota/v1alpha2"
tenantv1alpha2 "kubesphere.io/api/tenant/v1alpha2"
@@ -43,6 +40,7 @@ import (
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/metering"
"kubesphere.io/kubesphere/pkg/models/monitoring"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"kubesphere.io/kubesphere/pkg/server/errors"
@@ -70,7 +68,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s
mimePatch := []string{restful.MIME_JSON, runtime.MimeMergePatchJson, runtime.MimeJsonPatchJson}
ws := runtime.NewWebService(GroupVersion)
handler := newTenantHandler(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, stopCh)
handler := NewTenantHandler(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, stopCh)
ws.Route(ws.GET("/clusters").
To(handler.ListClusters).
@@ -79,21 +77,21 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s
Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserResourceTag}))
ws.Route(ws.POST("/workspaces").
To(handler.CreateWorkspace).
To(handler.CreateWorkspaceTemplate).
Reads(tenantv1alpha2.WorkspaceTemplate{}).
Returns(http.StatusOK, api.StatusOK, tenantv1alpha2.WorkspaceTemplate{}).
Doc("Create workspace.").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag}))
ws.Route(ws.DELETE("/workspaces/{workspace}").
To(handler.DeleteWorkspace).
To(handler.DeleteWorkspaceTemplate).
Param(ws.PathParameter("workspace", "workspace name")).
Returns(http.StatusOK, api.StatusOK, errors.None).
Doc("Delete workspace.").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag}))
ws.Route(ws.PUT("/workspaces/{workspace}").
To(handler.UpdateWorkspace).
To(handler.UpdateWorkspaceTemplate).
Param(ws.PathParameter("workspace", "workspace name")).
Reads(tenantv1alpha2.WorkspaceTemplate{}).
Returns(http.StatusOK, api.StatusOK, tenantv1alpha2.WorkspaceTemplate{}).
@@ -101,7 +99,7 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s
Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag}))
ws.Route(ws.PATCH("/workspaces/{workspace}").
To(handler.PatchWorkspace).
To(handler.PatchWorkspaceTemplate).
Param(ws.PathParameter("workspace", "workspace name")).
Consumes(mimePatch...).
Reads(tenantv1alpha2.WorkspaceTemplate{}).
@@ -110,13 +108,13 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s
Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag}))
ws.Route(ws.GET("/workspaces").
To(handler.ListWorkspaces).
To(handler.ListWorkspaceTemplates).
Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}).
Doc("List all workspaces that belongs to the current user").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag}))
ws.Route(ws.GET("/workspaces/{workspace}").
To(handler.DescribeWorkspace).
To(handler.DescribeWorkspaceTemplate).
Param(ws.PathParameter("workspace", "workspace name")).
Returns(http.StatusOK, api.StatusOK, tenantv1alpha2.WorkspaceTemplate{}).
Doc("Describe workspace.").

View File

@@ -0,0 +1,80 @@
/*
Copyright 2020 KubeSphere Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha3
import (
"fmt"
"github.com/emicklei/go-restful"
"k8s.io/client-go/kubernetes"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
"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/iam/am"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"kubesphere.io/kubesphere/pkg/models/tenant"
"kubesphere.io/kubesphere/pkg/simple/client/auditing"
"kubesphere.io/kubesphere/pkg/simple/client/events"
"kubesphere.io/kubesphere/pkg/simple/client/logging"
meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering"
monitoringclient "kubesphere.io/kubesphere/pkg/simple/client/monitoring"
)
type tenantHandler struct {
tenant tenant.Interface
meteringOptions *meteringclient.Options
}
func newTenantHandler(factory informers.InformerFactory, k8sclient kubernetes.Interface, ksclient kubesphere.Interface,
evtsClient events.Client, loggingClient logging.Client, auditingclient auditing.Client,
am am.AccessManagementInterface, authorizer authorizer.Authorizer,
monitoringclient monitoringclient.Interface, resourceGetter *resourcev1alpha3.ResourceGetter,
meteringOptions *meteringclient.Options, stopCh <-chan struct{}) *tenantHandler {
if meteringOptions == nil || meteringOptions.RetentionDay == "" {
meteringOptions = &meteringclient.DefaultMeteringOption
}
return &tenantHandler{
tenant: tenant.New(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourceGetter, stopCh),
meteringOptions: meteringOptions,
}
}
func (h *tenantHandler) ListWorkspaces(req *restful.Request, resp *restful.Response) {
queryParam := query.ParseQueryParameter(req)
user, ok := request.UserFrom(req.Request.Context())
if !ok {
err := fmt.Errorf("cannot obtain user info")
klog.Errorln(err)
api.HandleForbidden(resp, nil, err)
return
}
result, err := h.tenant.ListWorkspaces(user, queryParam)
if err != nil {
api.HandleInternalError(resp, nil, err)
return
}
resp.WriteEntity(result)
}

View File

@@ -0,0 +1,120 @@
/*
Copyright 2019 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha3
import (
"net/http"
"github.com/emicklei/go-restful"
restfulspec "github.com/emicklei/go-restful-openapi"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/cache"
tenantv1alpha2 "kubesphere.io/api/tenant/v1alpha2"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/kapis/tenant/v1alpha2"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/iam/am"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/simple/client/auditing"
"kubesphere.io/kubesphere/pkg/simple/client/events"
"kubesphere.io/kubesphere/pkg/simple/client/logging"
meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering"
monitoringclient "kubesphere.io/kubesphere/pkg/simple/client/monitoring"
)
const (
GroupName = "tenant.kubesphere.io"
)
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha3"}
func Resource(resource string) schema.GroupResource {
return GroupVersion.WithResource(resource).GroupResource()
}
func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8sclient kubernetes.Interface,
ksclient kubesphere.Interface, evtsClient events.Client, loggingClient logging.Client,
auditingclient auditing.Client, am am.AccessManagementInterface, authorizer authorizer.Authorizer,
monitoringclient monitoringclient.Interface, cache cache.Cache, meteringOptions *meteringclient.Options, stopCh <-chan struct{}) error {
mimePatch := []string{restful.MIME_JSON, runtime.MimeMergePatchJson, runtime.MimeJsonPatchJson}
ws := runtime.NewWebService(GroupVersion)
v1alpha2Handler := v1alpha2.NewTenantHandler(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, stopCh)
handler := newTenantHandler(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, stopCh)
ws.Route(ws.POST("/workspacetemplates").
To(v1alpha2Handler.CreateWorkspaceTemplate).
Reads(tenantv1alpha2.WorkspaceTemplate{}).
Returns(http.StatusOK, api.StatusOK, tenantv1alpha2.WorkspaceTemplate{}).
Doc("Create workspace.").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag}))
ws.Route(ws.DELETE("/workspacetemplates/{workspace}").
To(v1alpha2Handler.DeleteWorkspaceTemplate).
Param(ws.PathParameter("workspace", "workspace name")).
Returns(http.StatusOK, api.StatusOK, errors.None).
Doc("Delete workspace.").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag}))
ws.Route(ws.PUT("/workspacetemplates/{workspace}").
To(v1alpha2Handler.UpdateWorkspaceTemplate).
Param(ws.PathParameter("workspace", "workspace name")).
Reads(tenantv1alpha2.WorkspaceTemplate{}).
Returns(http.StatusOK, api.StatusOK, tenantv1alpha2.WorkspaceTemplate{}).
Doc("Update workspace.").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag}))
ws.Route(ws.PATCH("/workspacetemplates/{workspace}").
To(v1alpha2Handler.PatchWorkspaceTemplate).
Param(ws.PathParameter("workspace", "workspace name")).
Consumes(mimePatch...).
Reads(tenantv1alpha2.WorkspaceTemplate{}).
Returns(http.StatusOK, api.StatusOK, tenantv1alpha2.WorkspaceTemplate{}).
Doc("Update workspace.").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag}))
ws.Route(ws.GET("/workspacetemplates").
To(v1alpha2Handler.ListWorkspaceTemplates).
Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}).
Doc("List all workspaces that belongs to the current user").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag}))
ws.Route(ws.GET("/workspacetemplates/{workspace}").
To(v1alpha2Handler.DescribeWorkspaceTemplate).
Param(ws.PathParameter("workspace", "workspace name")).
Returns(http.StatusOK, api.StatusOK, tenantv1alpha2.WorkspaceTemplate{}).
Doc("Describe workspace.").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag}))
ws.Route(ws.GET("/workspaces").
To(handler.ListWorkspaces).
Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}).
Doc("List all workspaces that belongs to the current user").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.WorkspaceTag}))
c.Add(ws)
return nil
}

View File

@@ -188,7 +188,7 @@ func (t *tenantOperator) makeQueryOptions(user user.Info, q meteringv1alpha1.Que
var wsList *api.ListResult
qu := query.New()
qu.LabelSelector = q.LabelSelector
wsList, err = t.ListWorkspaces(user, qu)
wsList, err = t.ListWorkspaceTemplates(user, qu)
if err != nil {
return qo, err
}
@@ -703,7 +703,7 @@ func (t *tenantOperator) transformMetricData(metrics monitoringmodel.Metrics) me
for _, metric := range metrics.Results {
metricName := metric.MetricName
for _, metricValue := range metric.MetricValues {
//metricValue.SumValue
// metricValue.SumValue
podName := metricValue.Metadata["pod"]
if s, err := strconv.ParseFloat(metricValue.SumValue, 64); err != nil {
klog.Error("failed to parse string to float64")

View File

@@ -24,8 +24,6 @@ import (
"strings"
"time"
"kubesphere.io/kubesphere/pkg/models/openpitrix"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -58,6 +56,7 @@ import (
"kubesphere.io/kubesphere/pkg/models/logging"
"kubesphere.io/kubesphere/pkg/models/metering"
"kubesphere.io/kubesphere/pkg/models/monitoring"
"kubesphere.io/kubesphere/pkg/models/openpitrix"
resources "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
resourcesv1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
@@ -72,15 +71,17 @@ import (
const orphanFinalizer = "orphan.finalizers.kubesphere.io"
type Interface interface {
ListWorkspaces(user user.Info, query *query.Query) (*api.ListResult, error)
ListWorkspaces(user user.Info, queryParam *query.Query) (*api.ListResult, error)
ListWorkspaceTemplates(user user.Info, query *query.Query) (*api.ListResult, error)
CreateWorkspaceTemplate(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error)
DeleteWorkspaceTemplate(workspace string, opts metav1.DeleteOptions) error
UpdateWorkspaceTemplate(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error)
PatchWorkspaceTemplate(workspace string, data json.RawMessage) (*tenantv1alpha2.WorkspaceTemplate, error)
DescribeWorkspaceTemplate(workspace string) (*tenantv1alpha2.WorkspaceTemplate, error)
ListNamespaces(user user.Info, workspace string, query *query.Query) (*api.ListResult, error)
ListDevOpsProjects(user user.Info, workspace string, query *query.Query) (*api.ListResult, error)
ListFederatedNamespaces(info user.Info, workspace string, param *query.Query) (*api.ListResult, error)
CreateNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error)
CreateWorkspace(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error)
DeleteWorkspace(workspace string, opts metav1.DeleteOptions) error
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)
@@ -90,7 +91,6 @@ type Interface interface {
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 string, data json.RawMessage) (*tenantv1alpha2.WorkspaceTemplate, error)
ListClusters(info user.Info) (*api.ListResult, error)
Metering(user user.Info, queryParam *meteringv1alpha1.Query, priceInfo meteringclient.PriceInfo) (monitoring.Metrics, error)
MeteringHierarchy(user user.Info, queryParam *meteringv1alpha1.Query, priceInfo meteringclient.PriceInfo) (metering.ResourceStatistic, error)
@@ -134,6 +134,69 @@ func New(informers informers.InformerFactory, k8sclient kubernetes.Interface, ks
}
func (t *tenantOperator) ListWorkspaces(user user.Info, queryParam *query.Query) (*api.ListResult, error) {
listWS := authorizer.AttributesRecord{
User: user,
Verb: "list",
APIGroup: "*",
Resource: "workspaces",
ResourceRequest: true,
ResourceScope: request.GlobalScope,
}
decision, _, err := t.authorizer.Authorize(listWS)
if err != nil {
klog.Error(err)
return nil, err
}
// allowed to list all workspaces
if decision == authorizer.DecisionAllow {
result, err := t.resourceGetter.List(tenantv1alpha1.ResourcePluralWorkspace, "", queryParam)
if err != nil {
klog.Error(err)
return nil, err
}
return result, nil
}
// retrieving associated resources through role binding
workspaceRoleBindings, err := t.am.ListWorkspaceRoleBindings(user.GetName(), user.GetGroups(), "")
if err != nil {
klog.Error(err)
return nil, err
}
workspaces := make([]runtime.Object, 0)
for _, roleBinding := range workspaceRoleBindings {
workspaceName := roleBinding.Labels[tenantv1alpha1.WorkspaceLabel]
obj, err := t.resourceGetter.Get(tenantv1alpha1.ResourcePluralWorkspace, "", workspaceName)
if errors.IsNotFound(err) {
klog.Warningf("workspace role binding: %+v found but workspace not exist", roleBinding.Name)
continue
}
if err != nil {
klog.Error(err)
return nil, err
}
workspace := obj.(*tenantv1alpha1.Workspace)
// label matching selector, remove duplicate entity
if queryParam.Selector().Matches(labels.Set(workspace.Labels)) &&
!contains(workspaces, workspace) {
workspaces = append(workspaces, workspace)
}
}
// use default pagination search logic
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)
}, func(workspace runtime.Object, filter query.Filter) bool {
return resources.DefaultObjectMetaFilter(workspace.(*tenantv1alpha1.Workspace).ObjectMeta, filter)
})
return result, nil
}
func (t *tenantOperator) ListWorkspaceTemplates(user user.Info, queryParam *query.Query) (*api.ListResult, error) {
listWS := authorizer.AttributesRecord{
User: user,
@@ -396,19 +459,19 @@ func (t *tenantOperator) PatchNamespace(workspace string, namespace *corev1.Name
return t.k8sclient.CoreV1().Namespaces().Patch(context.Background(), namespace.Name, types.MergePatchType, data, metav1.PatchOptions{})
}
func (t *tenantOperator) PatchWorkspace(workspace string, data json.RawMessage) (*tenantv1alpha2.WorkspaceTemplate, error) {
func (t *tenantOperator) PatchWorkspaceTemplate(workspace string, data json.RawMessage) (*tenantv1alpha2.WorkspaceTemplate, error) {
return t.ksclient.TenantV1alpha2().WorkspaceTemplates().Patch(context.Background(), workspace, types.MergePatchType, data, metav1.PatchOptions{})
}
func (t *tenantOperator) CreateWorkspace(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error) {
func (t *tenantOperator) CreateWorkspaceTemplate(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error) {
return t.ksclient.TenantV1alpha2().WorkspaceTemplates().Create(context.Background(), workspace, metav1.CreateOptions{})
}
func (t *tenantOperator) UpdateWorkspace(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error) {
func (t *tenantOperator) UpdateWorkspaceTemplate(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error) {
return t.ksclient.TenantV1alpha2().WorkspaceTemplates().Update(context.Background(), workspace, metav1.UpdateOptions{})
}
func (t *tenantOperator) DescribeWorkspace(workspace string) (*tenantv1alpha2.WorkspaceTemplate, error) {
func (t *tenantOperator) DescribeWorkspaceTemplate(workspace string) (*tenantv1alpha2.WorkspaceTemplate, error) {
obj, err := t.resourceGetter.Get(tenantv1alpha2.ResourcePluralWorkspaceTemplate, "", workspace)
if err != nil {
klog.Error(err)
@@ -416,8 +479,9 @@ func (t *tenantOperator) DescribeWorkspace(workspace string) (*tenantv1alpha2.Wo
}
return obj.(*tenantv1alpha2.WorkspaceTemplate), nil
}
func (t *tenantOperator) ListWorkspaceClusters(workspaceName string) (*api.ListResult, error) {
workspace, err := t.DescribeWorkspace(workspaceName)
workspace, err := t.DescribeWorkspaceTemplate(workspaceName)
if err != nil {
klog.Error(err)
return nil, err
@@ -457,6 +521,7 @@ func (t *tenantOperator) ListWorkspaceClusters(workspaceName string) (*api.ListR
// In this case, you can either set spec: {} as above or remove spec field from your placement policy. The resource will not be propagated to member clusters.
return &api.ListResult{Items: []interface{}{}, TotalItems: 0}, nil
}
func (t *tenantOperator) ListClusters(user user.Info) (*api.ListResult, error) {
listClustersInGlobalScope := authorizer.AttributesRecord{
@@ -510,7 +575,7 @@ func (t *tenantOperator) ListClusters(user user.Info) (*api.ListResult, error) {
for _, roleBinding := range workspaceRoleBindings {
workspaceName := roleBinding.Labels[tenantv1alpha1.WorkspaceLabel]
workspace, err := t.DescribeWorkspace(workspaceName)
workspace, err := t.DescribeWorkspaceTemplate(workspaceName)
if err != nil {
klog.Error(err)
return nil, err
@@ -542,10 +607,10 @@ func (t *tenantOperator) ListClusters(user user.Info) (*api.ListResult, error) {
return &api.ListResult{Items: items, TotalItems: len(items)}, nil
}
func (t *tenantOperator) DeleteWorkspace(workspace string, opts metav1.DeleteOptions) error {
func (t *tenantOperator) DeleteWorkspaceTemplate(workspace string, opts metav1.DeleteOptions) error {
if opts.PropagationPolicy != nil && *opts.PropagationPolicy == metav1.DeletePropagationOrphan {
wsp, err := t.DescribeWorkspace(workspace)
wsp, err := t.DescribeWorkspaceTemplate(workspace)
if err != nil {
klog.Error(err)
return err

View File

@@ -66,7 +66,7 @@ func TestTenantOperator_ListWorkspaces(t *testing.T) {
}
for i, test := range tests {
result, err := tenantOperator.ListWorkspaces(&user.DefaultInfo{Name: test.username}, query.New())
result, err := tenantOperator.ListWorkspaceTemplates(&user.DefaultInfo{Name: test.username}, query.New())
if err != nil {
if !reflect.DeepEqual(err, test.expectError) {

View File

@@ -24,11 +24,6 @@ import (
"io/ioutil"
"log"
kapisdevops "kubesphere.io/kubesphere/pkg/kapis/devops"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
"kubesphere.io/kubesphere/pkg/version"
"github.com/emicklei/go-restful"
restfulspec "github.com/emicklei/go-restful-openapi"
"github.com/go-openapi/loads"
@@ -41,10 +36,12 @@ import (
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/informers"
alertingv2alpha1 "kubesphere.io/kubesphere/pkg/kapis/alerting/v2alpha1"
clusterkapisv1alpha1 "kubesphere.io/kubesphere/pkg/kapis/cluster/v1alpha1"
kapisdevops "kubesphere.io/kubesphere/pkg/kapis/devops"
iamv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/iam/v1alpha2"
monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3"
networkv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/network/v1alpha2"
@@ -56,10 +53,12 @@ import (
resourcesv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/resources/v1alpha3"
metricsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/servicemesh/metrics/v1alpha2"
tenantv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/tenant/v1alpha2"
tenantv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/tenant/v1alpha3"
terminalv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/terminal/v1alpha2"
"kubesphere.io/kubesphere/pkg/models/iam/group"
"kubesphere.io/kubesphere/pkg/simple/client/alerting"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/version"
)
var output string
@@ -129,6 +128,7 @@ func generateSwaggerJson() []byte {
urlruntime.Must(resourcesv1alpha2.AddToContainer(container, clientsets.Kubernetes(), informerFactory, ""))
urlruntime.Must(resourcesv1alpha3.AddToContainer(container, informerFactory, nil))
urlruntime.Must(tenantv1alpha2.AddToContainer(container, informerFactory, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil))
urlruntime.Must(tenantv1alpha3.AddToContainer(container, informerFactory, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil))
urlruntime.Must(terminalv1alpha2.AddToContainer(container, clientsets.Kubernetes(), nil, nil, nil))
urlruntime.Must(metricsv1alpha2.AddToContainer(nil, container, clientsets.Kubernetes(), nil))
urlruntime.Must(networkv1alpha2.AddToContainer(container, ""))