From 0e4e9f770618ebb8ecf580fd7b796df035b2f4aa Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Wed, 24 Aug 2022 11:29:28 -0700 Subject: [PATCH] addrs: Be explicit about checkable object address kinds Previously we were attempting to infer the checkable object address kind of a given address by whether it included "output" in the position where a resource type name would otherwise go. That was already potentially risky because we've historically not prevented a resource type named "output", and it's also a forward-compatibility hazard in case we introduce additional object kinds with entirely-new addressing schemes in future. Given that, we'll instead always be explicit about what kind of address we're storing in a wire or file format, so that we can make sure to always use the intended parser when reading an address back into memory, or return an error if we encounter a kind we're not familiar with. --- internal/addrs/check.go | 126 +++++--- internal/addrs/checkablekind_string.go | 33 ++ internal/addrs/output_value.go | 8 + internal/addrs/resource.go | 8 + internal/command/jsonchecks/objects.go | 10 + internal/command/jsonplan/checks.go | 1 - .../plans/internal/planproto/planfile.pb.go | 304 +++++++++++------- .../plans/internal/planproto/planfile.proto | 14 +- internal/plans/planfile/tfplan.go | 22 +- internal/states/statefile/version4.go | 37 ++- 10 files changed, 393 insertions(+), 170 deletions(-) create mode 100644 internal/addrs/checkablekind_string.go delete mode 100644 internal/command/jsonplan/checks.go diff --git a/internal/addrs/check.go b/internal/addrs/check.go index 39e124d70e..430b50c990 100644 --- a/internal/addrs/check.go +++ b/internal/addrs/check.go @@ -20,7 +20,8 @@ import ( // // Note also that the check address is only relevant within the scope of a run, // as reordering check blocks between runs will result in their addresses -// changing. +// changing. Check is therefore for internal use only and should not be exposed +// in durable artifacts such as state snapshots. type Check struct { Container Checkable Type CheckType @@ -66,37 +67,14 @@ type checkKey struct { func (k checkKey) uniqueKeySigil() {} -// 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 -} - -var ( - _ Checkable = AbsResourceInstance{} - _ Checkable = AbsOutputValue{} -) - -// CheckType describes the category of check. +// CheckType describes a category of check. We use this only to establish +// uniqueness for Check values, and do not expose this concept of "check types" +// (which is subject to change in future) in any durable artifacts such as +// state snapshots. +// +// (See [CheckableKind] for an enumeration that we _do_ use externally, to +// describe the type of object being checked rather than the type of the check +// itself.) type CheckType int //go:generate go run golang.org/x/tools/cmd/stringer -type=CheckType check.go @@ -124,6 +102,48 @@ func (c CheckType) Description() 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 + + CheckableKind() CheckableKind + String() string +} + +var ( + _ Checkable = AbsResourceInstance{} + _ Checkable = AbsOutputValue{} +) + +// CheckableKind describes the different kinds of checkable objects. +type CheckableKind rune + +//go:generate go run golang.org/x/tools/cmd/stringer -type=CheckableKind check.go + +const ( + CheckableKindInvalid CheckableKind = 0 + CheckableResource CheckableKind = 'R' + CheckableOutputValue CheckableKind = 'O' +) + // ConfigCheckable is an interfaces implemented by address types that represent // configuration constructs that can have Checkable addresses associated with // them. @@ -137,6 +157,7 @@ type ConfigCheckable interface { configCheckableSigil() + CheckableKind() CheckableKind String() string } @@ -145,15 +166,17 @@ var ( _ ConfigCheckable = ConfigOutputValue{} ) -// ParseCheckableStr attempts to parse the given string as a Checkable address. +// ParseCheckableStr attempts to parse the given string as a Checkable address +// of the given kind. // // This should be the opposite of Checkable.String for any Checkable address -// type. +// type, as long as "kind" is set to the value returned by the address's +// CheckableKind method. // // We do not typically expect users to write out checkable addresses as input, // but we use them as part of some of our wire formats for persisting check // results between runs. -func ParseCheckableStr(src string) (Checkable, tfdiags.Diagnostics) { +func ParseCheckableStr(kind CheckableKind, src string) (Checkable, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics traversal, parseDiags := hclsyntax.ParseTraversalAbs([]byte(src), "", hcl.InitialPos) @@ -178,8 +201,20 @@ func ParseCheckableStr(src string) (Checkable, tfdiags.Diagnostics) { return nil, diags } - switch remain.RootName() { - case "output": + // We use "kind" to disambiguate here because unfortunately we've + // historically never reserved "output" as a possible resource type name + // and so it is in principle possible -- albeit unlikely -- that there + // might be a resource whose type is literally "output". + switch kind { + case CheckableResource: + riAddr, moreDiags := parseResourceInstanceUnderModule(path, remain) + diags = diags.Append(moreDiags) + if diags.HasErrors() { + return nil, diags + } + return riAddr, diags + + case CheckableOutputValue: if len(remain) != 2 { diags = diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, @@ -189,6 +224,15 @@ func ParseCheckableStr(src string) (Checkable, tfdiags.Diagnostics) { }) return nil, diags } + if remain.RootName() != "output" { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid checkable address", + Detail: "Output address must follow the module address with the keyword 'output'.", + Subject: remain.SourceRange().Ptr(), + }) + return nil, diags + } if step, ok := remain[1].(hcl.TraverseAttr); !ok { diags = diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, @@ -200,12 +244,8 @@ func ParseCheckableStr(src string) (Checkable, tfdiags.Diagnostics) { } else { return OutputValue{Name: step.Name}.Absolute(path), diags } + default: - riAddr, moreDiags := parseResourceInstanceUnderModule(path, remain) - diags = diags.Append(moreDiags) - if diags.HasErrors() { - return nil, diags - } - return riAddr, diags + panic(fmt.Sprintf("unsupported CheckableKind %s", kind)) } } diff --git a/internal/addrs/checkablekind_string.go b/internal/addrs/checkablekind_string.go new file mode 100644 index 0000000000..8987cd02bf --- /dev/null +++ b/internal/addrs/checkablekind_string.go @@ -0,0 +1,33 @@ +// Code generated by "stringer -type=CheckableKind check.go"; DO NOT EDIT. + +package addrs + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[CheckableKindInvalid-0] + _ = x[CheckableResource-82] + _ = x[CheckableOutputValue-79] +} + +const ( + _CheckableKind_name_0 = "CheckableKindInvalid" + _CheckableKind_name_1 = "CheckableOutputValue" + _CheckableKind_name_2 = "CheckableResource" +) + +func (i CheckableKind) String() string { + switch { + case i == 0: + return _CheckableKind_name_0 + case i == 79: + return _CheckableKind_name_1 + case i == 82: + return _CheckableKind_name_2 + default: + return "CheckableKind(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/internal/addrs/output_value.go b/internal/addrs/output_value.go index 9fc016cb30..ff76556b2a 100644 --- a/internal/addrs/output_value.go +++ b/internal/addrs/output_value.go @@ -98,6 +98,10 @@ func (v AbsOutputValue) ConfigCheckable() ConfigCheckable { return v.ConfigOutputValue() } +func (v AbsOutputValue) CheckableKind() CheckableKind { + return CheckableOutputValue +} + func (v AbsOutputValue) UniqueKey() UniqueKey { return absOutputValueUniqueKey(v.String()) } @@ -206,6 +210,10 @@ func (v ConfigOutputValue) configCheckableSigil() { // ConfigOutputValue is the ConfigCheckable for AbsOutputValue. } +func (v ConfigOutputValue) CheckableKind() CheckableKind { + return CheckableOutputValue +} + func (v ConfigOutputValue) UniqueKey() UniqueKey { return configOutputValueUniqueKey(v.String()) } diff --git a/internal/addrs/resource.go b/internal/addrs/resource.go index 12bdcf1132..f400bcb421 100644 --- a/internal/addrs/resource.go +++ b/internal/addrs/resource.go @@ -297,6 +297,10 @@ func (r AbsResourceInstance) Check(t CheckType, i int) Check { } } +func (v AbsResourceInstance) CheckableKind() CheckableKind { + return CheckableResource +} + func (r AbsResourceInstance) Equal(o AbsResourceInstance) bool { return r.Module.Equal(o.Module) && r.Resource.Equal(o.Resource) } @@ -421,6 +425,10 @@ func (r ConfigResource) configCheckableSigil() { // ConfigResource represents a configuration object that declares checkable objects } +func (v ConfigResource) CheckableKind() CheckableKind { + return CheckableResource +} + type configResourceKey string func (k configResourceKey) uniqueKeySigil() {} diff --git a/internal/command/jsonchecks/objects.go b/internal/command/jsonchecks/objects.go index 472ef6922b..d7a5014fee 100644 --- a/internal/command/jsonchecks/objects.go +++ b/internal/command/jsonchecks/objects.go @@ -15,6 +15,11 @@ func makeStaticObjectAddr(addr addrs.ConfigCheckable) staticObjectAddr { switch addr := addr.(type) { case addrs.ConfigResource: + if kind := addr.CheckableKind(); kind != addrs.CheckableResource { + // Something has gone very wrong + panic(fmt.Sprintf("%T has CheckableKind %s", addr, kind)) + } + ret["kind"] = "resource" switch addr.Resource.Mode { case addrs.ManagedResourceMode: @@ -30,6 +35,11 @@ func makeStaticObjectAddr(addr addrs.ConfigCheckable) staticObjectAddr { ret["module"] = addr.Module.String() } case addrs.ConfigOutputValue: + if kind := addr.CheckableKind(); kind != addrs.CheckableOutputValue { + // Something has gone very wrong + panic(fmt.Sprintf("%T has CheckableKind %s", addr, kind)) + } + ret["kind"] = "output_value" ret["name"] = addr.OutputValue.Name if !addr.Module.IsRoot() { diff --git a/internal/command/jsonplan/checks.go b/internal/command/jsonplan/checks.go deleted file mode 100644 index 30cd8b3576..0000000000 --- a/internal/command/jsonplan/checks.go +++ /dev/null @@ -1 +0,0 @@ -package jsonplan diff --git a/internal/plans/internal/planproto/planfile.pb.go b/internal/plans/internal/planproto/planfile.pb.go index 951a730f01..8e09fee33c 100644 --- a/internal/plans/internal/planproto/planfile.pb.go +++ b/internal/plans/internal/planproto/planfile.pb.go @@ -267,6 +267,55 @@ func (CheckResults_Status) EnumDescriptor() ([]byte, []int) { return file_planfile_proto_rawDescGZIP(), []int{5, 0} } +type CheckResults_ObjectKind int32 + +const ( + CheckResults_UNSPECIFIED CheckResults_ObjectKind = 0 + CheckResults_RESOURCE CheckResults_ObjectKind = 1 + CheckResults_OUTPUT_VALUE CheckResults_ObjectKind = 2 +) + +// Enum value maps for CheckResults_ObjectKind. +var ( + CheckResults_ObjectKind_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "RESOURCE", + 2: "OUTPUT_VALUE", + } + CheckResults_ObjectKind_value = map[string]int32{ + "UNSPECIFIED": 0, + "RESOURCE": 1, + "OUTPUT_VALUE": 2, + } +) + +func (x CheckResults_ObjectKind) Enum() *CheckResults_ObjectKind { + p := new(CheckResults_ObjectKind) + *p = x + return p +} + +func (x CheckResults_ObjectKind) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CheckResults_ObjectKind) Descriptor() protoreflect.EnumDescriptor { + return file_planfile_proto_enumTypes[4].Descriptor() +} + +func (CheckResults_ObjectKind) Type() protoreflect.EnumType { + return &file_planfile_proto_enumTypes[4] +} + +func (x CheckResults_ObjectKind) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CheckResults_ObjectKind.Descriptor instead. +func (CheckResults_ObjectKind) EnumDescriptor() ([]byte, []int) { + return file_planfile_proto_rawDescGZIP(), []int{5, 1} +} + // Plan is the root message type for the tfplan file type Plan struct { state protoimpl.MessageState @@ -802,14 +851,15 @@ type CheckResults struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + Kind CheckResults_ObjectKind `protobuf:"varint,1,opt,name=kind,proto3,enum=tfplan.CheckResults_ObjectKind" json:"kind,omitempty"` // Address of the configuration object that declared the checks. - ConfigAddr string `protobuf:"bytes,1,opt,name=config_addr,json=configAddr,proto3" json:"config_addr,omitempty"` + ConfigAddr string `protobuf:"bytes,2,opt,name=config_addr,json=configAddr,proto3" json:"config_addr,omitempty"` // The aggregate status of the entire configuration object, based on // the statuses of its zero or more checkable objects. - Status CheckResults_Status `protobuf:"varint,2,opt,name=status,proto3,enum=tfplan.CheckResults_Status" json:"status,omitempty"` + Status CheckResults_Status `protobuf:"varint,3,opt,name=status,proto3,enum=tfplan.CheckResults_Status" json:"status,omitempty"` // The results for individual objects that were declared by the // configuration object named in config_addr. - Objects []*CheckResults_ObjectResult `protobuf:"bytes,3,rep,name=objects,proto3" json:"objects,omitempty"` + Objects []*CheckResults_ObjectResult `protobuf:"bytes,4,rep,name=objects,proto3" json:"objects,omitempty"` } func (x *CheckResults) Reset() { @@ -844,6 +894,13 @@ func (*CheckResults) Descriptor() ([]byte, []int) { return file_planfile_proto_rawDescGZIP(), []int{5} } +func (x *CheckResults) GetKind() CheckResults_ObjectKind { + if x != nil { + return x.Kind + } + return CheckResults_UNSPECIFIED +} + func (x *CheckResults) GetConfigAddr() string { if x != nil { return x.ConfigAddr @@ -1281,82 +1338,89 @@ var file_planfile_proto_rawDesc = []byte{ 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, 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, 0xe9, 0x02, 0x0a, 0x0c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, - 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x41, 0x64, 0x64, 0x72, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3b, 0x0a, 0x07, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, - 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, - 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x1a, 0x8f, 0x01, 0x0a, 0x0c, 0x4f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x74, 0x66, 0x70, - 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x29, 0x0a, 0x10, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x66, 0x61, 0x69, 0x6c, 0x75, - 0x72, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 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, 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, 0x28, 0x0a, 0x0c, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x73, 0x67, 0x70, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x6d, 0x73, 0x67, 0x70, 0x61, 0x63, 0x6b, 0x22, 0xa5, 0x01, 0x0a, 0x04, 0x50, - 0x61, 0x74, 0x68, 0x12, 0x27, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50, 0x61, 0x74, 0x68, - 0x2e, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x1a, 0x74, 0x0a, 0x04, - 0x53, 0x74, 0x65, 0x70, 0x12, 0x27, 0x0a, 0x0e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, - 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x44, 0x79, 0x6e, 0x61, - 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x65, 0x6c, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x2a, 0x31, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, - 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, - 0x59, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x45, 0x46, 0x52, 0x45, 0x53, 0x48, 0x5f, 0x4f, - 0x4e, 0x4c, 0x59, 0x10, 0x02, 0x2a, 0x70, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4f, 0x50, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x45, - 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x45, 0x41, 0x44, 0x10, 0x02, 0x12, - 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x44, - 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x45, 0x4c, 0x45, 0x54, - 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x06, 0x12, - 0x16, 0x0a, 0x12, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f, 0x44, - 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x07, 0x2a, 0x86, 0x03, 0x0a, 0x1c, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, - 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x45, - 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, - 0x16, 0x0a, 0x12, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x59, 0x5f, 0x52, 0x45, - 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, 0x50, 0x4c, 0x41, - 0x43, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x41, 0x4e, 0x4e, 0x4f, - 0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x45, - 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e, 0x4f, 0x5f, - 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, - 0x04, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, - 0x55, 0x53, 0x45, 0x5f, 0x57, 0x52, 0x4f, 0x4e, 0x47, 0x5f, 0x52, 0x45, 0x50, 0x45, 0x54, 0x49, - 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, - 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x49, - 0x4e, 0x44, 0x45, 0x58, 0x10, 0x06, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, - 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x45, 0x41, 0x43, 0x48, 0x5f, 0x4b, 0x45, - 0x59, 0x10, 0x07, 0x12, 0x1c, 0x0a, 0x18, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, - 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, - 0x08, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x59, 0x5f, - 0x54, 0x52, 0x49, 0x47, 0x47, 0x45, 0x52, 0x53, 0x10, 0x09, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x45, - 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, - 0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x0a, 0x12, 0x23, 0x0a, 0x1f, 0x52, - 0x45, 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x44, 0x45, 0x50, 0x45, - 0x4e, 0x44, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x0b, - 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, - 0x72, 0x6d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 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, + 0x74, 0x69, 0x76, 0x65, 0x22, 0xdd, 0x03, 0x0a, 0x0c, 0x43, 0x68, 0x65, 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, 0x2e, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x72, 0x12, 0x33, 0x0a, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x1a, 0x8f, 0x01, + 0x0a, 0x0c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, + 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x12, + 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x1b, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, + 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 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, 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, 0x3d, 0x0a, 0x0a, 0x4f, 0x62, 0x6a, 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, 0x55, 0x52, 0x43, 0x45, + 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, 0x56, 0x41, 0x4c, + 0x55, 0x45, 0x10, 0x02, 0x22, 0x28, 0x0a, 0x0c, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x73, 0x67, 0x70, 0x61, 0x63, 0x6b, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x73, 0x67, 0x70, 0x61, 0x63, 0x6b, 0x22, 0xa5, + 0x01, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x27, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, + 0x50, 0x61, 0x74, 0x68, 0x2e, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, + 0x1a, 0x74, 0x0a, 0x04, 0x53, 0x74, 0x65, 0x70, 0x12, 0x27, 0x0a, 0x0e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, + 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x0a, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2a, 0x31, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0a, + 0x0a, 0x06, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, + 0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x45, 0x46, 0x52, 0x45, + 0x53, 0x48, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, 0x2a, 0x70, 0x0a, 0x06, 0x41, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4f, 0x50, 0x10, 0x00, 0x12, 0x0a, 0x0a, + 0x06, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x45, 0x41, + 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x12, + 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x44, + 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, + 0x45, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x48, + 0x45, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x07, 0x2a, 0x86, 0x03, 0x0a, 0x1c, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, + 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, + 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x45, + 0x44, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, + 0x59, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x52, + 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, + 0x41, 0x4e, 0x4e, 0x4f, 0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x12, 0x25, + 0x0a, 0x21, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, + 0x5f, 0x4e, 0x4f, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x4e, + 0x46, 0x49, 0x47, 0x10, 0x04, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, + 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x57, 0x52, 0x4f, 0x4e, 0x47, 0x5f, 0x52, 0x45, + 0x50, 0x45, 0x54, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x44, 0x45, + 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x10, 0x06, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x45, + 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x45, 0x41, 0x43, + 0x48, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x07, 0x12, 0x1c, 0x0a, 0x18, 0x44, 0x45, 0x4c, 0x45, 0x54, + 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x4f, 0x44, + 0x55, 0x4c, 0x45, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, + 0x5f, 0x42, 0x59, 0x5f, 0x54, 0x52, 0x49, 0x47, 0x47, 0x45, 0x52, 0x53, 0x10, 0x09, 0x12, 0x1f, + 0x0a, 0x1b, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, + 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x0a, 0x12, + 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, + 0x44, 0x45, 0x50, 0x45, 0x4e, 0x44, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, + 0x4e, 0x47, 0x10, 0x0b, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x74, 0x65, 0x72, + 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 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 ( @@ -1371,56 +1435,58 @@ func file_planfile_proto_rawDescGZIP() []byte { return file_planfile_proto_rawDescData } -var file_planfile_proto_enumTypes = make([]protoimpl.EnumInfo, 4) +var file_planfile_proto_enumTypes = make([]protoimpl.EnumInfo, 5) var file_planfile_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_planfile_proto_goTypes = []interface{}{ (Mode)(0), // 0: tfplan.Mode (Action)(0), // 1: tfplan.Action (ResourceInstanceActionReason)(0), // 2: tfplan.ResourceInstanceActionReason (CheckResults_Status)(0), // 3: tfplan.CheckResults.Status - (*Plan)(nil), // 4: tfplan.Plan - (*Backend)(nil), // 5: tfplan.Backend - (*Change)(nil), // 6: tfplan.Change - (*ResourceInstanceChange)(nil), // 7: tfplan.ResourceInstanceChange - (*OutputChange)(nil), // 8: tfplan.OutputChange - (*CheckResults)(nil), // 9: tfplan.CheckResults - (*DynamicValue)(nil), // 10: tfplan.DynamicValue - (*Path)(nil), // 11: tfplan.Path - nil, // 12: tfplan.Plan.VariablesEntry - (*PlanResourceAttr)(nil), // 13: tfplan.Plan.resource_attr - (*CheckResults_ObjectResult)(nil), // 14: tfplan.CheckResults.ObjectResult - (*Path_Step)(nil), // 15: tfplan.Path.Step + (CheckResults_ObjectKind)(0), // 4: tfplan.CheckResults.ObjectKind + (*Plan)(nil), // 5: tfplan.Plan + (*Backend)(nil), // 6: tfplan.Backend + (*Change)(nil), // 7: tfplan.Change + (*ResourceInstanceChange)(nil), // 8: tfplan.ResourceInstanceChange + (*OutputChange)(nil), // 9: tfplan.OutputChange + (*CheckResults)(nil), // 10: tfplan.CheckResults + (*DynamicValue)(nil), // 11: tfplan.DynamicValue + (*Path)(nil), // 12: tfplan.Path + nil, // 13: tfplan.Plan.VariablesEntry + (*PlanResourceAttr)(nil), // 14: tfplan.Plan.resource_attr + (*CheckResults_ObjectResult)(nil), // 15: tfplan.CheckResults.ObjectResult + (*Path_Step)(nil), // 16: tfplan.Path.Step } var file_planfile_proto_depIdxs = []int32{ 0, // 0: tfplan.Plan.ui_mode:type_name -> tfplan.Mode - 12, // 1: tfplan.Plan.variables:type_name -> tfplan.Plan.VariablesEntry - 7, // 2: tfplan.Plan.resource_changes:type_name -> tfplan.ResourceInstanceChange - 7, // 3: tfplan.Plan.resource_drift:type_name -> tfplan.ResourceInstanceChange - 8, // 4: tfplan.Plan.output_changes:type_name -> tfplan.OutputChange - 9, // 5: tfplan.Plan.check_results:type_name -> tfplan.CheckResults - 5, // 6: tfplan.Plan.backend:type_name -> tfplan.Backend - 13, // 7: tfplan.Plan.relevant_attributes:type_name -> tfplan.Plan.resource_attr - 10, // 8: tfplan.Backend.config:type_name -> tfplan.DynamicValue + 13, // 1: tfplan.Plan.variables:type_name -> tfplan.Plan.VariablesEntry + 8, // 2: tfplan.Plan.resource_changes:type_name -> tfplan.ResourceInstanceChange + 8, // 3: tfplan.Plan.resource_drift:type_name -> tfplan.ResourceInstanceChange + 9, // 4: tfplan.Plan.output_changes:type_name -> tfplan.OutputChange + 10, // 5: tfplan.Plan.check_results:type_name -> tfplan.CheckResults + 6, // 6: tfplan.Plan.backend:type_name -> tfplan.Backend + 14, // 7: tfplan.Plan.relevant_attributes:type_name -> tfplan.Plan.resource_attr + 11, // 8: tfplan.Backend.config:type_name -> tfplan.DynamicValue 1, // 9: tfplan.Change.action:type_name -> tfplan.Action - 10, // 10: tfplan.Change.values:type_name -> tfplan.DynamicValue - 11, // 11: tfplan.Change.before_sensitive_paths:type_name -> tfplan.Path - 11, // 12: tfplan.Change.after_sensitive_paths:type_name -> tfplan.Path - 6, // 13: tfplan.ResourceInstanceChange.change:type_name -> tfplan.Change - 11, // 14: tfplan.ResourceInstanceChange.required_replace:type_name -> tfplan.Path + 11, // 10: tfplan.Change.values:type_name -> tfplan.DynamicValue + 12, // 11: tfplan.Change.before_sensitive_paths:type_name -> tfplan.Path + 12, // 12: tfplan.Change.after_sensitive_paths:type_name -> tfplan.Path + 7, // 13: tfplan.ResourceInstanceChange.change:type_name -> tfplan.Change + 12, // 14: tfplan.ResourceInstanceChange.required_replace:type_name -> tfplan.Path 2, // 15: tfplan.ResourceInstanceChange.action_reason:type_name -> tfplan.ResourceInstanceActionReason - 6, // 16: tfplan.OutputChange.change:type_name -> tfplan.Change - 3, // 17: tfplan.CheckResults.status:type_name -> tfplan.CheckResults.Status - 14, // 18: tfplan.CheckResults.objects:type_name -> tfplan.CheckResults.ObjectResult - 15, // 19: tfplan.Path.steps:type_name -> tfplan.Path.Step - 10, // 20: tfplan.Plan.VariablesEntry.value:type_name -> tfplan.DynamicValue - 11, // 21: tfplan.Plan.resource_attr.attr:type_name -> tfplan.Path - 3, // 22: tfplan.CheckResults.ObjectResult.status:type_name -> tfplan.CheckResults.Status - 10, // 23: tfplan.Path.Step.element_key:type_name -> tfplan.DynamicValue - 24, // [24:24] is the sub-list for method output_type - 24, // [24:24] is the sub-list for method input_type - 24, // [24:24] is the sub-list for extension type_name - 24, // [24:24] is the sub-list for extension extendee - 0, // [0:24] is the sub-list for field type_name + 7, // 16: tfplan.OutputChange.change:type_name -> tfplan.Change + 4, // 17: tfplan.CheckResults.kind:type_name -> tfplan.CheckResults.ObjectKind + 3, // 18: tfplan.CheckResults.status:type_name -> tfplan.CheckResults.Status + 15, // 19: tfplan.CheckResults.objects:type_name -> tfplan.CheckResults.ObjectResult + 16, // 20: tfplan.Path.steps:type_name -> tfplan.Path.Step + 11, // 21: tfplan.Plan.VariablesEntry.value:type_name -> tfplan.DynamicValue + 12, // 22: tfplan.Plan.resource_attr.attr:type_name -> tfplan.Path + 3, // 23: tfplan.CheckResults.ObjectResult.status:type_name -> tfplan.CheckResults.Status + 11, // 24: tfplan.Path.Step.element_key:type_name -> tfplan.DynamicValue + 25, // [25:25] is the sub-list for method output_type + 25, // [25:25] is the sub-list for method input_type + 25, // [25:25] is the sub-list for extension type_name + 25, // [25:25] is the sub-list for extension extendee + 0, // [0:25] is the sub-list for field type_name } func init() { file_planfile_proto_init() } @@ -1571,7 +1637,7 @@ func file_planfile_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_planfile_proto_rawDesc, - NumEnums: 4, + NumEnums: 5, NumMessages: 12, NumExtensions: 0, NumServices: 0, diff --git a/internal/plans/internal/planproto/planfile.proto b/internal/plans/internal/planproto/planfile.proto index 8c8912afa1..2941b1dc34 100644 --- a/internal/plans/internal/planproto/planfile.proto +++ b/internal/plans/internal/planproto/planfile.proto @@ -227,22 +227,30 @@ message CheckResults { ERROR = 3; } + enum ObjectKind { + UNSPECIFIED = 0; + RESOURCE = 1; + OUTPUT_VALUE = 2; + } + message ObjectResult { string object_addr = 1; Status status = 2; repeated string failure_messages = 3; } + ObjectKind kind = 1; + // Address of the configuration object that declared the checks. - string config_addr = 1; + string config_addr = 2; // The aggregate status of the entire configuration object, based on // the statuses of its zero or more checkable objects. - Status status = 2; + Status status = 3; // The results for individual objects that were declared by the // configuration object named in config_addr. - repeated ObjectResult objects = 3; + repeated ObjectResult objects = 4; } // DynamicValue represents a value whose type is not decided until runtime, diff --git a/internal/plans/planfile/tfplan.go b/internal/plans/planfile/tfplan.go index 863f5220ea..a840c378ef 100644 --- a/internal/plans/planfile/tfplan.go +++ b/internal/plans/planfile/tfplan.go @@ -106,13 +106,23 @@ func readTfplan(r io.Reader) (*plans.Plan, error) { return nil, fmt.Errorf("aggregate check results for %s have unsupported status %#v", rawCRs.ConfigAddr, rawCRs.Status) } + var objKind addrs.CheckableKind + switch rawCRs.Kind { + case planproto.CheckResults_RESOURCE: + objKind = addrs.CheckableResource + case planproto.CheckResults_OUTPUT_VALUE: + objKind = addrs.CheckableOutputValue + default: + return nil, fmt.Errorf("aggregate check results for %s have unsupported object kind %s", rawCRs.ConfigAddr, objKind) + } + // Some trickiness here: we only have an address parser for // addrs.Checkable and not for addrs.ConfigCheckable, but that's okay // because once we have an addrs.Checkable we can always derive an // addrs.ConfigCheckable from it, and a ConfigCheckable should always // be the same syntax as a Checkable with no index information and // thus we can reuse the same parser for both here. - configAddrProxy, diags := addrs.ParseCheckableStr(rawCRs.ConfigAddr) + configAddrProxy, diags := addrs.ParseCheckableStr(objKind, rawCRs.ConfigAddr) if diags.HasErrors() { return nil, diags.Err() } @@ -126,7 +136,7 @@ func readTfplan(r io.Reader) (*plans.Plan, error) { aggr.ObjectResults = addrs.MakeMap[addrs.Checkable, *states.CheckResultObject]() for _, rawCR := range rawCRs.Objects { - objectAddr, diags := addrs.ParseCheckableStr(rawCR.ObjectAddr) + objectAddr, diags := addrs.ParseCheckableStr(objKind, rawCR.ObjectAddr) if diags.HasErrors() { return nil, diags.Err() } @@ -503,6 +513,14 @@ func writeTfplan(plan *plans.Plan, w io.Writer) error { default: return fmt.Errorf("checkable configuration %s has unsupported aggregate status %s", configElem.Key, crs.Status) } + switch kind := configElem.Key.CheckableKind(); kind { + case addrs.CheckableResource: + pcrs.Kind = planproto.CheckResults_RESOURCE + case addrs.CheckableOutputValue: + pcrs.Kind = planproto.CheckResults_OUTPUT_VALUE + default: + return fmt.Errorf("checkable configuration %s has unsupported object type kind %s", configElem.Key, kind) + } for _, objectElem := range configElem.Value.ObjectResults.Elems { cr := objectElem.Value diff --git a/internal/states/statefile/version4.go b/internal/states/statefile/version4.go index 0725b264a3..cb3dd694dd 100644 --- a/internal/states/statefile/version4.go +++ b/internal/states/statefile/version4.go @@ -522,13 +522,19 @@ func decodeCheckResultsV4(in []checkResultsV4) (*states.CheckResults, tfdiags.Di ret.ConfigResults = addrs.MakeMap[addrs.ConfigCheckable, *states.CheckResultAggregate]() for _, aggrIn := range in { + objectKind := decodeCheckableObjectKindV4(aggrIn.ObjectKind) + if objectKind == addrs.CheckableKindInvalid { + diags = diags.Append(fmt.Errorf("unsupported checkable object kind %q", aggrIn.ObjectKind)) + continue + } + // Some trickiness here: we only have an address parser for // addrs.Checkable and not for addrs.ConfigCheckable, but that's okay // because once we have an addrs.Checkable we can always derive an // addrs.ConfigCheckable from it, and a ConfigCheckable should always // be the same syntax as a Checkable with no index information and // thus we can reuse the same parser for both here. - configAddrProxy, moreDiags := addrs.ParseCheckableStr(aggrIn.ConfigAddr) + configAddrProxy, moreDiags := addrs.ParseCheckableStr(objectKind, aggrIn.ConfigAddr) diags = diags.Append(moreDiags) if moreDiags.HasErrors() { continue @@ -549,7 +555,7 @@ func decodeCheckResultsV4(in []checkResultsV4) (*states.CheckResults, tfdiags.Di if len(aggrIn.Objects) != 0 { aggr.ObjectResults = addrs.MakeMap[addrs.Checkable, *states.CheckResultObject]() for _, objectIn := range aggrIn.Objects { - objectAddr, moreDiags := addrs.ParseCheckableStr(objectIn.ObjectAddr) + objectAddr, moreDiags := addrs.ParseCheckableStr(objectKind, objectIn.ObjectAddr) diags = diags.Append(moreDiags) if moreDiags.HasErrors() { continue @@ -574,6 +580,7 @@ func encodeCheckResultsV4(in *states.CheckResults) []checkResultsV4 { for _, configElem := range in.ConfigResults.Elems { configResultsOut := checkResultsV4{ + ObjectKind: encodeCheckableObjectKindV4(configElem.Key.CheckableKind()), ConfigAddr: configElem.Key.String(), Status: encodeCheckStatusV4(configElem.Value.Status), } @@ -622,6 +629,31 @@ func encodeCheckStatusV4(in checks.Status) string { } } +func decodeCheckableObjectKindV4(in string) addrs.CheckableKind { + switch in { + case "resource": + return addrs.CheckableResource + case "output": + return addrs.CheckableOutputValue + default: + // We'll treat anything else as invalid just as a concession to + // forward-compatible parsing, in case a later version of Terraform + // introduces a new status. + return addrs.CheckableKindInvalid + } +} + +func encodeCheckableObjectKindV4(in addrs.CheckableKind) string { + switch in { + case addrs.CheckableResource: + return "resource" + case addrs.CheckableOutputValue: + return "output" + default: + panic(fmt.Sprintf("unsupported checkable object kind %s", in)) + } +} + type stateV4 struct { Version stateVersionV4 `json:"version"` TerraformVersion string `json:"terraform_version"` @@ -676,6 +708,7 @@ type instanceObjectStateV4 struct { } type checkResultsV4 struct { + ObjectKind string `json:"object_kind"` ConfigAddr string `json:"config_addr"` Status string `json:"status"` Objects []checkResultsObjectV4 `json:"objects"`