validate the configuration before ignore_changes
The ignore_changes option `all` can cause computed attributes to show up in the validation configuration, which will be rejected by the provider SDK. Validate the config before applying the ignore_changes options. In the future it we should probably have a way for processIgnoreChanges to skip computed values based on the schema. Since we also want a way to more easily query the schema for "computed-ness" to validate the ignore_changes arguments for computed values, we can fix these at the same time with a future change to configschema. This will most likely require some sort of method to retrieve info from the configschema.Block via cty.Path, which we cannot easily do right now.
This commit is contained in:
parent
02e7efab9e
commit
4f4e8c17e0
|
@ -6539,3 +6539,63 @@ resource "test_instance" "a" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContext2Plan_validateIgnoreAll(t *testing.T) {
|
||||||
|
m := testModuleInline(t, map[string]string{
|
||||||
|
"main.tf": `
|
||||||
|
resource "test_instance" "a" {
|
||||||
|
lifecycle {
|
||||||
|
ignore_changes = all
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
|
||||||
|
p := testProvider("test")
|
||||||
|
p.GetSchemaReturn = &ProviderSchema{
|
||||||
|
ResourceTypes: map[string]*configschema.Block{
|
||||||
|
"test_instance": {
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Computed: true},
|
||||||
|
"data": {Type: cty.String, Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p.PlanResourceChangeFn = testDiffFn
|
||||||
|
p.ValidateResourceTypeConfigFn = func(req providers.ValidateResourceTypeConfigRequest) providers.ValidateResourceTypeConfigResponse {
|
||||||
|
var diags tfdiags.Diagnostics
|
||||||
|
if req.TypeName == "test_instance" {
|
||||||
|
if !req.Config.GetAttr("id").IsNull() {
|
||||||
|
diags = diags.Append(errors.New("id cannot be set in config"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return providers.ValidateResourceTypeConfigResponse{
|
||||||
|
Diagnostics: diags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state := states.NewState()
|
||||||
|
root := state.EnsureModule(addrs.RootModuleInstance)
|
||||||
|
root.SetResourceInstanceCurrent(
|
||||||
|
mustResourceInstanceAddr("test_instance.a").Resource,
|
||||||
|
&states.ResourceInstanceObjectSrc{
|
||||||
|
Status: states.ObjectReady,
|
||||||
|
AttrsJSON: []byte(`{"id":"a","data":"foo"}`),
|
||||||
|
Dependencies: []addrs.ConfigResource{},
|
||||||
|
},
|
||||||
|
mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
|
||||||
|
)
|
||||||
|
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
Providers: map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
State: state,
|
||||||
|
})
|
||||||
|
_, diags := ctx.Plan()
|
||||||
|
if diags.HasErrors() {
|
||||||
|
t.Fatal(diags.Err())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -212,6 +212,24 @@ func (n *EvalDiff) Eval(ctx EvalContext) tfdiags.Diagnostics {
|
||||||
unmarkedConfigVal, unmarkedPaths := origConfigVal.UnmarkDeepWithPaths()
|
unmarkedConfigVal, unmarkedPaths := origConfigVal.UnmarkDeepWithPaths()
|
||||||
unmarkedPriorVal, priorPaths := priorVal.UnmarkDeepWithPaths()
|
unmarkedPriorVal, priorPaths := priorVal.UnmarkDeepWithPaths()
|
||||||
|
|
||||||
|
log.Printf("[TRACE] Re-validating config for %q", n.Addr.Absolute(ctx.Path()))
|
||||||
|
// Allow the provider to validate the final set of values.
|
||||||
|
// The config was statically validated early on, but there may have been
|
||||||
|
// unknown values which the provider could not validate at the time.
|
||||||
|
// TODO: It would be more correct to validate the config after
|
||||||
|
// ignore_changes has been applied, but the current implementation cannot
|
||||||
|
// exclude computed-only attributes when given the `all` option.
|
||||||
|
validateResp := provider.ValidateResourceTypeConfig(
|
||||||
|
providers.ValidateResourceTypeConfigRequest{
|
||||||
|
TypeName: n.Addr.Resource.Type,
|
||||||
|
Config: unmarkedConfigVal,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if validateResp.Diagnostics.HasErrors() {
|
||||||
|
diags = diags.Append(validateResp.Diagnostics.InConfigBody(config.Config))
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
// ignore_changes is meant to only apply to the configuration, so it must
|
// ignore_changes is meant to only apply to the configuration, so it must
|
||||||
// be applied before we generate a plan. This ensures the config used for
|
// be applied before we generate a plan. This ensures the config used for
|
||||||
// the proposed value, the proposed value itself, and the config presented
|
// the proposed value, the proposed value itself, and the config presented
|
||||||
|
@ -235,21 +253,6 @@ func (n *EvalDiff) Eval(ctx EvalContext) tfdiags.Diagnostics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[TRACE] Re-validating config for %q", n.Addr.Absolute(ctx.Path()))
|
|
||||||
// Allow the provider to validate the final set of values.
|
|
||||||
// The config was statically validated early on, but there may have been
|
|
||||||
// unknown values which the provider could not validate at the time.
|
|
||||||
validateResp := provider.ValidateResourceTypeConfig(
|
|
||||||
providers.ValidateResourceTypeConfigRequest{
|
|
||||||
TypeName: n.Addr.Resource.Type,
|
|
||||||
Config: configValIgnored,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if validateResp.Diagnostics.HasErrors() {
|
|
||||||
diags = diags.Append(validateResp.Diagnostics.InConfigBody(config.Config))
|
|
||||||
return diags
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := provider.PlanResourceChange(providers.PlanResourceChangeRequest{
|
resp := provider.PlanResourceChange(providers.PlanResourceChangeRequest{
|
||||||
TypeName: n.Addr.Resource.Type,
|
TypeName: n.Addr.Resource.Type,
|
||||||
Config: configValIgnored,
|
Config: configValIgnored,
|
||||||
|
|
Loading…
Reference in New Issue