Skip to content

Commit af13637

Browse files
committed
Saving my progress, todo: add clientcapabilities to plugin go
1 parent eefd07f commit af13637

22 files changed

+1095
-112
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ toolchain go1.24.4
66

77
require (
88
github.com/google/go-cmp v0.7.0
9-
github.com/hashicorp/terraform-plugin-go v0.29.1-0.20251028091959-b0e5c5f97a7c
9+
github.com/hashicorp/terraform-plugin-go v0.29.1-0.20251107103451-b1dbec9688da
1010
github.com/hashicorp/terraform-plugin-log v0.9.0
1111
)
1212

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshf
2323
github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
2424
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
2525
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
26-
github.com/hashicorp/terraform-plugin-go v0.29.1-0.20251028091959-b0e5c5f97a7c h1:CZun5uZTGnQhElJBvo49mqvIBzQOPH2OSL6xazuzeQE=
27-
github.com/hashicorp/terraform-plugin-go v0.29.1-0.20251028091959-b0e5c5f97a7c/go.mod h1:KHRnT9vExG+r1fLxwOzOP6C6YXiaKHtsCIrky7teDYc=
26+
github.com/hashicorp/terraform-plugin-go v0.29.1-0.20251107103451-b1dbec9688da h1:RvFdseryCMkoBWxucUSEnQkeROpBiungf3bNQV1efgc=
27+
github.com/hashicorp/terraform-plugin-go v0.29.1-0.20251107103451-b1dbec9688da/go.mod h1:KHRnT9vExG+r1fLxwOzOP6C6YXiaKHtsCIrky7teDYc=
2828
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
2929
github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
3030
github.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk=

internal/fromproto6/client_capabilities.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@ func ConfigureProviderClientCapabilities(in *tfprotov6.ConfigureProviderClientCa
2626
}
2727
}
2828

29+
// TODO: Add to plugin-go tfprotov6 and implement properly when capabilities are defined.
30+
func ConfigureStateStoreClientCapabilities(in *tfprotov6.ConfigureStateStoreClientCapabilities) provider.ConfigureStateStoreClientCapabilities {
31+
if in == nil {
32+
// Client did not indicate any supported capabilities
33+
return provider.ConfigureStateStoreClientCapabilities{
34+
DeferralAllowed: false,
35+
}
36+
}
37+
38+
return provider.ConfigureStateStoreClientCapabilities{
39+
DeferralAllowed: in.DeferralAllowed,
40+
}
41+
}
42+
2943
func ReadDataSourceClientCapabilities(in *tfprotov6.ReadDataSourceClientCapabilities) datasource.ReadClientCapabilities {
3044
if in == nil {
3145
// Client did not indicate any supported capabilities
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package fromproto6
5+
6+
import (
7+
"context"
8+
9+
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
10+
11+
"github.com/hashicorp/terraform-plugin-framework/diag"
12+
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
13+
"github.com/hashicorp/terraform-plugin-framework/statestore"
14+
)
15+
16+
// ConfigureStateStoreRequest returns the *fwserver.ConfigureStateStoreRequest
17+
// equivalent of a *tfprotov6.ConfigureStateStoreRequest.
18+
func ConfigureStateStoreRequest(ctx context.Context, proto6 *tfprotov6.ConfigureStateStoreRequest, statestoreSchema fwschema.Schema) (*statestore.ConfigureStateStoreRequest, diag.Diagnostics) {
19+
if proto6 == nil {
20+
return nil, nil
21+
}
22+
23+
fw := &statestore.ConfigureStateStoreRequest{
24+
TypeName: proto6.TypeName,
25+
Capabilities: ConfigureStateStoreClientCapabilities(proto6.ClientCapabilities), //TODO: Add to plugin-go tfprotov6 and implement properly when capabilities are defined.
26+
}
27+
28+
config, diags := Config(ctx, proto6.Config, statestoreSchema)
29+
30+
if config != nil {
31+
fw.Config = *config
32+
}
33+
34+
return fw, diags
35+
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package fromproto6_test
5+
6+
import (
7+
"context"
8+
"testing"
9+
10+
"github.com/google/go-cmp/cmp"
11+
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
12+
"github.com/hashicorp/terraform-plugin-go/tftypes"
13+
14+
"github.com/hashicorp/terraform-plugin-framework/diag"
15+
"github.com/hashicorp/terraform-plugin-framework/internal/fromproto6"
16+
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
17+
"github.com/hashicorp/terraform-plugin-framework/statestore"
18+
"github.com/hashicorp/terraform-plugin-framework/statestore/schema"
19+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
20+
)
21+
22+
func TestConfigureStateStoreRequest(t *testing.T) {
23+
t.Parallel()
24+
25+
testProto6Type := tftypes.Object{
26+
AttributeTypes: map[string]tftypes.Type{
27+
"test_attribute": tftypes.String,
28+
},
29+
}
30+
31+
testProto6Value := tftypes.NewValue(testProto6Type, map[string]tftypes.Value{
32+
"test_attribute": tftypes.NewValue(tftypes.String, "test-value"),
33+
})
34+
35+
testProto6DynamicValue, err := tfprotov6.NewDynamicValue(testProto6Type, testProto6Value)
36+
37+
if err != nil {
38+
t.Fatalf("unexpected error calling tfprotov6.NewDynamicValue(): %s", err)
39+
}
40+
41+
testFwSchema := schema.Schema{
42+
Attributes: map[string]schema.Attribute{
43+
"test_attribute": schema.StringAttribute{
44+
Required: true,
45+
},
46+
},
47+
}
48+
49+
testCases := map[string]struct {
50+
input *tfprotov6.ConfigureStateStoreRequest
51+
statestoreSchema fwschema.Schema
52+
expected *statestore.ConfigureStateStoreRequest
53+
expectedDiagnostics diag.Diagnostics
54+
}{
55+
"nil": {
56+
input: nil,
57+
expected: nil,
58+
},
59+
"empty": {
60+
input: &tfprotov6.ConfigureStateStoreRequest{},
61+
expected: &statestore.ConfigureStateStoreRequest{},
62+
},
63+
"config-missing-schema": {
64+
input: &tfprotov6.ConfigureStateStoreRequest{
65+
Config: &testProto6DynamicValue,
66+
},
67+
expected: &statestore.ConfigureStateStoreRequest{},
68+
expectedDiagnostics: diag.Diagnostics{
69+
diag.NewErrorDiagnostic(
70+
"Unable to Convert Configuration",
71+
"An unexpected error was encountered when converting the configuration from the protocol type. "+
72+
"This is always an issue in terraform-plugin-framework used to implement the statestore and should be reported to the statestore developers.\n\n"+
73+
"Please report this to the statestore developer:\n\n"+
74+
"Missing schema.",
75+
),
76+
},
77+
},
78+
"config": {
79+
input: &tfprotov6.ConfigureStateStoreRequest{
80+
Config: &testProto6DynamicValue,
81+
},
82+
statestoreSchema: testFwSchema,
83+
expected: &statestore.ConfigureStateStoreRequest{
84+
Config: tfsdk.Config{
85+
Raw: testProto6Value,
86+
Schema: testFwSchema,
87+
},
88+
},
89+
},
90+
"typename": {
91+
input: &tfprotov6.ConfigureStateStoreRequest{
92+
TypeName: "foo",
93+
},
94+
expected: &statestore.ConfigureStateStoreRequest{
95+
TypeName: "foo",
96+
},
97+
},
98+
"client-capabilities": {
99+
input: &tfprotov6.ConfigureStateStoreRequest{
100+
Capabilities: &tfprotov6.ConfigureStateStoreClientCapabilities{
101+
DeferralAllowed: true,
102+
},
103+
},
104+
expected: &statestore.ConfigureStateStoreRequest{
105+
Capabilities: statestore.ConfigureStateStoreClientCapabilities{
106+
DeferralAllowed: true,
107+
},
108+
},
109+
},
110+
"client-capabilities-unset": {
111+
input: &tfprotov6.ConfigureStateStoreRequest{},
112+
expected: &statestore.ConfigureStateStoreRequest{
113+
Capabilities: statestore.ConfigureStateStoreClientCapabilities{
114+
DeferralAllowed: false,
115+
},
116+
},
117+
},
118+
}
119+
120+
for name, testCase := range testCases {
121+
t.Run(name, func(t *testing.T) {
122+
t.Parallel()
123+
124+
got, diags := fromproto6.ConfigureStateStoreRequest(context.Background(), testCase.input, testCase.statestoreSchema)
125+
126+
if diff := cmp.Diff(got, testCase.expected); diff != "" {
127+
t.Errorf("unexpected difference: %s", diff)
128+
}
129+
130+
if diff := cmp.Diff(diags, testCase.expectedDiagnostics); diff != "" {
131+
t.Errorf("unexpected diagnostics difference: %s", diff)
132+
}
133+
})
134+
}
135+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package fromproto6
5+
6+
import (
7+
"context"
8+
9+
"github.com/hashicorp/terraform-plugin-framework/diag"
10+
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
11+
"github.com/hashicorp/terraform-plugin-framework/statestore"
12+
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
13+
)
14+
15+
// ReadStateBytesRequest returns the *fwserver.ReadStateBytesRequest
16+
// equivalent of a *tfprotov6.ReadStateBytesRequest.
17+
func ReadStateBytesRequest(ctx context.Context, proto6 *tfprotov6.ReadStateBytesRequest, stateBytes statestore.StateStore) (*fwserver.ReadStateBytesRequest, diag.Diagnostics) {
18+
if proto6 == nil {
19+
return nil, nil
20+
}
21+
22+
var diags diag.Diagnostics
23+
24+
// Panic prevention here to simplify the calling implementations.
25+
// This should not happen, but just in case.
26+
27+
fw := &fwserver.ReadStateBytesRequest{
28+
StateId: proto6.StateId,
29+
}
30+
31+
fw.StateId = proto6.StateId
32+
33+
return fw, diags
34+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package fromproto6_test
5+
6+
import (
7+
"context"
8+
"testing"
9+
10+
"github.com/google/go-cmp/cmp"
11+
"github.com/hashicorp/terraform-plugin-framework/diag"
12+
"github.com/hashicorp/terraform-plugin-framework/internal/fromproto6"
13+
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
14+
"github.com/hashicorp/terraform-plugin-framework/statestore"
15+
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
16+
)
17+
18+
func TestReadStateBytesRequest(t *testing.T) {
19+
t.Parallel()
20+
21+
testCases := map[string]struct {
22+
input *tfprotov6.ReadStateBytesRequest
23+
stateStore statestore.StateStore
24+
expected *fwserver.ReadStateBytesRequest
25+
expectedDiagnostics diag.Diagnostics
26+
}{
27+
"nil": {
28+
input: nil,
29+
expected: nil,
30+
},
31+
"empty": {
32+
input: &tfprotov6.ReadStateBytesRequest{},
33+
expected: nil,
34+
expectedDiagnostics: diag.Diagnostics{
35+
diag.NewErrorDiagnostic(
36+
"Missing StateBytes Schema",
37+
"An unexpected error was encountered when handling the request. "+
38+
"This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+
39+
"Please report this to the provider developer:\n\n"+
40+
"Missing schema.",
41+
),
42+
},
43+
},
44+
"id-missing": {
45+
input: &tfprotov6.ReadStateBytesRequest{
46+
StateId: "",
47+
},
48+
expected: nil,
49+
expectedDiagnostics: diag.Diagnostics{
50+
diag.NewErrorDiagnostic(
51+
"Missing State ID",
52+
"An unexpected error was encountered when handling the request. "+
53+
"This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+
54+
"Please report this to the provider developer:\n\n"+
55+
"Missing State ID.",
56+
),
57+
},
58+
},
59+
"state-id": {
60+
input: &tfprotov6.ReadStateBytesRequest{
61+
StateId: "test-value",
62+
},
63+
expected: &fwserver.ReadStateBytesRequest{
64+
StateId: "test-value",
65+
},
66+
},
67+
}
68+
69+
for name, testCase := range testCases {
70+
t.Run(name, func(t *testing.T) {
71+
t.Parallel()
72+
73+
got, diags := fromproto6.ReadStateBytesRequest(context.Background(), testCase.input, testCase.stateStore)
74+
75+
if diff := cmp.Diff(got, testCase.expected); diff != "" {
76+
t.Errorf("unexpected difference: %s", diff)
77+
}
78+
79+
if diff := cmp.Diff(diags, testCase.expectedDiagnostics); diff != "" {
80+
t.Errorf("unexpected diagnostics difference: %s", diff)
81+
}
82+
})
83+
}
84+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package fromproto6
5+
6+
import (
7+
"context"
8+
9+
"github.com/hashicorp/terraform-plugin-framework/diag"
10+
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
11+
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
12+
"github.com/hashicorp/terraform-plugin-framework/statestore"
13+
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
14+
)
15+
16+
// ValidateStateStoreRequest returns the *fwserver.ValidateStateStoreRequest
17+
// equivalent of a *tfprotov6.ValidateStateStoreRequest.
18+
func ValidateStateStoreRequest(ctx context.Context, proto6 *tfprotov6.ValidateStateStoreRequest, reqStateStore statestore.StateStore, StateStoreSchema fwschema.Schema) (*fwserver.ValidateStateStoreRequest, diag.Diagnostics) {
19+
if proto6 == nil {
20+
return nil, nil
21+
}
22+
23+
fw := &fwserver.ValidateStateStoreRequest{}
24+
25+
config, diags := Config(ctx, proto6.Config, StateStoreSchema)
26+
27+
fw.Config = config
28+
fw.StateStore = reqStateStore
29+
30+
return fw, diags
31+
}

0 commit comments

Comments
 (0)