Skip to content

Commit

Permalink
AssertPlanValid for computed with config value
Browse files Browse the repository at this point in the history
Return early from AssertPlanValid for any attribute which is only
computed. We currently fail if there's a config value, but that could
only happen because of core, not because of the provider.
  • Loading branch information
jbardin committed Jul 25, 2022
1 parent 5da30c2 commit a6a08fe
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 12 deletions.
31 changes: 19 additions & 12 deletions internal/plans/objchange/plan_valid.go
Expand Up @@ -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.
Expand 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
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.
if configV.IsNull() {
if attrS.Computed {
return errs
}
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
Expand Down
26 changes: 26 additions & 0 deletions internal/plans/objchange/plan_valid_test.go
Expand Up @@ -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 {
Expand Down

0 comments on commit a6a08fe

Please sign in to comment.