diff --git a/states/module.go b/states/module.go index d89e7878d8..f767463402 100644 --- a/states/module.go +++ b/states/module.go @@ -1,6 +1,8 @@ package states import ( + "fmt" + "github.com/zclconf/go-cty/cty" "github.com/hashicorp/terraform/addrs" @@ -55,7 +57,9 @@ func (ms *Module) ResourceInstance(addr addrs.ResourceInstance) *ResourceInstanc // with the given address, creating the resource state for it if it doesn't // already exist. func (ms *Module) SetResourceMeta(addr addrs.Resource, eachMode EachMode, provider addrs.AbsProviderConfig) { + fmt.Printf("%s Set resource meta called with %s \n", addr, eachMode) rs := ms.Resource(addr) + fmt.Println(addr) if rs == nil { rs = &Resource{ Addr: addr, @@ -88,23 +92,56 @@ func (ms *Module) RemoveResource(addr addrs.Resource) { // are updated for all other instances of the same resource as a side-effect of // this call. func (ms *Module) SetResourceInstanceCurrent(addr addrs.ResourceInstance, obj *ResourceInstanceObjectSrc, provider addrs.AbsProviderConfig) { - ms.SetResourceMeta(addr.Resource, eachModeForInstanceKey(addr.Key), provider) - + // cases for doing nothing + // go get resource: rs := ms.Resource(addr.Resource) + // if the resource is nil and the object is nil, don't do anything! + if obj == nil && rs == nil { + return + } + if obj == nil && rs != nil { + // does the resource have any other objects? + // if not then delete the whole resource + if len(rs.Instances) == 0 { + delete(ms.Resources, addr.Resource.String()) + return + } + inst := rs.Instances[addr.Key] + if inst == nil { + // THERE IS NO INSTANCE Bail, don't change everything for no reason + return + } + // then the obj is nil, and we do have an instance, + // set current to nil + inst.Current = obj + if !inst.HasObjects() { + // If we have no objects at all then we'll clean up. + delete(rs.Instances, addr.Key) + if len(rs.Instances) == 0 { + delete(ms.Resources, addr.Resource.String()) + return + } + } + return + } + if rs == nil && obj != nil { + // make the resource! which happens in setResourceMeta, so okay + fmt.Println("Called at the middle", addr.Key) + ms.SetResourceMeta(addr.Resource, eachModeForInstanceKey(addr.Key), provider) + // now we have a resource! + rs = ms.Resource(addr.Resource) + } + inst := rs.Instances[addr.Key] + if inst == nil { + rs.EnsureInstance(addr.Key) + ms.SetResourceMeta(addr.Resource, eachModeForInstanceKey(addr.Key), provider) + + } is := rs.EnsureInstance(addr.Key) - is.Current = obj - - if !is.HasObjects() { - // If we have no objects at all then we'll clean up. - delete(rs.Instances, addr.Key) - } - if rs.EachMode == NoEach && len(rs.Instances) == 0 { - // Also clean up if we only expect to have one instance anyway - // and there are none. We leave the resource behind if an each mode - // is active because an empty list or map of instances is a valid state. - delete(ms.Resources, addr.Resource.String()) - } + fmt.Println("Called at the end", addr.Key) + fmt.Printf("%#v\n", obj) + // ms.SetResourceMeta(addr.Resource, eachModeForInstanceKey(addr.Key), provider) } // SetResourceInstanceDeposed saves the given instance object as a deposed @@ -124,6 +161,7 @@ func (ms *Module) SetResourceInstanceCurrent(addr addrs.ResourceInstance, obj *R // the instance is left with no objects after this operation then it will // be removed from its containing resource altogether. func (ms *Module) SetResourceInstanceDeposed(addr addrs.ResourceInstance, key DeposedKey, obj *ResourceInstanceObjectSrc, provider addrs.AbsProviderConfig) { + fmt.Println("called with deposed") ms.SetResourceMeta(addr.Resource, eachModeForInstanceKey(addr.Key), provider) rs := ms.Resource(addr.Resource) diff --git a/states/resource.go b/states/resource.go index 7f58543c43..1e3d70d19d 100644 --- a/states/resource.go +++ b/states/resource.go @@ -46,7 +46,9 @@ func (rs *Resource) Instance(key addrs.InstanceKey) *ResourceInstance { // a write operation. func (rs *Resource) EnsureInstance(key addrs.InstanceKey) *ResourceInstance { ret := rs.Instance(key) + fmt.Println("in ensure") if ret == nil { + fmt.Println("creating an instance") ret = NewResourceInstance() rs.Instances[key] = ret } @@ -180,10 +182,13 @@ const ( func eachModeForInstanceKey(key addrs.InstanceKey) EachMode { switch key.(type) { case addrs.IntKey: + fmt.Println("is int key") return EachList case addrs.StringKey: + fmt.Println("is string key") return EachMap default: + fmt.Println(key) if key == addrs.NoKey { return NoEach } diff --git a/states/sync.go b/states/sync.go index 47fb16d6ea..7bf44cd7aa 100644 --- a/states/sync.go +++ b/states/sync.go @@ -1,6 +1,7 @@ package states import ( + "fmt" "log" "sync" @@ -190,6 +191,7 @@ func (s *SyncState) SetResourceMeta(addr addrs.AbsResource, eachMode EachMode, p defer s.lock.Unlock() ms := s.state.EnsureModule(addr.Module) + fmt.Println("called from syncstate") ms.SetResourceMeta(addr.Resource, eachMode, provider) } diff --git a/terraform/evaluate.go b/terraform/evaluate.go index de1fd9a058..a70382442e 100644 --- a/terraform/evaluate.go +++ b/terraform/evaluate.go @@ -577,6 +577,8 @@ func (d *evaluationStateData) getResourceInstancesAll(addr addrs.Resource, rng t }) return cty.DynamicVal, diags } + fmt.Println(addr.String(), "in getResourceAll") + fmt.Println(rs.EachMode) switch rs.EachMode { case states.NoEach: