config: parsing of local.foo variables for interpolation
This commit is contained in:
parent
f6797d6cb0
commit
d41d58967f
|
@ -101,6 +101,12 @@ type UserVariable struct {
|
|||
key string
|
||||
}
|
||||
|
||||
// A LocalVariable is a variable that references a local value defined within
|
||||
// the current module, via a "locals" block. This looks like "${local.foo}".
|
||||
type LocalVariable struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func NewInterpolatedVariable(v string) (InterpolatedVariable, error) {
|
||||
if strings.HasPrefix(v, "count.") {
|
||||
return NewCountVariable(v)
|
||||
|
@ -112,6 +118,8 @@ func NewInterpolatedVariable(v string) (InterpolatedVariable, error) {
|
|||
return NewTerraformVariable(v)
|
||||
} else if strings.HasPrefix(v, "var.") {
|
||||
return NewUserVariable(v)
|
||||
} else if strings.HasPrefix(v, "local.") {
|
||||
return NewLocalVariable(v)
|
||||
} else if strings.HasPrefix(v, "module.") {
|
||||
return NewModuleVariable(v)
|
||||
} else if !strings.ContainsRune(v, '.') {
|
||||
|
@ -331,6 +339,25 @@ func (v *UserVariable) GoString() string {
|
|||
return fmt.Sprintf("*%#v", *v)
|
||||
}
|
||||
|
||||
func NewLocalVariable(key string) (*LocalVariable, error) {
|
||||
name := key[len("local."):]
|
||||
if idx := strings.Index(name, "."); idx > -1 {
|
||||
return nil, fmt.Errorf("Can't use dot (.) attribute access in local.%s; use square bracket indexing", name)
|
||||
}
|
||||
|
||||
return &LocalVariable{
|
||||
Name: name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v *LocalVariable) FullKey() string {
|
||||
return fmt.Sprintf("local.%s", v.Name)
|
||||
}
|
||||
|
||||
func (v *LocalVariable) GoString() string {
|
||||
return fmt.Sprintf("*%#v", *v)
|
||||
}
|
||||
|
||||
// DetectVariables takes an AST root and returns all the interpolated
|
||||
// variables that are detected in the AST tree.
|
||||
func DetectVariables(root ast.Node) ([]InterpolatedVariable, error) {
|
||||
|
|
|
@ -9,9 +9,9 @@ import (
|
|||
)
|
||||
|
||||
func TestNewInterpolatedVariable(t *testing.T) {
|
||||
cases := []struct {
|
||||
tests := []struct {
|
||||
Input string
|
||||
Result InterpolatedVariable
|
||||
Want InterpolatedVariable
|
||||
Error bool
|
||||
}{
|
||||
{
|
||||
|
@ -22,6 +22,18 @@ func TestNewInterpolatedVariable(t *testing.T) {
|
|||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"local.foo",
|
||||
&LocalVariable{
|
||||
Name: "foo",
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"local.foo.nope",
|
||||
nil,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"module.foo.bar",
|
||||
&ModuleVariable{
|
||||
|
@ -73,14 +85,19 @@ func TestNewInterpolatedVariable(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
actual, err := NewInterpolatedVariable(tc.Input)
|
||||
if err != nil != tc.Error {
|
||||
t.Fatalf("%d. Error: %s", i, err)
|
||||
for i, test := range tests {
|
||||
t.Run(test.Input, func(t *testing.T) {
|
||||
got, err := NewInterpolatedVariable(test.Input)
|
||||
if err != nil != test.Error {
|
||||
t.Errorf("%d. Error: %s", i, err)
|
||||
}
|
||||
if !reflect.DeepEqual(actual, tc.Result) {
|
||||
t.Fatalf("%d bad: %#v", i, actual)
|
||||
if !test.Error && !reflect.DeepEqual(got, test.Want) {
|
||||
t.Errorf(
|
||||
"wrong result\ninput: %s\ngot: %#v\nwant: %#v",
|
||||
test.Input, got, test.Want,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue