feat: kubesphere 4.0 (#6115)

* feat: kubesphere 4.0

Signed-off-by: ci-bot <ci-bot@kubesphere.io>

* feat: kubesphere 4.0

Signed-off-by: ci-bot <ci-bot@kubesphere.io>

---------

Signed-off-by: ci-bot <ci-bot@kubesphere.io>
Co-authored-by: ks-ci-bot <ks-ci-bot@example.com>
Co-authored-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
KubeSphere CI Bot
2024-09-06 11:05:52 +08:00
committed by GitHub
parent b5015ec7b9
commit 447a51f08b
8557 changed files with 546695 additions and 1146174 deletions

View File

@@ -1,18 +1,7 @@
/*
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.
*/
* Please refer to the LICENSE file in the root directory of the project.
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
*/
package v1alpha3
@@ -31,50 +20,42 @@ import (
"kubesphere.io/kubesphere/pkg/apiserver/query"
"kubesphere.io/kubesphere/pkg/models/components"
v2 "kubesphere.io/kubesphere/pkg/models/registries/v2"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
resourcev1alpha2 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/resource"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"kubesphere.io/kubesphere/pkg/server/params"
"kubesphere.io/kubesphere/pkg/simple/client/overview"
)
type Handler struct {
resourceGetterV1alpha3 *resourcev1alpha3.ResourceGetter
resourcesGetterV1alpha2 *resourcev1alpha2.ResourceGetter
componentsGetter components.ComponentsGetter
registryHelper v2.RegistryHelper
}
func New(resourceGetterV1alpha3 *resourcev1alpha3.ResourceGetter, resourcesGetterV1alpha2 *resourcev1alpha2.ResourceGetter, componentsGetter components.ComponentsGetter) *Handler {
return &Handler{
resourceGetterV1alpha3: resourceGetterV1alpha3,
resourcesGetterV1alpha2: resourcesGetterV1alpha2,
componentsGetter: componentsGetter,
registryHelper: v2.NewRegistryHelper(),
var (
ClusterMetricNames = []string{
overview.NamespaceCount, overview.PodCount, overview.DeploymentCount,
overview.StatefulSetCount, overview.DaemonSetCount, overview.JobCount,
overview.CronJobCount, overview.PersistentVolumeClaimCount, overview.ServiceCount,
overview.IngressCount, overview.ClusterRoleBindingCount, overview.ClusterRoleCount,
}
NamespaceMetricNames = []string{
overview.PodCount, overview.DeploymentCount, overview.StatefulSetCount,
overview.DaemonSetCount, overview.JobCount, overview.CronJobCount,
overview.PersistentVolumeClaimCount, overview.ServiceCount,
overview.IngressCount, overview.RoleCount, overview.RoleBindingCount,
}
)
type handler struct {
resourceGetterV1alpha3 *resourcev1alpha3.Getter
componentsGetter components.Getter
registryHelper v2.RegistryHelper
counter overview.Counter
}
func (h *Handler) handleGetResources(request *restful.Request, response *restful.Response) {
func (h *handler) GetResources(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
resourceType := request.PathParameter("resources")
name := request.PathParameter("name")
// use informers to retrieve resources
result, err := h.resourceGetterV1alpha3.Get(resourceType, namespace, name)
if err == nil {
response.WriteEntity(result)
return
}
if err != resourcev1alpha3.ErrResourceNotSupported {
klog.Errorf("%s, resource type: %s", err, resourceType)
api.HandleInternalError(response, nil, err)
return
}
// fallback to v1alpha2
resultV1alpha2, err := h.resourcesGetterV1alpha2.GetResource(namespace, resourceType, name)
if err != nil {
if err == resourcev1alpha2.ErrResourceNotSupported {
if err == resourcev1alpha3.ErrResourceNotSupported {
api.HandleNotFound(response, request, err)
return
}
@@ -83,32 +64,18 @@ func (h *Handler) handleGetResources(request *restful.Request, response *restful
return
}
response.WriteEntity(resultV1alpha2)
response.WriteEntity(result)
}
// handleListResources retrieves resources
func (h *Handler) handleListResources(request *restful.Request, response *restful.Response) {
// ListResources retrieves resources
func (h *handler) ListResources(request *restful.Request, response *restful.Response) {
query := query.ParseQueryParameter(request)
resourceType := request.PathParameter("resources")
namespace := request.PathParameter("namespace")
result, err := h.resourceGetterV1alpha3.List(resourceType, namespace, query)
if err == nil {
response.WriteEntity(result)
return
}
if err != resourcev1alpha3.ErrResourceNotSupported {
klog.Errorf("%s, resource type: %s", err, resourceType)
api.HandleInternalError(response, request, err)
return
}
// fallback to v1alpha2
result, err = h.fallback(resourceType, namespace, query)
if err != nil {
if err == resourcev1alpha2.ErrResourceNotSupported {
if err == resourcev1alpha3.ErrResourceNotSupported {
api.HandleNotFound(response, request, err)
return
}
@@ -116,60 +83,11 @@ func (h *Handler) handleListResources(request *restful.Request, response *restfu
api.HandleError(response, request, err)
return
}
response.WriteEntity(result)
}
func (h *Handler) fallback(resourceType string, namespace string, q *query.Query) (*api.ListResult, error) {
orderBy := string(q.SortBy)
limit, offset := q.Pagination.Limit, q.Pagination.Offset
reverse := !q.Ascending
conditions := &params.Conditions{Match: make(map[string]string, 0), Fuzzy: make(map[string]string, 0)}
for field, value := range q.Filters {
switch field {
case query.FieldName:
conditions.Fuzzy[v1alpha2.Name] = string(value)
case query.FieldNames:
conditions.Match[v1alpha2.Name] = string(value)
case query.FieldCreationTimeStamp:
conditions.Match[v1alpha2.CreateTime] = string(value)
case query.FieldLastUpdateTimestamp:
conditions.Match[v1alpha2.UpdateTime] = string(value)
case query.FieldLabel:
values := strings.SplitN(string(value), ":", 2)
if len(values) == 2 {
conditions.Match[values[0]] = values[1]
} else {
conditions.Match[v1alpha2.Label] = values[0]
}
case query.FieldAnnotation:
values := strings.SplitN(string(value), ":", 2)
if len(values) == 2 {
conditions.Match[v1alpha2.Annotation] = values[1]
} else {
conditions.Match[v1alpha2.Annotation] = values[0]
}
case query.FieldStatus:
conditions.Match[v1alpha2.Status] = string(value)
case query.FieldOwnerReference:
conditions.Match[v1alpha2.Owner] = string(value)
default:
conditions.Match[string(field)] = string(value)
}
}
result, err := h.resourcesGetterV1alpha2.ListResources(namespace, resourceType, conditions, orderBy, reverse, limit, offset)
if err != nil {
klog.Error(err)
return nil, err
}
return &api.ListResult{
Items: result.Items,
TotalItems: result.TotalCount,
}, nil
}
func (h *Handler) handleGetComponentStatus(request *restful.Request, response *restful.Response) {
func (h *handler) GetComponentStatus(request *restful.Request, response *restful.Response) {
component := request.PathParameter("component")
result, err := h.componentsGetter.GetComponentStatus(component)
if err != nil {
@@ -180,7 +98,7 @@ func (h *Handler) handleGetComponentStatus(request *restful.Request, response *r
response.WriteEntity(result)
}
func (h *Handler) handleGetSystemHealthStatus(request *restful.Request, response *restful.Response) {
func (h *handler) GetSystemHealthStatus(request *restful.Request, response *restful.Response) {
result, err := h.componentsGetter.GetSystemHealthStatus()
if err != nil {
klog.Error(err)
@@ -192,7 +110,7 @@ func (h *Handler) handleGetSystemHealthStatus(request *restful.Request, response
}
// get all componentsHandler
func (h *Handler) handleGetComponents(request *restful.Request, response *restful.Response) {
func (h *handler) GetComponents(request *restful.Request, response *restful.Response) {
result, err := h.componentsGetter.GetAllComponentsStatus()
if err != nil {
klog.Error(err)
@@ -203,10 +121,10 @@ func (h *Handler) handleGetComponents(request *restful.Request, response *restfu
response.WriteEntity(result)
}
// handleVerifyImageRepositorySecret verifies image secret against registry, it takes k8s.io/api/core/v1/types.Secret
// VerifyImageRepositorySecret verifies image secret against registry, it takes k8s.io/api/core/v1/types.Secret
// as input, and authenticate registry with credential specified. Returns http.StatusOK if authenticate successfully,
// returns http.StatusUnauthorized if failed.
func (h *Handler) handleVerifyImageRepositorySecret(request *restful.Request, response *restful.Response) {
func (h *handler) VerifyImageRepositorySecret(request *restful.Request, response *restful.Response) {
secret := &v1.Secret{}
err := request.ReadEntity(secret)
if err != nil {
@@ -222,8 +140,8 @@ func (h *Handler) handleVerifyImageRepositorySecret(request *restful.Request, re
}
}
// handleGetImageConfig fetches container image spec described in https://github.com/opencontainers/image-spec/blob/main/manifest.md
func (h *Handler) handleGetImageConfig(request *restful.Request, response *restful.Response) {
// GetImageConfig fetches container image spec described in https://github.com/opencontainers/image-spec/blob/main/manifest.md
func (h *handler) GetImageConfig(request *restful.Request, response *restful.Response) {
secretName := request.QueryParameter("secret")
namespace := request.PathParameter("namespace")
image := request.QueryParameter("image")
@@ -247,8 +165,8 @@ func (h *Handler) handleGetImageConfig(request *restful.Request, response *restf
response.WriteHeaderAndJson(http.StatusOK, config, restful.MIME_JSON)
}
// handleGetRepositoryTags fetchs all tags of given repository, no paging.
func (h *Handler) handleGetRepositoryTags(request *restful.Request, response *restful.Response) {
// GetRepositoryTags fetchs all tags of given repository, no paging.
func (h *handler) GetRepositoryTags(request *restful.Request, response *restful.Response) {
secretName := request.QueryParameter("secret")
namespace := request.PathParameter("namespace")
repository := request.QueryParameter("repository")
@@ -285,6 +203,25 @@ func (h *Handler) handleGetRepositoryTags(request *restful.Request, response *re
response.WriteHeaderAndJson(http.StatusOK, tags, restful.MIME_JSON)
}
func (h *handler) GetClusterOverview(request *restful.Request, response *restful.Response) {
metrics, err := h.counter.GetMetrics(ClusterMetricNames, "", "", "cluster")
if err != nil {
api.HandleError(response, request, err)
return
}
_ = response.WriteEntity(metrics)
}
func (h *handler) GetNamespaceOverview(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
metrics, err := h.counter.GetMetrics(NamespaceMetricNames, namespace, "", "namespace")
if err != nil {
api.HandleError(response, request, err)
return
}
_ = response.WriteEntity(metrics)
}
func canonicalizeRegistryError(request *restful.Request, response *restful.Response, err error) {
if strings.Contains(err.Error(), "Unauthorized") {
api.HandleUnauthorized(response, request, err)