From 844e1abdd3c6f8c0a56fe5a364c95aaafe4d205e Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Sun, 1 May 2016 18:51:54 -0700 Subject: [PATCH] core: ResourceStateKey understands resource modes Once a data resource gets into the state, the state system needs to be able to parse its id to match it with resources in the configuration. Since data resources live in a separate namespace than managed resources, the extra "mode" discriminator is required to specify which namespace we're talking about, just like we do in the resource configuration. --- terraform/state.go | 27 ++++++++++++++++++++++++--- terraform/state_test.go | 12 ++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/terraform/state.go b/terraform/state.go index 1dc2ed752..6edff0e46 100644 --- a/terraform/state.go +++ b/terraform/state.go @@ -855,6 +855,7 @@ func (m *ModuleState) String() string { type ResourceStateKey struct { Name string Type string + Mode config.ResourceMode Index int } @@ -863,6 +864,9 @@ func (rsk *ResourceStateKey) Equal(other *ResourceStateKey) bool { if rsk == nil || other == nil { return false } + if rsk.Mode != other.Mode { + return false + } if rsk.Type != other.Type { return false } @@ -879,10 +883,19 @@ func (rsk *ResourceStateKey) String() string { if rsk == nil { return "" } - if rsk.Index == -1 { - return fmt.Sprintf("%s.%s", rsk.Type, rsk.Name) + var prefix string + switch rsk.Mode { + case config.ManagedResourceMode: + prefix = "" + case config.DataResourceMode: + prefix = "data." + default: + panic(fmt.Errorf("unknown resource mode %s", rsk.Mode)) } - return fmt.Sprintf("%s.%s.%d", rsk.Type, rsk.Name, rsk.Index) + if rsk.Index == -1 { + return fmt.Sprintf("%s%s.%s", prefix, rsk.Type, rsk.Name) + } + return fmt.Sprintf("%s%s.%s.%d", prefix, rsk.Type, rsk.Name, rsk.Index) } // ParseResourceStateKey accepts a key in the format used by @@ -891,10 +904,18 @@ func (rsk *ResourceStateKey) String() string { // latter case, the index is returned as -1. func ParseResourceStateKey(k string) (*ResourceStateKey, error) { parts := strings.Split(k, ".") + mode := config.ManagedResourceMode + if len(parts) > 0 && parts[0] == "data" { + mode = config.DataResourceMode + // Don't need the constant "data" prefix for parsing + // now that we've figured out the mode. + parts = parts[1:] + } if len(parts) < 2 || len(parts) > 3 { return nil, fmt.Errorf("Malformed resource state key: %s", k) } rsk := &ResourceStateKey{ + Mode: mode, Type: parts[0], Name: parts[1], Index: -1, diff --git a/terraform/state_test.go b/terraform/state_test.go index a51b670b7..5c45c16e4 100644 --- a/terraform/state_test.go +++ b/terraform/state_test.go @@ -1501,6 +1501,7 @@ func TestParseResourceStateKey(t *testing.T) { { Input: "aws_instance.foo.3", Expected: &ResourceStateKey{ + Mode: config.ManagedResourceMode, Type: "aws_instance", Name: "foo", Index: 3, @@ -1509,6 +1510,7 @@ func TestParseResourceStateKey(t *testing.T) { { Input: "aws_instance.foo.0", Expected: &ResourceStateKey{ + Mode: config.ManagedResourceMode, Type: "aws_instance", Name: "foo", Index: 0, @@ -1517,11 +1519,21 @@ func TestParseResourceStateKey(t *testing.T) { { Input: "aws_instance.foo", Expected: &ResourceStateKey{ + Mode: config.ManagedResourceMode, Type: "aws_instance", Name: "foo", Index: -1, }, }, + { + Input: "data.aws_ami.foo", + Expected: &ResourceStateKey{ + Mode: config.DataResourceMode, + Type: "aws_ami", + Name: "foo", + Index: -1, + }, + }, { Input: "aws_instance.foo.malformed", ExpectedErr: true,