terraform: evaluation interpolater connect
This commit is contained in:
parent
3908b6319a
commit
de3d9fb9d9
|
@ -30,6 +30,8 @@ type Context2 struct {
|
||||||
module *module.Tree
|
module *module.Tree
|
||||||
providers map[string]ResourceProviderFactory
|
providers map[string]ResourceProviderFactory
|
||||||
state *State
|
state *State
|
||||||
|
stateLock sync.RWMutex
|
||||||
|
variables map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContext creates a new Context structure.
|
// NewContext creates a new Context structure.
|
||||||
|
@ -42,6 +44,7 @@ func NewContext2(opts *ContextOpts) *Context2 {
|
||||||
module: opts.Module,
|
module: opts.Module,
|
||||||
providers: opts.Providers,
|
providers: opts.Providers,
|
||||||
state: opts.State,
|
state: opts.State,
|
||||||
|
variables: opts.Variables,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,8 +74,7 @@ func (c *Context2) Validate() ([]string, []error) {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
evalCtx := c.evalContext()
|
evalCtx := c.evalContext(walkValidate)
|
||||||
evalCtx.ComputeMissing = true
|
|
||||||
|
|
||||||
// Build the graph
|
// Build the graph
|
||||||
graph, err := c.GraphBuilder().Build(RootModulePath)
|
graph, err := c.GraphBuilder().Build(RootModulePath)
|
||||||
|
@ -114,8 +116,17 @@ func (c *Context2) Validate() ([]string, []error) {
|
||||||
return warns, errs
|
return warns, errs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context2) evalContext() *BuiltinEvalContext {
|
func (c *Context2) evalContext(op walkOperation) *BuiltinEvalContext {
|
||||||
return &BuiltinEvalContext{
|
return &BuiltinEvalContext{
|
||||||
|
Path: RootModulePath,
|
||||||
Providers: c.providers,
|
Providers: c.providers,
|
||||||
|
|
||||||
|
Interpolater: &Interpolater{
|
||||||
|
Operation: op,
|
||||||
|
Module: c.module,
|
||||||
|
State: c.state,
|
||||||
|
StateLock: &c.stateLock,
|
||||||
|
Variables: nil,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,6 @@ func TestContext2Validate_requiredVar(t *testing.T) {
|
||||||
if len(w) > 0 {
|
if len(w) > 0 {
|
||||||
t.Fatalf("bad: %#v", w)
|
t.Fatalf("bad: %#v", w)
|
||||||
}
|
}
|
||||||
// TODO: fail
|
|
||||||
if len(e) == 0 {
|
if len(e) == 0 {
|
||||||
t.Fatalf("bad: %s", e)
|
t.Fatalf("bad: %s", e)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,10 @@ type EvalContext interface {
|
||||||
|
|
||||||
// Interpolate takes the given raw configuration and completes
|
// Interpolate takes the given raw configuration and completes
|
||||||
// the interpolations, returning the processed ResourceConfig.
|
// the interpolations, returning the processed ResourceConfig.
|
||||||
Interpolate(*config.RawConfig) (*ResourceConfig, error)
|
//
|
||||||
|
// The resource argument is optional. If given, it is the resource
|
||||||
|
// that is currently being acted upon.
|
||||||
|
Interpolate(*config.RawConfig, *Resource) (*ResourceConfig, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MockEvalContext is a mock version of EvalContext that can be used
|
// MockEvalContext is a mock version of EvalContext that can be used
|
||||||
|
@ -35,6 +38,7 @@ type MockEvalContext struct {
|
||||||
|
|
||||||
InterpolateCalled bool
|
InterpolateCalled bool
|
||||||
InterpolateConfig *config.RawConfig
|
InterpolateConfig *config.RawConfig
|
||||||
|
InterpolateResource *Resource
|
||||||
InterpolateConfigResult *ResourceConfig
|
InterpolateConfigResult *ResourceConfig
|
||||||
InterpolateError error
|
InterpolateError error
|
||||||
}
|
}
|
||||||
|
@ -52,8 +56,9 @@ func (c *MockEvalContext) Provider(n string) ResourceProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MockEvalContext) Interpolate(
|
func (c *MockEvalContext) Interpolate(
|
||||||
config *config.RawConfig) (*ResourceConfig, error) {
|
config *config.RawConfig, resource *Resource) (*ResourceConfig, error) {
|
||||||
c.InterpolateCalled = true
|
c.InterpolateCalled = true
|
||||||
c.InterpolateConfig = config
|
c.InterpolateConfig = config
|
||||||
|
c.InterpolateResource = resource
|
||||||
return c.InterpolateConfigResult, c.InterpolateError
|
return c.InterpolateConfigResult, c.InterpolateError
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,14 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/config"
|
"github.com/hashicorp/terraform/config"
|
||||||
"github.com/hashicorp/terraform/config/lang/ast"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// BuiltinEvalContext is an EvalContext implementation that is used by
|
// BuiltinEvalContext is an EvalContext implementation that is used by
|
||||||
// Terraform by default.
|
// Terraform by default.
|
||||||
type BuiltinEvalContext struct {
|
type BuiltinEvalContext struct {
|
||||||
Providers map[string]ResourceProviderFactory
|
Path []string
|
||||||
ComputeMissing bool
|
Interpolater *Interpolater
|
||||||
|
Providers map[string]ResourceProviderFactory
|
||||||
|
|
||||||
providers map[string]ResourceProvider
|
providers map[string]ResourceProvider
|
||||||
once sync.Once
|
once sync.Once
|
||||||
|
@ -45,42 +45,23 @@ func (ctx *BuiltinEvalContext) Provider(n string) ResourceProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *BuiltinEvalContext) Interpolate(
|
func (ctx *BuiltinEvalContext) Interpolate(
|
||||||
cfg *config.RawConfig) (*ResourceConfig, error) {
|
cfg *config.RawConfig, r *Resource) (*ResourceConfig, error) {
|
||||||
vs := make(map[string]ast.Variable)
|
if cfg != nil {
|
||||||
|
scope := &InterpolationScope{
|
||||||
|
Path: ctx.Path,
|
||||||
|
Resource: r,
|
||||||
|
}
|
||||||
|
vs, err := ctx.Interpolater.Values(scope, cfg.Variables)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// If we don't have a config, use the blank config
|
// Do the interpolation
|
||||||
if cfg == nil {
|
if err := cfg.Interpolate(vs); err != nil {
|
||||||
goto INTERPOLATE_RESULT
|
return nil, err
|
||||||
}
|
|
||||||
|
|
||||||
for n, rawV := range cfg.Variables {
|
|
||||||
switch rawV.(type) {
|
|
||||||
case *config.ModuleVariable:
|
|
||||||
if ctx.ComputeMissing {
|
|
||||||
vs[n] = ast.Variable{
|
|
||||||
Value: config.UnknownVariableValue,
|
|
||||||
Type: ast.TypeString,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case *config.ResourceVariable:
|
|
||||||
if ctx.ComputeMissing {
|
|
||||||
vs[n] = ast.Variable{
|
|
||||||
Value: config.UnknownVariableValue,
|
|
||||||
Type: ast.TypeString,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf(
|
|
||||||
"unknown interpolation type: %#v", rawV)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the interpolation
|
|
||||||
if err := cfg.Interpolate(vs); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERPOLATE_RESULT:
|
|
||||||
result := NewResourceConfig(cfg)
|
result := NewResourceConfig(cfg)
|
||||||
result.interpolateForce()
|
result.interpolateForce()
|
||||||
return result, nil
|
return result, nil
|
||||||
|
|
|
@ -7,7 +7,8 @@ import (
|
||||||
// EvalInterpolate is an EvalNode implementation that takes a raw
|
// EvalInterpolate is an EvalNode implementation that takes a raw
|
||||||
// configuration and interpolates it.
|
// configuration and interpolates it.
|
||||||
type EvalInterpolate struct {
|
type EvalInterpolate struct {
|
||||||
Config *config.RawConfig
|
Config *config.RawConfig
|
||||||
|
Resource *Resource
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *EvalInterpolate) Args() ([]EvalNode, []EvalType) {
|
func (n *EvalInterpolate) Args() ([]EvalNode, []EvalType) {
|
||||||
|
@ -16,7 +17,7 @@ func (n *EvalInterpolate) Args() ([]EvalNode, []EvalType) {
|
||||||
|
|
||||||
func (n *EvalInterpolate) Eval(
|
func (n *EvalInterpolate) Eval(
|
||||||
ctx EvalContext, args []interface{}) (interface{}, error) {
|
ctx EvalContext, args []interface{}) (interface{}, error) {
|
||||||
return ctx.Interpolate(n.Config)
|
return ctx.Interpolate(n.Config, n.Resource)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *EvalInterpolate) Type() EvalType {
|
func (n *EvalInterpolate) Type() EvalType {
|
||||||
|
|
Loading…
Reference in New Issue