Skip to content

Commit da1aba6

Browse files
committed
fwserver: add list resources to GetProviderSchema
1 parent c57458a commit da1aba6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+13223
-20
lines changed

internal/fwserver/server_getproviderschema.go

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type GetProviderSchemaResponse struct {
2525
DataSourceSchemas map[string]fwschema.Schema
2626
EphemeralResourceSchemas map[string]fwschema.Schema
2727
FunctionDefinitions map[string]function.Definition
28+
ListResourceSchemas map[string]fwschema.Schema
2829
Diagnostics diag.Diagnostics
2930
}
3031

@@ -33,62 +34,51 @@ func (s *Server) GetProviderSchema(ctx context.Context, req *GetProviderSchemaRe
3334
resp.ServerCapabilities = s.ServerCapabilities()
3435

3536
providerSchema, diags := s.ProviderSchema(ctx)
36-
3737
resp.Diagnostics.Append(diags...)
38-
3938
if diags.HasError() {
4039
return
4140
}
42-
4341
resp.Provider = providerSchema
4442

4543
providerMetaSchema, diags := s.ProviderMetaSchema(ctx)
46-
4744
resp.Diagnostics.Append(diags...)
48-
4945
if diags.HasError() {
5046
return
5147
}
52-
5348
resp.ProviderMeta = providerMetaSchema
5449

5550
resourceSchemas, diags := s.ResourceSchemas(ctx)
56-
5751
resp.Diagnostics.Append(diags...)
58-
5952
if resp.Diagnostics.HasError() {
6053
return
6154
}
62-
6355
resp.ResourceSchemas = resourceSchemas
6456

6557
dataSourceSchemas, diags := s.DataSourceSchemas(ctx)
66-
6758
resp.Diagnostics.Append(diags...)
68-
6959
if resp.Diagnostics.HasError() {
7060
return
7161
}
72-
7362
resp.DataSourceSchemas = dataSourceSchemas
7463

7564
functions, diags := s.FunctionDefinitions(ctx)
76-
7765
resp.Diagnostics.Append(diags...)
78-
7966
if resp.Diagnostics.HasError() {
8067
return
8168
}
82-
8369
resp.FunctionDefinitions = functions
8470

8571
ephemeralResourceSchemas, diags := s.EphemeralResourceSchemas(ctx)
86-
8772
resp.Diagnostics.Append(diags...)
88-
8973
if resp.Diagnostics.HasError() {
9074
return
9175
}
92-
9376
resp.EphemeralResourceSchemas = ephemeralResourceSchemas
77+
78+
listResourceSchemas, diags := s.ListResourceSchemas(ctx)
79+
resp.Diagnostics.Append(diags...)
80+
if resp.Diagnostics.HasError() {
81+
return
82+
}
83+
resp.ListResourceSchemas = listResourceSchemas
9484
}

internal/fwserver/server_getproviderschema_test.go

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import (
1818
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
1919
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
2020
"github.com/hashicorp/terraform-plugin-framework/internal/testing/testprovider"
21+
"github.com/hashicorp/terraform-plugin-framework/list"
22+
listschema "github.com/hashicorp/terraform-plugin-framework/list/schema"
2123
"github.com/hashicorp/terraform-plugin-framework/provider"
2224
"github.com/hashicorp/terraform-plugin-framework/provider/metaschema"
2325
providerschema "github.com/hashicorp/terraform-plugin-framework/provider/schema"
@@ -41,6 +43,7 @@ func TestServerGetProviderSchema(t *testing.T) {
4143
DataSourceSchemas: map[string]fwschema.Schema{},
4244
EphemeralResourceSchemas: map[string]fwschema.Schema{},
4345
FunctionDefinitions: map[string]function.Definition{},
46+
ListResourceSchemas: map[string]fwschema.Schema{},
4447
Provider: providerschema.Schema{},
4548
ResourceSchemas: map[string]fwschema.Schema{},
4649
ServerCapabilities: &fwserver.ServerCapabilities{
@@ -111,6 +114,7 @@ func TestServerGetProviderSchema(t *testing.T) {
111114
},
112115
EphemeralResourceSchemas: map[string]fwschema.Schema{},
113116
FunctionDefinitions: map[string]function.Definition{},
117+
ListResourceSchemas: map[string]fwschema.Schema{},
114118
Provider: providerschema.Schema{},
115119
ResourceSchemas: map[string]fwschema.Schema{},
116120
ServerCapabilities: &fwserver.ServerCapabilities{
@@ -318,6 +322,7 @@ func TestServerGetProviderSchema(t *testing.T) {
318322
},
319323
EphemeralResourceSchemas: map[string]fwschema.Schema{},
320324
FunctionDefinitions: map[string]function.Definition{},
325+
ListResourceSchemas: map[string]fwschema.Schema{},
321326
Provider: providerschema.Schema{},
322327
ResourceSchemas: map[string]fwschema.Schema{},
323328
ServerCapabilities: &fwserver.ServerCapabilities{
@@ -388,6 +393,7 @@ func TestServerGetProviderSchema(t *testing.T) {
388393
},
389394
},
390395
FunctionDefinitions: map[string]function.Definition{},
396+
ListResourceSchemas: map[string]fwschema.Schema{},
391397
Provider: providerschema.Schema{},
392398
ResourceSchemas: map[string]fwschema.Schema{},
393399
ServerCapabilities: &fwserver.ServerCapabilities{
@@ -601,6 +607,7 @@ func TestServerGetProviderSchema(t *testing.T) {
601607
},
602608
},
603609
FunctionDefinitions: map[string]function.Definition{},
610+
ListResourceSchemas: map[string]fwschema.Schema{},
604611
Provider: providerschema.Schema{},
605612
ResourceSchemas: map[string]fwschema.Schema{},
606613
ServerCapabilities: &fwserver.ServerCapabilities{
@@ -655,8 +662,9 @@ func TestServerGetProviderSchema(t *testing.T) {
655662
Return: function.StringReturn{},
656663
},
657664
},
658-
Provider: providerschema.Schema{},
659-
ResourceSchemas: map[string]fwschema.Schema{},
665+
ListResourceSchemas: map[string]fwschema.Schema{},
666+
Provider: providerschema.Schema{},
667+
ResourceSchemas: map[string]fwschema.Schema{},
660668
ServerCapabilities: &fwserver.ServerCapabilities{
661669
GetProviderSchemaOptional: true,
662670
MoveResourceState: true,
@@ -808,6 +816,82 @@ func TestServerGetProviderSchema(t *testing.T) {
808816
},
809817
},
810818
},
819+
"listresource-schemas": {
820+
server: &fwserver.Server{
821+
Provider: &testprovider.Provider{
822+
ListResourcesMethod: func(_ context.Context) []func() list.ListResource {
823+
return []func() list.ListResource{
824+
func() list.ListResource {
825+
return &testprovider.ListResource{
826+
ListResourceConfigSchemaMethod: func(_ context.Context, _ list.ListResourceSchemaRequest, resp *list.ListResourceSchemaResponse) {
827+
resp.Schema = listschema.Schema{
828+
Attributes: map[string]listschema.Attribute{
829+
"test1": listschema.StringAttribute{
830+
Required: true,
831+
},
832+
},
833+
}
834+
},
835+
MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) {
836+
resp.TypeName = "test_resource"
837+
},
838+
}
839+
},
840+
}
841+
},
842+
ResourcesMethod: func(_ context.Context) []func() resource.Resource {
843+
return []func() resource.Resource{
844+
func() resource.Resource {
845+
return &testprovider.Resource{
846+
SchemaMethod: func(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
847+
resp.Schema = resourceschema.Schema{
848+
Attributes: map[string]resourceschema.Attribute{
849+
"test1": resourceschema.StringAttribute{
850+
Required: true,
851+
},
852+
},
853+
}
854+
},
855+
MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) {
856+
resp.TypeName = "test_resource"
857+
},
858+
}
859+
},
860+
}
861+
},
862+
},
863+
},
864+
request: &fwserver.GetProviderSchemaRequest{},
865+
expectedResponse: &fwserver.GetProviderSchemaResponse{
866+
DataSourceSchemas: map[string]fwschema.Schema{},
867+
EphemeralResourceSchemas: map[string]fwschema.Schema{},
868+
FunctionDefinitions: map[string]function.Definition{},
869+
ListResourceSchemas: map[string]fwschema.Schema{
870+
"test_resource": listschema.Schema{
871+
Attributes: map[string]listschema.Attribute{
872+
"test1": listschema.StringAttribute{
873+
Required: true,
874+
},
875+
},
876+
},
877+
},
878+
Provider: providerschema.Schema{},
879+
ResourceSchemas: map[string]fwschema.Schema{
880+
"test_resource": resourceschema.Schema{
881+
Attributes: map[string]resourceschema.Attribute{
882+
"test1": resourceschema.StringAttribute{
883+
Required: true,
884+
},
885+
},
886+
},
887+
},
888+
ServerCapabilities: &fwserver.ServerCapabilities{
889+
GetProviderSchemaOptional: true,
890+
MoveResourceState: true,
891+
PlanDestroy: true,
892+
},
893+
},
894+
},
811895
"provider": {
812896
server: &fwserver.Server{
813897
Provider: &testprovider.Provider{
@@ -827,6 +911,7 @@ func TestServerGetProviderSchema(t *testing.T) {
827911
DataSourceSchemas: map[string]fwschema.Schema{},
828912
EphemeralResourceSchemas: map[string]fwschema.Schema{},
829913
FunctionDefinitions: map[string]function.Definition{},
914+
ListResourceSchemas: map[string]fwschema.Schema{},
830915
Provider: providerschema.Schema{
831916
Attributes: map[string]providerschema.Attribute{
832917
"test": providerschema.StringAttribute{
@@ -894,6 +979,7 @@ func TestServerGetProviderSchema(t *testing.T) {
894979
DataSourceSchemas: map[string]fwschema.Schema{},
895980
EphemeralResourceSchemas: map[string]fwschema.Schema{},
896981
FunctionDefinitions: map[string]function.Definition{},
982+
ListResourceSchemas: map[string]fwschema.Schema{},
897983
Provider: providerschema.Schema{},
898984
ProviderMeta: metaschema.Schema{
899985
Attributes: map[string]metaschema.Attribute{
@@ -990,6 +1076,7 @@ func TestServerGetProviderSchema(t *testing.T) {
9901076
DataSourceSchemas: map[string]fwschema.Schema{},
9911077
EphemeralResourceSchemas: map[string]fwschema.Schema{},
9921078
FunctionDefinitions: map[string]function.Definition{},
1079+
ListResourceSchemas: map[string]fwschema.Schema{},
9931080
Provider: providerschema.Schema{},
9941081
ResourceSchemas: map[string]fwschema.Schema{
9951082
"test_resource1": resourceschema.Schema{
@@ -1203,6 +1290,7 @@ func TestServerGetProviderSchema(t *testing.T) {
12031290
DataSourceSchemas: map[string]fwschema.Schema{},
12041291
EphemeralResourceSchemas: map[string]fwschema.Schema{},
12051292
FunctionDefinitions: map[string]function.Definition{},
1293+
ListResourceSchemas: map[string]fwschema.Schema{},
12061294
Provider: providerschema.Schema{},
12071295
ResourceSchemas: map[string]fwschema.Schema{
12081296
"testprovidertype_resource": resourceschema.Schema{

internal/fwserver/server_listresources.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99

1010
"github.com/hashicorp/terraform-plugin-framework/diag"
11+
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
1112
"github.com/hashicorp/terraform-plugin-framework/internal/logging"
1213
"github.com/hashicorp/terraform-plugin-framework/list"
1314
"github.com/hashicorp/terraform-plugin-framework/provider"
@@ -98,3 +99,31 @@ func (s *Server) ListResourceMetadatas(ctx context.Context) ([]ListResourceMetad
9899

99100
return resourceMetadatas, diags
100101
}
102+
103+
// ListResourceSchemas returns a map of ListResource Schemas for the
104+
// GetProviderSchema RPC without caching since not all schemas are guaranteed to
105+
// be necessary for later provider operations. The schema implementations are
106+
// also validated.
107+
func (s *Server) ListResourceSchemas(ctx context.Context) (map[string]fwschema.Schema, diag.Diagnostics) {
108+
listResourceSchemas := make(map[string]fwschema.Schema)
109+
listResourceFuncs, diags := s.ListResourceFuncs(ctx)
110+
111+
for typeName, listResourceFunc := range listResourceFuncs {
112+
listResource := listResourceFunc()
113+
schemaReq := list.ListResourceSchemaRequest{}
114+
schemaResp := list.ListResourceSchemaResponse{}
115+
116+
logging.FrameworkTrace(ctx, "Calling provider defined ListResource Schemas", map[string]interface{}{logging.KeyListResourceType: typeName})
117+
listResource.ListResourceConfigSchema(ctx, schemaReq, &schemaResp)
118+
logging.FrameworkTrace(ctx, "Called provider defined ListResource Schemas", map[string]interface{}{logging.KeyListResourceType: typeName})
119+
120+
diags.Append(schemaResp.Diagnostics...)
121+
if schemaResp.Diagnostics.HasError() {
122+
continue
123+
}
124+
125+
listResourceSchemas[typeName] = schemaResp.Schema
126+
}
127+
128+
return listResourceSchemas, diags
129+
}

list/schema/attribute.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package schema
5+
6+
import "github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
7+
8+
// Attribute defines a value field inside the Schema. Implementations in this
9+
// package include:
10+
// - BoolAttribute
11+
// - DynamicAttribute
12+
// - Float32Attribute
13+
// - Float64Attribute
14+
// - Int32Attribute
15+
// - Int64Attribute
16+
// - ListAttribute
17+
// - MapAttribute
18+
// - NumberAttribute
19+
// - ObjectAttribute
20+
// - SetAttribute
21+
// - StringAttribute
22+
//
23+
// Additionally, the NestedAttribute interface extends Attribute with nested
24+
// attributes. Only supported in protocol version 6. Implementations in this
25+
// package include:
26+
// - ListNestedAttribute
27+
// - MapNestedAttribute
28+
// - SetNestedAttribute
29+
// - SingleNestedAttribute
30+
//
31+
// In practitioner configurations, an equals sign (=) is required to set
32+
// the value. [Configuration Reference]
33+
//
34+
// [Configuration Reference]: https://developer.hashicorp.com/terraform/language/syntax/configuration
35+
type Attribute interface {
36+
fwschema.Attribute
37+
}

list/schema/block.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package schema
5+
6+
import (
7+
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
8+
)
9+
10+
// Block defines a structural field inside a Schema. Implementations in this
11+
// package include:
12+
// - ListNestedBlock
13+
// - SetNestedBlock
14+
// - SingleNestedBlock
15+
//
16+
// In practitioner configurations, an equals sign (=) cannot be used to set the
17+
// value. Blocks are instead repeated as necessary, or require the use of
18+
// [Dynamic Block Expressions].
19+
//
20+
// Prefer NestedAttribute over Block. Blocks should typically be used for
21+
// configuration compatibility with previously existing schemas from an older
22+
// Terraform Plugin SDK. Efforts should be made to convert from Block to
23+
// NestedAttribute as a breaking change for practitioners.
24+
//
25+
// [Dynamic Block Expressions]: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks
26+
//
27+
// [Configuration Reference]: https://developer.hashicorp.com/terraform/language/syntax/configuration
28+
type Block interface {
29+
fwschema.Block
30+
}

0 commit comments

Comments
 (0)