Initial commit
This commit is contained in:
66
pkg/apiserver/components/components.go
Normal file
66
pkg/apiserver/components/components.go
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
|
||||
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 components
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models/components"
|
||||
)
|
||||
|
||||
func V1Alpha2(ws *restful.WebService) {
|
||||
ws.Route(ws.GET("/components").To(getComponents))
|
||||
ws.Route(ws.GET("/components/{component}").To(getComponentStatus))
|
||||
ws.Route(ws.GET("/health").To(getSystemHealthStatus))
|
||||
}
|
||||
|
||||
func getSystemHealthStatus(request *restful.Request, response *restful.Response) {
|
||||
result, err := components.GetAllComponentsStatus()
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(result)
|
||||
}
|
||||
|
||||
// get a specific component status
|
||||
func getComponentStatus(request *restful.Request, response *restful.Response) {
|
||||
component := request.PathParameter("component")
|
||||
|
||||
result, err := components.GetComponentStatus(component)
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(result)
|
||||
}
|
||||
|
||||
// get all componentsHandler
|
||||
func getComponents(request *restful.Request, response *restful.Response) {
|
||||
|
||||
result, err := components.GetAllComponentsStatus()
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(result)
|
||||
}
|
||||
52
pkg/apiserver/hpa/hpa.go
Normal file
52
pkg/apiserver/hpa/hpa.go
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
|
||||
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 hpa
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful-openapi"
|
||||
"k8s.io/api/autoscaling/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models/hpa"
|
||||
)
|
||||
|
||||
func V1Alpha2(ws *restful.WebService) {
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/horizontalpodautoscalers/{horizontalpodautoscaler}").
|
||||
To(getHpa).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{"hpa"}).
|
||||
Doc("get horizontalpodautoscalers").
|
||||
Param(ws.PathParameter("namespace", "horizontalpodautoscalers's namespace").
|
||||
DataType("string")).
|
||||
Param(ws.PathParameter("horizontalpodautoscaler", "horizontalpodautoscaler's name")).
|
||||
Writes(v1.HorizontalPodAutoscaler{}))
|
||||
}
|
||||
|
||||
func getHpa(req *restful.Request, resp *restful.Response) {
|
||||
name := req.PathParameter("horizontalpodautoscaler")
|
||||
namespace := req.PathParameter("namespace")
|
||||
|
||||
result, err := hpa.GetHPA(namespace, name)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(result)
|
||||
}
|
||||
76
pkg/apiserver/metrics/metrics.go
Normal file
76
pkg/apiserver/metrics/metrics.go
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
|
||||
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 metrics
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models/storage"
|
||||
)
|
||||
|
||||
type scMetricsItem struct {
|
||||
Name string `json:"name"`
|
||||
Metrics *storage.ScMetrics `json:"metrics"`
|
||||
}
|
||||
|
||||
// Get StorageClass item
|
||||
// Extended API URL: "GET /api/v1alpha1/storage/storageclasses/{storageclass}/metrics"
|
||||
func GetScMetrics(request *restful.Request, response *restful.Response) {
|
||||
scName := request.PathParameter("storageclass")
|
||||
|
||||
metrics, err := storage.GetScMetrics(scName)
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
result := scMetricsItem{
|
||||
Name: scName, Metrics: metrics,
|
||||
}
|
||||
|
||||
response.WriteAsJson(result)
|
||||
}
|
||||
|
||||
// Get StorageClass item list
|
||||
// Extended API URL: "GET /api/v1alpha1/storage/storageclasses/metrics"
|
||||
func GetScMetricsList(request *restful.Request, response *restful.Response) {
|
||||
scList, err := storage.GetScList()
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
// Set return value
|
||||
items := make([]scMetricsItem, 0)
|
||||
|
||||
for _, v := range scList {
|
||||
metrics, err := storage.GetScMetrics(v.GetName())
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
item := scMetricsItem{
|
||||
Name: v.GetName(), Metrics: metrics,
|
||||
}
|
||||
|
||||
items = append(items, item)
|
||||
}
|
||||
|
||||
response.WriteAsJson(items)
|
||||
}
|
||||
51
pkg/apiserver/operations/job.go
Normal file
51
pkg/apiserver/operations/job.go
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
|
||||
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 operations
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models/workloads"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func RerunJob(req *restful.Request, resp *restful.Response) {
|
||||
var err error
|
||||
|
||||
job := req.PathParameter("job")
|
||||
namespace := req.PathParameter("namespace")
|
||||
action := req.QueryParameter("a")
|
||||
|
||||
switch action {
|
||||
case "rerun":
|
||||
err = workloads.JobReRun(namespace, job)
|
||||
default:
|
||||
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New(errors.InvalidArgument, fmt.Sprintf("invalid operation %s", action)))
|
||||
return
|
||||
}
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(errors.None)
|
||||
}
|
||||
39
pkg/apiserver/operations/node.go
Normal file
39
pkg/apiserver/operations/node.go
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
|
||||
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 operations
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models/nodes"
|
||||
)
|
||||
|
||||
func DrainNode(request *restful.Request, response *restful.Response) {
|
||||
|
||||
nodeName := request.PathParameter("node")
|
||||
|
||||
err := nodes.DrainNode(nodeName)
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(errors.None)
|
||||
}
|
||||
69
pkg/apiserver/quotas/quotas.go
Normal file
69
pkg/apiserver/quotas/quotas.go
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
|
||||
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 quotas
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful-openapi"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/quotas"
|
||||
)
|
||||
|
||||
func V1Alpha2(ws *restful.WebService) {
|
||||
|
||||
tags := []string{"quotas"}
|
||||
|
||||
ws.Route(ws.GET("/quotas").
|
||||
To(getClusterQuotas).
|
||||
Doc("get whole cluster's resource usage").
|
||||
Writes(quotas.ResourceQuota{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags))
|
||||
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/quotas").
|
||||
Doc("get specified namespace's resource quota and usage").
|
||||
Param(ws.PathParameter("namespace", "namespace's name").
|
||||
DataType("string")).
|
||||
Writes(quotas.ResourceQuota{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(getNamespaceQuotas))
|
||||
|
||||
}
|
||||
|
||||
func getNamespaceQuotas(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
quota, err := quotas.GetNamespaceQuotas(namespace)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(quota)
|
||||
}
|
||||
|
||||
func getClusterQuotas(req *restful.Request, resp *restful.Response) {
|
||||
quota, err := quotas.GetClusterQuotas()
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(quota)
|
||||
}
|
||||
74
pkg/apiserver/registries/registries.go
Normal file
74
pkg/apiserver/registries/registries.go
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
|
||||
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 registries
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models/registries"
|
||||
)
|
||||
|
||||
func V1Alpha2(ws *restful.WebService) {
|
||||
|
||||
ws.Route(ws.POST("registries/verify").To(registryVerify))
|
||||
|
||||
}
|
||||
|
||||
func registryVerify(request *restful.Request, response *restful.Response) {
|
||||
|
||||
authInfo := registries.AuthInfo{}
|
||||
|
||||
err := request.ReadEntity(&authInfo)
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
err = registries.RegistryVerify(authInfo)
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(errors.None)
|
||||
}
|
||||
|
||||
//func (c *registriesHandler) handlerImageSearch(request *restful.Request, response *restful.Response) {
|
||||
//
|
||||
// registry := request.PathParameter("name")
|
||||
// searchWord := request.PathParameter("searchWord")
|
||||
// namespace := request.PathParameter("namespace")
|
||||
//
|
||||
// res := c.registries.ImageSearch(namespace, registry, searchWord)
|
||||
//
|
||||
// response.WriteAsJson(res)
|
||||
//
|
||||
//}
|
||||
//
|
||||
//func (c *registriesHandler) handlerGetImageTags(request *restful.Request, response *restful.Response) {
|
||||
//
|
||||
// registry := request.PathParameter("name")
|
||||
// image := request.QueryParameter("image")
|
||||
// namespace := request.PathParameter("namespace")
|
||||
//
|
||||
// res := c.registries.GetImageTags(namespace, registry, image)
|
||||
//
|
||||
// response.WriteAsJson(res)
|
||||
//}
|
||||
42
pkg/apiserver/resources/cluster_resources.go
Normal file
42
pkg/apiserver/resources/cluster_resources.go
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
|
||||
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 resources
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
)
|
||||
|
||||
func ClusterResourceHandler(req *restful.Request, resp *restful.Response) {
|
||||
resourceName := req.PathParameter("resources")
|
||||
conditions := req.QueryParameter(params.Conditions)
|
||||
orderBy := req.QueryParameter(params.OrderBy)
|
||||
limit, offset := params.ParsePaging(req.QueryParameter(params.Paging))
|
||||
reverse := params.ParseReserve(req.QueryParameter(params.Reserve))
|
||||
|
||||
result, err := resources.ListClusterResource(resourceName, conditions, orderBy, reverse, limit, offset)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(result)
|
||||
}
|
||||
43
pkg/apiserver/resources/namespace_resources.go
Normal file
43
pkg/apiserver/resources/namespace_resources.go
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
|
||||
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 resources
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
)
|
||||
|
||||
func NamespaceResourceHandler(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
resourceName := req.PathParameter("resources")
|
||||
conditions := req.QueryParameter(params.Conditions)
|
||||
orderBy := req.QueryParameter(params.OrderBy)
|
||||
limit, offset := params.ParsePaging(req.QueryParameter(params.Paging))
|
||||
reverse := params.ParseReserve(req.QueryParameter(params.Reserve))
|
||||
|
||||
result, err := resources.ListNamespaceResource(namespace, resourceName, conditions, orderBy, reverse, limit, offset)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(result)
|
||||
}
|
||||
68
pkg/apiserver/resources/storage.go
Normal file
68
pkg/apiserver/resources/storage.go
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
|
||||
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 resources
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"k8s.io/api/core/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models/storage"
|
||||
)
|
||||
|
||||
type pvcList struct {
|
||||
Name string `json:"name"`
|
||||
Items []*v1.PersistentVolumeClaim `json:"items"`
|
||||
}
|
||||
|
||||
type podListByPvc struct {
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace"`
|
||||
Pods []*v1.Pod `json:"pods"`
|
||||
}
|
||||
|
||||
// List all pods of a specific PVC
|
||||
// Extended API URL: "GET /api/v1alpha2/namespaces/{namespace}/persistentvolumeclaims/{name}/pods"
|
||||
func GetPodListByPvc(request *restful.Request, response *restful.Response) {
|
||||
|
||||
pvcName := request.PathParameter("pvc")
|
||||
nsName := request.PathParameter("namespace")
|
||||
pods, err := storage.GetPodListByPvc(pvcName, nsName)
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
result := podListByPvc{Name: pvcName, Namespace: nsName, Pods: pods}
|
||||
response.WriteAsJson(result)
|
||||
}
|
||||
|
||||
// List all PersistentVolumeClaims of a specific StorageClass
|
||||
// Extended API URL: "GET /api/v1alpha2/storageclasses/{storageclass}/persistentvolumeclaims"
|
||||
func GetPvcListBySc(request *restful.Request, response *restful.Response) {
|
||||
scName := request.PathParameter("storageclass")
|
||||
claims, err := storage.GetPvcListBySc(scName)
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
result := pvcList{
|
||||
Name: scName, Items: claims,
|
||||
}
|
||||
|
||||
response.WriteAsJson(result)
|
||||
}
|
||||
52
pkg/apiserver/resources/user.go
Normal file
52
pkg/apiserver/resources/user.go
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
|
||||
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 resources
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models/kubeconfig"
|
||||
"kubesphere.io/kubesphere/pkg/models/kubectl"
|
||||
)
|
||||
|
||||
func GetKubectl(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
user := req.PathParameter("username")
|
||||
|
||||
kubectlPod, err := kubectl.GetKubectlPod(user)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(kubectlPod)
|
||||
}
|
||||
|
||||
func GetKubeconfig(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
user := req.PathParameter("username")
|
||||
|
||||
kubectlConfig, err := kubeconfig.GetKubeConfig(user)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(kubectlConfig)
|
||||
}
|
||||
116
pkg/apiserver/revisions/revisions.go
Normal file
116
pkg/apiserver/revisions/revisions.go
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
|
||||
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 revisions
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful-openapi"
|
||||
"k8s.io/api/apps/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models/revisions"
|
||||
)
|
||||
|
||||
func V1Alpha2(ws *restful.WebService) {
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/daemonsets/{daemonset}/revisions/{revision}").
|
||||
To(getDaemonSetRevision).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{"daemonsets", "revision"}).
|
||||
Doc("Handle daemonset operation").
|
||||
Param(ws.PathParameter("daemonset", "daemonset's name").
|
||||
DataType("string")).
|
||||
Param(ws.PathParameter("namespace", "daemonset's namespace").
|
||||
DataType("string")).
|
||||
Param(ws.PathParameter("revision", "daemonset's revision")).
|
||||
Writes(v1.DaemonSet{}))
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/deployments/{deployment}/revisions/{revision}").
|
||||
To(getDeployRevision).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{"deployments", "revision"}).
|
||||
Doc("Handle deployment operation").
|
||||
Param(ws.PathParameter("deployment", "deployment's name").
|
||||
DataType("string")).
|
||||
Param(ws.PathParameter("namespace",
|
||||
"deployment's namespace").
|
||||
DataType("string")).
|
||||
Param(ws.PathParameter("deployment", "deployment's name")).
|
||||
Writes(v1.ReplicaSet{}))
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/statefulsets/{statefulset}/revisions/{revision}").
|
||||
To(getStatefulSetRevision).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{"statefulsets", "revisions"}).
|
||||
Doc("Handle statefulset operation").
|
||||
Param(ws.PathParameter("statefulset", "statefulset's name").
|
||||
DataType("string")).
|
||||
Param(ws.PathParameter("namespace", "statefulset's namespace").
|
||||
DataType("string")).
|
||||
Param(ws.PathParameter("revision", "statefulset's revision")).
|
||||
Writes(v1.StatefulSet{}))
|
||||
}
|
||||
|
||||
func getDaemonSetRevision(req *restful.Request, resp *restful.Response) {
|
||||
daemonset := req.PathParameter("daemonset")
|
||||
namespace := req.PathParameter("namespace")
|
||||
revision, err := strconv.Atoi(req.PathParameter("revision"))
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New(errors.InvalidArgument, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
result, err := revisions.GetDaemonSetRevision(namespace, daemonset, revision)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(result)
|
||||
}
|
||||
|
||||
func getDeployRevision(req *restful.Request, resp *restful.Response) {
|
||||
deploy := req.PathParameter("deployment")
|
||||
namespace := req.PathParameter("namespace")
|
||||
revision := req.PathParameter("revision")
|
||||
|
||||
result, err := revisions.GetDeployRevision(namespace, deploy, revision)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(result)
|
||||
}
|
||||
|
||||
func getStatefulSetRevision(req *restful.Request, resp *restful.Response) {
|
||||
statefulset := req.PathParameter("statefulset")
|
||||
namespace := req.PathParameter("namespace")
|
||||
revision, err := strconv.Atoi(req.PathParameter("revision"))
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New(errors.InvalidArgument, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
result, err := revisions.GetStatefulSetRevision(namespace, statefulset, revision)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(result)
|
||||
}
|
||||
187
pkg/apiserver/routers/routers.go
Normal file
187
pkg/apiserver/routers/routers.go
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
|
||||
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 routers
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/core/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/routers"
|
||||
)
|
||||
|
||||
func V1Alpha2(ws *restful.WebService) {
|
||||
ws.Route(ws.GET("/routers").To(getAllRouters).
|
||||
Doc("Get all routers"))
|
||||
|
||||
ws.Route(ws.GET("/users/{username}/routers").To(getAllRoutersOfUser).
|
||||
Doc("Get routers for user"))
|
||||
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/router").To(getRouter).
|
||||
Doc("Get router of a specified project").
|
||||
Param(ws.PathParameter("namespace", "name of the project").
|
||||
DataType("string")))
|
||||
|
||||
ws.Route(ws.DELETE("/namespaces/{namespace}/router").To(deleteRouter).
|
||||
Doc("Get router of a specified project").
|
||||
Param(ws.PathParameter("namespace", "name of the project").
|
||||
DataType("string")))
|
||||
|
||||
ws.Route(ws.POST("/namespaces/{namespace}/router").To(createRouter).
|
||||
Doc("Create a router for a specified project").
|
||||
Param(ws.PathParameter("namespace", "name of the project").
|
||||
DataType("string")))
|
||||
|
||||
ws.Route(ws.PUT("/namespaces/{namespace}/router").To(updateRouter).
|
||||
Doc("Update a router for a specified project").
|
||||
Param(ws.PathParameter("namespace", "name of the project").
|
||||
DataType("string")))
|
||||
}
|
||||
|
||||
type Router struct {
|
||||
RouterType string `json:"type"`
|
||||
Annotations map[string]string `json:"annotations"`
|
||||
}
|
||||
|
||||
// Get all namespace ingress controller services
|
||||
func getAllRouters(request *restful.Request, response *restful.Response) {
|
||||
|
||||
routers, err := routers.GetAllRouters()
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(routers)
|
||||
}
|
||||
|
||||
// Get all namespace ingress controller services for user
|
||||
func getAllRoutersOfUser(request *restful.Request, response *restful.Response) {
|
||||
|
||||
username := request.PathParameter("username")
|
||||
|
||||
routers, err := routers.GetAllRoutersOfUser(username)
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(routers)
|
||||
}
|
||||
|
||||
// Get ingress controller service for specified namespace
|
||||
func getRouter(request *restful.Request, response *restful.Response) {
|
||||
|
||||
namespace := request.PathParameter("namespace")
|
||||
router, err := routers.GetRouter(namespace)
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(router)
|
||||
}
|
||||
|
||||
// Create ingress controller and related services
|
||||
func createRouter(request *restful.Request, response *restful.Response) {
|
||||
|
||||
namespace := request.PathParameter("namespace")
|
||||
|
||||
newRouter := Router{}
|
||||
err := request.ReadEntity(&newRouter)
|
||||
|
||||
if err != nil {
|
||||
response.WriteAsJson(err)
|
||||
return
|
||||
}
|
||||
|
||||
var router *v1.Service
|
||||
|
||||
serviceType, annotationMap, err := ParseParameter(newRouter)
|
||||
|
||||
if err != nil {
|
||||
glog.Error("Wrong annotations, missing key or value")
|
||||
response.WriteHeaderAndEntity(http.StatusBadRequest,
|
||||
errors.New(errors.InvalidArgument, "Wrong annotations, missing key or value"))
|
||||
return
|
||||
}
|
||||
|
||||
router, err = routers.CreateRouter(namespace, serviceType, annotationMap)
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(router)
|
||||
}
|
||||
|
||||
// Delete ingress controller and services
|
||||
func deleteRouter(request *restful.Request, response *restful.Response) {
|
||||
namespace := request.PathParameter("namespace")
|
||||
|
||||
router, err := routers.DeleteRouter(namespace)
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(router)
|
||||
}
|
||||
|
||||
func updateRouter(request *restful.Request, response *restful.Response) {
|
||||
|
||||
namespace := request.PathParameter("namespace")
|
||||
|
||||
newRouter := Router{}
|
||||
err := request.ReadEntity(&newRouter)
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
response.WriteHeaderAndEntity(http.StatusBadRequest, errors.New(errors.InvalidArgument, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
serviceType, annotationMap, err := ParseParameter(newRouter)
|
||||
|
||||
router, err := routers.UpdateRouter(namespace, serviceType, annotationMap)
|
||||
|
||||
if errors.HandlerError(err, response) {
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(router)
|
||||
}
|
||||
|
||||
func ParseParameter(router Router) (routerType v1.ServiceType, annotationMap map[string]string, err error) {
|
||||
|
||||
routerType = v1.ServiceTypeNodePort
|
||||
|
||||
if strings.Compare(strings.ToLower(router.RouterType), "loadbalancer") == 0 {
|
||||
return v1.ServiceTypeLoadBalancer, router.Annotations, nil
|
||||
} else {
|
||||
return v1.ServiceTypeNodePort, make(map[string]string, 0), nil
|
||||
}
|
||||
|
||||
}
|
||||
64
pkg/apiserver/runtime/runtime.go
Normal file
64
pkg/apiserver/runtime/runtime.go
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
|
||||
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 runtime
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
ApiRootPath = "/apis"
|
||||
)
|
||||
|
||||
// container holds all webservice of apiserver
|
||||
var Container = restful.NewContainer()
|
||||
|
||||
type ContainerBuilder []func(c *restful.Container) error
|
||||
|
||||
//
|
||||
func NewWebService(gv schema.GroupVersion) *restful.WebService {
|
||||
webservice := restful.WebService{}
|
||||
|
||||
webservice.Path(ApiRootPath + "/" + gv.String())
|
||||
|
||||
return &webservice
|
||||
}
|
||||
|
||||
func (cb *ContainerBuilder) AddToContainer(c *restful.Container) error {
|
||||
for _, f := range *cb {
|
||||
if err := f(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cb *ContainerBuilder) Register(funcs ...func(*restful.Container) error) {
|
||||
for _, f := range funcs {
|
||||
*cb = append(*cb, f)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
func NewContainerBuilder(funcs ...func(*restful.Container) error) ContainerBuilder {
|
||||
var cb ContainerBuilder
|
||||
cb.Register(funcs...)
|
||||
|
||||
return cb
|
||||
}
|
||||
59
pkg/apiserver/workloadstatuses/workloadstatuses.go
Normal file
59
pkg/apiserver/workloadstatuses/workloadstatuses.go
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
|
||||
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 workloadstatuses
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful-openapi"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models/status"
|
||||
)
|
||||
|
||||
func V1Alpha2(ws *restful.WebService) {
|
||||
tags := []string{"workloadStatus"}
|
||||
|
||||
ws.Route(ws.GET("/workloadstatuses").
|
||||
Doc("get abnormal workloads' count of whole cluster").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(getClusterResourceStatus))
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/workloadstatuses").
|
||||
Doc("get abnormal workloads' count of specified namespace").
|
||||
Param(ws.PathParameter("namespace", "the name of namespace").
|
||||
DataType("string")).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(getNamespacesResourceStatus))
|
||||
|
||||
}
|
||||
|
||||
func getClusterResourceStatus(req *restful.Request, resp *restful.Response) {
|
||||
res, err := status.GetClusterResourceStatus()
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
resp.WriteAsJson(res)
|
||||
}
|
||||
|
||||
func getNamespacesResourceStatus(req *restful.Request, resp *restful.Response) {
|
||||
res, err := status.GetNamespacesResourceStatus(req.PathParameter("namespace"))
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
resp.WriteAsJson(res)
|
||||
}
|
||||
506
pkg/apiserver/workspaces/workspaces.go
Normal file
506
pkg/apiserver/workspaces/workspaces.go
Normal file
@@ -0,0 +1,506 @@
|
||||
/*
|
||||
|
||||
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 workspaces
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/metrics"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"k8s.io/api/core/v1"
|
||||
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"strconv"
|
||||
|
||||
"regexp"
|
||||
|
||||
"sort"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/iam"
|
||||
"kubesphere.io/kubesphere/pkg/models/workspaces"
|
||||
)
|
||||
|
||||
const UserNameHeader = "X-Token-Username"
|
||||
|
||||
func V1Alpha2(ws *restful.WebService) {
|
||||
ws.Route(ws.GET("/workspaces").To(UserWorkspaceListHandler))
|
||||
ws.Route(ws.POST("/workspaces").To(WorkspaceCreateHandler))
|
||||
ws.Route(ws.DELETE("/workspaces/{name}").To(DeleteWorkspaceHandler))
|
||||
ws.Route(ws.GET("/workspaces/{name}").To(WorkspaceDetailHandler))
|
||||
ws.Route(ws.PUT("/workspaces/{name}").To(WorkspaceEditHandler))
|
||||
ws.Route(ws.GET("/workspaces/{workspace}/namespaces").To(UserNamespaceListHandler))
|
||||
ws.Route(ws.GET("/workspaces/{workspace}/members/{username}/namespaces").To(UserNamespaceListHandler))
|
||||
ws.Route(ws.POST("/workspaces/{name}/namespaces").To(NamespaceCreateHandler))
|
||||
ws.Route(ws.DELETE("/workspaces/{name}/namespaces/{namespace}").To(NamespaceDeleteHandler))
|
||||
ws.Route(ws.GET("/workspaces/{name}/namespaces/{namespace}").To(NamespaceCheckHandler))
|
||||
ws.Route(ws.GET("/namespaces/{namespace}").To(NamespaceCheckHandler))
|
||||
ws.Route(ws.GET("/workspaces/{name}/devops").To(DevOpsProjectHandler))
|
||||
ws.Route(ws.GET("/workspaces/{name}/members/{username}/devops").To(DevOpsProjectHandler))
|
||||
ws.Route(ws.POST("/workspaces/{name}/devops").To(DevOpsProjectCreateHandler))
|
||||
ws.Route(ws.DELETE("/workspaces/{name}/devops/{id}").To(DevOpsProjectDeleteHandler))
|
||||
|
||||
ws.Route(ws.GET("/workspaces/{name}/members").To(MembersHandler))
|
||||
ws.Route(ws.GET("/workspaces/{name}/members/{member}").To(MemberHandler))
|
||||
ws.Route(ws.GET("/workspaces/{name}/roles").To(RolesHandler))
|
||||
// TODO /workspaces/{name}/roles/{role}
|
||||
ws.Route(ws.POST("/workspaces/{name}/members").To(MembersInviteHandler))
|
||||
ws.Route(ws.DELETE("/workspaces/{name}/members").To(MembersRemoveHandler))
|
||||
}
|
||||
|
||||
func RolesHandler(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
name := req.PathParameter("name")
|
||||
|
||||
workspace, err := workspaces.Detail(name)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
roles, err := workspaces.Roles(workspace)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(roles)
|
||||
}
|
||||
|
||||
func MembersHandler(req *restful.Request, resp *restful.Response) {
|
||||
workspace := req.PathParameter("name")
|
||||
keyword := req.QueryParameter("keyword")
|
||||
|
||||
users, err := workspaces.GetWorkspaceMembers(workspace, keyword)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(users)
|
||||
}
|
||||
|
||||
func MemberHandler(req *restful.Request, resp *restful.Response) {
|
||||
workspace := req.PathParameter("name")
|
||||
username := req.PathParameter("member")
|
||||
|
||||
user, err := iam.GetUser(username)
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
namespaces, err := workspaces.Namespaces(workspace)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
user.WorkspaceRole = user.WorkspaceRoles[workspace]
|
||||
|
||||
roles := make(map[string]string)
|
||||
|
||||
for _, namespace := range namespaces {
|
||||
if role := user.Roles[namespace.Name]; role != "" {
|
||||
roles[namespace.Name] = role
|
||||
}
|
||||
}
|
||||
|
||||
user.Roles = roles
|
||||
user.Rules = nil
|
||||
user.WorkspaceRules = nil
|
||||
user.WorkspaceRoles = nil
|
||||
user.ClusterRules = nil
|
||||
resp.WriteAsJson(user)
|
||||
}
|
||||
|
||||
func MembersInviteHandler(req *restful.Request, resp *restful.Response) {
|
||||
var users []workspaces.UserInvite
|
||||
workspace := req.PathParameter("name")
|
||||
err := req.ReadEntity(&users)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
err = workspaces.Invite(workspace, users)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(errors.None)
|
||||
}
|
||||
|
||||
func MembersRemoveHandler(req *restful.Request, resp *restful.Response) {
|
||||
query := req.QueryParameter("name")
|
||||
workspace := req.PathParameter("name")
|
||||
|
||||
names := strings.Split(query, ",")
|
||||
|
||||
err := workspaces.RemoveMembers(workspace, names)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(errors.None)
|
||||
}
|
||||
|
||||
func NamespaceCheckHandler(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
|
||||
exist, err := workspaces.NamespaceExistCheck(namespace)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(map[string]bool{"exist": exist})
|
||||
}
|
||||
|
||||
func NamespaceDeleteHandler(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
workspace := req.PathParameter("name")
|
||||
|
||||
err := workspaces.DeleteNamespace(workspace, namespace)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(errors.None)
|
||||
}
|
||||
|
||||
func DevOpsProjectDeleteHandler(req *restful.Request, resp *restful.Response) {
|
||||
devops := req.PathParameter("id")
|
||||
workspace := req.PathParameter("name")
|
||||
force := req.QueryParameter("force")
|
||||
username := req.HeaderParameter(UserNameHeader)
|
||||
|
||||
err := workspaces.UnBindDevopsProject(workspace, devops)
|
||||
|
||||
if err != nil && force != "true" {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.New(errors.Internal, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
err = workspaces.DeleteDevopsProject(username, devops)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(errors.None)
|
||||
}
|
||||
|
||||
func DevOpsProjectCreateHandler(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
workspace := req.PathParameter("name")
|
||||
username := req.HeaderParameter(UserNameHeader)
|
||||
|
||||
var devops workspaces.DevopsProject
|
||||
|
||||
err := req.ReadEntity(&devops)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New(errors.InvalidArgument, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
project, err := workspaces.CreateDevopsProject(username, workspace, devops)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(project)
|
||||
|
||||
}
|
||||
|
||||
func NamespaceCreateHandler(req *restful.Request, resp *restful.Response) {
|
||||
workspace := req.PathParameter("name")
|
||||
username := req.HeaderParameter(UserNameHeader)
|
||||
|
||||
namespace := &v1.Namespace{}
|
||||
|
||||
err := req.ReadEntity(namespace)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New(errors.InvalidArgument, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if namespace.Annotations == nil {
|
||||
namespace.Annotations = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
namespace.Annotations["creator"] = username
|
||||
namespace.Annotations["workspace"] = workspace
|
||||
|
||||
if namespace.Labels == nil {
|
||||
namespace.Labels = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
namespace.Labels["kubesphere.io/workspace"] = workspace
|
||||
|
||||
namespace, err = workspaces.CreateNamespace(namespace)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New(errors.InvalidArgument, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(namespace)
|
||||
}
|
||||
|
||||
func DevOpsProjectHandler(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
workspace := req.PathParameter("name")
|
||||
username := req.PathParameter("username")
|
||||
keyword := req.QueryParameter("keyword")
|
||||
|
||||
if username == "" {
|
||||
username = req.HeaderParameter(UserNameHeader)
|
||||
}
|
||||
|
||||
limit := 65535
|
||||
offset := 0
|
||||
orderBy := "createTime"
|
||||
reverse := true
|
||||
|
||||
if groups := regexp.MustCompile(`^limit=(\d+),page=(\d+)$`).FindStringSubmatch(req.QueryParameter("paging")); len(groups) == 3 {
|
||||
limit, _ = strconv.Atoi(groups[1])
|
||||
page, _ := strconv.Atoi(groups[2])
|
||||
offset = (page - 1) * limit
|
||||
}
|
||||
|
||||
if groups := regexp.MustCompile(`^(createTime|name)$`).FindStringSubmatch(req.QueryParameter("order")); len(groups) == 2 {
|
||||
orderBy = groups[1]
|
||||
reverse = false
|
||||
}
|
||||
|
||||
if q := req.QueryParameter("reverse"); q != "" {
|
||||
b, err := strconv.ParseBool(q)
|
||||
if err == nil {
|
||||
reverse = b
|
||||
}
|
||||
}
|
||||
|
||||
total, devOpsProjects, err := workspaces.ListDevopsProjectsByUser(username, workspace, keyword, orderBy, reverse, limit, offset)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
result := models.PageableResponse{}
|
||||
result.TotalCount = total
|
||||
result.Items = make([]interface{}, 0)
|
||||
for _, n := range devOpsProjects {
|
||||
result.Items = append(result.Items, n)
|
||||
}
|
||||
resp.WriteAsJson(result)
|
||||
}
|
||||
|
||||
func WorkspaceCreateHandler(req *restful.Request, resp *restful.Response) {
|
||||
var workspace workspaces.Workspace
|
||||
username := req.HeaderParameter(UserNameHeader)
|
||||
err := req.ReadEntity(&workspace)
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New(errors.InvalidArgument, err.Error()))
|
||||
return
|
||||
}
|
||||
if workspace.Name == "" || strings.Contains(workspace.Name, ":") {
|
||||
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New(errors.InvalidArgument, "invalid workspace name"))
|
||||
return
|
||||
}
|
||||
|
||||
workspace.Path = workspace.Name
|
||||
workspace.Members = nil
|
||||
|
||||
if workspace.Admin != "" {
|
||||
workspace.Creator = workspace.Admin
|
||||
} else {
|
||||
workspace.Creator = username
|
||||
}
|
||||
|
||||
created, err := workspaces.Create(&workspace)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(created)
|
||||
|
||||
}
|
||||
|
||||
func DeleteWorkspaceHandler(req *restful.Request, resp *restful.Response) {
|
||||
name := req.PathParameter("name")
|
||||
|
||||
if name == "" || strings.Contains(name, ":") {
|
||||
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New(errors.InvalidArgument, "invalid workspace name"))
|
||||
return
|
||||
}
|
||||
|
||||
workspace, err := workspaces.Detail(name)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
err = workspaces.Delete(workspace)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(errors.None)
|
||||
}
|
||||
func WorkspaceEditHandler(req *restful.Request, resp *restful.Response) {
|
||||
var workspace workspaces.Workspace
|
||||
name := req.PathParameter("name")
|
||||
err := req.ReadEntity(&workspace)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New(errors.InvalidArgument, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if name != workspace.Name {
|
||||
resp.WriteError(http.StatusBadRequest, fmt.Errorf("the name of workspace (%s) does not match the name on the URL (%s)", workspace.Name, name))
|
||||
return
|
||||
}
|
||||
|
||||
if workspace.Name == "" || strings.Contains(workspace.Name, ":") {
|
||||
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New(errors.InvalidArgument, "invalid workspace name"))
|
||||
return
|
||||
}
|
||||
|
||||
workspace.Path = workspace.Name
|
||||
|
||||
workspace.Members = nil
|
||||
|
||||
edited, err := workspaces.Edit(&workspace)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(edited)
|
||||
}
|
||||
func WorkspaceDetailHandler(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
name := req.PathParameter("name")
|
||||
|
||||
workspace, err := workspaces.Detail(name)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(workspace)
|
||||
}
|
||||
|
||||
// List all workspaces for the current user
|
||||
func UserWorkspaceListHandler(req *restful.Request, resp *restful.Response) {
|
||||
keyword := req.QueryParameter("keyword")
|
||||
username := req.HeaderParameter(UserNameHeader)
|
||||
|
||||
ws, err := workspaces.ListWorkspaceByUser(username, keyword)
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
sort.Slice(ws, func(i, j int) bool {
|
||||
t1, err := ws[i].GetCreateTime()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
t2, err := ws[j].GetCreateTime()
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
return t1.After(t2)
|
||||
})
|
||||
|
||||
resp.WriteAsJson(ws)
|
||||
}
|
||||
|
||||
func UserNamespaceListHandler(req *restful.Request, resp *restful.Response) {
|
||||
withMetrics, err := strconv.ParseBool(req.QueryParameter("metrics"))
|
||||
|
||||
if err != nil {
|
||||
withMetrics = false
|
||||
}
|
||||
|
||||
username := req.PathParameter("username")
|
||||
keyword := req.QueryParameter("keyword")
|
||||
if username == "" {
|
||||
username = req.HeaderParameter(UserNameHeader)
|
||||
}
|
||||
limit := 65535
|
||||
offset := 0
|
||||
orderBy := "createTime"
|
||||
reverse := true
|
||||
|
||||
if groups := regexp.MustCompile(`^limit=(\d+),page=(\d+)$`).FindStringSubmatch(req.QueryParameter("paging")); len(groups) == 3 {
|
||||
limit, _ = strconv.Atoi(groups[1])
|
||||
page, _ := strconv.Atoi(groups[2])
|
||||
if page < 0 {
|
||||
page = 1
|
||||
}
|
||||
offset = (page - 1) * limit
|
||||
}
|
||||
|
||||
if groups := regexp.MustCompile(`^(createTime|name)$`).FindStringSubmatch(req.QueryParameter("order")); len(groups) == 2 {
|
||||
orderBy = groups[1]
|
||||
reverse = false
|
||||
}
|
||||
|
||||
if q := req.QueryParameter("reverse"); q != "" {
|
||||
b, err := strconv.ParseBool(q)
|
||||
if err == nil {
|
||||
reverse = b
|
||||
}
|
||||
}
|
||||
|
||||
workspaceName := req.PathParameter("workspace")
|
||||
|
||||
total, namespaces, err := workspaces.ListNamespaceByUser(workspaceName, username, keyword, orderBy, reverse, limit, offset)
|
||||
|
||||
if withMetrics {
|
||||
namespaces = metrics.GetNamespacesWithMetrics(namespaces)
|
||||
}
|
||||
|
||||
if errors.HandlerError(err, resp) {
|
||||
return
|
||||
}
|
||||
|
||||
result := models.PageableResponse{}
|
||||
result.TotalCount = total
|
||||
result.Items = make([]interface{}, 0)
|
||||
for _, n := range namespaces {
|
||||
result.Items = append(result.Items, n)
|
||||
}
|
||||
|
||||
resp.WriteAsJson(result)
|
||||
}
|
||||
Reference in New Issue
Block a user