diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/terraform/eval_validate_selfref.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/terraform/eval_validate_selfref.go | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/terraform/eval_validate_selfref.go b/vendor/github.com/hashicorp/terraform/terraform/eval_validate_selfref.go new file mode 100644 index 0000000..ae4436a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/terraform/eval_validate_selfref.go | |||
@@ -0,0 +1,74 @@ | |||
1 | package terraform | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | |||
6 | "github.com/hashicorp/terraform/config" | ||
7 | ) | ||
8 | |||
9 | // EvalValidateResourceSelfRef is an EvalNode implementation that validates that | ||
10 | // a configuration doesn't contain a reference to the resource itself. | ||
11 | // | ||
12 | // This must be done prior to interpolating configuration in order to avoid | ||
13 | // any infinite loop scenarios. | ||
14 | type EvalValidateResourceSelfRef struct { | ||
15 | Addr **ResourceAddress | ||
16 | Config **config.RawConfig | ||
17 | } | ||
18 | |||
19 | func (n *EvalValidateResourceSelfRef) Eval(ctx EvalContext) (interface{}, error) { | ||
20 | addr := *n.Addr | ||
21 | conf := *n.Config | ||
22 | |||
23 | // Go through the variables and find self references | ||
24 | var errs []error | ||
25 | for k, raw := range conf.Variables { | ||
26 | rv, ok := raw.(*config.ResourceVariable) | ||
27 | if !ok { | ||
28 | continue | ||
29 | } | ||
30 | |||
31 | // Build an address from the variable | ||
32 | varAddr := &ResourceAddress{ | ||
33 | Path: addr.Path, | ||
34 | Mode: rv.Mode, | ||
35 | Type: rv.Type, | ||
36 | Name: rv.Name, | ||
37 | Index: rv.Index, | ||
38 | InstanceType: TypePrimary, | ||
39 | } | ||
40 | |||
41 | // If the variable access is a multi-access (*), then we just | ||
42 | // match the index so that we'll match our own addr if everything | ||
43 | // else matches. | ||
44 | if rv.Multi && rv.Index == -1 { | ||
45 | varAddr.Index = addr.Index | ||
46 | } | ||
47 | |||
48 | // This is a weird thing where ResourceAddres has index "-1" when | ||
49 | // index isn't set at all. This means index "0" for resource access. | ||
50 | // So, if we have this scenario, just set our varAddr to -1 so it | ||
51 | // matches. | ||
52 | if addr.Index == -1 && varAddr.Index == 0 { | ||
53 | varAddr.Index = -1 | ||
54 | } | ||
55 | |||
56 | // If the addresses match, then this is a self reference | ||
57 | if varAddr.Equals(addr) && varAddr.Index == addr.Index { | ||
58 | errs = append(errs, fmt.Errorf( | ||
59 | "%s: self reference not allowed: %q", | ||
60 | addr, k)) | ||
61 | } | ||
62 | } | ||
63 | |||
64 | // If no errors, no errors! | ||
65 | if len(errs) == 0 { | ||
66 | return nil, nil | ||
67 | } | ||
68 | |||
69 | // Wrap the errors in the proper wrapper so we can handle validation | ||
70 | // formatting properly upstream. | ||
71 | return nil, &EvalValidateError{ | ||
72 | Errors: errs, | ||
73 | } | ||
74 | } | ||