]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/terraform/node_resource_validate.go
0df223d9ea491913791c8260be7cc6fa3f277d8a
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / terraform / node_resource_validate.go
1 package terraform
2
3 import (
4 "github.com/hashicorp/terraform/dag"
5 )
6
7 // NodeValidatableResource represents a resource that is used for validation
8 // only.
9 type NodeValidatableResource struct {
10 *NodeAbstractCountResource
11 }
12
13 // GraphNodeEvalable
14 func (n *NodeValidatableResource) EvalTree() EvalNode {
15 // Ensure we're validating
16 c := n.NodeAbstractCountResource
17 c.Validate = true
18 return c.EvalTree()
19 }
20
21 // GraphNodeDynamicExpandable
22 func (n *NodeValidatableResource) DynamicExpand(ctx EvalContext) (*Graph, error) {
23 // Grab the state which we read
24 state, lock := ctx.State()
25 lock.RLock()
26 defer lock.RUnlock()
27
28 // Expand the resource count which must be available by now from EvalTree
29 count := 1
30 if n.Config.RawCount.Value() != unknownValue() {
31 var err error
32 count, err = n.Config.Count()
33 if err != nil {
34 return nil, err
35 }
36 }
37
38 // The concrete resource factory we'll use
39 concreteResource := func(a *NodeAbstractResource) dag.Vertex {
40 // Add the config and state since we don't do that via transforms
41 a.Config = n.Config
42 a.ResolvedProvider = n.ResolvedProvider
43
44 return &NodeValidatableResourceInstance{
45 NodeAbstractResource: a,
46 }
47 }
48
49 // Start creating the steps
50 steps := []GraphTransformer{
51 // Expand the count.
52 &ResourceCountTransformer{
53 Concrete: concreteResource,
54 Count: count,
55 Addr: n.ResourceAddr(),
56 },
57
58 // Attach the state
59 &AttachStateTransformer{State: state},
60
61 // Targeting
62 &TargetsTransformer{ParsedTargets: n.Targets},
63
64 // Connect references so ordering is correct
65 &ReferenceTransformer{},
66
67 // Make sure there is a single root
68 &RootTransformer{},
69 }
70
71 // Build the graph
72 b := &BasicGraphBuilder{
73 Steps: steps,
74 Validate: true,
75 Name: "NodeValidatableResource",
76 }
77
78 return b.Build(ctx.Path())
79 }
80
81 // This represents a _single_ resource instance to validate.
82 type NodeValidatableResourceInstance struct {
83 *NodeAbstractResource
84 }
85
86 // GraphNodeEvalable
87 func (n *NodeValidatableResourceInstance) EvalTree() EvalNode {
88 addr := n.NodeAbstractResource.Addr
89
90 // Build the resource for eval
91 resource := &Resource{
92 Name: addr.Name,
93 Type: addr.Type,
94 CountIndex: addr.Index,
95 }
96 if resource.CountIndex < 0 {
97 resource.CountIndex = 0
98 }
99
100 // Declare a bunch of variables that are used for state during
101 // evaluation. Most of this are written to by-address below.
102 var config *ResourceConfig
103 var provider ResourceProvider
104
105 seq := &EvalSequence{
106 Nodes: []EvalNode{
107 &EvalValidateResourceSelfRef{
108 Addr: &addr,
109 Config: &n.Config.RawConfig,
110 },
111 &EvalGetProvider{
112 Name: n.ResolvedProvider,
113 Output: &provider,
114 },
115 &EvalInterpolate{
116 Config: n.Config.RawConfig.Copy(),
117 Resource: resource,
118 Output: &config,
119 },
120 &EvalValidateResource{
121 Provider: &provider,
122 Config: &config,
123 ResourceName: n.Config.Name,
124 ResourceType: n.Config.Type,
125 ResourceMode: n.Config.Mode,
126 },
127 },
128 }
129
130 // Validate all the provisioners
131 for _, p := range n.Config.Provisioners {
132 var provisioner ResourceProvisioner
133 var connConfig *ResourceConfig
134 seq.Nodes = append(
135 seq.Nodes,
136 &EvalGetProvisioner{
137 Name: p.Type,
138 Output: &provisioner,
139 },
140 &EvalInterpolate{
141 Config: p.RawConfig.Copy(),
142 Resource: resource,
143 Output: &config,
144 },
145 &EvalInterpolate{
146 Config: p.ConnInfo.Copy(),
147 Resource: resource,
148 Output: &connConfig,
149 },
150 &EvalValidateProvisioner{
151 Provisioner: &provisioner,
152 Config: &config,
153 ConnConfig: &connConfig,
154 },
155 )
156 }
157
158 return seq
159 }