]>
Commit | Line | Data |
---|---|---|
bae9f6d2 JC |
1 | package terraform |
2 | ||
3 | import ( | |
4 | "log" | |
107c1cdb ND |
5 | |
6 | "github.com/hashicorp/terraform/tfdiags" | |
bae9f6d2 JC |
7 | ) |
8 | ||
9 | // EvalNode is the interface that must be implemented by graph nodes to | |
10 | // evaluate/execute. | |
11 | type EvalNode interface { | |
12 | // Eval evaluates this node with the given context. The second parameter | |
13 | // are the argument values. These will match in order and 1-1 with the | |
14 | // results of the Args() return value. | |
15 | Eval(EvalContext) (interface{}, error) | |
16 | } | |
17 | ||
18 | // GraphNodeEvalable is the interface that graph nodes must implement | |
19 | // to enable valuation. | |
20 | type GraphNodeEvalable interface { | |
21 | EvalTree() EvalNode | |
22 | } | |
23 | ||
24 | // EvalEarlyExitError is a special error return value that can be returned | |
25 | // by eval nodes that does an early exit. | |
26 | type EvalEarlyExitError struct{} | |
27 | ||
28 | func (EvalEarlyExitError) Error() string { return "early exit" } | |
29 | ||
30 | // Eval evaluates the given EvalNode with the given context, properly | |
31 | // evaluating all args in the correct order. | |
32 | func Eval(n EvalNode, ctx EvalContext) (interface{}, error) { | |
33 | // Call the lower level eval which doesn't understand early exit, | |
34 | // and if we early exit, it isn't an error. | |
35 | result, err := EvalRaw(n, ctx) | |
36 | if err != nil { | |
37 | if _, ok := err.(EvalEarlyExitError); ok { | |
38 | return nil, nil | |
39 | } | |
40 | } | |
41 | ||
42 | return result, err | |
43 | } | |
44 | ||
45 | // EvalRaw is like Eval except that it returns all errors, even if they | |
46 | // signal something normal such as EvalEarlyExitError. | |
47 | func EvalRaw(n EvalNode, ctx EvalContext) (interface{}, error) { | |
48 | path := "unknown" | |
49 | if ctx != nil { | |
107c1cdb ND |
50 | path = ctx.Path().String() |
51 | } | |
52 | if path == "" { | |
53 | path = "<root>" | |
bae9f6d2 JC |
54 | } |
55 | ||
15c0b25d | 56 | log.Printf("[TRACE] %s: eval: %T", path, n) |
bae9f6d2 JC |
57 | output, err := n.Eval(ctx) |
58 | if err != nil { | |
107c1cdb ND |
59 | switch err.(type) { |
60 | case EvalEarlyExitError: | |
61 | log.Printf("[TRACE] %s: eval: %T, early exit err: %s", path, n, err) | |
62 | case tfdiags.NonFatalError: | |
63 | log.Printf("[WARN] %s: eval: %T, non-fatal err: %s", path, n, err) | |
64 | default: | |
bae9f6d2 JC |
65 | log.Printf("[ERROR] %s: eval: %T, err: %s", path, n, err) |
66 | } | |
67 | } | |
68 | ||
69 | return output, err | |
70 | } |