github.com/skyscape-cloud-services/terraform@v0.9.2-0.20170609144644-7ece028a1747/terraform/eval_validate_selfref.go (about) 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 }