mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-27 16:17:34 +00:00
Fix: use value instead of instance in openapi.gen (#4739)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com> Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
This commit is contained in:
+3
-5
@@ -32,7 +32,7 @@ import (
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/google/go-github/v32/github"
|
||||
"github.com/imdario/mergo"
|
||||
@@ -589,18 +589,16 @@ func unmarshalToContent(content []byte) (fileContent *github.RepositoryContent,
|
||||
return nil, nil, fmt.Errorf("unmarshalling failed for both file and directory content: %s and %w", fileUnmarshalError, directoryUnmarshalError)
|
||||
}
|
||||
|
||||
// nolint:staticcheck
|
||||
func genAddonAPISchema(addonRes *UIData) error {
|
||||
param, err := utils2.PrepareParameterCue(addonRes.Name, addonRes.Parameters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var r cue.Runtime
|
||||
cueInst, err := r.Compile("-", param)
|
||||
val := cuecontext.New().CompileString(param)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data, err := common.GenOpenAPI(cueInst)
|
||||
data, err := common.GenOpenAPI(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+2
-2
@@ -25,6 +25,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"cuelang.org/go/cue/format"
|
||||
"cuelang.org/go/encoding/gocode/gocodec"
|
||||
"github.com/fatih/color"
|
||||
@@ -240,8 +241,7 @@ func (cmd *InitCmd) createURLComponent() error {
|
||||
// toCUEResourceString formats object to CUE string used in addons
|
||||
// nolint:staticcheck
|
||||
func toCUEResourceString(obj interface{}) (string, error) {
|
||||
r := cue.Runtime{}
|
||||
v, err := gocodec.New(&r, nil).Decode(obj)
|
||||
v, err := gocodec.New((*cue.Runtime)(cuecontext.New()), nil).Decode(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -84,7 +84,6 @@ func GetChartValuesJSONSchema(ctx context.Context, h *common.Helm) ([]byte, erro
|
||||
|
||||
// generateSchemaFromValues generate OpenAPIv3 schema based on Chart Values
|
||||
// file.
|
||||
// nolint:staticcheck
|
||||
func generateSchemaFromValues(values []byte) ([]byte, error) {
|
||||
valuesIdentifier := "values"
|
||||
cuectx := cuecontext.New()
|
||||
@@ -104,13 +103,12 @@ func generateSchemaFromValues(values []byte) ([]byte, error) {
|
||||
// an identifier manually
|
||||
valuesStr := fmt.Sprintf("#%s:{\n%s\n}", valuesIdentifier, string(c))
|
||||
|
||||
r := cue.Runtime{}
|
||||
inst, err := r.Compile("-", valuesStr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot compile CUE generated from Values.yaml")
|
||||
val := cuecontext.New().CompileString(valuesStr)
|
||||
if val.Err() != nil {
|
||||
return nil, errors.Wrap(val.Err(), "cannot compile CUE generated from Values.yaml")
|
||||
}
|
||||
// generate OpenAPIv3 schema through cue openapi encoder
|
||||
rawSchema, err := openapi.Gen(inst, &openapi.Config{})
|
||||
rawSchema, err := openapi.Gen(val, &openapi.Config{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot generate OpenAPIv3 schema")
|
||||
}
|
||||
|
||||
@@ -26,8 +26,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/build"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/src-d/go-git.v4"
|
||||
@@ -715,39 +714,23 @@ func getOpenAPISchema(capability types.Capability, pd *packages.PackageDiscover)
|
||||
}
|
||||
|
||||
// generateOpenAPISchemaFromCapabilityParameter returns the parameter of a definition in cue.Value format
|
||||
// nolint:staticcheck
|
||||
func generateOpenAPISchemaFromCapabilityParameter(capability types.Capability, pd *packages.PackageDiscover) ([]byte, error) {
|
||||
ctx := cuecontext.New()
|
||||
template, err := PrepareParameterCue(capability.Name, capability.CueTemplate)
|
||||
if err != nil {
|
||||
if errors.As(err, &ErrNoSectionParameterInCue{}) {
|
||||
// return OpenAPI with empty object parameter, making it possible to generate ConfigMap
|
||||
var r cue.Runtime
|
||||
cueInst, _ := r.Compile("-", "")
|
||||
return common.GenOpenAPI(cueInst)
|
||||
return common.GenOpenAPI(ctx.CompileString(""))
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
template += velacue.BaseTemplate
|
||||
if pd == nil {
|
||||
var r cue.Runtime
|
||||
cueInst, err := r.Compile("-", template)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return common.GenOpenAPI(cueInst)
|
||||
}
|
||||
bi := build.NewContext().NewInstance("", nil)
|
||||
err = value.AddFile(bi, "-", template)
|
||||
val, err := value.NewValue(template, pd, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cueInst, err := pd.ImportPackagesAndBuildInstance(bi)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return common.GenOpenAPI(cueInst)
|
||||
return common.GenOpenAPI(val.CueValue())
|
||||
}
|
||||
|
||||
// GenerateOpenAPISchemaFromDefinition returns the parameter of a definition
|
||||
|
||||
@@ -164,8 +164,7 @@ func (def *Definition) ToCUE() (*cue.Value, string, error) {
|
||||
"attributes": spec,
|
||||
},
|
||||
}
|
||||
r := &cue.Runtime{}
|
||||
codec := gocodec.New(r, &gocodec.Config{})
|
||||
codec := gocodec.New((*cue.Runtime)(cuecontext.New()), &gocodec.Config{})
|
||||
val, err := codec.Decode(obj)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
|
||||
+14
-33
@@ -31,7 +31,7 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/ast"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"cuelang.org/go/cue/format"
|
||||
"cuelang.org/go/encoding/openapi"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
@@ -263,22 +263,22 @@ func GetCUEParameterValue(cueStr string, pd *packages.PackageDiscover) (cue.Valu
|
||||
}
|
||||
|
||||
// GenOpenAPI generates OpenAPI json schema from cue.Instance
|
||||
func GenOpenAPI(inst *cue.Instance) (b []byte, err error) {
|
||||
func GenOpenAPI(val cue.Value) (b []byte, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("invalid cue definition to generate open api: %v", r)
|
||||
return
|
||||
}
|
||||
}()
|
||||
if inst.Err != nil {
|
||||
return nil, inst.Err
|
||||
if val.Err() != nil {
|
||||
return nil, val.Err()
|
||||
}
|
||||
paramOnlyIns, err := RefineParameterInstance(inst)
|
||||
paramOnlyVal, err := RefineParameterValue(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defaultConfig := &openapi.Config{ExpandReferences: true}
|
||||
b, err = openapi.Gen(paramOnlyIns, defaultConfig)
|
||||
b, err = openapi.Gen(paramOnlyVal, defaultConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -287,29 +287,10 @@ func GenOpenAPI(inst *cue.Instance) (b []byte, err error) {
|
||||
return out.Bytes(), nil
|
||||
}
|
||||
|
||||
// extractParameterDefinitionNodeFromInstance extracts the `#parameter` ast.Node from root instance, if failed fall back to `parameter` by LookUpDef
|
||||
// RefineParameterValue refines cue value to merely include `parameter` identifier
|
||||
// nolint:staticcheck
|
||||
func extractParameterDefinitionNodeFromInstance(inst *cue.Instance) ast.Node {
|
||||
opts := []cue.Option{cue.Docs(true), cue.InlineImports(true)}
|
||||
node := inst.Value().Syntax(opts...)
|
||||
if fileNode, ok := node.(*ast.File); ok {
|
||||
for _, decl := range fileNode.Decls {
|
||||
if field, ok := decl.(*ast.Field); ok {
|
||||
if label, ok := field.Label.(*ast.Ident); ok && label.Name == "#"+process.ParameterFieldName {
|
||||
return decl.(*ast.Field).Value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
paramVal := inst.LookupDef(process.ParameterFieldName)
|
||||
return paramVal.Syntax(opts...)
|
||||
}
|
||||
|
||||
// RefineParameterInstance refines cue instance to merely include `parameter` identifier
|
||||
// nolint:staticcheck
|
||||
func RefineParameterInstance(inst *cue.Instance) (*cue.Instance, error) {
|
||||
r := cue.Runtime{}
|
||||
paramVal := inst.Lookup(process.ParameterFieldName)
|
||||
func RefineParameterValue(val cue.Value) (cue.Value, error) {
|
||||
paramVal := val.Lookup(process.ParameterFieldName)
|
||||
var paramOnlyStr string
|
||||
switch k := paramVal.IncompleteKind(); k {
|
||||
case cue.StructKind, cue.ListKind:
|
||||
@@ -320,13 +301,13 @@ func RefineParameterInstance(inst *cue.Instance) (*cue.Instance, error) {
|
||||
case cue.BottomKind:
|
||||
paramOnlyStr = fmt.Sprintf("#%s: {}", process.ParameterFieldName)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupport parameter kind: %s", k.String())
|
||||
return cue.Value{}, fmt.Errorf("unsupport parameter kind: %s", k.String())
|
||||
}
|
||||
paramOnlyIns, err := r.Compile("-", paramOnlyStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
paramOnlyVal := cuecontext.New().CompileString(paramOnlyStr)
|
||||
if paramOnlyVal.Err() != nil {
|
||||
return cue.Value{}, paramOnlyVal.Err()
|
||||
}
|
||||
return paramOnlyIns, nil
|
||||
return paramOnlyVal, nil
|
||||
}
|
||||
|
||||
// RealtimePrintCommandOutput prints command output in real time
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"cuelang.org/go/cue/load"
|
||||
"github.com/crossplane/crossplane-runtime/pkg/test"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
@@ -305,7 +305,6 @@ name
|
||||
}
|
||||
}
|
||||
|
||||
// nolint:staticcheck
|
||||
func TestGenOpenAPI(t *testing.T) {
|
||||
type want struct {
|
||||
targetSchemaFile string
|
||||
@@ -337,10 +336,12 @@ func TestGenOpenAPI(t *testing.T) {
|
||||
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
inst := cue.Build(load.Instances([]string{filepath.FromSlash(tc.fileName)}, &load.Config{
|
||||
vals, err := cuecontext.New().BuildInstances(load.Instances([]string{filepath.FromSlash(tc.fileName)}, &load.Config{
|
||||
Dir: "testdata",
|
||||
}))[0]
|
||||
got, err := GenOpenAPI(inst)
|
||||
}))
|
||||
assert.NoError(t, err)
|
||||
val := vals[0]
|
||||
got, err := GenOpenAPI(val)
|
||||
if tc.want.err != nil {
|
||||
if diff := cmp.Diff(tc.want.err, errors.New(err.Error()), test.EquateErrors()); diff != "" {
|
||||
t.Errorf("\n%s\nGenOpenAPIFromFile(...): -want error, +got error:\n%s", tc.reason, diff)
|
||||
@@ -446,7 +447,6 @@ variable "mapVar" {
|
||||
assert.True(t, intVarExisted)
|
||||
}
|
||||
|
||||
// nolint:staticcheck
|
||||
func TestRefineParameterInstance(t *testing.T) {
|
||||
// test #parameter exists: mock issues in #1939 & #2062
|
||||
s := `parameter: #parameter
|
||||
@@ -461,10 +461,10 @@ patch: {
|
||||
label: parameter.x
|
||||
}
|
||||
}`
|
||||
r := cue.Runtime{}
|
||||
inst, err := r.Compile("-", s)
|
||||
assert.NoError(t, err)
|
||||
_, err = RefineParameterInstance(inst)
|
||||
cuectx := cuecontext.New()
|
||||
val := cuectx.CompileString(s)
|
||||
assert.NoError(t, val.Err())
|
||||
_, err := RefineParameterValue(val)
|
||||
assert.NoError(t, err)
|
||||
// test #parameter not exist but parameter exists
|
||||
s = `parameter: {
|
||||
@@ -473,24 +473,23 @@ patch: {
|
||||
y: string
|
||||
}
|
||||
}`
|
||||
inst, err = r.Compile("-", s)
|
||||
val = cuectx.CompileString(s)
|
||||
assert.NoError(t, err)
|
||||
_ = extractParameterDefinitionNodeFromInstance(inst)
|
||||
_, err = RefineParameterInstance(inst)
|
||||
_, err = RefineParameterValue(val)
|
||||
assert.NoError(t, err)
|
||||
// test #parameter as int
|
||||
s = `parameter: #parameter
|
||||
#parameter: int`
|
||||
inst, err = r.Compile("-", s)
|
||||
val = cuectx.CompileString(s)
|
||||
assert.NoError(t, err)
|
||||
_, err = RefineParameterInstance(inst)
|
||||
_, err = RefineParameterValue(val)
|
||||
assert.NoError(t, err)
|
||||
// test invalid parameter kind
|
||||
s = `parameter: #parameter
|
||||
#parameter: '\x03abc'`
|
||||
inst, err = r.Compile("-", s)
|
||||
val = cuectx.CompileString(s)
|
||||
assert.NoError(t, err)
|
||||
_, err = RefineParameterInstance(inst)
|
||||
_, err = RefineParameterValue(val)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
"time"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"cuelang.org/go/encoding/gocode/gocodec"
|
||||
crossplane "github.com/oam-dev/terraform-controller/api/types/crossplane-runtime"
|
||||
"github.com/pkg/errors"
|
||||
@@ -142,7 +143,7 @@ func buildTemplateFromYAML(templateYAML string, def *pkgdef.Definition) error {
|
||||
templateObject[process.OutputsFieldName].(map[string]interface{})[name] = yamlObject
|
||||
}
|
||||
}
|
||||
codec := gocodec.New(&cue.Runtime{}, &gocodec.Config{})
|
||||
codec := gocodec.New((*cue.Runtime)(cuecontext.New()), &gocodec.Config{})
|
||||
val, err := codec.Decode(templateObject)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to decode template into cue")
|
||||
|
||||
Reference in New Issue
Block a user