mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
config: substring containing computed value replaces element
This commit is contained in:
parent
abd68c2c87
commit
2feaebdca5
@ -152,12 +152,12 @@ func (w *interpolationWalker) Primitive(v reflect.Value) error {
|
|||||||
if w.loc == reflectwalk.SliceElem {
|
if w.loc == reflectwalk.SliceElem {
|
||||||
parts := strings.Split(replaceVal, InterpSplitDelim)
|
parts := strings.Split(replaceVal, InterpSplitDelim)
|
||||||
for _, p := range parts {
|
for _, p := range parts {
|
||||||
if p == UnknownVariableValue {
|
if strings.Contains(p, UnknownVariableValue) {
|
||||||
remove = true
|
remove = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if replaceVal == UnknownVariableValue {
|
} else if strings.Contains(replaceVal, UnknownVariableValue) {
|
||||||
remove = true
|
remove = true
|
||||||
}
|
}
|
||||||
if remove {
|
if remove {
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/config/lang"
|
||||||
"github.com/hashicorp/terraform/config/lang/ast"
|
"github.com/hashicorp/terraform/config/lang/ast"
|
||||||
"github.com/mitchellh/reflectwalk"
|
"github.com/mitchellh/reflectwalk"
|
||||||
)
|
)
|
||||||
@ -124,7 +125,7 @@ func TestInterpolationWalker_replace(t *testing.T) {
|
|||||||
"foo": "hello, ${var.foo}",
|
"foo": "hello, ${var.foo}",
|
||||||
},
|
},
|
||||||
Output: map[string]interface{}{
|
Output: map[string]interface{}{
|
||||||
"foo": "bar",
|
"foo": "hello, bar",
|
||||||
},
|
},
|
||||||
Value: "bar",
|
Value: "bar",
|
||||||
},
|
},
|
||||||
@ -170,11 +171,38 @@ func TestInterpolationWalker_replace(t *testing.T) {
|
|||||||
Output: map[string]interface{}{},
|
Output: map[string]interface{}{},
|
||||||
Value: UnknownVariableValue + InterpSplitDelim + "baz",
|
Value: UnknownVariableValue + InterpSplitDelim + "baz",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Input: map[string]interface{}{
|
||||||
|
"foo": []interface{}{
|
||||||
|
"${var.foo}/32",
|
||||||
|
"bing",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Output: map[string]interface{}{},
|
||||||
|
Value: UnknownVariableValue,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tc := range cases {
|
for i, tc := range cases {
|
||||||
fn := func(ast.Node) (string, error) {
|
config := &lang.EvalConfig{
|
||||||
return tc.Value, nil
|
GlobalScope: &ast.BasicScope{
|
||||||
|
VarMap: map[string]ast.Variable{
|
||||||
|
"var.foo": ast.Variable{
|
||||||
|
Value: tc.Value,
|
||||||
|
Type: ast.TypeString,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
fn := func(root ast.Node) (string, error) {
|
||||||
|
value, _, err := lang.Eval(root, config)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.(string), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
w := &interpolationWalker{F: fn, Replace: true}
|
w := &interpolationWalker{F: fn, Replace: true}
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/config"
|
"github.com/hashicorp/terraform/config"
|
||||||
|
"github.com/hashicorp/terraform/config/lang/ast"
|
||||||
|
"github.com/hashicorp/terraform/helper/hashcode"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -48,16 +50,6 @@ func TestConfigFieldReader(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func testConfig(
|
|
||||||
t *testing.T, raw map[string]interface{}) *terraform.ResourceConfig {
|
|
||||||
rc, err := config.NewRawConfig(raw)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return terraform.NewResourceConfig(rc)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestConfigFieldReader_DefaultHandling(t *testing.T) {
|
func TestConfigFieldReader_DefaultHandling(t *testing.T) {
|
||||||
schema := map[string]*Schema{
|
schema := map[string]*Schema{
|
||||||
"strWithDefault": &Schema{
|
"strWithDefault": &Schema{
|
||||||
@ -142,3 +134,116 @@ func TestConfigFieldReader_DefaultHandling(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConfigFieldReader_ComputedSet(t *testing.T) {
|
||||||
|
schema := map[string]*Schema{
|
||||||
|
"strSet": &Schema{
|
||||||
|
Type: TypeSet,
|
||||||
|
Elem: &Schema{Type: TypeString},
|
||||||
|
Set: func(v interface{}) int {
|
||||||
|
return hashcode.String(v.(string))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cases := map[string]struct {
|
||||||
|
Addr []string
|
||||||
|
Result FieldReadResult
|
||||||
|
Config *terraform.ResourceConfig
|
||||||
|
Err bool
|
||||||
|
}{
|
||||||
|
"set, normal": {
|
||||||
|
[]string{"strSet"},
|
||||||
|
FieldReadResult{
|
||||||
|
Value: map[int]interface{}{
|
||||||
|
2356372769: "foo",
|
||||||
|
},
|
||||||
|
Exists: true,
|
||||||
|
Computed: false,
|
||||||
|
},
|
||||||
|
testConfig(t, map[string]interface{}{
|
||||||
|
"strSet": []interface{}{"foo"},
|
||||||
|
}),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
|
||||||
|
"set, computed element": {
|
||||||
|
[]string{"strSet"},
|
||||||
|
FieldReadResult{
|
||||||
|
Value: nil,
|
||||||
|
Exists: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
testConfigInterpolate(t, map[string]interface{}{
|
||||||
|
"strSet": []interface{}{"${var.foo}"},
|
||||||
|
}, map[string]ast.Variable{
|
||||||
|
"var.foo": ast.Variable{
|
||||||
|
Value: config.UnknownVariableValue,
|
||||||
|
Type: ast.TypeString,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
|
||||||
|
"set, computed element substring": {
|
||||||
|
[]string{"strSet"},
|
||||||
|
FieldReadResult{
|
||||||
|
Value: nil,
|
||||||
|
Exists: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
testConfigInterpolate(t, map[string]interface{}{
|
||||||
|
"strSet": []interface{}{"${var.foo}/32"},
|
||||||
|
}, map[string]ast.Variable{
|
||||||
|
"var.foo": ast.Variable{
|
||||||
|
Value: config.UnknownVariableValue,
|
||||||
|
Type: ast.TypeString,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, tc := range cases {
|
||||||
|
r := &ConfigFieldReader{
|
||||||
|
Schema: schema,
|
||||||
|
Config: tc.Config,
|
||||||
|
}
|
||||||
|
out, err := r.ReadField(tc.Addr)
|
||||||
|
if (err != nil) != tc.Err {
|
||||||
|
t.Fatalf("%s: err: %s", name, err)
|
||||||
|
}
|
||||||
|
if s, ok := out.Value.(*Set); ok {
|
||||||
|
// If it is a set, convert to the raw map
|
||||||
|
out.Value = s.m
|
||||||
|
if len(s.m) == 0 {
|
||||||
|
out.Value = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(tc.Result, out) {
|
||||||
|
t.Fatalf("%s: bad: %#v", name, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testConfig(
|
||||||
|
t *testing.T, raw map[string]interface{}) *terraform.ResourceConfig {
|
||||||
|
return testConfigInterpolate(t, raw, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testConfigInterpolate(
|
||||||
|
t *testing.T,
|
||||||
|
raw map[string]interface{},
|
||||||
|
vs map[string]ast.Variable) *terraform.ResourceConfig {
|
||||||
|
rc, err := config.NewRawConfig(raw)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if len(vs) > 0 {
|
||||||
|
if err := rc.Interpolate(vs); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return terraform.NewResourceConfig(rc)
|
||||||
|
}
|
||||||
|
@ -2165,6 +2165,42 @@ func TestSchemaMap_Diff(t *testing.T) {
|
|||||||
|
|
||||||
Err: false,
|
Err: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// #56 - Set element computed substring
|
||||||
|
{
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"ports": &Schema{
|
||||||
|
Type: TypeSet,
|
||||||
|
Required: true,
|
||||||
|
Elem: &Schema{Type: TypeInt},
|
||||||
|
Set: func(a interface{}) int {
|
||||||
|
return a.(int)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"ports": []interface{}{1, "${var.foo}32"},
|
||||||
|
},
|
||||||
|
|
||||||
|
ConfigVariables: map[string]string{
|
||||||
|
"var.foo": config.UnknownVariableValue,
|
||||||
|
},
|
||||||
|
|
||||||
|
Diff: &terraform.InstanceDiff{
|
||||||
|
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||||
|
"ports.#": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "",
|
||||||
|
New: "",
|
||||||
|
NewComputed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
Err: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tc := range cases {
|
for i, tc := range cases {
|
||||||
|
Loading…
Reference in New Issue
Block a user