Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,7 @@ func (p PrimeNumberProvider) RenewEphemeralResource(ctx context.Context, request
func (p PrimeNumberProvider) CloseEphemeralResource(ctx context.Context, request *tfprotov5.CloseEphemeralResourceRequest) (*tfprotov5.CloseEphemeralResourceResponse, error) {
panic("not implemented")
}

func (p PrimeNumberProvider) GenerateResourceConfig(ctx context.Context, request *tfprotov5.GenerateResourceConfigRequest) (*tfprotov5.GenerateResourceConfigResponse, error) {
panic("not implemented")
}
9 changes: 9 additions & 0 deletions internal/logging/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,15 @@ func ActionContext(ctx context.Context, action string) context.Context {
return ctx
}

// GenerateResourceConfig injects the resource type into logger contexts.
func GenerateResourceConfigContext(ctx context.Context, action string) context.Context {
ctx = tfsdklog.SetField(ctx, KeyGenerateResourceConfigType, action)
ctx = tfsdklog.SubsystemSetField(ctx, SubsystemProto, KeyGenerateResourceConfigType, action)
ctx = tflog.SetField(ctx, KeyGenerateResourceConfigType, action)

return ctx
}

// RpcContext injects the RPC name into logger contexts.
func RpcContext(ctx context.Context, rpc string) context.Context {
ctx = tfsdklog.SetField(ctx, KeyRPC, rpc)
Expand Down
6 changes: 6 additions & 0 deletions internal/logging/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ const (
// The action being operated on
KeyActionType = "tf_action_type"

// The type of resource being operated on
KeyGenerateResourceConfigType = "tf_generate_resource_config_type"

// Path to protocol data file, such as "/tmp/example.json"
KeyProtocolDataFile = "tf_proto_data_file"

Expand All @@ -84,6 +87,9 @@ const (
// Whether the PlanDestroy server capability is enabled
KeyServerCapabilityPlanDestroy = "tf_server_capability_plan_destroy"

// Whether the PlanDestroy server capability is enabled
KeyServerCapabilityGenerateResourceConfig = "tf_server_capability_generate_resource_config"

// Whether the DeferralAllowed client capability is enabled
KeyClientCapabilityDeferralAllowed = "tf_client_capability_deferral_allowed"

Expand Down
24 changes: 24 additions & 0 deletions tfprotov5/generate_resource_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package tfprotov5

// GenerateResourceConfigRequest is the request Terraform sends when it wants to generate configuration
// from a resource's state value.
type GenerateResourceConfigRequest struct {
// TypeName is the name of the resource.
TypeName string

// State is the resource's state value.
State *DynamicValue
}

// GenerateResourceConfigResponse is the response from the provider containing the config value
// that can be generated by Terraform.
type GenerateResourceConfigResponse struct {
// Config contains the resource's config value.
Config *DynamicValue

// Diagnostics report errors or warnings related to the creation of the config value.
Diagnostics []*Diagnostic
}
20 changes: 20 additions & 0 deletions tfprotov5/internal/fromproto/generate_resource_config.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 GenerateResourceConfigRequest(in *tfplugin5.GenerateResourceConfig_Request) *tfprotov5.GenerateResourceConfigRequest {
if in == nil {
return nil
}

return &tfprotov5.GenerateResourceConfigRequest{
TypeName: in.TypeName,
State: DynamicValue(in.State),
}
}
60 changes: 60 additions & 0 deletions tfprotov5/internal/fromproto/generate_resource_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package fromproto_test

import (
"testing"

"github.com/google/go-cmp/cmp"

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

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

testCases := map[string]struct {
in *tfplugin5.GenerateResourceConfig_Request
expected *tfprotov5.GenerateResourceConfigRequest
}{
"nil": {
in: nil,
expected: nil,
},
"zero": {
in: &tfplugin5.GenerateResourceConfig_Request{},
expected: &tfprotov5.GenerateResourceConfigRequest{},
},
"State": {
in: &tfplugin5.GenerateResourceConfig_Request{
State: testTfplugin5DynamicValue(),
},
expected: &tfprotov5.GenerateResourceConfigRequest{
State: testTfprotov5DynamicValue(),
},
},
"TypeName": {
in: &tfplugin5.GenerateResourceConfig_Request{
TypeName: "test",
},
expected: &tfprotov5.GenerateResourceConfigRequest{
TypeName: "test",
},
},
}

for name, testCase := range testCases {
t.Run(name, func(t *testing.T) {
t.Parallel()

got := fromproto.GenerateResourceConfigRequest(testCase.in)

if diff := cmp.Diff(got, testCase.expected); diff != "" {
t.Errorf("unexpected difference: %s", diff)
}
})
}
}
2 changes: 2 additions & 0 deletions tfprotov5/internal/tf5serverlogging/server_capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ func ServerCapabilities(ctx context.Context, capabilities *tfprotov5.ServerCapab
logging.KeyServerCapabilityGetProviderSchemaOptional: false,
logging.KeyServerCapabilityMoveResourceState: false,
logging.KeyServerCapabilityPlanDestroy: false,
logging.KeyServerCapabilityGenerateResourceConfig: false,
}

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

logging.ProtocolTrace(ctx, "Announced server capabilities", responseFields)
Expand Down
21 changes: 21 additions & 0 deletions tfprotov5/internal/tf5serverlogging/server_capabilities_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func TestServerCapabilities(t *testing.T) {
"tf_server_capability_get_provider_schema_optional": false,
"tf_server_capability_move_resource_state": false,
"tf_server_capability_plan_destroy": false,
"tf_server_capability_generate_resource_config": false,
},
},
},
Expand All @@ -46,6 +47,7 @@ func TestServerCapabilities(t *testing.T) {
"tf_server_capability_get_provider_schema_optional": false,
"tf_server_capability_move_resource_state": false,
"tf_server_capability_plan_destroy": false,
"tf_server_capability_generate_resource_config": false,
},
},
},
Expand All @@ -61,6 +63,7 @@ func TestServerCapabilities(t *testing.T) {
"tf_server_capability_get_provider_schema_optional": true,
"tf_server_capability_move_resource_state": false,
"tf_server_capability_plan_destroy": false,
"tf_server_capability_generate_resource_config": false,
},
},
},
Expand All @@ -76,6 +79,7 @@ func TestServerCapabilities(t *testing.T) {
"tf_server_capability_get_provider_schema_optional": false,
"tf_server_capability_move_resource_state": true,
"tf_server_capability_plan_destroy": false,
"tf_server_capability_generate_resource_config": false,
},
},
},
Expand All @@ -91,6 +95,23 @@ func TestServerCapabilities(t *testing.T) {
"tf_server_capability_get_provider_schema_optional": false,
"tf_server_capability_move_resource_state": false,
"tf_server_capability_plan_destroy": true,
"tf_server_capability_generate_resource_config": false,
},
},
},
"generate_resource_config": {
capabilities: &tfprotov5.ServerCapabilities{
GenerateResourceConfig: 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_move_resource_state": false,
"tf_server_capability_plan_destroy": false,
"tf_server_capability_generate_resource_config": true,
},
},
},
Expand Down
Loading
Loading