Merge pull request #1534 from hashicorp/b-crash-on-output-interpolate

core: don't crash when count.index is used in the wrong context
This commit is contained in:
Paul Hinze 2015-04-15 11:03:37 -05:00
commit 43231b56d2
5 changed files with 72 additions and 0 deletions

View File

@ -290,6 +290,14 @@ func (c *Config) Validate() error {
raw[k] = strVal
}
// Check for invalid count variables
for _, v := range m.RawConfig.Variables {
if _, ok := v.(*CountVariable); ok {
errs = append(errs, fmt.Errorf(
"%s: count variables are only valid within resources", m.Name))
}
}
// Update the raw configuration to only contain the string values
m.RawConfig, err = NewRawConfig(raw)
if err != nil {
@ -472,6 +480,13 @@ func (c *Config) Validate() error {
errs = append(errs, fmt.Errorf(
"%s: output should only have 'value' field", o.Name))
}
for _, v := range o.RawConfig.Variables {
if _, ok := v.(*CountVariable); ok {
errs = append(errs, fmt.Errorf(
"%s: count variables are only valid within resources", o.Name))
}
}
}
// Check that all variables are in the proper context

View File

@ -3,6 +3,7 @@ package config
import (
"path/filepath"
"reflect"
"strings"
"testing"
)
@ -60,6 +61,22 @@ func TestConfigValidate_countInt(t *testing.T) {
}
}
func TestConfigValidate_countBadContext(t *testing.T) {
c := testConfig(t, "validate-count-bad-context")
err := c.Validate()
expected := []string{
"no_count_in_output: count variables are only valid within resources",
"no_count_in_module: count variables are only valid within resources",
}
for _, exp := range expected {
if !strings.Contains(err.Error(), exp) {
t.Fatalf("expected: %q,\nto contain: %q", err, exp)
}
}
}
func TestConfigValidate_countCountVar(t *testing.T) {
c := testConfig(t, "validate-count-count-var")
if err := c.Validate(); err == nil {

View File

@ -0,0 +1,11 @@
resource "aws_instance" "foo" {
}
output "no_count_in_output" {
value = "${count.index}"
}
module "no_count_in_module" {
source = "./child"
somevar = "${count.index}"
}

View File

@ -85,6 +85,9 @@ func (i *Interpolater) valueCountVar(
result map[string]ast.Variable) error {
switch v.Type {
case config.CountValueIndex:
if scope.Resource == nil {
return fmt.Errorf("%s: count.index is only valid within resources", n)
}
result[n] = ast.Variable{
Value: scope.Resource.CountIndex,
Type: ast.TypeInt,

View File

@ -1,6 +1,7 @@
package terraform
import (
"fmt"
"os"
"reflect"
"sync"
@ -24,6 +25,31 @@ func TestInterpolater_countIndex(t *testing.T) {
})
}
func TestInterpolater_countIndexInWrongContext(t *testing.T) {
i := &Interpolater{}
scope := &InterpolationScope{
Path: rootModulePath,
}
n := "count.index"
v, err := config.NewInterpolatedVariable(n)
if err != nil {
t.Fatalf("err: %s", err)
}
expectedErr := fmt.Errorf("foo: count.index is only valid within resources")
_, err = i.Values(scope, map[string]config.InterpolatedVariable{
"foo": v,
})
if !reflect.DeepEqual(expectedErr, err) {
t.Fatalf("expected: %#v, got %#v", expectedErr, err)
}
}
func TestInterpolater_moduleVariable(t *testing.T) {
lock := new(sync.RWMutex)
state := &State{