github.com/trawler/terraform@v0.10.8-0.20171106022149-4b1c7a1d9b48/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  }