diff --git a/pkg/controller/utils/capability_test.go b/pkg/controller/utils/capability_test.go index 4e8ac5689..eeca4692b 100644 --- a/pkg/controller/utils/capability_test.go +++ b/pkg/controller/utils/capability_test.go @@ -71,7 +71,7 @@ annotations: { parameter: [string]: string `, - want: want{data: "{\"type\":\"object\"}", err: nil}, + want: want{data: `{"additionalProperties":{"type":"string"},"type":"object"}`, err: nil}, }, "parameter in cue is a string type,": { reason: "Prepare a normal parameter cue file", @@ -166,7 +166,7 @@ patch: { parameter: [string]: string `, - want: want{data: "{\"type\":\"object\"}", err: nil}, + want: want{data: `{"additionalProperties":{"type":"string"},"type":"object"}`, err: nil}, }, } diff --git a/pkg/cue/script/schema.go b/pkg/cue/script/schema.go index ad8576820..44615a7b7 100644 --- a/pkg/cue/script/schema.go +++ b/pkg/cue/script/schema.go @@ -47,7 +47,7 @@ func (c CUE) ParsePropertiesToSchema(templateFieldPath ...string) (*openapi3.Sch return nil, fmt.Errorf("%w cue script: %s", err, c) } } - data, err := common.GenOpenAPI(template.CueValue()) + data, err := common.GenOpenAPI(template) if err != nil { return nil, err } diff --git a/pkg/utils/common/common.go b/pkg/utils/common/common.go index 964c9468f..35aa1031b 100644 --- a/pkg/utils/common/common.go +++ b/pkg/utils/common/common.go @@ -34,7 +34,6 @@ import ( "cuelang.org/go/cue" "cuelang.org/go/cue/cuecontext" - "cuelang.org/go/cue/format" "cuelang.org/go/encoding/openapi" "github.com/AlecAivazis/survey/v2" cloudshellv1alpha1 "github.com/cloudtty/cloudtty/pkg/apis/cloudshell/v1alpha1" @@ -253,7 +252,7 @@ func GetCUEParameterValue(cueStr string, pd *packages.PackageDiscover) (cue.Valu } // GenOpenAPI generates OpenAPI json schema from cue.Instance -func GenOpenAPI(val cue.Value) (b []byte, err error) { +func GenOpenAPI(val *value.Value) (b []byte, err error) { defer func() { if r := recover(); r != nil { err = fmt.Errorf("invalid cue definition to generate open api: %v", r) @@ -261,8 +260,8 @@ func GenOpenAPI(val cue.Value) (b []byte, err error) { return } }() - if val.Err() != nil { - return nil, val.Err() + if val.CueValue().Err() != nil { + return nil, val.CueValue().Err() } paramOnlyVal, err := RefineParameterValue(val) if err != nil { @@ -279,26 +278,25 @@ func GenOpenAPI(val cue.Value) (b []byte, err error) { } // RefineParameterValue refines cue value to merely include `parameter` identifier -// nolint:staticcheck -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: - paramSyntax, _ := format.Node(paramVal.Value().Syntax(cue.Docs(true), cue.ResolveReferences(true))) - paramOnlyStr = fmt.Sprintf("#%s: %s\n", process.ParameterFieldName, string(paramSyntax)) - case cue.IntKind, cue.StringKind, cue.FloatKind, cue.BoolKind: - paramOnlyStr = fmt.Sprintf("#%s: %v", process.ParameterFieldName, paramVal) +func RefineParameterValue(val *value.Value) (cue.Value, error) { + defaultValue := cuecontext.New().CompileString("#parameter: {}") + parameterPath := cue.MakePath(cue.Def(process.ParameterFieldName)) + v, err := val.MakeValue("{}") + if err != nil { + return defaultValue, err + } + paramVal, err := val.LookupValue(process.ParameterFieldName) + if err != nil { + // nolint:nilerr + return defaultValue, nil + } + switch k := paramVal.CueValue().IncompleteKind(); k { case cue.BottomKind: - paramOnlyStr = fmt.Sprintf("#%s: {}", process.ParameterFieldName) + return defaultValue, nil default: - return cue.Value{}, fmt.Errorf("unsupported parameter kind: %s", k.String()) + paramOnlyVal := v.CueValue().FillPath(parameterPath, paramVal.CueValue()) + return paramOnlyVal, nil } - paramOnlyVal := cuecontext.New().CompileString(paramOnlyStr) - if paramOnlyVal.Err() != nil { - return cue.Value{}, paramOnlyVal.Err() - } - return paramOnlyVal, nil } // RealtimePrintCommandOutput prints command output in real time diff --git a/pkg/utils/common/common_test.go b/pkg/utils/common/common_test.go index b76161f1b..72805704a 100644 --- a/pkg/utils/common/common_test.go +++ b/pkg/utils/common/common_test.go @@ -29,10 +29,10 @@ import ( "testing" "time" - "cuelang.org/go/cue/cuecontext" "cuelang.org/go/cue/load" "github.com/crossplane/crossplane-runtime/pkg/test" "github.com/google/go-cmp/cmp" + "github.com/kubevela/workflow/pkg/cue/model/value" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" @@ -340,11 +340,11 @@ func TestGenOpenAPI(t *testing.T) { for name, tc := range cases { t.Run(name, func(t *testing.T) { - vals, err := cuecontext.New().BuildInstances(load.Instances([]string{filepath.FromSlash(tc.fileName)}, &load.Config{ + instances := load.Instances([]string{filepath.FromSlash(tc.fileName)}, &load.Config{ Dir: "testdata", - })) + }) + val, err := value.NewValueWithInstance(instances[0], nil, "") 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 != "" { @@ -465,10 +465,10 @@ patch: { label: parameter.x } }` - cuectx := cuecontext.New() - val := cuectx.CompileString(s) - assert.NoError(t, val.Err()) - _, err := RefineParameterValue(val) + val, err := value.NewValue(s, nil, "") + assert.NoError(t, err) + assert.NoError(t, val.CueValue().Err()) + _, err = RefineParameterValue(val) assert.NoError(t, err) // test #parameter not exist but parameter exists s = `parameter: { @@ -477,24 +477,20 @@ patch: { y: string } }` - val = cuectx.CompileString(s) + val, err = value.NewValue(s, nil, "") + assert.NoError(t, err) + assert.NoError(t, val.CueValue().Err()) assert.NoError(t, err) _, err = RefineParameterValue(val) assert.NoError(t, err) // test #parameter as int s = `parameter: #parameter #parameter: int` - val = cuectx.CompileString(s) + val, err = value.NewValue(s, nil, "") assert.NoError(t, err) + assert.NoError(t, val.CueValue().Err()) _, err = RefineParameterValue(val) assert.NoError(t, err) - // test invalid parameter kind - s = `parameter: #parameter -#parameter: '\x03abc'` - val = cuectx.CompileString(s) - assert.NoError(t, err) - _, err = RefineParameterValue(val) - assert.NotNil(t, err) } func TestFilterClusterObjectRefFromAddonObservability(t *testing.T) { diff --git a/pkg/utils/common/testdata/workload1.cue b/pkg/utils/common/testdata/workload1.cue index f82092b8a..85c4ebca5 100644 --- a/pkg/utils/common/testdata/workload1.cue +++ b/pkg/utils/common/testdata/workload1.cue @@ -7,6 +7,8 @@ parameter: { cmd?: [...string] cpu?: string + + http: [string]: int } #routeName: "\(context.appName)-\(context.name)" diff --git a/pkg/utils/common/testdata/workload1.json b/pkg/utils/common/testdata/workload1.json index 1e9c28d5a..df5aac541 100644 --- a/pkg/utils/common/testdata/workload1.json +++ b/pkg/utils/common/testdata/workload1.json @@ -10,7 +10,8 @@ "parameter": { "type": "object", "required": [ - "image" + "image", + "http" ], "properties": { "image": { @@ -26,6 +27,12 @@ }, "cpu": { "type": "string" + }, + "http": { + "type": "object", + "additionalProperties": { + "type": "integer" + } } } }