devlopment branch (#1736)
This commit is contained in:
81
pkg/apiserver/apiserver.go
Normal file
81
pkg/apiserver/apiserver.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package apiserver
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/kapis/resources/v1alpha3"
|
||||
"kubesphere.io/kubesphere/pkg/server/options"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/cache"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/db"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/logging"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/monitoring"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/s3"
|
||||
)
|
||||
|
||||
const (
|
||||
// ApiRootPath defines the root path of all KubeSphere apis.
|
||||
ApiRootPath = "/kapis"
|
||||
|
||||
// MimeMergePatchJson is the mime header used in merge request
|
||||
MimeMergePatchJson = "application/merge-patch+json"
|
||||
|
||||
//
|
||||
MimeJsonPatchJson = "application/json-patch+json"
|
||||
)
|
||||
|
||||
// Dependencies is objects constructed at runtime that are necessary for running apiserver.
|
||||
type Dependencies struct {
|
||||
|
||||
// Injected Dependencies
|
||||
KubeClient k8s.Client
|
||||
S3 s3.Interface
|
||||
OpenPitrix openpitrix.Interface
|
||||
Monitoring monitoring.Interface
|
||||
Logging logging.Interface
|
||||
Devops devops.Interface
|
||||
DB db.Interface
|
||||
}
|
||||
|
||||
type APIServer struct {
|
||||
|
||||
// number of kubesphere apiserver
|
||||
apiserverCount int
|
||||
|
||||
//
|
||||
genericServerOptions *options.ServerRunOptions
|
||||
|
||||
// webservice container, where all webservice defines
|
||||
container *restful.Container
|
||||
|
||||
// kubeClient is a collection of all kubernetes(include CRDs) objects clientset
|
||||
kubeClient k8s.Client
|
||||
|
||||
// informerFactory is a collection of all kubernetes(include CRDs) objects informers,
|
||||
// mainly for fast query
|
||||
informerFactory informers.InformerFactory
|
||||
|
||||
// cache is used for short lived objects, like session
|
||||
cache cache.Interface
|
||||
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
func New(deps *Dependencies) *APIServer {
|
||||
|
||||
server := &APIServer{}
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
func (s *APIServer) InstallKubeSphereAPIs() {
|
||||
|
||||
resourcev1alpha3.AddWebService(s.container, s.kubeClient)
|
||||
}
|
||||
|
||||
func (s *APIServer) Serve() error {
|
||||
panic("implement me")
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
|
||||
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/models/components"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func GetSystemHealthStatus(request *restful.Request, response *restful.Response) {
|
||||
result, err := components.GetSystemHealthStatus()
|
||||
|
||||
if err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
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 err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(result)
|
||||
}
|
||||
|
||||
// get all componentsHandler
|
||||
func GetComponents(request *restful.Request, response *restful.Response) {
|
||||
|
||||
result, err := components.GetAllComponentsStatus()
|
||||
|
||||
if err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(result)
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"kubesphere.io/kubesphere/pkg/models/git"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
)
|
||||
|
||||
func GitReadVerify(request *restful.Request, response *restful.Response) {
|
||||
|
||||
authInfo := git.AuthInfo{}
|
||||
|
||||
err := request.ReadEntity(&authInfo)
|
||||
ns := request.PathParameter("namespace")
|
||||
if err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
err = git.GitReadVerify(ns, authInfo)
|
||||
|
||||
if err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(errors.None)
|
||||
}
|
||||
@@ -28,7 +28,6 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models/log"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
cs "kubesphere.io/kubesphere/pkg/simple/client"
|
||||
fb "kubesphere.io/kubesphere/pkg/simple/client/fluentbit"
|
||||
"kubesphere.io/kubesphere/pkg/utils/stringutils"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/openpitrix"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
@@ -53,7 +53,7 @@ func ListApplications(req *restful.Request, resp *restful.Response) {
|
||||
}
|
||||
|
||||
if namespaceName != "" {
|
||||
namespace, err := resources.GetResource("", resources.Namespaces, namespaceName)
|
||||
namespace, err := v1alpha2.GetResource("", v1alpha2.Namespaces, namespaceName)
|
||||
|
||||
if err != nil {
|
||||
klog.Errorln(err)
|
||||
@@ -109,7 +109,7 @@ func DescribeApplication(req *restful.Request, resp *restful.Response) {
|
||||
return
|
||||
}
|
||||
|
||||
namespace, err := resources.GetResource("", resources.Namespaces, namespaceName)
|
||||
namespace, err := resources.GetResource("", v1alpha2.Namespaces, namespaceName)
|
||||
|
||||
if err != nil {
|
||||
klog.Errorln(err)
|
||||
@@ -186,7 +186,7 @@ func ModifyApplication(req *restful.Request, resp *restful.Response) {
|
||||
return
|
||||
}
|
||||
|
||||
namespace, err := resources.GetResource("", resources.Namespaces, namespaceName)
|
||||
namespace, err := resources.GetResource("", v1alpha2.Namespaces, namespaceName)
|
||||
|
||||
if err != nil {
|
||||
klog.Errorln(err)
|
||||
@@ -243,7 +243,7 @@ func DeleteApplication(req *restful.Request, resp *restful.Response) {
|
||||
return
|
||||
}
|
||||
|
||||
namespace, err := resources.GetResource("", resources.Namespaces, namespaceName)
|
||||
namespace, err := resources.GetResource("", v1alpha2.Namespaces, namespaceName)
|
||||
|
||||
if err != nil {
|
||||
klog.Errorln(err)
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
|
||||
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 (
|
||||
k8serr "k8s.io/apimachinery/pkg/api/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models/workloads"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
"net/http"
|
||||
|
||||
"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("action")
|
||||
resourceVersion := req.QueryParameter("resourceVersion")
|
||||
|
||||
switch action {
|
||||
case "rerun":
|
||||
err = workloads.JobReRun(namespace, job, resourceVersion)
|
||||
default:
|
||||
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(fmt.Errorf("invalid operation %s", action)))
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
if k8serr.IsConflict(err) {
|
||||
resp.WriteHeaderAndEntity(http.StatusConflict, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(errors.None)
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
|
||||
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"
|
||||
"net/http"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/nodes"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
)
|
||||
|
||||
func DrainNode(request *restful.Request, response *restful.Response) {
|
||||
|
||||
nodeName := request.PathParameter("node")
|
||||
|
||||
err := nodes.DrainNode(nodeName)
|
||||
|
||||
if err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(errors.None)
|
||||
}
|
||||
30
pkg/apiserver/query/field.go
Normal file
30
pkg/apiserver/query/field.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package query
|
||||
|
||||
type Field string
|
||||
|
||||
const (
|
||||
FieldName = "name"
|
||||
FieldCreationTimeStamp = "creationTimestamp"
|
||||
FieldLastUpdateTimestamp = "lastUpdateTimestamp"
|
||||
FieldNamespace = "namespace"
|
||||
FieldStatus = "status"
|
||||
FieldApplication = "application"
|
||||
FieldOwner = "owner"
|
||||
FieldOwnerKind = "ownerKind"
|
||||
)
|
||||
|
||||
var SortableFields = []Field{
|
||||
FieldCreationTimeStamp,
|
||||
FieldLastUpdateTimestamp,
|
||||
FieldName,
|
||||
}
|
||||
|
||||
// Field contains all the query field that can be compared
|
||||
var ComparableFields = []Field{
|
||||
FieldName,
|
||||
FieldNamespace,
|
||||
FieldStatus,
|
||||
FieldApplication,
|
||||
FieldOwner,
|
||||
FieldOwnerKind,
|
||||
}
|
||||
145
pkg/apiserver/query/types.go
Normal file
145
pkg/apiserver/query/types.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
ParameterName = "name"
|
||||
ParameterLabelSelector = "labelSelector"
|
||||
ParameterFieldSelector = "fieldSelector"
|
||||
ParameterPage = "page"
|
||||
ParameterLimit = "limit"
|
||||
ParameterOrderBy = "sortBy"
|
||||
ParameterAscending = "ascending"
|
||||
)
|
||||
|
||||
type Comparable interface {
|
||||
Compare(Comparable) int
|
||||
|
||||
Contains(Comparable) bool
|
||||
}
|
||||
|
||||
type ComparableString string
|
||||
|
||||
func (c ComparableString) Compare(comparable Comparable) int {
|
||||
other := comparable.(ComparableString)
|
||||
return strings.Compare(string(c), string(other))
|
||||
}
|
||||
|
||||
func (c ComparableString) Contains(comparable Comparable) bool {
|
||||
other := comparable.(ComparableString)
|
||||
return strings.Contains(string(c), string(other))
|
||||
}
|
||||
|
||||
// Query represents api search terms
|
||||
type Query struct {
|
||||
Pagination *Pagination
|
||||
|
||||
// sort result in which field, default to FieldCreationTimeStamp
|
||||
SortBy Field
|
||||
|
||||
// sort result in ascending or descending order, default to descending
|
||||
Ascending bool
|
||||
|
||||
//
|
||||
Filters []Filter
|
||||
}
|
||||
|
||||
type Pagination struct {
|
||||
// items per page
|
||||
Limit int
|
||||
|
||||
// page number
|
||||
Page int
|
||||
}
|
||||
|
||||
var NoPagination = newPagination(-1, -1)
|
||||
|
||||
func newPagination(limit int, page int) *Pagination {
|
||||
return &Pagination{
|
||||
Limit: limit,
|
||||
Page: page,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pagination) IsValidPagintaion() bool {
|
||||
return p.Limit >= 0 && p.Page >= 0
|
||||
}
|
||||
|
||||
func (p *Pagination) IsPageAvailable(total, startIndex int) bool {
|
||||
return total > startIndex && p.Limit > 0
|
||||
}
|
||||
|
||||
func (p *Pagination) GetPaginationSettings(total int) (startIndex, endIndex int) {
|
||||
startIndex = p.Limit * p.Page
|
||||
endIndex = startIndex + p.Limit
|
||||
|
||||
if endIndex > total {
|
||||
endIndex = total
|
||||
}
|
||||
|
||||
return startIndex, endIndex
|
||||
}
|
||||
|
||||
func New() *Query {
|
||||
return &Query{
|
||||
Pagination: &Pagination{
|
||||
Limit: -1,
|
||||
Page: -1,
|
||||
},
|
||||
SortBy: "",
|
||||
Ascending: false,
|
||||
Filters: []Filter{},
|
||||
}
|
||||
}
|
||||
|
||||
type Filter struct {
|
||||
Field Field
|
||||
Value Comparable
|
||||
}
|
||||
|
||||
func ParseQueryParameter(request *restful.Request) *Query {
|
||||
query := New()
|
||||
|
||||
limit, err := strconv.ParseInt(request.QueryParameter("limit"), 10, 0)
|
||||
if err != nil {
|
||||
query.Pagination = NoPagination
|
||||
}
|
||||
|
||||
page, err := strconv.ParseInt(request.QueryParameter("page"), 10, 0)
|
||||
if err == nil {
|
||||
query.Pagination = newPagination(int(limit), int(page-1))
|
||||
}
|
||||
|
||||
query.SortBy = Field(defaultString(request.QueryParameter("sortBy"), FieldCreationTimeStamp))
|
||||
|
||||
ascending, err := strconv.ParseBool(defaultString(request.QueryParameter("ascending"), "false"))
|
||||
if err != nil {
|
||||
query.Ascending = false
|
||||
} else {
|
||||
query.Ascending = ascending
|
||||
}
|
||||
|
||||
for _, field := range ComparableFields {
|
||||
f := request.QueryParameter(string(field))
|
||||
if len(f) != 0 {
|
||||
query.Filters = append(query.Filters, Filter{
|
||||
Field: field,
|
||||
Value: ComparableString(f),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return query
|
||||
|
||||
}
|
||||
|
||||
func defaultString(value, defaultValue string) string {
|
||||
if len(value) == 0 {
|
||||
return defaultValue
|
||||
}
|
||||
return value
|
||||
}
|
||||
72
pkg/apiserver/query/types_test.go
Normal file
72
pkg/apiserver/query/types_test.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseQueryParameter(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
queryString string
|
||||
expected *Query
|
||||
}{
|
||||
{
|
||||
"test normal case",
|
||||
"name=foo&status=Running&application=book&page=1&limit=10&ascending=true",
|
||||
&Query{
|
||||
Pagination: newPagination(10, 0),
|
||||
SortBy: FieldCreationTimeStamp,
|
||||
Ascending: true,
|
||||
Filters: []Filter{
|
||||
{
|
||||
FieldName,
|
||||
ComparableString("foo"),
|
||||
},
|
||||
{
|
||||
FieldStatus,
|
||||
ComparableString("Running"),
|
||||
},
|
||||
{
|
||||
FieldApplication,
|
||||
ComparableString("book"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"test bad case",
|
||||
"xxxx=xxxx&dsfsw=xxxx&page=abc&limit=add&ascending=ssss",
|
||||
&Query{
|
||||
Pagination: &Pagination{
|
||||
Limit: -1,
|
||||
Page: -1,
|
||||
},
|
||||
SortBy: FieldCreationTimeStamp,
|
||||
Ascending: false,
|
||||
Filters: []Filter{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
req, err := http.NewRequest("GET", fmt.Sprintf("http://localhost?%s", test.queryString), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
request := restful.NewRequest(req)
|
||||
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
got := ParseQueryParameter(request)
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
|
||||
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"
|
||||
"net/http"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/quotas"
|
||||
)
|
||||
|
||||
func GetNamespaceQuotas(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
quota, err := quotas.GetNamespaceQuotas(namespace)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(quota)
|
||||
}
|
||||
|
||||
func GetClusterQuotas(req *restful.Request, resp *restful.Response) {
|
||||
quota, err := quotas.GetClusterQuotas()
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(quota)
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
|
||||
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"
|
||||
"net/http"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/registries"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
|
||||
k8serror "k8s.io/apimachinery/pkg/api/errors"
|
||||
log "k8s.io/klog"
|
||||
)
|
||||
|
||||
func RegistryVerify(request *restful.Request, response *restful.Response) {
|
||||
|
||||
authInfo := registries.AuthInfo{}
|
||||
|
||||
err := request.ReadEntity(&authInfo)
|
||||
|
||||
if err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
err = registries.RegistryVerify(authInfo)
|
||||
|
||||
if err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
response.WriteAsJson(errors.None)
|
||||
}
|
||||
|
||||
func RegistryImageBlob(request *restful.Request, response *restful.Response) {
|
||||
imageName := request.QueryParameter("image")
|
||||
namespace := request.QueryParameter("namespace")
|
||||
secretName := request.QueryParameter("secret")
|
||||
|
||||
// get entry
|
||||
entry, err := registries.GetEntryBySecret(namespace, secretName)
|
||||
if err != nil {
|
||||
log.Errorf("%+v", err)
|
||||
if k8serror.IsNotFound(err) {
|
||||
log.Errorf("%+v", err)
|
||||
errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), response)
|
||||
return
|
||||
}
|
||||
response.WriteAsJson(®istries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// parse image
|
||||
image, err := registries.ParseImage(imageName)
|
||||
if err != nil {
|
||||
log.Errorf("%+v", err)
|
||||
errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), response)
|
||||
return
|
||||
}
|
||||
|
||||
// Create the registry client.
|
||||
r, err := registries.CreateRegistryClient(entry.Username, entry.Password, image.Domain)
|
||||
if err != nil {
|
||||
log.Errorf("%+v", err)
|
||||
response.WriteAsJson(®istries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
digestUrl := r.GetDigestUrl(image)
|
||||
|
||||
// Get token.
|
||||
token, err := r.Token(digestUrl)
|
||||
if err != nil {
|
||||
log.Errorf("%+v", err)
|
||||
response.WriteAsJson(®istries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Get digest.
|
||||
imageManifest, err := r.ImageManifest(image, token)
|
||||
if err != nil {
|
||||
if serviceError, ok := err.(restful.ServiceError); ok {
|
||||
response.WriteAsJson(®istries.ImageDetails{Status: registries.StatusFailed, Message: serviceError.Message})
|
||||
return
|
||||
}
|
||||
log.Errorf("%+v", err)
|
||||
response.WriteAsJson(®istries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()})
|
||||
return
|
||||
}
|
||||
image.Digest = imageManifest.ManifestConfig.Digest
|
||||
|
||||
// Get blob.
|
||||
imageBlob, err := r.ImageBlob(image, token)
|
||||
if err != nil {
|
||||
log.Errorf("%+v", err)
|
||||
response.WriteAsJson(®istries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
imageDetails := ®istries.ImageDetails{
|
||||
Status: registries.StatusSuccess,
|
||||
ImageManifest: imageManifest,
|
||||
ImageBlob: imageBlob,
|
||||
ImageTag: image.Tag,
|
||||
Registry: image.Domain,
|
||||
}
|
||||
|
||||
response.WriteAsJson(imageDetails)
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
|
||||
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/models/resources"
|
||||
"net/http"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
func ListNamespacedResources(req *restful.Request, resp *restful.Response) {
|
||||
ListResources(req, resp)
|
||||
}
|
||||
|
||||
func ListResources(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
resourceName := req.PathParameter("resources")
|
||||
conditions, err := params.ParseConditions(req.QueryParameter(params.ConditionsParam))
|
||||
orderBy := params.GetStringValueWithDefault(req, params.OrderByParam, resources.CreateTime)
|
||||
limit, offset := params.ParsePaging(req.QueryParameter(params.PagingParam))
|
||||
reverse := params.ParseReverse(req)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
result, err := resources.ListResources(namespace, resourceName, conditions, orderBy, reverse, limit, offset)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(result)
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
|
||||
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"
|
||||
"net/http"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/storage"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
)
|
||||
|
||||
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 err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
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 err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
result := pvcList{
|
||||
Name: scName, Items: claims,
|
||||
}
|
||||
|
||||
response.WriteAsJson(result)
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
|
||||
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"
|
||||
"kubesphere.io/kubesphere/pkg/models/revisions"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
)
|
||||
|
||||
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.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
result, err := revisions.GetDaemonSetRevision(namespace, daemonset, revision)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
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 err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
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.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
result, err := revisions.GetStatefulSetRevision(namespace, statefulset, revision)
|
||||
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(result)
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
|
||||
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 (
|
||||
"fmt"
|
||||
"github.com/emicklei/go-restful"
|
||||
k8serr "k8s.io/apimachinery/pkg/api/errors"
|
||||
"net/http"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/routers"
|
||||
)
|
||||
|
||||
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 err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
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 err != nil {
|
||||
if k8serr.IsNotFound(err) {
|
||||
response.WriteHeaderAndEntity(http.StatusNotFound, errors.Wrap(err))
|
||||
} else {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
}
|
||||
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 {
|
||||
response.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(fmt.Errorf("wrong annotations, missing key or value")))
|
||||
return
|
||||
}
|
||||
|
||||
router, err = routers.CreateRouter(namespace, serviceType, annotationMap)
|
||||
|
||||
if err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
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 err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
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 {
|
||||
response.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
serviceType, annotationMap, err := parseParameter(newRouter)
|
||||
|
||||
router, err := routers.UpdateRouter(namespace, serviceType, annotationMap)
|
||||
|
||||
if err != nil {
|
||||
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
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 {
|
||||
routerType = v1.ServiceTypeLoadBalancer
|
||||
}
|
||||
|
||||
return routerType, router.Annotations, nil
|
||||
}
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam"
|
||||
"kubesphere.io/kubesphere/pkg/models/metrics"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/models/tenant"
|
||||
"kubesphere.io/kubesphere/pkg/models/workspaces"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
@@ -64,7 +64,7 @@ func ListWorkspaces(req *restful.Request, resp *restful.Response) {
|
||||
reverse := params.ParseReverse(req)
|
||||
|
||||
if orderBy == "" {
|
||||
orderBy = resources.CreateTime
|
||||
orderBy = v1alpha2.CreateTime
|
||||
reverse = true
|
||||
}
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
|
||||
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"
|
||||
"net/http"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/status"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
)
|
||||
|
||||
func GetClusterAbnormalWorkloads(req *restful.Request, resp *restful.Response) {
|
||||
res, err := status.GetClusterResourceStatus()
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
resp.WriteAsJson(res)
|
||||
}
|
||||
|
||||
func GetNamespacedAbnormalWorkloads(req *restful.Request, resp *restful.Response) {
|
||||
res, err := status.GetNamespacesResourceStatus(req.PathParameter("namespace"))
|
||||
if err != nil {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
|
||||
return
|
||||
}
|
||||
resp.WriteAsJson(res)
|
||||
}
|
||||
Reference in New Issue
Block a user