diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go b/vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go new file mode 100644 index 00000000..02d86970 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go @@ -0,0 +1,161 @@ +package terraform + +import ( + "sync" + + "github.com/hashicorp/terraform/config/module" + "github.com/hashicorp/terraform/dag" +) + +// PlanGraphBuilder implements GraphBuilder and is responsible for building +// a graph for planning (creating a Terraform Diff). +// +// The primary difference between this graph and others: +// +// * Based on the config since it represents the target state +// +// * Ignores lifecycle options since no lifecycle events occur here. This +// simplifies the graph significantly since complex transforms such as +// create-before-destroy can be completely ignored. +// +type PlanGraphBuilder struct { + // Module is the root module for the graph to build. + Module *module.Tree + + // State is the current state + State *State + + // Providers is the list of providers supported. + Providers []string + + // Provisioners is the list of provisioners supported. + Provisioners []string + + // Targets are resources to target + Targets []string + + // DisableReduce, if true, will not reduce the graph. Great for testing. + DisableReduce bool + + // Validate will do structural validation of the graph. + Validate bool + + // CustomConcrete can be set to customize the node types created + // for various parts of the plan. This is useful in order to customize + // the plan behavior. + CustomConcrete bool + ConcreteProvider ConcreteProviderNodeFunc + ConcreteResource ConcreteResourceNodeFunc + ConcreteResourceOrphan ConcreteResourceNodeFunc + + once sync.Once +} + +// See GraphBuilder +func (b *PlanGraphBuilder) Build(path []string) (*Graph, error) { + return (&BasicGraphBuilder{ + Steps: b.Steps(), + Validate: b.Validate, + Name: "PlanGraphBuilder", + }).Build(path) +} + +// See GraphBuilder +func (b *PlanGraphBuilder) Steps() []GraphTransformer { + b.once.Do(b.init) + + steps := []GraphTransformer{ + // Creates all the resources represented in the config + &ConfigTransformer{ + Concrete: b.ConcreteResource, + Module: b.Module, + }, + + // Add the outputs + &OutputTransformer{Module: b.Module}, + + // Add orphan resources + &OrphanResourceTransformer{ + Concrete: b.ConcreteResourceOrphan, + State: b.State, + Module: b.Module, + }, + + // Attach the configuration to any resources + &AttachResourceConfigTransformer{Module: b.Module}, + + // Attach the state + &AttachStateTransformer{State: b.State}, + + // Add root variables + &RootVariableTransformer{Module: b.Module}, + + // Create all the providers + &MissingProviderTransformer{Providers: b.Providers, Concrete: b.ConcreteProvider}, + &ProviderTransformer{}, + &DisableProviderTransformer{}, + &ParentProviderTransformer{}, + &AttachProviderConfigTransformer{Module: b.Module}, + + // Provisioner-related transformations. Only add these if requested. + GraphTransformIf( + func() bool { return b.Provisioners != nil }, + GraphTransformMulti( + &MissingProvisionerTransformer{Provisioners: b.Provisioners}, + &ProvisionerTransformer{}, + ), + ), + + // Add module variables + &ModuleVariableTransformer{Module: b.Module}, + + // Connect so that the references are ready for targeting. We'll + // have to connect again later for providers and so on. + &ReferenceTransformer{}, + + // Target + &TargetsTransformer{Targets: b.Targets}, + + // Close opened plugin connections + &CloseProviderTransformer{}, + &CloseProvisionerTransformer{}, + + // Single root + &RootTransformer{}, + } + + if !b.DisableReduce { + // Perform the transitive reduction to make our graph a bit + // more sane if possible (it usually is possible). + steps = append(steps, &TransitiveReductionTransformer{}) + } + + return steps +} + +func (b *PlanGraphBuilder) init() { + // Do nothing if the user requests customizing the fields + if b.CustomConcrete { + return + } + + b.ConcreteProvider = func(a *NodeAbstractProvider) dag.Vertex { + return &NodeApplyableProvider{ + NodeAbstractProvider: a, + } + } + + b.ConcreteResource = func(a *NodeAbstractResource) dag.Vertex { + return &NodePlannableResource{ + NodeAbstractCountResource: &NodeAbstractCountResource{ + NodeAbstractResource: a, + }, + } + } + + b.ConcreteResourceOrphan = func(a *NodeAbstractResource) dag.Vertex { + return &NodePlannableResourceOrphan{ + NodeAbstractResource: a, + } + } +} |