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