diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/terraform/evaluate.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/terraform/evaluate.go | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/vendor/github.com/hashicorp/terraform/terraform/evaluate.go b/vendor/github.com/hashicorp/terraform/terraform/evaluate.go index ab65d47..9bb6009 100644 --- a/vendor/github.com/hashicorp/terraform/terraform/evaluate.go +++ b/vendor/github.com/hashicorp/terraform/terraform/evaluate.go | |||
@@ -120,20 +120,24 @@ type InstanceKeyEvalData struct { | |||
120 | 120 | ||
121 | // EvalDataForInstanceKey constructs a suitable InstanceKeyEvalData for | 121 | // EvalDataForInstanceKey constructs a suitable InstanceKeyEvalData for |
122 | // evaluating in a context that has the given instance key. | 122 | // evaluating in a context that has the given instance key. |
123 | func EvalDataForInstanceKey(key addrs.InstanceKey) InstanceKeyEvalData { | 123 | func EvalDataForInstanceKey(key addrs.InstanceKey, forEachMap map[string]cty.Value) InstanceKeyEvalData { |
124 | // At the moment we don't actually implement for_each, so we only | ||
125 | // ever populate CountIndex. | ||
126 | // (When we implement for_each later we may need to reorganize this some, | ||
127 | // so that we can resolve the ambiguity that an int key may either be | ||
128 | // a count.index or an each.key where for_each is over a list.) | ||
129 | |||
130 | var countIdx cty.Value | 124 | var countIdx cty.Value |
125 | var eachKey cty.Value | ||
126 | var eachVal cty.Value | ||
127 | |||
131 | if intKey, ok := key.(addrs.IntKey); ok { | 128 | if intKey, ok := key.(addrs.IntKey); ok { |
132 | countIdx = cty.NumberIntVal(int64(intKey)) | 129 | countIdx = cty.NumberIntVal(int64(intKey)) |
133 | } | 130 | } |
134 | 131 | ||
132 | if stringKey, ok := key.(addrs.StringKey); ok { | ||
133 | eachKey = cty.StringVal(string(stringKey)) | ||
134 | eachVal = forEachMap[string(stringKey)] | ||
135 | } | ||
136 | |||
135 | return InstanceKeyEvalData{ | 137 | return InstanceKeyEvalData{ |
136 | CountIndex: countIdx, | 138 | CountIndex: countIdx, |
139 | EachKey: eachKey, | ||
140 | EachValue: eachVal, | ||
137 | } | 141 | } |
138 | } | 142 | } |
139 | 143 | ||
@@ -173,6 +177,37 @@ func (d *evaluationStateData) GetCountAttr(addr addrs.CountAttr, rng tfdiags.Sou | |||
173 | } | 177 | } |
174 | } | 178 | } |
175 | 179 | ||
180 | func (d *evaluationStateData) GetForEachAttr(addr addrs.ForEachAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) { | ||
181 | var diags tfdiags.Diagnostics | ||
182 | var returnVal cty.Value | ||
183 | switch addr.Name { | ||
184 | |||
185 | case "key": | ||
186 | returnVal = d.InstanceKeyData.EachKey | ||
187 | case "value": | ||
188 | returnVal = d.InstanceKeyData.EachValue | ||
189 | default: | ||
190 | diags = diags.Append(&hcl.Diagnostic{ | ||
191 | Severity: hcl.DiagError, | ||
192 | Summary: `Invalid "each" attribute`, | ||
193 | Detail: fmt.Sprintf(`The "each" object does not have an attribute named %q. The supported attributes are each.key and each.value, the current key and value pair of the "for_each" attribute set.`, addr.Name), | ||
194 | Subject: rng.ToHCL().Ptr(), | ||
195 | }) | ||
196 | return cty.DynamicVal, diags | ||
197 | } | ||
198 | |||
199 | if returnVal == cty.NilVal { | ||
200 | diags = diags.Append(&hcl.Diagnostic{ | ||
201 | Severity: hcl.DiagError, | ||
202 | Summary: `Reference to "each" in context without for_each`, | ||
203 | Detail: fmt.Sprintf(`The "each" object can be used only in "resource" blocks, and only when the "for_each" argument is set.`), | ||
204 | Subject: rng.ToHCL().Ptr(), | ||
205 | }) | ||
206 | return cty.UnknownVal(cty.DynamicPseudoType), diags | ||
207 | } | ||
208 | return returnVal, diags | ||
209 | } | ||
210 | |||
176 | func (d *evaluationStateData) GetInputVariable(addr addrs.InputVariable, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) { | 211 | func (d *evaluationStateData) GetInputVariable(addr addrs.InputVariable, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) { |
177 | var diags tfdiags.Diagnostics | 212 | var diags tfdiags.Diagnostics |
178 | 213 | ||
@@ -569,7 +604,7 @@ func (d *evaluationStateData) GetResourceInstance(addr addrs.ResourceInstance, r | |||
569 | } | 604 | } |
570 | case states.EachMap: | 605 | case states.EachMap: |
571 | multi = key == addrs.NoKey | 606 | multi = key == addrs.NoKey |
572 | if _, ok := addr.Key.(addrs.IntKey); !multi && !ok { | 607 | if _, ok := addr.Key.(addrs.StringKey); !multi && !ok { |
573 | diags = diags.Append(&hcl.Diagnostic{ | 608 | diags = diags.Append(&hcl.Diagnostic{ |
574 | Severity: hcl.DiagError, | 609 | Severity: hcl.DiagError, |
575 | Summary: "Invalid resource index", | 610 | Summary: "Invalid resource index", |
@@ -696,7 +731,7 @@ func (d *evaluationStateData) getResourceInstancesAll(addr addrs.Resource, rng t | |||
696 | ty := schema.ImpliedType() | 731 | ty := schema.ImpliedType() |
697 | key := addrs.IntKey(i) | 732 | key := addrs.IntKey(i) |
698 | is, exists := rs.Instances[key] | 733 | is, exists := rs.Instances[key] |
699 | if exists { | 734 | if exists && is.Current != nil { |
700 | instAddr := addr.Instance(key).Absolute(d.ModulePath) | 735 | instAddr := addr.Instance(key).Absolute(d.ModulePath) |
701 | 736 | ||
702 | // Prefer pending value in plan if present. See getResourceInstanceSingle | 737 | // Prefer pending value in plan if present. See getResourceInstanceSingle |