diff --git a/terraform/state_add.go b/terraform/state_add.go index 74fa62255..b837e8f57 100644 --- a/terraform/state_add.go +++ b/terraform/state_add.go @@ -97,6 +97,10 @@ func stateAddFunc_Module_Module(s *State, addr *ResourceAddress, raw interface{} func stateAddFunc_Resource_Resource(s *State, addr *ResourceAddress, raw interface{}) error { src := raw.(*ResourceState) + // Initialize the resource + resource := stateAddInitAddr(s, addr).(*ResourceState) + resource.Type = src.Type + // TODO: Dependencies // TODO: Provider? @@ -210,3 +214,64 @@ func detectValueAddLoc(raw interface{}) stateAddLoc { return stateAddInvalid } } + +// stateAddInitAddr takes a ResourceAddress and creates the non-existing +// resources up to that point, returning the empty (or existing) interface +// at that address. +func stateAddInitAddr(s *State, addr *ResourceAddress) interface{} { + addType := detectAddrAddLoc(addr) + + // Get the module + path := append([]string{"root"}, addr.Path...) + mod := s.ModuleByPath(path) + if mod == nil { + mod = s.AddModule(path) + } + if addType == stateAddModule { + return mod + } + + // Add the resource + resourceKey := (&ResourceStateKey{ + Name: addr.Name, + Type: addr.Type, + Index: addr.Index, + }).String() + resource, ok := mod.Resources[resourceKey] + if !ok { + resource = &ResourceState{Type: addr.Type} + resource.init() + mod.Resources[resourceKey] = resource + } + if addType == stateAddResource { + return resource + } + + // Get the instance + var instance *InstanceState + switch addr.InstanceType { + case TypePrimary: + instance = resource.Primary + case TypeTainted: + idx := addr.Index + if addr.Index < 0 { + idx = 0 + } + if len(resource.Tainted) > idx { + instance = resource.Tainted[idx] + } + case TypeDeposed: + idx := addr.Index + if addr.Index < 0 { + idx = 0 + } + if len(resource.Deposed) > idx { + instance = resource.Deposed[idx] + } + } + if instance == nil { + instance = &InstanceState{} + } + + return instance +} diff --git a/terraform/state_add_test.go b/terraform/state_add_test.go index 50596af1f..9cd54457e 100644 --- a/terraform/state_add_test.go +++ b/terraform/state_add_test.go @@ -134,6 +134,34 @@ func TestStateAdd(t *testing.T) { }, nil, }, + + "ResourceState => Resource Addr (new)": { + false, + "aws_instance.foo", + &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + + &State{}, + &State{ + Modules: []*ModuleState{ + &ModuleState{ + Path: []string{"root"}, + Resources: map[string]*ResourceState{ + "aws_instance.foo": &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + }, + }, + }, + }, + }, } for k, tc := range cases { @@ -158,7 +186,7 @@ func TestStateAdd(t *testing.T) { // Verify equality if !tc.One.Equal(tc.Two) { - //t.Fatalf("Bad: %s\n\n%#v\n\n%#v", k, tc.One, tc.Two) + // t.Fatalf("Bad: %s\n\n%#v\n\n%#v", k, tc.One, tc.Two) t.Fatalf("Bad: %s\n\n%s\n\n%s", k, tc.One.String(), tc.Two.String()) } }