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
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ toolchain go1.23.7

require (
github.com/google/go-cmp v0.7.0
github.com/hashicorp/terraform-plugin-go v0.28.0
github.com/hashicorp/terraform-plugin-go v0.28.1-0.20250604150620-c6d59498a4e1
github.com/hashicorp/terraform-plugin-log v0.9.0
google.golang.org/grpc v1.72.1
google.golang.org/grpc v1.72.2
)

require (
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ github.com/hashicorp/go-plugin v1.6.3 h1:xgHB+ZUSYeuJi96WtxEjzi23uh7YQpznjGh0U0U
github.com/hashicorp/go-plugin v1.6.3/go.mod h1:MRobyh+Wc/nYy1V4KAXUiYfzxoYhs7V1mlH1Z7iY2h0=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/terraform-plugin-go v0.28.0 h1:zJmu2UDwhVN0J+J20RE5huiF3XXlTYVIleaevHZgKPA=
github.com/hashicorp/terraform-plugin-go v0.28.0/go.mod h1:FDa2Bb3uumkTGSkTFpWSOwWJDwA7bf3vdP3ltLDTH6o=
github.com/hashicorp/terraform-plugin-go v0.28.1-0.20250604150620-c6d59498a4e1 h1:TbYGMFWFJDeGgLf5r/vZ8U7sV/f8dg3PR/tDDV4lw/I=
github.com/hashicorp/terraform-plugin-go v0.28.1-0.20250604150620-c6d59498a4e1/go.mod h1:2t+AK4nKnRw39xPaCHHEMz79e8BIZoEWsSsVUkC8jVU=
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
github.com/hashicorp/terraform-registry-address v0.2.5 h1:2GTftHqmUhVOeuu9CW3kwDkRe4pcBDq0uuK5VJngU1M=
Expand Down Expand Up @@ -80,8 +80,8 @@ golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ=
google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA=
google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8=
google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
11 changes: 11 additions & 0 deletions internal/tf5testserver/tf5testserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ type TestServer struct {
ValidateDataSourceConfigCalled map[string]bool

ValidateResourceTypeConfigCalled map[string]bool

ValidateListResourceConfigCalled map[string]bool
}

func (s *TestServer) ProviderServer() tfprotov5.ProviderServer {
Expand Down Expand Up @@ -269,6 +271,15 @@ func (s *TestServer) ValidateResourceTypeConfig(_ context.Context, req *tfprotov
return nil, nil
}

func (s *TestServer) ValidateListResourceConfig(_ context.Context, req *tfprotov5.ValidateListResourceConfigRequest) (*tfprotov5.ValidateListResourceConfigResponse, error) {
if s.ValidateListResourceConfigCalled == nil {
s.ValidateListResourceConfigCalled = make(map[string]bool)
}

s.ValidateListResourceConfigCalled[req.TypeName] = true
return nil, nil
}

func (s *TestServer) PrepareProviderConfig(_ context.Context, req *tfprotov5.PrepareProviderConfigRequest) (*tfprotov5.PrepareProviderConfigResponse, error) {
s.PrepareProviderConfigCalled = true
return s.PrepareProviderConfigResponse, nil
Expand Down
11 changes: 11 additions & 0 deletions internal/tf6testserver/tf6testserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ type TestServer struct {
ValidateProviderConfigResponse *tfprotov6.ValidateProviderConfigResponse

ValidateResourceConfigCalled map[string]bool

ValidateListResourceConfigCalled map[string]bool
}

func (s *TestServer) ProviderServer() tfprotov6.ProviderServer {
Expand Down Expand Up @@ -273,3 +275,12 @@ func (s *TestServer) ValidateProviderConfig(_ context.Context, req *tfprotov6.Va
s.ValidateProviderConfigCalled = true
return s.ValidateProviderConfigResponse, nil
}

func (s *TestServer) ValidateListResourceConfig(_ context.Context, req *tfprotov6.ValidateListResourceConfigRequest) (*tfprotov6.ValidateListResourceConfigResponse, error) {
if s.ValidateListResourceConfigCalled == nil {
s.ValidateListResourceConfigCalled = make(map[string]bool)
}

s.ValidateListResourceConfigCalled[req.TypeName] = true
return nil, nil
}
39 changes: 39 additions & 0 deletions internal/tfprotov5tov6/tfprotov5tov6.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ func EphemeralResourceMetadata(in tfprotov5.EphemeralResourceMetadata) tfprotov6
}
}

func ListResourceMetadata(in tfprotov5.ListResourceMetadata) tfprotov6.ListResourceMetadata {
return tfprotov6.ListResourceMetadata{
TypeName: in.TypeName,
}
}

func Function(in *tfprotov5.Function) *tfprotov6.Function {
if in == nil {
return nil
Expand Down Expand Up @@ -298,6 +304,7 @@ func GetMetadataResponse(in *tfprotov5.GetMetadataResponse) *tfprotov6.GetMetada
DataSources: make([]tfprotov6.DataSourceMetadata, 0, len(in.DataSources)),
Diagnostics: Diagnostics(in.Diagnostics),
EphemeralResources: make([]tfprotov6.EphemeralResourceMetadata, 0, len(in.Resources)),
ListResources: make([]tfprotov6.ListResourceMetadata, 0, len(in.Resources)),
Functions: make([]tfprotov6.FunctionMetadata, 0, len(in.Functions)),
Resources: make([]tfprotov6.ResourceMetadata, 0, len(in.Resources)),
ServerCapabilities: ServerCapabilities(in.ServerCapabilities),
Expand All @@ -311,6 +318,10 @@ func GetMetadataResponse(in *tfprotov5.GetMetadataResponse) *tfprotov6.GetMetada
resp.EphemeralResources = append(resp.EphemeralResources, EphemeralResourceMetadata(ephemeralResource))
}

for _, listResource := range in.ListResources {
resp.ListResources = append(resp.ListResources, ListResourceMetadata(listResource))
}

for _, function := range in.Functions {
resp.Functions = append(resp.Functions, FunctionMetadata(function))
}
Expand Down Expand Up @@ -347,6 +358,12 @@ func GetProviderSchemaResponse(in *tfprotov5.GetProviderSchemaResponse) *tfproto
ephemeralResourceSchemas[k] = Schema(v)
}

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

for k, v := range in.ListResourceSchemas {
listResourceSchemas[k] = Schema(v)
}

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

for name, function := range in.Functions {
Expand All @@ -363,6 +380,7 @@ func GetProviderSchemaResponse(in *tfprotov5.GetProviderSchemaResponse) *tfproto
DataSourceSchemas: dataSourceSchemas,
Diagnostics: Diagnostics(in.Diagnostics),
EphemeralResourceSchemas: ephemeralResourceSchemas,
ListResourceSchemas: listResourceSchemas,
Functions: functions,
Provider: Schema(in.Provider),
ProviderMeta: Schema(in.ProviderMeta),
Expand Down Expand Up @@ -977,3 +995,24 @@ func ValidateResourceConfigResponse(in *tfprotov5.ValidateResourceTypeConfigResp
Diagnostics: Diagnostics(in.Diagnostics),
}
}

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

return &tfprotov6.ValidateListResourceConfigRequest{
Config: DynamicValue(in.Config),
TypeName: in.TypeName,
}
}

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

return &tfprotov6.ValidateListResourceConfigResponse{
Diagnostics: Diagnostics(in.Diagnostics),
}
}
92 changes: 92 additions & 0 deletions internal/tfprotov5tov6/tfprotov5tov6_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ var (
TypeName: "test_ephemeral_resource",
}

testTfprotov5ListResourceMetadata tfprotov5.ListResourceMetadata = tfprotov5.ListResourceMetadata{
TypeName: "test_list_resource",
}

testTfprotov6ListResourceMetadata tfprotov6.ListResourceMetadata = tfprotov6.ListResourceMetadata{
TypeName: "test_list_resource",
}

testTfprotov5Function *tfprotov5.Function = &tfprotov5.Function{
Parameters: []*tfprotov5.FunctionParameter{},
Return: &tfprotov5.FunctionReturn{
Expand Down Expand Up @@ -921,6 +929,9 @@ func TestGetMetadataResponse(t *testing.T) {
EphemeralResources: []tfprotov5.EphemeralResourceMetadata{
testTfprotov5EphemeralResourceMetadata,
},
ListResources: []tfprotov5.ListResourceMetadata{
testTfprotov5ListResourceMetadata,
},
Functions: []tfprotov5.FunctionMetadata{
testTfprotov5FunctionMetadata,
},
Expand All @@ -936,6 +947,9 @@ func TestGetMetadataResponse(t *testing.T) {
EphemeralResources: []tfprotov6.EphemeralResourceMetadata{
testTfprotov6EphemeralResourceMetadata,
},
ListResources: []tfprotov6.ListResourceMetadata{
testTfprotov6ListResourceMetadata,
},
Functions: []tfprotov6.FunctionMetadata{
testTfprotov6FunctionMetadata,
},
Expand Down Expand Up @@ -1011,6 +1025,9 @@ func TestGetProviderSchemaResponse(t *testing.T) {
EphemeralResourceSchemas: map[string]*tfprotov5.Schema{
"test_ephemeral_resource": testTfprotov5Schema,
},
ListResourceSchemas: map[string]*tfprotov5.Schema{
"test_list_resource": testTfprotov5Schema,
},
Functions: map[string]*tfprotov5.Function{
"test_function": testTfprotov5Function,
},
Expand All @@ -1028,6 +1045,9 @@ func TestGetProviderSchemaResponse(t *testing.T) {
EphemeralResourceSchemas: map[string]*tfprotov6.Schema{
"test_ephemeral_resource": testTfprotov6Schema,
},
ListResourceSchemas: map[string]*tfprotov6.Schema{
"test_list_resource": testTfprotov6Schema,
},
Functions: map[string]*tfprotov6.Function{
"test_function": testTfprotov6Function,
},
Expand Down Expand Up @@ -2898,6 +2918,78 @@ func TestValidateResourceConfigResponse(t *testing.T) {
}
}

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

testCases := map[string]struct {
in *tfprotov5.ValidateListResourceConfigRequest
expected *tfprotov6.ValidateListResourceConfigRequest
}{
"nil": {
in: nil,
expected: nil,
},
"all-valid-fields": {
in: &tfprotov5.ValidateListResourceConfigRequest{
Config: &testTfprotov5DynamicValue,
TypeName: "test_list_resource",
},
expected: &tfprotov6.ValidateListResourceConfigRequest{
Config: &testTfprotov6DynamicValue,
TypeName: "test_list_resource",
},
},
}

for name, testCase := range testCases {

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

got := tfprotov5tov6.ValidateListResourceConfigRequest(testCase.in)

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

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

testCases := map[string]struct {
in *tfprotov5.ValidateListResourceConfigResponse
expected *tfprotov6.ValidateListResourceConfigResponse
}{
"nil": {
in: nil,
expected: nil,
},
"all-valid-fields": {
in: &tfprotov5.ValidateListResourceConfigResponse{
Diagnostics: testTfprotov5Diagnostics,
},
expected: &tfprotov6.ValidateListResourceConfigResponse{
Diagnostics: testTfprotov6Diagnostics,
},
},
}

for name, testCase := range testCases {

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

got := tfprotov5tov6.ValidateListResourceConfigResponse(testCase.in)

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

func pointer[T any](value T) *T {
return &value
}
45 changes: 45 additions & 0 deletions internal/tfprotov6tov5/tfprotov6tov5.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,12 @@ func EphemeralResourceMetadata(in tfprotov6.EphemeralResourceMetadata) tfprotov5
}
}

func ListResourceMetadata(in tfprotov6.ListResourceMetadata) tfprotov5.ListResourceMetadata {
return tfprotov5.ListResourceMetadata{
TypeName: in.TypeName,
}
}

func Function(in *tfprotov6.Function) *tfprotov5.Function {
if in == nil {
return nil
Expand Down Expand Up @@ -303,6 +309,7 @@ func GetMetadataResponse(in *tfprotov6.GetMetadataResponse) *tfprotov5.GetMetada
DataSources: make([]tfprotov5.DataSourceMetadata, 0, len(in.DataSources)),
Diagnostics: Diagnostics(in.Diagnostics),
EphemeralResources: make([]tfprotov5.EphemeralResourceMetadata, 0, len(in.Resources)),
ListResources: make([]tfprotov5.ListResourceMetadata, 0, len(in.Resources)),
Functions: make([]tfprotov5.FunctionMetadata, 0, len(in.Functions)),
Resources: make([]tfprotov5.ResourceMetadata, 0, len(in.Resources)),
ServerCapabilities: ServerCapabilities(in.ServerCapabilities),
Expand All @@ -316,6 +323,10 @@ func GetMetadataResponse(in *tfprotov6.GetMetadataResponse) *tfprotov5.GetMetada
resp.EphemeralResources = append(resp.EphemeralResources, EphemeralResourceMetadata(ephemeralResource))
}

for _, listResource := range in.ListResources {
resp.ListResources = append(resp.ListResources, ListResourceMetadata(listResource))
}

for _, function := range in.Functions {
resp.Functions = append(resp.Functions, FunctionMetadata(function))
}
Expand Down Expand Up @@ -364,6 +375,18 @@ func GetProviderSchemaResponse(in *tfprotov6.GetProviderSchemaResponse) (*tfprot
ephemeralResourceSchemas[k] = v5Schema
}

listResourceSchemas := make(map[string]*tfprotov5.Schema, len(in.ListResourceSchemas))

for k, v := range in.ListResourceSchemas {
v5Schema, err := Schema(v)

if err != nil {
return nil, fmt.Errorf("unable to convert list resource %q schema: %w", k, err)
}

listResourceSchemas[k] = v5Schema
}

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

for name, function := range in.Functions {
Expand Down Expand Up @@ -398,6 +421,7 @@ func GetProviderSchemaResponse(in *tfprotov6.GetProviderSchemaResponse) (*tfprot
DataSourceSchemas: dataSourceSchemas,
Diagnostics: Diagnostics(in.Diagnostics),
EphemeralResourceSchemas: ephemeralResourceSchemas,
ListResourceSchemas: listResourceSchemas,
Functions: functions,
Provider: provider,
ProviderMeta: providerMeta,
Expand Down Expand Up @@ -1038,3 +1062,24 @@ func ValidateResourceTypeConfigResponse(in *tfprotov6.ValidateResourceConfigResp
Diagnostics: Diagnostics(in.Diagnostics),
}
}

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

return &tfprotov5.ValidateListResourceConfigRequest{
Config: DynamicValue(in.Config),
TypeName: in.TypeName,
}
}

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

return &tfprotov5.ValidateListResourceConfigResponse{
Diagnostics: Diagnostics(in.Diagnostics),
}
}
Loading