From 4e010d7bae7c18c6cb3c40c262df5bf73e922468 Mon Sep 17 00:00:00 2001 From: Zheng Xi Zhou Date: Mon, 30 Aug 2021 20:16:24 +0800 Subject: [PATCH] Fix: support more Terraform variable types (#2194) Including null, list(...), map(...) Terraform types --- pkg/controller/utils/capability.go | 18 ++++++ pkg/controller/utils/capability_test.go | 77 ++++++++++++++++++++++--- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/pkg/controller/utils/capability.go b/pkg/controller/utils/capability.go index 5a268125c..7b31e2992 100644 --- a/pkg/controller/utils/capability.go +++ b/pkg/controller/utils/capability.go @@ -55,6 +55,12 @@ const ( TerraformVariableTuple string = "tuple" TerraformVariableMap string = "map" TerraformVariableObject string = "object" + TerraformVariableNull string = "" + + TerraformListTypePrefix string = "list(" + TerraformTupleTypePrefix string = "tuple(" + TerraformMapTypePrefix string = "map(" + TerraformObjectTypePrefix string = "object(" ) // ErrNoSectionParameterInCue means there is not parameter section in Cue template of a workload @@ -142,6 +148,18 @@ func GetOpenAPISchemaFromTerraformComponentDefinition(configuration string) ([]b schema = openapi3.NewArraySchema() case TerraformVariableMap, TerraformVariableObject: schema = openapi3.NewObjectSchema() + case TerraformVariableNull: + return nil, fmt.Errorf("null type variable is NOT supported, please specify a type for the variable: %s", v.Name) + } + + // To identify unusual list type + if schema == nil { + switch { + case strings.HasPrefix(v.Type, TerraformListTypePrefix) || strings.HasPrefix(v.Type, TerraformTupleTypePrefix): + schema = openapi3.NewArraySchema() + case strings.HasPrefix(v.Type, TerraformMapTypePrefix) || strings.HasPrefix(v.Type, TerraformObjectTypePrefix): + schema = openapi3.NewObjectSchema() + } } schema.Title = k required = append(required, k) diff --git a/pkg/controller/utils/capability_test.go b/pkg/controller/utils/capability_test.go index 154cb4025..3923f2c92 100644 --- a/pkg/controller/utils/capability_test.go +++ b/pkg/controller/utils/capability_test.go @@ -18,6 +18,7 @@ package utils import ( + "errors" "io/ioutil" "path/filepath" "strings" @@ -240,7 +241,16 @@ func TestNewCapabilityComponentDef(t *testing.T) { } func TestGetOpenAPISchemaFromTerraformComponentDefinition(t *testing.T) { - configuration := ` + type want struct { + subStr string + err error + } + cases := map[string]struct { + configuration string + want want + }{ + "valid": { + configuration: ` module "rds" { source = "terraform-alicloud-modules/rds/alicloud" engine = "MySQL" @@ -300,11 +310,64 @@ variable "listVar" { variable "mapVar" { type = "map" -}` +}`, + want: want{ + subStr: "account_name", + err: nil, + }, + }, + "null type variable": { + configuration: ` +variable "name" { + default = "abc" +}`, + want: want{ + subStr: "", + err: errors.New("null type variable is NOT supported, please specify a type for the variable: name"), + }, + }, + "complicated list variable": { + configuration: ` +variable "aaa" { + type = list(object({ + type = string + sourceArn = string + config = string + })) + default = [] +}`, + want: want{ + subStr: "aaa", + err: nil, + }, + }, + "complicated map variable": { + configuration: ` +variable "bbb" { + type = map({ + type = string + sourceArn = string + config = string + }) + default = [] +}`, + want: want{ + subStr: "bbb", + err: nil, + }, + }, + } - schema, err := GetOpenAPISchemaFromTerraformComponentDefinition(configuration) - assert.NilError(t, err) - data := string(schema) - assert.Equal(t, strings.Contains(data, "account_name"), true) - assert.Equal(t, strings.Contains(data, "intVar"), true) + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + schema, err := GetOpenAPISchemaFromTerraformComponentDefinition(tc.configuration) + if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" { + t.Errorf("\n%s\nGetOpenAPISchemaFromTerraformComponentDefinition(...): -want error, +got error:\n%s", name, diff) + } + if tc.want.err == nil { + data := string(schema) + assert.Equal(t, strings.Contains(data, tc.want.subStr), true) + } + }) + } }