core: pass InstanceKey to EvaluateBlock

This gives us the value we need to evaluate a "count.index" reference, and
later also the equivalent for the "for_each" argument once implemented.
This commit is contained in:
Martin Atkins 2018-05-01 13:40:52 -07:00
parent d4285dd27f
commit d4cfe85361
9 changed files with 24 additions and 16 deletions

View File

@ -302,10 +302,10 @@ func (n *EvalApplyProvisioners) apply(ctx EvalContext, provs []*configs.Provisio
schema := ctx.ProvisionerSchema(prov.Type)
// Evaluate the main provisioner configuration.
config, _, configDiags := ctx.EvaluateBlock(prov.Config, schema, instanceAddr)
config, _, configDiags := ctx.EvaluateBlock(prov.Config, schema, instanceAddr, instanceAddr.Key)
diags = diags.Append(configDiags)
connInfo, _, connInfoDiags := ctx.EvaluateBlock(prov.Config, connectionBlockSupersetSchema, instanceAddr)
connInfo, _, connInfoDiags := ctx.EvaluateBlock(prov.Config, connectionBlockSupersetSchema, instanceAddr, instanceAddr.Key)
diags = diags.Append(connInfoDiags)
if configDiags.HasErrors() || connInfoDiags.HasErrors() {

View File

@ -89,11 +89,17 @@ type EvalContext interface {
// address that the name "self" should behave as an alias for when
// evaluating. Set this to nil if the "self" object should not be available.
//
// The "key" argument is also optional. If given, it is the instance key
// of the current object within the multi-instance container it belongs
// to. For example, on a resource block with "count" set this should be
// set to a different addrs.IntKey for each instance created from that
// block. Set this to addrs.NoKey if not appropriate.
//
// The returned body is an expanded version of the given body, with any
// "dynamic" blocks replaced with zero or more static blocks. This can be
// used to extract correct source location information about attributes of
// the returned object value.
EvaluateBlock(body hcl.Body, schema *configschema.Block, self addrs.Referenceable) (cty.Value, hcl.Body, tfdiags.Diagnostics)
EvaluateBlock(body hcl.Body, schema *configschema.Block, self addrs.Referenceable, key addrs.InstanceKey) (cty.Value, hcl.Body, tfdiags.Diagnostics)
// EvaluateExpr takes the given HCL expression and evaluates it to produce
// a value.

View File

@ -292,9 +292,9 @@ func (ctx *BuiltinEvalContext) CloseProvisioner(n string) error {
return nil
}
func (ctx *BuiltinEvalContext) EvaluateBlock(body hcl.Body, schema *configschema.Block, self addrs.Referenceable) (cty.Value, hcl.Body, tfdiags.Diagnostics) {
func (ctx *BuiltinEvalContext) EvaluateBlock(body hcl.Body, schema *configschema.Block, self addrs.Referenceable, key addrs.InstanceKey) (cty.Value, hcl.Body, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
scope := ctx.Evaluator.Scope(ctx.PathValue, self)
scope := ctx.Evaluator.Scope(ctx.PathValue, self, key)
body, evalDiags := scope.ExpandBlock(body, schema)
diags = diags.Append(evalDiags)
val, evalDiags := scope.EvalBlock(body, schema)
@ -303,7 +303,7 @@ func (ctx *BuiltinEvalContext) EvaluateBlock(body hcl.Body, schema *configschema
}
func (ctx *BuiltinEvalContext) EvaluateExpr(expr hcl.Expression, wantType cty.Type, self addrs.Referenceable) (cty.Value, tfdiags.Diagnostics) {
scope := ctx.Evaluator.Scope(ctx.PathValue, self)
scope := ctx.Evaluator.Scope(ctx.PathValue, self, addrs.NoKey)
return scope.EvalExpr(expr, wantType)
}

View File

@ -78,6 +78,7 @@ type MockEvalContext struct {
EvaluateBlockBody hcl.Body
EvaluateBlockSchema *configschema.Block
EvaluateBlockSelf addrs.Referenceable
EvaluateBlockKey addrs.InstanceKey
EvaluateBlockResult cty.Value
EvaluateBlockExpandedBody hcl.Body
EvaluateBlockDiags tfdiags.Diagnostics
@ -209,11 +210,12 @@ func (c *MockEvalContext) CloseProvisioner(n string) error {
return nil
}
func (c *MockEvalContext) EvaluateBlock(body hcl.Body, schema *configschema.Block, self addrs.Referenceable) (cty.Value, hcl.Body, tfdiags.Diagnostics) {
func (c *MockEvalContext) EvaluateBlock(body hcl.Body, schema *configschema.Block, self addrs.Referenceable, key addrs.InstanceKey) (cty.Value, hcl.Body, tfdiags.Diagnostics) {
c.EvaluateBlockCalled = true
c.EvaluateBlockBody = body
c.EvaluateBlockSchema = schema
c.EvaluateBlockSelf = self
c.EvaluateBlockKey = key
return c.EvaluateBlockResult, c.EvaluateBlockExpandedBody, c.EvaluateBlockDiags
}

View File

@ -129,7 +129,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
// Should be caught during validation, so we don't bother with a pretty error here
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
}
configVal, _, configDiags := ctx.EvaluateBlock(config.Config, schema, nil)
configVal, _, configDiags := ctx.EvaluateBlock(config.Config, schema, nil, n.Addr.Key)
diags = diags.Append(configDiags)
if configDiags.HasErrors() {
return nil, diags.Err()

View File

@ -26,7 +26,7 @@ type EvalConfigBlock struct {
}
func (n *EvalConfigBlock) Eval(ctx EvalContext) (interface{}, error) {
val, body, diags := ctx.EvaluateBlock(*n.Config, n.Schema, n.SelfAddr)
val, body, diags := ctx.EvaluateBlock(*n.Config, n.Schema, n.SelfAddr, addrs.NoKey)
if diags.HasErrors() && n.ContinueOnErr {
log.Printf("[WARN] Block evaluation failed: %s", diags.Err())
return nil, EvalEarlyExitError{}

View File

@ -55,7 +55,7 @@ func (n *EvalConfigProvider) Eval(ctx EvalContext) (interface{}, error) {
configSchema := schema.Provider
configBody := buildProviderConfig(ctx, n.Addr, config.Config)
configVal, configBody, evalDiags := ctx.EvaluateBlock(configBody, configSchema, nil)
configVal, configBody, evalDiags := ctx.EvaluateBlock(configBody, configSchema, nil, addrs.NoKey)
diags = diags.Append(evalDiags)
if evalDiags.HasErrors() {
return nil, diags.NonFatalErr()

View File

@ -60,7 +60,7 @@ func (n *EvalReadDataDiff) Eval(ctx EvalContext) (interface{}, error) {
}
var configDiags tfdiags.Diagnostics
configVal, _, configDiags = ctx.EvaluateBlock(config.Config, schema, nil)
configVal, _, configDiags = ctx.EvaluateBlock(config.Config, schema, nil, n.Addr.Key)
diags = diags.Append(configDiags)
if configDiags.HasErrors() {
return nil, diags.Err()

View File

@ -86,7 +86,7 @@ func (n *EvalValidateProvider) Eval(ctx EvalContext) (interface{}, error) {
configSchema := schema.Provider
configBody := buildProviderConfig(ctx, n.Addr, config.Config)
configVal, configBody, evalDiags := ctx.EvaluateBlock(configBody, configSchema, nil)
configVal, configBody, evalDiags := ctx.EvaluateBlock(configBody, configSchema, nil, addrs.NoKey)
diags = diags.Append(evalDiags)
if evalDiags.HasErrors() {
return nil, diags.NonFatalErr()
@ -136,7 +136,7 @@ func (n *EvalValidateProvisioner) Eval(ctx EvalContext) (interface{}, error) {
{
// Validate the provisioner's own config first
configVal, _, configDiags := ctx.EvaluateBlock(config.Config, schema, n.ResourceAddr)
configVal, _, configDiags := ctx.EvaluateBlock(config.Config, schema, n.ResourceAddr, n.ResourceAddr.Key)
diags = diags.Append(configDiags)
if configDiags.HasErrors() {
return nil, diags.Err()
@ -184,7 +184,7 @@ func (n *EvalValidateProvisioner) validateConnConfig(ctx EvalContext, config *co
// We evaluate here just by evaluating the block and returning any
// diagnostics we get, since evaluation alone is enough to check for
// extraneous arguments and incorrectly-typed arguments.
_, _, configDiags := ctx.EvaluateBlock(config.Config, connectionBlockSupersetSchema, self)
_, _, configDiags := ctx.EvaluateBlock(config.Config, connectionBlockSupersetSchema, self, n.ResourceAddr.Key)
diags = diags.Append(configDiags)
return diags
@ -339,7 +339,7 @@ func (n *EvalValidateResource) Eval(ctx EvalContext) (interface{}, error) {
return nil, diags.Err()
}
configVal, _, valDiags := ctx.EvaluateBlock(cfg.Config, schema, nil)
configVal, _, valDiags := ctx.EvaluateBlock(cfg.Config, schema, nil, n.Addr.Key)
diags = diags.Append(valDiags)
if valDiags.HasErrors() {
return nil, diags.Err()
@ -366,7 +366,7 @@ func (n *EvalValidateResource) Eval(ctx EvalContext) (interface{}, error) {
return nil, diags.Err()
}
configVal, _, valDiags := ctx.EvaluateBlock(cfg.Config, schema, nil)
configVal, _, valDiags := ctx.EvaluateBlock(cfg.Config, schema, nil, n.Addr.Key)
diags = diags.Append(valDiags)
if valDiags.HasErrors() {
return nil, diags.Err()