diff --git a/go.mod b/go.mod index 92576511..c400ce81 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-20210311200725-da0537032422 + github.com/hashicorp/hcl-lang v0.0.0-20210317074414-9bb6847208c3 github.com/hashicorp/hcl/v2 v2.9.1 github.com/hashicorp/terraform-config-inspect v0.0.0-20201102131242-0c45ba392e51 github.com/hashicorp/terraform-json v0.8.0 diff --git a/go.sum b/go.sum index bbadaa9e..e4df4b7b 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,6 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= @@ -33,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-20210311200725-da0537032422 h1:hDjba3BV66uIFJN07x2xcubtueRoZMVPpSScv0fQtjI= -github.com/hashicorp/hcl-lang v0.0.0-20210311200725-da0537032422/go.mod h1:TUGbLnxaJsOmfcJ+hwWTQxLmZX2lZSd+uMFNNphz6hc= +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/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/refdecoder/decoder_test.go b/internal/refdecoder/decoder_test.go index 442602f7..f2a7bdb7 100644 --- a/internal/refdecoder/decoder_test.go +++ b/internal/refdecoder/decoder_test.go @@ -80,6 +80,32 @@ terraform { }, }, }, + { + "default namespace provider under different local name", + ` +terraform { + required_providers { + rand = { + source = "hashicorp/random" + version = "3.0.0" + } + } +} + +resource "random_string" "name" { + provider = rand +} +`, + addrs.ProviderReferences{ + addrs.LocalProviderConfig{ + LocalName: "rand", + }: addrs.Provider{ + Hostname: addrs.DefaultRegistryHost, + Namespace: "hashicorp", + Type: "random", + }, + }, + }, { "resource block", ` diff --git a/schema/schema_merge.go b/schema/schema_merge.go index b7e39abd..86ca0096 100644 --- a/schema/schema_merge.go +++ b/schema/schema_merge.go @@ -2,6 +2,7 @@ package schema import ( "fmt" + "strings" "github.com/hashicorp/go-version" "github.com/hashicorp/hcl-lang/lang" @@ -94,13 +95,6 @@ func (m *SchemaMerger) MergeWithJsonProviderSchemas(ps *tfjson.ProviderSchemas) localRefs := refs.LocalNamesByAddr(srcAddr) - if len(localRefs) == 0 && (srcAddr.IsBuiltIn() || srcAddr.IsLegacy() || srcAddr.IsDefault()) { - // Assume this provider does not have alias - localRefs = append(localRefs, addrs.LocalProviderConfig{ - LocalName: srcAddr.Type, - }) - } - var providerSchema *tfjson.SchemaBlock if provider.ConfigSchema != nil { providerSchema = provider.ConfigSchema.Block @@ -118,6 +112,13 @@ func (m *SchemaMerger) MergeWithJsonProviderSchemas(ps *tfjson.ProviderSchemas) }, })] = pSchema + providerAddr := lang.Address{ + lang.RootStep{Name: localRef.LocalName}, + } + if localRef.Alias != "" { + providerAddr = append(providerAddr, lang.AttrStep{Name: localRef.Alias}) + } + for rName, rJsonSchema := range provider.ResourceSchemas { rSchema := convertBodySchemaFromJson(detail, rJsonSchema.Block) @@ -125,20 +126,28 @@ func (m *SchemaMerger) MergeWithJsonProviderSchemas(ps *tfjson.ProviderSchemas) Labels: []schema.LabelDependent{ {Index: 0, Value: rName}, }, - } - if localRef.Alias != "" { - depKeys.Attributes = append(depKeys.Attributes, schema.AttributeDependent{ - Name: "provider", - Expr: schema.ExpressionValue{ - Address: lang.Address{ - lang.RootStep{Name: localRef.LocalName}, - lang.AttrStep{Name: localRef.Alias}, + Attributes: []schema.AttributeDependent{ + { + Name: "provider", + Expr: schema.ExpressionValue{ + Address: providerAddr, }, }, - }) + }, } mergedSchema.Blocks["resource"].DependentBody[schema.NewSchemaKey(depKeys)] = rSchema + + // No explicit association is required + // if the resource prefix matches provider name + if strings.HasPrefix(rName, localRef.LocalName+"_") { + depKeys := schema.DependencyKeys{ + Labels: []schema.LabelDependent{ + {Index: 0, Value: rName}, + }, + } + mergedSchema.Blocks["resource"].DependentBody[schema.NewSchemaKey(depKeys)] = rSchema + } } for dsName, dsJsonSchema := range provider.DataSourceSchemas { @@ -148,20 +157,28 @@ func (m *SchemaMerger) MergeWithJsonProviderSchemas(ps *tfjson.ProviderSchemas) Labels: []schema.LabelDependent{ {Index: 0, Value: dsName}, }, - } - if localRef.Alias != "" { - depKeys.Attributes = append(depKeys.Attributes, schema.AttributeDependent{ - Name: "provider", - Expr: schema.ExpressionValue{ - Address: lang.Address{ - lang.RootStep{Name: localRef.LocalName}, - lang.AttrStep{Name: localRef.Alias}, + Attributes: []schema.AttributeDependent{ + { + Name: "provider", + Expr: schema.ExpressionValue{ + Address: providerAddr, }, }, - }) + }, } mergedSchema.Blocks["data"].DependentBody[schema.NewSchemaKey(depKeys)] = dsSchema + + // No explicit association is required + // if the resource prefix matches provider name + if strings.HasPrefix(dsName, localRef.LocalName+"_") { + depKeys := schema.DependencyKeys{ + Labels: []schema.LabelDependent{ + {Index: 0, Value: dsName}, + }, + } + mergedSchema.Blocks["data"].DependentBody[schema.NewSchemaKey(depKeys)] = dsSchema + } } } } diff --git a/schema/schema_merge_test.go b/schema/schema_merge_test.go index 1a5922cf..75dc0be5 100644 --- a/schema/schema_merge_test.go +++ b/schema/schema_merge_test.go @@ -29,6 +29,42 @@ func TestMergeWithJsonProviderSchemas_noCoreSchema(t *testing.T) { } func TestMergeWithJsonProviderSchemas_noProviderSchema(t *testing.T) { + 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) _, err := sm.MergeWithJsonProviderSchemas(nil) @@ -57,6 +93,42 @@ func TestMergeWithJsonProviderSchemas_v012(t *testing.T) { 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, @@ -96,6 +168,42 @@ func TestMergeWithJsonProviderSchemas_v013(t *testing.T) { 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, @@ -114,40 +222,3 @@ func TestMergeWithJsonProviderSchemas_v013(t *testing.T) { t.Fatalf("schema differs: %s", diff) } } - -var 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}, - }, - }, - }, - }, -} diff --git a/schema/schema_merge_v012_test.go b/schema/schema_merge_v012_test.go index 28820038..80bec82e 100644 --- a/schema/schema_merge_v012_test.go +++ b/schema/schema_merge_v012_test.go @@ -69,6 +69,21 @@ var expectedMergedSchema_v012 = &schema.BodySchema{ }, }, }, + `{"labels":[{"index":0,"value":"null_resource"}],"attrs":[{"name":"provider","expr":{"addr":"null"}}]}`: { + Detail: "hashicorp/null", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "triggers": { + Description: lang.MarkupContent{ + Value: "A map of arbitrary strings that, when changed, will force the null resource to be replaced, re-running any associated provisioners.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + IsOptional: true, + }, + }, + }, `{"labels":[{"index":0,"value":"null_resource"}],"attrs":[{"name":"provider","expr":{"addr":"null.foobar"}}]}`: { Detail: "hashicorp/null", Blocks: map[string]*schema.BlockSchema{}, @@ -509,6 +524,431 @@ var expectedMergedSchema_v012 = &schema.BodySchema{ }, }, }, + `{"labels":[{"index":0,"value":"random_id"}],"attrs":[{"name":"provider","expr":{"addr":"random"}}]}`: { + Detail: "hashicorp/random", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "b64_std": { + Description: lang.MarkupContent{ + Value: "The generated id presented in base64 without additional transformations.", + Kind: lang.PlainTextKind, + }, + IsComputed: true, + Expr: schema.LiteralTypeOnly(cty.String), + }, + "b64_url": { + Description: lang.MarkupContent{ + Value: "The generated id presented in base64, using the URL-friendly character set: case-sensitive letters, digits and the characters `_` and `-`.", + Kind: lang.PlainTextKind, + }, + IsComputed: true, + Expr: schema.LiteralTypeOnly(cty.String), + }, + "byte_length": { + Description: lang.MarkupContent{ + Value: "The number of random bytes to produce. The minimum value is 1, which produces eight bits of randomness.", + Kind: lang.PlainTextKind, + }, + IsRequired: true, + Expr: schema.LiteralTypeOnly(cty.Number), + }, + "dec": { + Description: lang.MarkupContent{ + Value: "The generated id presented in non-padded decimal digits.", + Kind: lang.PlainTextKind, + }, + IsComputed: true, + Expr: schema.LiteralTypeOnly(cty.String), + }, + "hex": { + Description: lang.MarkupContent{ + Value: "The generated id presented in padded hexadecimal digits. This result will always be twice as long as the requested byte length.", + Kind: lang.PlainTextKind, + }, + IsComputed: true, + Expr: schema.LiteralTypeOnly(cty.String), + }, + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "keepers": { + Description: lang.MarkupContent{ + Value: "Arbitrary map of values that, when changed, will trigger recreation of resource. See [the main provider documentation](../index.html) for more information.", + Kind: lang.PlainTextKind, + }, + IsOptional: true, + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + }, + "prefix": { + Description: lang.MarkupContent{ + Value: "Arbitrary string to prefix the output value with. This string is supplied as-is, meaning it is not guaranteed to be URL-safe or base64 encoded.", + Kind: lang.PlainTextKind, + }, + IsOptional: true, + Expr: schema.LiteralTypeOnly(cty.String), + }, + }, + }, + `{"labels":[{"index":0,"value":"random_integer"}],"attrs":[{"name":"provider","expr":{"addr":"random"}}]}`: { + Detail: "hashicorp/random", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "keepers": { + Description: lang.MarkupContent{ + Value: "Arbitrary map of values that, when changed, will trigger recreation of resource. See [the main provider documentation](../index.html) for more information.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + IsOptional: true, + }, + "max": { + Description: lang.MarkupContent{ + Value: "The maximum inclusive value of the range.", + Kind: lang.PlainTextKind, + }, + IsRequired: true, + Expr: schema.LiteralTypeOnly(cty.Number), + }, + "min": { + Description: lang.MarkupContent{ + Value: "The minimum inclusive value of the range.", + Kind: lang.PlainTextKind, + }, + IsRequired: true, + Expr: schema.LiteralTypeOnly(cty.Number), + }, + "result": { + Description: lang.MarkupContent{ + Value: "The random integer result.", + Kind: lang.PlainTextKind, + }, + IsComputed: true, + Expr: schema.LiteralTypeOnly(cty.Number), + }, + "seed": { + Description: lang.MarkupContent{ + Value: "A custom seed to always produce the same value.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.String), + IsOptional: true, + }, + }, + }, + `{"labels":[{"index":0,"value":"random_password"}],"attrs":[{"name":"provider","expr":{"addr":"random"}}]}`: { + Detail: "hashicorp/random", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "keepers": { + Description: lang.MarkupContent{ + Value: "Arbitrary map of values that, when changed, will trigger recreation of resource. See [the main provider documentation](../index.html) for more information.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + IsOptional: true, + }, + "length": { + Description: lang.MarkupContent{ + Value: "The length of the string desired.", + Kind: lang.PlainTextKind, + }, + IsRequired: true, + Expr: schema.LiteralTypeOnly(cty.Number), + }, + "lower": { + Description: lang.MarkupContent{ + Value: "Include lowercase alphabet characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Bool), + IsOptional: true, + }, + "min_lower": { + Description: lang.MarkupContent{ + Value: "Minimum number of lowercase alphabet characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Number), + IsOptional: true, + }, + "min_numeric": { + Description: lang.MarkupContent{ + Value: "Minimum number of numeric characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Number), + IsOptional: true, + }, + "min_special": { + Description: lang.MarkupContent{ + Value: "Minimum number of special characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Number), + IsOptional: true, + }, + "min_upper": { + Description: lang.MarkupContent{ + Value: "Minimum number of uppercase alphabet characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Number), + IsOptional: true, + }, + "number": { + Description: lang.MarkupContent{ + Value: "Include numeric characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Bool), + IsOptional: true, + }, + "override_special": { + Description: lang.MarkupContent{ + Value: "Supply your own list of special characters to use for string generation. This overrides the default character list in the special argument. The `special` argument must still be set to true for any overwritten characters to be used in generation.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.String), + IsOptional: true, + }, + "result": { + Description: lang.MarkupContent{ + Value: "The generated random string.", + Kind: lang.PlainTextKind, + }, + IsComputed: true, + Expr: schema.LiteralTypeOnly(cty.String), + }, + "special": { + Description: lang.MarkupContent{ + Value: "Include special characters in the result. These are `!@#$%&*()-_=+[]{}<>:?`", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Bool), + IsOptional: true, + }, + "upper": { + Description: lang.MarkupContent{ + Value: "Include uppercase alphabet characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Bool), + IsOptional: true, + }, + }, + }, + `{"labels":[{"index":0,"value":"random_pet"}],"attrs":[{"name":"provider","expr":{"addr":"random"}}]}`: { + Detail: "hashicorp/random", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "keepers": { + Description: lang.MarkupContent{ + Value: "Arbitrary map of values that, when changed, will trigger recreation of resource. See [the main provider documentation](../index.html) for more information.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + IsOptional: true, + }, + "length": { + Description: lang.MarkupContent{ + Value: "The length (in words) of the pet name.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Number), + IsOptional: true, + }, + "prefix": { + Description: lang.MarkupContent{ + Value: "A string to prefix the name with.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.String), + IsOptional: true, + }, + "separator": { + Description: lang.MarkupContent{ + Value: "The character to separate words in the pet name.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.String), + IsOptional: true, + }, + }, + }, + `{"labels":[{"index":0,"value":"random_shuffle"}],"attrs":[{"name":"provider","expr":{"addr":"random"}}]}`: { + Detail: "hashicorp/random", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "input": { + Description: lang.MarkupContent{ + Value: "The list of strings to shuffle.", + Kind: lang.PlainTextKind, + }, + IsRequired: true, + Expr: schema.LiteralTypeOnly(cty.List(cty.String)), + }, + "keepers": { + Description: lang.MarkupContent{ + Value: "Arbitrary map of values that, when changed, will trigger recreation of resource. See [the main provider documentation](../index.html) for more information.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + IsOptional: true, + }, + "result": { + Description: lang.MarkupContent{ + Value: "Random permutation of the list of strings given in `input`.", + Kind: lang.PlainTextKind, + }, + IsComputed: true, + Expr: schema.LiteralTypeOnly(cty.List(cty.String)), + }, + "result_count": { + Description: lang.MarkupContent{ + Value: "The number of results to return. Defaults to the number of items in the `input` list. If fewer items are requested, some elements will be excluded from the result. If more items are requested, items will be repeated in the result but not more frequently than the number of items in the input list.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Number), + IsOptional: true, + }, + "seed": { + Description: lang.MarkupContent{ + Value: "Arbitrary string with which to seed the random number generator, in order to produce less-volatile permutations of the list.\n\n**Important:** Even with an identical seed, it is not guaranteed that the same permutation will be produced across different versions of Terraform. This argument causes the result to be *less volatile*, but not fixed for all time.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.String), + IsOptional: true, + }, + }, + }, + `{"labels":[{"index":0,"value":"random_string"}],"attrs":[{"name":"provider","expr":{"addr":"random"}}]}`: { + Detail: "hashicorp/random", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "keepers": { + Description: lang.MarkupContent{ + Value: "Arbitrary map of values that, when changed, will trigger recreation of resource. See [the main provider documentation](../index.html) for more information.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + IsOptional: true, + }, + "length": { + Description: lang.MarkupContent{ + Value: "The length of the string desired.", + Kind: lang.PlainTextKind, + }, + IsRequired: true, + Expr: schema.LiteralTypeOnly(cty.Number), + }, + "lower": { + Description: lang.MarkupContent{ + Value: "Include lowercase alphabet characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Bool), + IsOptional: true, + }, + "min_lower": { + Description: lang.MarkupContent{ + Value: "Minimum number of lowercase alphabet characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Number), + IsOptional: true, + }, + "min_numeric": { + Description: lang.MarkupContent{ + Value: "Minimum number of numeric characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Number), + IsOptional: true, + }, + "min_special": { + Description: lang.MarkupContent{ + Value: "Minimum number of special characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Number), + IsOptional: true, + }, + "min_upper": { + Description: lang.MarkupContent{ + Value: "Minimum number of uppercase alphabet characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Number), + IsOptional: true, + }, + "number": { + Description: lang.MarkupContent{ + Value: "Include numeric characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Bool), + IsOptional: true, + }, + "override_special": { + Description: lang.MarkupContent{ + Value: "Supply your own list of special characters to use for string generation. This overrides the default character list in the special argument. The `special` argument must still be set to true for any overwritten characters to be used in generation.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.String), + IsOptional: true, + }, + "result": { + Description: lang.MarkupContent{ + Value: "The generated random string.", + Kind: lang.PlainTextKind, + }, + IsComputed: true, + Expr: schema.LiteralTypeOnly(cty.String), + }, + "special": { + Description: lang.MarkupContent{ + Value: "Include special characters in the result. These are `!@#$%&*()-_=+[]{}<>:?`", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Bool), + IsOptional: true, + }, + "upper": { + Description: lang.MarkupContent{ + Value: "Include uppercase alphabet characters in the result.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Bool), + IsOptional: true, + }, + }, + }, + `{"labels":[{"index":0,"value":"random_uuid"}],"attrs":[{"name":"provider","expr":{"addr":"random"}}]}`: { + Detail: "hashicorp/random", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "keepers": { + Description: lang.MarkupContent{ + Value: "Arbitrary map of values that, when changed, will trigger recreation of resource. See [the main provider documentation](../index.html) for more information.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + IsOptional: true, + }, + "result": { + Description: lang.MarkupContent{ + Value: "The generated uuid presented in string format.", + Kind: lang.PlainTextKind, + }, + IsComputed: true, + Expr: schema.LiteralTypeOnly(cty.String), + }, + }, + }, }, }, "data": { @@ -562,6 +1002,46 @@ var expectedMergedSchema_v012 = &schema.BodySchema{ }, }, }, + `{"labels":[{"index":0,"value":"null_data_source"}],"attrs":[{"name":"provider","expr":{"addr":"null"}}]}`: { + Detail: "hashicorp/null", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "has_computed_default": { + Description: lang.MarkupContent{ + Value: "If set, its literal value will be stored and returned. If not, its value defaults to `\"default\"`. This argument exists primarily for testing and has little practical use.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.String), + IsOptional: true, + IsComputed: true, + }, + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "inputs": { + Description: lang.MarkupContent{ + Value: "A map of arbitrary strings that is copied into the `outputs` attribute, and accessible directly for interpolation.", + Kind: lang.PlainTextKind, + }, + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + IsOptional: true, + }, + "outputs": { + Description: lang.MarkupContent{ + Value: "After the data source is \"read\", a copy of the `inputs` map.", + Kind: lang.PlainTextKind, + }, + IsComputed: true, + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + }, + "random": { + Description: lang.MarkupContent{ + Value: "A random value. This is primarily for testing and has little practical use; prefer the [random provider](https://www.terraform.io/docs/providers/random/) for more practical random number use-cases.", + Kind: lang.PlainTextKind, + }, + IsComputed: true, + Expr: schema.LiteralTypeOnly(cty.String), + }, + }, + }, `{"labels":[{"index":0,"value":"null_data_source"}],"attrs":[{"name":"provider","expr":{"addr":"null.foobar"}}]}`: { Detail: "hashicorp/null", Blocks: map[string]*schema.BlockSchema{}, @@ -613,6 +1093,17 @@ var expectedMergedSchema_v012 = &schema.BodySchema{ "workspace": {IsOptional: true, Expr: schema.LiteralTypeOnly(cty.String)}, }, }, + `{"labels":[{"index":0,"value":"terraform_remote_state"}],"attrs":[{"name":"provider","expr":{"addr":"terraform"}}]}`: { + Detail: "(builtin)", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "backend": {IsRequired: true, Expr: schema.LiteralTypeOnly(cty.String)}, + "config": {IsOptional: true, Expr: schema.LiteralTypeOnly(cty.DynamicPseudoType)}, + "defaults": {IsOptional: true, Expr: schema.LiteralTypeOnly(cty.DynamicPseudoType)}, + "outputs": {IsComputed: true, Expr: schema.LiteralTypeOnly(cty.DynamicPseudoType)}, + "workspace": {IsOptional: true, Expr: schema.LiteralTypeOnly(cty.String)}, + }, + }, }, }, }, diff --git a/schema/schema_merge_v013_test.go b/schema/schema_merge_v013_test.go index bdf64e9d..75248fad 100644 --- a/schema/schema_merge_v013_test.go +++ b/schema/schema_merge_v013_test.go @@ -53,7 +53,7 @@ var expectedMergedSchema_v013 = &schema.BodySchema{ Blocks: map[string]*schema.BlockSchema{}, Attributes: map[string]*schema.AttributeSchema{}, }, - `{"labels":[{"index":0,"value":"random"}]}`: { + `{"labels":[{"index":0,"value":"rand"}]}`: { Detail: "hashicorp/random", DocsLink: &schema.DocsLink{ URL: "https://registry.terraform.io/providers/hashicorp/random/latest/docs", @@ -234,6 +234,160 @@ var expectedMergedSchema_v013 = &schema.BodySchema{ "password": {IsRequired: true, Expr: schema.LiteralTypeOnly(cty.String)}, }, }, + `{"labels":[{"index":0,"value":"grafana_alert_notification"}],"attrs":[{"name":"provider","expr":{"addr":"grafana"}}]}`: { + Detail: "grafana/grafana", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "frequency": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsComputed: true, IsOptional: true}, + "is_default": {Expr: schema.LiteralTypeOnly(cty.Bool), IsOptional: true}, + "name": {IsRequired: true, Expr: schema.LiteralTypeOnly(cty.String)}, + "send_reminder": {Expr: schema.LiteralTypeOnly(cty.Bool), IsOptional: true}, + "settings": { + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + IsOptional: true, + }, + "type": {IsRequired: true, Expr: schema.LiteralTypeOnly(cty.String)}, + "uid": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + }, + }, + `{"labels":[{"index":0,"value":"grafana_dashboard"}],"attrs":[{"name":"provider","expr":{"addr":"grafana"}}]}`: { + Detail: "grafana/grafana", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "config_json": {IsRequired: true, Expr: schema.LiteralTypeOnly(cty.String)}, + "folder": {Expr: schema.LiteralTypeOnly(cty.Number), IsOptional: true}, + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "slug": {IsComputed: true, Expr: schema.LiteralTypeOnly(cty.String)}, + }, + }, + `{"labels":[{"index":0,"value":"grafana_data_source"}],"attrs":[{"name":"provider","expr":{"addr":"grafana"}}]}`: { + Detail: "grafana/grafana", + Blocks: map[string]*schema.BlockSchema{ + "json_data": { + Labels: []*schema.LabelSchema{}, + Type: schema.BlockTypeList, + Body: &schema.BodySchema{ + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "assume_role_arn": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "auth_type": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "conn_max_lifetime": {Expr: schema.LiteralTypeOnly(cty.Number), IsOptional: true}, + "custom_metrics_namespaces": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "default_region": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "encrypt": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "es_version": {Expr: schema.LiteralTypeOnly(cty.Number), IsOptional: true}, + "graphite_version": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "http_method": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "interval": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "log_level_field": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "log_message_field": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "max_idle_conns": {Expr: schema.LiteralTypeOnly(cty.Number), IsOptional: true}, + "max_open_conns": {Expr: schema.LiteralTypeOnly(cty.Number), IsOptional: true}, + "postgres_version": {Expr: schema.LiteralTypeOnly(cty.Number), IsOptional: true}, + "query_timeout": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "ssl_mode": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "time_field": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "time_interval": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "timescaledb": {Expr: schema.LiteralTypeOnly(cty.Bool), IsOptional: true}, + "tls_auth": {Expr: schema.LiteralTypeOnly(cty.Bool), IsOptional: true}, + "tls_auth_with_ca_cert": {Expr: schema.LiteralTypeOnly(cty.Bool), IsOptional: true}, + "tls_skip_verify": {Expr: schema.LiteralTypeOnly(cty.Bool), IsOptional: true}, + "tsdb_resolution": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "tsdb_version": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + }, + }, + }, + "secure_json_data": { + Labels: []*schema.LabelSchema{}, + Type: schema.BlockTypeList, + Body: &schema.BodySchema{ + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "access_key": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "basic_auth_password": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "password": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "private_key": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "secret_key": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "tls_ca_cert": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "tls_client_cert": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "tls_client_key": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + }, + }, + }, + }, + Attributes: map[string]*schema.AttributeSchema{ + "access_mode": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "basic_auth_enabled": {Expr: schema.LiteralTypeOnly(cty.Bool), IsOptional: true}, + "basic_auth_password": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "basic_auth_username": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "database_name": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "is_default": {Expr: schema.LiteralTypeOnly(cty.Bool), IsOptional: true}, + "name": {IsRequired: true, Expr: schema.LiteralTypeOnly(cty.String)}, + "password": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "type": {IsRequired: true, Expr: schema.LiteralTypeOnly(cty.String)}, + "url": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "username": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + }, + }, + `{"labels":[{"index":0,"value":"grafana_folder"}],"attrs":[{"name":"provider","expr":{"addr":"grafana"}}]}`: { + Detail: "grafana/grafana", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsComputed: true, IsOptional: true}, + "title": {IsRequired: true, Expr: schema.LiteralTypeOnly(cty.String)}, + "uid": {IsComputed: true, Expr: schema.LiteralTypeOnly(cty.String)}, + }, + }, + `{"labels":[{"index":0,"value":"grafana_organization"}],"attrs":[{"name":"provider","expr":{"addr":"grafana"}}]}`: { + Detail: "grafana/grafana", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "admin_user": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "admins": { + Expr: schema.LiteralTypeOnly(cty.List(cty.String)), + IsOptional: true, + }, + "create_users": {Expr: schema.LiteralTypeOnly(cty.Bool), IsOptional: true}, + "editors": { + Expr: schema.LiteralTypeOnly(cty.List(cty.String)), + IsOptional: true, + }, + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "name": {IsRequired: true, Expr: schema.LiteralTypeOnly(cty.String)}, + "org_id": {IsComputed: true, Expr: schema.LiteralTypeOnly(cty.Number)}, + "viewers": { + Expr: schema.LiteralTypeOnly(cty.List(cty.String)), + IsOptional: true, + }, + }, + }, + `{"labels":[{"index":0,"value":"grafana_team"}],"attrs":[{"name":"provider","expr":{"addr":"grafana"}}]}`: { + Detail: "grafana/grafana", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "email": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "members": { + Expr: schema.LiteralTypeOnly(cty.List(cty.String)), + IsOptional: true, + }, + "name": {IsRequired: true, Expr: schema.LiteralTypeOnly(cty.String)}, + "team_id": {IsComputed: true, Expr: schema.LiteralTypeOnly(cty.Number)}, + }, + }, + `{"labels":[{"index":0,"value":"grafana_user"}],"attrs":[{"name":"provider","expr":{"addr":"grafana"}}]}`: { + Detail: "grafana/grafana", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "email": {IsRequired: true, Expr: schema.LiteralTypeOnly(cty.String)}, + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "login": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "name": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true}, + "password": {IsRequired: true, Expr: schema.LiteralTypeOnly(cty.String)}, + }, + }, `{"labels":[{"index":0,"value":"null_resource"}]}`: { Detail: "hashicorp/null", Blocks: map[string]*schema.BlockSchema{}, @@ -253,6 +407,25 @@ var expectedMergedSchema_v013 = &schema.BodySchema{ Kind: lang.MarkdownKind, }, }, + `{"labels":[{"index":0,"value":"null_resource"}],"attrs":[{"name":"provider","expr":{"addr":"null"}}]}`: { + Detail: "hashicorp/null", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsOptional: true, IsComputed: true}, + "triggers": { + Description: lang.MarkupContent{ + Value: "A map of arbitrary strings that, when changed, will force the null resource to be replaced, re-running any associated provisioners.", + Kind: lang.MarkdownKind, + }, + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + IsOptional: true, + }, + }, + Description: lang.MarkupContent{ + Value: "The `null_resource` resource implements the standard resource lifecycle but takes no further action.\n\nThe `triggers` argument allows specifying an arbitrary set of values that, when changed, will cause the resource to be replaced.", + Kind: lang.MarkdownKind, + }, + }, `{"labels":[{"index":0,"value":"null_resource"}],"attrs":[{"name":"provider","expr":{"addr":"null.foobar"}}]}`: { Detail: "hashicorp/null", Blocks: map[string]*schema.BlockSchema{}, @@ -272,7 +445,7 @@ var expectedMergedSchema_v013 = &schema.BodySchema{ Kind: lang.MarkdownKind, }, }, - `{"labels":[{"index":0,"value":"random_id"}]}`: { + `{"labels":[{"index":0,"value":"random_id"}],"attrs":[{"name":"provider","expr":{"addr":"rand"}}]}`: { Detail: "hashicorp/random", Blocks: map[string]*schema.BlockSchema{}, Attributes: map[string]*schema.AttributeSchema{ @@ -339,7 +512,7 @@ var expectedMergedSchema_v013 = &schema.BodySchema{ Kind: lang.MarkdownKind, }, }, - `{"labels":[{"index":0,"value":"random_integer"}]}`: { + `{"labels":[{"index":0,"value":"random_integer"}],"attrs":[{"name":"provider","expr":{"addr":"rand"}}]}`: { Detail: "hashicorp/random", Blocks: map[string]*schema.BlockSchema{}, Attributes: map[string]*schema.AttributeSchema{ @@ -390,7 +563,7 @@ var expectedMergedSchema_v013 = &schema.BodySchema{ Kind: lang.MarkdownKind, }, }, - `{"labels":[{"index":0,"value":"random_password"}]}`: { + `{"labels":[{"index":0,"value":"random_password"}],"attrs":[{"name":"provider","expr":{"addr":"rand"}}]}`: { Detail: "hashicorp/random", Blocks: map[string]*schema.BlockSchema{}, Attributes: map[string]*schema.AttributeSchema{ @@ -497,7 +670,7 @@ var expectedMergedSchema_v013 = &schema.BodySchema{ Kind: lang.MarkdownKind, }, }, - `{"labels":[{"index":0,"value":"random_pet"}]}`: { + `{"labels":[{"index":0,"value":"random_pet"}],"attrs":[{"name":"provider","expr":{"addr":"rand"}}]}`: { Detail: "hashicorp/random", Blocks: map[string]*schema.BlockSchema{}, Attributes: map[string]*schema.AttributeSchema{ @@ -540,7 +713,7 @@ var expectedMergedSchema_v013 = &schema.BodySchema{ Kind: lang.MarkdownKind, }, }, - `{"labels":[{"index":0,"value":"random_shuffle"}]}`: { + `{"labels":[{"index":0,"value":"random_shuffle"}],"attrs":[{"name":"provider","expr":{"addr":"rand"}}]}`: { Detail: "hashicorp/random", Blocks: map[string]*schema.BlockSchema{}, Attributes: map[string]*schema.AttributeSchema{ @@ -591,7 +764,7 @@ var expectedMergedSchema_v013 = &schema.BodySchema{ Kind: lang.MarkdownKind, }, }, - `{"labels":[{"index":0,"value":"random_string"}]}`: { + `{"labels":[{"index":0,"value":"random_string"}],"attrs":[{"name":"provider","expr":{"addr":"rand"}}]}`: { Detail: "hashicorp/random", Blocks: map[string]*schema.BlockSchema{}, Attributes: map[string]*schema.AttributeSchema{ @@ -698,7 +871,7 @@ var expectedMergedSchema_v013 = &schema.BodySchema{ Kind: lang.MarkdownKind, }, }, - `{"labels":[{"index":0,"value":"random_uuid"}]}`: { + `{"labels":[{"index":0,"value":"random_uuid"}],"attrs":[{"name":"provider","expr":{"addr":"rand"}}]}`: { Detail: "hashicorp/random", Blocks: map[string]*schema.BlockSchema{}, Attributes: map[string]*schema.AttributeSchema{ @@ -782,6 +955,50 @@ var expectedMergedSchema_v013 = &schema.BodySchema{ Kind: lang.MarkdownKind, }, }, + `{"labels":[{"index":0,"value":"null_data_source"}],"attrs":[{"name":"provider","expr":{"addr":"null"}}]}`: { + Detail: "hashicorp/null", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "has_computed_default": { + Description: lang.MarkupContent{ + Value: "If set, its literal value will be stored and returned. If not, its value defaults to `\"default\"`. This argument exists primarily for testing and has little practical use.", + Kind: lang.MarkdownKind, + }, + Expr: schema.LiteralTypeOnly(cty.String), + IsOptional: true, + IsComputed: true, + }, + "id": {Expr: schema.LiteralTypeOnly(cty.String), IsComputed: true, IsOptional: true}, + "inputs": { + Description: lang.MarkupContent{ + Value: "A map of arbitrary strings that is copied into the `outputs` attribute, and accessible directly for interpolation.", + Kind: lang.MarkdownKind, + }, + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + IsOptional: true, + }, + "outputs": { + Description: lang.MarkupContent{ + Value: "After the data source is \"read\", a copy of the `inputs` map.", + Kind: lang.MarkdownKind, + }, + IsComputed: true, + Expr: schema.LiteralTypeOnly(cty.Map(cty.String)), + }, + "random": { + Description: lang.MarkupContent{ + Value: "A random value. This is primarily for testing and has little practical use; prefer the [random provider](https://www.terraform.io/docs/providers/random/) for more practical random number use-cases.", + Kind: lang.MarkdownKind, + }, + IsComputed: true, + Expr: schema.LiteralTypeOnly(cty.String), + }, + }, + Description: lang.MarkupContent{ + Value: "The `null_data_source` data source implements the standard data source lifecycle but does not interact with any external APIs.", + Kind: lang.MarkdownKind, + }, + }, `{"labels":[{"index":0,"value":"null_data_source"}],"attrs":[{"name":"provider","expr":{"addr":"null.foobar"}}]}`: { Detail: "hashicorp/null", Blocks: map[string]*schema.BlockSchema{}, @@ -837,6 +1054,17 @@ var expectedMergedSchema_v013 = &schema.BodySchema{ "workspace": {IsOptional: true, Expr: schema.LiteralTypeOnly(cty.String)}, }, }, + `{"labels":[{"index":0,"value":"terraform_remote_state"}],"attrs":[{"name":"provider","expr":{"addr":"terraform"}}]}`: { + Detail: "(builtin)", + Blocks: map[string]*schema.BlockSchema{}, + Attributes: map[string]*schema.AttributeSchema{ + "backend": {IsRequired: true, Expr: schema.LiteralTypeOnly(cty.String)}, + "config": {IsOptional: true, Expr: schema.LiteralTypeOnly(cty.DynamicPseudoType)}, + "defaults": {IsOptional: true, Expr: schema.LiteralTypeOnly(cty.DynamicPseudoType)}, + "outputs": {IsComputed: true, Expr: schema.LiteralTypeOnly(cty.DynamicPseudoType)}, + "workspace": {IsOptional: true, Expr: schema.LiteralTypeOnly(cty.String)}, + }, + }, }, }, }, diff --git a/schema/testdata/test-config-0.13.tf b/schema/testdata/test-config-0.13.tf index cc8fcda4..92a45646 100644 --- a/schema/testdata/test-config-0.13.tf +++ b/schema/testdata/test-config-0.13.tf @@ -2,16 +2,16 @@ # with v0.13 generates relevant JSON file terraform { required_providers { - random = { - source = "hashicorp/random" + rand = { + source = "hashicorp/random" version = "3.0.0" } null = { - source = "hashicorp/null" + source = "hashicorp/null" version = "3.0.0" } grafana = { - source = "grafana/grafana" + source = "grafana/grafana" version = "1.6.0" } } @@ -22,7 +22,7 @@ provider "null" { } resource "random_string" "name" { - + provider = rand } resource "null_resource" "name" {