Skip to content

Commit afb7e09

Browse files
committed
extend support for supplying raw schema types to proto6
1 parent 25209ea commit afb7e09

File tree

5 files changed

+87
-28
lines changed

5 files changed

+87
-28
lines changed

internal/fwserver/server_getmetadata_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,8 @@ func TestServerGetMetadata(t *testing.T) {
839839
diag.NewErrorDiagnostic(
840840
"ListResource Type Defined without a Matching Managed Resource Type",
841841
"The test_resource_1 ListResource type name was returned, but no matching managed Resource type was defined. "+
842-
"If the matching managed Resource type is a legacy resource, ProtoV5Schema and ProtoV5IdentitySchema must be specified in the RawV5Schemas method. "+
842+
"If the matching managed Resource type not a framework resource either ProtoV5Schema and ProtoV5IdentitySchema must be specified in the RawV5Schemas method, "+
843+
"or ProtoV6Schema and ProtoV6IdentitySchema must be specified in the RawV6Schemas method. "+
843844
"This is always an issue with the provider and should be reported to the provider developers.",
844845
),
845846
},

internal/fwserver/server_listresources.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,18 +85,24 @@ func (s *Server) ListResourceFuncs(ctx context.Context) (map[string]func() list.
8585
continue
8686
}
8787

88-
schemasResp := list.SchemaResponse{}
88+
rawV5SchemasResp := list.RawV5SchemaResponse{}
8989
if listResourceWithSchemas, ok := listResource.(list.ListResourceWithRawV5Schemas); ok {
90-
listResourceWithSchemas.RawV5Schemas(ctx, list.SchemaRequest{}, &schemasResp)
90+
listResourceWithSchemas.RawV5Schemas(ctx, list.RawV5SchemaRequest{}, &rawV5SchemasResp)
91+
}
92+
93+
rawV6SchemasResp := list.RawV6SchemaResponse{}
94+
if listResourceWithSchemas, ok := listResource.(list.ListResourceWithRawV6Schemas); ok {
95+
listResourceWithSchemas.RawV6Schemas(ctx, list.RawV6SchemaRequest{}, &rawV6SchemasResp)
9196
}
9297

9398
resourceFuncs, _ := s.ResourceFuncs(ctx)
9499
if _, ok := resourceFuncs[typeName]; !ok {
95-
if schemasResp.ProtoV5Schema == nil || schemasResp.ProtoV5IdentitySchema == nil {
100+
if (rawV5SchemasResp.ProtoV5Schema == nil || rawV5SchemasResp.ProtoV5IdentitySchema == nil) && (rawV6SchemasResp.ProtoV6Schema == nil || rawV6SchemasResp.ProtoV6IdentitySchema == nil) {
96101
s.listResourceFuncsDiags.AddError(
97102
"ListResource Type Defined without a Matching Managed Resource Type",
98103
fmt.Sprintf("The %s ListResource type name was returned, but no matching managed Resource type was defined. ", typeName)+
99-
"If the matching managed Resource type is a legacy resource, ProtoV5Schema and ProtoV5IdentitySchema must be specified in the RawV5Schemas method. "+
104+
"If the matching managed Resource type not a framework resource either ProtoV5Schema and ProtoV5IdentitySchema must be specified in the RawV5Schemas method, "+
105+
"or ProtoV6Schema and ProtoV6IdentitySchema must be specified in the RawV6Schemas method. "+
100106
"This is always an issue with the provider and should be reported to the provider developers.",
101107
)
102108
continue

internal/proto5server/server_listresource.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ func (s *Server) ListResource(ctx context.Context, protoReq *tfprotov5.ListResou
5555
Limit: protoReq.Limit,
5656
}
5757

58-
schemaResp := list.SchemaResponse{}
58+
schemaResp := list.RawV5SchemaResponse{}
5959
if listResourceWithProtoSchemas, ok := listResource.(list.ListResourceWithRawV5Schemas); ok {
60-
listResourceWithProtoSchemas.RawV5Schemas(ctx, list.SchemaRequest{}, &schemaResp)
60+
listResourceWithProtoSchemas.RawV5Schemas(ctx, list.RawV5SchemaRequest{}, &schemaResp)
6161
}
6262

6363
// There's validation in ListResources that ensures both are set if either is provided so it should be sufficient to only nil check Identity
@@ -77,7 +77,6 @@ func (s *Server) ListResource(ctx context.Context, protoReq *tfprotov5.ListResou
7777
allDiags.Append(diags...)
7878
return ListRequestErrorDiagnostics(ctx, allDiags...)
7979
}
80-
8180
} else {
8281
req.ResourceSchema, diags = s.FrameworkServer.ResourceSchema(ctx, protoReq.TypeName)
8382
allDiags.Append(diags...)

internal/proto6server/server_listresource.go

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/hashicorp/terraform-plugin-framework/internal/fromproto6"
1111
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
1212
"github.com/hashicorp/terraform-plugin-framework/internal/toproto6"
13+
"github.com/hashicorp/terraform-plugin-framework/list"
1314
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
1415
)
1516

@@ -47,26 +48,48 @@ func (s *Server) ListResource(ctx context.Context, protoReq *tfprotov6.ListResou
4748
return ListRequestErrorDiagnostics(ctx, allDiags...)
4849
}
4950

50-
resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, protoReq.TypeName)
51-
allDiags.Append(diags...)
52-
if diags.HasError() {
53-
return ListRequestErrorDiagnostics(ctx, allDiags...)
51+
req := &fwserver.ListRequest{
52+
Config: config,
53+
ListResource: listResource,
54+
IncludeResource: protoReq.IncludeResource,
55+
Limit: protoReq.Limit,
5456
}
5557

56-
identitySchema, diags := s.FrameworkServer.ResourceIdentitySchema(ctx, protoReq.TypeName)
57-
allDiags.Append(diags...)
58-
if diags.HasError() {
59-
return ListRequestErrorDiagnostics(ctx, allDiags...)
58+
schemaResp := list.RawV6SchemaResponse{}
59+
if listResourceWithProtoSchemas, ok := listResource.(list.ListResourceWithRawV6Schemas); ok {
60+
listResourceWithProtoSchemas.RawV6Schemas(ctx, list.RawV6SchemaRequest{}, &schemaResp)
6061
}
6162

62-
req := &fwserver.ListRequest{
63-
Config: config,
64-
ListResource: listResource,
65-
ResourceSchema: resourceSchema,
66-
ResourceIdentitySchema: identitySchema,
67-
IncludeResource: protoReq.IncludeResource,
68-
Limit: protoReq.Limit,
63+
if schemaResp.ProtoV6IdentitySchema != nil {
64+
var err error
65+
66+
req.ResourceSchema, err = fromproto6.ResourceSchema(ctx, schemaResp.ProtoV6Schema)
67+
if err != nil {
68+
diags.AddError("Converting Resource Schema", err.Error())
69+
allDiags.Append(diags...)
70+
return ListRequestErrorDiagnostics(ctx, allDiags...)
71+
}
72+
73+
req.ResourceIdentitySchema, err = fromproto6.IdentitySchema(ctx, schemaResp.ProtoV6IdentitySchema)
74+
if err != nil {
75+
diags.AddError("Converting Resource Identity Schema", err.Error())
76+
allDiags.Append(diags...)
77+
return ListRequestErrorDiagnostics(ctx, allDiags...)
78+
}
79+
} else {
80+
req.ResourceSchema, diags = s.FrameworkServer.ResourceSchema(ctx, protoReq.TypeName)
81+
allDiags.Append(diags...)
82+
if diags.HasError() {
83+
return ListRequestErrorDiagnostics(ctx, allDiags...)
84+
}
85+
86+
req.ResourceIdentitySchema, diags = s.FrameworkServer.ResourceIdentitySchema(ctx, protoReq.TypeName)
87+
allDiags.Append(diags...)
88+
if diags.HasError() {
89+
return ListRequestErrorDiagnostics(ctx, allDiags...)
90+
}
6991
}
92+
7093
stream := &fwserver.ListResultsStream{}
7194

7295
s.FrameworkServer.ListResource(ctx, req, stream)

list/list_resource.go

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/hashicorp/terraform-plugin-framework/resource"
1313
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
1414
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
15+
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
1516
"github.com/hashicorp/terraform-plugin-go/tftypes"
1617
)
1718

@@ -49,7 +50,17 @@ type ListResourceWithRawV5Schemas interface {
4950
ListResource
5051

5152
// RawV5Schemas is called to provide the ProtoV5 representations of the resource and resource identity schemas.
52-
RawV5Schemas(context.Context, SchemaRequest, *SchemaResponse)
53+
RawV5Schemas(context.Context, RawV5SchemaRequest, *RawV5SchemaResponse)
54+
}
55+
56+
// ListResourceWithRawV6Schemas is an interface type that extends ListResource to include a method
57+
// which allows provider developers to supply the ProtoV5 representations of resource and resource identity
58+
// schemas. This is necessary if list functionality is being used with a legacy resource.
59+
type ListResourceWithRawV6Schemas interface {
60+
ListResource
61+
62+
// RawV6Schemas is called to provide the ProtoV5 representations of the resource and resource identity schemas.
63+
RawV6Schemas(context.Context, RawV6SchemaRequest, *RawV6SchemaResponse)
5364
}
5465

5566
// ListResourceWithConfigure is an interface type that extends ListResource to include a method
@@ -193,14 +204,14 @@ type ListResult struct {
193204
Diagnostics diag.Diagnostics
194205
}
195206

196-
// SchemaRequest represents a request for the ListResource to return the
207+
// RawV5SchemaRequest represents a request for the ListResource to return the
197208
// ProtoV5 schemas. An instance of this request struct is supplied as an argument
198209
// to the ListResource type RawV5Schemas method.
199-
type SchemaRequest struct{}
210+
type RawV5SchemaRequest struct{}
200211

201-
// SchemaResponse represents a response that is populated by the Schemas method
212+
// RawV5SchemaResponse represents a response that is populated by the Schemas method
202213
// and is used to pass along the ProtoV5 representations of the resource and resource identity schemas.
203-
type SchemaResponse struct {
214+
type RawV5SchemaResponse struct {
204215
// ProtoV5IdentitySchema is the ProtoV5 representation of the resource identity
205216
// schema. This should only be supplied if framework functionality is being used
206217
// with a legacy resource. Currently, this only applies to list.
@@ -212,6 +223,25 @@ type SchemaResponse struct {
212223
ProtoV5Schema *tfprotov5.Schema
213224
}
214225

226+
// RawV6SchemaRequest represents a request for the ListResource to return the
227+
// ProtoV5 schemas. An instance of this request struct is supplied as an argument
228+
// to the ListResource type RawV5Schemas method.
229+
type RawV6SchemaRequest struct{}
230+
231+
// RawV6SchemaResponse represents a response that is populated by the Schemas method
232+
// and is used to pass along the ProtoV5 representations of the resource and resource identity schemas.
233+
type RawV6SchemaResponse struct {
234+
// ProtoV5IdentitySchema is the ProtoV5 representation of the resource identity
235+
// schema. This should only be supplied if framework functionality is being used
236+
// with a legacy resource. Currently, this only applies to list.
237+
ProtoV6IdentitySchema *tfprotov6.ResourceIdentitySchema
238+
239+
// ProtoV5Schema is the ProtoV5 representation of the resource schema
240+
// This should only be supplied if framework functionality is being used
241+
// with a legacy resource. Currently, this only applies to list.
242+
ProtoV6Schema *tfprotov6.Schema
243+
}
244+
215245
// ValidateConfigRequest represents a request to validate the configuration of
216246
// a list resource. An instance of this request struct is supplied as an
217247
// argument to the [ListResourceWithValidateConfig.ValidateListResourceConfig]

0 commit comments

Comments
 (0)