mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Add input validation into the 'checks' outputs and tracking (#33481)
This commit is contained in:
parent
f74a8d16cf
commit
c9bc7e8479
@ -44,6 +44,12 @@ func (c CheckRule) String() string {
|
|||||||
return fmt.Sprintf("%s.postcondition[%d]", container, c.Index)
|
return fmt.Sprintf("%s.postcondition[%d]", container, c.Index)
|
||||||
case OutputPrecondition:
|
case OutputPrecondition:
|
||||||
return fmt.Sprintf("%s.precondition[%d]", container, c.Index)
|
return fmt.Sprintf("%s.precondition[%d]", container, c.Index)
|
||||||
|
case CheckDataResource:
|
||||||
|
return fmt.Sprintf("%s.data[%d]", container, c.Index)
|
||||||
|
case CheckAssertion:
|
||||||
|
return fmt.Sprintf("%s.assert[%d]", container, c.Index)
|
||||||
|
case InputValidation:
|
||||||
|
return fmt.Sprintf("%s.validation[%d]", container, c.Index)
|
||||||
default:
|
default:
|
||||||
// This should not happen
|
// This should not happen
|
||||||
return fmt.Sprintf("%s.condition[%d]", container, c.Index)
|
return fmt.Sprintf("%s.condition[%d]", container, c.Index)
|
||||||
@ -85,6 +91,7 @@ const (
|
|||||||
OutputPrecondition CheckRuleType = 3
|
OutputPrecondition CheckRuleType = 3
|
||||||
CheckDataResource CheckRuleType = 4
|
CheckDataResource CheckRuleType = 4
|
||||||
CheckAssertion CheckRuleType = 5
|
CheckAssertion CheckRuleType = 5
|
||||||
|
InputValidation CheckRuleType = 6
|
||||||
)
|
)
|
||||||
|
|
||||||
// Description returns a human-readable description of the check type. This is
|
// Description returns a human-readable description of the check type. This is
|
||||||
@ -101,6 +108,8 @@ func (c CheckRuleType) Description() string {
|
|||||||
return "Check block data resource"
|
return "Check block data resource"
|
||||||
case CheckAssertion:
|
case CheckAssertion:
|
||||||
return "Check block assertion"
|
return "Check block assertion"
|
||||||
|
case InputValidation:
|
||||||
|
return "Input variable validation"
|
||||||
default:
|
default:
|
||||||
// This should not happen
|
// This should not happen
|
||||||
return "Condition"
|
return "Condition"
|
||||||
|
@ -56,6 +56,7 @@ const (
|
|||||||
CheckableResource CheckableKind = 'R'
|
CheckableResource CheckableKind = 'R'
|
||||||
CheckableOutputValue CheckableKind = 'O'
|
CheckableOutputValue CheckableKind = 'O'
|
||||||
CheckableCheck CheckableKind = 'C'
|
CheckableCheck CheckableKind = 'C'
|
||||||
|
CheckableInputVariable CheckableKind = 'I'
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConfigCheckable is an interfaces implemented by address types that represent
|
// ConfigCheckable is an interfaces implemented by address types that represent
|
||||||
@ -179,6 +180,14 @@ func ParseCheckableStr(kind CheckableKind, src string) (Checkable, tfdiags.Diagn
|
|||||||
}
|
}
|
||||||
return Check{Name: name}.Absolute(path), diags
|
return Check{Name: name}.Absolute(path), diags
|
||||||
|
|
||||||
|
case CheckableInputVariable:
|
||||||
|
name, nameDiags := getCheckableName("var", "variable value")
|
||||||
|
diags = diags.Append(nameDiags)
|
||||||
|
if diags.HasErrors() {
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
|
return InputVariable{Name: name}.Absolute(path), diags
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupported CheckableKind %s", kind))
|
panic(fmt.Sprintf("unsupported CheckableKind %s", kind))
|
||||||
}
|
}
|
||||||
|
@ -12,13 +12,15 @@ func _() {
|
|||||||
_ = x[CheckableResource-82]
|
_ = x[CheckableResource-82]
|
||||||
_ = x[CheckableOutputValue-79]
|
_ = x[CheckableOutputValue-79]
|
||||||
_ = x[CheckableCheck-67]
|
_ = x[CheckableCheck-67]
|
||||||
|
_ = x[CheckableInputVariable-73]
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_CheckableKind_name_0 = "CheckableKindInvalid"
|
_CheckableKind_name_0 = "CheckableKindInvalid"
|
||||||
_CheckableKind_name_1 = "CheckableCheck"
|
_CheckableKind_name_1 = "CheckableCheck"
|
||||||
_CheckableKind_name_2 = "CheckableOutputValue"
|
_CheckableKind_name_2 = "CheckableInputVariable"
|
||||||
_CheckableKind_name_3 = "CheckableResource"
|
_CheckableKind_name_3 = "CheckableOutputValue"
|
||||||
|
_CheckableKind_name_4 = "CheckableResource"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (i CheckableKind) String() string {
|
func (i CheckableKind) String() string {
|
||||||
@ -27,10 +29,12 @@ func (i CheckableKind) String() string {
|
|||||||
return _CheckableKind_name_0
|
return _CheckableKind_name_0
|
||||||
case i == 67:
|
case i == 67:
|
||||||
return _CheckableKind_name_1
|
return _CheckableKind_name_1
|
||||||
case i == 79:
|
case i == 73:
|
||||||
return _CheckableKind_name_2
|
return _CheckableKind_name_2
|
||||||
case i == 82:
|
case i == 79:
|
||||||
return _CheckableKind_name_3
|
return _CheckableKind_name_3
|
||||||
|
case i == 82:
|
||||||
|
return _CheckableKind_name_4
|
||||||
default:
|
default:
|
||||||
return "CheckableKind(" + strconv.FormatInt(int64(i), 10) + ")"
|
return "CheckableKind(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,12 @@ func _() {
|
|||||||
_ = x[OutputPrecondition-3]
|
_ = x[OutputPrecondition-3]
|
||||||
_ = x[CheckDataResource-4]
|
_ = x[CheckDataResource-4]
|
||||||
_ = x[CheckAssertion-5]
|
_ = x[CheckAssertion-5]
|
||||||
|
_ = x[InputValidation-6]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _CheckRuleType_name = "InvalidConditionResourcePreconditionResourcePostconditionOutputPreconditionCheckDataResourceCheckAssertion"
|
const _CheckRuleType_name = "InvalidConditionResourcePreconditionResourcePostconditionOutputPreconditionCheckDataResourceCheckAssertionInputValidation"
|
||||||
|
|
||||||
var _CheckRuleType_index = [...]uint8{0, 16, 36, 57, 75, 92, 106}
|
var _CheckRuleType_index = [...]uint8{0, 16, 36, 57, 75, 92, 106, 121}
|
||||||
|
|
||||||
func (i CheckRuleType) String() string {
|
func (i CheckRuleType) String() string {
|
||||||
if i < 0 || i >= CheckRuleType(len(_CheckRuleType_index)-1) {
|
if i < 0 || i >= CheckRuleType(len(_CheckRuleType_index)-1) {
|
||||||
|
@ -32,6 +32,13 @@ func (v InputVariable) Absolute(m ModuleInstance) AbsInputVariableInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v InputVariable) InModule(module Module) ConfigInputVariable {
|
||||||
|
return ConfigInputVariable{
|
||||||
|
Module: module,
|
||||||
|
Variable: v,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// AbsInputVariableInstance is the address of an input variable within a
|
// AbsInputVariableInstance is the address of an input variable within a
|
||||||
// particular module instance.
|
// particular module instance.
|
||||||
type AbsInputVariableInstance struct {
|
type AbsInputVariableInstance struct {
|
||||||
@ -39,6 +46,8 @@ type AbsInputVariableInstance struct {
|
|||||||
Variable InputVariable
|
Variable InputVariable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ Checkable = AbsInputVariableInstance{}
|
||||||
|
|
||||||
// InputVariable returns the absolute address of the input variable of the
|
// InputVariable returns the absolute address of the input variable of the
|
||||||
// given name inside the receiving module instance.
|
// given name inside the receiving module instance.
|
||||||
func (m ModuleInstance) InputVariable(name string) AbsInputVariableInstance {
|
func (m ModuleInstance) InputVariable(name string) AbsInputVariableInstance {
|
||||||
@ -57,3 +66,61 @@ func (v AbsInputVariableInstance) String() string {
|
|||||||
|
|
||||||
return fmt.Sprintf("%s.%s", v.Module.String(), v.Variable.String())
|
return fmt.Sprintf("%s.%s", v.Module.String(), v.Variable.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v AbsInputVariableInstance) UniqueKey() UniqueKey {
|
||||||
|
return absInputVariableInstanceUniqueKey(v.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v AbsInputVariableInstance) checkableSigil() {}
|
||||||
|
|
||||||
|
func (v AbsInputVariableInstance) CheckRule(typ CheckRuleType, i int) CheckRule {
|
||||||
|
return CheckRule{
|
||||||
|
Container: v,
|
||||||
|
Type: typ,
|
||||||
|
Index: i,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v AbsInputVariableInstance) ConfigCheckable() ConfigCheckable {
|
||||||
|
return ConfigInputVariable{
|
||||||
|
Module: v.Module.Module(),
|
||||||
|
Variable: v.Variable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v AbsInputVariableInstance) CheckableKind() CheckableKind {
|
||||||
|
return CheckableInputVariable
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConfigInputVariable struct {
|
||||||
|
Module Module
|
||||||
|
Variable InputVariable
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ ConfigCheckable = ConfigInputVariable{}
|
||||||
|
|
||||||
|
func (v ConfigInputVariable) UniqueKey() UniqueKey {
|
||||||
|
return configInputVariableUniqueKey(v.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v ConfigInputVariable) configCheckableSigil() {}
|
||||||
|
|
||||||
|
func (v ConfigInputVariable) CheckableKind() CheckableKind {
|
||||||
|
return CheckableInputVariable
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v ConfigInputVariable) String() string {
|
||||||
|
if len(v.Module) == 0 {
|
||||||
|
return v.Variable.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s.%s", v.Module.String(), v.Variable.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
type configInputVariableUniqueKey string
|
||||||
|
|
||||||
|
func (k configInputVariableUniqueKey) uniqueKeySigil() {}
|
||||||
|
|
||||||
|
type absInputVariableInstanceUniqueKey string
|
||||||
|
|
||||||
|
func (k absInputVariableInstanceUniqueKey) uniqueKeySigil() {}
|
||||||
|
@ -68,6 +68,22 @@ func collectInitialStatuses(into addrs.Map[addrs.ConfigCheckable, *configCheckab
|
|||||||
into.Put(addr, st)
|
into.Put(addr, st)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, v := range cfg.Module.Variables {
|
||||||
|
addr := v.Addr().InModule(moduleAddr)
|
||||||
|
|
||||||
|
vs := len(v.Validations)
|
||||||
|
if vs == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
st := &configCheckableState{}
|
||||||
|
st.checkTypes = map[addrs.CheckRuleType]int{
|
||||||
|
addrs.InputValidation: vs,
|
||||||
|
}
|
||||||
|
|
||||||
|
into.Put(addr, st)
|
||||||
|
}
|
||||||
|
|
||||||
// Must also visit child modules to collect everything
|
// Must also visit child modules to collect everything
|
||||||
for _, child := range cfg.Children {
|
for _, child := range cfg.Children {
|
||||||
collectInitialStatuses(into, child)
|
collectInitialStatuses(into, child)
|
||||||
|
@ -59,6 +59,17 @@ func makeStaticObjectAddr(addr addrs.ConfigCheckable) staticObjectAddr {
|
|||||||
if !addr.Module.IsRoot() {
|
if !addr.Module.IsRoot() {
|
||||||
ret["module"] = addr.Module.String()
|
ret["module"] = addr.Module.String()
|
||||||
}
|
}
|
||||||
|
case addrs.ConfigInputVariable:
|
||||||
|
if kind := addr.CheckableKind(); kind != addrs.CheckableInputVariable {
|
||||||
|
// Something has gone very wrong
|
||||||
|
panic(fmt.Sprintf("%T has CheckableKind %s", addr, kind))
|
||||||
|
}
|
||||||
|
|
||||||
|
ret["kind"] = "var"
|
||||||
|
ret["name"] = addr.Variable.Name
|
||||||
|
if !addr.Module.IsRoot() {
|
||||||
|
ret["module"] = addr.Module.String()
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupported ConfigCheckable implementation %T", addr))
|
panic(fmt.Sprintf("unsupported ConfigCheckable implementation %T", addr))
|
||||||
}
|
}
|
||||||
@ -89,6 +100,10 @@ func makeDynamicObjectAddr(addr addrs.Checkable) dynamicObjectAddr {
|
|||||||
if !addr.Module.IsRoot() {
|
if !addr.Module.IsRoot() {
|
||||||
ret["module"] = addr.Module.String()
|
ret["module"] = addr.Module.String()
|
||||||
}
|
}
|
||||||
|
case addrs.AbsInputVariableInstance:
|
||||||
|
if !addr.Module.IsRoot() {
|
||||||
|
ret["module"] = addr.Module.String()
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupported Checkable implementation %T", addr))
|
panic(fmt.Sprintf("unsupported Checkable implementation %T", addr))
|
||||||
}
|
}
|
||||||
|
@ -283,6 +283,7 @@ const (
|
|||||||
CheckResults_RESOURCE CheckResults_ObjectKind = 1
|
CheckResults_RESOURCE CheckResults_ObjectKind = 1
|
||||||
CheckResults_OUTPUT_VALUE CheckResults_ObjectKind = 2
|
CheckResults_OUTPUT_VALUE CheckResults_ObjectKind = 2
|
||||||
CheckResults_CHECK CheckResults_ObjectKind = 3
|
CheckResults_CHECK CheckResults_ObjectKind = 3
|
||||||
|
CheckResults_INPUT_VARIABLE CheckResults_ObjectKind = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
// Enum value maps for CheckResults_ObjectKind.
|
// Enum value maps for CheckResults_ObjectKind.
|
||||||
@ -292,12 +293,14 @@ var (
|
|||||||
1: "RESOURCE",
|
1: "RESOURCE",
|
||||||
2: "OUTPUT_VALUE",
|
2: "OUTPUT_VALUE",
|
||||||
3: "CHECK",
|
3: "CHECK",
|
||||||
|
4: "INPUT_VARIABLE",
|
||||||
}
|
}
|
||||||
CheckResults_ObjectKind_value = map[string]int32{
|
CheckResults_ObjectKind_value = map[string]int32{
|
||||||
"UNSPECIFIED": 0,
|
"UNSPECIFIED": 0,
|
||||||
"RESOURCE": 1,
|
"RESOURCE": 1,
|
||||||
"OUTPUT_VALUE": 2,
|
"OUTPUT_VALUE": 2,
|
||||||
"CHECK": 3,
|
"CHECK": 3,
|
||||||
|
"INPUT_VARIABLE": 4,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1449,7 +1452,7 @@ var file_planfile_proto_rawDesc = []byte{
|
|||||||
0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x61, 0x6e,
|
0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x61, 0x6e,
|
||||||
0x67, 0x65, 0x52, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65,
|
0x67, 0x65, 0x52, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65,
|
||||||
0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73,
|
0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73,
|
||||||
0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x22, 0xe8, 0x03, 0x0a, 0x0c, 0x43, 0x68, 0x65,
|
0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x22, 0xfc, 0x03, 0x0a, 0x0c, 0x43, 0x68, 0x65,
|
||||||
0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x33, 0x0a, 0x04, 0x6b, 0x69, 0x6e,
|
0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x33, 0x0a, 0x04, 0x6b, 0x69, 0x6e,
|
||||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e,
|
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e,
|
||||||
0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x4f, 0x62,
|
0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x4f, 0x62,
|
||||||
@ -1475,70 +1478,72 @@ var file_planfile_proto_rawDesc = []byte{
|
|||||||
0x67, 0x65, 0x73, 0x22, 0x34, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a,
|
0x67, 0x65, 0x73, 0x22, 0x34, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a,
|
||||||
0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x41,
|
0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x41,
|
||||||
0x53, 0x53, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x02, 0x12, 0x09,
|
0x53, 0x53, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x02, 0x12, 0x09,
|
||||||
0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x22, 0x48, 0x0a, 0x0a, 0x4f, 0x62, 0x6a,
|
0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x22, 0x5c, 0x0a, 0x0a, 0x4f, 0x62, 0x6a,
|
||||||
0x65, 0x63, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45,
|
0x65, 0x63, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45,
|
||||||
0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x53, 0x4f,
|
0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x53, 0x4f,
|
||||||
0x55, 0x52, 0x43, 0x45, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54,
|
0x55, 0x52, 0x43, 0x45, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54,
|
||||||
0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x48, 0x45, 0x43,
|
0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x48, 0x45, 0x43,
|
||||||
0x4b, 0x10, 0x03, 0x22, 0x28, 0x0a, 0x0c, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61,
|
0x4b, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x56, 0x41, 0x52,
|
||||||
0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x73, 0x67, 0x70, 0x61, 0x63, 0x6b, 0x18, 0x01,
|
0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x04, 0x22, 0x28, 0x0a, 0x0c, 0x44, 0x79, 0x6e, 0x61, 0x6d,
|
||||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x73, 0x67, 0x70, 0x61, 0x63, 0x6b, 0x22, 0xa5, 0x01,
|
0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x73, 0x67, 0x70, 0x61,
|
||||||
0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x27, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18,
|
0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x73, 0x67, 0x70, 0x61, 0x63,
|
||||||
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50,
|
0x6b, 0x22, 0xa5, 0x01, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x27, 0x0a, 0x05, 0x73, 0x74,
|
||||||
0x61, 0x74, 0x68, 0x2e, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x1a,
|
0x65, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c,
|
||||||
0x74, 0x0a, 0x04, 0x53, 0x74, 0x65, 0x70, 0x12, 0x27, 0x0a, 0x0e, 0x61, 0x74, 0x74, 0x72, 0x69,
|
0x61, 0x6e, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05, 0x73, 0x74,
|
||||||
0x62, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48,
|
0x65, 0x70, 0x73, 0x1a, 0x74, 0x0a, 0x04, 0x53, 0x74, 0x65, 0x70, 0x12, 0x27, 0x0a, 0x0e, 0x61,
|
||||||
0x00, 0x52, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65,
|
0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
|
||||||
0x12, 0x37, 0x0a, 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18,
|
0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
|
||||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x44,
|
0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f,
|
||||||
0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x65,
|
0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x66, 0x70, 0x6c,
|
||||||
0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x65, 0x6c,
|
0x61, 0x6e, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48,
|
||||||
0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x1b, 0x0a, 0x09, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x69,
|
0x00, 0x52, 0x0a, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x42, 0x0a, 0x0a,
|
||||||
0x6e, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
|
0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x1b, 0x0a, 0x09, 0x49, 0x6d, 0x70,
|
||||||
0x69, 0x64, 0x2a, 0x31, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f,
|
0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||||
0x52, 0x4d, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f,
|
0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x2a, 0x31, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0a,
|
||||||
0x59, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x45, 0x46, 0x52, 0x45, 0x53, 0x48, 0x5f, 0x4f,
|
0x0a, 0x06, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45,
|
||||||
0x4e, 0x4c, 0x59, 0x10, 0x02, 0x2a, 0x70, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12,
|
0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x45, 0x46, 0x52, 0x45,
|
||||||
0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4f, 0x50, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x45,
|
0x53, 0x48, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, 0x2a, 0x70, 0x0a, 0x06, 0x41, 0x63, 0x74,
|
||||||
0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x45, 0x41, 0x44, 0x10, 0x02, 0x12,
|
0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4f, 0x50, 0x10, 0x00, 0x12, 0x0a, 0x0a,
|
||||||
0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x44,
|
0x06, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x45, 0x41,
|
||||||
0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x45, 0x4c, 0x45, 0x54,
|
0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x12,
|
||||||
0x45, 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x06, 0x12,
|
0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x44,
|
||||||
0x16, 0x0a, 0x12, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f, 0x44,
|
0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54,
|
||||||
0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x07, 0x2a, 0xc8, 0x03, 0x0a, 0x1c, 0x52, 0x65, 0x73, 0x6f,
|
0x45, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x48,
|
||||||
0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69,
|
0x45, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x07, 0x2a, 0xc8, 0x03, 0x0a, 0x1c,
|
||||||
0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45,
|
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
|
||||||
0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x45,
|
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04,
|
||||||
0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12,
|
0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43,
|
||||||
0x16, 0x0a, 0x12, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x59, 0x5f, 0x52, 0x45,
|
0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x45,
|
||||||
0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, 0x50, 0x4c, 0x41,
|
0x44, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42,
|
||||||
0x43, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x41, 0x4e, 0x4e, 0x4f,
|
0x59, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x52,
|
||||||
0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x45,
|
0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43,
|
||||||
0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e, 0x4f, 0x5f,
|
0x41, 0x4e, 0x4e, 0x4f, 0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x12, 0x25,
|
||||||
0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10,
|
0x0a, 0x21, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45,
|
||||||
0x04, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41,
|
0x5f, 0x4e, 0x4f, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x4e,
|
||||||
0x55, 0x53, 0x45, 0x5f, 0x57, 0x52, 0x4f, 0x4e, 0x47, 0x5f, 0x52, 0x45, 0x50, 0x45, 0x54, 0x49,
|
0x46, 0x49, 0x47, 0x10, 0x04, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f,
|
||||||
0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45,
|
0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x57, 0x52, 0x4f, 0x4e, 0x47, 0x5f, 0x52, 0x45,
|
||||||
0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x49,
|
0x50, 0x45, 0x54, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x44, 0x45,
|
||||||
0x4e, 0x44, 0x45, 0x58, 0x10, 0x06, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45,
|
0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x4f, 0x55,
|
||||||
0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x45, 0x41, 0x43, 0x48, 0x5f, 0x4b, 0x45,
|
0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x10, 0x06, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x45,
|
||||||
0x59, 0x10, 0x07, 0x12, 0x1c, 0x0a, 0x18, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45,
|
0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x45, 0x41, 0x43,
|
||||||
0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10,
|
0x48, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x07, 0x12, 0x1c, 0x0a, 0x18, 0x44, 0x45, 0x4c, 0x45, 0x54,
|
||||||
0x08, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x59, 0x5f,
|
0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x4f, 0x44,
|
||||||
0x54, 0x52, 0x49, 0x47, 0x47, 0x45, 0x52, 0x53, 0x10, 0x09, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x45,
|
0x55, 0x4c, 0x45, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45,
|
||||||
0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49,
|
0x5f, 0x42, 0x59, 0x5f, 0x54, 0x52, 0x49, 0x47, 0x47, 0x45, 0x52, 0x53, 0x10, 0x09, 0x12, 0x1f,
|
||||||
0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x0a, 0x12, 0x23, 0x0a, 0x1f, 0x52,
|
0x0a, 0x1b, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43,
|
||||||
0x45, 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x44, 0x45, 0x50, 0x45,
|
0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x0a, 0x12,
|
||||||
0x4e, 0x44, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x0b,
|
0x23, 0x0a, 0x1f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f,
|
||||||
0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45,
|
0x44, 0x45, 0x50, 0x45, 0x4e, 0x44, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49,
|
||||||
0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x4e, 0x45, 0x53, 0x54, 0x45, 0x44, 0x10, 0x0d, 0x12,
|
0x4e, 0x47, 0x10, 0x0b, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43,
|
||||||
0x21, 0x0a, 0x1d, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53,
|
0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x4e, 0x45, 0x53, 0x54, 0x45,
|
||||||
0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54,
|
0x44, 0x10, 0x0d, 0x12, 0x21, 0x0a, 0x1d, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45,
|
||||||
0x10, 0x0c, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x41,
|
||||||
0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x74, 0x65, 0x72, 0x72, 0x61,
|
0x52, 0x47, 0x45, 0x54, 0x10, 0x0c, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||||
0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6c,
|
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x74,
|
||||||
0x61, 0x6e, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6c, 0x61,
|
0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
|
||||||
0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x6c, 0x2f, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||||
|
0x2f, 0x70, 0x6c, 0x61, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||||
|
0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -253,6 +253,7 @@ message CheckResults {
|
|||||||
RESOURCE = 1;
|
RESOURCE = 1;
|
||||||
OUTPUT_VALUE = 2;
|
OUTPUT_VALUE = 2;
|
||||||
CHECK = 3;
|
CHECK = 3;
|
||||||
|
INPUT_VARIABLE = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ObjectResult {
|
message ObjectResult {
|
||||||
|
@ -120,6 +120,8 @@ func readTfplan(r io.Reader) (*plans.Plan, error) {
|
|||||||
objKind = addrs.CheckableOutputValue
|
objKind = addrs.CheckableOutputValue
|
||||||
case planproto.CheckResults_CHECK:
|
case planproto.CheckResults_CHECK:
|
||||||
objKind = addrs.CheckableCheck
|
objKind = addrs.CheckableCheck
|
||||||
|
case planproto.CheckResults_INPUT_VARIABLE:
|
||||||
|
objKind = addrs.CheckableInputVariable
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("aggregate check results for %s have unsupported object kind %s", rawCRs.ConfigAddr, objKind)
|
return nil, fmt.Errorf("aggregate check results for %s have unsupported object kind %s", rawCRs.ConfigAddr, objKind)
|
||||||
}
|
}
|
||||||
@ -545,6 +547,8 @@ func writeTfplan(plan *plans.Plan, w io.Writer) error {
|
|||||||
pcrs.Kind = planproto.CheckResults_OUTPUT_VALUE
|
pcrs.Kind = planproto.CheckResults_OUTPUT_VALUE
|
||||||
case addrs.CheckableCheck:
|
case addrs.CheckableCheck:
|
||||||
pcrs.Kind = planproto.CheckResults_CHECK
|
pcrs.Kind = planproto.CheckResults_CHECK
|
||||||
|
case addrs.CheckableInputVariable:
|
||||||
|
pcrs.Kind = planproto.CheckResults_INPUT_VARIABLE
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("checkable configuration %s has unsupported object type kind %s", configElem.Key, kind)
|
return fmt.Errorf("checkable configuration %s has unsupported object type kind %s", configElem.Key, kind)
|
||||||
}
|
}
|
||||||
|
@ -643,6 +643,8 @@ func decodeCheckableObjectKindV4(in string) addrs.CheckableKind {
|
|||||||
return addrs.CheckableOutputValue
|
return addrs.CheckableOutputValue
|
||||||
case "check":
|
case "check":
|
||||||
return addrs.CheckableCheck
|
return addrs.CheckableCheck
|
||||||
|
case "var":
|
||||||
|
return addrs.CheckableInputVariable
|
||||||
default:
|
default:
|
||||||
// We'll treat anything else as invalid just as a concession to
|
// We'll treat anything else as invalid just as a concession to
|
||||||
// forward-compatible parsing, in case a later version of Terraform
|
// forward-compatible parsing, in case a later version of Terraform
|
||||||
@ -659,6 +661,8 @@ func encodeCheckableObjectKindV4(in addrs.CheckableKind) string {
|
|||||||
return "output"
|
return "output"
|
||||||
case addrs.CheckableCheck:
|
case addrs.CheckableCheck:
|
||||||
return "check"
|
return "check"
|
||||||
|
case addrs.CheckableInputVariable:
|
||||||
|
return "var"
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupported checkable object kind %s", in))
|
panic(fmt.Sprintf("unsupported checkable object kind %s", in))
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,14 @@ import (
|
|||||||
|
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/hcl/v2/gohcl"
|
"github.com/hashicorp/hcl/v2/gohcl"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
"github.com/zclconf/go-cty/cty/convert"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/internal/addrs"
|
"github.com/hashicorp/terraform/internal/addrs"
|
||||||
|
"github.com/hashicorp/terraform/internal/checks"
|
||||||
"github.com/hashicorp/terraform/internal/configs"
|
"github.com/hashicorp/terraform/internal/configs"
|
||||||
"github.com/hashicorp/terraform/internal/lang/marks"
|
"github.com/hashicorp/terraform/internal/lang/marks"
|
||||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||||
"github.com/zclconf/go-cty/cty"
|
|
||||||
"github.com/zclconf/go-cty/cty/convert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func prepareFinalInputVariableValue(addr addrs.AbsInputVariableInstance, raw *InputValue, cfg *configs.Variable) (cty.Value, tfdiags.Diagnostics) {
|
func prepareFinalInputVariableValue(addr addrs.AbsInputVariableInstance, raw *InputValue, cfg *configs.Variable) (cty.Value, tfdiags.Diagnostics) {
|
||||||
@ -202,6 +204,16 @@ func evalVariableValidations(addr addrs.AbsInputVariableInstance, config *config
|
|||||||
}
|
}
|
||||||
log.Printf("[TRACE] evalVariableValidations: validating %s", addr)
|
log.Printf("[TRACE] evalVariableValidations: validating %s", addr)
|
||||||
|
|
||||||
|
checkState := ctx.Checks()
|
||||||
|
if !checkState.ConfigHasChecks(addr.ConfigCheckable()) {
|
||||||
|
// We have nothing to do if this object doesn't have any checks,
|
||||||
|
// but the "rules" slice should agree that we don't.
|
||||||
|
if ct := len(config.Validations); ct != 0 {
|
||||||
|
panic(fmt.Sprintf("check state says that %s should have no rules, but it has %d", addr, ct))
|
||||||
|
}
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
// Variable nodes evaluate in the parent module to where they were declared
|
// Variable nodes evaluate in the parent module to where they were declared
|
||||||
// because the value expression (n.Expr, if set) comes from the calling
|
// because the value expression (n.Expr, if set) comes from the calling
|
||||||
// "module" block in the parent module.
|
// "module" block in the parent module.
|
||||||
@ -229,13 +241,28 @@ func evalVariableValidations(addr addrs.AbsInputVariableInstance, config *config
|
|||||||
Functions: ctx.EvaluationScope(nil, nil, EvalDataForNoInstanceKey).Functions(),
|
Functions: ctx.EvaluationScope(nil, nil, EvalDataForNoInstanceKey).Functions(),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, validation := range config.Validations {
|
for ix, validation := range config.Validations {
|
||||||
|
result, ruleDiags := evalVariableValidation(validation, hclCtx, addr, config, expr)
|
||||||
|
diags = diags.Append(ruleDiags)
|
||||||
|
|
||||||
|
log.Printf("[TRACE] evalVariableValidations: %s status is now %s", addr, result.Status)
|
||||||
|
if result.Status == checks.StatusFail {
|
||||||
|
checkState.ReportCheckFailure(addr, addrs.InputValidation, ix, result.FailureMessage)
|
||||||
|
} else {
|
||||||
|
checkState.ReportCheckResult(addr, addrs.InputValidation, ix, result.Status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
func evalVariableValidation(validation *configs.CheckRule, hclCtx *hcl.EvalContext, addr addrs.AbsInputVariableInstance, config *configs.Variable, expr hcl.Expression) (checkResult, tfdiags.Diagnostics) {
|
||||||
const errInvalidCondition = "Invalid variable validation result"
|
const errInvalidCondition = "Invalid variable validation result"
|
||||||
const errInvalidValue = "Invalid value for variable"
|
const errInvalidValue = "Invalid value for variable"
|
||||||
var ruleDiags tfdiags.Diagnostics
|
var diags tfdiags.Diagnostics
|
||||||
|
|
||||||
result, moreDiags := validation.Condition.Value(hclCtx)
|
result, moreDiags := validation.Condition.Value(hclCtx)
|
||||||
ruleDiags = ruleDiags.Append(moreDiags)
|
diags = diags.Append(moreDiags)
|
||||||
errorValue, errorDiags := validation.ErrorMessage.Value(hclCtx)
|
errorValue, errorDiags := validation.ErrorMessage.Value(hclCtx)
|
||||||
|
|
||||||
// The following error handling is a workaround to preserve backwards
|
// The following error handling is a workaround to preserve backwards
|
||||||
@ -286,17 +313,16 @@ func evalVariableValidations(addr addrs.AbsInputVariableInstance, config *config
|
|||||||
|
|
||||||
// We want to either report the original diagnostics if the
|
// We want to either report the original diagnostics if the
|
||||||
// fallback failed, or the warning generated above if it succeeded.
|
// fallback failed, or the warning generated above if it succeeded.
|
||||||
ruleDiags = ruleDiags.Append(errorDiags)
|
diags = diags.Append(errorDiags)
|
||||||
}
|
}
|
||||||
|
|
||||||
diags = diags.Append(ruleDiags)
|
if diags.HasErrors() {
|
||||||
|
log.Printf("[TRACE] evalVariableValidations: %s rule %s check rule evaluation failed: %s", addr, validation.DeclRange, diags.Err().Error())
|
||||||
if ruleDiags.HasErrors() {
|
|
||||||
log.Printf("[TRACE] evalVariableValidations: %s rule %s check rule evaluation failed: %s", addr, validation.DeclRange, ruleDiags.Err().Error())
|
|
||||||
}
|
}
|
||||||
if !result.IsKnown() {
|
if !result.IsKnown() {
|
||||||
log.Printf("[TRACE] evalVariableValidations: %s rule %s condition value is unknown, so skipping validation for now", addr, validation.DeclRange)
|
log.Printf("[TRACE] evalVariableValidations: %s rule %s condition value is unknown, so skipping validation for now", addr, validation.DeclRange)
|
||||||
continue // We'll wait until we've learned more, then.
|
|
||||||
|
return checkResult{Status: checks.StatusUnknown}, diags // We'll wait until we've learned more, then.
|
||||||
}
|
}
|
||||||
if result.IsNull() {
|
if result.IsNull() {
|
||||||
diags = diags.Append(&hcl.Diagnostic{
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
@ -307,7 +333,7 @@ func evalVariableValidations(addr addrs.AbsInputVariableInstance, config *config
|
|||||||
Expression: validation.Condition,
|
Expression: validation.Condition,
|
||||||
EvalContext: hclCtx,
|
EvalContext: hclCtx,
|
||||||
})
|
})
|
||||||
continue
|
return checkResult{Status: checks.StatusError}, diags
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
result, err = convert.Convert(result, cty.Bool)
|
result, err = convert.Convert(result, cty.Bool)
|
||||||
@ -320,16 +346,17 @@ func evalVariableValidations(addr addrs.AbsInputVariableInstance, config *config
|
|||||||
Expression: validation.Condition,
|
Expression: validation.Condition,
|
||||||
EvalContext: hclCtx,
|
EvalContext: hclCtx,
|
||||||
})
|
})
|
||||||
continue
|
return checkResult{Status: checks.StatusError}, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validation condition may be marked if the input variable is bound to
|
// Validation condition may be marked if the input variable is bound to
|
||||||
// a sensitive value. This is irrelevant to the validation process, so
|
// a sensitive value. This is irrelevant to the validation process, so
|
||||||
// we discard the marks now.
|
// we discard the marks now.
|
||||||
result, _ = result.Unmark()
|
result, _ = result.Unmark()
|
||||||
|
status := checks.StatusForCtyValue(result)
|
||||||
|
|
||||||
if result.True() {
|
if status != checks.StatusFail {
|
||||||
continue
|
return checkResult{Status: status}, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
var errorMessage string
|
var errorMessage string
|
||||||
@ -391,7 +418,9 @@ You can correct this by removing references to sensitive values, or by carefully
|
|||||||
EvalContext: hclCtx,
|
EvalContext: hclCtx,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return diags
|
return checkResult{
|
||||||
|
Status: status,
|
||||||
|
FailureMessage: errorMessage,
|
||||||
|
}, diags
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/internal/addrs"
|
"github.com/hashicorp/terraform/internal/addrs"
|
||||||
|
"github.com/hashicorp/terraform/internal/checks"
|
||||||
"github.com/hashicorp/terraform/internal/lang"
|
"github.com/hashicorp/terraform/internal/lang"
|
||||||
"github.com/hashicorp/terraform/internal/lang/marks"
|
"github.com/hashicorp/terraform/internal/lang/marks"
|
||||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||||
@ -1107,12 +1108,14 @@ func TestEvalVariableValidations_jsonErrorMessageEdgeCase(t *testing.T) {
|
|||||||
given cty.Value
|
given cty.Value
|
||||||
wantErr []string
|
wantErr []string
|
||||||
wantWarn []string
|
wantWarn []string
|
||||||
|
status checks.Status
|
||||||
}{
|
}{
|
||||||
// Valid variable validation declaration, assigned value which passes
|
// Valid variable validation declaration, assigned value which passes
|
||||||
// the condition generates no diagnostics.
|
// the condition generates no diagnostics.
|
||||||
{
|
{
|
||||||
varName: "valid",
|
varName: "valid",
|
||||||
given: cty.StringVal("foo"),
|
given: cty.StringVal("foo"),
|
||||||
|
status: checks.StatusPass,
|
||||||
},
|
},
|
||||||
// Assigning a value which fails the condition generates an error
|
// Assigning a value which fails the condition generates an error
|
||||||
// message with the expression successfully evaluated.
|
// message with the expression successfully evaluated.
|
||||||
@ -1123,6 +1126,7 @@ func TestEvalVariableValidations_jsonErrorMessageEdgeCase(t *testing.T) {
|
|||||||
"Invalid value for variable",
|
"Invalid value for variable",
|
||||||
"Valid template string bar",
|
"Valid template string bar",
|
||||||
},
|
},
|
||||||
|
status: checks.StatusFail,
|
||||||
},
|
},
|
||||||
// Invalid variable validation declaration due to an unparseable
|
// Invalid variable validation declaration due to an unparseable
|
||||||
// template string. Assigning a value which passes the condition
|
// template string. Assigning a value which passes the condition
|
||||||
@ -1134,6 +1138,7 @@ func TestEvalVariableValidations_jsonErrorMessageEdgeCase(t *testing.T) {
|
|||||||
"Validation error message expression is invalid",
|
"Validation error message expression is invalid",
|
||||||
"Missing expression; Expected the start of an expression, but found the end of the file.",
|
"Missing expression; Expected the start of an expression, but found the end of the file.",
|
||||||
},
|
},
|
||||||
|
status: checks.StatusPass,
|
||||||
},
|
},
|
||||||
// Assigning a value which fails the condition generates an error
|
// Assigning a value which fails the condition generates an error
|
||||||
// message including the configured string interpreted as a literal
|
// message including the configured string interpreted as a literal
|
||||||
@ -1149,6 +1154,7 @@ func TestEvalVariableValidations_jsonErrorMessageEdgeCase(t *testing.T) {
|
|||||||
"Validation error message expression is invalid",
|
"Validation error message expression is invalid",
|
||||||
"Missing expression; Expected the start of an expression, but found the end of the file.",
|
"Missing expression; Expected the start of an expression, but found the end of the file.",
|
||||||
},
|
},
|
||||||
|
status: checks.StatusFail,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1173,11 +1179,17 @@ func TestEvalVariableValidations_jsonErrorMessageEdgeCase(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return test.given
|
return test.given
|
||||||
}
|
}
|
||||||
|
ctx.ChecksState = checks.NewState(cfg)
|
||||||
|
ctx.ChecksState.ReportCheckableObjects(varAddr.ConfigCheckable(), addrs.MakeSet[addrs.Checkable](varAddr))
|
||||||
|
|
||||||
gotDiags := evalVariableValidations(
|
gotDiags := evalVariableValidations(
|
||||||
varAddr, varCfg, nil, ctx,
|
varAddr, varCfg, nil, ctx,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if ctx.ChecksState.ObjectCheckStatus(varAddr) != test.status {
|
||||||
|
t.Errorf("expected check result %s but instead %s", test.status, ctx.ChecksState.ObjectCheckStatus(varAddr))
|
||||||
|
}
|
||||||
|
|
||||||
if len(test.wantErr) == 0 && len(test.wantWarn) == 0 {
|
if len(test.wantErr) == 0 && len(test.wantWarn) == 0 {
|
||||||
if len(gotDiags) > 0 {
|
if len(gotDiags) > 0 {
|
||||||
t.Errorf("no diags expected, got %s", gotDiags.Err().Error())
|
t.Errorf("no diags expected, got %s", gotDiags.Err().Error())
|
||||||
@ -1258,12 +1270,14 @@ variable "bar" {
|
|||||||
varName string
|
varName string
|
||||||
given cty.Value
|
given cty.Value
|
||||||
wantErr []string
|
wantErr []string
|
||||||
|
status checks.Status
|
||||||
}{
|
}{
|
||||||
// Validations pass on a sensitive variable with an error message which
|
// Validations pass on a sensitive variable with an error message which
|
||||||
// would generate a sensitive value
|
// would generate a sensitive value
|
||||||
{
|
{
|
||||||
varName: "foo",
|
varName: "foo",
|
||||||
given: cty.StringVal("boop"),
|
given: cty.StringVal("boop"),
|
||||||
|
status: checks.StatusPass,
|
||||||
},
|
},
|
||||||
// Assigning a value which fails the condition generates a sensitive
|
// Assigning a value which fails the condition generates a sensitive
|
||||||
// error message, which is elided and generates another error
|
// error message, which is elided and generates another error
|
||||||
@ -1275,12 +1289,14 @@ variable "bar" {
|
|||||||
"The error message included a sensitive value, so it will not be displayed.",
|
"The error message included a sensitive value, so it will not be displayed.",
|
||||||
"Error message refers to sensitive values",
|
"Error message refers to sensitive values",
|
||||||
},
|
},
|
||||||
|
status: checks.StatusFail,
|
||||||
},
|
},
|
||||||
// Validations pass on a sensitive variable with a correctly defined
|
// Validations pass on a sensitive variable with a correctly defined
|
||||||
// error message
|
// error message
|
||||||
{
|
{
|
||||||
varName: "bar",
|
varName: "bar",
|
||||||
given: cty.StringVal("boop"),
|
given: cty.StringVal("boop"),
|
||||||
|
status: checks.StatusPass,
|
||||||
},
|
},
|
||||||
// Assigning a value which fails the condition generates a nonsensitive
|
// Assigning a value which fails the condition generates a nonsensitive
|
||||||
// error message, which is displayed
|
// error message, which is displayed
|
||||||
@ -1291,6 +1307,7 @@ variable "bar" {
|
|||||||
"Invalid value for variable",
|
"Invalid value for variable",
|
||||||
"Bar must be 4 characters, not 3.",
|
"Bar must be 4 characters, not 3.",
|
||||||
},
|
},
|
||||||
|
status: checks.StatusFail,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1319,11 +1336,17 @@ variable "bar" {
|
|||||||
return test.given
|
return test.given
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ctx.ChecksState = checks.NewState(cfg)
|
||||||
|
ctx.ChecksState.ReportCheckableObjects(varAddr.ConfigCheckable(), addrs.MakeSet[addrs.Checkable](varAddr))
|
||||||
|
|
||||||
gotDiags := evalVariableValidations(
|
gotDiags := evalVariableValidations(
|
||||||
varAddr, varCfg, nil, ctx,
|
varAddr, varCfg, nil, ctx,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if ctx.ChecksState.ObjectCheckStatus(varAddr) != test.status {
|
||||||
|
t.Errorf("expected check result %s but instead %s", test.status, ctx.ChecksState.ObjectCheckStatus(varAddr))
|
||||||
|
}
|
||||||
|
|
||||||
if len(test.wantErr) == 0 {
|
if len(test.wantErr) == 0 {
|
||||||
if len(gotDiags) > 0 {
|
if len(gotDiags) > 0 {
|
||||||
t.Errorf("no diags expected, got %s", gotDiags.Err().Error())
|
t.Errorf("no diags expected, got %s", gotDiags.Err().Error())
|
||||||
|
@ -67,8 +67,8 @@ func (b *EvalGraphBuilder) Steps() []GraphTransformer {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Add dynamic values
|
// Add dynamic values
|
||||||
&RootVariableTransformer{Config: b.Config, RawValues: b.RootVariableValues},
|
&RootVariableTransformer{Config: b.Config, RawValues: b.RootVariableValues, Planning: true},
|
||||||
&ModuleVariableTransformer{Config: b.Config},
|
&ModuleVariableTransformer{Config: b.Config, Planning: true},
|
||||||
&LocalTransformer{Config: b.Config},
|
&LocalTransformer{Config: b.Config},
|
||||||
&OutputTransformer{
|
&OutputTransformer{
|
||||||
Config: b.Config,
|
Config: b.Config,
|
||||||
|
@ -128,8 +128,8 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Add dynamic values
|
// Add dynamic values
|
||||||
&RootVariableTransformer{Config: b.Config, RawValues: b.RootVariableValues},
|
&RootVariableTransformer{Config: b.Config, RawValues: b.RootVariableValues, Planning: true},
|
||||||
&ModuleVariableTransformer{Config: b.Config},
|
&ModuleVariableTransformer{Config: b.Config, Planning: true},
|
||||||
&LocalTransformer{Config: b.Config},
|
&LocalTransformer{Config: b.Config},
|
||||||
&OutputTransformer{
|
&OutputTransformer{
|
||||||
Config: b.Config,
|
Config: b.Config,
|
||||||
|
@ -25,6 +25,10 @@ type nodeExpandModuleVariable struct {
|
|||||||
Module addrs.Module
|
Module addrs.Module
|
||||||
Config *configs.Variable
|
Config *configs.Variable
|
||||||
Expr hcl.Expression
|
Expr hcl.Expression
|
||||||
|
|
||||||
|
// Planning must be set to true when building a planning graph, and must be
|
||||||
|
// false when building an apply graph.
|
||||||
|
Planning bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -44,10 +48,27 @@ func (n *nodeExpandModuleVariable) temporaryValue() bool {
|
|||||||
|
|
||||||
func (n *nodeExpandModuleVariable) DynamicExpand(ctx EvalContext) (*Graph, error) {
|
func (n *nodeExpandModuleVariable) DynamicExpand(ctx EvalContext) (*Graph, error) {
|
||||||
var g Graph
|
var g Graph
|
||||||
|
|
||||||
|
// If this variable has preconditions, we need to report these checks now.
|
||||||
|
//
|
||||||
|
// We should only do this during planning as the apply phase starts with
|
||||||
|
// all the same checkable objects that were registered during the plan.
|
||||||
|
var checkableAddrs addrs.Set[addrs.Checkable]
|
||||||
|
if n.Planning {
|
||||||
|
if checkState := ctx.Checks(); checkState.ConfigHasChecks(n.Addr.InModule(n.Module)) {
|
||||||
|
checkableAddrs = addrs.MakeSet[addrs.Checkable]()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expander := ctx.InstanceExpander()
|
expander := ctx.InstanceExpander()
|
||||||
for _, module := range expander.ExpandModule(n.Module) {
|
for _, module := range expander.ExpandModule(n.Module) {
|
||||||
|
addr := n.Addr.Absolute(module)
|
||||||
|
if checkableAddrs != nil {
|
||||||
|
checkableAddrs.Add(addr)
|
||||||
|
}
|
||||||
|
|
||||||
o := &nodeModuleVariable{
|
o := &nodeModuleVariable{
|
||||||
Addr: n.Addr.Absolute(module),
|
Addr: addr,
|
||||||
Config: n.Config,
|
Config: n.Config,
|
||||||
Expr: n.Expr,
|
Expr: n.Expr,
|
||||||
ModuleInstance: module,
|
ModuleInstance: module,
|
||||||
@ -55,6 +76,11 @@ func (n *nodeExpandModuleVariable) DynamicExpand(ctx EvalContext) (*Graph, error
|
|||||||
g.Add(o)
|
g.Add(o)
|
||||||
}
|
}
|
||||||
addRootNodeToGraph(&g)
|
addRootNodeToGraph(&g)
|
||||||
|
|
||||||
|
if checkableAddrs != nil {
|
||||||
|
ctx.Checks().ReportCheckableObjects(n.Addr.InModule(n.Module), checkableAddrs)
|
||||||
|
}
|
||||||
|
|
||||||
return &g, nil
|
return &g, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,11 +6,12 @@ package terraform
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/internal/addrs"
|
"github.com/hashicorp/terraform/internal/addrs"
|
||||||
"github.com/hashicorp/terraform/internal/configs"
|
"github.com/hashicorp/terraform/internal/configs"
|
||||||
"github.com/hashicorp/terraform/internal/dag"
|
"github.com/hashicorp/terraform/internal/dag"
|
||||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||||
"github.com/zclconf/go-cty/cty"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NodeRootVariable represents a root variable input.
|
// NodeRootVariable represents a root variable input.
|
||||||
@ -24,6 +25,10 @@ type NodeRootVariable struct {
|
|||||||
// converted or validated, and can be nil for a variable that isn't
|
// converted or validated, and can be nil for a variable that isn't
|
||||||
// set at all.
|
// set at all.
|
||||||
RawValue *InputValue
|
RawValue *InputValue
|
||||||
|
|
||||||
|
// Planning must be set to true when building a planning graph, and must be
|
||||||
|
// false when building an apply graph.
|
||||||
|
Planning bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -82,6 +87,14 @@ func (n *NodeRootVariable) Execute(ctx EvalContext, op walkOperation) tfdiags.Di
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if n.Planning {
|
||||||
|
if checkState := ctx.Checks(); checkState.ConfigHasChecks(n.Addr.InModule(addrs.RootModule)) {
|
||||||
|
ctx.Checks().ReportCheckableObjects(
|
||||||
|
n.Addr.InModule(addrs.RootModule),
|
||||||
|
addrs.MakeSet[addrs.Checkable](n.Addr.Absolute(addrs.RootModuleInstance)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
finalVal, moreDiags := prepareFinalInputVariableValue(
|
finalVal, moreDiags := prepareFinalInputVariableValue(
|
||||||
addr,
|
addr,
|
||||||
givenVal,
|
givenVal,
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/internal/addrs"
|
"github.com/hashicorp/terraform/internal/addrs"
|
||||||
|
"github.com/hashicorp/terraform/internal/checks"
|
||||||
"github.com/hashicorp/terraform/internal/configs"
|
"github.com/hashicorp/terraform/internal/configs"
|
||||||
"github.com/hashicorp/terraform/internal/lang"
|
"github.com/hashicorp/terraform/internal/lang"
|
||||||
)
|
)
|
||||||
@ -115,8 +116,17 @@ func TestNodeRootVariableExecute(t *testing.T) {
|
|||||||
Value: cty.StringVal("5"),
|
Value: cty.StringVal("5"),
|
||||||
SourceType: ValueFromUnknown,
|
SourceType: ValueFromUnknown,
|
||||||
},
|
},
|
||||||
|
Planning: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.ChecksState = checks.NewState(&configs.Config{
|
||||||
|
Module: &configs.Module{
|
||||||
|
Variables: map[string]*configs.Variable{
|
||||||
|
"foo": n.Config,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
diags := n.Execute(ctx, walkApply)
|
diags := n.Execute(ctx, walkApply)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected error: %s", diags.Err())
|
t.Fatalf("unexpected error: %s", diags.Err())
|
||||||
@ -134,6 +144,9 @@ func TestNodeRootVariableExecute(t *testing.T) {
|
|||||||
// as part of preparing the "final value".
|
// as part of preparing the "final value".
|
||||||
t.Errorf("wrong value for ctx.SetRootModuleArgument\ngot: %#v\nwant: %#v", got, want)
|
t.Errorf("wrong value for ctx.SetRootModuleArgument\ngot: %#v\nwant: %#v", got, want)
|
||||||
}
|
}
|
||||||
|
if status := ctx.Checks().ObjectCheckStatus(n.Addr.Absolute(addrs.RootModuleInstance)); status != checks.StatusPass {
|
||||||
|
t.Errorf("expected checks to pass but go %s instead", status)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,11 +6,13 @@ package terraform
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/internal/addrs"
|
|
||||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/internal/addrs"
|
||||||
|
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/internal/configs"
|
"github.com/hashicorp/terraform/internal/configs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,6 +28,10 @@ import (
|
|||||||
// steps for validating module blocks, separate from this transform.
|
// steps for validating module blocks, separate from this transform.
|
||||||
type ModuleVariableTransformer struct {
|
type ModuleVariableTransformer struct {
|
||||||
Config *configs.Config
|
Config *configs.Config
|
||||||
|
|
||||||
|
// Planning must be set to true when building a planning graph, and must be
|
||||||
|
// false when building an apply graph.
|
||||||
|
Planning bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ModuleVariableTransformer) Transform(g *Graph) error {
|
func (t *ModuleVariableTransformer) Transform(g *Graph) error {
|
||||||
@ -107,6 +113,7 @@ func (t *ModuleVariableTransformer) transformSingle(g *Graph, parent, c *configs
|
|||||||
Module: c.Path,
|
Module: c.Path,
|
||||||
Config: v,
|
Config: v,
|
||||||
Expr: expr,
|
Expr: expr,
|
||||||
|
Planning: t.Planning,
|
||||||
}
|
}
|
||||||
g.Add(node)
|
g.Add(node)
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,10 @@ type RootVariableTransformer struct {
|
|||||||
Config *configs.Config
|
Config *configs.Config
|
||||||
|
|
||||||
RawValues InputValues
|
RawValues InputValues
|
||||||
|
|
||||||
|
// Planning must be set to true when building a planning graph, and must be
|
||||||
|
// false when building an apply graph.
|
||||||
|
Planning bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RootVariableTransformer) Transform(g *Graph) error {
|
func (t *RootVariableTransformer) Transform(g *Graph) error {
|
||||||
@ -38,6 +42,7 @@ func (t *RootVariableTransformer) Transform(g *Graph) error {
|
|||||||
},
|
},
|
||||||
Config: v,
|
Config: v,
|
||||||
RawValue: t.RawValues[v.Name],
|
RawValue: t.RawValues[v.Name],
|
||||||
|
Planning: t.Planning,
|
||||||
}
|
}
|
||||||
g.Add(node)
|
g.Add(node)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user