Skip to content

Commit

Permalink
all: Initial provider defined functions implementation (#209)
Browse files Browse the repository at this point in the history
Reference: hashicorp/terraform-plugin-go#351

The next versions of the plugin protocol (5.5/6.5) include support for provider defined functions. This change includes initial implementation of that support including:

- Temporarily pointing at terraform-plugin-go with provider function support (will be pointed at final terraform-plugin-go release before merge)
- Updates to all provider server packages for new `GetFunctions` and `CallFunction` RPCs
  • Loading branch information
bflad authored Dec 14, 2023
1 parent 58143df commit 3d1b409
Show file tree
Hide file tree
Showing 33 changed files with 3,991 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changes/unreleased/FEATURES-20231107-141509.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: FEATURES
body: 'all: Upgrade protocol versions to support provider-defined functions'
time: 2023-11-07T14:15:09.783296-05:00
custom:
Issue: "209"
24 changes: 24 additions & 0 deletions internal/tf5testserver/tf5testserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ var _ tfprotov5.ProviderServer = &TestServer{}
type TestServer struct {
ApplyResourceChangeCalled map[string]bool

CallFunctionCalled map[string]bool

ConfigureProviderCalled bool
ConfigureProviderResponse *tfprotov5.ConfigureProviderResponse

GetFunctionsCalled bool
GetFunctionsResponse *tfprotov5.GetFunctionsResponse

GetMetadataCalled bool
GetMetadataResponse *tfprotov5.GetMetadataResponse

Expand Down Expand Up @@ -59,6 +64,15 @@ func (s *TestServer) ApplyResourceChange(_ context.Context, req *tfprotov5.Apply
return nil, nil
}

func (s *TestServer) CallFunction(_ context.Context, req *tfprotov5.CallFunctionRequest) (*tfprotov5.CallFunctionResponse, error) {
if s.CallFunctionCalled == nil {
s.CallFunctionCalled = make(map[string]bool)
}

s.CallFunctionCalled[req.Name] = true
return nil, nil
}

func (s *TestServer) ConfigureProvider(_ context.Context, _ *tfprotov5.ConfigureProviderRequest) (*tfprotov5.ConfigureProviderResponse, error) {
s.ConfigureProviderCalled = true

Expand All @@ -69,6 +83,16 @@ func (s *TestServer) ConfigureProvider(_ context.Context, _ *tfprotov5.Configure
return &tfprotov5.ConfigureProviderResponse{}, nil
}

func (s *TestServer) GetFunctions(_ context.Context, _ *tfprotov5.GetFunctionsRequest) (*tfprotov5.GetFunctionsResponse, error) {
s.GetFunctionsCalled = true

if s.GetFunctionsResponse != nil {
return s.GetFunctionsResponse, nil
}

return &tfprotov5.GetFunctionsResponse{}, nil
}

func (s *TestServer) GetMetadata(_ context.Context, _ *tfprotov5.GetMetadataRequest) (*tfprotov5.GetMetadataResponse, error) {
s.GetMetadataCalled = true

Expand Down
24 changes: 24 additions & 0 deletions internal/tf6testserver/tf6testserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ var _ tfprotov6.ProviderServer = &TestServer{}
type TestServer struct {
ApplyResourceChangeCalled map[string]bool

CallFunctionCalled map[string]bool

ConfigureProviderCalled bool
ConfigureProviderResponse *tfprotov6.ConfigureProviderResponse

GetFunctionsCalled bool
GetFunctionsResponse *tfprotov6.GetFunctionsResponse

GetMetadataCalled bool
GetMetadataResponse *tfprotov6.GetMetadataResponse

Expand Down Expand Up @@ -59,6 +64,15 @@ func (s *TestServer) ApplyResourceChange(_ context.Context, req *tfprotov6.Apply
return nil, nil
}

func (s *TestServer) CallFunction(_ context.Context, req *tfprotov6.CallFunctionRequest) (*tfprotov6.CallFunctionResponse, error) {
if s.CallFunctionCalled == nil {
s.CallFunctionCalled = make(map[string]bool)
}

s.CallFunctionCalled[req.Name] = true
return nil, nil
}

func (s *TestServer) ConfigureProvider(_ context.Context, _ *tfprotov6.ConfigureProviderRequest) (*tfprotov6.ConfigureProviderResponse, error) {
s.ConfigureProviderCalled = true

Expand All @@ -69,6 +83,16 @@ func (s *TestServer) ConfigureProvider(_ context.Context, _ *tfprotov6.Configure
return &tfprotov6.ConfigureProviderResponse{}, nil
}

func (s *TestServer) GetFunctions(_ context.Context, _ *tfprotov6.GetFunctionsRequest) (*tfprotov6.GetFunctionsResponse, error) {
s.GetFunctionsCalled = true

if s.GetFunctionsResponse != nil {
return s.GetFunctionsResponse, nil
}

return &tfprotov6.GetFunctionsResponse{}, nil
}

func (s *TestServer) GetMetadata(_ context.Context, _ *tfprotov6.GetMetadataRequest) (*tfprotov6.GetMetadataResponse, error) {
s.GetMetadataCalled = true

Expand Down
118 changes: 118 additions & 0 deletions internal/tfprotov5tov6/tfprotov5tov6.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,34 @@ func ApplyResourceChangeResponse(in *tfprotov5.ApplyResourceChangeResponse) *tfp
}
}

func CallFunctionRequest(in *tfprotov5.CallFunctionRequest) *tfprotov6.CallFunctionRequest {
if in == nil {
return nil
}

out := &tfprotov6.CallFunctionRequest{
Arguments: make([]*tfprotov6.DynamicValue, 0, len(in.Arguments)),
Name: in.Name,
}

for _, argument := range in.Arguments {
out.Arguments = append(out.Arguments, DynamicValue(argument))
}

return out
}

func CallFunctionResponse(in *tfprotov5.CallFunctionResponse) *tfprotov6.CallFunctionResponse {
if in == nil {
return nil
}

return &tfprotov6.CallFunctionResponse{
Diagnostics: Diagnostics(in.Diagnostics),
Result: DynamicValue(in.Result),
}
}

func ConfigureProviderRequest(in *tfprotov5.ConfigureProviderRequest) *tfprotov6.ConfigureProviderRequest {
if in == nil {
return nil
Expand Down Expand Up @@ -98,6 +126,84 @@ func DynamicValue(in *tfprotov5.DynamicValue) *tfprotov6.DynamicValue {
}
}

func Function(in *tfprotov5.Function) *tfprotov6.Function {
if in == nil {
return nil
}

out := &tfprotov6.Function{
DeprecationMessage: in.DeprecationMessage,
Description: in.Description,
DescriptionKind: StringKind(in.DescriptionKind),
Parameters: make([]*tfprotov6.FunctionParameter, 0, len(in.Parameters)),
Return: FunctionReturn(in.Return),
Summary: in.Summary,
VariadicParameter: FunctionParameter(in.VariadicParameter),
}

for _, parameter := range in.Parameters {
out.Parameters = append(out.Parameters, FunctionParameter(parameter))
}

return out
}

func FunctionMetadata(in tfprotov5.FunctionMetadata) tfprotov6.FunctionMetadata {
return tfprotov6.FunctionMetadata{
Name: in.Name,
}
}

func FunctionParameter(in *tfprotov5.FunctionParameter) *tfprotov6.FunctionParameter {
if in == nil {
return nil
}

return &tfprotov6.FunctionParameter{
AllowNullValue: in.AllowNullValue,
AllowUnknownValues: in.AllowUnknownValues,
Description: in.Description,
DescriptionKind: StringKind(in.DescriptionKind),
Name: in.Name,
Type: in.Type,
}
}

func FunctionReturn(in *tfprotov5.FunctionReturn) *tfprotov6.FunctionReturn {
if in == nil {
return nil
}

return &tfprotov6.FunctionReturn{
Type: in.Type,
}
}

func GetFunctionsRequest(in *tfprotov5.GetFunctionsRequest) *tfprotov6.GetFunctionsRequest {
if in == nil {
return nil
}

return &tfprotov6.GetFunctionsRequest{}
}

func GetFunctionsResponse(in *tfprotov5.GetFunctionsResponse) *tfprotov6.GetFunctionsResponse {
if in == nil {
return nil
}

functions := make(map[string]*tfprotov6.Function, len(in.Functions))

for name, function := range in.Functions {
functions[name] = Function(function)
}

return &tfprotov6.GetFunctionsResponse{
Diagnostics: Diagnostics(in.Diagnostics),
Functions: functions,
}
}

func GetMetadataRequest(in *tfprotov5.GetMetadataRequest) *tfprotov6.GetMetadataRequest {
if in == nil {
return nil
Expand All @@ -114,6 +220,7 @@ func GetMetadataResponse(in *tfprotov5.GetMetadataResponse) *tfprotov6.GetMetada
resp := &tfprotov6.GetMetadataResponse{
DataSources: make([]tfprotov6.DataSourceMetadata, 0, len(in.DataSources)),
Diagnostics: Diagnostics(in.Diagnostics),
Functions: make([]tfprotov6.FunctionMetadata, 0, len(in.Functions)),
Resources: make([]tfprotov6.ResourceMetadata, 0, len(in.Resources)),
ServerCapabilities: ServerCapabilities(in.ServerCapabilities),
}
Expand All @@ -122,6 +229,10 @@ func GetMetadataResponse(in *tfprotov5.GetMetadataResponse) *tfprotov6.GetMetada
resp.DataSources = append(resp.DataSources, DataSourceMetadata(datasource))
}

for _, function := range in.Functions {
resp.Functions = append(resp.Functions, FunctionMetadata(function))
}

for _, resource := range in.Resources {
resp.Resources = append(resp.Resources, ResourceMetadata(resource))
}
Expand All @@ -148,6 +259,12 @@ func GetProviderSchemaResponse(in *tfprotov5.GetProviderSchemaResponse) *tfproto
dataSourceSchemas[k] = Schema(v)
}

functions := make(map[string]*tfprotov6.Function, len(in.Functions))

for name, function := range in.Functions {
functions[name] = Function(function)
}

resourceSchemas := make(map[string]*tfprotov6.Schema, len(in.ResourceSchemas))

for k, v := range in.ResourceSchemas {
Expand All @@ -157,6 +274,7 @@ func GetProviderSchemaResponse(in *tfprotov5.GetProviderSchemaResponse) *tfproto
return &tfprotov6.GetProviderSchemaResponse{
DataSourceSchemas: dataSourceSchemas,
Diagnostics: Diagnostics(in.Diagnostics),
Functions: functions,
Provider: Schema(in.Provider),
ProviderMeta: Schema(in.ProviderMeta),
ResourceSchemas: resourceSchemas,
Expand Down
Loading

0 comments on commit 3d1b409

Please sign in to comment.