config: Parsing of data.TYPE.NAME.FIELD variables

This allows ${data.TYPE.NAME.FIELD} interpolation syntax at the
configuration level, though since there is no special handling of them
in the core package this currently just acts as an alias for
${TYPE.NAME.FIELD}.
This commit is contained in:
Martin Atkins 2016-05-01 15:53:42 -07:00
parent 860140074f
commit 718cdda77b
3 changed files with 63 additions and 7 deletions

View File

@ -568,7 +568,7 @@ func (c *Config) Validate() error {
continue
}
id := fmt.Sprintf("%s.%s", rv.Type, rv.Name)
id := rv.ResourceId()
if _, ok := resources[id]; !ok {
errs = append(errs, fmt.Errorf(
"%s: unknown resource '%s' referenced in variable %s",

View File

@ -58,6 +58,7 @@ const (
// A ResourceVariable is a variable that is referencing the field
// of a resource, such as "${aws_instance.foo.ami}"
type ResourceVariable struct {
Mode ResourceMode
Type string // Resource type, i.e. "aws_instance"
Name string // Resource name
Field string // Resource field
@ -171,11 +172,28 @@ func (v *PathVariable) FullKey() string {
}
func NewResourceVariable(key string) (*ResourceVariable, error) {
parts := strings.SplitN(key, ".", 3)
if len(parts) < 3 {
return nil, fmt.Errorf(
"%s: resource variables must be three parts: type.name.attr",
key)
var mode ResourceMode
var parts []string
if strings.HasPrefix(key, "data.") {
mode = DataResourceMode
parts = strings.SplitN(key, ".", 4)
if len(parts) < 4 {
return nil, fmt.Errorf(
"%s: data variables must be four parts: data.TYPE.NAME.ATTR",
key)
}
// Don't actually need the "data." prefix for parsing, since it's
// always constant.
parts = parts[1:]
} else {
mode = ManagedResourceMode
parts = strings.SplitN(key, ".", 3)
if len(parts) < 3 {
return nil, fmt.Errorf(
"%s: resource variables must be three parts: TYPE.NAME.ATTR",
key)
}
}
field := parts[2]
@ -201,6 +219,7 @@ func NewResourceVariable(key string) (*ResourceVariable, error) {
}
return &ResourceVariable{
Mode: mode,
Type: parts[0],
Name: parts[1],
Field: field,
@ -211,7 +230,14 @@ func NewResourceVariable(key string) (*ResourceVariable, error) {
}
func (v *ResourceVariable) ResourceId() string {
return fmt.Sprintf("%s.%s", v.Type, v.Name)
switch v.Mode {
case ManagedResourceMode:
return fmt.Sprintf("%s.%s", v.Type, v.Name)
case DataResourceMode:
return fmt.Sprintf("data.%s.%s", v.Type, v.Name)
default:
panic(fmt.Errorf("unknown resource mode %s", v.Mode))
}
}
func (v *ResourceVariable) FullKey() string {

View File

@ -81,6 +81,9 @@ func TestNewResourceVariable(t *testing.T) {
t.Fatalf("err: %s", err)
}
if v.Mode != ManagedResourceMode {
t.Fatalf("bad: %#v", v)
}
if v.Type != "foo" {
t.Fatalf("bad: %#v", v)
}
@ -99,6 +102,33 @@ func TestNewResourceVariable(t *testing.T) {
}
}
func TestNewResourceVariableData(t *testing.T) {
v, err := NewResourceVariable("data.foo.bar.baz")
if err != nil {
t.Fatalf("err: %s", err)
}
if v.Mode != DataResourceMode {
t.Fatalf("bad: %#v", v)
}
if v.Type != "foo" {
t.Fatalf("bad: %#v", v)
}
if v.Name != "bar" {
t.Fatalf("bad: %#v", v)
}
if v.Field != "baz" {
t.Fatalf("bad: %#v", v)
}
if v.Multi {
t.Fatal("should not be multi")
}
if v.FullKey() != "data.foo.bar.baz" {
t.Fatalf("bad: %#v", v)
}
}
func TestNewUserVariable(t *testing.T) {
v, err := NewUserVariable("var.bar")
if err != nil {