Merge pull request #31509 from hashicorp/jbardin/valid-computed-plan

always allow computed-only changes in the plan
This commit is contained in:
James Bardin 2022-07-27 10:09:15 -04:00 committed by GitHub
commit 93c525bf81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 13 deletions

View File

@ -257,6 +257,7 @@ func assertPlannedAttrValid(name string, attrS *configschema.Attribute, priorSta
}
func assertPlannedValueValid(attrS *configschema.Attribute, priorV, configV, plannedV cty.Value, path cty.Path) []error {
var errs []error
if plannedV.RawEquals(configV) {
// This is the easy path: provider didn't change anything at all.
@ -270,22 +271,28 @@ func assertPlannedValueValid(attrS *configschema.Attribute, priorV, configV, pla
return errs
}
// the provider is allowed to insert values when the config is
// null, but only if the attribute is computed.
if configV.IsNull() {
if attrS.Computed {
return errs
}
switch {
// The provider can plan any value for a computed-only attribute. There may
// be a config value here in the case where a user used `ignore_changes` on
// a computed attribute and ignored the warning, or we failed to validate
// computed attributes in the config, but regardless it's not a plan error
// caused by the provider.
case attrS.Computed && !attrS.Optional:
return errs
// The provider is allowed to insert optional values when the config is
// null, but only if the attribute is computed.
case configV.IsNull() && attrS.Computed:
return errs
case configV.IsNull() && !plannedV.IsNull():
// if the attribute is not computed, then any planned value is incorrect
if !plannedV.IsNull() {
if attrS.Sensitive {
errs = append(errs, path.NewErrorf("sensitive planned value for a non-computed attribute"))
} else {
errs = append(errs, path.NewErrorf("planned value %#v for a non-computed attribute", plannedV))
}
return errs
if attrS.Sensitive {
errs = append(errs, path.NewErrorf("sensitive planned value for a non-computed attribute"))
} else {
errs = append(errs, path.NewErrorf("planned value %#v for a non-computed attribute", plannedV))
}
return errs
}
// If this attribute has a NestedType, validate the nested object

View File

@ -1628,6 +1628,32 @@ func TestAssertPlanValid(t *testing.T) {
}),
[]string{`.map.one.name: planned value cty.StringVal("from_provider") does not match config value cty.StringVal("from_config")`},
},
// If a config value ended up in a computed-only attribute it can still
// be a valid plan. We either got here because the user ignore warnings
// about ignore_changes on computed attributes, or we failed to
// validate a config with computed values. Either way, we don't want to
// indicate an error with the provider.
"computed only value with config": {
&configschema.Block{
Attributes: map[string]*configschema.Attribute{
"a": {
Type: cty.String,
Computed: true,
},
},
},
cty.ObjectVal(map[string]cty.Value{
"a": cty.StringVal("old"),
}),
cty.ObjectVal(map[string]cty.Value{
"a": cty.StringVal("old"),
}),
cty.ObjectVal(map[string]cty.Value{
"a": cty.UnknownVal(cty.String),
}),
nil,
},
}
for name, test := range tests {