mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
addrs: ConfigCheckable type
Our existing addrs.Checkable represents a particular (possibly-dynamic) object that can have checks associated with it. This new addrs.ConfigCheckable represents static configuration objects that can potentially generate addrs.Checkable objects. The idea here is to allow us to predict from the configuration a set of potential checkable object containers and then dynamically associate the dynamic checkable objects with them as we make progress with planning. This is intended for our integration of checks into the "terraform test" testing harness, to be used instead of the weirdo builtin provider we were using as a placeholder before we had first-class syntax for checks. Test reporting tools find it helpful for there to be a consistent set of test cases from one run to the next so that they can report on trends over multiple runs, and so our ConfigCheckable addresses will serve as the relatively-static "test case" that we'll then associate the dynamic checks with, so that we can still talk about objects in the test result report even if we end up not reaching them due to an upstream conditution failure.
This commit is contained in:
parent
746bd49723
commit
d06cbfe6c8
@ -39,11 +39,25 @@ func (c Check) String() string {
|
||||
// Checkable is an interface implemented by all address types that can contain
|
||||
// condition blocks.
|
||||
type Checkable interface {
|
||||
UniqueKeyer
|
||||
|
||||
checkableSigil()
|
||||
|
||||
// Check returns the address of an individual check rule of a specified
|
||||
// type and index within this checkable container.
|
||||
Check(CheckType, int) Check
|
||||
|
||||
// ConfigCheckable returns the address of the configuration construct that
|
||||
// this Checkable belongs to.
|
||||
//
|
||||
// Checkable objects can potentially be dynamically declared during a
|
||||
// plan operation using constructs like resource for_each, and so
|
||||
// ConfigCheckable gives us a way to talk about the static containers
|
||||
// those dynamic objects belong to, in case we wish to group together
|
||||
// dynamic checkable objects into their static checkable for reporting
|
||||
// purposes.
|
||||
ConfigCheckable() ConfigCheckable
|
||||
|
||||
String() string
|
||||
}
|
||||
|
||||
@ -52,12 +66,6 @@ var (
|
||||
_ Checkable = AbsOutputValue{}
|
||||
)
|
||||
|
||||
type checkable struct {
|
||||
}
|
||||
|
||||
func (c checkable) checkableSigil() {
|
||||
}
|
||||
|
||||
// CheckType describes the category of check.
|
||||
type CheckType int
|
||||
|
||||
@ -85,3 +93,24 @@ func (c CheckType) Description() string {
|
||||
return "Condition"
|
||||
}
|
||||
}
|
||||
|
||||
// ConfigCheckable is an interfaces implemented by address types that represent
|
||||
// configuration constructs that can have Checkable addresses associated with
|
||||
// them.
|
||||
//
|
||||
// This address type therefore in a sense represents a container for zero or
|
||||
// more checkable objects all declared by the same configuration construct,
|
||||
// so that we can talk about these groups of checkable objects before we're
|
||||
// ready to decide how many checkable objects belong to each one.
|
||||
type ConfigCheckable interface {
|
||||
UniqueKeyer
|
||||
|
||||
configCheckableSigil()
|
||||
|
||||
String() string
|
||||
}
|
||||
|
||||
var (
|
||||
_ ConfigCheckable = ConfigResource{}
|
||||
_ ConfigCheckable = ConfigOutputValue{}
|
||||
)
|
||||
|
@ -38,7 +38,6 @@ func (v OutputValue) Absolute(m ModuleInstance) AbsOutputValue {
|
||||
// configuration. It is related to but separate from ModuleCallOutput, which
|
||||
// represents a module output from the perspective of its parent module.
|
||||
type AbsOutputValue struct {
|
||||
checkable
|
||||
Module ModuleInstance
|
||||
OutputValue OutputValue
|
||||
}
|
||||
@ -73,6 +72,31 @@ func (v AbsOutputValue) Equal(o AbsOutputValue) bool {
|
||||
return v.OutputValue == o.OutputValue && v.Module.Equal(o.Module)
|
||||
}
|
||||
|
||||
func (v AbsOutputValue) ConfigOutputValue() ConfigOutputValue {
|
||||
return ConfigOutputValue{
|
||||
Module: v.Module.Module(),
|
||||
OutputValue: v.OutputValue,
|
||||
}
|
||||
}
|
||||
|
||||
func (v AbsOutputValue) checkableSigil() {
|
||||
// Output values are checkable
|
||||
}
|
||||
|
||||
func (v AbsOutputValue) ConfigCheckable() ConfigCheckable {
|
||||
// Output values are declared by "output" blocks in the configuration,
|
||||
// represented as ConfigOutputValue.
|
||||
return v.ConfigOutputValue()
|
||||
}
|
||||
|
||||
func (v AbsOutputValue) UniqueKey() UniqueKey {
|
||||
return absOutputValueUniqueKey(v.String())
|
||||
}
|
||||
|
||||
type absOutputValueUniqueKey string
|
||||
|
||||
func (k absOutputValueUniqueKey) uniqueKeySigil() {}
|
||||
|
||||
func ParseAbsOutputValue(traversal hcl.Traversal) (AbsOutputValue, tfdiags.Diagnostics) {
|
||||
path, remain, diags := parseModuleInstancePrefix(traversal)
|
||||
if diags.HasErrors() {
|
||||
@ -152,3 +176,31 @@ func (v AbsOutputValue) ModuleCallOutput() (ModuleInstance, ModuleCallInstanceOu
|
||||
Name: v.OutputValue.Name,
|
||||
}
|
||||
}
|
||||
|
||||
// ConfigOutputValue represents a particular "output" block in the
|
||||
// configuration, which might have many AbsOutputValue addresses associated
|
||||
// with it at runtime if it belongs to a module that was called using
|
||||
// "count" or "for_each".
|
||||
type ConfigOutputValue struct {
|
||||
Module Module
|
||||
OutputValue OutputValue
|
||||
}
|
||||
|
||||
func (v ConfigOutputValue) String() string {
|
||||
if v.Module.IsRoot() {
|
||||
return v.OutputValue.String()
|
||||
}
|
||||
return fmt.Sprintf("%s.%s", v.Module.String(), v.OutputValue.String())
|
||||
}
|
||||
|
||||
func (v ConfigOutputValue) configCheckableSigil() {
|
||||
// ConfigOutputValue is the ConfigCheckable for AbsOutputValue.
|
||||
}
|
||||
|
||||
func (v ConfigOutputValue) UniqueKey() UniqueKey {
|
||||
return configOutputValueUniqueKey(v.String())
|
||||
}
|
||||
|
||||
type configOutputValueUniqueKey string
|
||||
|
||||
func (k configOutputValueUniqueKey) uniqueKeySigil() {}
|
||||
|
@ -210,7 +210,6 @@ func (r AbsResource) UniqueKey() UniqueKey {
|
||||
// AbsResourceInstance is an absolute address for a resource instance under a
|
||||
// given module path.
|
||||
type AbsResourceInstance struct {
|
||||
checkable
|
||||
targetable
|
||||
Module ModuleInstance
|
||||
Resource ResourceInstance
|
||||
@ -241,6 +240,15 @@ func (r AbsResourceInstance) ContainingResource() AbsResource {
|
||||
}
|
||||
}
|
||||
|
||||
// ConfigResource returns the address of the configuration block that declared
|
||||
// this instance.
|
||||
func (r AbsResourceInstance) ConfigResource() ConfigResource {
|
||||
return ConfigResource{
|
||||
Module: r.Module.Module(),
|
||||
Resource: r.Resource.Resource,
|
||||
}
|
||||
}
|
||||
|
||||
// TargetContains implements Targetable by returning true if the given other
|
||||
// address is equal to the receiver.
|
||||
func (r AbsResourceInstance) TargetContains(other Targetable) bool {
|
||||
@ -322,6 +330,14 @@ func (r AbsResourceInstance) Less(o AbsResourceInstance) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// AbsResourceInstance is a Checkable
|
||||
func (r AbsResourceInstance) checkableSigil() {}
|
||||
|
||||
func (r AbsResourceInstance) ConfigCheckable() ConfigCheckable {
|
||||
// The ConfigCheckable for an AbsResourceInstance is its ConfigResource.
|
||||
return r.ConfigResource()
|
||||
}
|
||||
|
||||
type absResourceInstanceKey string
|
||||
|
||||
func (r AbsResourceInstance) UniqueKey() UniqueKey {
|
||||
@ -393,10 +409,22 @@ func (r ConfigResource) Equal(o ConfigResource) bool {
|
||||
return r.Module.Equal(o.Module) && r.Resource.Equal(o.Resource)
|
||||
}
|
||||
|
||||
func (r ConfigResource) configMoveableSigil() {
|
||||
// AbsResource is moveable
|
||||
func (r ConfigResource) UniqueKey() UniqueKey {
|
||||
return configResourceKey(r.String())
|
||||
}
|
||||
|
||||
func (r ConfigResource) configMoveableSigil() {
|
||||
// ConfigResource is moveable
|
||||
}
|
||||
|
||||
func (r ConfigResource) configCheckableSigil() {
|
||||
// ConfigResource represents a configuration object that declares checkable objects
|
||||
}
|
||||
|
||||
type configResourceKey string
|
||||
|
||||
func (k configResourceKey) uniqueKeySigil() {}
|
||||
|
||||
// ResourceMode defines which lifecycle applies to a given resource. Each
|
||||
// resource lifecycle has a slightly different address format.
|
||||
type ResourceMode rune
|
||||
|
Loading…
Reference in New Issue
Block a user