]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/terraform/node_resource_validate.go
Initial transfer of provider code
[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
43 return &NodeValidatableResourceInstance{
44 NodeAbstractResource: a,
45 }
46 }
47
48 // Start creating the steps
49 steps := []GraphTransformer{
50 // Expand the count.
51 &ResourceCountTransformer{
52 Concrete: concreteResource,
53 Count: count,
54 Addr: n.ResourceAddr(),
55 },
56
57 // Attach the state
58 &AttachStateTransformer{State: state},
59
60 // Targeting
61 &TargetsTransformer{ParsedTargets: n.Targets},
62
63 // Connect references so ordering is correct
64 &ReferenceTransformer{},
65
66 // Make sure there is a single root
67 &RootTransformer{},
68 }
69
70 // Build the graph
71 b := &BasicGraphBuilder{
72 Steps: steps,
73 Validate: true,
74 Name: "NodeValidatableResource",
75 }
76
77 return b.Build(ctx.Path())
78 }
79
80 // This represents a _single_ resource instance to validate.
81 type NodeValidatableResourceInstance struct {
82 *NodeAbstractResource
83 }
84
85 // GraphNodeEvalable
86 func (n *NodeValidatableResourceInstance) EvalTree() EvalNode {
87 addr := n.NodeAbstractResource.Addr
88
89 // Build the resource for eval
90 resource := &Resource{
91 Name: addr.Name,
92 Type: addr.Type,
93 CountIndex: addr.Index,
94 }
95 if resource.CountIndex < 0 {
96 resource.CountIndex = 0
97 }
98
99 // Declare a bunch of variables that are used for state during
100 // evaluation. Most of this are written to by-address below.
101 var config *ResourceConfig
102 var provider ResourceProvider
103
104 seq := &EvalSequence{
105 Nodes: []EvalNode{
106 &EvalValidateResourceSelfRef{
107 Addr: &addr,
108 Config: &n.Config.RawConfig,
109 },
110 &EvalGetProvider{
111 Name: n.ProvidedBy()[0],
112 Output: &provider,
113 },
114 &EvalInterpolate{
115 Config: n.Config.RawConfig.Copy(),
116 Resource: resource,
117 Output: &config,
118 },
119 &EvalValidateResource{
120 Provider: &provider,
121 Config: &config,
122 ResourceName: n.Config.Name,
123 ResourceType: n.Config.Type,
124 ResourceMode: n.Config.Mode,
125 },
126 },
127 }
128
129 // Validate all the provisioners
130 for _, p := range n.Config.Provisioners {
131 var provisioner ResourceProvisioner
132 var connConfig *ResourceConfig
133 seq.Nodes = append(
134 seq.Nodes,
135 &EvalGetProvisioner{
136 Name: p.Type,
137 Output: &provisioner,
138 },
139 &EvalInterpolate{
140 Config: p.RawConfig.Copy(),
141 Resource: resource,
142 Output: &config,
143 },
144 &EvalInterpolate{
145 Config: p.ConnInfo.Copy(),
146 Resource: resource,
147 Output: &connConfig,
148 },
149 &EvalValidateProvisioner{
150 Provisioner: &provisioner,
151 Config: &config,
152 ConnConfig: &connConfig,
153 },
154 )
155 }
156
157 return seq
158 }