From 6a29c6048aea0f926903964fcf8bba0a77d363e7 Mon Sep 17 00:00:00 2001 From: Peefy Date: Tue, 12 Mar 2024 21:00:41 +0800 Subject: [PATCH] fix: crd default value (#83) Signed-off-by: peefy --- ...tor_victoriametrics_com_v1beta1_vm_agent.k | 20 ++++---- pkg/swagger/generator/language.go | 50 ++++++++++++++++++- pkg/swagger/generator/model.go | 23 ++++++--- pkg/swagger/generator/spec.go | 11 ++-- 4 files changed, 80 insertions(+), 24 deletions(-) diff --git a/pkg/kube_resource/generator/testdata/array_branch/models/operator_victoriametrics_com_v1beta1_vm_agent.k b/pkg/kube_resource/generator/testdata/array_branch/models/operator_victoriametrics_com_v1beta1_vm_agent.k index 1f233e1..211eeb4 100644 --- a/pkg/kube_resource/generator/testdata/array_branch/models/operator_victoriametrics_com_v1beta1_vm_agent.k +++ b/pkg/kube_resource/generator/testdata/array_branch/models/operator_victoriametrics_com_v1beta1_vm_agent.k @@ -878,8 +878,8 @@ schema OperatorVictoriametricsComV1beta1VMAgentSpecClaimTemplatesItems0SpecResou check: - all _, n in limits { regex.match(str(n), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") } if limits - all _, n in requests { regex.match(str(n), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") } if requests + all _, limits in limits {regex.match(str(limits), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") if limits } if limits + all _, requests in requests {regex.match(str(requests), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") if requests } if requests schema OperatorVictoriametricsComV1beta1VMAgentSpecClaimTemplatesItems0SpecSelector: @@ -957,8 +957,8 @@ schema OperatorVictoriametricsComV1beta1VMAgentSpecClaimTemplatesItems0Status: check: - all _, n in allocatedResources { regex.match(str(n), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") } if allocatedResources - all _, n in capacity { regex.match(str(n), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") } if capacity + all _, allocatedResources in allocatedResources {regex.match(str(allocatedResources), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") if allocatedResources } if allocatedResources + all _, capacity in capacity {regex.match(str(capacity), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") if capacity } if capacity schema OperatorVictoriametricsComV1beta1VMAgentSpecClaimTemplatesItems0StatusConditionsItems0: @@ -2475,8 +2475,8 @@ schema OperatorVictoriametricsComV1beta1VMAgentSpecResources: check: - all _, n in limits { regex.match(str(n), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") } if limits - all _, n in requests { regex.match(str(n), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") } if requests + all _, limits in limits {regex.match(str(limits), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") if limits } if limits + all _, requests in requests {regex.match(str(requests), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") if requests } if requests schema OperatorVictoriametricsComV1beta1VMAgentSpecRollingUpdate: @@ -2876,8 +2876,8 @@ schema OperatorVictoriametricsComV1beta1VMAgentSpecStatefulStorageVolumeClaimTem check: - all _, n in limits { regex.match(str(n), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") } if limits - all _, n in requests { regex.match(str(n), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") } if requests + all _, limits in limits {regex.match(str(limits), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") if limits } if limits + all _, requests in requests {regex.match(str(requests), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") if requests } if requests schema OperatorVictoriametricsComV1beta1VMAgentSpecStatefulStorageVolumeClaimTemplateSpecSelector: @@ -2955,8 +2955,8 @@ schema OperatorVictoriametricsComV1beta1VMAgentSpecStatefulStorageVolumeClaimTem check: - all _, n in allocatedResources { regex.match(str(n), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") } if allocatedResources - all _, n in capacity { regex.match(str(n), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") } if capacity + all _, allocatedResources in allocatedResources {regex.match(str(allocatedResources), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") if allocatedResources } if allocatedResources + all _, capacity in capacity {regex.match(str(capacity), r"^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$") if capacity } if capacity schema OperatorVictoriametricsComV1beta1VMAgentSpecStatefulStorageVolumeClaimTemplateStatusConditionsItems0: diff --git a/pkg/swagger/generator/language.go b/pkg/swagger/generator/language.go index 418f849..a5d5e44 100644 --- a/pkg/swagger/generator/language.go +++ b/pkg/swagger/generator/language.go @@ -15,6 +15,7 @@ package generator import ( + "encoding/json" "fmt" "log" "path" @@ -164,14 +165,47 @@ func (l *LanguageOpts) ToKclValue(data interface{}) string { return fmt.Sprintf("[%s]", content) case reflect.String: return fmt.Sprintf("\"%s\"", data) + case reflect.Int, + reflect.Int8, + reflect.Int16, + reflect.Int32, + reflect.Int64, + reflect.Uint, + reflect.Uint8, + reflect.Uint16, + reflect.Uint32, + reflect.Uint64: + return fmt.Sprintf("%v", data) + case reflect.Float32, reflect.Float64: + return fmt.Sprintf("%v", data) case reflect.Bool: if data.(bool) { return "True" } return "False" default: - //TODO(xiarui.xr): support user defined struct - return fmt.Sprintf("%v", data) + // Reflect value + if dataValue, ok := data.(reflect.Value); ok { + return l.ToKclValue(dataValue.Interface()) + } else if dataSlice, ok := data.(yaml.MapSlice); ok { + // If is a MapSlice + var dictContents []string + for _, v := range dataSlice { + k := v.Key + v := v.Value + dictContents = append(dictContents, fmt.Sprintf("%s: %s", l.ToKclValue(k), l.ToKclValue(v))) + } + content := strings.Join(dictContents, ", ") + return fmt.Sprintf("{%s}", content) + } else { + // User defined struct + valueString, err := ToKCLValueString(data) + if err != nil { + log.Fatal(err) + return "None" + } + return valueString + } } } @@ -326,3 +360,15 @@ func KclLangOpts() *LanguageOpts { opts.Init() return opts } + +func ToKCLValueString(value interface{}) (string, error) { + jsonString, err := json.Marshal(value) + if err != nil { + return "", err + } + // In KCL, `true`, `false` and `null` are denoted by `True`, `False` and `None`. + result := strings.Replace(string(jsonString), ": true", ": True", -1) + result = strings.Replace(result, ": false", ": False", -1) + result = strings.Replace(result, ": null", ": None", -1) + return result, nil +} diff --git a/pkg/swagger/generator/model.go b/pkg/swagger/generator/model.go index a6f525d..cfe1711 100644 --- a/pkg/swagger/generator/model.go +++ b/pkg/swagger/generator/model.go @@ -1513,31 +1513,42 @@ func RecoverMapValueOrder(oldValue interface{}) interface{} { keys := value.MapKeys() var newValue yaml.MapSlice = make([]yaml.MapItem, len(keys)) - for _, key := range keys { + for i, key := range keys { k := key.Interface() v := value.MapIndex(key).Interface() - mapV := reflect.ValueOf(v) switch mapV.Kind() { case reflect.Map: + hasXOrder := false var order int64 var innerValue interface{} mapIter := mapV.MapRange() for mapIter.Next() { kk := mapIter.Key().String() if kk == xOrder { + hasXOrder = true order = int64(mapIter.Value().Interface().(float64)) } if kk == "value" { innerValue = mapIter.Value().Interface() } } - newValue[order] = yaml.MapItem{ - Key: k, - Value: RecoverMapValueOrder(innerValue), + if hasXOrder { + newValue[order] = yaml.MapItem{ + Key: k, + Value: RecoverMapValueOrder(innerValue), + } + } else { + newValue[i] = yaml.MapItem{ + Key: k, + Value: RecoverMapValueOrder(v), + } } default: - log.Fatalf("unexpected ordered map value: %s", v) + newValue[i] = yaml.MapItem{ + Key: k, + Value: RecoverMapValueOrder(v), + } } } return newValue diff --git a/pkg/swagger/generator/spec.go b/pkg/swagger/generator/spec.go index 50ddd95..b3dbba2 100644 --- a/pkg/swagger/generator/spec.go +++ b/pkg/swagger/generator/spec.go @@ -17,7 +17,6 @@ package generator import ( "errors" "fmt" - "io/ioutil" "log" "os" "path/filepath" @@ -186,11 +185,11 @@ func WithXOrder(specPath string, addXOrderFunc func(yamlDoc interface{}) interfa panic(err) } - tmpFile, err := ioutil.TempFile("", filepath.Base(specPath)) + tmpFile, err := os.CreateTemp("", filepath.Base(specPath)) if err != nil { panic(err) } - if err := ioutil.WriteFile(tmpFile.Name(), out, 0); err != nil { + if err := os.WriteFile(tmpFile.Name(), out, 0); err != nil { panic(err) } return tmpFile.Name() @@ -250,17 +249,17 @@ func AddXOrderOnDefaultExample(yamlDoc interface{}) interface{} { break } } - // add default / example x-order + // Add default / example x-order var addXOrder func(interface{}) addXOrder = func(element interface{}) { - // 假设element是某个definition,即,是一个schema,首先找到其中的default、example选项 + // Assuming element is a certain definition, that is, a schema, first find the default and example options in it if defaultValue, ok := lookForSlice(element, "default"); ok { addXOrder2MapValue(defaultValue) } if exampleValue, ok := lookForSlice(element, "example"); ok { addXOrder2MapValue(exampleValue) } - // look for the properties and add addXOrder on each property + // Look for the properties and add addXOrder on each property if props, ok := lookForMapSlice(element, "properties"); ok { for _, prop := range props { if pSlice, ok := prop.Value.(yaml.MapSlice); ok {