Skip to content

Commit 84437cb

Browse files
committed
expected 1 list result; got 0 list results
1 parent 747ca15 commit 84437cb

File tree

3 files changed

+66
-48
lines changed

3 files changed

+66
-48
lines changed

internal/fwserver/server_listresources.go

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,7 @@ func (s *Server) ListResourceFuncs(ctx context.Context) (map[string]func() list.
8282
"ListResource type names must be unique. "+
8383
"This is always an issue with the provider and should be reported to the provider developers.",
8484
)
85-
continue
86-
}
87-
88-
resourceFuncs, _ := s.ResourceFuncs(ctx)
89-
if _, ok := resourceFuncs[typeName]; !ok {
90-
s.listResourceFuncsDiags.AddError(
91-
"ListResource Type Defined without a Matching Managed Resource Type",
92-
fmt.Sprintf("The %s ListResource type name was returned, but no matching managed Resource type was defined. ", typeName)+
93-
"This is always an issue with the provider and should be reported to the provider developers.",
94-
)
85+
fmt.Printf("The %s ListResource type name was returned for multiple list resources. ", typeName)
9586
continue
9687
}
9788

internal/proto5server/server_listresource.go

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
1212
"github.com/hashicorp/terraform-plugin-framework/internal/toproto5"
1313
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
14+
sdk "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1415
)
1516

1617
// ListRequestErrorDiagnostics returns a value suitable for
@@ -25,6 +26,21 @@ func ListRequestErrorDiagnostics(ctx context.Context, diags ...diag.Diagnostic)
2526
}, nil
2627
}
2728

29+
type SDKContext string
30+
31+
var SDKResourceKey SDKContext = "sdk_resource"
32+
33+
// NewContextWithSDKResource returns a new Context that carries value r
34+
func NewContextWithSDKResource(ctx context.Context, r *sdk.Resource) context.Context {
35+
return context.WithValue(ctx, SDKResourceKey, r)
36+
}
37+
38+
// FromContext returns the SDK Resource value stored in ctx, if any.
39+
func SDKResourceFromContext(ctx context.Context) (*sdk.Resource, bool) {
40+
r, ok := ctx.Value(SDKResourceKey).(*sdk.Resource)
41+
return r, ok
42+
}
43+
2844
func (s *Server) ListResource(ctx context.Context, protoReq *tfprotov5.ListResourceRequest) (*tfprotov5.ListResourceServerStream, error) {
2945
protoStream := &tfprotov5.ListResourceServerStream{Results: tfprotov5.NoListResults}
3046
allDiags := diag.Diagnostics{}
@@ -47,43 +63,52 @@ func (s *Server) ListResource(ctx context.Context, protoReq *tfprotov5.ListResou
4763
return ListRequestErrorDiagnostics(ctx, allDiags...)
4864
}
4965

50-
resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, protoReq.TypeName)
51-
allDiags.Append(diags...)
52-
if diags.HasError() {
53-
return ListRequestErrorDiagnostics(ctx, allDiags...)
54-
}
66+
_, ok := SDKResourceFromContext(ctx)
67+
switch ok {
68+
case true:
69+
protoStream.Results = func(push func(tfprotov5.ListResourceResult) bool) {
70+
listResult := tfprotov5.ListResourceResult{}
71+
push(listResult)
72+
}
73+
case false:
74+
resourceSchema, diags := s.FrameworkServer.ResourceSchema(ctx, protoReq.TypeName)
75+
allDiags.Append(diags...)
76+
if diags.HasError() {
77+
return ListRequestErrorDiagnostics(ctx, allDiags...)
78+
}
5579

56-
identitySchema, diags := s.FrameworkServer.ResourceIdentitySchema(ctx, protoReq.TypeName)
57-
allDiags.Append(diags...)
58-
if diags.HasError() {
59-
return ListRequestErrorDiagnostics(ctx, allDiags...)
60-
}
80+
identitySchema, diags := s.FrameworkServer.ResourceIdentitySchema(ctx, protoReq.TypeName)
81+
allDiags.Append(diags...)
82+
if diags.HasError() {
83+
return ListRequestErrorDiagnostics(ctx, allDiags...)
84+
}
6185

62-
req := &fwserver.ListRequest{
63-
Config: config,
64-
ListResource: listResource,
65-
ResourceSchema: resourceSchema,
66-
ResourceIdentitySchema: identitySchema,
67-
IncludeResource: protoReq.IncludeResource,
68-
}
69-
stream := &fwserver.ListResultsStream{}
86+
req := &fwserver.ListRequest{
87+
Config: config,
88+
ListResource: listResource,
89+
ResourceSchema: resourceSchema,
90+
ResourceIdentitySchema: identitySchema,
91+
IncludeResource: protoReq.IncludeResource,
92+
}
93+
stream := &fwserver.ListResultsStream{}
7094

71-
err := s.FrameworkServer.ListResource(ctx, req, stream)
72-
if err != nil {
73-
return protoStream, err
74-
}
95+
err := s.FrameworkServer.ListResource(ctx, req, stream)
96+
if err != nil {
97+
return protoStream, err
98+
}
7599

76-
protoStream.Results = func(push func(tfprotov5.ListResourceResult) bool) {
77-
for result := range stream.Results {
78-
var protoResult tfprotov5.ListResourceResult
79-
if req.IncludeResource {
80-
protoResult = toproto5.ListResourceResultWithResource(ctx, &result)
81-
} else {
82-
protoResult = toproto5.ListResourceResult(ctx, &result)
83-
}
100+
protoStream.Results = func(push func(tfprotov5.ListResourceResult) bool) {
101+
for result := range stream.Results {
102+
var protoResult tfprotov5.ListResourceResult
103+
if req.IncludeResource {
104+
protoResult = toproto5.ListResourceResultWithResource(ctx, &result)
105+
} else {
106+
protoResult = toproto5.ListResourceResult(ctx, &result)
107+
}
84108

85-
if !push(protoResult) {
86-
return
109+
if !push(protoResult) {
110+
return
111+
}
87112
}
88113
}
89114
}

internal/proto5server/server_listresource_test.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,6 @@ func TestServerListResource(t *testing.T) {
282282
}
283283
}
284284

285-
type SDKContext string
286-
287-
var SDKResource SDKContext = "sdk_resource"
288-
289285
// a resource type defined in SDKv2
290286
var sdkResource sdk.Resource = sdk.Resource{
291287
Schema: map[string]*sdk.Schema{
@@ -328,8 +324,10 @@ func TestServerListResourceProto5ToProto5(t *testing.T) {
328324
aServer := server(listResource)
329325

330326
ctx := context.Background()
331-
ctx = context.WithValue(ctx, SDKResource, sdkResource)
332-
req := &tfprotov5.ListResourceRequest{}
327+
ctx = NewContextWithSDKResource(ctx, &sdkResource)
328+
req := &tfprotov5.ListResourceRequest{
329+
TypeName: "test_resource",
330+
}
333331

334332
stream, err := aServer.ListResource(ctx, req)
335333
if err != nil {
@@ -346,6 +344,10 @@ func TestServerListResourceProto5ToProto5(t *testing.T) {
346344
}
347345
}
348346

347+
if len(values) == 0 {
348+
t.Fatalf("expected 1 list result; got 0 list results")
349+
}
350+
349351
// 2: from the resource type, we can obtain an initialized ResourceData value
350352
d := sdkResource.Data(&terraformsdk.InstanceState{ID: "#groot"})
351353

0 commit comments

Comments
 (0)