display lifecycle triggered actions aside their triggering resources

pull/37389/head
Daniel Schmidt 9 months ago
parent 7d8b79a596
commit eb26b72d55

@ -4,6 +4,9 @@
package jsonformat
import (
"fmt"
"slices"
"github.com/hashicorp/terraform/internal/command/jsonformat/computed"
"github.com/hashicorp/terraform/internal/command/jsonformat/differ"
"github.com/hashicorp/terraform/internal/command/jsonformat/structured"
@ -56,9 +59,34 @@ func precomputeDiffs(plan Plan, mode plans.Mode) diffs {
for _, change := range plan.ResourceChanges {
schema := plan.getSchema(change)
structuredChange := structured.FromJsonChange(change.Change, attribute_path.AlwaysMatcher())
beforeActionsTriggered := []jsonplan.ActionInvocation{}
afterActionsTriggered := []jsonplan.ActionInvocation{}
for _, action := range plan.ActionInvocations {
if action.TriggeringResourceAddress != change.Address {
continue
}
switch action.TriggerEvent {
case "BeforeCreate", "BeforeUpdate", "BeforeDestroy":
beforeActionsTriggered = append(beforeActionsTriggered, action)
case "AfterCreate", "AfterUpdate", "AfterDestroy":
afterActionsTriggered = append(afterActionsTriggered, action)
default:
// The switch should be exhaustive.
panic(fmt.Sprintf("Unexpected triggering event when rendering action %s", action.TriggerEvent))
}
}
slices.SortFunc(beforeActionsTriggered, jsonplan.ActionInvocationCompare)
slices.SortFunc(afterActionsTriggered, jsonplan.ActionInvocationCompare)
diffs.changes = append(diffs.changes, diff{
change: change,
diff: differ.ComputeDiffForBlock(structuredChange, schema.Block),
change: change,
diff: differ.ComputeDiffForBlock(structuredChange, schema.Block),
beforeActionsTriggered: beforeActionsTriggered,
afterActionsTriggered: afterActionsTriggered,
})
}
@ -106,8 +134,10 @@ func (d diffs) Empty() bool {
}
type diff struct {
change jsonplan.ResourceChange
diff computed.Diff
change jsonplan.ResourceChange
diff computed.Diff
beforeActionsTriggered []jsonplan.ActionInvocation
afterActionsTriggered []jsonplan.ActionInvocation
}
func (d diff) Moved() bool {

@ -393,6 +393,31 @@ func renderHumanDiff(renderer Renderer, diff diff, cause string) (string, bool)
opts.ShowUnchangedChildren = diff.Importing()
buf.WriteString(fmt.Sprintf("%s %s %s", renderer.Colorize.Color(format.DiffActionSymbol(action)), resourceChangeHeader(diff.change), diff.diff.RenderHuman(0, opts)))
if len(diff.beforeActionsTriggered) > 0 {
buf.WriteString(renderer.Colorize.Color("\n\n [bold]# Actions to be invoked before this change in order:[reset]\n"))
for _, ai := range diff.beforeActionsTriggered {
buf.WriteString(fmt.Sprintf(" # - %s\n", ai.Address))
}
}
if len(diff.afterActionsTriggered) > 0 {
buf.WriteString(renderer.Colorize.Color("\n\n [bold]# Actions to be invoked after this change in order:[reset]\n"))
for _, ai := range diff.afterActionsTriggered {
// TODO: Save the type and name in jsonplan.ActionInvocation for easy access
buf.WriteString(fmt.Sprintf(" %s {\n", ai.Address))
if len(ai.ConfigValues) > 0 {
buf.WriteString(" config {\n")
for key, value := range ai.ConfigValues {
// TODO: How do I properly render this?
buf.WriteString(fmt.Sprintf(" %s = %s\n", renderers.EnsureValidAttributeName(key), value))
}
buf.WriteString(" }")
}
buf.WriteString(" }\n")
}
}
return buf.String(), true
}
@ -438,16 +463,10 @@ func renderHumanDeferredDiff(renderer Renderer, deferred deferredDiff) (string,
return buf.String(), true
}
// All actions that run based on the resource lifecycle should be rendered as part of the resource
// changes, therefore this function only renders actions that are invoked by the CLI
func renderHumanActionInvocations(renderer Renderer, actionInvocations []jsonplan.ActionInvocation) string {
var buf bytes.Buffer
for _, action := range actionInvocations {
buf.WriteString(renderer.Colorize.Color(fmt.Sprintf(
"[bold] # Triggered by %s[reset]\n",
action.TriggeringResourceAddress,
)))
buf.WriteString(fmt.Sprintf(" %s\n", action.Address))
}
return buf.String()
return "" // TODO: We will use this function once we support CLI invoked actions.
}
func resourceChangeComment(resource jsonplan.ResourceChange, action plans.Action, changeCause string) string {

@ -4,12 +4,23 @@
package jsonplan
import (
"fmt"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/terraform"
"github.com/zclconf/go-cty/cty"
)
type ActionInvocation struct {
// Address is the absolute action address
Address string `json:"address,omitempty"`
// Type is the type of the action
Type string `json:"type,omitempty"`
// Name is the name of the action
Name string `json:"name,omitempty"`
// ConfigValues is the JSON representation of the values in the config block of the action
ConfigValues attributeValues `json:"config_values,omitempty"`
// ProviderName allows the property "type" to be interpreted unambiguously
// in the unusual situation where a provider offers a type whose
@ -30,13 +41,55 @@ type ActionInvocation struct {
TriggerEvent string `json:"trigger_event,omitempty"`
}
func MarshalActionInvocations(actions []*plans.ActionInvocationInstanceSrc) ([]ActionInvocation, error) {
func ActionInvocationCompare(a, b ActionInvocation) int {
if a.TriggeringResourceAddress < b.TriggeringResourceAddress {
return -1
} else if a.TriggeringResourceAddress > b.TriggeringResourceAddress {
return 1
}
if a.ActionTriggerBlockIndex != nil && b.ActionTriggerBlockIndex != nil {
if *a.ActionTriggerBlockIndex < *b.ActionTriggerBlockIndex {
return -1
} else if *a.ActionTriggerBlockIndex > *b.ActionTriggerBlockIndex {
return 1
}
}
if a.ActionsListIndex != nil && b.ActionsListIndex != nil {
if *a.ActionsListIndex < *b.ActionsListIndex {
return -1
} else if *a.ActionsListIndex > *b.ActionsListIndex {
return 1
}
}
return 0
}
func MarshalActionInvocations(actions []*plans.ActionInvocationInstanceSrc, schemas *terraform.Schemas) ([]ActionInvocation, error) {
ret := make([]ActionInvocation, 0, len(actions))
for _, action := range actions {
schema := schemas.ActionTypeConfig(
action.ProviderAddr.Provider,
action.Addr.Action.Action.Type,
)
if schema.ConfigSchema == nil {
return ret, fmt.Errorf("no schema found for %s (in provider %s)", action.Addr.Action.Action.Type, action.ProviderAddr.Provider)
}
actionDec, err := action.Decode(&schema)
if err != nil {
return ret, fmt.Errorf("failed to decode action %s: %w", action.Addr, err)
}
ai := ActionInvocation{
Address: action.Addr.String(),
Type: action.Addr.Action.Action.Type,
Name: action.Addr.Action.Action.Name,
ProviderName: action.ProviderAddr.String(),
// These fields are only used for non-CLI actions. We will need to find another format
@ -47,6 +100,14 @@ func MarshalActionInvocations(actions []*plans.ActionInvocationInstanceSrc) ([]A
TriggerEvent: action.TriggerEvent.String(),
}
if actionDec.ConfigValue != cty.NilVal {
if actionDec.ConfigValue.IsWhollyKnown() {
ai.ConfigValues = marshalAttributeValues(actionDec.ConfigValue)
} else {
knowns := omitUnknowns(actionDec.ConfigValue)
ai.ConfigValues = marshalAttributeValues(knowns)
}
}
ret = append(ret, ai)
}

@ -239,7 +239,7 @@ func MarshalForRenderer(
return nil, nil, nil, nil, nil, err
}
if output.ActionInvocations, err = MarshalActionInvocations(p.Changes.ActionInvocations); err != nil {
if output.ActionInvocations, err = MarshalActionInvocations(p.Changes.ActionInvocations, schemas); err != nil {
return nil, nil, nil, nil, nil, err
}
@ -338,7 +338,7 @@ func Marshal(
// output.Changes.ActionInvocations
if p.Changes.ActionInvocations != nil {
if output.ActionInvocations, err = MarshalActionInvocations(p.Changes.ActionInvocations); err != nil {
if output.ActionInvocations, err = MarshalActionInvocations(p.Changes.ActionInvocations, schemas); err != nil {
return nil, fmt.Errorf("error marshaling action invocations: %s", err)
}
}

@ -6,6 +6,8 @@ package plans
import (
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/configs"
"github.com/hashicorp/terraform/internal/providers"
"github.com/zclconf/go-cty/cty"
)
type ActionInvocationInstance struct {
@ -24,12 +26,24 @@ type ActionInvocationInstance struct {
// to plan this action, and thus the configuration that must also be
// used to apply it.
ProviderAddr addrs.AbsProviderConfig
ConfigValue cty.Value
}
// Encode produces a variant of the receiver that has its change values
// serialized so it can be written to a plan file. Pass the implied type of the
// corresponding resource type schema for correct operation.
func (ai *ActionInvocationInstance) Encode() (*ActionInvocationInstanceSrc, error) {
func (ai *ActionInvocationInstance) Encode(schema *providers.ActionSchema) (*ActionInvocationInstanceSrc, error) {
ty := cty.DynamicPseudoType
if schema != nil {
ty = schema.ConfigSchema.ImpliedType()
}
configValue, err := NewDynamicValue(ai.ConfigValue, ty)
if err != nil {
return nil, err
}
return &ActionInvocationInstanceSrc{
Addr: ai.Addr,
TriggeringResourceAddr: ai.TriggeringResourceAddr,
@ -37,6 +51,7 @@ func (ai *ActionInvocationInstance) Encode() (*ActionInvocationInstanceSrc, erro
ActionTriggerBlockIndex: ai.ActionTriggerBlockIndex,
ActionsListIndex: ai.ActionsListIndex,
ProviderAddr: ai.ProviderAddr,
ConfigValue: configValue,
}, nil
}

@ -99,7 +99,15 @@ func (c *Changes) Encode(schemas *schemarepo.Schemas) (*ChangesSrc, error) {
}
for _, ai := range c.ActionInvocations {
a, err := ai.Encode()
p, ok := schemas.Providers[ai.ProviderAddr.Provider]
if !ok {
return changesSrc, fmt.Errorf("Changes.Encode: missing provider %s for %s", ai.ProviderAddr, ai.Addr)
}
schema, ok := p.Actions[ai.Addr.Action.Action.Type]
if !ok {
return changesSrc, fmt.Errorf("Changes.Encode: missing schema for %s", ai.Addr.Action.Action.Type)
}
a, err := ai.Encode(&schema)
if err != nil {
return changesSrc, fmt.Errorf("Changes.Encode: %w", err)
}

@ -161,7 +161,16 @@ func (c *ChangesSrc) Decode(schemas *schemarepo.Schemas) (*Changes, error) {
}
for _, ais := range c.ActionInvocations {
action, err := ais.Decode()
p, ok := schemas.Providers[ais.ProviderAddr.Provider]
if !ok {
return nil, fmt.Errorf("ChangesSrc.Decode: missing provider %s for %s", ais.ProviderAddr, ais.Addr)
}
schema, ok := p.Actions[ais.Addr.Action.Action.Type]
if !ok {
return nil, fmt.Errorf("ChangesSrc.Decode: missing schema for %s", ais.Addr.Action.Action.Type)
}
action, err := ais.Decode(&schema)
if err != nil {
return nil, err
}
@ -563,11 +572,24 @@ type ActionInvocationInstanceSrc struct {
ActionTriggerBlockIndex int
ActionsListIndex int
ConfigValue DynamicValue
ProviderAddr addrs.AbsProviderConfig
}
// Decode unmarshals the raw representation of any linked resources.
func (acs *ActionInvocationInstanceSrc) Decode() (*ActionInvocationInstance, error) {
func (acs *ActionInvocationInstanceSrc) Decode(schema *providers.ActionSchema) (*ActionInvocationInstance, error) {
ty := cty.DynamicPseudoType
if schema != nil {
ty = schema.ConfigSchema.ImpliedType()
}
config, err := acs.ConfigValue.Decode(ty)
if err != nil {
return nil, fmt.Errorf("error decoding 'config' value: %s", err)
}
ai := &ActionInvocationInstance{
Addr: acs.Addr,
TriggeringResourceAddr: acs.TriggeringResourceAddr,
@ -575,6 +597,7 @@ func (acs *ActionInvocationInstanceSrc) Decode() (*ActionInvocationInstance, err
ActionTriggerBlockIndex: acs.ActionTriggerBlockIndex,
ActionsListIndex: acs.ActionsListIndex,
ProviderAddr: acs.ProviderAddr,
ConfigValue: config,
}
return ai, nil
}
@ -584,5 +607,6 @@ func (acs *ActionInvocationInstanceSrc) DeepCopy() *ActionInvocationInstanceSrc
return acs
}
ret := *acs
ret.ConfigValue = ret.ConfigValue.Copy()
return &ret
}

@ -1654,10 +1654,11 @@ type ActionInvocationInstance struct {
// apply it.
Provider string `protobuf:"bytes,2,opt,name=provider,proto3" json:"provider,omitempty"`
LinkedResources []*ResourceInstanceActionChange `protobuf:"bytes,3,rep,name=linked_resources,json=linkedResources,proto3" json:"linked_resources,omitempty"`
TriggeringResourceAddr string `protobuf:"bytes,4,opt,name=triggering_resource_addr,json=triggeringResourceAddr,proto3" json:"triggering_resource_addr,omitempty"`
TriggerEvent ActionTriggerEvent `protobuf:"varint,5,opt,name=trigger_event,json=triggerEvent,proto3,enum=tfplan.ActionTriggerEvent" json:"trigger_event,omitempty"`
ActionTriggerBlockIndex int64 `protobuf:"varint,6,opt,name=action_trigger_block_index,json=actionTriggerBlockIndex,proto3" json:"action_trigger_block_index,omitempty"`
ActionsListIndex int64 `protobuf:"varint,7,opt,name=actions_list_index,json=actionsListIndex,proto3" json:"actions_list_index,omitempty"`
ConfigValue *DynamicValue `protobuf:"bytes,4,opt,name=config_value,json=configValue,proto3" json:"config_value,omitempty"`
TriggeringResourceAddr string `protobuf:"bytes,5,opt,name=triggering_resource_addr,json=triggeringResourceAddr,proto3" json:"triggering_resource_addr,omitempty"`
TriggerEvent ActionTriggerEvent `protobuf:"varint,6,opt,name=trigger_event,json=triggerEvent,proto3,enum=tfplan.ActionTriggerEvent" json:"trigger_event,omitempty"`
ActionTriggerBlockIndex int64 `protobuf:"varint,7,opt,name=action_trigger_block_index,json=actionTriggerBlockIndex,proto3" json:"action_trigger_block_index,omitempty"`
ActionsListIndex int64 `protobuf:"varint,8,opt,name=actions_list_index,json=actionsListIndex,proto3" json:"actions_list_index,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -1713,6 +1714,13 @@ func (x *ActionInvocationInstance) GetLinkedResources() []*ResourceInstanceActio
return nil
}
func (x *ActionInvocationInstance) GetConfigValue() *DynamicValue {
if x != nil {
return x.ConfigValue
}
return nil
}
func (x *ActionInvocationInstance) GetTriggeringResourceAddr() string {
if x != nil {
return x.TriggeringResourceAddr
@ -2233,7 +2241,7 @@ var file_planfile_proto_rawDesc = string([]byte{
0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e,
0x44, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x52, 0x06,
0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x81, 0x03, 0x0a, 0x18, 0x41, 0x63, 0x74, 0x69, 0x6f,
0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0xba, 0x03, 0x0a, 0x18, 0x41, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x49, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x73, 0x74, 0x61,
0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69,
@ -2243,95 +2251,98 @@ var file_planfile_proto_rawDesc = string([]byte{
0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49,
0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61,
0x6e, 0x67, 0x65, 0x52, 0x0f, 0x6c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69,
0x6e, 0x67, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72,
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69,
0x6e, 0x67, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, 0x12, 0x3f,
0x0a, 0x0d, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18,
0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x41,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e,
0x74, 0x52, 0x0c, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12,
0x3b, 0x0a, 0x1a, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65,
0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x06, 0x20,
0x01, 0x28, 0x03, 0x52, 0x17, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72, 0x69, 0x67, 0x67,
0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2c, 0x0a, 0x12,
0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x64,
0x65, 0x78, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x7b, 0x0a, 0x1c, 0x52, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64,
0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x1f,
0x0a, 0x0b, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12,
0x26, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 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, 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, 0x94, 0x01, 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, 0x12, 0x0a, 0x0a,
0x06, 0x46, 0x4f, 0x52, 0x47, 0x45, 0x54, 0x10, 0x08, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x52, 0x45,
0x41, 0x54, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f, 0x46, 0x4f, 0x52, 0x47, 0x45, 0x54, 0x10,
0x09, 0x2a, 0xc8, 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, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45,
0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b,
0x5f, 0x4e, 0x45, 0x53, 0x54, 0x45, 0x44, 0x10, 0x0d, 0x12, 0x21, 0x0a, 0x1d, 0x44, 0x45, 0x4c,
0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d,
0x4f, 0x56, 0x45, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x10, 0x0c, 0x2a, 0x9b, 0x01, 0x0a,
0x0e, 0x44, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12,
0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16,
0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x55,
0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x53, 0x4f,
0x55, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e,
0x4f, 0x57, 0x4e, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x44, 0x45,
0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e,
0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x41, 0x42, 0x53, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x52, 0x45,
0x52, 0x45, 0x51, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x45, 0x46, 0x45, 0x52, 0x52, 0x45,
0x44, 0x5f, 0x50, 0x52, 0x45, 0x52, 0x45, 0x51, 0x10, 0x05, 0x2a, 0xa1, 0x01, 0x0a, 0x12, 0x41,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e,
0x74, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x45, 0x56, 0x45,
0x4e, 0x54, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x42, 0x45, 0x46, 0x4f, 0x52, 0x45, 0x5f, 0x43,
0x45, 0x52, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x46, 0x54, 0x45, 0x52,
0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x42, 0x45, 0x46,
0x4f, 0x52, 0x45, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c,
0x41, 0x46, 0x54, 0x45, 0x52, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x04, 0x12, 0x12,
0x0a, 0x0e, 0x42, 0x45, 0x46, 0x4f, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59,
0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x41, 0x46, 0x54, 0x45, 0x52, 0x5f, 0x44, 0x45, 0x53, 0x54,
0x52, 0x4f, 0x59, 0x10, 0x06, 0x12, 0x07, 0x0a, 0x03, 0x43, 0x4c, 0x49, 0x10, 0x07, 0x42, 0x39,
0x5a, 0x37, 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,
0x70, 0x6c, 0x61, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
0x72, 0x63, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 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,
0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x38, 0x0a,
0x18, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
0x16, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, 0x12, 0x3f, 0x0a, 0x0d, 0x74, 0x72, 0x69, 0x67, 0x67,
0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a,
0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72,
0x69, 0x67, 0x67, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0c, 0x74, 0x72, 0x69, 0x67,
0x67, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3b, 0x0a, 0x1a, 0x61, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x61, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2c, 0x0a, 0x12, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28,
0x03, 0x52, 0x10, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e,
0x64, 0x65, 0x78, 0x22, 0x7b, 0x0a, 0x1c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49,
0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61,
0x6e, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x70, 0x6f, 0x73,
0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65,
0x70, 0x6f, 0x73, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x6e,
0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 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,
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, 0x94, 0x01, 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, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x4f, 0x52, 0x47, 0x45, 0x54,
0x10, 0x08, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x48, 0x45,
0x4e, 0x5f, 0x46, 0x4f, 0x52, 0x47, 0x45, 0x54, 0x10, 0x09, 0x2a, 0xc8, 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, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41,
0x55, 0x53, 0x45, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x4e, 0x45, 0x53, 0x54, 0x45, 0x44,
0x10, 0x0d, 0x12, 0x21, 0x0a, 0x1d, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43,
0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x41, 0x52,
0x47, 0x45, 0x54, 0x10, 0x0c, 0x2a, 0x9b, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x66, 0x65, 0x72, 0x72,
0x65, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41,
0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43,
0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10,
0x01, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x4f,
0x4e, 0x46, 0x49, 0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x02, 0x12, 0x1b,
0x0a, 0x17, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49,
0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x41,
0x42, 0x53, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x52, 0x45, 0x51, 0x10, 0x04, 0x12, 0x13,
0x0a, 0x0f, 0x44, 0x45, 0x46, 0x45, 0x52, 0x52, 0x45, 0x44, 0x5f, 0x50, 0x52, 0x45, 0x52, 0x45,
0x51, 0x10, 0x05, 0x2a, 0xa1, 0x01, 0x0a, 0x12, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72,
0x69, 0x67, 0x67, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x4e,
0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x11, 0x0a,
0x0d, 0x42, 0x45, 0x46, 0x4f, 0x52, 0x45, 0x5f, 0x43, 0x45, 0x52, 0x41, 0x54, 0x45, 0x10, 0x01,
0x12, 0x10, 0x0a, 0x0c, 0x41, 0x46, 0x54, 0x45, 0x52, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45,
0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x42, 0x45, 0x46, 0x4f, 0x52, 0x45, 0x5f, 0x55, 0x50, 0x44,
0x41, 0x54, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x46, 0x54, 0x45, 0x52, 0x5f, 0x55,
0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x42, 0x45, 0x46, 0x4f, 0x52,
0x45, 0x5f, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x41,
0x46, 0x54, 0x45, 0x52, 0x5f, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, 0x06, 0x12, 0x07,
0x0a, 0x03, 0x43, 0x4c, 0x49, 0x10, 0x07, 0x42, 0x39, 0x5a, 0x37, 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, 0x70, 0x6c, 0x61, 0x6e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
})
var (
@ -2413,17 +2424,18 @@ var file_planfile_proto_depIdxs = []int32{
17, // 32: tfplan.Importing.identity:type_name -> tfplan.DynamicValue
3, // 33: tfplan.Deferred.reason:type_name -> tfplan.DeferredReason
22, // 34: tfplan.ActionInvocationInstance.linked_resources:type_name -> tfplan.ResourceInstanceActionChange
4, // 35: tfplan.ActionInvocationInstance.trigger_event:type_name -> tfplan.ActionTriggerEvent
11, // 36: tfplan.ResourceInstanceActionChange.change:type_name -> tfplan.Change
17, // 37: tfplan.Plan.VariablesEntry.value:type_name -> tfplan.DynamicValue
18, // 38: tfplan.Plan.resource_attr.attr:type_name -> tfplan.Path
5, // 39: tfplan.CheckResults.ObjectResult.status:type_name -> tfplan.CheckResults.Status
17, // 40: tfplan.Path.Step.element_key:type_name -> tfplan.DynamicValue
41, // [41:41] is the sub-list for method output_type
41, // [41:41] is the sub-list for method input_type
41, // [41:41] is the sub-list for extension type_name
41, // [41:41] is the sub-list for extension extendee
0, // [0:41] is the sub-list for field type_name
17, // 35: tfplan.ActionInvocationInstance.config_value:type_name -> tfplan.DynamicValue
4, // 36: tfplan.ActionInvocationInstance.trigger_event:type_name -> tfplan.ActionTriggerEvent
11, // 37: tfplan.ResourceInstanceActionChange.change:type_name -> tfplan.Change
17, // 38: tfplan.Plan.VariablesEntry.value:type_name -> tfplan.DynamicValue
18, // 39: tfplan.Plan.resource_attr.attr:type_name -> tfplan.Path
5, // 40: tfplan.CheckResults.ObjectResult.status:type_name -> tfplan.CheckResults.Status
17, // 41: tfplan.Path.Step.element_key:type_name -> tfplan.DynamicValue
42, // [42:42] is the sub-list for method output_type
42, // [42:42] is the sub-list for method input_type
42, // [42:42] is the sub-list for extension type_name
42, // [42:42] is the sub-list for extension extendee
0, // [0:42] is the sub-list for field type_name
}
func init() { file_planfile_proto_init() }

@ -449,11 +449,12 @@ message ActionInvocationInstance {
string provider = 2;
repeated ResourceInstanceActionChange linked_resources = 3;
DynamicValue config_value = 4;
string triggering_resource_addr = 4;
ActionTriggerEvent trigger_event = 5;
int64 action_trigger_block_index = 6;
int64 actions_list_index = 7;
string triggering_resource_addr = 5;
ActionTriggerEvent trigger_event = 6;
int64 action_trigger_block_index = 7;
int64 actions_list_index = 8;
}
message ResourceInstanceActionChange {

@ -53,3 +53,11 @@ func (ss *Schemas) ResourceTypeConfig(provider addrs.Provider, resourceMode addr
func (ss *Schemas) ProvisionerConfig(name string) *configschema.Block {
return ss.Provisioners[name]
}
func (ss *Schemas) ActionTypeConfig(provider addrs.Provider, actionType string) providers.ActionSchema {
ps := ss.ProviderSchema(provider)
if ps.Actions == nil {
return providers.ActionSchema{}
}
return ps.Actions[actionType]
}

@ -11,13 +11,14 @@ import (
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/dag"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/plans/objchange"
"github.com/hashicorp/terraform/internal/providers"
"github.com/hashicorp/terraform/internal/tfdiags"
)
type nodeActionApply struct {
TriggeringResourceaddrs addrs.AbsResourceInstance
ActionInvocations []*plans.ActionInvocationInstance
ActionInvocations []*plans.ActionInvocationInstanceSrc
}
var (
@ -41,11 +42,11 @@ func (n *nodeActionApply) Execute(ctx EvalContext, _ walkOperation) (diags tfdia
return invokeActions(ctx, n.ActionInvocations)
}
func invokeActions(ctx EvalContext, actionInvocations []*plans.ActionInvocationInstance) tfdiags.Diagnostics {
func invokeActions(ctx EvalContext, actionInvocations []*plans.ActionInvocationInstanceSrc) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
// First we order the action invocations by their trigger block index and events list index.
// This way we have the correct order of execution.
orderedActionInvocations := make([]*plans.ActionInvocationInstance, len(actionInvocations))
orderedActionInvocations := make([]*plans.ActionInvocationInstanceSrc, len(actionInvocations))
copy(orderedActionInvocations, actionInvocations)
sort.Slice(orderedActionInvocations, func(i, j int) bool {
if orderedActionInvocations[i].ActionTriggerBlockIndex == orderedActionInvocations[j].ActionTriggerBlockIndex {
@ -78,7 +79,7 @@ func invokeActions(ctx EvalContext, actionInvocations []*plans.ActionInvocationI
for i, actionData := range orderedActionData {
ai := orderedActionInvocations[i]
provider, _, err := getProvider(ctx, actionData.ProviderAddr)
provider, schema, err := getProvider(ctx, actionData.ProviderAddr)
if err != nil {
diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error,
@ -88,9 +89,42 @@ func invokeActions(ctx EvalContext, actionInvocations []*plans.ActionInvocationI
return diags
}
actionSchema, ok := schema.Actions[ai.Addr.Action.Action.Type]
if !ok {
// This should have been caught earlier
diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error,
fmt.Sprintf("Action %s not found in provider schema", ai.Addr),
fmt.Sprintf("The action %s was not found in the provider schema for %s", ai.Addr.Action.Action.Type, actionData.ProviderAddr),
))
return diags
}
ais, err := ai.Decode(&actionSchema)
if err != nil {
diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error,
fmt.Sprintf("Failed to decode action data for %s", ai.Addr),
err.Error(),
))
}
// We don't want to send the marks, but all marks are okay in the context of an action invocation.
unmarkedConfigValue, _ := actionData.ConfigValue.UnmarkDeep()
// Validate that what we planned matches the action data we have.
errs := objchange.AssertObjectCompatible(actionSchema.ConfigSchema, ais.ConfigValue, unmarkedConfigValue)
for _, err := range errs {
diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error,
"Provider produced inconsistent final plan",
fmt.Sprintf(
"When expanding the plan for %s to include new values learned so far during apply, provider %q produced an invalid new value for %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.",
ai.Addr, actionData.ProviderAddr.Provider.String(), tfdiags.FormatError(err),
),
))
}
hookIdentity := HookActionIdentity{
Addr: ai.Addr,
TriggeringResourceAddr: ai.TriggeringResourceAddr,

@ -37,7 +37,7 @@ type NodeApplyableResourceInstance struct {
// that this node represents, which the node itself must therefore ignore.
forceReplace []addrs.AbsResourceInstance
beforeActionInvocations []*plans.ActionInvocationInstance
beforeActionInvocations []*plans.ActionInvocationInstanceSrc
}
var (

@ -86,20 +86,11 @@ func (t *DiffTransformer) Transform(g *Graph) error {
// to be run as part of the apply phase.
// The after-triggered action invocations will be run as part of a separate node
// that will be connected to the resource instance nodes.
runBeforeNode := addrs.MakeMap[addrs.AbsResourceInstance, []*plans.ActionInvocationInstance]()
runAfterNode := addrs.MakeMap[addrs.AbsResourceInstance, []*plans.ActionInvocationInstance]()
for _, aiSrc := range changes.ActionInvocations {
ai, err := aiSrc.Decode()
if err != nil {
diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error,
"Invalid action invocation",
fmt.Sprintf("The plan contains an invalid action invocation for %s: %s", aiSrc.Addr, err),
))
return diags.Err()
}
runBeforeNode := addrs.MakeMap[addrs.AbsResourceInstance, []*plans.ActionInvocationInstanceSrc]()
runAfterNode := addrs.MakeMap[addrs.AbsResourceInstance, []*plans.ActionInvocationInstanceSrc]()
for _, ai := range changes.ActionInvocations {
var targetMap addrs.Map[addrs.AbsResourceInstance, []*plans.ActionInvocationInstance]
var targetMap addrs.Map[addrs.AbsResourceInstance, []*plans.ActionInvocationInstanceSrc]
switch ai.TriggerEvent {
case configs.BeforeCreate, configs.BeforeUpdate, configs.BeforeDestroy:
targetMap = runBeforeNode
@ -109,7 +100,7 @@ func (t *DiffTransformer) Transform(g *Graph) error {
panic("I don't know when to run this action invocation")
}
basis := []*plans.ActionInvocationInstance{}
basis := []*plans.ActionInvocationInstanceSrc{}
if targetMap.Has(ai.TriggeringResourceAddr) {
basis = targetMap.Get(ai.TriggeringResourceAddr)
}

Loading…
Cancel
Save