Skip to content
Draft
Show file tree
Hide file tree
Changes from 7 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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ require (
github.com/hashicorp/logutils v1.0.0
github.com/hashicorp/terraform-exec v0.25.0
github.com/hashicorp/terraform-json v0.27.2
github.com/hashicorp/terraform-plugin-go v0.30.0
github.com/hashicorp/terraform-plugin-go v0.30.1-0.20260224203057-7d789423e31f
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to us to update this before merging/releasing

github.com/hashicorp/terraform-plugin-log v0.10.0
github.com/mitchellh/copystructure v1.2.0
github.com/mitchellh/go-testing-interface v1.14.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ github.com/hashicorp/terraform-json v0.27.2 h1:BwGuzM6iUPqf9JYM/Z4AF1OJ5VVJEEzoK
github.com/hashicorp/terraform-json v0.27.2/go.mod h1:GzPLJ1PLdUG5xL6xn1OXWIjteQRT2CNT9o/6A9mi9hE=
github.com/hashicorp/terraform-plugin-go v0.30.0 h1:VmEiD0n/ewxbvV5VI/bYwNtlSEAXtHaZlSnyUUuQK6k=
github.com/hashicorp/terraform-plugin-go v0.30.0/go.mod h1:8d523ORAW8OHgA9e8JKg0ezL3XUO84H0A25o4NY/jRo=
github.com/hashicorp/terraform-plugin-go v0.30.1-0.20260224203057-7d789423e31f h1:Gn9urczv0KsRi0YrjI7kdzHNUT2zQ/HLi5lfiLY6oxY=
github.com/hashicorp/terraform-plugin-go v0.30.1-0.20260224203057-7d789423e31f/go.mod h1:8d523ORAW8OHgA9e8JKg0ezL3XUO84H0A25o4NY/jRo=
github.com/hashicorp/terraform-plugin-log v0.10.0 h1:eu2kW6/QBVdN4P3Ju2WiB2W3ObjkAsyfBsL3Wh1fj3g=
github.com/hashicorp/terraform-plugin-log v0.10.0/go.mod h1:/9RR5Cv2aAbrqcTSdNmY1NRHP4E3ekrXRGjqORpXyB0=
github.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk=
Expand Down
10 changes: 5 additions & 5 deletions helper/resource/testcase_providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,26 @@ func (c TestCase) providerConfig(_ context.Context, skipProviderBlock bool) stri
// is being used and not the others, but leaving it here just in case
// it does have a special purpose that wasn't being unit tested prior.
for name := range c.Providers {
providerBlocks.WriteString(fmt.Sprintf("provider %q {}\n", name))
fmt.Fprintf(&providerBlocks, "provider %q {}\n", name)
}

for name, externalProvider := range c.ExternalProviders {
if !skipProviderBlock {
providerBlocks.WriteString(fmt.Sprintf("provider %q {}\n", name))
fmt.Fprintf(&providerBlocks, "provider %q {}\n", name)
}

if externalProvider.Source == "" && externalProvider.VersionConstraint == "" {
continue
}

requiredProviderBlocks.WriteString(fmt.Sprintf(" %s = {\n", name))
fmt.Fprintf(&requiredProviderBlocks, " %s = {\n", name)

if externalProvider.Source != "" {
requiredProviderBlocks.WriteString(fmt.Sprintf(" source = %q\n", externalProvider.Source))
fmt.Fprintf(&requiredProviderBlocks, " source = %q\n", externalProvider.Source)
}

if externalProvider.VersionConstraint != "" {
requiredProviderBlocks.WriteString(fmt.Sprintf(" version = %q\n", externalProvider.VersionConstraint))
fmt.Fprintf(&requiredProviderBlocks, " version = %q\n", externalProvider.VersionConstraint)
}

requiredProviderBlocks.WriteString(" }\n")
Expand Down
8 changes: 4 additions & 4 deletions helper/resource/teststep_providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,21 @@ func (s TestStep) providerConfig(_ context.Context, skipProviderBlock bool) stri

for name, externalProvider := range s.ExternalProviders {
if !skipProviderBlock {
providerBlocks.WriteString(fmt.Sprintf("provider %q {}\n", name))
fmt.Fprintf(&providerBlocks, "provider %q {}\n", name)
}

if externalProvider.Source == "" && externalProvider.VersionConstraint == "" {
continue
}

requiredProviderBlocks.WriteString(fmt.Sprintf(" %s = {\n", name))
fmt.Fprintf(&requiredProviderBlocks, " %s = {\n", name)

if externalProvider.Source != "" {
requiredProviderBlocks.WriteString(fmt.Sprintf(" source = %q\n", externalProvider.Source))
fmt.Fprintf(&requiredProviderBlocks, " source = %q\n", externalProvider.Source)
}

if externalProvider.VersionConstraint != "" {
requiredProviderBlocks.WriteString(fmt.Sprintf(" version = %q\n", externalProvider.VersionConstraint))
fmt.Fprintf(&requiredProviderBlocks, " version = %q\n", externalProvider.VersionConstraint)
}

requiredProviderBlocks.WriteString(" }\n")
Expand Down
4 changes: 2 additions & 2 deletions helper/schema/field_reader_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,8 @@ func TestConfigFieldReader_computedComplexSet(t *testing.T) {
hashfunc := func(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
buf.WriteString(fmt.Sprintf("%s-", m["vhd_uri"].(string)))
fmt.Fprintf(&buf, "%s-", m["name"].(string))
fmt.Fprintf(&buf, "%s-", m["vhd_uri"].(string))
return hashcode.String(buf.String())
}

Expand Down
88 changes: 88 additions & 0 deletions helper/schema/grpc_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func (s *GRPCProviderServer) StopContext(ctx context.Context) context.Context {
func (s *GRPCProviderServer) serverCapabilities() *tfprotov5.ServerCapabilities {
return &tfprotov5.ServerCapabilities{
GetProviderSchemaOptional: true,
GenerateResourceConfig: true,
}
}

Expand Down Expand Up @@ -1785,6 +1786,93 @@ func (s *GRPCProviderServer) ImportResourceState(ctx context.Context, req *tfpro
return resp, nil
}

func (s *GRPCProviderServer) GenerateResourceConfig(ctx context.Context, req *tfprotov5.GenerateResourceConfigRequest) (*tfprotov5.GenerateResourceConfigResponse, error) {
ctx = logging.InitContext(ctx)

resp := &tfprotov5.GenerateResourceConfigResponse{}

schemaBlock := s.getResourceSchemaBlock(req.TypeName)

stateVal, err := msgpack.Unmarshal(req.State.MsgPack, schemaBlock.ImpliedType())
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(ctx, resp.Diagnostics, err)
return resp, nil
}

newConfigVal := stateVal

// Handle top level attributes and defaults
newConfigVal, err = cty.Transform(newConfigVal, func(path cty.Path, val cty.Value) (cty.Value, error) {
if val.IsNull() {
return val, nil
}

if len(path) == 0 {
return val, nil
}

ty := val.Type()
null := cty.NullVal(ty)

// find the attribute or block schema representing the value
attr := schemaBlock.AttributeByPath(path)
block := schemaBlock.BlockByPath(path)
switch {
case attr != nil:
// deprecated attributes
if attr.Deprecated {
return null, nil
}

// read-only attributes are not written in the configuration
if attr.Computed && !attr.Optional {
return null, nil
}

// The legacy SDK adds an Optional+Computed "id" attribute to the
// resource schema even if not defined in provider code.
// During validation, however, the presence of an extraneous "id"
// attribute in config will cause an error.
// Remove this attribute so we do not generate an "id" attribute
// where there is a risk that it is not in the real resource schema.
if path.Equals(cty.GetAttrPath("id")) && attr.Computed && attr.Optional {
return null, nil
}

// If we have "" for an optional value, assume it is actually null
// due to the legacy SDK.
if ty == cty.String {
if !val.IsNull() && attr.Optional && len(val.AsString()) == 0 {
return null, nil
}
}
return val, nil

case block != nil:
if block.Deprecated {
return null, nil
}
}

return val, nil
})
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(ctx, resp.Diagnostics, err)
return resp, nil
}

newConfigMP, err := msgpack.Marshal(newConfigVal, schemaBlock.ImpliedType())
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(ctx, resp.Diagnostics, err)
return resp, nil
}
resp.Config = &tfprotov5.DynamicValue{
MsgPack: newConfigMP,
}

return resp, nil
}

func (s *GRPCProviderServer) MoveResourceState(ctx context.Context, req *tfprotov5.MoveResourceStateRequest) (*tfprotov5.MoveResourceStateResponse, error) {
if req == nil {
return nil, fmt.Errorf("MoveResourceState request is nil")
Expand Down
Loading