github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/not-internal/terraform/validate_selfref.go (about)

     1  package terraform
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hashicorp/hcl/v2"
     7  
     8  	"github.com/muratcelep/terraform/not-internal/addrs"
     9  	"github.com/muratcelep/terraform/not-internal/configs/configschema"
    10  	"github.com/muratcelep/terraform/not-internal/lang"
    11  	"github.com/muratcelep/terraform/not-internal/tfdiags"
    12  )
    13  
    14  // validateSelfRef checks to ensure that expressions within a particular
    15  // referencable block do not reference that same block.
    16  func validateSelfRef(addr addrs.Referenceable, config hcl.Body, providerSchema *ProviderSchema) tfdiags.Diagnostics {
    17  	var diags tfdiags.Diagnostics
    18  
    19  	addrStrs := make([]string, 0, 1)
    20  	addrStrs = append(addrStrs, addr.String())
    21  	switch tAddr := addr.(type) {
    22  	case addrs.ResourceInstance:
    23  		// A resource instance may not refer to its containing resource either.
    24  		addrStrs = append(addrStrs, tAddr.ContainingResource().String())
    25  	}
    26  
    27  	if providerSchema == nil {
    28  		diags = diags.Append(fmt.Errorf("provider schema unavailable while validating %s for self-references; this is a bug in Terraform and should be reported", addr))
    29  		return diags
    30  	}
    31  
    32  	var schema *configschema.Block
    33  	switch tAddr := addr.(type) {
    34  	case addrs.Resource:
    35  		schema, _ = providerSchema.SchemaForResourceAddr(tAddr)
    36  	case addrs.ResourceInstance:
    37  		schema, _ = providerSchema.SchemaForResourceAddr(tAddr.ContainingResource())
    38  	}
    39  
    40  	if schema == nil {
    41  		diags = diags.Append(fmt.Errorf("no schema available for %s to validate for self-references; this is a bug in Terraform and should be reported", addr))
    42  		return diags
    43  	}
    44  
    45  	refs, _ := lang.ReferencesInBlock(config, schema)
    46  	for _, ref := range refs {
    47  		for _, addrStr := range addrStrs {
    48  			if ref.Subject.String() == addrStr {
    49  				diags = diags.Append(&hcl.Diagnostic{
    50  					Severity: hcl.DiagError,
    51  					Summary:  "Self-referential block",
    52  					Detail:   fmt.Sprintf("Configuration for %s may not refer to itself.", addrStr),
    53  					Subject:  ref.SourceRange.ToHCL().Ptr(),
    54  				})
    55  			}
    56  		}
    57  	}
    58  
    59  	return diags
    60  }