core: ResourceAddress.HasResourceSpec method

The resource address documentation defines a resource address as being in
two parts: the module path and the resource spec. The resource spec can
be omitted, which represents addressing _all_ resources in a module.

In some cases (such as import) it doesn't make sense to address an entire
module, so this helper makes it easy for validation code to check for
this to reject insufficiently-specific resource addresses.
This commit is contained in:
Martin Atkins 2017-05-16 18:01:52 -07:00
parent 044ad5ef59
commit 05a5eb0047
2 changed files with 66 additions and 0 deletions

View File

@ -89,6 +89,15 @@ func (r *ResourceAddress) String() string {
return strings.Join(result, ".")
}
// HasResourceSpec returns true if the address has a resource spec, as
// defined in the documentation:
// https://www.terraform.io/docs/internals/resource-addressing.html
// In particular, this returns false if the address contains only
// a module path, thus addressing the entire module.
func (r *ResourceAddress) HasResourceSpec() bool {
return r.Type != "" && r.Name != ""
}
// stateId returns the ID that this resource should be entered with
// in the state. This is also used for diffs. In the future, we'd like to
// move away from this string field so I don't export this.

View File

@ -628,3 +628,60 @@ func TestResourceAddressStateId(t *testing.T) {
})
}
}
func TestResourceAddressHasResourceSpec(t *testing.T) {
cases := []struct {
Input string
Want bool
}{
{
"module.foo",
false,
},
{
"module.foo.module.bar",
false,
},
{
"null_resource.baz",
true,
},
{
"null_resource.baz[0]",
true,
},
{
"data.null_data_source.baz",
true,
},
{
"data.null_data_source.baz[0]",
true,
},
{
"module.foo.null_resource.baz",
true,
},
{
"module.foo.data.null_data_source.baz",
true,
},
{
"module.foo.module.bar.null_resource.baz",
true,
},
}
for _, test := range cases {
t.Run(test.Input, func(t *testing.T) {
addr, err := ParseResourceAddress(test.Input)
if err != nil {
t.Fatalf("error parsing address: %s", err)
}
got := addr.HasResourceSpec()
if got != test.Want {
t.Fatalf("%q: wrong result %#v; want %#v", test.Input, got, test.Want)
}
})
}
}