github.com/opentofu/opentofu@v1.7.1/internal/tofu/eval_context.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/hashicorp/hcl/v2"
    10  	"github.com/opentofu/opentofu/internal/addrs"
    11  	"github.com/opentofu/opentofu/internal/checks"
    12  	"github.com/opentofu/opentofu/internal/configs/configschema"
    13  	"github.com/opentofu/opentofu/internal/encryption"
    14  	"github.com/opentofu/opentofu/internal/instances"
    15  	"github.com/opentofu/opentofu/internal/lang"
    16  	"github.com/opentofu/opentofu/internal/plans"
    17  	"github.com/opentofu/opentofu/internal/providers"
    18  	"github.com/opentofu/opentofu/internal/provisioners"
    19  	"github.com/opentofu/opentofu/internal/refactoring"
    20  	"github.com/opentofu/opentofu/internal/states"
    21  	"github.com/opentofu/opentofu/internal/tfdiags"
    22  	"github.com/zclconf/go-cty/cty"
    23  )
    24  
    25  // EvalContext is the interface that is given to eval nodes to execute.
    26  type EvalContext interface {
    27  	// Stopped returns a channel that is closed when evaluation is stopped
    28  	// via tofu.Context.Stop()
    29  	Stopped() <-chan struct{}
    30  
    31  	// Path is the current module path.
    32  	Path() addrs.ModuleInstance
    33  
    34  	// Hook is used to call hook methods. The callback is called for each
    35  	// hook and should return the hook action to take and the error.
    36  	Hook(func(Hook) (HookAction, error)) error
    37  
    38  	// Input is the UIInput object for interacting with the UI.
    39  	Input() UIInput
    40  
    41  	// InitProvider initializes the provider with the given address, and returns
    42  	// the implementation of the resource provider or an error.
    43  	//
    44  	// It is an error to initialize the same provider more than once. This
    45  	// method will panic if the module instance address of the given provider
    46  	// configuration does not match the Path() of the EvalContext.
    47  	InitProvider(addr addrs.AbsProviderConfig) (providers.Interface, error)
    48  
    49  	// Provider gets the provider instance with the given address (already
    50  	// initialized) or returns nil if the provider isn't initialized.
    51  	//
    52  	// This method expects an _absolute_ provider configuration address, since
    53  	// resources in one module are able to use providers from other modules.
    54  	// InitProvider must've been called on the EvalContext of the module
    55  	// that owns the given provider before calling this method.
    56  	Provider(addrs.AbsProviderConfig) providers.Interface
    57  
    58  	// ProviderSchema retrieves the schema for a particular provider, which
    59  	// must have already been initialized with InitProvider.
    60  	//
    61  	// This method expects an _absolute_ provider configuration address, since
    62  	// resources in one module are able to use providers from other modules.
    63  	ProviderSchema(addrs.AbsProviderConfig) (providers.ProviderSchema, error)
    64  
    65  	// CloseProvider closes provider connections that aren't needed anymore.
    66  	//
    67  	// This method will panic if the module instance address of the given
    68  	// provider configuration does not match the Path() of the EvalContext.
    69  	CloseProvider(addrs.AbsProviderConfig) error
    70  
    71  	// ConfigureProvider configures the provider with the given
    72  	// configuration. This is a separate context call because this call
    73  	// is used to store the provider configuration for inheritance lookups
    74  	// with ParentProviderConfig().
    75  	//
    76  	// This method will panic if the module instance address of the given
    77  	// provider configuration does not match the Path() of the EvalContext.
    78  	ConfigureProvider(addrs.AbsProviderConfig, cty.Value) tfdiags.Diagnostics
    79  
    80  	// ProviderInput and SetProviderInput are used to configure providers
    81  	// from user input.
    82  	//
    83  	// These methods will panic if the module instance address of the given
    84  	// provider configuration does not match the Path() of the EvalContext.
    85  	ProviderInput(addrs.AbsProviderConfig) map[string]cty.Value
    86  	SetProviderInput(addrs.AbsProviderConfig, map[string]cty.Value)
    87  
    88  	// Provisioner gets the provisioner instance with the given name.
    89  	Provisioner(string) (provisioners.Interface, error)
    90  
    91  	// ProvisionerSchema retrieves the main configuration schema for a
    92  	// particular provisioner, which must have already been initialized with
    93  	// InitProvisioner.
    94  	ProvisionerSchema(string) (*configschema.Block, error)
    95  
    96  	// CloseProvisioner closes all provisioner plugins.
    97  	CloseProvisioners() error
    98  
    99  	// EvaluateBlock takes the given raw configuration block and associated
   100  	// schema and evaluates it to produce a value of an object type that
   101  	// conforms to the implied type of the schema.
   102  	//
   103  	// The "self" argument is optional. If given, it is the referenceable
   104  	// address that the name "self" should behave as an alias for when
   105  	// evaluating. Set this to nil if the "self" object should not be available.
   106  	//
   107  	// The "key" argument is also optional. If given, it is the instance key
   108  	// of the current object within the multi-instance container it belongs
   109  	// to. For example, on a resource block with "count" set this should be
   110  	// set to a different addrs.IntKey for each instance created from that
   111  	// block. Set this to addrs.NoKey if not appropriate.
   112  	//
   113  	// The returned body is an expanded version of the given body, with any
   114  	// "dynamic" blocks replaced with zero or more static blocks. This can be
   115  	// used to extract correct source location information about attributes of
   116  	// the returned object value.
   117  	EvaluateBlock(body hcl.Body, schema *configschema.Block, self addrs.Referenceable, keyData InstanceKeyEvalData) (cty.Value, hcl.Body, tfdiags.Diagnostics)
   118  
   119  	// EvaluateExpr takes the given HCL expression and evaluates it to produce
   120  	// a value.
   121  	//
   122  	// The "self" argument is optional. If given, it is the referenceable
   123  	// address that the name "self" should behave as an alias for when
   124  	// evaluating. Set this to nil if the "self" object should not be available.
   125  	EvaluateExpr(expr hcl.Expression, wantType cty.Type, self addrs.Referenceable) (cty.Value, tfdiags.Diagnostics)
   126  
   127  	// EvaluateReplaceTriggeredBy takes the raw reference expression from the
   128  	// config, and returns the evaluated *addrs.Reference along with a boolean
   129  	// indicating if that reference forces replacement.
   130  	EvaluateReplaceTriggeredBy(expr hcl.Expression, repData instances.RepetitionData) (*addrs.Reference, bool, tfdiags.Diagnostics)
   131  
   132  	// EvaluateImportAddress takes the raw reference expression of the import address
   133  	// from the config, and returns the evaluated address addrs.AbsResourceInstance
   134  	EvaluateImportAddress(expr hcl.Expression, keyData instances.RepetitionData) (addrs.AbsResourceInstance, tfdiags.Diagnostics)
   135  
   136  	// EvaluationScope returns a scope that can be used to evaluate reference
   137  	// addresses in this context.
   138  	EvaluationScope(self addrs.Referenceable, source addrs.Referenceable, keyData InstanceKeyEvalData) *lang.Scope
   139  
   140  	// SetRootModuleArgument defines the value for one variable of the root
   141  	// module. The caller must ensure that given value is a suitable
   142  	// "final value" for the variable, which means that it's already converted
   143  	// and validated to match any configured constraints and validation rules.
   144  	//
   145  	// Calling this function multiple times with the same variable address
   146  	// will silently overwrite the value provided by a previous call.
   147  	SetRootModuleArgument(addrs.InputVariable, cty.Value)
   148  
   149  	// SetModuleCallArgument defines the value for one input variable of a
   150  	// particular child module call. The caller must ensure that the given
   151  	// value is a suitable "final value" for the variable, which means that
   152  	// it's already converted and validated to match any configured
   153  	// constraints and validation rules.
   154  	//
   155  	// Calling this function multiple times with the same variable address
   156  	// will silently overwrite the value provided by a previous call.
   157  	SetModuleCallArgument(addrs.ModuleCallInstance, addrs.InputVariable, cty.Value)
   158  
   159  	// GetVariableValue returns the value provided for the input variable with
   160  	// the given address, or cty.DynamicVal if the variable hasn't been assigned
   161  	// a value yet.
   162  	//
   163  	// Most callers should deal with variable values only indirectly via
   164  	// EvaluationScope and the other expression evaluation functions, but
   165  	// this is provided because variables tend to be evaluated outside of
   166  	// the context of the module they belong to and so we sometimes need to
   167  	// override the normal expression evaluation behavior.
   168  	GetVariableValue(addr addrs.AbsInputVariableInstance) cty.Value
   169  
   170  	// Changes returns the writer object that can be used to write new proposed
   171  	// changes into the global changes set.
   172  	Changes() *plans.ChangesSync
   173  
   174  	// State returns a wrapper object that provides safe concurrent access to
   175  	// the global state.
   176  	State() *states.SyncState
   177  
   178  	// Checks returns the object that tracks the state of any custom checks
   179  	// declared in the configuration.
   180  	Checks() *checks.State
   181  
   182  	// RefreshState returns a wrapper object that provides safe concurrent
   183  	// access to the state used to store the most recently refreshed resource
   184  	// values.
   185  	RefreshState() *states.SyncState
   186  
   187  	// PrevRunState returns a wrapper object that provides safe concurrent
   188  	// access to the state which represents the result of the previous run,
   189  	// updated only so that object data conforms to current schemas for
   190  	// meaningful comparison with RefreshState.
   191  	PrevRunState() *states.SyncState
   192  
   193  	// InstanceExpander returns a helper object for tracking the expansion of
   194  	// graph nodes during the plan phase in response to "count" and "for_each"
   195  	// arguments.
   196  	//
   197  	// The InstanceExpander is a global object that is shared across all of the
   198  	// EvalContext objects for a given configuration.
   199  	InstanceExpander() *instances.Expander
   200  
   201  	// MoveResults returns a map describing the results of handling any
   202  	// resource instance move statements prior to the graph walk, so that
   203  	// the graph walk can then record that information appropriately in other
   204  	// artifacts produced by the graph walk.
   205  	//
   206  	// This data structure is created prior to the graph walk and read-only
   207  	// thereafter, so callers must not modify the returned map or any other
   208  	// objects accessible through it.
   209  	MoveResults() refactoring.MoveResults
   210  
   211  	// ImportResolver returns a helper object for tracking the resolution of
   212  	// imports, after evaluating the dynamic address and ID of the import targets
   213  	//
   214  	// This data is created during the graph walk, as import target addresses are being resolved
   215  	// Its primary use is for validation at the end of a plan - To make sure all imports have been satisfied
   216  	// and have a configuration
   217  	ImportResolver() *ImportResolver
   218  
   219  	// WithPath returns a copy of the context with the internal path set to the
   220  	// path argument.
   221  	WithPath(path addrs.ModuleInstance) EvalContext
   222  
   223  	// Returns the currently configured encryption setup
   224  	GetEncryption() encryption.Encryption
   225  }