Skip to content

Commit 62ca775

Browse files
authored
tfprotov5+tfprotov6: Require FunctionServer in ProviderServer and MoveResourceState in ResourceServer (#388)
Reference: #353 Reference: #363 This removes the temporary handling to smoothly release the new Terraform 1.8 and later RPC handling for provider servers. These changes codify this Go module's desired design that it reflects the protocol via its required implementations.
1 parent 1861b52 commit 62ca775

File tree

9 files changed

+56
-150
lines changed

9 files changed

+56
-150
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
kind: BREAKING CHANGES
2+
body: 'tfprotov5+tfprotov6: `FunctionServer` interface is now required in `ProviderServer`.
3+
Implementations not needing function support can return errors from the `GetFunctions`
4+
and `CallFunction` methods.'
5+
time: 2024-03-11T09:32:08.806864-04:00
6+
custom:
7+
Issue: "388"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
kind: BREAKING CHANGES
2+
body: 'tfprotov5+tfprotov6: `MoveResourceState` method is now required in
3+
`ResourceServer`. Implementations not needing move state support can return
4+
errors from the `MoveResourceState` method.'
5+
time: 2024-03-11T09:34:36.800884-04:00
6+
custom:
7+
Issue: "388"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
kind: NOTES
2+
body: 'all: To prevent compilation errors, ensure your Go module is updated to at
3+
4+
terraform-plugin-sdk/[email protected], and [email protected] before
5+
upgrading this dependency.'
6+
time: 2024-03-11T09:37:36.503168-04:00
7+
custom:
8+
Issue: "388"

tfprotov5/provider.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,7 @@ type ProviderServer interface {
5353
// are a handy interface for defining what a function is to
5454
// terraform-plugin-go, so they are their own interface that is composed
5555
// into ProviderServer.
56-
//
57-
// This will be required in an upcoming release.
58-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353
59-
// FunctionServer
56+
FunctionServer
6057
}
6158

6259
// GetMetadataRequest represents a GetMetadata RPC request.

tfprotov5/resource.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,24 @@ type ResourceServer interface {
5252
// specified by the passed ID and return it as one or more resource
5353
// states for Terraform to assume control of.
5454
ImportResourceState(context.Context, *ImportResourceStateRequest) (*ImportResourceStateResponse, error)
55+
56+
// MoveResourceState is called when Terraform is asked to change a resource
57+
// type for an existing resource. The provider must accept the change as
58+
// valid by ensuring the source resource type, schema version, and provider
59+
// address are compatible to convert the source state into the target
60+
// resource type and latest state version.
61+
//
62+
// This functionality is only supported in Terraform 1.8 and later. The
63+
// provider must have enabled the MoveResourceState server capability to
64+
// enable these requests.
65+
MoveResourceState(context.Context, *MoveResourceStateRequest) (*MoveResourceStateResponse, error)
5566
}
5667

5768
// ResourceServerWithMoveResourceState is a temporary interface for servers
5869
// to implement MoveResourceState RPC handling.
5970
//
60-
// Deprecated: The MoveResourceState method will be moved into the
61-
// ResourceServer interface and this interface will be removed in a future
62-
// version.
71+
// Deprecated: This interface will be removed in a future version. Use
72+
// ResourceServer instead.
6373
type ResourceServerWithMoveResourceState interface {
6474
ResourceServer
6575

tfprotov5/tf5server/server.go

+3-68
Original file line numberDiff line numberDiff line change
@@ -900,37 +900,11 @@ func (s *server) MoveResourceState(ctx context.Context, protoReq *tfplugin5.Move
900900
logging.ProtocolTrace(ctx, "Received request")
901901
defer logging.ProtocolTrace(ctx, "Served request")
902902

903-
// Remove this check and error in preference of
904-
// s.downstream.MoveResourceState below once ResourceServer interface
905-
// implements the MoveResourceState method.
906-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/363
907-
// nolint:staticcheck
908-
resourceServerWMRS, ok := s.downstream.(tfprotov5.ResourceServerWithMoveResourceState)
909-
910-
if !ok {
911-
logging.ProtocolError(ctx, "ProviderServer does not implement ResourceServerWithMoveResourceState")
912-
913-
protoResp := &tfplugin5.MoveResourceState_Response{
914-
Diagnostics: []*tfplugin5.Diagnostic{
915-
{
916-
Severity: tfplugin5.Diagnostic_ERROR,
917-
Summary: "Provider Move Resource State Not Implemented",
918-
Detail: "A MoveResourceState call was received by the provider, however the provider does not implement the call. " +
919-
"Either upgrade the provider to a version that implements move resource state support or this is a bug in Terraform that should be reported to the Terraform maintainers.",
920-
},
921-
},
922-
}
923-
924-
return protoResp, nil
925-
}
926-
927903
req := fromproto.MoveResourceStateRequest(protoReq)
928904

929905
ctx = tf5serverlogging.DownstreamRequest(ctx)
930906

931-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/363
932-
// resp, err := s.downstream.MoveResourceState(ctx, req)
933-
resp, err := resourceServerWMRS.MoveResourceState(ctx, req)
907+
resp, err := s.downstream.MoveResourceState(ctx, req)
934908

935909
if err != nil {
936910
logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err})
@@ -954,26 +928,6 @@ func (s *server) CallFunction(ctx context.Context, protoReq *tfplugin5.CallFunct
954928
logging.ProtocolTrace(ctx, "Received request")
955929
defer logging.ProtocolTrace(ctx, "Served request")
956930

957-
// Remove this check and error in preference of s.downstream.CallFunction
958-
// below once ProviderServer interface requires FunctionServer.
959-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353
960-
functionServer, ok := s.downstream.(tfprotov5.FunctionServer)
961-
962-
if !ok {
963-
logging.ProtocolError(ctx, "ProviderServer does not implement FunctionServer")
964-
965-
text := "Provider Functions Not Implemented: A provider-defined function call was received by the provider, however the provider does not implement functions. " +
966-
"Either upgrade the provider to a version that implements provider-defined functions or this is a bug in Terraform that should be reported to the Terraform maintainers."
967-
968-
protoResp := &tfplugin5.CallFunction_Response{
969-
Error: &tfplugin5.FunctionError{
970-
Text: text,
971-
},
972-
}
973-
974-
return protoResp, nil
975-
}
976-
977931
req := fromproto.CallFunctionRequest(protoReq)
978932

979933
for position, argument := range req.Arguments {
@@ -982,9 +936,7 @@ func (s *server) CallFunction(ctx context.Context, protoReq *tfplugin5.CallFunct
982936

983937
ctx = tf5serverlogging.DownstreamRequest(ctx)
984938

985-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353
986-
// resp, err := s.downstream.CallFunction(ctx, req)
987-
resp, err := functionServer.CallFunction(ctx, req)
939+
resp, err := s.downstream.CallFunction(ctx, req)
988940

989941
if err != nil {
990942
logging.ProtocolError(ctx, "Error from downstream", map[string]any{logging.KeyError: err})
@@ -1007,28 +959,11 @@ func (s *server) GetFunctions(ctx context.Context, protoReq *tfplugin5.GetFuncti
1007959
logging.ProtocolTrace(ctx, "Received request")
1008960
defer logging.ProtocolTrace(ctx, "Served request")
1009961

1010-
// Remove this check and response in preference of s.downstream.GetFunctions
1011-
// below once ProviderServer interface requires FunctionServer.
1012-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353
1013-
functionServer, ok := s.downstream.(tfprotov5.FunctionServer)
1014-
1015-
if !ok {
1016-
logging.ProtocolWarn(ctx, "ProviderServer does not implement FunctionServer")
1017-
1018-
protoResp := &tfplugin5.GetFunctions_Response{
1019-
Functions: map[string]*tfplugin5.Function{},
1020-
}
1021-
1022-
return protoResp, nil
1023-
}
1024-
1025962
req := fromproto.GetFunctionsRequest(protoReq)
1026963

1027964
ctx = tf5serverlogging.DownstreamRequest(ctx)
1028965

1029-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353
1030-
// resp, err := s.downstream.GetFunctions(ctx, req)
1031-
resp, err := functionServer.GetFunctions(ctx, req)
966+
resp, err := s.downstream.GetFunctions(ctx, req)
1032967

1033968
if err != nil {
1034969
logging.ProtocolError(ctx, "Error from downstream", map[string]any{logging.KeyError: err})

tfprotov6/provider.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,7 @@ type ProviderServer interface {
5353
// are a handy interface for defining what a function is to
5454
// terraform-plugin-go, so they are their own interface that is composed
5555
// into ProviderServer.
56-
//
57-
// This will be required in an upcoming release.
58-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353
59-
// FunctionServer
56+
FunctionServer
6057
}
6158

6259
// GetMetadataRequest represents a GetMetadata RPC request.

tfprotov6/resource.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,24 @@ type ResourceServer interface {
5252
// specified by the passed ID and return it as one or more resource
5353
// states for Terraform to assume control of.
5454
ImportResourceState(context.Context, *ImportResourceStateRequest) (*ImportResourceStateResponse, error)
55+
56+
// MoveResourceState is called when Terraform is asked to change a resource
57+
// type for an existing resource. The provider must accept the change as
58+
// valid by ensuring the source resource type, schema version, and provider
59+
// address are compatible to convert the source state into the target
60+
// resource type and latest state version.
61+
//
62+
// This functionality is only supported in Terraform 1.8 and later. The
63+
// provider must have enabled the MoveResourceState server capability to
64+
// enable these requests.
65+
MoveResourceState(context.Context, *MoveResourceStateRequest) (*MoveResourceStateResponse, error)
5566
}
5667

5768
// ResourceServerWithMoveResourceState is a temporary interface for servers
5869
// to implement MoveResourceState RPC handling.
5970
//
60-
// Deprecated: The MoveResourceState method will be moved into the
61-
// ResourceServer interface and this interface will be removed in a future
62-
// version.
71+
// Deprecated: This interface will be removed in a future version. Use
72+
// ResourceServer instead.
6373
type ResourceServerWithMoveResourceState interface {
6474
ResourceServer
6575

tfprotov6/tf6server/server.go

+3-68
Original file line numberDiff line numberDiff line change
@@ -900,37 +900,11 @@ func (s *server) MoveResourceState(ctx context.Context, protoReq *tfplugin6.Move
900900
logging.ProtocolTrace(ctx, "Received request")
901901
defer logging.ProtocolTrace(ctx, "Served request")
902902

903-
// Remove this check and error in preference of
904-
// s.downstream.MoveResourceState below once ResourceServer interface
905-
// implements the MoveResourceState method.
906-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/363
907-
// nolint:staticcheck
908-
resourceServerWMRS, ok := s.downstream.(tfprotov6.ResourceServerWithMoveResourceState)
909-
910-
if !ok {
911-
logging.ProtocolError(ctx, "ProviderServer does not implement ResourceServerWithMoveResourceState")
912-
913-
protoResp := &tfplugin6.MoveResourceState_Response{
914-
Diagnostics: []*tfplugin6.Diagnostic{
915-
{
916-
Severity: tfplugin6.Diagnostic_ERROR,
917-
Summary: "Provider Move Resource State Not Implemented",
918-
Detail: "A MoveResourceState call was received by the provider, however the provider does not implement the call. " +
919-
"Either upgrade the provider to a version that implements move resource state support or this is a bug in Terraform that should be reported to the Terraform maintainers.",
920-
},
921-
},
922-
}
923-
924-
return protoResp, nil
925-
}
926-
927903
req := fromproto.MoveResourceStateRequest(protoReq)
928904

929905
ctx = tf6serverlogging.DownstreamRequest(ctx)
930906

931-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/363
932-
// resp, err := s.downstream.MoveResourceState(ctx, req)
933-
resp, err := resourceServerWMRS.MoveResourceState(ctx, req)
907+
resp, err := s.downstream.MoveResourceState(ctx, req)
934908

935909
if err != nil {
936910
logging.ProtocolError(ctx, "Error from downstream", map[string]interface{}{logging.KeyError: err})
@@ -954,26 +928,6 @@ func (s *server) CallFunction(ctx context.Context, protoReq *tfplugin6.CallFunct
954928
logging.ProtocolTrace(ctx, "Received request")
955929
defer logging.ProtocolTrace(ctx, "Served request")
956930

957-
// Remove this check and error in preference of s.downstream.CallFunction
958-
// below once ProviderServer interface requires FunctionServer.
959-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353
960-
functionServer, ok := s.downstream.(tfprotov6.FunctionServer)
961-
962-
if !ok {
963-
logging.ProtocolError(ctx, "ProviderServer does not implement FunctionServer")
964-
965-
text := "Provider Functions Not Implemented: A provider-defined function call was received by the provider, however the provider does not implement functions. " +
966-
"Either upgrade the provider to a version that implements provider-defined functions or this is a bug in Terraform that should be reported to the Terraform maintainers."
967-
968-
protoResp := &tfplugin6.CallFunction_Response{
969-
Error: &tfplugin6.FunctionError{
970-
Text: text,
971-
},
972-
}
973-
974-
return protoResp, nil
975-
}
976-
977931
req := fromproto.CallFunctionRequest(protoReq)
978932

979933
for position, argument := range req.Arguments {
@@ -982,9 +936,7 @@ func (s *server) CallFunction(ctx context.Context, protoReq *tfplugin6.CallFunct
982936

983937
ctx = tf6serverlogging.DownstreamRequest(ctx)
984938

985-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353
986-
// resp, err := s.downstream.CallFunction(ctx, req)
987-
resp, err := functionServer.CallFunction(ctx, req)
939+
resp, err := s.downstream.CallFunction(ctx, req)
988940

989941
if err != nil {
990942
logging.ProtocolError(ctx, "Error from downstream", map[string]any{logging.KeyError: err})
@@ -1007,28 +959,11 @@ func (s *server) GetFunctions(ctx context.Context, protoReq *tfplugin6.GetFuncti
1007959
logging.ProtocolTrace(ctx, "Received request")
1008960
defer logging.ProtocolTrace(ctx, "Served request")
1009961

1010-
// Remove this check and response in preference of s.downstream.GetFunctions
1011-
// below once ProviderServer interface requires FunctionServer.
1012-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353
1013-
functionServer, ok := s.downstream.(tfprotov6.FunctionServer)
1014-
1015-
if !ok {
1016-
logging.ProtocolWarn(ctx, "ProviderServer does not implement FunctionServer")
1017-
1018-
protoResp := &tfplugin6.GetFunctions_Response{
1019-
Functions: map[string]*tfplugin6.Function{},
1020-
}
1021-
1022-
return protoResp, nil
1023-
}
1024-
1025962
req := fromproto.GetFunctionsRequest(protoReq)
1026963

1027964
ctx = tf6serverlogging.DownstreamRequest(ctx)
1028965

1029-
// Reference: https://github.com/hashicorp/terraform-plugin-go/issues/353
1030-
// resp, err := s.downstream.GetFunctions(ctx, req)
1031-
resp, err := functionServer.GetFunctions(ctx, req)
966+
resp, err := s.downstream.GetFunctions(ctx, req)
1032967

1033968
if err != nil {
1034969
logging.ProtocolError(ctx, "Error from downstream", map[string]any{logging.KeyError: err})

0 commit comments

Comments
 (0)