From 5049a0ed57528a483ff18630bc69e52c49db6705 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Mon, 22 Mar 2021 12:52:09 +0000 Subject: [PATCH] Support attribute nested type --- go.mod | 2 +- go.sum | 4 +- internal/schema/0.12/terraform_block.go | 2 +- internal/schema/0.13/terraform_block.go | 4 +- internal/schema/0.14/terraform.go | 4 +- internal/schema/0.15/terraform.go | 6 +- schema/schema_merge.go | 66 +++- schema/schema_merge_test.go | 75 ++++ schema/schema_merge_v015_test.go | 418 +++++++++++++++++++++ schema/testdata/provider-schemas-0.15.json | 161 ++++++++ schema/testdata/test-config-0.15.tf | 8 + 11 files changed, 738 insertions(+), 12 deletions(-) create mode 100644 schema/schema_merge_v015_test.go create mode 100644 schema/testdata/provider-schemas-0.15.json create mode 100644 schema/testdata/test-config-0.15.tf diff --git a/go.mod b/go.mod index 32f596ba..f93c1fac 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/google/go-cmp v0.5.5 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-version v1.2.1 - github.com/hashicorp/hcl-lang v0.0.0-20210317074414-9bb6847208c3 + github.com/hashicorp/hcl-lang v0.0.0-20210325104312-683155cd29b5 github.com/hashicorp/hcl/v2 v2.9.1 github.com/hashicorp/terraform-config-inspect v0.0.0-20210318070130-9a80970d6b34 github.com/hashicorp/terraform-json v0.9.0 diff --git a/go.sum b/go.sum index ce36ef42..b24e8184 100644 --- a/go.sum +++ b/go.sum @@ -31,8 +31,8 @@ github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pB github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws= github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= -github.com/hashicorp/hcl-lang v0.0.0-20210317074414-9bb6847208c3 h1:s33G8woMGjgqckJnOXbDqRi42kNfPs0+I5TmqRU5Xts= -github.com/hashicorp/hcl-lang v0.0.0-20210317074414-9bb6847208c3/go.mod h1:ZGuDQ7IWG2eFZZJC4pBZFnbH8afJ8gyOPmlHt5lJZK0= +github.com/hashicorp/hcl-lang v0.0.0-20210325104312-683155cd29b5 h1:UtKBwxbwj9lKk8InHWRrPtBNf3dW5Vyb6EVxRtA8RYs= +github.com/hashicorp/hcl-lang v0.0.0-20210325104312-683155cd29b5/go.mod h1:ZGuDQ7IWG2eFZZJC4pBZFnbH8afJ8gyOPmlHt5lJZK0= github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90= github.com/hashicorp/hcl/v2 v2.9.1 h1:eOy4gREY0/ZQHNItlfuEZqtcQbXIxzojlP301hDpnac= github.com/hashicorp/hcl/v2 v2.9.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= diff --git a/internal/schema/0.12/terraform_block.go b/internal/schema/0.12/terraform_block.go index 661b680e..04d9c49c 100644 --- a/internal/schema/0.12/terraform_block.go +++ b/internal/schema/0.12/terraform_block.go @@ -72,7 +72,7 @@ func terraformBlockSchema(v *version.Version) *schema.BlockSchema { Expr: schema.ExprConstraints{ schema.ObjectExpr{ Attributes: schema.ObjectExprAttributes{ - "version": schema.ObjectAttribute{ + "version": &schema.AttributeSchema{ Expr: schema.LiteralTypeOnly(cty.String), Description: lang.Markdown("Version constraint specifying which subset of " + "available provider versions the module is compatible with, e.g. `~> 1.0`"), diff --git a/internal/schema/0.13/terraform_block.go b/internal/schema/0.13/terraform_block.go index 14e8113b..54adfd41 100644 --- a/internal/schema/0.13/terraform_block.go +++ b/internal/schema/0.13/terraform_block.go @@ -56,12 +56,12 @@ var terraformBlockSchema = &schema.BlockSchema{ Expr: schema.ExprConstraints{ schema.ObjectExpr{ Attributes: schema.ObjectExprAttributes{ - "source": schema.ObjectAttribute{ + "source": &schema.AttributeSchema{ Expr: schema.LiteralTypeOnly(cty.String), Description: lang.Markdown("The global source address for the provider " + "you intend to use, such as `hashicorp/aws`"), }, - "version": schema.ObjectAttribute{ + "version": &schema.AttributeSchema{ Expr: schema.LiteralTypeOnly(cty.String), Description: lang.Markdown("Version constraint specifying which subset of " + "available provider versions the module is compatible with, e.g. `~> 1.0`"), diff --git a/internal/schema/0.14/terraform.go b/internal/schema/0.14/terraform.go index d941decd..9397e9a8 100644 --- a/internal/schema/0.14/terraform.go +++ b/internal/schema/0.14/terraform.go @@ -68,12 +68,12 @@ func terraformBlockSchema(v *version.Version) *schema.BlockSchema { Expr: schema.ExprConstraints{ schema.ObjectExpr{ Attributes: schema.ObjectExprAttributes{ - "source": schema.ObjectAttribute{ + "source": &schema.AttributeSchema{ Expr: schema.LiteralTypeOnly(cty.String), Description: lang.Markdown("The global source address for the provider " + "you intend to use, such as `hashicorp/aws`"), }, - "version": schema.ObjectAttribute{ + "version": &schema.AttributeSchema{ Expr: schema.LiteralTypeOnly(cty.String), Description: lang.Markdown("Version constraint specifying which subset of " + "available provider versions the module is compatible with, e.g. `~> 1.0`"), diff --git a/internal/schema/0.15/terraform.go b/internal/schema/0.15/terraform.go index 6f245b71..50832851 100644 --- a/internal/schema/0.15/terraform.go +++ b/internal/schema/0.15/terraform.go @@ -13,17 +13,17 @@ func patchTerraformBlockSchema(bs *schema.BlockSchema, v *version.Version) *sche Expr: schema.ExprConstraints{ schema.ObjectExpr{ Attributes: schema.ObjectExprAttributes{ - "source": schema.ObjectAttribute{ + "source": &schema.AttributeSchema{ Expr: schema.LiteralTypeOnly(cty.String), Description: lang.Markdown("The global source address for the provider " + "you intend to use, such as `hashicorp/aws`"), }, - "version": schema.ObjectAttribute{ + "version": &schema.AttributeSchema{ Expr: schema.LiteralTypeOnly(cty.String), Description: lang.Markdown("Version constraint specifying which subset of " + "available provider versions the module is compatible with, e.g. `~> 1.0`"), }, - "configuration_aliases": schema.ObjectAttribute{ + "configuration_aliases": &schema.AttributeSchema{ Expr: schema.ExprConstraints{ schema.TupleConsExpr{ Name: "set of aliases", diff --git a/schema/schema_merge.go b/schema/schema_merge.go index 86ca0096..edc5c4f9 100644 --- a/schema/schema_merge.go +++ b/schema/schema_merge.go @@ -11,6 +11,7 @@ import ( tfjson "github.com/hashicorp/terraform-json" "github.com/hashicorp/terraform-schema/internal/addrs" "github.com/hashicorp/terraform-schema/internal/refdecoder" + "github.com/zclconf/go-cty/cty" ) type SchemaMerger struct { @@ -295,12 +296,75 @@ func convertAttributesFromJson(attributes map[string]*tfjson.SchemaAttribute) ma IsComputed: attr.Computed, IsOptional: attr.Optional, IsRequired: attr.Required, - Expr: schema.LiteralTypeOnly(attr.AttributeType), + Expr: exprConstraintsFromAttribute(attr), } } return cAttrs } +func exprConstraintsFromAttribute(attr *tfjson.SchemaAttribute) schema.ExprConstraints { + var expr schema.ExprConstraints + if attr.AttributeType != cty.NilType { + expr = schema.LiteralTypeOnly(attr.AttributeType) + } + if attr.AttributeNestedType != nil { + switch attr.AttributeNestedType.NestingMode { + case tfjson.SchemaNestingModeSingle: + return schema.ExprConstraints{ + convertJsonAttributesToObjectExprAttr(attr.AttributeNestedType.Attributes), + } + case tfjson.SchemaNestingModeList: + return schema.ExprConstraints{ + schema.ListExpr{ + Elem: schema.ExprConstraints{ + convertJsonAttributesToObjectExprAttr(attr.AttributeNestedType.Attributes), + }, + MinItems: attr.AttributeNestedType.MinItems, + MaxItems: attr.AttributeNestedType.MaxItems, + }, + } + case tfjson.SchemaNestingModeSet: + return schema.ExprConstraints{ + schema.SetExpr{ + Elem: schema.ExprConstraints{ + convertJsonAttributesToObjectExprAttr(attr.AttributeNestedType.Attributes), + }, + MinItems: attr.AttributeNestedType.MinItems, + MaxItems: attr.AttributeNestedType.MaxItems, + }, + } + case tfjson.SchemaNestingModeMap: + return schema.ExprConstraints{ + schema.MapExpr{ + Elem: schema.ExprConstraints{ + convertJsonAttributesToObjectExprAttr(attr.AttributeNestedType.Attributes), + }, + MinItems: attr.AttributeNestedType.MinItems, + MaxItems: attr.AttributeNestedType.MaxItems, + }, + } + } + } + return expr +} + +func convertJsonAttributesToObjectExprAttr(attrs map[string]*tfjson.SchemaAttribute) schema.ObjectExpr { + attributes := make(schema.ObjectExprAttributes, len(attrs)) + for name, attr := range attrs { + attributes[name] = &schema.AttributeSchema{ + Description: markupContent(attr.Description, attr.DescriptionKind), + IsDeprecated: attr.Deprecated, + IsComputed: attr.Computed, + IsOptional: attr.Optional, + IsRequired: attr.Required, + Expr: exprConstraintsFromAttribute(attr), + } + } + return schema.ObjectExpr{ + Attributes: attributes, + } +} + func markupContent(value string, kind tfjson.SchemaDescriptionKind) lang.MarkupContent { if value == "" { return lang.MarkupContent{} diff --git a/schema/schema_merge_test.go b/schema/schema_merge_test.go index 75dc0be5..ed1c10df 100644 --- a/schema/schema_merge_test.go +++ b/schema/schema_merge_test.go @@ -222,3 +222,78 @@ func TestMergeWithJsonProviderSchemas_v013(t *testing.T) { t.Fatalf("schema differs: %s", diff) } } + +func TestMergeWithJsonProviderSchemas_v015(t *testing.T) { + b, err := ioutil.ReadFile("testdata/test-config-0.15.tf") + if err != nil { + t.Fatal(err) + } + f, diags := hclsyntax.ParseConfig(b, "test.tf", hcl.InitialPos) + if len(diags) > 0 { + t.Fatal(diags) + } + + ps := &tfjson.ProviderSchemas{} + b, err = ioutil.ReadFile("testdata/provider-schemas-0.15.json") + if err != nil { + t.Fatal(err) + } + err = json.Unmarshal(b, ps) + if err != nil { + t.Fatal(err) + } + + testCoreSchema := &schema.BodySchema{ + Blocks: map[string]*schema.BlockSchema{ + "provider": { + Labels: []*schema.LabelSchema{ + {Name: "name"}, + }, + Body: &schema.BodySchema{ + Attributes: map[string]*schema.AttributeSchema{ + "alias": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + }, + }, + }, + "resource": { + Labels: []*schema.LabelSchema{ + {Name: "type"}, + {Name: "name"}, + }, + Body: &schema.BodySchema{ + Attributes: map[string]*schema.AttributeSchema{ + "count": {Expr: schema.LiteralTypeOnly(cty.Number), IsOptional: true}, + }, + }, + }, + "data": { + Labels: []*schema.LabelSchema{ + {Name: "type"}, + {Name: "name"}, + }, + Body: &schema.BodySchema{ + Attributes: map[string]*schema.AttributeSchema{ + "count": {Expr: schema.LiteralTypeOnly(cty.Number), IsOptional: true}, + }, + }, + }, + }, + } + sm := NewSchemaMerger(testCoreSchema) + sm.SetParsedFiles(map[string]*hcl.File{ + "test.tf": f, + }) + + mergedSchema, err := sm.MergeWithJsonProviderSchemas(ps) + if err != nil { + t.Fatal(err) + } + + opts := cmp.Options{ + cmpopts.IgnoreUnexported(cty.Type{}), + } + + if diff := cmp.Diff(expectedMergedSchema_v015, mergedSchema, opts); diff != "" { + t.Fatalf("schema differs: %s", diff) + } +} diff --git a/schema/schema_merge_v015_test.go b/schema/schema_merge_v015_test.go new file mode 100644 index 00000000..eb124839 --- /dev/null +++ b/schema/schema_merge_v015_test.go @@ -0,0 +1,418 @@ +package schema + +import ( + //"github.com/hashicorp/hcl-lang/lang" + "github.com/hashicorp/hcl-lang/schema" + "github.com/zclconf/go-cty/cty" +) + +var expectedMergedSchema_v015 = &schema.BodySchema{ + Blocks: map[string]*schema.BlockSchema{ + "data": { + Labels: []*schema.LabelSchema{ + {Name: "type"}, + {Name: "name"}, + }, + Body: &schema.BodySchema{ + Attributes: map[string]*schema.AttributeSchema{ + "count": {Expr: schema.LiteralTypeOnly(cty.Number), IsOptional: true}, + }, + }, + DependentBody: map[schema.SchemaKey]*schema.BodySchema{ + `{"labels":[{"index":0,"value":"hashicup_test"}],"attrs":[{"name":"provider","expr":{"addr":"hashicup"}}]}`: { + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "backend": { + IsRequired: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + "config1": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "first": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + "second": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.Number}, + }, + }, + "third": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "nested": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "config2": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.ListExpr{ + Elem: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "first": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + "second": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.Number}, + }, + }, + "third": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "nested": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + MinItems: 2, + MaxItems: 3, + }, + }, + }, + "config3": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.SetExpr{ + Elem: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "first": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + "second": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.Number}, + }, + }, + "third": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "nested": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + MinItems: 1, + MaxItems: 5, + }, + }, + }, + "config4": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.MapExpr{ + Elem: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "first": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + "second": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.Number}, + }, + }, + "third": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "nested": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + MinItems: 9, + MaxItems: 10, + }, + }, + }, + "workspace": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + }, + Detail: "hashicorp/hashicup", + }, + `{"labels":[{"index":0,"value":"hashicup_test"}]}`: { + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "backend": { + IsRequired: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + "config1": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "first": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + "second": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.Number}, + }, + }, + "third": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "nested": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "config2": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.ListExpr{ + Elem: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "first": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + "second": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.Number}, + }, + }, + "third": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "nested": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + MinItems: 2, + MaxItems: 3, + }, + }, + }, + "config3": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.SetExpr{ + Elem: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "first": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + "second": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.Number}, + }, + }, + "third": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "nested": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + MinItems: 1, + MaxItems: 5, + }, + }, + }, + "config4": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.MapExpr{ + Elem: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "first": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + "second": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.Number}, + }, + }, + "third": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.ObjectExpr{ + Attributes: schema.ObjectExprAttributes{ + "nested": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + MinItems: 9, + MaxItems: 10, + }, + }, + }, + "workspace": { + IsOptional: true, + Expr: schema.ExprConstraints{ + schema.LiteralTypeExpr{Type: cty.String}, + }, + }, + }, + Detail: "hashicorp/hashicup", + }, + }, + }, + "provider": { + Labels: []*schema.LabelSchema{ + {Name: "name"}, + }, + Body: &schema.BodySchema{ + Attributes: map[string]*schema.AttributeSchema{ + "alias": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + }, + }, + DependentBody: map[schema.SchemaKey]*schema.BodySchema{ + `{"labels":[{"index":0,"value":"hashicup"}]}`: { + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{}, + Detail: "hashicorp/hashicup", + DocsLink: &schema.DocsLink{ + URL: "https://registry.terraform.io/providers/hashicorp/hashicup/latest/docs", + Tooltip: "hashicorp/hashicup Documentation", + }, + }, + }, + }, + "resource": { + Labels: []*schema.LabelSchema{ + {Name: "type"}, + {Name: "name"}, + }, + Body: &schema.BodySchema{ + Attributes: map[string]*schema.AttributeSchema{ + "count": {Expr: schema.LiteralTypeOnly(cty.Number), IsOptional: true}, + }, + }, + DependentBody: map[schema.SchemaKey]*schema.BodySchema{}, + }, + }, +} diff --git a/schema/testdata/provider-schemas-0.15.json b/schema/testdata/provider-schemas-0.15.json new file mode 100644 index 00000000..b76aac3e --- /dev/null +++ b/schema/testdata/provider-schemas-0.15.json @@ -0,0 +1,161 @@ +{ + "format_version": "0.1", + "provider_schemas": { + "registry.terraform.io/hashicorp/hashicup": { + "data_source_schemas": { + "hashicup_test": { + "version": 0, + "block": { + "attributes": { + "backend": { + "type": "string", + "description_kind": "plain", + "required": true + }, + "config1": { + "nested_type": { + "attributes": { + "first": { + "type": "string", + "description_kind": "plain", + "optional": true + }, + "second": { + "type": "number", + "description_kind": "plain", + "optional": true + }, + "third": { + "nested_type": { + "attributes": { + "nested": { + "type": "string", + "optional": true + } + }, + "nesting_mode": "single" + }, + "description_kind": "plain", + "optional": true + } + }, + "nesting_mode": "single" + }, + "description_kind": "plain", + "optional": true + }, + "config2": { + "nested_type": { + "attributes": { + "first": { + "type": "string", + "description_kind": "plain", + "optional": true + }, + "second": { + "type": "number", + "description_kind": "plain", + "optional": true + }, + "third": { + "nested_type": { + "attributes": { + "nested": { + "type": "string", + "optional": true + } + }, + "nesting_mode": "single" + }, + "description_kind": "plain", + "optional": true + } + }, + "nesting_mode": "list", + "min_items": 2, + "max_items": 3 + }, + "description_kind": "plain", + "optional": true + }, + "config3": { + "nested_type": { + "attributes": { + "first": { + "type": "string", + "description_kind": "plain", + "optional": true + }, + "second": { + "type": "number", + "description_kind": "plain", + "optional": true + }, + "third": { + "nested_type": { + "attributes": { + "nested": { + "type": "string", + "optional": true + } + }, + "nesting_mode": "single" + }, + "description_kind": "plain", + "optional": true + } + }, + "nesting_mode": "set", + "min_items": 1, + "max_items": 5 + }, + "description_kind": "plain", + "optional": true + }, + "config4": { + "nested_type": { + "attributes": { + "first": { + "type": "string", + "description_kind": "plain", + "optional": true + }, + "second": { + "type": "number", + "description_kind": "plain", + "optional": true + }, + "third": { + "nested_type": { + "attributes": { + "nested": { + "type": "string", + "optional": true + } + }, + "nesting_mode": "single" + }, + "description_kind": "plain", + "optional": true + } + }, + "nesting_mode": "map", + "min_items": 9, + "max_items": 10 + }, + "description_kind": "plain", + "optional": true + }, + "workspace": { + "type": "string", + "description_kind": "plain", + "optional": true + } + }, + "description_kind": "plain" + } + } + } + } + } +} diff --git a/schema/testdata/test-config-0.15.tf b/schema/testdata/test-config-0.15.tf new file mode 100644 index 00000000..d86f022b --- /dev/null +++ b/schema/testdata/test-config-0.15.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + hashicup = { + source = "hashicorp/hashicup" + version = "0.0.0" + } + } +}