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