github.com/oam-dev/kubevela@v1.9.11/pkg/cue/script/schema.go (about) 1 /* 2 Copyright 2022 The KubeVela Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package script 18 19 import ( 20 "errors" 21 "fmt" 22 "strings" 23 24 "cuelang.org/go/cue" 25 26 "github.com/getkin/kin-openapi/openapi3" 27 28 "github.com/kubevela/workflow/pkg/cue/model/value" 29 30 "github.com/oam-dev/kubevela/pkg/appfile" 31 "github.com/oam-dev/kubevela/pkg/cue/process" 32 "github.com/oam-dev/kubevela/pkg/oam/util" 33 "github.com/oam-dev/kubevela/pkg/utils/common" 34 ) 35 36 // ParsePropertiesToSchema parse the properties in cue script to the openapi schema 37 // Read the template.parameter field 38 func (c CUE) ParsePropertiesToSchema(templateFieldPath ...string) (*openapi3.Schema, error) { 39 val, err := c.ParseToValue() 40 if err != nil { 41 return nil, err 42 } 43 var template *value.Value 44 if len(templateFieldPath) == 0 { 45 template = val 46 } else { 47 template, err = val.LookupValue(templateFieldPath...) 48 if err != nil { 49 return nil, fmt.Errorf("%w cue script: %s", err, c) 50 } 51 } 52 data, err := common.GenOpenAPI(template) 53 if err != nil { 54 return nil, err 55 } 56 schema, err := ConvertOpenAPISchema2SwaggerObject(data) 57 if err != nil { 58 return nil, err 59 } 60 FixOpenAPISchema("", schema) 61 return schema, nil 62 } 63 64 // ParsePropertiesToSchemaWithCueX parse the properties in cue script to the openapi schema 65 // Read the template.parameter field 66 func (c CUE) ParsePropertiesToSchemaWithCueX(templateFieldPath string) (*openapi3.Schema, error) { 67 val, err := c.ParseToValueWithCueX() 68 if err != nil { 69 return nil, err 70 } 71 var template cue.Value 72 if len(templateFieldPath) == 0 { 73 template = val 74 } else { 75 template = val.LookupPath(cue.ParsePath(templateFieldPath)) 76 if !template.Exists() { 77 return nil, fmt.Errorf("failed to lookup value: var(path=%s) not exist, cue script: %s", templateFieldPath, c) 78 } 79 } 80 data, err := common.GenOpenAPIWithCueX(template) 81 if err != nil { 82 return nil, err 83 } 84 schema, err := ConvertOpenAPISchema2SwaggerObject(data) 85 if err != nil { 86 return nil, err 87 } 88 FixOpenAPISchema("", schema) 89 return schema, nil 90 } 91 92 // FixOpenAPISchema fixes tainted `description` filed, missing of title `field`. 93 func FixOpenAPISchema(name string, schema *openapi3.Schema) { 94 t := schema.Type 95 switch t { 96 case "object": 97 for k, v := range schema.Properties { 98 s := v.Value 99 FixOpenAPISchema(k, s) 100 } 101 case "array": 102 if schema.Items != nil { 103 FixOpenAPISchema("", schema.Items.Value) 104 } 105 } 106 if name != "" { 107 schema.Title = name 108 } 109 110 description := schema.Description 111 if strings.Contains(description, appfile.UsageTag) { 112 description = strings.Split(description, appfile.UsageTag)[1] 113 } 114 if strings.Contains(description, appfile.ShortTag) { 115 description = strings.Split(description, appfile.ShortTag)[0] 116 description = strings.TrimSpace(description) 117 } 118 schema.Description = description 119 } 120 121 // ConvertOpenAPISchema2SwaggerObject converts OpenAPI v2 JSON schema to Swagger Object 122 func ConvertOpenAPISchema2SwaggerObject(data []byte) (*openapi3.Schema, error) { 123 swagger, err := openapi3.NewLoader().LoadFromData(data) 124 if err != nil { 125 return nil, err 126 } 127 128 schemaRef, ok := swagger.Components.Schemas[process.ParameterFieldName] 129 if !ok { 130 return nil, errors.New(util.ErrGenerateOpenAPIV2JSONSchemaForCapability) 131 } 132 return schemaRef.Value, nil 133 }