opentofu/internal/checks/state_init.go
Martin Atkins 3785619f93 core: Use the new checks package for condition tracking
The "checks" package is an expansion what we previously called
plans.Conditions to accommodate a new requirement that we be able to track
which checks we're expecting to run even if we don't actually get around
to running them, which will be helpful when we start using checks as part
of our module testing story because test reporting tools appreciate there
being a relatively consistent set of test cases from one run to the next.

So far this should be essentially a no-op change from an external
functionality standpoint, aside from some minor adjustments to how we
report some of the error and warning cases from condition evaluation in
light of the fact that the "checks" package can now track errors as a
different outcome than a failure of a valid check.

As is often the case with anything which changes what we track
in the EvalContext and persist between plan and apply, Terraform Core is
pretty brittle and so this had knock-on effects elsewhere too. Again, the
goal is for these changes to not create any material externally-visible
difference, and just to accommodate the new assumption that there will
always be a "checks" object available for tracking during a graph walk.
2022-08-26 15:47:29 -07:00

78 lines
2.0 KiB
Go

package checks
import (
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/configs"
)
func initialStatuses(cfg *configs.Config) addrs.Map[addrs.ConfigCheckable, *configCheckableState] {
ret := addrs.MakeMap[addrs.ConfigCheckable, *configCheckableState]()
if cfg == nil {
// This should not happen in normal use, but can arise in some
// unit tests that are not working with a full configuration and
// don't care about checks.
return ret
}
collectInitialStatuses(ret, cfg)
return ret
}
func collectInitialStatuses(into addrs.Map[addrs.ConfigCheckable, *configCheckableState], cfg *configs.Config) {
moduleAddr := cfg.Path
for _, rc := range cfg.Module.ManagedResources {
addr := rc.Addr().InModule(moduleAddr)
collectInitialStatusForResource(into, addr, rc)
}
for _, rc := range cfg.Module.DataResources {
addr := rc.Addr().InModule(moduleAddr)
collectInitialStatusForResource(into, addr, rc)
}
for _, oc := range cfg.Module.Outputs {
addr := oc.Addr().InModule(moduleAddr)
ct := len(oc.Preconditions)
if ct == 0 {
// We just ignore output values that don't declare any checks.
continue
}
st := &configCheckableState{}
st.checkTypes = map[addrs.CheckType]int{
addrs.OutputPrecondition: ct,
}
into.Put(addr, st)
}
// Must also visit child modules to collect everything
for _, child := range cfg.Children {
collectInitialStatuses(into, child)
}
}
func collectInitialStatusForResource(into addrs.Map[addrs.ConfigCheckable, *configCheckableState], addr addrs.ConfigResource, rc *configs.Resource) {
if (len(rc.Preconditions) + len(rc.Postconditions)) == 0 {
// Don't bother with any resource that doesn't have at least
// one condition.
return
}
st := &configCheckableState{
checkTypes: make(map[addrs.CheckType]int),
}
if ct := len(rc.Preconditions); ct > 0 {
st.checkTypes[addrs.ResourcePrecondition] = ct
}
if ct := len(rc.Postconditions); ct > 0 {
st.checkTypes[addrs.ResourcePostcondition] = ct
}
into.Put(addr, st)
}