Remove unknown value strings from apply diffs
The synthetic config value used to create the Apply diff should contain no unknown config values. Any remaining UnknownConfigValues were due to that being used as a placeholder for values yet to be computed, and these should be marked NewComputed in the diff.
This commit is contained in:
parent
7df3275120
commit
5f52aba3ae
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/zclconf/go-cty/cty"
|
||||
ctyjson "github.com/zclconf/go-cty/cty/json"
|
||||
|
||||
"github.com/hashicorp/terraform/config"
|
||||
"github.com/hashicorp/terraform/configs/configschema"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
@ -31,6 +32,8 @@ func diffFromValues(prior, planned cty.Value, res *Resource, cust CustomizeDiffF
|
|||
configSchema := res.CoreConfigSchema()
|
||||
|
||||
cfg := terraform.NewResourceConfigShimmed(planned, configSchema)
|
||||
removeConfigUnknowns(cfg.Config)
|
||||
removeConfigUnknowns(cfg.Raw)
|
||||
|
||||
diff, err := schemaMap(res.Schema).Diff(instanceState, cfg, cust, nil, false)
|
||||
if err != nil {
|
||||
|
@ -40,6 +43,28 @@ func diffFromValues(prior, planned cty.Value, res *Resource, cust CustomizeDiffF
|
|||
return diff, err
|
||||
}
|
||||
|
||||
// During apply the only unknown values are those which are to be computed by
|
||||
// the resource itself. These may have been marked as unknown config values, and
|
||||
// need to be removed to prevent the UnknownVariableValue from appearing the diff.
|
||||
func removeConfigUnknowns(cfg map[string]interface{}) {
|
||||
for k, v := range cfg {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
if v == config.UnknownVariableValue {
|
||||
cfg[k] = ""
|
||||
}
|
||||
case []interface{}:
|
||||
for _, i := range v {
|
||||
if m, ok := i.(map[string]interface{}); ok {
|
||||
removeConfigUnknowns(m)
|
||||
}
|
||||
}
|
||||
case map[string]interface{}:
|
||||
removeConfigUnknowns(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ApplyDiff takes a cty.Value state and applies a terraform.InstanceDiff to
|
||||
// get a new cty.Value state. This is used to convert the diff returned from
|
||||
// the legacy provider Diff method to the state required for the new
|
||||
|
|
|
@ -3590,6 +3590,14 @@ func TestShimSchemaMap_Diff(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// there would be no unknown config variables during apply, so
|
||||
// return early here.
|
||||
for _, v := range tc.ConfigVariables {
|
||||
if s, ok := v.Value.(string); ok && s == config.UnknownVariableValue {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// our diff function can't set DestroyTainted, but match the
|
||||
// expected value here for the test fixtures
|
||||
if tainted {
|
||||
|
@ -3610,3 +3618,55 @@ func TestShimSchemaMap_Diff(t *testing.T) {
|
|||
func resourceSchemaToBlock(s map[string]*Schema) *configschema.Block {
|
||||
return (&Resource{Schema: s}).CoreConfigSchema()
|
||||
}
|
||||
|
||||
func TestRemoveConfigUnknowns(t *testing.T) {
|
||||
cfg := map[string]interface{}{
|
||||
"id": "74D93920-ED26-11E3-AC10-0800200C9A66",
|
||||
"route_rules": []interface{}{
|
||||
map[string]interface{}{
|
||||
"cidr_block": "74D93920-ED26-11E3-AC10-0800200C9A66",
|
||||
"destination": "0.0.0.0/0",
|
||||
"destination_type": "CIDR_BLOCK",
|
||||
"network_entity_id": "1",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"cidr_block": "74D93920-ED26-11E3-AC10-0800200C9A66",
|
||||
"destination": "0.0.0.0/0",
|
||||
"destination_type": "CIDR_BLOCK",
|
||||
"sub_block": []interface{}{
|
||||
map[string]interface{}{
|
||||
"computed": "74D93920-ED26-11E3-AC10-0800200C9A66",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
expect := map[string]interface{}{
|
||||
"id": "",
|
||||
"route_rules": []interface{}{
|
||||
map[string]interface{}{
|
||||
"cidr_block": "",
|
||||
"destination": "0.0.0.0/0",
|
||||
"destination_type": "CIDR_BLOCK",
|
||||
"network_entity_id": "1",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"cidr_block": "",
|
||||
"destination": "0.0.0.0/0",
|
||||
"destination_type": "CIDR_BLOCK",
|
||||
"sub_block": []interface{}{
|
||||
map[string]interface{}{
|
||||
"computed": "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
removeConfigUnknowns(cfg)
|
||||
|
||||
if !reflect.DeepEqual(cfg, expect) {
|
||||
t.Fatalf("\nexpected: %#v\ngot: %#v", expect, cfg)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue