/
githubmirror
/
terraform
Обзор
Документация
Войти
/
githubmirror
/
terraform
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
internal/plans/action_invocation.go
214 строк
6 KB
James Bardin
expose on_failure to the json hook output
10 июл 2026, 18:43
10 июл 2026, 18:43
ccd981e
Код
Авторство
О чём код?
// Copyright IBM Corp. 2014, 2026 // SPDX-License-Identifier: BUSL-1.1 package plans import ( "fmt" "github.com/zclconf/go-cty/cty" "github.com/hashicorp/terraform/internal/addrs" "github.com/hashicorp/terraform/internal/configs" "github.com/hashicorp/terraform/internal/lang/marks" "github.com/hashicorp/terraform/internal/providers" "github.com/hashicorp/terraform/internal/tfdiags" ) type ActionInvocationInstance struct { Addr addrs.AbsActionInstance ActionTrigger ActionTrigger // Provider is the address of the provider configuration that was used // to plan this action, and thus the configuration that must also be // used to apply it. ProviderAddr addrs.AbsProviderConfig ConfigValue cty.Value Caller addrs.Referenceable } func (ai *ActionInvocationInstance) Equals(other *ActionInvocationInstance) bool { // Since the trigger can be the same if it's a CLI invocation we also compare the action addr return ai.Addr.Equal(other.Addr) && ai.ActionTrigger.Equals(other.ActionTrigger) } type ActionTrigger interface { actionTriggerSigil() TriggerEvent() configs.ActionTriggerEvent String() string Equals(to ActionTrigger) bool Less(other ActionTrigger) bool OnFailure() configs.ActionOnFailure } var ( _ ActionTrigger = (*ResourceActionTrigger)(nil) _ ActionTrigger = (*InvokeActionTrigger)(nil) ) // ResourceActionTrigger contains the action trigger configuration from the resource. type ResourceActionTrigger struct { TriggeringResourceAddr addrs.AbsResourceInstance // Information about the trigger // The event that triggered this action invocation. ActionTriggerEvent configs.ActionTriggerEvent // The index of the action_trigger block that triggered this invocation. ActionTriggerBlockIndex int // The index of the action in the events list of the action_trigger block ActionsListIndex int // ActionOnFailure indicates the configured on_failure mode ActionOnFailure configs.ActionOnFailure } func (t *ResourceActionTrigger) TriggerEvent() configs.ActionTriggerEvent { return t.ActionTriggerEvent } func (t *ResourceActionTrigger) actionTriggerSigil() {} func (t *ResourceActionTrigger) String() string { return t.TriggeringResourceAddr.String() } func (t *ResourceActionTrigger) Equals(other ActionTrigger) bool { o, ok := other.(*ResourceActionTrigger) if !ok { return false } return t.TriggeringResourceAddr.Equal(o.TriggeringResourceAddr) && t.ActionTriggerBlockIndex == o.ActionTriggerBlockIndex && t.ActionsListIndex == o.ActionsListIndex && t.ActionTriggerEvent == o.ActionTriggerEvent } func (t *ResourceActionTrigger) Less(other ActionTrigger) bool { o, ok := other.(*ResourceActionTrigger) if !ok { return false // We always want to show non-lifecycle actions first } return t.TriggeringResourceAddr.Less(o.TriggeringResourceAddr) || (t.TriggeringResourceAddr.Equal(o.TriggeringResourceAddr) && t.ActionTriggerBlockIndex < o.ActionTriggerBlockIndex) || (t.TriggeringResourceAddr.Equal(o.TriggeringResourceAddr) && t.ActionTriggerBlockIndex == o.ActionTriggerBlockIndex && t.ActionsListIndex < o.ActionsListIndex && t.ActionTriggerEvent < o.ActionTriggerEvent) } func (t *ResourceActionTrigger) OnFailure() configs.ActionOnFailure { return t.ActionOnFailure } // InvokeActionTrigger contains the configuration for an action triggered // (invoked) directly via CLI command. type InvokeActionTrigger struct { // There may be an associated triggering resource to fill in the caller // object. Since we need an optional address here, but resource addresses // are not handled as pointers, one must always check for a nil pointer here // before using the value. CallingResourceAddr *addrs.AbsResourceInstance } func (t *InvokeActionTrigger) actionTriggerSigil() {} func (t *InvokeActionTrigger) String() string { return "CLI" } func (t *InvokeActionTrigger) TriggerEvent() configs.ActionTriggerEvent { return configs.Invoke } func (t *InvokeActionTrigger) Equals(other ActionTrigger) bool { if other, ok := other.(*InvokeActionTrigger); ok { if t.CallingResourceAddr == nil || other.CallingResourceAddr == nil { return t.CallingResourceAddr == other.CallingResourceAddr } return addrs.Equivalent(*t.CallingResourceAddr, *other.CallingResourceAddr) } return false } func (t *InvokeActionTrigger) Less(other ActionTrigger) bool { if other, ok := other.(*InvokeActionTrigger); ok { if t.CallingResourceAddr == nil || other.CallingResourceAddr == nil { return t.CallingResourceAddr == nil } return t.CallingResourceAddr.String() < other.CallingResourceAddr.String() } return false } func (t *InvokeActionTrigger) OnFailure() configs.ActionOnFailure { return configs.ActionOnFailureHalt } // 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(schema *providers.ActionSchema) (*ActionInvocationInstanceSrc, error) { ret := &ActionInvocationInstanceSrc{ Addr: ai.Addr, ActionTrigger: ai.ActionTrigger, ProviderAddr: ai.ProviderAddr, } if ai.ConfigValue != cty.NilVal { ty := cty.DynamicPseudoType if schema != nil { ty = schema.ConfigSchema.ImpliedType() } unmarkedConfigValue, pvms := ai.ConfigValue.UnmarkDeepWithPaths() sensitivePaths, otherMarks := marks.PathsWithMark(pvms, marks.Sensitive) if len(otherMarks) > 0 { return nil, fmt.Errorf("%s: error serializing action invocation with unexpected marks on config value: %#v. This is a bug in Terraform.", tfdiags.FormatCtyPath(otherMarks[0].Path), otherMarks[0].Marks) } var err error ret.ConfigValue, err = NewDynamicValue(unmarkedConfigValue, ty) ret.SensitiveConfigPaths = sensitivePaths if err != nil { return nil, err } } return ret, nil } type ActionInvocationInstances []*ActionInvocationInstance func (ais ActionInvocationInstances) DeepCopy() ActionInvocationInstances { if ais == nil { return ais } ret := make(ActionInvocationInstances, len(ais)) for i, ai := range ais { ret[i] = ai.DeepCopy() } return ret } func (ai *ActionInvocationInstance) DeepCopy() *ActionInvocationInstance { if ai == nil { return ai } ret := *ai return &ret }