Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changes/unreleased/ENHANCEMENTS-20230707-100231.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: ENHANCEMENTS
body: 'tfprotov5: Added `ServerCapabilities` type `GetProviderSchemaOptional` field,
which when enabled can signal that the provider supports RPC operations without
the `GetProviderSchema` RPC being called first'
time: 2023-07-07T10:02:31.242394-04:00
custom:
Issue: "310"
7 changes: 7 additions & 0 deletions .changes/unreleased/ENHANCEMENTS-20230707-100339.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: ENHANCEMENTS
body: 'tfprotov6: Added `ServerCapabilities` type `GetProviderSchemaOptional` field,
which when enabled can signal that the provider supports RPC operations without
the `GetProviderSchema` RPC being called first'
time: 2023-07-07T10:03:39.802189-04:00
custom:
Issue: "310"
5 changes: 5 additions & 0 deletions .changes/unreleased/FEATURES-20230824-152200.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: FEATURES
body: 'tfprotov5: Upgraded protocol to 5.4 and implemented `GetMetadata` RPC'
time: 2023-08-24T15:22:00.773731-04:00
custom:
Issue: "310"
5 changes: 5 additions & 0 deletions .changes/unreleased/FEATURES-20230824-152220.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: FEATURES
body: 'tfprotov6: Upgraded protocol to 6.4 and implemented `GetMetadata` RPC'
time: 2023-08-24T15:22:20.285837-04:00
custom:
Issue: "310"
7 changes: 7 additions & 0 deletions .changes/unreleased/NOTES-20230824-153956.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: NOTES
body: 'all: If using terraform-plugin-framework, terraform-plugin-mux, or terraform-plugin-sdk,
only upgrade this Go module when upgrading those Go modules or you may receive
a `missing GetMetadata method` error when compiling'
time: 2023-08-24T15:39:56.697018-04:00
custom:
Issue: "310"
6 changes: 6 additions & 0 deletions internal/logging/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,10 @@ const (

// The protocol version being used, as a string, such as "6"
KeyProtocolVersion = "tf_proto_version"

// Whether the GetProviderSchemaOptional server capability is enabled
KeyServerCapabilityGetProviderSchemaOptional = "tf_server_capability_get_provider_schema_optional"

// Whether the PlanDestroy server capability is enabled
KeyServerCapabilityPlanDestroy = "tf_server_capability_plan_destroy"
)
7 changes: 7 additions & 0 deletions tfprotov5/data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import (
"context"
)

// DataSourceMetadata describes metadata for a data resource in the GetMetadata
// RPC.
type DataSourceMetadata struct {
// TypeName is the name of the data resource.
TypeName string
}

// DataSourceServer is an interface containing the methods a data source
// implementation needs to fill.
type DataSourceServer interface {
Expand Down
10 changes: 10 additions & 0 deletions tfprotov5/internal/fromproto/data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ import (
"github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5"
)

func DataSourceMetadata(in *tfplugin5.GetMetadata_DataSourceMetadata) *tfprotov5.DataSourceMetadata {
if in == nil {
return nil
}

return &tfprotov5.DataSourceMetadata{
TypeName: in.TypeName,
}
}

func ValidateDataSourceConfigRequest(in *tfplugin5.ValidateDataSourceConfig_Request) (*tfprotov5.ValidateDataSourceConfigRequest, error) {
resp := &tfprotov5.ValidateDataSourceConfigRequest{
TypeName: in.TypeName,
Expand Down
34 changes: 34 additions & 0 deletions tfprotov5/internal/fromproto/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,40 @@ import (
"github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5"
)

func GetMetadataRequest(in *tfplugin5.GetMetadata_Request) (*tfprotov5.GetMetadataRequest, error) {
return &tfprotov5.GetMetadataRequest{}, nil
}

func GetMetadataResponse(in *tfplugin5.GetMetadata_Response) (*tfprotov5.GetMetadataResponse, error) {
if in == nil {
return nil, nil
}

resp := &tfprotov5.GetMetadataResponse{
DataSources: make([]tfprotov5.DataSourceMetadata, 0, len(in.DataSources)),
Resources: make([]tfprotov5.ResourceMetadata, 0, len(in.Resources)),
ServerCapabilities: ServerCapabilities(in.ServerCapabilities),
}

for _, datasource := range in.DataSources {
resp.DataSources = append(resp.DataSources, *DataSourceMetadata(datasource))
}

for _, resource := range in.Resources {
resp.Resources = append(resp.Resources, *ResourceMetadata(resource))
}

diags, err := Diagnostics(in.Diagnostics)

if err != nil {
return resp, err
}

resp.Diagnostics = diags

return resp, nil
}

func GetProviderSchemaRequest(in *tfplugin5.GetProviderSchema_Request) (*tfprotov5.GetProviderSchemaRequest, error) {
return &tfprotov5.GetProviderSchemaRequest{}, nil
}
Expand Down
10 changes: 10 additions & 0 deletions tfprotov5/internal/fromproto/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ import (
"github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5"
)

func ResourceMetadata(in *tfplugin5.GetMetadata_ResourceMetadata) *tfprotov5.ResourceMetadata {
if in == nil {
return nil
}

return &tfprotov5.ResourceMetadata{
TypeName: in.TypeName,
}
}

func ValidateResourceTypeConfigRequest(in *tfplugin5.ValidateResourceTypeConfig_Request) (*tfprotov5.ValidateResourceTypeConfigRequest, error) {
resp := &tfprotov5.ValidateResourceTypeConfigRequest{
TypeName: in.TypeName,
Expand Down
20 changes: 20 additions & 0 deletions tfprotov5/internal/fromproto/server_capabilities.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package fromproto

import (
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
"github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5"
)

func ServerCapabilities(in *tfplugin5.ServerCapabilities) *tfprotov5.ServerCapabilities {
if in == nil {
return nil
}

return &tfprotov5.ServerCapabilities{
GetProviderSchemaOptional: in.GetProviderSchemaOptional,
PlanDestroy: in.PlanDestroy,
}
}
26 changes: 26 additions & 0 deletions tfprotov5/internal/tf5serverlogging/server_capabilities.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package tf5serverlogging

import (
"context"

"github.com/hashicorp/terraform-plugin-go/internal/logging"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
)

// ServerCapabilities generates a TRACE "Announced server capabilities" log.
func ServerCapabilities(ctx context.Context, capabilities *tfprotov5.ServerCapabilities) {
responseFields := map[string]interface{}{
logging.KeyServerCapabilityGetProviderSchemaOptional: false,
logging.KeyServerCapabilityPlanDestroy: false,
}

if capabilities != nil {
responseFields[logging.KeyServerCapabilityGetProviderSchemaOptional] = capabilities.GetProviderSchemaOptional
responseFields[logging.KeyServerCapabilityPlanDestroy] = capabilities.PlanDestroy
}

logging.ProtocolTrace(ctx, "Announced server capabilities", responseFields)
}
104 changes: 104 additions & 0 deletions tfprotov5/internal/tf5serverlogging/server_capabilities_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package tf5serverlogging_test

import (
"bytes"
"context"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-go/internal/logging"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
"github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tf5serverlogging"
"github.com/hashicorp/terraform-plugin-log/tfsdklog"
"github.com/hashicorp/terraform-plugin-log/tfsdklogtest"
)

func TestServerCapabilities(t *testing.T) {
t.Parallel()

testCases := map[string]struct {
capabilities *tfprotov5.ServerCapabilities
expected []map[string]interface{}
}{
"nil": {
capabilities: nil,
expected: []map[string]interface{}{
{
"@level": "trace",
"@message": "Announced server capabilities",
"@module": "sdk.proto",
"tf_server_capability_get_provider_schema_optional": false,
"tf_server_capability_plan_destroy": false,
},
},
},
"empty": {
capabilities: &tfprotov5.ServerCapabilities{},
expected: []map[string]interface{}{
{
"@level": "trace",
"@message": "Announced server capabilities",
"@module": "sdk.proto",
"tf_server_capability_get_provider_schema_optional": false,
"tf_server_capability_plan_destroy": false,
},
},
},
"get_provider_schema_optional": {
capabilities: &tfprotov5.ServerCapabilities{
GetProviderSchemaOptional: true,
},
expected: []map[string]interface{}{
{
"@level": "trace",
"@message": "Announced server capabilities",
"@module": "sdk.proto",
"tf_server_capability_get_provider_schema_optional": true,
"tf_server_capability_plan_destroy": false,
},
},
},
"plan_destroy": {
capabilities: &tfprotov5.ServerCapabilities{
PlanDestroy: true,
},
expected: []map[string]interface{}{
{
"@level": "trace",
"@message": "Announced server capabilities",
"@module": "sdk.proto",
"tf_server_capability_get_provider_schema_optional": false,
"tf_server_capability_plan_destroy": true,
},
},
},
}

for name, testCase := range testCases {
name, testCase := name, testCase

t.Run(name, func(t *testing.T) {
t.Parallel()

var output bytes.Buffer

ctx := tfsdklogtest.RootLogger(context.Background(), &output)
ctx = logging.ProtoSubsystemContext(ctx, tfsdklog.Options{})

tf5serverlogging.ServerCapabilities(ctx, testCase.capabilities)

entries, err := tfsdklogtest.MultilineJSONDecode(&output)

if err != nil {
t.Fatalf("unable to read multiple line JSON: %s", err)
}

if diff := cmp.Diff(entries, testCase.expected); diff != "" {
t.Errorf("unexpected difference: %s", diff)
}
})
}
}
Loading