terraform: Eval
This commit is contained in:
parent
d59ced3c57
commit
012d68923c
|
@ -22,3 +22,20 @@ type EvalNode interface {
|
|||
type GraphNodeEvalable interface {
|
||||
EvalTree() EvalNode
|
||||
}
|
||||
|
||||
// Eval evaluates the given EvalNode with the given context, properly
|
||||
// evaluating all args in the correct order.
|
||||
func Eval(n EvalNode, ctx EvalContext) (interface{}, error) {
|
||||
argNodes, _ := n.Args()
|
||||
args := make([]interface{}, len(argNodes))
|
||||
for i, n := range argNodes {
|
||||
v, err := Eval(n, ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
args[i] = v
|
||||
}
|
||||
|
||||
return n.Eval(ctx, args)
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/hashicorp/terraform/config"
|
||||
"github.com/hashicorp/terraform/config/lang/ast"
|
||||
)
|
||||
|
||||
// BuiltinEvalContext is an EvalContext implementation that is used by
|
||||
// Terraform by default.
|
||||
type BuiltinEvalContext struct {
|
||||
Providers map[string]ResourceProviderFactory
|
||||
ComputeMissing bool
|
||||
|
||||
providers map[string]ResourceProvider
|
||||
once sync.Once
|
||||
|
@ -37,9 +39,45 @@ func (ctx *BuiltinEvalContext) Provider(n string) ResourceProvider {
|
|||
}
|
||||
|
||||
func (ctx *BuiltinEvalContext) Interpolate(
|
||||
config *config.RawConfig) (*ResourceConfig, error) {
|
||||
// TODO: Actual interpolation, for now we just return it as-is
|
||||
return NewResourceConfig(config), nil
|
||||
cfg *config.RawConfig) (*ResourceConfig, error) {
|
||||
vs := make(map[string]ast.Variable)
|
||||
|
||||
// If we don't have a config, use the blank config
|
||||
if cfg == nil {
|
||||
goto INTERPOLATE_RESULT
|
||||
}
|
||||
|
||||
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.interpolateForce()
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (ctx *BuiltinEvalContext) init() {
|
||||
|
|
|
@ -7,3 +7,48 @@ import (
|
|||
func TestMockEvalContext_impl(t *testing.T) {
|
||||
var _ EvalContext = new(MockEvalContext)
|
||||
}
|
||||
|
||||
func TestEval(t *testing.T) {
|
||||
n := &testEvalAdd{
|
||||
Items: []EvalNode{
|
||||
&EvalLiteral{Value: 10},
|
||||
&EvalLiteral{Value: 32},
|
||||
},
|
||||
}
|
||||
|
||||
result, err := Eval(n, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if result != 42 {
|
||||
t.Fatalf("bad: %#v", result)
|
||||
}
|
||||
}
|
||||
|
||||
type testEvalAdd struct {
|
||||
Items []EvalNode
|
||||
}
|
||||
|
||||
func (n *testEvalAdd) Args() ([]EvalNode, []EvalType) {
|
||||
types := make([]EvalType, len(n.Items))
|
||||
for i, _ := range n.Items {
|
||||
types[i] = EvalTypeInvalid
|
||||
}
|
||||
|
||||
return n.Items, types
|
||||
}
|
||||
|
||||
func (n *testEvalAdd) Eval(
|
||||
ctx EvalContext, args []interface{}) (interface{}, error) {
|
||||
result := 0
|
||||
for _, arg := range args {
|
||||
result += arg.(int)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (n *testEvalAdd) Type() EvalType {
|
||||
return EvalTypeInvalid
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ var RootModulePath = []string{RootModuleName}
|
|||
type Graph struct {
|
||||
// Graph is the actual DAG. This is embedded so you can call the DAG
|
||||
// methods directly.
|
||||
*dag.Graph
|
||||
dag.AcyclicGraph
|
||||
|
||||
// Path is the path in the module tree that this Graph represents.
|
||||
// The root is represented by a single element list containing
|
||||
|
@ -112,10 +112,6 @@ func (g *Graph) Dependable(n string) dag.Vertex {
|
|||
}
|
||||
|
||||
func (g *Graph) init() {
|
||||
if g.Graph == nil {
|
||||
g.Graph = new(dag.Graph)
|
||||
}
|
||||
|
||||
if g.dependableMap == nil {
|
||||
g.dependableMap = make(map[string]dag.Vertex)
|
||||
}
|
||||
|
|
|
@ -226,3 +226,12 @@ func (c *ResourceConfig) interpolate(
|
|||
c.Config = c.raw.Config()
|
||||
return nil
|
||||
}
|
||||
|
||||
// interpolateForce is a temporary thing. We want to get rid of interpolate
|
||||
// above and likewise this, but it can only be done after the f-ast-graph
|
||||
// refactor is complete.
|
||||
func (c *ResourceConfig) interpolateForce() {
|
||||
c.ComputedKeys = c.raw.UnknownKeys()
|
||||
c.Raw = c.raw.Raw
|
||||
c.Config = c.raw.Config()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue