github.com/opentofu/opentofu@v1.7.1/internal/tofu/graph_builder_eval.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package tofu
     7  
     8  import (
     9  	"github.com/opentofu/opentofu/internal/addrs"
    10  	"github.com/opentofu/opentofu/internal/configs"
    11  	"github.com/opentofu/opentofu/internal/dag"
    12  	"github.com/opentofu/opentofu/internal/states"
    13  	"github.com/opentofu/opentofu/internal/tfdiags"
    14  )
    15  
    16  // EvalGraphBuilder implements GraphBuilder and constructs a graph suitable
    17  // for evaluating in-memory values (input variables, local values, output
    18  // values) in the state without any other side-effects.
    19  //
    20  // This graph is used only in weird cases, such as the "tofu console"
    21  // CLI command, where we need to evaluate expressions against the state
    22  // without taking any other actions.
    23  //
    24  // The generated graph will include nodes for providers, resources, etc
    25  // just to allow indirect dependencies to be resolved, but these nodes will
    26  // not take any actions themselves since we assume that their parts of the
    27  // state, if any, are already complete.
    28  //
    29  // Although the providers are never configured, they must still be available
    30  // in order to obtain schema information used for type checking, etc.
    31  type EvalGraphBuilder struct {
    32  	// Config is the configuration tree.
    33  	Config *configs.Config
    34  
    35  	// State is the current state
    36  	State *states.State
    37  
    38  	// RootVariableValues are the raw input values for root input variables
    39  	// given by the caller, which we'll resolve into final values as part
    40  	// of the plan walk.
    41  	RootVariableValues InputValues
    42  
    43  	// Plugins is a library of plug-in components (providers and
    44  	// provisioners) available for use.
    45  	Plugins *contextPlugins
    46  }
    47  
    48  // See GraphBuilder
    49  func (b *EvalGraphBuilder) Build(path addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) {
    50  	return (&BasicGraphBuilder{
    51  		Steps: b.Steps(),
    52  		Name:  "EvalGraphBuilder",
    53  	}).Build(path)
    54  }
    55  
    56  // See GraphBuilder
    57  func (b *EvalGraphBuilder) Steps() []GraphTransformer {
    58  	concreteProvider := func(a *NodeAbstractProvider) dag.Vertex {
    59  		return &NodeEvalableProvider{
    60  			NodeAbstractProvider: a,
    61  		}
    62  	}
    63  
    64  	steps := []GraphTransformer{
    65  		// Creates all the data resources that aren't in the state. This will also
    66  		// add any orphans from scaling in as destroy nodes.
    67  		&ConfigTransformer{
    68  			Config: b.Config,
    69  		},
    70  
    71  		// Add dynamic values
    72  		&RootVariableTransformer{Config: b.Config, RawValues: b.RootVariableValues},
    73  		&ModuleVariableTransformer{Config: b.Config},
    74  		&LocalTransformer{Config: b.Config},
    75  		&OutputTransformer{
    76  			Config:   b.Config,
    77  			Planning: true,
    78  		},
    79  
    80  		// Attach the configuration to any resources
    81  		&AttachResourceConfigTransformer{Config: b.Config},
    82  
    83  		// Attach the state
    84  		&AttachStateTransformer{State: b.State},
    85  
    86  		transformProviders(concreteProvider, b.Config),
    87  
    88  		// Must attach schemas before ReferenceTransformer so that we can
    89  		// analyze the configuration to find references.
    90  		&AttachSchemaTransformer{Plugins: b.Plugins, Config: b.Config},
    91  
    92  		// After schema transformer, we can add function references
    93  		&ProviderFunctionTransformer{Config: b.Config},
    94  
    95  		// Remove unused providers and proxies
    96  		&PruneProviderTransformer{},
    97  
    98  		// Create expansion nodes for all of the module calls. This must
    99  		// come after all other transformers that create nodes representing
   100  		// objects that can belong to modules.
   101  		&ModuleExpansionTransformer{Config: b.Config},
   102  
   103  		// Connect so that the references are ready for targeting. We'll
   104  		// have to connect again later for providers and so on.
   105  		&ReferenceTransformer{},
   106  
   107  		// Although we don't configure providers, we do still start them up
   108  		// to get their schemas, and so we must shut them down again here.
   109  		&CloseProviderTransformer{},
   110  
   111  		// Close root module
   112  		&CloseRootModuleTransformer{},
   113  
   114  		// Remove redundant edges to simplify the graph.
   115  		&TransitiveReductionTransformer{},
   116  	}
   117  
   118  	return steps
   119  }