blob: ab95f0f4acf7d4c86c03bb56307f02a1f320bbd8 [file] [log] [blame] [edit]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package stackplan
import (
"time"
"github.com/zclconf/go-cty/cty"
"google.golang.org/protobuf/types/known/anypb"
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/collections"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/providers"
"github.com/hashicorp/terraform/internal/stacks/stackaddrs"
)
// Plan is the main type in this package, representing an entire stack plan,
// or at least the subset of the information that Terraform needs to reliably
// apply the plan and detect any inconsistencies during the apply process.
//
// However, the process of _creating_ a plan doesn't actually produce a single
// object of this type, and instead produces fragments of it gradually as the
// planning process proceeds. The caller of the stack runtime must retain
// all of the raw parts in the order they were emitted and provide them back
// during the apply phase, and then we will finally construct a single instance
// of Plan covering the entire set of changes before we begin applying it.
type Plan struct {
// Applyable is true for a plan that was successfully created in full and
// is sufficient to be applied, or false if the plan is incomplete for
// some reason, such as if an error occurred during planning and so
// the planning process did not entirely run.
Applyable bool
// Complete is true for a plan that shouldn't need any follow-up plans to
// converge.
Complete bool
// Mode is the original mode of the plan.
Mode plans.Mode
// The raw representation of the raw state that was provided in the request
// to create the plan. We use this primarily to perform mundane state
// data structure maintenence operations, such as discarding keys that
// are no longer needed or replacing data in old formats with the
// equivalent new representations.
PrevRunStateRaw map[string]*anypb.Any
// RootInputValues are the input variable values provided to calculate
// the plan. We must use the same values during the apply step to
// sure that the actions taken can be consistent with what was planned.
RootInputValues map[stackaddrs.InputVariable]cty.Value
// ApplyTimeInputVariables are the names of the root input variable
// values whose values must be re-supplied during the apply phase,
// instead of being persisted in [Plan.RootInputValues].
ApplyTimeInputVariables collections.Set[stackaddrs.InputVariable]
// DeletedInputVariables tracks the set of input variables that are being
// deleted by this plan. The apply operation will miss any values
// that are not defined in the configuration, but should still emit
// deletion events to remove them from the state.
DeletedInputVariables collections.Set[stackaddrs.InputVariable]
// DeletedOutputValues tracks the set of output values that are being
// deleted by this plan. The apply operation will miss any output values
// that are not defined in the configuration, but should still emit
// deletion events to remove them from the state. Output values not being
// deleted will be recomputed during the apply so are not needed.
DeletedOutputValues collections.Set[stackaddrs.OutputValue]
// Components contains the separate plans for each of the compoonent
// instances defined in the overall stack configuration, including any
// nested component instances from embedded stacks.
Components collections.Map[stackaddrs.AbsComponentInstance, *Component]
// DeletedComponents are a set of components that are in the state that
// should just be removed without any apply operation. This is typically
// because they are not referenced in the configuration and have no
// associated resources.
DeletedComponents collections.Set[stackaddrs.AbsComponentInstance]
// ProviderFunctionResults is a shared table of results from calling
// provider functions. This is stored and loaded from during the planning
// stage to use during apply operations.
ProviderFunctionResults []providers.FunctionHash
// PlanTimestamp is the time at which the plan was created.
PlanTimestamp time.Time
}
// ComponentInstances returns a set of the component instances that belong to
// the given component.
func (p *Plan) ComponentInstances(addr stackaddrs.AbsComponent) collections.Set[stackaddrs.ComponentInstance] {
ret := collections.NewSet[stackaddrs.ComponentInstance]()
for elem := range p.Components.All() {
if elem.Stack.String() != addr.Stack.String() {
// Then
continue
}
if elem.Item.Component.Name != addr.Item.Name {
continue
}
ret.Add(elem.Item)
}
return ret
}
// RequiredProviderInstances returns a description of all of the provider
// instance slots that are required to satisfy the resource instances
// belonging to the given component instance.
//
// See also stackeval.ComponentConfig.RequiredProviderInstances for a similar
// function that operates on the configuration of a component instance rather
// than the plan of one.
func (p *Plan) RequiredProviderInstances(addr stackaddrs.AbsComponentInstance) addrs.Set[addrs.RootProviderConfig] {
component, ok := p.Components.GetOk(addr)
if !ok {
return addrs.MakeSet[addrs.RootProviderConfig]()
}
return component.RequiredProviderInstances()
}