terraform: parse internal resource addresses used in state/diff
This commit is contained in:
parent
50afee2a30
commit
361bc5a8df
|
@ -85,6 +85,37 @@ func (r *ResourceAddress) String() string {
|
|||
return strings.Join(result, ".")
|
||||
}
|
||||
|
||||
// parseResourceAddressInternal parses the somewhat bespoke resource
|
||||
// identifier used in states and diffs, such as "instance.name.0".
|
||||
func parseResourceAddressInternal(s string) (*ResourceAddress, error) {
|
||||
// Split based on ".". Every resource address should have at least two
|
||||
// elements (type and name).
|
||||
parts := strings.Split(s, ".")
|
||||
if len(parts) < 2 || len(parts) > 3 {
|
||||
return nil, fmt.Errorf("Invalid internal resource address format: %s", s)
|
||||
}
|
||||
|
||||
// Build the parts of the resource address that are guaranteed to exist
|
||||
addr := &ResourceAddress{
|
||||
Type: parts[0],
|
||||
Name: parts[1],
|
||||
Index: -1,
|
||||
InstanceType: TypePrimary,
|
||||
}
|
||||
|
||||
// If we have more parts, then we have an index. Parse that.
|
||||
if len(parts) > 2 {
|
||||
idx, err := strconv.ParseInt(parts[2], 0, 0)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error parsing resource address %q: %s", s, err)
|
||||
}
|
||||
|
||||
addr.Index = int(idx)
|
||||
}
|
||||
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
func ParseResourceAddress(s string) (*ResourceAddress, error) {
|
||||
matches, err := tokenizeResourceAddress(s)
|
||||
if err != nil {
|
||||
|
|
|
@ -7,6 +7,66 @@ import (
|
|||
"github.com/hashicorp/terraform/config"
|
||||
)
|
||||
|
||||
func TestParseResourceAddressInternal(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Input string
|
||||
Expected *ResourceAddress
|
||||
Output string
|
||||
}{
|
||||
"basic resource": {
|
||||
"aws_instance.foo",
|
||||
&ResourceAddress{
|
||||
Mode: config.ManagedResourceMode,
|
||||
Type: "aws_instance",
|
||||
Name: "foo",
|
||||
InstanceType: TypePrimary,
|
||||
Index: -1,
|
||||
},
|
||||
"aws_instance.foo",
|
||||
},
|
||||
|
||||
"basic resource with count": {
|
||||
"aws_instance.foo.1",
|
||||
&ResourceAddress{
|
||||
Mode: config.ManagedResourceMode,
|
||||
Type: "aws_instance",
|
||||
Name: "foo",
|
||||
InstanceType: TypePrimary,
|
||||
Index: 1,
|
||||
},
|
||||
"aws_instance.foo[1]",
|
||||
},
|
||||
}
|
||||
|
||||
for tn, tc := range cases {
|
||||
t.Run(tc.Input, func(t *testing.T) {
|
||||
out, err := parseResourceAddressInternal(tc.Input)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: unexpected err: %#v", tn, err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(out, tc.Expected) {
|
||||
t.Fatalf("bad: %q\n\nexpected:\n%#v\n\ngot:\n%#v", tn, tc.Expected, out)
|
||||
}
|
||||
|
||||
// Compare outputs if those exist
|
||||
expected := tc.Input
|
||||
if tc.Output != "" {
|
||||
expected = tc.Output
|
||||
}
|
||||
if out.String() != expected {
|
||||
t.Fatalf("bad: %q\n\nexpected: %s\n\ngot: %s", tn, expected, out)
|
||||
}
|
||||
|
||||
// Compare equality because the internal parse is used
|
||||
// to compare equality to equal inputs.
|
||||
if !out.Equals(tc.Expected) {
|
||||
t.Fatalf("expected equality:\n\n%#v\n\n%#v", out, tc.Expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseResourceAddress(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Input string
|
||||
|
|
Loading…
Reference in New Issue