lang: Data methods now take context.Context

This caused a bunch of mechanical changes to callers, of course. Expression
evaluation is a very cross-cutting concern, so updating everything all at
once would be a lot and so this stops at a mostly-arbitrary point wiring
a bunch of callers to pass in contexts without changing anything that has
lots of callers.

We'll continue pulling on this thread in later commits.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
This commit is contained in:
Martin Atkins
2025-06-17 14:55:20 -07:00
parent 782b817ff9
commit 1380154250
32 changed files with 235 additions and 220 deletions

View File

@@ -75,7 +75,7 @@ func (s staticScopeData) enhanceDiagnostics(ident StaticIdentifier, diags tfdiag
}
// Early check to only allow references we expect in a static context
func (s staticScopeData) StaticValidateReferences(refs []*addrs.Reference, _ addrs.Referenceable, _ addrs.Referenceable) tfdiags.Diagnostics {
func (s staticScopeData) StaticValidateReferences(_ context.Context, refs []*addrs.Reference, _ addrs.Referenceable, _ addrs.Referenceable) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
top := s.stack[len(s.stack)-1]
for _, ref := range refs {
@@ -114,19 +114,19 @@ func (s staticScopeData) StaticValidateReferences(refs []*addrs.Reference, _ add
return diags
}
func (s staticScopeData) GetCountAttr(addrs.CountAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (s staticScopeData) GetCountAttr(context.Context, addrs.CountAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
panic("Not Available in Static Context")
}
func (s staticScopeData) GetForEachAttr(addrs.ForEachAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (s staticScopeData) GetForEachAttr(context.Context, addrs.ForEachAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
panic("Not Available in Static Context")
}
func (s staticScopeData) GetResource(addrs.Resource, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (s staticScopeData) GetResource(context.Context, addrs.Resource, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
panic("Not Available in Static Context")
}
func (s staticScopeData) GetLocalValue(ident addrs.LocalValue, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (s staticScopeData) GetLocalValue(ctx context.Context, ident addrs.LocalValue, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
local, ok := s.eval.cfg.Locals[ident.Name]
@@ -151,15 +151,15 @@ func (s staticScopeData) GetLocalValue(ident addrs.LocalValue, rng tfdiags.Sourc
return cty.DynamicVal, diags
}
val, valDiags := scope.EvalExpr(context.TODO(), local.Expr, cty.DynamicPseudoType)
val, valDiags := scope.EvalExpr(ctx, local.Expr, cty.DynamicPseudoType)
return val, s.enhanceDiagnostics(id, diags.Append(valDiags))
}
func (s staticScopeData) GetModule(addrs.ModuleCall, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (s staticScopeData) GetModule(context.Context, addrs.ModuleCall, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
panic("Not Available in Static Context")
}
func (s staticScopeData) GetPathAttr(addr addrs.PathAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (s staticScopeData) GetPathAttr(_ context.Context, addr addrs.PathAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
// TODO this is copied and trimmed down from tofu/evaluate.go GetPathAttr. Ideally this should be refactored to a common location.
var diags tfdiags.Diagnostics
switch addr.Name {
@@ -208,7 +208,7 @@ func (s staticScopeData) GetPathAttr(addr addrs.PathAttr, rng tfdiags.SourceRang
}
}
func (s staticScopeData) GetTerraformAttr(addr addrs.TerraformAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (s staticScopeData) GetTerraformAttr(_ context.Context, addr addrs.TerraformAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
// TODO this is copied and trimmed down from tofu/evaluate.go GetTerraformAttr. Ideally this should be refactored to a common location.
var diags tfdiags.Diagnostics
switch addr.Name {
@@ -239,7 +239,7 @@ func (s staticScopeData) GetTerraformAttr(addr addrs.TerraformAttr, rng tfdiags.
}
}
func (s staticScopeData) GetInputVariable(ident addrs.InputVariable, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (s staticScopeData) GetInputVariable(_ context.Context, ident addrs.InputVariable, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
variable, ok := s.eval.cfg.Variables[ident.Name]
@@ -376,10 +376,10 @@ func (s staticScopeData) GetInputVariable(ident addrs.InputVariable, rng tfdiags
return val, s.enhanceDiagnostics(id, diags)
}
func (s staticScopeData) GetOutput(addrs.OutputValue, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (s staticScopeData) GetOutput(context.Context, addrs.OutputValue, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
panic("Not Available in Static Context")
}
func (s staticScopeData) GetCheckBlock(addrs.Check, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (s staticScopeData) GetCheckBlock(context.Context, addrs.Check, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
panic("Not Available in Static Context")
}

View File

@@ -199,7 +199,7 @@ func TestStaticScope_GetInputVariable(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
addr := addrs.InputVariable{Name: name}
gotFinalVal, moreDiags := scope.Data.GetInputVariable(addr, tfdiags.SourceRange{Filename: "test.tf"})
gotFinalVal, moreDiags := scope.Data.GetInputVariable(t.Context(), addr, tfdiags.SourceRange{Filename: "test.tf"})
assertNoDiagnostics(t, moreDiags.ToHCL())
if !test.wantFinalVal.RawEquals(gotFinalVal) {
@@ -233,7 +233,7 @@ func TestStaticScope_GetInputVariable(t *testing.T) {
scope := newStaticScope(eval, test_ident)
addr := addrs.InputVariable{Name: "bad_default"}
_, moreDiags := scope.Data.GetInputVariable(addr, tfdiags.SourceRange{Filename: "test.tf"})
_, moreDiags := scope.Data.GetInputVariable(t.Context(), addr, tfdiags.SourceRange{Filename: "test.tf"})
if !moreDiags.HasErrors() {
t.Fatal("unexpected success; want a type conversion error")
}
@@ -271,7 +271,7 @@ func TestStaticScope_GetInputVariable(t *testing.T) {
scope := newStaticScope(eval, test_ident)
addr := addrs.InputVariable{Name: "not_nullable"}
_, moreDiags := scope.Data.GetInputVariable(addr, tfdiags.SourceRange{Filename: "test.tf"})
_, moreDiags := scope.Data.GetInputVariable(t.Context(), addr, tfdiags.SourceRange{Filename: "test.tf"})
if !moreDiags.HasErrors() {
t.Fatal("unexpected success; want an error about the variable being required")
}
@@ -313,7 +313,7 @@ func TestStaticScope_GetLocalValue(t *testing.T) {
scope := newStaticScope(eval, test_ident)
addr := addrs.LocalValue{Name: "foo"}
got, moreDiags := scope.Data.GetLocalValue(addr, tfdiags.SourceRange{Filename: "test.tf"})
got, moreDiags := scope.Data.GetLocalValue(t.Context(), addr, tfdiags.SourceRange{Filename: "test.tf"})
want := cty.StringVal("bar")
assertNoDiagnostics(t, moreDiags.ToHCL())
if !got.RawEquals(want) {
@@ -344,7 +344,7 @@ func TestStaticScope_GetLocalValue(t *testing.T) {
scope := newStaticScope(eval, test_ident)
addr := addrs.LocalValue{Name: "nonexist"}
_, moreDiags := scope.Data.GetLocalValue(addr, tfdiags.SourceRange{Filename: "test.tf"})
_, moreDiags := scope.Data.GetLocalValue(t.Context(), addr, tfdiags.SourceRange{Filename: "test.tf"})
if !moreDiags.HasErrors() {
t.Fatal("unexpected success; want error")
}

View File

@@ -6,6 +6,8 @@
package lang
import (
"context"
"github.com/zclconf/go-cty/cty"
"github.com/opentofu/opentofu/internal/addrs"
@@ -26,16 +28,16 @@ import (
// cases where it's not possible to even determine a suitable result type,
// cty.DynamicVal is returned along with errors describing the problem.
type Data interface {
StaticValidateReferences(refs []*addrs.Reference, self addrs.Referenceable, source addrs.Referenceable) tfdiags.Diagnostics
StaticValidateReferences(ctx context.Context, refs []*addrs.Reference, self addrs.Referenceable, source addrs.Referenceable) tfdiags.Diagnostics
GetCountAttr(addrs.CountAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetForEachAttr(addrs.ForEachAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetResource(addrs.Resource, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetLocalValue(addrs.LocalValue, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetModule(addrs.ModuleCall, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetPathAttr(addrs.PathAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetTerraformAttr(addrs.TerraformAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetInputVariable(addrs.InputVariable, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetOutput(addrs.OutputValue, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetCheckBlock(addrs.Check, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetCountAttr(context.Context, addrs.CountAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetForEachAttr(context.Context, addrs.ForEachAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetResource(context.Context, addrs.Resource, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetLocalValue(context.Context, addrs.LocalValue, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetModule(context.Context, addrs.ModuleCall, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetPathAttr(context.Context, addrs.PathAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetTerraformAttr(context.Context, addrs.TerraformAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetInputVariable(context.Context, addrs.InputVariable, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetOutput(context.Context, addrs.OutputValue, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetCheckBlock(context.Context, addrs.Check, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
}

View File

@@ -6,6 +6,8 @@
package lang
import (
"context"
"github.com/zclconf/go-cty/cty"
"github.com/opentofu/opentofu/internal/addrs"
@@ -27,52 +29,52 @@ type dataForTests struct {
var _ Data = &dataForTests{}
func (d *dataForTests) StaticValidateReferences(refs []*addrs.Reference, self addrs.Referenceable, source addrs.Referenceable) tfdiags.Diagnostics {
func (d *dataForTests) StaticValidateReferences(_ context.Context, refs []*addrs.Reference, self addrs.Referenceable, source addrs.Referenceable) tfdiags.Diagnostics {
return nil // does nothing in this stub implementation
}
func (d *dataForTests) GetCountAttr(addr addrs.CountAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *dataForTests) GetCountAttr(_ context.Context, addr addrs.CountAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
return d.CountAttrs[addr.Name], nil
}
func (d *dataForTests) GetForEachAttr(addr addrs.ForEachAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *dataForTests) GetForEachAttr(_ context.Context, addr addrs.ForEachAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
return d.ForEachAttrs[addr.Name], nil
}
func (d *dataForTests) GetResource(addr addrs.Resource, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *dataForTests) GetResource(_ context.Context, addr addrs.Resource, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
return d.Resources[addr.String()], nil
}
func (d *dataForTests) GetInputVariable(addr addrs.InputVariable, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *dataForTests) GetInputVariable(_ context.Context, addr addrs.InputVariable, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
return d.InputVariables[addr.Name], nil
}
func (d *dataForTests) GetLocalValue(addr addrs.LocalValue, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *dataForTests) GetLocalValue(_ context.Context, addr addrs.LocalValue, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
return d.LocalValues[addr.Name], nil
}
func (d *dataForTests) GetModule(addr addrs.ModuleCall, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *dataForTests) GetModule(_ context.Context, addr addrs.ModuleCall, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
return d.Modules[addr.String()], nil
}
func (d *dataForTests) GetModuleInstanceOutput(addr addrs.ModuleCallInstanceOutput, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *dataForTests) GetModuleInstanceOutput(_ context.Context, addr addrs.ModuleCallInstanceOutput, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
// This will panic if the module object does not have the requested attribute
obj := d.Modules[addr.Call.String()]
return obj.GetAttr(addr.Name), nil
}
func (d *dataForTests) GetPathAttr(addr addrs.PathAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *dataForTests) GetPathAttr(_ context.Context, addr addrs.PathAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
return d.PathAttrs[addr.Name], nil
}
func (d *dataForTests) GetTerraformAttr(addr addrs.TerraformAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *dataForTests) GetTerraformAttr(_ context.Context, addr addrs.TerraformAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
return d.TerraformAttrs[addr.Name], nil
}
func (d *dataForTests) GetOutput(addr addrs.OutputValue, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *dataForTests) GetOutput(_ context.Context, addr addrs.OutputValue, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
return d.OutputValues[addr.Name], nil
}
func (d *dataForTests) GetCheckBlock(addr addrs.Check, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *dataForTests) GetCheckBlock(_ context.Context, addr addrs.Check, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
return d.CheckBlocks[addr.Name], nil
}

View File

@@ -90,7 +90,7 @@ func (s *Scope) EvalBlock(ctx context.Context, body hcl.Body, schema *configsche
// object and instance key data. References to the object must use self, and the
// key data will only contain count.index or each.key. The static values for
// terraform and path will also be available in this context.
func (s *Scope) EvalSelfBlock(body hcl.Body, self cty.Value, schema *configschema.Block, keyData instances.RepetitionData) (cty.Value, tfdiags.Diagnostics) {
func (s *Scope) EvalSelfBlock(ctx context.Context, body hcl.Body, self cty.Value, schema *configschema.Block, keyData instances.RepetitionData) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
spec := schema.DecoderSpec()
@@ -126,12 +126,12 @@ func (s *Scope) EvalSelfBlock(body hcl.Body, self cty.Value, schema *configschem
switch subj := ref.Subject.(type) {
case addrs.PathAttr:
val, valDiags := normalizeRefValue(s.Data.GetPathAttr(subj, ref.SourceRange))
val, valDiags := normalizeRefValue(s.Data.GetPathAttr(ctx, subj, ref.SourceRange))
diags = diags.Append(valDiags)
pathAttrs[subj.Name] = val
case addrs.TerraformAttr:
val, valDiags := normalizeRefValue(s.Data.GetTerraformAttr(subj, ref.SourceRange))
val, valDiags := normalizeRefValue(s.Data.GetTerraformAttr(ctx, subj, ref.SourceRange))
diags = diags.Append(valDiags)
terraformAttrs[subj.Name] = val
@@ -154,13 +154,13 @@ func (s *Scope) EvalSelfBlock(body hcl.Body, self cty.Value, schema *configschem
vals["terraform"] = cty.ObjectVal(terraformAttrs)
vals["tofu"] = cty.ObjectVal(terraformAttrs)
ctx := &hcl.EvalContext{
hclCtx := &hcl.EvalContext{
Variables: vals,
// TODO consider if any provider functions make sense here
Functions: s.Functions(),
}
val, decDiags := hcldec.Decode(body, schema.DecoderSpec(), ctx)
val, decDiags := hcldec.Decode(body, schema.DecoderSpec(), hclCtx)
diags = diags.Append(enhanceFunctionDiags(decDiags))
return val, diags
}
@@ -351,7 +351,7 @@ func (s *Scope) evalContext(ctx context.Context, parent *hcl.EvalContext, refs [
// First we'll do static validation of the references. This catches things
// early that might otherwise not get caught due to unknown values being
// present in the scope during planning.
staticDiags := s.Data.StaticValidateReferences(refs, selfAddr, s.SourceAddr)
staticDiags := s.Data.StaticValidateReferences(ctx, refs, selfAddr, s.SourceAddr)
diags = diags.Append(staticDiags)
if staticDiags.HasErrors() {
return hclCtx, diags
@@ -369,7 +369,7 @@ func (s *Scope) evalContext(ctx context.Context, parent *hcl.EvalContext, refs [
for _, ref := range refs {
if ref.Subject == addrs.Self {
diags.Append(varBuilder.putSelfValue(selfAddr, ref))
diags.Append(varBuilder.putSelfValue(ctx, selfAddr, ref))
continue
}
@@ -387,7 +387,7 @@ func (s *Scope) evalContext(ctx context.Context, parent *hcl.EvalContext, refs [
continue
}
diags = diags.Append(varBuilder.putValueBySubject(ref))
diags = diags.Append(varBuilder.putValueBySubject(ctx, ref))
}
varBuilder.buildAllVariablesInto(hclCtx.Variables)
@@ -430,7 +430,7 @@ func (s *Scope) newEvalVarBuilder() *evalVarBuilder {
}
}
func (b *evalVarBuilder) putSelfValue(selfAddr addrs.Referenceable, ref *addrs.Reference) tfdiags.Diagnostics {
func (b *evalVarBuilder) putSelfValue(ctx context.Context, selfAddr addrs.Referenceable, ref *addrs.Reference) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
if selfAddr == nil {
@@ -457,7 +457,7 @@ func (b *evalVarBuilder) putSelfValue(selfAddr addrs.Referenceable, ref *addrs.R
panic("BUG: self addr must be a resource instance, got " + reflect.TypeOf(selfAddr).String())
}
val, valDiags := normalizeRefValue(b.s.Data.GetResource(subj.ContainingResource(), ref.SourceRange))
val, valDiags := normalizeRefValue(b.s.Data.GetResource(ctx, subj.ContainingResource(), ref.SourceRange))
diags = diags.Append(valDiags)
@@ -480,7 +480,7 @@ func (b *evalVarBuilder) putSelfValue(selfAddr addrs.Referenceable, ref *addrs.R
return diags
}
func (b *evalVarBuilder) putValueBySubject(ref *addrs.Reference) tfdiags.Diagnostics {
func (b *evalVarBuilder) putValueBySubject(ctx context.Context, ref *addrs.Reference) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
rawSubj := ref.Subject
@@ -502,34 +502,34 @@ func (b *evalVarBuilder) putValueBySubject(ref *addrs.Reference) tfdiags.Diagnos
switch subj := rawSubj.(type) {
case addrs.Resource:
diags = diags.Append(b.putResourceValue(subj, rng))
diags = diags.Append(b.putResourceValue(ctx, subj, rng))
case addrs.ModuleCall:
b.wholeModules[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetModule(subj, rng))
b.wholeModules[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetModule(ctx, subj, rng))
case addrs.InputVariable:
b.inputVariables[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetInputVariable(subj, rng))
b.inputVariables[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetInputVariable(ctx, subj, rng))
case addrs.LocalValue:
b.localValues[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetLocalValue(subj, rng))
b.localValues[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetLocalValue(ctx, subj, rng))
case addrs.PathAttr:
b.pathAttrs[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetPathAttr(subj, rng))
b.pathAttrs[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetPathAttr(ctx, subj, rng))
case addrs.TerraformAttr:
b.terraformAttrs[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetTerraformAttr(subj, rng))
b.terraformAttrs[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetTerraformAttr(ctx, subj, rng))
case addrs.CountAttr:
b.countAttrs[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetCountAttr(subj, rng))
b.countAttrs[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetCountAttr(ctx, subj, rng))
case addrs.ForEachAttr:
b.forEachAttrs[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetForEachAttr(subj, rng))
b.forEachAttrs[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetForEachAttr(ctx, subj, rng))
case addrs.OutputValue:
b.outputValues[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetOutput(subj, rng))
b.outputValues[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetOutput(ctx, subj, rng))
case addrs.Check:
b.outputValues[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetCheckBlock(subj, rng))
b.outputValues[subj.Name], normDiags = normalizeRefValue(b.s.Data.GetCheckBlock(ctx, subj, rng))
default:
// Should never happen
@@ -541,7 +541,7 @@ func (b *evalVarBuilder) putValueBySubject(ref *addrs.Reference) tfdiags.Diagnos
return diags
}
func (b *evalVarBuilder) putResourceValue(res addrs.Resource, rng tfdiags.SourceRange) tfdiags.Diagnostics {
func (b *evalVarBuilder) putResourceValue(ctx context.Context, res addrs.Resource, rng tfdiags.SourceRange) tfdiags.Diagnostics {
var into map[string]map[string]cty.Value
switch res.Mode {
@@ -555,7 +555,7 @@ func (b *evalVarBuilder) putResourceValue(res addrs.Resource, rng tfdiags.Source
panic(fmt.Errorf("BUG: got undefined ResourceMode %s", res.Mode))
}
val, diags := normalizeRefValue(b.s.Data.GetResource(res, rng))
val, diags := normalizeRefValue(b.s.Data.GetResource(ctx, res, rng))
if into[res.Type] == nil {
into[res.Type] = make(map[string]cty.Value)

View File

@@ -929,7 +929,7 @@ func TestScopeEvalSelfBlock(t *testing.T) {
ParseRef: addrs.ParseRef,
}
gotVal, ctxDiags := scope.EvalSelfBlock(body, test.Self, schema, test.KeyData)
gotVal, ctxDiags := scope.EvalSelfBlock(t.Context(), body, test.Self, schema, test.KeyData)
if ctxDiags.HasErrors() {
t.Fatal(ctxDiags.Err())
}

View File

@@ -25,7 +25,7 @@ func evalContextProviderFunction(ctx context.Context, provider providers.Interfa
var diags tfdiags.Diagnostics
// First try to look up the function from provider schema
schema := provider.GetProviderSchema(context.TODO())
schema := provider.GetProviderSchema(ctx)
if schema.Diagnostics.HasErrors() {
return nil, schema.Diagnostics
}

View File

@@ -127,7 +127,7 @@ func (ri *ImportResolver) ExpandAndResolveImport(importTarget *ImportTarget, ctx
const tupleAllowed = true
// The import target has a for_each attribute, so we need to expand it
forEachVal, evalDiags := evaluateForEachExpressionValue(importTarget.Config.ForEach, rootCtx, unknownsNotAllowed, tupleAllowed, nil)
forEachVal, evalDiags := evaluateForEachExpressionValue(context.TODO(), importTarget.Config.ForEach, rootCtx, unknownsNotAllowed, tupleAllowed, nil)
diags = diags.Append(evalDiags)
if diags.HasErrors() {
return diags

View File

@@ -33,10 +33,10 @@ import (
//
// If any of the rules do not pass, the returned diagnostics will contain
// errors. Otherwise, it will either be empty or contain only warnings.
func evalCheckRules(typ addrs.CheckRuleType, rules []*configs.CheckRule, ctx EvalContext, self addrs.Checkable, keyData instances.RepetitionData, diagSeverity tfdiags.Severity) tfdiags.Diagnostics {
func evalCheckRules(ctx context.Context, typ addrs.CheckRuleType, rules []*configs.CheckRule, evalCtx EvalContext, self addrs.Checkable, keyData instances.RepetitionData, diagSeverity tfdiags.Severity) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
checkState := ctx.Checks()
checkState := evalCtx.Checks()
if !checkState.ConfigHasChecks(self.ConfigCheckable()) {
// We have nothing to do if this object doesn't have any checks,
// but the "rules" slice should agree that we don't.
@@ -54,7 +54,7 @@ func evalCheckRules(typ addrs.CheckRuleType, rules []*configs.CheckRule, ctx Eva
severity := diagSeverity.ToHCL()
for i, rule := range rules {
result, ruleDiags := evalCheckRule(addrs.NewCheckRule(self, typ, i), rule, ctx, keyData, severity)
result, ruleDiags := evalCheckRule(ctx, addrs.NewCheckRule(self, typ, i), rule, evalCtx, keyData, severity)
diags = diags.Append(ruleDiags)
log.Printf("[TRACE] evalCheckRules: %s status is now %s", self, result.Status)
@@ -73,7 +73,7 @@ type checkResult struct {
FailureMessage string
}
func validateCheckRule(addr addrs.CheckRule, rule *configs.CheckRule, ctx EvalContext, keyData instances.RepetitionData) (string, *hcl.EvalContext, tfdiags.Diagnostics) {
func validateCheckRule(ctx context.Context, addr addrs.CheckRule, rule *configs.CheckRule, evalCtx EvalContext, keyData instances.RepetitionData) (string, *hcl.EvalContext, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
refs, moreDiags := lang.ReferencesInExpr(addrs.ParseRef, rule.Condition)
@@ -102,9 +102,9 @@ func validateCheckRule(addr addrs.CheckRule, rule *configs.CheckRule, ctx EvalCo
panic(fmt.Sprintf("Invalid source reference type %t", addr.Container))
}
}
scope := ctx.EvaluationScope(selfReference, sourceReference, keyData)
scope := evalCtx.EvaluationScope(selfReference, sourceReference, keyData)
hclCtx, moreDiags := scope.EvalContext(context.TODO(), refs)
hclCtx, moreDiags := scope.EvalContext(ctx, refs)
diags = diags.Append(moreDiags)
errorMessage, moreDiags := evalCheckErrorMessage(rule.ErrorMessage, hclCtx)
@@ -113,11 +113,11 @@ func validateCheckRule(addr addrs.CheckRule, rule *configs.CheckRule, ctx EvalCo
return errorMessage, hclCtx, diags
}
func evalCheckRule(addr addrs.CheckRule, rule *configs.CheckRule, ctx EvalContext, keyData instances.RepetitionData, severity hcl.DiagnosticSeverity) (checkResult, tfdiags.Diagnostics) {
func evalCheckRule(ctx context.Context, addr addrs.CheckRule, rule *configs.CheckRule, evalCtx EvalContext, keyData instances.RepetitionData, severity hcl.DiagnosticSeverity) (checkResult, tfdiags.Diagnostics) {
// NOTE: Intentionally not passing the caller's selected severity in here,
// because this reports errors in the configuration itself, not the failure
// of an otherwise-valid condition.
errorMessage, hclCtx, diags := validateCheckRule(addr, rule, ctx, keyData)
errorMessage, hclCtx, diags := validateCheckRule(ctx, addr, rule, evalCtx, keyData)
const errInvalidCondition = "Invalid condition result"

View File

@@ -477,7 +477,7 @@ func (c *BuiltinEvalContext) EvaluationScope(self addrs.Referenceable, source ad
}
var keyDiags tfdiags.Diagnostics
providerKey, keyDiags = resolveProviderModuleInstance(c, providedBy.KeyExpression, moduleInstanceForKey, c.PathValue.String()+" "+pf.String())
providerKey, keyDiags = resolveProviderModuleInstance(ctx, c, providedBy.KeyExpression, moduleInstanceForKey, c.PathValue.String()+" "+pf.String())
if keyDiags.HasErrors() {
return nil, keyDiags
}

View File

@@ -34,7 +34,7 @@ func TestEvaluateCountExpression(t *testing.T) {
t.Run(name, func(t *testing.T) {
ctx := &MockEvalContext{}
ctx.installSimpleEval()
countVal, diags := evaluateCountExpression(test.Expr, ctx, nil)
countVal, diags := evaluateCountExpression(t.Context(), test.Expr, ctx, nil)
if len(diags) != 0 {
t.Errorf("unexpected diagnostics %s", spew.Sdump(diags))

View File

@@ -16,7 +16,7 @@ import (
"github.com/opentofu/opentofu/internal/tfdiags"
)
func evalContextScope(evalCtx EvalContext) evalchecks.ContextFunc {
func evalContextScope(ctx context.Context, evalCtx EvalContext) evalchecks.ContextFunc {
scope := evalCtx.EvaluationScope(nil, nil, EvalDataForNoInstanceKey)
return func(refs []*addrs.Reference) (*hcl.EvalContext, tfdiags.Diagnostics) {
if scope == nil {
@@ -24,28 +24,28 @@ func evalContextScope(evalCtx EvalContext) evalchecks.ContextFunc {
// in unit tests due to incompletely-implemented mocks. :(
return &hcl.EvalContext{}, nil
}
return scope.EvalContext(context.TODO(), refs)
return scope.EvalContext(ctx, refs)
}
}
func evalContextEvaluate(evalCtx EvalContext) evalchecks.EvaluateFunc {
func evalContextEvaluate(ctx context.Context, evalCtx EvalContext) evalchecks.EvaluateFunc {
return func(expr hcl.Expression) (cty.Value, tfdiags.Diagnostics) {
return evalCtx.EvaluateExpr(expr, cty.Number, nil)
}
}
func evaluateForEachExpression(expr hcl.Expression, evalCtx EvalContext, excludeableAddr addrs.Targetable) (map[string]cty.Value, tfdiags.Diagnostics) {
return evalchecks.EvaluateForEachExpression(expr, evalContextScope(evalCtx), excludeableAddr)
func evaluateForEachExpression(ctx context.Context, expr hcl.Expression, evalCtx EvalContext, excludeableAddr addrs.Targetable) (map[string]cty.Value, tfdiags.Diagnostics) {
return evalchecks.EvaluateForEachExpression(expr, evalContextScope(ctx, evalCtx), excludeableAddr)
}
func evaluateForEachExpressionValue(expr hcl.Expression, evalCtx EvalContext, allowUnknown bool, allowTuple bool, excludeableAddr addrs.Targetable) (cty.Value, tfdiags.Diagnostics) {
return evalchecks.EvaluateForEachExpressionValue(expr, evalContextScope(evalCtx), allowUnknown, allowTuple, excludeableAddr)
func evaluateForEachExpressionValue(ctx context.Context, expr hcl.Expression, evalCtx EvalContext, allowUnknown bool, allowTuple bool, excludeableAddr addrs.Targetable) (cty.Value, tfdiags.Diagnostics) {
return evalchecks.EvaluateForEachExpressionValue(expr, evalContextScope(ctx, evalCtx), allowUnknown, allowTuple, excludeableAddr)
}
func evaluateCountExpression(expr hcl.Expression, evalCtx EvalContext, excludeableAddr addrs.Targetable) (int, tfdiags.Diagnostics) {
return evalchecks.EvaluateCountExpression(expr, evalContextEvaluate(evalCtx), excludeableAddr)
func evaluateCountExpression(ctx context.Context, expr hcl.Expression, evalCtx EvalContext, excludeableAddr addrs.Targetable) (int, tfdiags.Diagnostics) {
return evalchecks.EvaluateCountExpression(expr, evalContextEvaluate(ctx, evalCtx), excludeableAddr)
}
func evaluateCountExpressionValue(expr hcl.Expression, evalCtx EvalContext) (cty.Value, tfdiags.Diagnostics) {
return evalchecks.EvaluateCountExpressionValue(expr, evalContextEvaluate(evalCtx))
func evaluateCountExpressionValue(ctx context.Context, expr hcl.Expression, evalCtx EvalContext) (cty.Value, tfdiags.Diagnostics) {
return evalchecks.EvaluateCountExpressionValue(expr, evalContextEvaluate(ctx, evalCtx))
}

View File

@@ -53,24 +53,24 @@ func buildProviderConfig(ctx context.Context, evalCtx EvalContext, addr addrs.Ab
}
}
func resolveProviderResourceInstance(ctx EvalContext, keyExpr hcl.Expression, resourcePath addrs.AbsResourceInstance) (addrs.InstanceKey, tfdiags.Diagnostics) {
keyData := ctx.InstanceExpander().GetResourceInstanceRepetitionData(resourcePath)
keyScope := ctx.EvaluationScope(nil, nil, keyData)
return resolveProviderInstance(keyExpr, keyScope, resourcePath.String())
func resolveProviderResourceInstance(ctx context.Context, evalCtx EvalContext, keyExpr hcl.Expression, resourcePath addrs.AbsResourceInstance) (addrs.InstanceKey, tfdiags.Diagnostics) {
keyData := evalCtx.InstanceExpander().GetResourceInstanceRepetitionData(resourcePath)
keyScope := evalCtx.EvaluationScope(nil, nil, keyData)
return resolveProviderInstance(ctx, keyExpr, keyScope, resourcePath.String())
}
func resolveProviderModuleInstance(ctx EvalContext, keyExpr hcl.Expression, modulePath addrs.ModuleInstance, source string) (addrs.InstanceKey, tfdiags.Diagnostics) {
keyData := ctx.InstanceExpander().GetModuleInstanceRepetitionData(modulePath)
func resolveProviderModuleInstance(ctx context.Context, evalCtx EvalContext, keyExpr hcl.Expression, modulePath addrs.ModuleInstance, source string) (addrs.InstanceKey, tfdiags.Diagnostics) {
keyData := evalCtx.InstanceExpander().GetModuleInstanceRepetitionData(modulePath)
// module providers block is evaluated in the parent module scope, similar to GraphNodeReferenceOutside
evalPath := modulePath.Parent()
keyScope := ctx.WithPath(evalPath).EvaluationScope(nil, nil, keyData)
return resolveProviderInstance(keyExpr, keyScope, source)
keyScope := evalCtx.WithPath(evalPath).EvaluationScope(nil, nil, keyData)
return resolveProviderInstance(ctx, keyExpr, keyScope, source)
}
func resolveProviderInstance(keyExpr hcl.Expression, keyScope *lang.Scope, source string) (addrs.InstanceKey, tfdiags.Diagnostics) {
func resolveProviderInstance(ctx context.Context, keyExpr hcl.Expression, keyScope *lang.Scope, source string) (addrs.InstanceKey, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
keyVal, keyDiags := keyScope.EvalExpr(context.TODO(), keyExpr, cty.DynamicPseudoType)
keyVal, keyDiags := keyScope.EvalExpr(ctx, keyExpr, cty.DynamicPseudoType)
diags = diags.Append(keyDiags)
if keyDiags.HasErrors() {
return nil, diags

View File

@@ -96,7 +96,7 @@ func TestResolveProviderInstance_TypeConversion(t *testing.T) {
BaseDir: ".",
}
// call of the function to test
actualKey, diags := resolveProviderInstance(expr, scope, "test-source")
actualKey, diags := resolveProviderInstance(t.Context(), expr, scope, "test-source")
if diags.HasErrors() {
t.Fatalf("Unexpected error: %s", diags.Err())

View File

@@ -202,14 +202,14 @@ func prepareFinalInputVariableValue(addr addrs.AbsInputVariableInstance, raw *In
// This must be used only after any side-effects that make the value of the
// variable available for use in expression evaluation, such as
// EvalModuleCallArgument for variables in descendent modules.
func evalVariableValidations(addr addrs.AbsInputVariableInstance, config *configs.Variable, expr hcl.Expression, ctx EvalContext) (diags tfdiags.Diagnostics) {
func evalVariableValidations(ctx context.Context, addr addrs.AbsInputVariableInstance, config *configs.Variable, expr hcl.Expression, evalCtx EvalContext) (diags tfdiags.Diagnostics) {
if config == nil || len(config.Validations) == 0 {
log.Printf("[TRACE] evalVariableValidations: no validation rules declared for %s, so skipping", addr)
return nil
}
log.Printf("[TRACE] evalVariableValidations: validating %s", addr)
checkState := ctx.Checks()
checkState := evalCtx.Checks()
if !checkState.ConfigHasChecks(addr.ConfigCheckable()) {
// We have nothing to do if this object doesn't have any checks,
// but the "rules" slice should agree that we don't.
@@ -228,7 +228,7 @@ func evalVariableValidations(addr addrs.AbsInputVariableInstance, config *config
// bypass our usual evaluation machinery here and just produce a minimal
// evaluation context containing just the required value, and thus avoid
// the problem that ctx's evaluation functions refer to the wrong module.
val := ctx.GetVariableValue(addr)
val := evalCtx.GetVariableValue(addr)
if val == cty.NilVal {
diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
@@ -254,7 +254,7 @@ func evalVariableValidations(addr addrs.AbsInputVariableInstance, config *config
continue
}
hclCtx, ctxDiags := ctx.WithPath(addr.Module).EvaluationScope(nil, nil, EvalDataForNoInstanceKey).EvalContext(context.TODO(), append(condRefs, errRefs...))
hclCtx, ctxDiags := evalCtx.WithPath(addr.Module).EvaluationScope(nil, nil, EvalDataForNoInstanceKey).EvalContext(ctx, append(condRefs, errRefs...))
diags = diags.Append(ctxDiags)
if diags.HasErrors() {
continue

View File

@@ -1172,11 +1172,11 @@ func TestEvalVariableValidations_jsonErrorMessageEdgeCase(t *testing.T) {
// Build a mock context to allow the function under test to
// retrieve the variable value and evaluate the expressions
ctx := &MockEvalContext{}
evalCtx := &MockEvalContext{}
// We need a minimal scope to allow basic functions to be passed to
// the HCL scope
ctx.EvaluationScopeScope = &lang.Scope{
evalCtx.EvaluationScopeScope = &lang.Scope{
Data: &evaluationStateData{Evaluator: &Evaluator{
Config: cfg,
VariableValuesLock: &sync.Mutex{},
@@ -1185,21 +1185,21 @@ func TestEvalVariableValidations_jsonErrorMessageEdgeCase(t *testing.T) {
}},
}},
}
ctx.GetVariableValueFunc = func(addr addrs.AbsInputVariableInstance) cty.Value {
evalCtx.GetVariableValueFunc = func(addr addrs.AbsInputVariableInstance) cty.Value {
if got, want := addr.String(), varAddr.String(); got != want {
t.Errorf("incorrect argument to GetVariableValue: got %s, want %s", got, want)
}
return test.given
}
ctx.ChecksState = checks.NewState(cfg)
ctx.ChecksState.ReportCheckableObjects(varAddr.ConfigCheckable(), addrs.MakeSet[addrs.Checkable](varAddr))
evalCtx.ChecksState = checks.NewState(cfg)
evalCtx.ChecksState.ReportCheckableObjects(varAddr.ConfigCheckable(), addrs.MakeSet[addrs.Checkable](varAddr))
gotDiags := evalVariableValidations(
varAddr, varCfg, nil, ctx,
t.Context(), varAddr, varCfg, nil, evalCtx,
)
if ctx.ChecksState.ObjectCheckStatus(varAddr) != test.status {
t.Errorf("expected check result %s but instead %s", test.status, ctx.ChecksState.ObjectCheckStatus(varAddr))
if evalCtx.ChecksState.ObjectCheckStatus(varAddr) != test.status {
t.Errorf("expected check result %s but instead %s", test.status, evalCtx.ChecksState.ObjectCheckStatus(varAddr))
}
if len(test.wantErr) == 0 && len(test.wantWarn) == 0 {
@@ -1333,11 +1333,11 @@ variable "bar" {
// Build a mock context to allow the function under test to
// retrieve the variable value and evaluate the expressions
ctx := &MockEvalContext{}
evalCtx := &MockEvalContext{}
// We need a minimal scope to allow basic functions to be passed to
// the HCL scope
ctx.EvaluationScopeScope = &lang.Scope{
evalCtx.EvaluationScopeScope = &lang.Scope{
Data: &evaluationStateData{Evaluator: &Evaluator{
Config: cfg,
VariableValuesLock: &sync.Mutex{},
@@ -1346,7 +1346,7 @@ variable "bar" {
}},
}},
}
ctx.GetVariableValueFunc = func(addr addrs.AbsInputVariableInstance) cty.Value {
evalCtx.GetVariableValueFunc = func(addr addrs.AbsInputVariableInstance) cty.Value {
if got, want := addr.String(), varAddr.String(); got != want {
t.Errorf("incorrect argument to GetVariableValue: got %s, want %s", got, want)
}
@@ -1356,15 +1356,15 @@ variable "bar" {
// configured sensitivity.
return test.given
}
ctx.ChecksState = checks.NewState(cfg)
ctx.ChecksState.ReportCheckableObjects(varAddr.ConfigCheckable(), addrs.MakeSet[addrs.Checkable](varAddr))
evalCtx.ChecksState = checks.NewState(cfg)
evalCtx.ChecksState.ReportCheckableObjects(varAddr.ConfigCheckable(), addrs.MakeSet[addrs.Checkable](varAddr))
gotDiags := evalVariableValidations(
varAddr, varCfg, nil, ctx,
t.Context(), varAddr, varCfg, nil, evalCtx,
)
if ctx.ChecksState.ObjectCheckStatus(varAddr) != test.status {
t.Errorf("expected check result %s but instead %s", test.status, ctx.ChecksState.ObjectCheckStatus(varAddr))
if evalCtx.ChecksState.ObjectCheckStatus(varAddr) != test.status {
t.Errorf("expected check result %s but instead %s", test.status, evalCtx.ChecksState.ObjectCheckStatus(varAddr))
}
if len(test.wantErr) == 0 {
@@ -1437,7 +1437,7 @@ func TestEvalVariableValidations_sensitiveValueDiagnostics(t *testing.T) {
ctx.ChecksState.ReportCheckableObjects(varAddr.ConfigCheckable(), addrs.MakeSet[addrs.Checkable](varAddr))
gotDiags := evalVariableValidations(
varAddr, cfg.Module.Variables["foo"], nil, ctx,
t.Context(), varAddr, cfg.Module.Variables["foo"], nil, ctx,
)
if !gotDiags.HasErrors() {
t.Fatalf("unexpected success; want validation error")

View File

@@ -111,6 +111,9 @@ type evaluationStateData struct {
Operation walkOperation
}
// evaluationStateData must implement lang.Data
var _ lang.Data = (*evaluationStateData)(nil)
// InstanceKeyEvalData is the old name for instances.RepetitionData, aliased
// here for compatibility. In new code, use instances.RepetitionData instead.
type InstanceKeyEvalData = instances.RepetitionData
@@ -144,10 +147,7 @@ func EvalDataForInstanceKey(key addrs.InstanceKey, forEachMap map[string]cty.Val
// is relevant.
var EvalDataForNoInstanceKey = InstanceKeyEvalData{}
// evaluationStateData must implement lang.Data
var _ lang.Data = (*evaluationStateData)(nil)
func (d *evaluationStateData) GetCountAttr(addr addrs.CountAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *evaluationStateData) GetCountAttr(_ context.Context, addr addrs.CountAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
switch addr.Name {
@@ -175,7 +175,7 @@ func (d *evaluationStateData) GetCountAttr(addr addrs.CountAttr, rng tfdiags.Sou
}
}
func (d *evaluationStateData) GetForEachAttr(addr addrs.ForEachAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *evaluationStateData) GetForEachAttr(_ context.Context, addr addrs.ForEachAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
var returnVal cty.Value
switch addr.Name {
@@ -216,7 +216,7 @@ func (d *evaluationStateData) GetForEachAttr(addr addrs.ForEachAttr, rng tfdiags
return returnVal, diags
}
func (d *evaluationStateData) GetInputVariable(addr addrs.InputVariable, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *evaluationStateData) GetInputVariable(_ context.Context, addr addrs.InputVariable, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
// First we'll make sure the requested value is declared in configuration,
@@ -312,7 +312,7 @@ func (d *evaluationStateData) GetInputVariable(addr addrs.InputVariable, rng tfd
return val, diags
}
func (d *evaluationStateData) GetLocalValue(addr addrs.LocalValue, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *evaluationStateData) GetLocalValue(_ context.Context, addr addrs.LocalValue, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
// First we'll make sure the requested value is declared in configuration,
@@ -353,7 +353,7 @@ func (d *evaluationStateData) GetLocalValue(addr addrs.LocalValue, rng tfdiags.S
return val, diags
}
func (d *evaluationStateData) GetModule(addr addrs.ModuleCall, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *evaluationStateData) GetModule(_ context.Context, addr addrs.ModuleCall, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
// Output results live in the module that declares them, which is one of
// the child module instances of our current module path.
@@ -581,7 +581,7 @@ func (d *evaluationStateData) GetModule(addr addrs.ModuleCall, rng tfdiags.Sourc
return ret, diags
}
func (d *evaluationStateData) GetPathAttr(addr addrs.PathAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *evaluationStateData) GetPathAttr(_ context.Context, addr addrs.PathAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
switch addr.Name {
@@ -650,7 +650,7 @@ func (d *evaluationStateData) GetPathAttr(addr addrs.PathAttr, rng tfdiags.Sourc
}
}
func (d *evaluationStateData) GetResource(addr addrs.Resource, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *evaluationStateData) GetResource(ctx context.Context, addr addrs.Resource, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
// First we'll consult the configuration to see if an resource of this
// name is declared at all.
@@ -677,7 +677,7 @@ func (d *evaluationStateData) GetResource(addr addrs.Resource, rng tfdiags.Sourc
// state available in all cases.
// We need to build an abs provider address, but we can use a default
// instance since we're only interested in the schema.
schema := d.getResourceSchema(addr, config.Provider)
schema := d.getResourceSchema(ctx, addr, config.Provider)
if schema == nil {
// This shouldn't happen, since validation before we get here should've
// taken care of it, but we'll show a reasonable error message anyway.
@@ -924,9 +924,9 @@ func (d *evaluationStateData) GetResource(addr addrs.Resource, rng tfdiags.Sourc
return ret, diags
}
func (d *evaluationStateData) getResourceSchema(addr addrs.Resource, providerAddr addrs.Provider) *configschema.Block {
func (d *evaluationStateData) getResourceSchema(ctx context.Context, addr addrs.Resource, providerAddr addrs.Provider) *configschema.Block {
// TODO: Plumb a useful context.Context through to here.
schema, _, err := d.Evaluator.Plugins.ResourceTypeSchema(context.TODO(), providerAddr, addr.Mode, addr.Type)
schema, _, err := d.Evaluator.Plugins.ResourceTypeSchema(ctx, providerAddr, addr.Mode, addr.Type)
if err != nil {
// We have plenty of other codepaths that will detect and report
// schema lookup errors before we'd reach this point, so we'll just
@@ -936,7 +936,7 @@ func (d *evaluationStateData) getResourceSchema(addr addrs.Resource, providerAdd
return schema
}
func (d *evaluationStateData) GetTerraformAttr(addr addrs.TerraformAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *evaluationStateData) GetTerraformAttr(_ context.Context, addr addrs.TerraformAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
switch addr.Name {
case "workspace":
@@ -966,7 +966,7 @@ func (d *evaluationStateData) GetTerraformAttr(addr addrs.TerraformAttr, rng tfd
}
}
func (d *evaluationStateData) GetOutput(addr addrs.OutputValue, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *evaluationStateData) GetOutput(_ context.Context, addr addrs.OutputValue, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
// First we'll make sure the requested value is declared in configuration,
@@ -1029,7 +1029,7 @@ func (d *evaluationStateData) GetOutput(addr addrs.OutputValue, rng tfdiags.Sour
}
}
func (d *evaluationStateData) GetCheckBlock(addr addrs.Check, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
func (d *evaluationStateData) GetCheckBlock(_ context.Context, addr addrs.Check, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
// For now, check blocks don't contain any meaningful data and can only
// be referenced from the testing scope within an expect_failures attribute.
//

View File

@@ -35,7 +35,7 @@ func TestEvaluatorGetTerraformAttr(t *testing.T) {
t.Run("terraform.workspace", func(t *testing.T) {
want := cty.StringVal("foo")
got, diags := scope.Data.GetTerraformAttr(addrs.NewTerraformAttr("terraform", "workspace"), tfdiags.SourceRange{})
got, diags := scope.Data.GetTerraformAttr(t.Context(), addrs.NewTerraformAttr("terraform", "workspace"), tfdiags.SourceRange{})
if len(diags) != 0 {
t.Errorf("unexpected diagnostics %s", spew.Sdump(diags))
}
@@ -46,7 +46,7 @@ func TestEvaluatorGetTerraformAttr(t *testing.T) {
t.Run("tofu.workspace", func(t *testing.T) {
want := cty.StringVal("foo")
got, diags := scope.Data.GetTerraformAttr(addrs.NewTerraformAttr("tofu", "workspace"), tfdiags.SourceRange{})
got, diags := scope.Data.GetTerraformAttr(t.Context(), addrs.NewTerraformAttr("tofu", "workspace"), tfdiags.SourceRange{})
if len(diags) != 0 {
t.Errorf("unexpected diagnostics %s", spew.Sdump(diags))
}
@@ -74,7 +74,7 @@ func TestEvaluatorGetPathAttr(t *testing.T) {
t.Run("module", func(t *testing.T) {
want := cty.StringVal("bar/baz")
got, diags := scope.Data.GetPathAttr(addrs.PathAttr{
got, diags := scope.Data.GetPathAttr(t.Context(), addrs.PathAttr{
Name: "module",
}, tfdiags.SourceRange{})
if len(diags) != 0 {
@@ -87,7 +87,7 @@ func TestEvaluatorGetPathAttr(t *testing.T) {
t.Run("root", func(t *testing.T) {
want := cty.StringVal("bar/baz")
got, diags := scope.Data.GetPathAttr(addrs.PathAttr{
got, diags := scope.Data.GetPathAttr(t.Context(), addrs.PathAttr{
Name: "root",
}, tfdiags.SourceRange{})
if len(diags) != 0 {
@@ -139,7 +139,7 @@ func TestEvaluatorGetOutputValue(t *testing.T) {
scope := evaluator.Scope(data, nil, nil, nil)
want := cty.StringVal("first").Mark(marks.Sensitive)
got, diags := scope.Data.GetOutput(addrs.OutputValue{
got, diags := scope.Data.GetOutput(t.Context(), addrs.OutputValue{
Name: "some_output",
}, tfdiags.SourceRange{})
@@ -151,7 +151,7 @@ func TestEvaluatorGetOutputValue(t *testing.T) {
}
want = cty.StringVal("second")
got, diags = scope.Data.GetOutput(addrs.OutputValue{
got, diags = scope.Data.GetOutput(t.Context(), addrs.OutputValue{
Name: "some_other_output",
}, tfdiags.SourceRange{})
@@ -206,7 +206,7 @@ func TestEvaluatorGetInputVariable(t *testing.T) {
scope := evaluator.Scope(data, nil, nil, nil)
want := cty.StringVal("bar").Mark(marks.Sensitive)
got, diags := scope.Data.GetInputVariable(addrs.InputVariable{
got, diags := scope.Data.GetInputVariable(t.Context(), addrs.InputVariable{
Name: "some_var",
}, tfdiags.SourceRange{})
@@ -218,7 +218,7 @@ func TestEvaluatorGetInputVariable(t *testing.T) {
}
want = cty.StringVal("boop").Mark(marks.Sensitive)
got, diags = scope.Data.GetInputVariable(addrs.InputVariable{
got, diags = scope.Data.GetInputVariable(t.Context(), addrs.InputVariable{
Name: "some_other_var",
}, tfdiags.SourceRange{})
@@ -391,7 +391,7 @@ func TestEvaluatorGetResource(t *testing.T) {
Type: "test_resource",
Name: "foo",
}
got, diags := scope.Data.GetResource(addr, tfdiags.SourceRange{})
got, diags := scope.Data.GetResource(t.Context(), addr, tfdiags.SourceRange{})
if len(diags) != 0 {
t.Errorf("unexpected diagnostics %s", spew.Sdump(diags))
@@ -532,7 +532,7 @@ func TestEvaluatorGetResource_changes(t *testing.T) {
}).Mark(marks.Sensitive),
})
got, diags := scope.Data.GetResource(addr, tfdiags.SourceRange{})
got, diags := scope.Data.GetResource(t.Context(), addr, tfdiags.SourceRange{})
if len(diags) != 0 {
t.Errorf("unexpected diagnostics %s", spew.Sdump(diags))
@@ -559,7 +559,7 @@ func TestEvaluatorGetModule(t *testing.T) {
}
scope := evaluator.Scope(data, nil, nil, nil)
want := cty.ObjectVal(map[string]cty.Value{"out": cty.StringVal("bar").Mark(marks.Sensitive)})
got, diags := scope.Data.GetModule(addrs.ModuleCall{
got, diags := scope.Data.GetModule(t.Context(), addrs.ModuleCall{
Name: "mod",
}, tfdiags.SourceRange{})
@@ -587,7 +587,7 @@ func TestEvaluatorGetModule(t *testing.T) {
}
scope = evaluator.Scope(data, nil, nil, nil)
want = cty.ObjectVal(map[string]cty.Value{"out": cty.StringVal("baz").Mark(marks.Sensitive)})
got, diags = scope.Data.GetModule(addrs.ModuleCall{
got, diags = scope.Data.GetModule(t.Context(), addrs.ModuleCall{
Name: "mod",
}, tfdiags.SourceRange{})
@@ -605,7 +605,7 @@ func TestEvaluatorGetModule(t *testing.T) {
}
scope = evaluator.Scope(data, nil, nil, nil)
want = cty.ObjectVal(map[string]cty.Value{"out": cty.StringVal("baz").Mark(marks.Sensitive)})
got, diags = scope.Data.GetModule(addrs.ModuleCall{
got, diags = scope.Data.GetModule(t.Context(), addrs.ModuleCall{
Name: "mod",
}, tfdiags.SourceRange{})

View File

@@ -34,16 +34,16 @@ import (
//
// The result may include warning diagnostics if, for example, deprecated
// features are referenced.
func (d *evaluationStateData) StaticValidateReferences(refs []*addrs.Reference, self addrs.Referenceable, source addrs.Referenceable) tfdiags.Diagnostics {
func (d *evaluationStateData) StaticValidateReferences(ctx context.Context, refs []*addrs.Reference, self addrs.Referenceable, source addrs.Referenceable) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
for _, ref := range refs {
moreDiags := d.staticValidateReference(ref, self, source)
moreDiags := d.staticValidateReference(ctx, ref, self, source)
diags = diags.Append(moreDiags)
}
return diags
}
func (d *evaluationStateData) staticValidateReference(ref *addrs.Reference, self addrs.Referenceable, source addrs.Referenceable) tfdiags.Diagnostics {
func (d *evaluationStateData) staticValidateReference(ctx context.Context, ref *addrs.Reference, self addrs.Referenceable, source addrs.Referenceable) tfdiags.Diagnostics {
modCfg := d.Evaluator.Config.DescendentForInstance(d.ModulePath)
if modCfg == nil {
// This is a bug in the caller rather than a problem with the
@@ -83,13 +83,13 @@ func (d *evaluationStateData) staticValidateReference(ref *addrs.Reference, self
// staticValidateMultiResourceReference respectively.
case addrs.Resource:
var diags tfdiags.Diagnostics
diags = diags.Append(d.staticValidateSingleResourceReference(modCfg, addr, ref.Remaining, ref.SourceRange))
diags = diags.Append(d.staticValidateResourceReference(modCfg, addr, source, ref.Remaining, ref.SourceRange))
diags = diags.Append(d.staticValidateSingleResourceReference(ctx, modCfg, addr, ref.Remaining, ref.SourceRange))
diags = diags.Append(d.staticValidateResourceReference(ctx, modCfg, addr, source, ref.Remaining, ref.SourceRange))
return diags
case addrs.ResourceInstance:
var diags tfdiags.Diagnostics
diags = diags.Append(d.staticValidateMultiResourceReference(modCfg, addr, ref.Remaining, ref.SourceRange))
diags = diags.Append(d.staticValidateResourceReference(modCfg, addr.ContainingResource(), source, ref.Remaining, ref.SourceRange))
diags = diags.Append(d.staticValidateMultiResourceReference(ctx, modCfg, addr, ref.Remaining, ref.SourceRange))
diags = diags.Append(d.staticValidateResourceReference(ctx, modCfg, addr.ContainingResource(), source, ref.Remaining, ref.SourceRange))
return diags
// We also handle all module call references the same way, disregarding index.
@@ -121,7 +121,7 @@ func (d *evaluationStateData) staticValidateReference(ref *addrs.Reference, self
}
}
func (d *evaluationStateData) staticValidateSingleResourceReference(modCfg *configs.Config, addr addrs.Resource, remain hcl.Traversal, rng tfdiags.SourceRange) tfdiags.Diagnostics {
func (d *evaluationStateData) staticValidateSingleResourceReference(_ context.Context, modCfg *configs.Config, addr addrs.Resource, remain hcl.Traversal, rng tfdiags.SourceRange) tfdiags.Diagnostics {
// If we have at least one step in "remain" and this resource has
// "count" set then we know for sure this in invalid because we have
// something like:
@@ -166,7 +166,7 @@ func (d *evaluationStateData) staticValidateSingleResourceReference(modCfg *conf
return diags
}
func (d *evaluationStateData) staticValidateMultiResourceReference(modCfg *configs.Config, addr addrs.ResourceInstance, remain hcl.Traversal, rng tfdiags.SourceRange) tfdiags.Diagnostics {
func (d *evaluationStateData) staticValidateMultiResourceReference(ctx context.Context, modCfg *configs.Config, addr addrs.ResourceInstance, remain hcl.Traversal, rng tfdiags.SourceRange) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
cfg := modCfg.Module.ResourceByAddr(addr.ContainingResource())
@@ -178,7 +178,7 @@ func (d *evaluationStateData) staticValidateMultiResourceReference(modCfg *confi
if addr.Key == addrs.NoKey {
// This is a different path into staticValidateSingleResourceReference
return d.staticValidateSingleResourceReference(modCfg, addr.ContainingResource(), remain, rng)
return d.staticValidateSingleResourceReference(ctx, modCfg, addr.ContainingResource(), remain, rng)
} else {
if cfg.Count == nil && cfg.ForEach == nil {
diags = diags.Append(&hcl.Diagnostic{
@@ -193,7 +193,7 @@ func (d *evaluationStateData) staticValidateMultiResourceReference(modCfg *confi
return diags
}
func (d *evaluationStateData) staticValidateResourceReference(modCfg *configs.Config, addr addrs.Resource, source addrs.Referenceable, remain hcl.Traversal, rng tfdiags.SourceRange) tfdiags.Diagnostics {
func (d *evaluationStateData) staticValidateResourceReference(ctx context.Context, modCfg *configs.Config, addr addrs.Resource, source addrs.Referenceable, remain hcl.Traversal, rng tfdiags.SourceRange) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
var modeAdjective string
@@ -240,7 +240,7 @@ func (d *evaluationStateData) staticValidateResourceReference(modCfg *configs.Co
// TODO: Plugin a suitable context.Context through to here.
providerFqn := modCfg.Module.ProviderForLocalConfig(cfg.ProviderConfigAddr())
schema, _, err := d.Evaluator.Plugins.ResourceTypeSchema(context.TODO(), providerFqn, addr.Mode, addr.Type)
schema, _, err := d.Evaluator.Plugins.ResourceTypeSchema(ctx, providerFqn, addr.Mode, addr.Type)
if err != nil {
// Prior validation should've taken care of a schema lookup error,
// so we should never get here but we'll handle it here anyway for

View File

@@ -133,7 +133,7 @@ For example, to correlate with indices of a referring resource, use:
Evaluator: evaluator,
}
diags = data.StaticValidateReferences(refs, nil, test.Src)
diags = data.StaticValidateReferences(t.Context(), refs, nil, test.Src)
if diags.HasErrors() {
if test.WantErr == "" {
t.Fatalf("Unexpected diagnostics: %s", diags.Err())

View File

@@ -151,7 +151,7 @@ func (n *nodeCheckAssert) Path() addrs.ModuleInstance {
return n.addr.Module
}
func (n *nodeCheckAssert) Execute(_ context.Context, evalCtx EvalContext, _ walkOperation) tfdiags.Diagnostics {
func (n *nodeCheckAssert) Execute(ctx context.Context, evalCtx EvalContext, _ walkOperation) tfdiags.Diagnostics {
// We only want to actually execute the checks during specific
// operations, such as plan and applies.
@@ -164,6 +164,7 @@ func (n *nodeCheckAssert) Execute(_ context.Context, evalCtx EvalContext, _ walk
}
return evalCheckRules(
ctx,
addrs.CheckAssertion,
n.config.Asserts,
evalCtx,
@@ -177,7 +178,7 @@ func (n *nodeCheckAssert) Execute(_ context.Context, evalCtx EvalContext, _ walk
// diagnostics if references do not exist etc.
var diags tfdiags.Diagnostics
for ix, assert := range n.config.Asserts {
_, _, moreDiags := validateCheckRule(addrs.NewCheckRule(n.addr, addrs.CheckAssertion, ix), assert, evalCtx, EvalDataForNoInstanceKey)
_, _, moreDiags := validateCheckRule(ctx, addrs.NewCheckRule(n.addr, addrs.CheckAssertion, ix), assert, evalCtx, EvalDataForNoInstanceKey)
diags = diags.Append(moreDiags)
}
return diags

View File

@@ -113,7 +113,7 @@ func (n *nodeExpandModule) ReferenceOutside() (selfPath, referencePath addrs.Mod
}
// GraphNodeExecutable
func (n *nodeExpandModule) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
func (n *nodeExpandModule) Execute(ctx context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
expander := evalCtx.InstanceExpander()
_, call := n.Addr.Call()
@@ -124,7 +124,7 @@ func (n *nodeExpandModule) Execute(_ context.Context, evalCtx EvalContext, op wa
evalCtx = evalCtx.WithPath(module)
switch {
case n.ModuleCall.Count != nil:
count, ctDiags := evaluateCountExpression(n.ModuleCall.Count, evalCtx, module)
count, ctDiags := evaluateCountExpression(ctx, n.ModuleCall.Count, evalCtx, module)
diags = diags.Append(ctDiags)
if diags.HasErrors() {
return diags
@@ -132,7 +132,7 @@ func (n *nodeExpandModule) Execute(_ context.Context, evalCtx EvalContext, op wa
expander.SetModuleCount(module, call, count)
case n.ModuleCall.ForEach != nil:
forEach, feDiags := evaluateForEachExpression(n.ModuleCall.ForEach, evalCtx, module)
forEach, feDiags := evaluateForEachExpression(ctx, n.ModuleCall.ForEach, evalCtx, module)
diags = diags.Append(feDiags)
if diags.HasErrors() {
return diags
@@ -247,7 +247,7 @@ type nodeValidateModule struct {
var _ GraphNodeExecutable = (*nodeValidateModule)(nil)
// GraphNodeEvalable
func (n *nodeValidateModule) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
func (n *nodeValidateModule) Execute(ctx context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
_, call := n.Addr.Call()
expander := evalCtx.InstanceExpander()
@@ -263,17 +263,17 @@ func (n *nodeValidateModule) Execute(_ context.Context, evalCtx EvalContext, op
// a full expansion, presuming these errors will be caught in later steps
switch {
case n.ModuleCall.Count != nil:
_, countDiags := evaluateCountExpressionValue(n.ModuleCall.Count, evalCtx)
_, countDiags := evaluateCountExpressionValue(ctx, n.ModuleCall.Count, evalCtx)
diags = diags.Append(countDiags)
case n.ModuleCall.ForEach != nil:
const unknownsAllowed = true
const tupleNotAllowed = false
_, forEachDiags := evaluateForEachExpressionValue(n.ModuleCall.ForEach, evalCtx, unknownsAllowed, tupleNotAllowed, module)
_, forEachDiags := evaluateForEachExpressionValue(ctx, n.ModuleCall.ForEach, evalCtx, unknownsAllowed, tupleNotAllowed, module)
diags = diags.Append(forEachDiags)
}
diags = diags.Append(validateDependsOn(evalCtx, n.ModuleCall.DependsOn))
diags = diags.Append(validateDependsOn(ctx, evalCtx, n.ModuleCall.DependsOn))
// now set our own mode to single
expander.SetModuleSingle(module, call)

View File

@@ -151,10 +151,10 @@ func (n *nodeModuleVariable) ModulePath() addrs.Module {
}
// GraphNodeExecutable
func (n *nodeModuleVariable) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
func (n *nodeModuleVariable) Execute(ctx context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
log.Printf("[TRACE] nodeModuleVariable: evaluating %s", n.Addr)
val, err := n.evalModuleVariable(evalCtx, op == walkValidate)
val, err := n.evalModuleVariable(ctx, evalCtx, op == walkValidate)
diags = diags.Append(err)
if diags.HasErrors() {
return diags
@@ -190,7 +190,7 @@ func (n *nodeModuleVariable) DotNode(name string, opts *dag.DotOpts) *dag.DotNod
// validateOnly indicates that this evaluation is only for config
// validation, and we will not have any expansion module instance
// repetition data.
func (n *nodeModuleVariable) evalModuleVariable(evalCtx EvalContext, validateOnly bool) (cty.Value, error) {
func (n *nodeModuleVariable) evalModuleVariable(ctx context.Context, evalCtx EvalContext, validateOnly bool) (cty.Value, error) {
var diags tfdiags.Diagnostics
var givenVal cty.Value
var errSourceRange tfdiags.SourceRange
@@ -214,7 +214,7 @@ func (n *nodeModuleVariable) evalModuleVariable(evalCtx EvalContext, validateOnl
}
scope := evalCtx.EvaluationScope(nil, nil, moduleInstanceRepetitionData)
val, moreDiags := scope.EvalExpr(context.TODO(), expr, cty.DynamicPseudoType)
val, moreDiags := scope.EvalExpr(ctx, expr, cty.DynamicPseudoType)
diags = diags.Append(moreDiags)
if moreDiags.HasErrors() {
return cty.DynamicVal, diags.ErrWithWarnings()

View File

@@ -303,7 +303,7 @@ func (n *NodeApplyableOutput) References() []*addrs.Reference {
}
// GraphNodeExecutable
func (n *NodeApplyableOutput) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
func (n *NodeApplyableOutput) Execute(ctx context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
state := evalCtx.State()
if state == nil {
return
@@ -331,6 +331,7 @@ func (n *NodeApplyableOutput) Execute(_ context.Context, evalCtx EvalContext, op
checkRuleSeverity = tfdiags.Warning
}
checkDiags := evalCheckRules(
ctx,
addrs.OutputPrecondition,
n.Config.Preconditions,
evalCtx, n.Addr, EvalDataForNoInstanceKey,
@@ -368,7 +369,7 @@ func (n *NodeApplyableOutput) Execute(_ context.Context, evalCtx EvalContext, op
// We'll handle errors below, after we have loaded the module.
// Outputs don't have a separate mode for validation, so validate
// depends_on expressions here too
diags = diags.Append(validateDependsOn(evalCtx, n.Config.DependsOn))
diags = diags.Append(validateDependsOn(ctx, evalCtx, n.Config.DependsOn))
// For root module outputs in particular, an output value must be
// statically declared as sensitive in order to dynamically return

View File

@@ -506,7 +506,7 @@ func (n *NodeAbstractResource) writeResourceState(evalCtx EvalContext, addr addr
switch {
case n.Config != nil && n.Config.Count != nil:
count, countDiags := evaluateCountExpression(n.Config.Count, evalCtx, addr)
count, countDiags := evaluateCountExpression(context.TODO(), n.Config.Count, evalCtx, addr)
diags = diags.Append(countDiags)
if countDiags.HasErrors() {
return diags
@@ -516,7 +516,7 @@ func (n *NodeAbstractResource) writeResourceState(evalCtx EvalContext, addr addr
expander.SetResourceCount(addr.Module, n.Addr.Resource, count)
case n.Config != nil && n.Config.ForEach != nil:
forEach, forEachDiags := evaluateForEachExpression(n.Config.ForEach, evalCtx, addr)
forEach, forEachDiags := evaluateForEachExpression(context.TODO(), n.Config.ForEach, evalCtx, addr)
diags = diags.Append(forEachDiags)
if forEachDiags.HasErrors() {
return diags

View File

@@ -170,7 +170,7 @@ func (n *NodeAbstractResourceInstance) resolveProvider(ctx context.Context, eval
}
}
if validExpansion {
n.ResolvedProviderKey, diags = resolveProviderResourceInstance(evalCtx, n.Config.ProviderConfigRef.KeyExpression, n.Addr)
n.ResolvedProviderKey, diags = resolveProviderResourceInstance(ctx, evalCtx, n.Config.ProviderConfigRef.KeyExpression, n.Addr)
} else {
useStateFallback = true
}
@@ -194,7 +194,7 @@ func (n *NodeAbstractResourceInstance) resolveProvider(ctx context.Context, eval
}
if validExpansion {
// We can use the standard resolver
n.ResolvedProviderKey, diags = resolveProviderModuleInstance(evalCtx, n.ResolvedProvider.KeyExpression, moduleInstanceForKey, n.Addr.String())
n.ResolvedProviderKey, diags = resolveProviderModuleInstance(ctx, evalCtx, n.ResolvedProvider.KeyExpression, moduleInstanceForKey, n.Addr.String())
} else {
useStateFallback = true
}
@@ -927,11 +927,12 @@ func (n *NodeAbstractResourceInstance) plan(
}
// Evaluate the configuration
forEach, _ := evaluateForEachExpression(n.Config.ForEach, evalCtx, n.Addr)
forEach, _ := evaluateForEachExpression(ctx, n.Config.ForEach, evalCtx, n.Addr)
keyData = EvalDataForInstanceKey(n.ResourceInstanceAddr().Resource.Key, forEach)
checkDiags := evalCheckRules(
ctx,
addrs.ResourcePrecondition,
n.Config.Preconditions,
evalCtx, n.Addr, keyData,
@@ -1825,10 +1826,11 @@ func (n *NodeAbstractResourceInstance) planDataSource(ctx context.Context, evalC
objTy := schema.ImpliedType()
priorVal := cty.NullVal(objTy)
forEach, _ := evaluateForEachExpression(config.ForEach, evalCtx, n.Addr)
forEach, _ := evaluateForEachExpression(ctx, config.ForEach, evalCtx, n.Addr)
keyData = EvalDataForInstanceKey(n.ResourceInstanceAddr().Resource.Key, forEach)
checkDiags := evalCheckRules(
ctx,
addrs.ResourcePrecondition,
n.Config.Preconditions,
evalCtx, n.Addr, keyData,
@@ -2104,10 +2106,11 @@ func (n *NodeAbstractResourceInstance) applyDataSource(ctx context.Context, eval
return nil, keyData, diags
}
forEach, _ := evaluateForEachExpression(config.ForEach, evalCtx, n.Addr)
forEach, _ := evaluateForEachExpression(ctx, config.ForEach, evalCtx, n.Addr)
keyData = EvalDataForInstanceKey(n.Addr.Resource.Key, forEach)
checkDiags := evalCheckRules(
ctx,
addrs.ResourcePrecondition,
n.Config.Preconditions,
evalCtx, n.Addr, keyData,
@@ -2259,14 +2262,14 @@ func filterProvisioners(provisioners []*configs.Provisioner, when configs.Provis
}
// applyProvisioners executes the provisioners for a resource.
func (n *NodeAbstractResourceInstance) applyProvisioners(_ context.Context, evalCtx EvalContext, state *states.ResourceInstanceObject, when configs.ProvisionerWhen, provs []*configs.Provisioner) tfdiags.Diagnostics {
func (n *NodeAbstractResourceInstance) applyProvisioners(ctx context.Context, evalCtx EvalContext, state *states.ResourceInstanceObject, when configs.ProvisionerWhen, provs []*configs.Provisioner) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
// this self is only used for destroy provisioner evaluation, and must
// refer to the last known value of the resource.
self := state.Value
var evalScope func(EvalContext, hcl.Body, cty.Value, *configschema.Block) (cty.Value, tfdiags.Diagnostics)
var evalScope func(context.Context, EvalContext, hcl.Body, cty.Value, *configschema.Block) (cty.Value, tfdiags.Diagnostics)
switch when {
case configs.ProvisionerWhenDestroy:
evalScope = n.evalDestroyProvisionerConfig
@@ -2300,7 +2303,7 @@ func (n *NodeAbstractResourceInstance) applyProvisioners(_ context.Context, eval
return diags
}
config, configDiags := evalScope(evalCtx, prov.Config, self, schema)
config, configDiags := evalScope(ctx, evalCtx, prov.Config, self, schema)
diags = diags.Append(configDiags)
if diags.HasErrors() {
return diags
@@ -2332,7 +2335,7 @@ func (n *NodeAbstractResourceInstance) applyProvisioners(_ context.Context, eval
if connBody != nil {
var connInfoDiags tfdiags.Diagnostics
connInfo, connInfoDiags = evalScope(evalCtx, connBody, self, connectionBlockSupersetSchema)
connInfo, connInfoDiags = evalScope(ctx, evalCtx, connBody, self, connectionBlockSupersetSchema)
diags = diags.Append(connInfoDiags)
if diags.HasErrors() {
return diags
@@ -2417,10 +2420,10 @@ func (n *NodeAbstractResourceInstance) applyProvisioners(_ context.Context, eval
return diags
}
func (n *NodeAbstractResourceInstance) evalProvisionerConfig(evalCtx EvalContext, body hcl.Body, self cty.Value, schema *configschema.Block) (cty.Value, tfdiags.Diagnostics) {
func (n *NodeAbstractResourceInstance) evalProvisionerConfig(ctx context.Context, evalCtx EvalContext, body hcl.Body, self cty.Value, schema *configschema.Block) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
forEach, forEachDiags := evaluateForEachExpression(n.Config.ForEach, evalCtx, n.Addr)
forEach, forEachDiags := evaluateForEachExpression(ctx, n.Config.ForEach, evalCtx, n.Addr)
diags = diags.Append(forEachDiags)
keyData := EvalDataForInstanceKey(n.ResourceInstanceAddr().Resource.Key, forEach)
@@ -2432,7 +2435,7 @@ func (n *NodeAbstractResourceInstance) evalProvisionerConfig(evalCtx EvalContext
}
// during destroy a provisioner can only evaluate within the scope of the parent resource
func (n *NodeAbstractResourceInstance) evalDestroyProvisionerConfig(evalCtx EvalContext, body hcl.Body, self cty.Value, schema *configschema.Block) (cty.Value, tfdiags.Diagnostics) {
func (n *NodeAbstractResourceInstance) evalDestroyProvisionerConfig(ctx context.Context, evalCtx EvalContext, body hcl.Body, self cty.Value, schema *configschema.Block) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
// For a destroy-time provisioner forEach is intentionally nil here,
@@ -2442,7 +2445,7 @@ func (n *NodeAbstractResourceInstance) evalDestroyProvisionerConfig(evalCtx Eval
keyData := EvalDataForInstanceKey(n.ResourceInstanceAddr().Resource.Key, nil)
evalScope := evalCtx.EvaluationScope(n.ResourceInstanceAddr().Resource, nil, keyData)
config, evalDiags := evalScope.EvalSelfBlock(body, self, schema, keyData)
config, evalDiags := evalScope.EvalSelfBlock(ctx, body, self, schema, keyData)
diags = diags.Append(evalDiags)
return config, diags

View File

@@ -231,6 +231,7 @@ func (n *NodeApplyableResourceInstance) dataResourceExecute(ctx context.Context,
// the result of the operation, and to fail on future operations
// until the user makes the condition succeed.
checkDiags := evalCheckRules(
ctx,
addrs.ResourcePostcondition,
n.Config.Postconditions,
evalCtx, n.ResourceInstanceAddr(),
@@ -334,7 +335,7 @@ func (n *NodeApplyableResourceInstance) managedResourceExecute(ctx context.Conte
// If there is no change, there was nothing to apply, and we don't need to
// re-write the state, but we do need to re-evaluate postconditions.
if diffApply.Action == plans.NoOp {
return diags.Append(n.managedResourcePostconditions(evalCtx, repeatData))
return diags.Append(n.managedResourcePostconditions(ctx, evalCtx, repeatData))
}
state, applyDiags := n.apply(ctx, evalCtx, state, diffApply, n.Config, repeatData, n.CreateBeforeDestroy())
@@ -412,12 +413,13 @@ func (n *NodeApplyableResourceInstance) managedResourceExecute(ctx context.Conte
// _after_ writing the state because we want to check against
// the result of the operation, and to fail on future operations
// until the user makes the condition succeed.
return diags.Append(n.managedResourcePostconditions(evalCtx, repeatData))
return diags.Append(n.managedResourcePostconditions(ctx, evalCtx, repeatData))
}
func (n *NodeApplyableResourceInstance) managedResourcePostconditions(evalCtx EvalContext, repeatData instances.RepetitionData) (diags tfdiags.Diagnostics) {
func (n *NodeApplyableResourceInstance) managedResourcePostconditions(ctx context.Context, evalCtx EvalContext, repeatData instances.RepetitionData) (diags tfdiags.Diagnostics) {
checkDiags := evalCheckRules(
ctx,
addrs.ResourcePostcondition,
n.Config.Postconditions,
evalCtx, n.ResourceInstanceAddr(), repeatData,

View File

@@ -196,7 +196,7 @@ func TestNodePlanDeposedResourceInstanceObject_Execute(t *testing.T) {
deposedKey := states.NewDeposedKey()
absResource := mustResourceInstanceAddr(test.nodeAddress)
evalCtx, p := initMockEvalContext(test.nodeAddress, deposedKey)
evalCtx, p := initMockEvalContext(t.Context(), test.nodeAddress, deposedKey)
node := NodePlanDeposedResourceInstanceObject{
NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
@@ -231,7 +231,7 @@ func TestNodeDestroyDeposedResourceInstanceObject_Execute(t *testing.T) {
deposedKey := states.NewDeposedKey()
state := states.NewState()
absResourceAddr := "test_instance.foo"
evalCtx, _ := initMockEvalContext(absResourceAddr, deposedKey)
evalCtx, _ := initMockEvalContext(t.Context(), absResourceAddr, deposedKey)
absResource := mustResourceInstanceAddr(absResourceAddr)
node := NodeDestroyDeposedResourceInstanceObject{
@@ -327,7 +327,7 @@ func TestNodeForgetDeposedResourceInstanceObject_Execute(t *testing.T) {
deposedKey := states.NewDeposedKey()
state := states.NewState()
absResourceAddr := "test_instance.foo"
evalCtx, _ := initMockEvalContext(absResourceAddr, deposedKey)
evalCtx, _ := initMockEvalContext(t.Context(), absResourceAddr, deposedKey)
absResource := mustResourceInstanceAddr(absResourceAddr)
node := NodeForgetDeposedResourceInstanceObject{
@@ -350,7 +350,7 @@ func TestNodeForgetDeposedResourceInstanceObject_Execute(t *testing.T) {
}
}
func initMockEvalContext(resourceAddrs string, deposedKey states.DeposedKey) (*MockEvalContext, *MockProvider) {
func initMockEvalContext(ctx context.Context, resourceAddrs string, deposedKey states.DeposedKey) (*MockEvalContext, *MockProvider) {
state := states.NewState()
absResource := mustResourceInstanceAddr(resourceAddrs)
@@ -385,7 +385,7 @@ func initMockEvalContext(resourceAddrs string, deposedKey states.DeposedKey) (*M
}
p := testProvider("test")
p.ConfigureProvider(context.TODO(), providers.ConfigureProviderRequest{})
p.ConfigureProvider(ctx, providers.ConfigureProviderRequest{})
p.GetProviderSchemaResponse = &schema
p.UpgradeResourceStateResponse = &providers.UpgradeResourceStateResponse{

View File

@@ -435,6 +435,6 @@ func (n *nodeExpandPlannableResource) resourceInstanceSubgraph(ctx context.Conte
Steps: steps,
Name: "nodeExpandPlannableResource",
}
graph, graphDiags := b.Build(context.TODO(), addr.Module)
graph, graphDiags := b.Build(ctx, addr.Module)
return graph, diags.Append(graphDiags).ErrWithWarnings()
}

View File

@@ -172,6 +172,7 @@ func (n *NodePlannableResourceInstance) dataResourceExecute(ctx context.Context,
// the result of the operation, and to fail on future operations
// until the user makes the condition succeed.
checkDiags := evalCheckRules(
ctx,
addrs.ResourcePostcondition,
n.Config.Postconditions,
evalCtx, addr, repeatData,
@@ -412,6 +413,7 @@ func (n *NodePlannableResourceInstance) managedResourceExecute(ctx context.Conte
// (Note that some preconditions will end up being skipped during
// planning, because their conditions depend on values not yet known.)
checkDiags := evalCheckRules(
ctx,
addrs.ResourcePostcondition,
n.Config.Postconditions,
evalCtx, n.ResourceInstanceAddr(), repeatData,
@@ -426,10 +428,11 @@ func (n *NodePlannableResourceInstance) managedResourceExecute(ctx context.Conte
// values, which could result in a post-condition check relying on that
// value being inaccurate. Unless we decide to store the value of the
// for-each expression in state, this is unavoidable.
forEach, _ := evaluateForEachExpression(n.Config.ForEach, evalCtx, n.ResourceAddr())
forEach, _ := evaluateForEachExpression(ctx, n.Config.ForEach, evalCtx, n.ResourceAddr())
repeatData := EvalDataForInstanceKey(n.ResourceInstanceAddr().Resource.Key, forEach)
checkDiags := evalCheckRules(
ctx,
addrs.ResourcePrecondition,
n.Config.Preconditions,
evalCtx, addr, repeatData,
@@ -453,6 +456,7 @@ func (n *NodePlannableResourceInstance) managedResourceExecute(ctx context.Conte
// even if pre-conditions generated diagnostics, because we have no
// planned changes to block.
checkDiags = evalCheckRules(
ctx,
addrs.ResourcePostcondition,
n.Config.Postconditions,
evalCtx, addr, repeatData,

View File

@@ -65,7 +65,7 @@ func (n *NodeValidatableResource) Execute(ctx context.Context, evalCtx EvalConte
diags = diags.Append(n.validateResource(ctx, evalCtx))
diags = diags.Append(n.validateCheckRules(evalCtx, n.Config))
diags = diags.Append(n.validateCheckRules(ctx, evalCtx, n.Config))
if managed := n.Config.Managed; managed != nil {
// Validate all the provisioners
@@ -313,7 +313,7 @@ func (n *NodeValidatableResource) validateResource(ctx context.Context, evalCtx
// Basic type-checking of the count argument. More complete validation
// of this will happen when we DynamicExpand during the plan walk.
countDiags := validateCount(evalCtx, n.Config.Count)
countDiags := validateCount(ctx, evalCtx, n.Config.Count)
diags = diags.Append(countDiags)
case n.Config.ForEach != nil:
@@ -323,11 +323,11 @@ func (n *NodeValidatableResource) validateResource(ctx context.Context, evalCtx
}
// Evaluate the for_each expression here so we can expose the diagnostics
forEachDiags := validateForEach(evalCtx, n.Config.ForEach)
forEachDiags := validateForEach(ctx, evalCtx, n.Config.ForEach)
diags = diags.Append(forEachDiags)
}
diags = diags.Append(validateDependsOn(evalCtx, n.Config.DependsOn))
diags = diags.Append(validateDependsOn(ctx, evalCtx, n.Config.DependsOn))
// Validate the provider_meta block for the provider this resource
// belongs to, if there is one.
@@ -486,7 +486,7 @@ func (n *NodeValidatableResource) validateResource(ctx context.Context, evalCtx
return diags
}
func (n *NodeValidatableResource) evaluateExpr(evalCtx EvalContext, expr hcl.Expression, wantTy cty.Type, self addrs.Referenceable, keyData instances.RepetitionData) (cty.Value, tfdiags.Diagnostics) {
func (n *NodeValidatableResource) evaluateExpr(ctx context.Context, evalCtx EvalContext, expr hcl.Expression, wantTy cty.Type, self addrs.Referenceable, keyData instances.RepetitionData) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
refs, refDiags := lang.ReferencesInExpr(addrs.ParseRef, expr)
@@ -494,7 +494,7 @@ func (n *NodeValidatableResource) evaluateExpr(evalCtx EvalContext, expr hcl.Exp
scope := evalCtx.EvaluationScope(self, nil, keyData)
hclCtx, moreDiags := scope.EvalContext(context.TODO(), refs)
hclCtx, moreDiags := scope.EvalContext(ctx, refs)
diags = diags.Append(moreDiags)
result, hclDiags := expr.Value(hclCtx)
@@ -537,32 +537,32 @@ func (n *NodeValidatableResource) stubRepetitionData(hasCount, hasForEach bool)
return keyData, selfAddr
}
func (n *NodeValidatableResource) validateCheckRules(evalCtx EvalContext, config *configs.Resource) tfdiags.Diagnostics {
func (n *NodeValidatableResource) validateCheckRules(ctx context.Context, evalCtx EvalContext, config *configs.Resource) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
keyData, selfAddr := n.stubRepetitionData(n.Config.Count != nil, n.Config.ForEach != nil)
for _, cr := range config.Preconditions {
_, conditionDiags := n.evaluateExpr(evalCtx, cr.Condition, cty.Bool, nil, keyData)
_, conditionDiags := n.evaluateExpr(ctx, evalCtx, cr.Condition, cty.Bool, nil, keyData)
diags = diags.Append(conditionDiags)
_, errorMessageDiags := n.evaluateExpr(evalCtx, cr.ErrorMessage, cty.Bool, nil, keyData)
_, errorMessageDiags := n.evaluateExpr(ctx, evalCtx, cr.ErrorMessage, cty.Bool, nil, keyData)
diags = diags.Append(errorMessageDiags)
}
for _, cr := range config.Postconditions {
_, conditionDiags := n.evaluateExpr(evalCtx, cr.Condition, cty.Bool, selfAddr, keyData)
_, conditionDiags := n.evaluateExpr(ctx, evalCtx, cr.Condition, cty.Bool, selfAddr, keyData)
diags = diags.Append(conditionDiags)
_, errorMessageDiags := n.evaluateExpr(evalCtx, cr.ErrorMessage, cty.Bool, selfAddr, keyData)
_, errorMessageDiags := n.evaluateExpr(ctx, evalCtx, cr.ErrorMessage, cty.Bool, selfAddr, keyData)
diags = diags.Append(errorMessageDiags)
}
return diags
}
func validateCount(evalCtx EvalContext, expr hcl.Expression) (diags tfdiags.Diagnostics) {
val, countDiags := evaluateCountExpressionValue(expr, evalCtx)
func validateCount(ctx context.Context, evalCtx EvalContext, expr hcl.Expression) (diags tfdiags.Diagnostics) {
val, countDiags := evaluateCountExpressionValue(ctx, expr, evalCtx)
// If the value isn't known then that's the best we can do for now, but
// we'll check more thoroughly during the plan walk
if !val.IsKnown() {
@@ -576,11 +576,11 @@ func validateCount(evalCtx EvalContext, expr hcl.Expression) (diags tfdiags.Diag
return diags
}
func validateForEach(evalCtx EvalContext, expr hcl.Expression) (diags tfdiags.Diagnostics) {
func validateForEach(ctx context.Context, evalCtx EvalContext, expr hcl.Expression) (diags tfdiags.Diagnostics) {
const unknownsAllowed = true
const tupleNotAllowed = false
val, forEachDiags := evaluateForEachExpressionValue(expr, evalCtx, unknownsAllowed, tupleNotAllowed, nil)
val, forEachDiags := evaluateForEachExpressionValue(ctx, expr, evalCtx, unknownsAllowed, tupleNotAllowed, nil)
// If the value isn't known then that's the best we can do for now, but
// we'll check more thoroughly during the plan walk
if !val.IsKnown() {
@@ -592,7 +592,7 @@ func validateForEach(evalCtx EvalContext, expr hcl.Expression) (diags tfdiags.Di
return diags
}
func validateDependsOn(evalCtx EvalContext, dependsOn []hcl.Traversal) (diags tfdiags.Diagnostics) {
func validateDependsOn(ctx context.Context, evalCtx EvalContext, dependsOn []hcl.Traversal) (diags tfdiags.Diagnostics) {
for _, traversal := range dependsOn {
ref, refDiags := addrs.ParseRef(traversal)
diags = diags.Append(refDiags)
@@ -611,7 +611,7 @@ func validateDependsOn(evalCtx EvalContext, dependsOn []hcl.Traversal) (diags tf
if !diags.HasErrors() {
scope := evalCtx.EvaluationScope(nil, nil, EvalDataForNoInstanceKey)
if scope != nil { // sometimes nil in tests, due to incomplete mocks
_, refDiags = scope.EvalReference(context.TODO(), ref, cty.DynamicPseudoType)
_, refDiags = scope.EvalReference(ctx, ref, cty.DynamicPseudoType)
diags = diags.Append(refDiags)
}
}

View File

@@ -154,9 +154,9 @@ func (n *nodeVariableReferenceInstance) ModulePath() addrs.Module {
}
// GraphNodeExecutable
func (n *nodeVariableReferenceInstance) Execute(_ context.Context, evalCtx EvalContext, op walkOperation) tfdiags.Diagnostics {
func (n *nodeVariableReferenceInstance) Execute(ctx context.Context, evalCtx EvalContext, op walkOperation) tfdiags.Diagnostics {
log.Printf("[TRACE] nodeVariableReferenceInstance: evaluating %s", n.Addr)
diags := evalVariableValidations(n.Addr, n.Config, n.Expr, evalCtx)
diags := evalVariableValidations(ctx, n.Addr, n.Config, n.Expr, evalCtx)
if op == walkValidate {
var filtered tfdiags.Diagnostics