core: Enforce the validity of planned new objects

We've been gradually adding safety checks of this sort throughout the
lifecycle to help ensure that buggy providers can't introduce
hard-to-diagnose downstream failures and misbehavior. This completes the
set by verifying during plan time that the provider has produced a plan
that actually achieves the goals defined in the configuration.

In particular, this catches the situation where a provider may incorrectly
override a value explicitly set in configuration, which avoids creating
confusion by betraying the reasonable user expectation that referencing an
explicitly-defined attribute will produce exactly the value shown in
configuration.
This commit is contained in:
Martin Atkins 2019-02-08 19:30:34 -08:00
parent fec6e0328d
commit 419f5e58cd
1 changed files with 14 additions and 0 deletions

View File

@ -216,6 +216,20 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
return nil, diags.Err() return nil, diags.Err()
} }
for _, err := range objchange.AssertPlanValid(schema, priorVal, configVal, plannedNewVal) {
diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error,
"Provider produced invalid plan",
fmt.Sprintf(
"Provider %q planned an invalid value for %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.",
n.ProviderAddr.ProviderConfig.Type, tfdiags.FormatErrorPrefixed(err, absAddr.String()),
),
))
}
if diags.HasErrors() {
return nil, diags.Err()
}
{ {
var moreDiags tfdiags.Diagnostics var moreDiags tfdiags.Diagnostics
plannedNewVal, moreDiags = n.processIgnoreChanges(priorVal, plannedNewVal) plannedNewVal, moreDiags = n.processIgnoreChanges(priorVal, plannedNewVal)