Skip to content

Commit

Permalink
Fix proposed new unknown blocks (#2060)
Browse files Browse the repository at this point in the history
This updates our `objchange` algorithm with the newest one from the
OpenTofu repo. This fixes an issue with the way unknown sets are
presented to TF.

fixes #1951
  • Loading branch information
VenelinMartinov committed Jun 6, 2024
1 parent ba48631 commit b012fa8
Show file tree
Hide file tree
Showing 13 changed files with 1,007 additions and 475 deletions.
71 changes: 71 additions & 0 deletions pkg/tests/cross-tests/cross_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -601,3 +601,74 @@ func TestOptionalComputedBlockCollection(t *testing.T) {
})
}
}

func TestComputedSetFieldsNoDiff(t *testing.T) {
skipUnlessLinux(t)

elemSchema := schema.Resource{
Schema: map[string]*schema.Schema{
"metro_code": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"metro_name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
}

resource := &schema.Resource{
Schema: map[string]*schema.Schema{
"location": {
Required: true,
MaxItems: 1,
Type: schema.TypeSet,
Elem: &elemSchema,
},
},
CreateContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics {
rd.SetId("r1")
// The field is computed and the provider always returns a metro_name.
err := rd.Set("location", schema.NewSet(schema.HashResource(&elemSchema), []interface{}{
map[string]interface{}{"metro_name": "Frankfurt", "metro_code": "FR"},
}))
require.NoError(t, err)
return diag.Diagnostics{}
},
}

t1 := tftypes.Object{
AttributeTypes: map[string]tftypes.Type{
"metro_code": tftypes.String,
},
}

t0 := tftypes.NewValue(
tftypes.Object{
AttributeTypes: map[string]tftypes.Type{
"location": tftypes.Set{
ElementType: t1,
},
},
},
map[string]tftypes.Value{
"location": tftypes.NewValue(
tftypes.Set{ElementType: t1},
[]tftypes.Value{
tftypes.NewValue(t1, map[string]tftypes.Value{
// We try to set the metro_code but the provider should return metro_name
"metro_code": tftypes.NewValue(tftypes.String, "FR"),
}),
},
),
},
)
runDiffCheck(t, diffTestCase{
Resource: resource,
Config1: t0,
Config2: t0,
})
}
5 changes: 2 additions & 3 deletions pkg/tfbridge/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4742,8 +4742,7 @@ func TestUnknowns(t *testing.T) {
},
"response": {
"properties":{
"id":"",
"setBlockProps": [{"prop": ""}]
"id":""
}
}
}`)
Expand Down Expand Up @@ -5189,7 +5188,7 @@ func TestPlanResourceChangeUnknowns(t *testing.T) {
"listProps":null,
"nestedListProps":null,
"maxItemsOneProp":null,
"setBlockProps":[{"prop":""}],
"setBlockProps":"04da6b54-80e4-46f7-96ec-b56ff0331ba9",
"listBlockProps":[],
"nestedListBlockProps":[],
"maxItemsOneBlockProp":null
Expand Down
3 changes: 3 additions & 0 deletions pkg/tfshim/sdk-v2/internal/tf/configs/configschema/LICENSE
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
Copyright (c) The OpenTofu Authors
Copyright (c) 2014 HashiCorp, Inc.

Mozilla Public License, version 2.0

1. Definitions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
// Code copied from https://github.com/hashicorp/terraform.git by go generate; DO NOT EDIT.
// Code copied from https://github.com/opentofu/opentofu.git by go generate; DO NOT EDIT.
// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package configschema

import (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
// Code copied from https://github.com/hashicorp/terraform.git by go generate; DO NOT EDIT.
// Code copied from https://github.com/opentofu/opentofu.git by go generate; DO NOT EDIT.
// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package configschema

import (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
// Code copied from https://github.com/hashicorp/terraform.git by go generate; DO NOT EDIT.
// Code copied from https://github.com/opentofu/opentofu.git by go generate; DO NOT EDIT.
// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package configschema

import (
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions pkg/tfshim/sdk-v2/internal/tf/configs/configschema/path.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Code copied from https://github.com/opentofu/opentofu.git by go generate; DO NOT EDIT.
// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package configschema

import (
"github.com/zclconf/go-cty/cty"
)

// AttributeByPath looks up the Attribute schema which corresponds to the given
// cty.Path. A nil value is returned if the given path does not correspond to a
// specific attribute.
func (b *Block) AttributeByPath(path cty.Path) *Attribute {
block := b
for i, step := range path {
switch step := step.(type) {
case cty.GetAttrStep:
if attr := block.Attributes[step.Name]; attr != nil {
// If the Attribute is defined with a NestedType and there's
// more to the path, descend into the NestedType
if attr.NestedType != nil && i < len(path)-1 {
return attr.NestedType.AttributeByPath(path[i+1:])
} else if i < len(path)-1 { // There's more to the path, but not more to this Attribute.
return nil
}
return attr
}

if nestedBlock := block.BlockTypes[step.Name]; nestedBlock != nil {
block = &nestedBlock.Block
continue
}

return nil
}
}
return nil
}

// AttributeByPath recurses through a NestedType to look up the Attribute scheme
// which corresponds to the given cty.Path. A nil value is returned if the given
// path does not correspond to a specific attribute.
func (o *Object) AttributeByPath(path cty.Path) *Attribute {
for i, step := range path {
switch step := step.(type) {
case cty.GetAttrStep:
if attr := o.Attributes[step.Name]; attr != nil {
if attr.NestedType != nil && i < len(path)-1 {
return attr.NestedType.AttributeByPath(path[i+1:])
} else if i < len(path)-1 { // There's more to the path, but not more to this Attribute.
return nil
}
return attr
}
}
}
return nil
}
11 changes: 8 additions & 3 deletions pkg/tfshim/sdk-v2/internal/tf/configs/configschema/schema.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
// Code copied from https://github.com/hashicorp/terraform.git by go generate; DO NOT EDIT.
// Code copied from https://github.com/opentofu/opentofu.git by go generate; DO NOT EDIT.
// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package configschema

import (
Expand All @@ -15,7 +20,7 @@ const (
// Block represents a configuration block.
//
// "Block" here is a logical grouping construct, though it happens to map
// directly onto the physical block syntax of Terraform's native configuration
// directly onto the physical block syntax of OpenTofu's native configuration
// syntax. It may be a more a matter of convention in other syntaxes, such as
// JSON.
//
Expand Down Expand Up @@ -71,7 +76,7 @@ type Attribute struct {
//
// At present nothing is done with this information, but callers are
// encouraged to set it where appropriate so that it may be used in the
// future to help Terraform mask sensitive information. (Terraform
// future to help OpenTofu mask sensitive information. (OpenTofu
// currently achieves this in a limited sense via other mechanisms.)
Sensitive bool

Expand Down
16 changes: 13 additions & 3 deletions pkg/tfshim/sdk-v2/internal/tf/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import (

//go:generate go run generate.go

const terraformRepo = "https://github.com/hashicorp/terraform.git"
const terraformVer = "v1.3.9"
const terraformRepo = "https://github.com/opentofu/opentofu.git"
const terraformVer = "v1.7.2"

type file struct {
src string
Expand All @@ -48,7 +48,7 @@ func main() {
}

func files() []file {
oldPkg := "github.com/hashicorp/terraform"
oldPkg := "github.com/opentofu/opentofu"
newPkg := "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim/sdk-v2/internal/tf"

replacePkg := gofmtReplace(fmt.Sprintf(`"%s/internal/configs/configschema" -> "%s/configs/configschema"`,
Expand Down Expand Up @@ -89,11 +89,21 @@ func files() []file {
dest: "configs/configschema/decoder_spec.go",
transforms: transforms,
},
{
src: "internal/configs/configschema/path.go",
dest: "configs/configschema/path.go",
transforms: transforms,
},
{
src: "internal/plans/objchange/objchange.go",
dest: "plans/objchange/objchange.go",
transforms: transforms,
},
{
src: "internal/plans/objchange/plan_valid.go",
dest: "plans/objchange/plan_valid.go",
transforms: transforms,
},
}
}

Expand Down
3 changes: 3 additions & 0 deletions pkg/tfshim/sdk-v2/internal/tf/plans/objchange/LICENSE
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
Copyright (c) The OpenTofu Authors
Copyright (c) 2014 HashiCorp, Inc.

Mozilla Public License, version 2.0

1. Definitions
Expand Down
Loading

0 comments on commit b012fa8

Please sign in to comment.