Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions internal/command/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,9 @@ func queryFixtureProvider() *testing_provider.MockProvider {
},
},
},
Nesting: configschema.NestingSingle,
Nesting: configschema.NestingSingle,
MinItems: 1,
MaxItems: 1,
},
},
}
Expand All @@ -306,7 +308,9 @@ func queryFixtureProvider() *testing_provider.MockProvider {
},
},
},
Nesting: configschema.NestingSingle,
Nesting: configschema.NestingSingle,
MinItems: 1,
MaxItems: 1,
},
},
}
Expand Down Expand Up @@ -371,15 +375,13 @@ func queryFixtureProvider() *testing_provider.MockProvider {
// Check the config to determine what kind of response to return
wholeConfigMap := request.Config.AsValueMap()

configMap := wholeConfigMap["config"]

// For empty results test case
ami, ok := configMap.AsValueMap()["ami"]
ami, ok := wholeConfigMap["ami"]
if ok && ami.AsString() == "ami-nonexistent" {
return providers.ListResourceResponse{
Result: cty.ObjectVal(map[string]cty.Value{
"data": cty.ListValEmpty(cty.DynamicPseudoType),
"config": configMap,
"config": request.Config,
}),
}
}
Expand Down Expand Up @@ -410,7 +412,7 @@ func queryFixtureProvider() *testing_provider.MockProvider {
"display_name": cty.StringVal("Test Instance 2"),
}),
}),
"config": configMap,
"config": request.Config,
}),
}
case "test_database":
Expand All @@ -428,14 +430,14 @@ func queryFixtureProvider() *testing_provider.MockProvider {
"display_name": cty.StringVal("Test Database 1"),
}),
}),
"config": configMap,
"config": request.Config,
}),
}
default:
return providers.ListResourceResponse{
Result: cty.ObjectVal(map[string]cty.Value{
"data": cty.ListVal([]cty.Value{}),
"config": configMap,
"config": request.Config,
}),
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/command/views/query_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (v *QueryOperationHuman) Plan(plan *plans.Plan, schemas *terraform.Schemas)
for _, query := range plan.Changes.Queries {
pSchema := schemas.ProviderSchema(query.ProviderAddr.Provider)
addr := query.Addr
schema := pSchema.ListResourceTypes[addr.Resource.Resource.Type]
schema := pSchema.SchemaForListResourceType(addr.Resource.Resource.Type)

results, err := query.Decode(schema)
if err != nil {
Expand Down
5 changes: 2 additions & 3 deletions internal/configs/query_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,10 @@ func decodeQueryListBlock(block *hcl.Block) (*Resource, hcl.Diagnostics) {
})
diags = append(diags, contentDiags...)

var configBlock hcl.Body
for _, block := range content.Blocks {
switch block.Type {
case "config":
if configBlock != nil {
if r.List.Config != nil {
diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Duplicate config block",
Expand All @@ -180,7 +179,7 @@ func decodeQueryListBlock(block *hcl.Block) (*Resource, hcl.Diagnostics) {
})
continue
}
configBlock = block.Body
r.List.Config = block.Body
default:
// Should not get here because the above should cover all
// block types declared in the schema.
Expand Down
3 changes: 3 additions & 0 deletions internal/configs/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ type ManagedResource struct {
}

type ListResource struct {
// Config is the "config" block from the list resource configuration.
Config hcl.Body

// By default, the results of a list resource only include the identities of
// the discovered resources. If the user specifies "include_resources = true",
// then the provider should include the resource data in the result.
Expand Down
8 changes: 4 additions & 4 deletions internal/plans/changes.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ func (c *Changes) Encode(schemas *schemarepo.Schemas) (*ChangesSrc, error) {
return changesSrc, fmt.Errorf("Changes.Encode: missing provider %s for %s", qi.ProviderAddr, qi.Addr)
}

schema := p.ListResourceTypes[qi.Addr.Resource.Resource.Type]
if schema.Body == nil {
schema := p.SchemaForListResourceType(qi.Addr.Resource.Resource.Type)
if schema.IsNil() {
return changesSrc, fmt.Errorf("Changes.Encode: missing schema for %s", qi.Addr)
}
rcs, err := qi.Encode(schema)
Expand Down Expand Up @@ -308,8 +308,8 @@ func (qi *QueryInstance) DeepCopy() *QueryInstance {
return &ret
}

func (rc *QueryInstance) Encode(schema providers.Schema) (*QueryInstanceSrc, error) {
results, err := NewDynamicValue(rc.Results.Value, schema.Body.ImpliedType())
func (rc *QueryInstance) Encode(schema providers.ListResourceSchema) (*QueryInstanceSrc, error) {
results, err := NewDynamicValue(rc.Results.Value, schema.FullSchema.ImpliedType())
if err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions internal/plans/changes_src.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ func (c *ChangesSrc) Decode(schemas *schemarepo.Schemas) (*Changes, error) {
if !ok {
return nil, fmt.Errorf("ChangesSrc.Decode: missing provider %s for %s", qis.ProviderAddr, qis.Addr)
}
schema := p.ListResourceTypes[qis.Addr.Resource.Resource.Type]
schema := p.SchemaForListResourceType(qis.Addr.Resource.Resource.Type)

if schema.Body == nil {
if schema.IsNil() {
return nil, fmt.Errorf("ChangesSrc.Decode: missing schema for %s", qis.Addr)
}

Expand Down Expand Up @@ -210,8 +210,8 @@ type QueryInstanceSrc struct {
Generated genconfig.ImportGroup
}

func (qis *QueryInstanceSrc) Decode(schema providers.Schema) (*QueryInstance, error) {
query, err := qis.Results.Decode(schema.Body.ImpliedType())
func (qis *QueryInstanceSrc) Decode(schema providers.ListResourceSchema) (*QueryInstance, error) {
query, err := qis.Results.Decode(schema.FullSchema.ImpliedType())
if err != nil {
return nil, err
}
Expand Down
40 changes: 40 additions & 0 deletions internal/plugin/convert/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/hashicorp/terraform/internal/configs/configschema"
"github.com/hashicorp/terraform/internal/providers"
proto "github.com/hashicorp/terraform/internal/tfplugin5"
"github.com/zclconf/go-cty/cty"
)

// ConfigSchemaToProto takes a *configschema.Block and converts it to a
Expand Down Expand Up @@ -111,6 +112,45 @@ func ProtoToActionSchema(s *proto.ActionSchema) providers.ActionSchema {
}
}

func ProtoToListSchema(s *proto.Schema) providers.Schema {
listSchema := ProtoToProviderSchema(s, nil)
itemCount := 0
// check if the provider has set some attributes/blocks as required.
// When yes, then we set minItem = 1, which
// validates that the configuration contains a "config" block.
for _, attrS := range listSchema.Body.Attributes {
if attrS.Required {
itemCount = 1
break
}
}
for _, block := range listSchema.Body.BlockTypes {
if block.MinItems > 0 {
itemCount = 1
break
}
}
return providers.Schema{
Version: s.Version,
Body: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"data": {
Type: cty.DynamicPseudoType,
Computed: true,
},
},
BlockTypes: map[string]*configschema.NestedBlock{
"config": {
Block: *listSchema.Body,
Nesting: configschema.NestingSingle,
MinItems: itemCount,
MaxItems: itemCount,
},
},
},
}
}

// ProtoToConfigSchema takes the GetSchcema_Block from a grpc response and converts it
// to a terraform *configschema.Block.
func ProtoToConfigSchema(b *proto.Schema_Block) *configschema.Block {
Expand Down
50 changes: 11 additions & 39 deletions internal/plugin/grpc_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"google.golang.org/grpc/status"

"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/configs/configschema"
"github.com/hashicorp/terraform/internal/logging"
"github.com/hashicorp/terraform/internal/plugin/convert"
"github.com/hashicorp/terraform/internal/providers"
Expand Down Expand Up @@ -171,24 +170,7 @@ func (p *GRPCProvider) GetProviderSchema() providers.GetProviderSchemaResponse {
}

for name, list := range protoResp.ListResourceSchemas {
ret := convert.ProtoToProviderSchema(list, nil)
resp.ListResourceTypes[name] = providers.Schema{
Version: ret.Version,
Body: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"data": {
Type: cty.DynamicPseudoType,
Computed: true,
},
},
BlockTypes: map[string]*configschema.NestedBlock{
"config": {
Block: *ret.Body,
Nesting: configschema.NestingSingle,
},
},
},
}
resp.ListResourceTypes[name] = convert.ProtoToListSchema(list)
}

for name, action := range protoResp.ActionSchemas {
Expand Down Expand Up @@ -374,18 +356,13 @@ func (p *GRPCProvider) ValidateListResourceConfig(r providers.ValidateListResour
return resp
}

listResourceSchema, ok := schema.ListResourceTypes[r.TypeName]
if !ok {
listResourceSchema := schema.SchemaForListResourceType(r.TypeName)
if listResourceSchema.IsNil() {
resp.Diagnostics = resp.Diagnostics.Append(fmt.Errorf("unknown list resource type %q", r.TypeName))
return resp
}

configSchema := listResourceSchema.Body.BlockTypes["config"]
config := cty.NullVal(configSchema.ImpliedType())
if r.Config.Type().HasAttribute("config") {
config = r.Config.GetAttr("config")
}
mp, err := msgpack.Marshal(config, configSchema.ImpliedType())
mp, err := msgpack.Marshal(r.Config, listResourceSchema.ConfigSchema.ImpliedType())
if err != nil {
resp.Diagnostics = resp.Diagnostics.Append(err)
return resp
Expand Down Expand Up @@ -1329,24 +1306,19 @@ func (p *GRPCProvider) ListResource(r providers.ListResourceRequest) providers.L
return resp
}

listResourceSchema, ok := schema.ListResourceTypes[r.TypeName]
if !ok {
resp.Diagnostics = resp.Diagnostics.Append(fmt.Errorf("unknown list resource type %q", r.TypeName))
return resp
}

resourceSchema, ok := schema.ResourceTypes[r.TypeName]
if !ok || resourceSchema.Identity == nil {
resp.Diagnostics = resp.Diagnostics.Append(fmt.Errorf("identity schema not found for resource type %s", r.TypeName))
return resp
}

configSchema := listResourceSchema.Body.BlockTypes["config"]
config := cty.NullVal(configSchema.ImpliedType())
if r.Config.Type().HasAttribute("config") {
config = r.Config.GetAttr("config")
listResourceSchema := schema.SchemaForListResourceType(r.TypeName)
if listResourceSchema.IsNil() {
resp.Diagnostics = resp.Diagnostics.Append(fmt.Errorf("unknown list resource type %q", r.TypeName))
return resp
}
mp, err := msgpack.Marshal(config, configSchema.ImpliedType())

mp, err := msgpack.Marshal(r.Config, listResourceSchema.ConfigSchema.ImpliedType())
if err != nil {
resp.Diagnostics = resp.Diagnostics.Append(err)
return resp
Expand Down Expand Up @@ -1445,7 +1417,7 @@ func (p *GRPCProvider) ListResource(r providers.ListResourceRequest) providers.L
// and the elements of the result of a list resource instance (list.aws_instance.test.data[index])
resp.Result = cty.ObjectVal(map[string]cty.Value{
"data": cty.TupleVal(results),
"config": config,
"config": r.Config,
})
return resp
}
Expand Down
Loading
Loading