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

@@ -132,18 +132,25 @@ func buildOperation(ws *restful.WebService, r restful.Route, patterns map[string
return o
}
// stringAutoType automatically picks the correct type from an ambiguously typed
// string. Ex. numbers become int, true/false become bool, etc.
func stringAutoType(ambiguous string) interface{} {
// stringAutoType picks the correct type when dataType is set. Otherwise, it automatically picks the correct type from
// an ambiguously typed string. Ex. numbers become int, true/false become bool, etc.
func stringAutoType(dataType, ambiguous string) interface{} {
if ambiguous == "" {
return nil
}
if parsedInt, err := strconv.ParseInt(ambiguous, 10, 64); err == nil {
return parsedInt
if dataType == "" || dataType == "integer" {
if parsedInt, err := strconv.ParseInt(ambiguous, 10, 64); err == nil {
return parsedInt
}
}
if parsedBool, err := strconv.ParseBool(ambiguous); err == nil {
return parsedBool
if dataType == "" || dataType == "boolean" {
if parsedBool, err := strconv.ParseBool(ambiguous); err == nil {
return parsedBool
}
}
return ambiguous
}
@@ -188,7 +195,7 @@ func buildParameter(r restful.Route, restfulParam *restful.Parameter, pattern st
// init Enum to our known size and populate it
p.Enum = make([]interface{}, 0, numPossible)
for _, value := range param.PossibleValues {
p.Enum = append(p.Enum, value)
p.Enum = append(p.Enum, stringAutoType(p.Type, value))
}
} else {
if numAllowable := len(param.AllowableValues); numAllowable > 0 {
@@ -204,7 +211,7 @@ func buildParameter(r restful.Route, restfulParam *restful.Parameter, pattern st
// init Enum to our known size and populate it
p.Enum = make([]interface{}, 0, numAllowable)
for _, key := range allowableSortedKeys {
p.Enum = append(p.Enum, param.AllowableValues[key])
p.Enum = append(p.Enum, stringAutoType(p.Type, key))
}
}
}
@@ -250,7 +257,7 @@ func buildParameter(r restful.Route, restfulParam *restful.Parameter, pattern st
} else {
p.Type = param.DataType
}
p.Default = stringAutoType(param.DefaultValue)
p.Default = stringAutoType(param.DataType, param.DefaultValue)
p.Format = param.DataFormat
}

View File

@@ -40,12 +40,10 @@ func (b definitionBuilder) addModelFrom(sample interface{}) {
func (b definitionBuilder) addModel(st reflect.Type, nameOverride string) *spec.Schema {
// Turn pointers into simpler types so further checks are
// correct.
isArray := false
if st.Kind() == reflect.Ptr {
st = st.Elem()
}
if b.isSliceOrArrayType(st.Kind()) {
isArray = true
st = st.Elem()
}
@@ -77,15 +75,6 @@ func (b definitionBuilder) addModel(st reflect.Type, nameOverride string) *spec.
},
}
// fixes issue 77 but feels like a workaround.
if b.isPrimitiveType(modelName, st.Kind()) {
if isArray {
sm.Type = []string{"array"}
sm.Items = &spec.SchemaOrArray{Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{Type: []string{jsonSchemaType(st.Kind().String())}}}}
}
}
// reference the model before further initializing (enables recursive structs)
b.Definitions[modelName] = sm
@@ -267,8 +256,12 @@ func (b definitionBuilder) buildStructTypeProperty(field reflect.StructField, js
}
if field.Name == fieldType.Name() && field.Anonymous && !hasNamedJSONTag(field) {
definitions := make(map[string]spec.Schema, len(b.Definitions))
for k, v := range b.Definitions {
definitions[k] = v
}
// embedded struct
sub := definitionBuilder{b.Definitions, b.Config}
sub := definitionBuilder{definitions, b.Config}
sub.addModel(fieldType, "")
subKey := keyFrom(fieldType, b.Config)
// merge properties from sub
@@ -313,26 +306,41 @@ func (b definitionBuilder) buildArrayTypeProperty(field reflect.StructField, jso
prop.Type = []string{stringt}
return jsonName, prop
}
var pType = "array"
prop.Type = []string{pType}
isPrimitive := b.isPrimitiveType(fieldType.Elem().Name(), fieldType.Elem().Kind())
elemTypeName := b.getElementTypeName(modelName, jsonName, fieldType.Elem())
prop.Items = &spec.SchemaOrArray{
Schema: &spec.Schema{},
}
itemSchema := &prop
itemType := fieldType
isArray := b.isSliceOrArrayType(fieldType.Kind())
for isArray {
itemType = itemType.Elem()
isArray = b.isSliceOrArrayType(itemType.Kind())
if itemType.Kind() == reflect.Uint8 {
stringt := "string"
itemSchema.Type = []string{stringt}
return jsonName, prop
}
itemSchema.Items = &spec.SchemaOrArray{
Schema: &spec.Schema{},
}
itemSchema.Type = []string{"array"}
itemSchema = itemSchema.Items.Schema
}
isPrimitive := b.isPrimitiveType(itemType.Name(), itemType.Kind())
elemTypeName := b.getElementTypeName(modelName, jsonName, itemType)
if isPrimitive {
mapped := b.jsonSchemaType(elemTypeName, fieldType.Elem().Kind())
prop.Items.Schema.Type = []string{mapped}
prop.Items.Schema.Format = b.jsonSchemaFormat(elemTypeName, fieldType.Elem().Kind())
mapped := b.jsonSchemaType(elemTypeName, itemType.Kind())
itemSchema.Type = []string{mapped}
itemSchema.Format = b.jsonSchemaFormat(elemTypeName, itemType.Kind())
} else {
prop.Items.Schema.Ref = spec.MustCreateRef("#/definitions/" + elemTypeName)
itemSchema.Ref = spec.MustCreateRef("#/definitions/" + elemTypeName)
}
// add|overwrite model for element type
if fieldType.Elem().Kind() == reflect.Ptr {
fieldType = fieldType.Elem()
if itemType.Kind() == reflect.Ptr {
itemType = itemType.Elem()
}
if !isPrimitive {
b.addModel(fieldType.Elem(), elemTypeName)
b.addModel(itemType, elemTypeName)
}
return jsonName, prop
}

View File

@@ -22,7 +22,7 @@ func setDescription(prop *spec.Schema, field reflect.StructField) {
func setDefaultValue(prop *spec.Schema, field reflect.StructField) {
if tag := field.Tag.Get("default"); tag != "" {
prop.Default = stringAutoType(tag)
prop.Default = stringAutoType("", tag)
}
}