Skip to content

Commit 0c90fa1

Browse files
committed
Implement ValidateStateStoreConfig + ConfigureStateStore methods
1 parent 23856be commit 0c90fa1

File tree

7 files changed

+210
-3
lines changed

7 files changed

+210
-3
lines changed
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 fromproto
5+
6+
import (
7+
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
8+
"github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6"
9+
)
10+
11+
func ValidateStateStoreRequest(in *tfplugin6.ValidateStateStore_Request) *tfprotov6.ValidateStateStoreRequest {
12+
if in == nil {
13+
return nil
14+
}
15+
16+
return &tfprotov6.ValidateStateStoreRequest{
17+
TypeName: in.TypeName,
18+
Config: DynamicValue(in.Config),
19+
}
20+
}
21+
22+
func ConfigureStateStoreRequest(in *tfplugin6.ConfigureStateStore_Request) *tfprotov6.ConfigureStateStoreRequest {
23+
if in == nil {
24+
return nil
25+
}
26+
27+
return &tfprotov6.ConfigureStateStoreRequest{
28+
TypeName: in.TypeName,
29+
Config: DynamicValue(in.Config),
30+
}
31+
}

tfprotov6/internal/toproto/provider.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ func GetProviderSchema_Response(in *tfprotov6.GetProviderSchemaResponse) *tfplug
6262
Diagnostics: Diagnostics(in.Diagnostics),
6363
EphemeralResourceSchemas: make(map[string]*tfplugin6.Schema, len(in.EphemeralResourceSchemas)),
6464
ListResourceSchemas: make(map[string]*tfplugin6.Schema, len(in.ListResourceSchemas)),
65+
StateStoreSchemas: make(map[string]*tfplugin6.Schema, len(in.StateStoreSchemas)),
6566
Functions: make(map[string]*tfplugin6.Function, len(in.Functions)),
6667
Provider: Schema(in.Provider),
6768
ProviderMeta: Schema(in.ProviderMeta),
@@ -77,6 +78,10 @@ func GetProviderSchema_Response(in *tfprotov6.GetProviderSchemaResponse) *tfplug
7778
resp.ListResourceSchemas[name] = Schema(schema)
7879
}
7980

81+
for name, schema := range in.StateStoreSchemas {
82+
resp.StateStoreSchemas[name] = Schema(schema)
83+
}
84+
8085
for name, schema := range in.ResourceSchemas {
8186
resp.ResourceSchemas[name] = Schema(schema)
8287
}

tfprotov6/internal/toproto/provider_test.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ func TestGetProviderSchema_Response(t *testing.T) {
310310
Diagnostics: []*tfplugin6.Diagnostic{},
311311
EphemeralResourceSchemas: map[string]*tfplugin6.Schema{},
312312
ListResourceSchemas: map[string]*tfplugin6.Schema{},
313+
StateStoreSchemas: map[string]*tfplugin6.Schema{},
313314
Functions: map[string]*tfplugin6.Function{},
314315
ResourceSchemas: map[string]*tfplugin6.Schema{},
315316
},
@@ -353,6 +354,7 @@ func TestGetProviderSchema_Response(t *testing.T) {
353354
Diagnostics: []*tfplugin6.Diagnostic{},
354355
EphemeralResourceSchemas: map[string]*tfplugin6.Schema{},
355356
ListResourceSchemas: map[string]*tfplugin6.Schema{},
357+
StateStoreSchemas: map[string]*tfplugin6.Schema{},
356358
Functions: map[string]*tfplugin6.Function{},
357359
ResourceSchemas: map[string]*tfplugin6.Schema{},
358360
},
@@ -388,6 +390,7 @@ func TestGetProviderSchema_Response(t *testing.T) {
388390
Diagnostics: []*tfplugin6.Diagnostic{},
389391
EphemeralResourceSchemas: map[string]*tfplugin6.Schema{},
390392
ListResourceSchemas: map[string]*tfplugin6.Schema{},
393+
StateStoreSchemas: map[string]*tfplugin6.Schema{},
391394
Functions: map[string]*tfplugin6.Function{},
392395
ResourceSchemas: map[string]*tfplugin6.Schema{},
393396
},
@@ -406,6 +409,7 @@ func TestGetProviderSchema_Response(t *testing.T) {
406409
},
407410
EphemeralResourceSchemas: map[string]*tfplugin6.Schema{},
408411
ListResourceSchemas: map[string]*tfplugin6.Schema{},
412+
StateStoreSchemas: map[string]*tfplugin6.Schema{},
409413
Functions: map[string]*tfplugin6.Function{},
410414
ResourceSchemas: map[string]*tfplugin6.Schema{},
411415
},
@@ -441,6 +445,7 @@ func TestGetProviderSchema_Response(t *testing.T) {
441445
},
442446
},
443447
ListResourceSchemas: map[string]*tfplugin6.Schema{},
448+
StateStoreSchemas: map[string]*tfplugin6.Schema{},
444449
Functions: map[string]*tfplugin6.Function{},
445450
ResourceSchemas: map[string]*tfplugin6.Schema{},
446451
},
@@ -461,6 +466,7 @@ func TestGetProviderSchema_Response(t *testing.T) {
461466
Diagnostics: []*tfplugin6.Diagnostic{},
462467
EphemeralResourceSchemas: map[string]*tfplugin6.Schema{},
463468
ListResourceSchemas: map[string]*tfplugin6.Schema{},
469+
StateStoreSchemas: map[string]*tfplugin6.Schema{},
464470
Functions: map[string]*tfplugin6.Function{
465471
"test": {
466472
Parameters: []*tfplugin6.Function_Parameter{},
@@ -503,8 +509,9 @@ func TestGetProviderSchema_Response(t *testing.T) {
503509
},
504510
},
505511
},
506-
Functions: map[string]*tfplugin6.Function{},
507-
ResourceSchemas: map[string]*tfplugin6.Schema{},
512+
StateStoreSchemas: map[string]*tfplugin6.Schema{},
513+
Functions: map[string]*tfplugin6.Function{},
514+
ResourceSchemas: map[string]*tfplugin6.Schema{},
508515
},
509516
},
510517
"Provider": {
@@ -525,6 +532,7 @@ func TestGetProviderSchema_Response(t *testing.T) {
525532
Diagnostics: []*tfplugin6.Diagnostic{},
526533
EphemeralResourceSchemas: map[string]*tfplugin6.Schema{},
527534
ListResourceSchemas: map[string]*tfplugin6.Schema{},
535+
StateStoreSchemas: map[string]*tfplugin6.Schema{},
528536
Functions: map[string]*tfplugin6.Function{},
529537
Provider: &tfplugin6.Schema{
530538
Block: &tfplugin6.Schema_Block{
@@ -557,6 +565,7 @@ func TestGetProviderSchema_Response(t *testing.T) {
557565
Diagnostics: []*tfplugin6.Diagnostic{},
558566
EphemeralResourceSchemas: map[string]*tfplugin6.Schema{},
559567
ListResourceSchemas: map[string]*tfplugin6.Schema{},
568+
StateStoreSchemas: map[string]*tfplugin6.Schema{},
560569
Functions: map[string]*tfplugin6.Function{},
561570
ProviderMeta: &tfplugin6.Schema{
562571
Block: &tfplugin6.Schema_Block{
@@ -591,6 +600,7 @@ func TestGetProviderSchema_Response(t *testing.T) {
591600
Diagnostics: []*tfplugin6.Diagnostic{},
592601
EphemeralResourceSchemas: map[string]*tfplugin6.Schema{},
593602
ListResourceSchemas: map[string]*tfplugin6.Schema{},
603+
StateStoreSchemas: map[string]*tfplugin6.Schema{},
594604
Functions: map[string]*tfplugin6.Function{},
595605
ResourceSchemas: map[string]*tfplugin6.Schema{
596606
"test": {
@@ -618,6 +628,7 @@ func TestGetProviderSchema_Response(t *testing.T) {
618628
Diagnostics: []*tfplugin6.Diagnostic{},
619629
EphemeralResourceSchemas: map[string]*tfplugin6.Schema{},
620630
ListResourceSchemas: map[string]*tfplugin6.Schema{},
631+
StateStoreSchemas: map[string]*tfplugin6.Schema{},
621632
Functions: map[string]*tfplugin6.Function{},
622633
ResourceSchemas: map[string]*tfplugin6.Schema{},
623634
ServerCapabilities: &tfplugin6.ServerCapabilities{
@@ -651,7 +662,7 @@ func TestGetProviderSchema_Response(t *testing.T) {
651662
tfplugin6.ServerCapabilities{},
652663
)
653664

654-
if diff := cmp.Diff(got, testCase.expected, diffOpts); diff != "" {
665+
if diff := cmp.Diff(testCase.expected, got, diffOpts); diff != "" {
655666
t.Errorf("unexpected difference: %s", diff)
656667
}
657668
})
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package toproto
5+
6+
import (
7+
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
8+
"github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6"
9+
)
10+
11+
func ValidateStateStoreConfig_Response(in *tfprotov6.ValidateStateStoreResponse) *tfplugin6.ValidateStateStore_Response {
12+
if in == nil {
13+
return nil
14+
}
15+
16+
return &tfplugin6.ValidateStateStore_Response{
17+
Diagnostics: Diagnostics(in.Diagnostics),
18+
}
19+
}
20+
21+
func ConfigureStateStore_Response(in *tfprotov6.ConfigureStateStoreResponse) *tfplugin6.ConfigureStateStore_Response {
22+
if in == nil {
23+
return nil
24+
}
25+
26+
return &tfplugin6.ConfigureStateStore_Response{
27+
Diagnostics: Diagnostics(in.Diagnostics),
28+
}
29+
}

tfprotov6/provider.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ type GetProviderSchemaResponse struct {
201201
// shortname and an underscore.
202202
ActionSchemas map[string]*ActionSchema
203203

204+
// StateStoreSchemas is a map of state store name and its schema
205+
StateStoreSchemas map[string]*Schema
206+
204207
// Diagnostics report errors or warnings related to returning the
205208
// provider's schemas. Returning an empty slice indicates success, with
206209
// no errors or warnings generated.

tfprotov6/state_store.go

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 tfprotov6
5+
6+
import "context"
7+
8+
// StateStoreServer is an interface containing the methods an list resource
9+
// implementation needs to fill.
10+
type StateStoreServer interface {
11+
// ValidateStateStoreConfig performs configuration validation
12+
ValidateStateStoreConfig(context.Context, *ValidateStateStoreRequest) (*ValidateStateStoreResponse, error)
13+
14+
// ConfigureStateStore configures the state store, such as S3 connection in the context of already configured provider
15+
ConfigureStateStore(context.Context, *ConfigureStateStoreRequest) (*ConfigureStateStoreResponse, error)
16+
}
17+
18+
type ValidateStateStoreRequest struct {
19+
TypeName string
20+
Config *DynamicValue
21+
}
22+
23+
type ValidateStateStoreResponse struct {
24+
Diagnostics []*Diagnostic
25+
}
26+
27+
type ConfigureStateStoreRequest struct {
28+
TypeName string
29+
Config *DynamicValue
30+
}
31+
32+
type ConfigureStateStoreResponse struct {
33+
Diagnostics []*Diagnostic
34+
}

tfprotov6/tf6server/server.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,6 +1504,100 @@ func (s *server) InvokeAction(protoReq *tfplugin6.InvokeAction_Request, protoStr
15041504
return nil
15051505
}
15061506

1507+
func (s *server) ValidateStateStoreConfig(ctx context.Context, protoReq *tfplugin6.ValidateStateStore_Request) (*tfplugin6.ValidateStateStore_Response, error) {
1508+
rpc := "ValidateStateStoreConfig"
1509+
ctx = s.loggingContext(ctx)
1510+
ctx = logging.RpcContext(ctx, rpc)
1511+
ctx = logging.ResourceContext(ctx, protoReq.TypeName)
1512+
ctx = s.stoppableContext(ctx)
1513+
logging.ProtocolTrace(ctx, "Received request")
1514+
defer logging.ProtocolTrace(ctx, "Served request")
1515+
1516+
req := fromproto.ValidateStateStoreRequest(protoReq)
1517+
1518+
logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config)
1519+
1520+
ctx = tf6serverlogging.DownstreamRequest(ctx)
1521+
1522+
server, ok := s.downstream.(tfprotov6.StateStoreServer)
1523+
if !ok {
1524+
logging.ProtocolError(ctx, "ProviderServer does not implement ValidateStateStoreConfig")
1525+
1526+
protoResp := &tfplugin6.ValidateStateStore_Response{
1527+
Diagnostics: []*tfplugin6.Diagnostic{
1528+
{
1529+
Severity: tfplugin6.Diagnostic_ERROR,
1530+
Summary: "Provider ValidateStateStoreConfig Not Implemented",
1531+
Detail: "A ValidateStateStoreConfig call was received by the provider, however the provider does not implement the call. " +
1532+
"Either upgrade the provider to a version that implements state store or this is a bug in Terraform that should be reported to the Terraform maintainers.",
1533+
},
1534+
},
1535+
}
1536+
1537+
return protoResp, nil
1538+
}
1539+
1540+
resp, err := server.ValidateStateStoreConfig(ctx, req)
1541+
1542+
if err != nil {
1543+
logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err})
1544+
return nil, err
1545+
}
1546+
1547+
tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics)
1548+
1549+
protoResp := toproto.ValidateStateStoreConfig_Response(resp)
1550+
1551+
return protoResp, nil
1552+
}
1553+
1554+
func (s *server) ConfigureStateStore(ctx context.Context, protoReq *tfplugin6.ConfigureStateStore_Request) (*tfplugin6.ConfigureStateStore_Response, error) {
1555+
rpc := "ConfigureStateStore"
1556+
ctx = s.loggingContext(ctx)
1557+
ctx = logging.RpcContext(ctx, rpc)
1558+
ctx = logging.ResourceContext(ctx, protoReq.TypeName)
1559+
ctx = s.stoppableContext(ctx)
1560+
logging.ProtocolTrace(ctx, "Received request")
1561+
defer logging.ProtocolTrace(ctx, "Served request")
1562+
1563+
req := fromproto.ConfigureStateStoreRequest(protoReq)
1564+
1565+
logging.ProtocolData(ctx, s.protocolDataDir, rpc, "Request", "Config", req.Config)
1566+
1567+
ctx = tf6serverlogging.DownstreamRequest(ctx)
1568+
1569+
server, ok := s.downstream.(tfprotov6.StateStoreServer)
1570+
if !ok {
1571+
logging.ProtocolError(ctx, "ProviderServer does not implement ConfigureStateStore")
1572+
1573+
protoResp := &tfplugin6.ConfigureStateStore_Response{
1574+
Diagnostics: []*tfplugin6.Diagnostic{
1575+
{
1576+
Severity: tfplugin6.Diagnostic_ERROR,
1577+
Summary: "Provider ConfigureStateStore Not Implemented",
1578+
Detail: "A ConfigureStateStore call was received by the provider, however the provider does not implement the call. " +
1579+
"Either upgrade the provider to a version that implements state store or this is a bug in Terraform that should be reported to the Terraform maintainers.",
1580+
},
1581+
},
1582+
}
1583+
1584+
return protoResp, nil
1585+
}
1586+
1587+
resp, err := server.ConfigureStateStore(ctx, req)
1588+
1589+
if err != nil {
1590+
logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err})
1591+
return nil, err
1592+
}
1593+
1594+
tf6serverlogging.DownstreamResponse(ctx, resp.Diagnostics)
1595+
1596+
protoResp := toproto.ConfigureStateStore_Response(resp)
1597+
1598+
return protoResp, nil
1599+
}
1600+
15071601
func invalidDeferredResponseDiag(reason tfprotov6.DeferredReason) *tfprotov6.Diagnostic {
15081602
return &tfprotov6.Diagnostic{
15091603
Severity: tfprotov6.DiagnosticSeverityError,

0 commit comments

Comments
 (0)