mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
The checks.Checks type aims to encapsulate keeping track of check results during a run and then reporting on them afterwards even if the run was aborted early for some reason. The intended model here is that each new run starts with an entirely fresh checks.Checks, with all of the statuses therefore initially unknown, and gradually populates the check results as we walk the graph in Terraform Core. This means that even if we don't complete the run due to an error or due to targeting options we'll still report anything we didn't visit yet as unknown. This commit only includes the modeling of checks in the checks package. For now this is just dead code, and we'll wire it in to Terraform Core in subsequent commits.
75 lines
2.4 KiB
Go
75 lines
2.4 KiB
Go
package checks
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/zclconf/go-cty/cty"
|
|
)
|
|
|
|
// Status represents the status of an individual check associated with a
|
|
// checkable object.
|
|
type Status rune
|
|
|
|
//go:generate go run golang.org/x/tools/cmd/stringer -type=Status
|
|
|
|
const (
|
|
// StatusUnknown represents that there is not yet a conclusive result
|
|
// for the check, either because we haven't yet visited its associated
|
|
// object or because the check condition itself depends on a value not
|
|
// yet known during planning.
|
|
StatusUnknown Status = 0
|
|
// NOTE: Our implementation relies on StatusUnknown being the zero value
|
|
// of Status.
|
|
|
|
// StatusPass represents that Terraform Core has evaluated the check's
|
|
// condition and it returned true, indicating success.
|
|
StatusPass Status = 'P'
|
|
|
|
// StatusFail represents that Terraform Core has evaluated the check's
|
|
// condition and it returned false, indicating failure.
|
|
StatusFail Status = 'F'
|
|
|
|
// StatusError represents that Terraform Core tried to evaluate the check's
|
|
// condition but encountered an error while evaluating the check expression.
|
|
//
|
|
// This is different than StatusFail because StatusFail indiciates that
|
|
// the condition was valid and returned false, whereas StatusError
|
|
// indicates that the condition was not valid at all.
|
|
StatusError Status = 'E'
|
|
)
|
|
|
|
// StatusForCtyValue returns the Status value corresponding to the given
|
|
// cty Value, which must be one of either cty.True, cty.False, or
|
|
// cty.UnknownVal(cty.Bool) or else this function will panic.
|
|
//
|
|
// The current behavior of this function is:
|
|
//
|
|
// cty.True StatusPass
|
|
// cty.False StatusFail
|
|
// cty.UnknownVal(cty.Bool) StatusUnknown
|
|
//
|
|
// Any other input will panic. Note that there's no value that can produce
|
|
// StatusError, because in case of a condition error there will not typically
|
|
// be a result value at all.
|
|
func StatusForCtyValue(v cty.Value) Status {
|
|
if !v.Type().Equals(cty.Bool) {
|
|
panic(fmt.Sprintf("cannot use %s as check status", v.Type().FriendlyName()))
|
|
}
|
|
if v.IsNull() {
|
|
panic("cannot use null as check status")
|
|
}
|
|
|
|
switch {
|
|
case v == cty.True:
|
|
return StatusPass
|
|
case v == cty.False:
|
|
return StatusFail
|
|
case !v.IsKnown():
|
|
return StatusUnknown
|
|
default:
|
|
// Should be impossible to get here unless something particularly
|
|
// weird is going on, like a marked condition result.
|
|
panic(fmt.Sprintf("cannot use %#v as check status", v))
|
|
}
|
|
}
|