107 lines
2.6 KiB
Go
107 lines
2.6 KiB
Go
/*
|
|
* Copyright 2024 the KubeSphere Authors.
|
|
* Please refer to the LICENSE file in the root directory of the project.
|
|
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
|
*/
|
|
|
|
package v2
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/emicklei/go-restful/v3"
|
|
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
|
|
"kubesphere.io/kubesphere/pkg/api"
|
|
)
|
|
|
|
func (h *appHandler) exampleCr(req *restful.Request, resp *restful.Response) {
|
|
name := req.PathParameter("name")
|
|
crd := v1.CustomResourceDefinition{}
|
|
err := h.client.Get(req.Request.Context(), client.ObjectKey{Name: name}, &crd)
|
|
if err != nil {
|
|
api.HandleInternalError(resp, nil, err)
|
|
return
|
|
}
|
|
cr, err := convertCRDToCR(crd)
|
|
if err != nil {
|
|
api.HandleInternalError(resp, nil, err)
|
|
return
|
|
}
|
|
resp.WriteEntity(cr)
|
|
}
|
|
|
|
func convertCRDToCR(crd v1.CustomResourceDefinition) (dstCr unstructured.Unstructured, err error) {
|
|
|
|
cr := unstructured.Unstructured{}
|
|
cr.SetName(fmt.Sprintf("%s-set-your-own-name", crd.Spec.Names.Singular))
|
|
cr.SetGroupVersionKind(schema.GroupVersionKind{
|
|
Group: crd.Spec.Group,
|
|
Kind: crd.Spec.Names.Kind,
|
|
})
|
|
|
|
var selectedVersion *v1.CustomResourceDefinitionVersion
|
|
for _, version := range crd.Spec.Versions {
|
|
if version.Served && version.Storage {
|
|
selectedVersion = &version
|
|
break
|
|
}
|
|
}
|
|
if selectedVersion == nil {
|
|
return dstCr, errors.New("no served and storage version found in CRD")
|
|
}
|
|
cr.SetAPIVersion(selectedVersion.Name)
|
|
|
|
generateProps(selectedVersion, cr, "spec")
|
|
generateProps(selectedVersion, cr, "status")
|
|
|
|
return cr, nil
|
|
}
|
|
|
|
func generateProps(selectedVersion *v1.CustomResourceDefinitionVersion, cr unstructured.Unstructured, name string) {
|
|
data := make(map[string]any)
|
|
specProps := selectedVersion.Schema.OpenAPIV3Schema.Properties[name].Properties
|
|
for key, value := range specProps {
|
|
data[key] = getDefaultValue(value)
|
|
}
|
|
cr.Object[name] = data
|
|
}
|
|
|
|
func getDefaultValue(value v1.JSONSchemaProps) any {
|
|
switch value.Type {
|
|
case "object":
|
|
return parseObject(value.Properties)
|
|
case "integer":
|
|
if value.Minimum != nil {
|
|
return *value.Minimum
|
|
}
|
|
return 0
|
|
case "boolean":
|
|
return false
|
|
case "array":
|
|
if value.Items.Schema != nil {
|
|
return []any{getDefaultValue(*value.Items.Schema)}
|
|
}
|
|
return []any{}
|
|
case "string":
|
|
if len(value.Enum) > 0 {
|
|
return string(value.Enum[0].Raw)
|
|
}
|
|
return ""
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func parseObject(obj map[string]v1.JSONSchemaProps) map[string]any {
|
|
res := make(map[string]any)
|
|
for key, value := range obj {
|
|
res[key] = getDefaultValue(value)
|
|
}
|
|
return res
|
|
}
|