github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/command/views/hook_count.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package views 5 6 import ( 7 "sync" 8 9 "github.com/zclconf/go-cty/cty" 10 11 "github.com/terramate-io/tf/addrs" 12 "github.com/terramate-io/tf/plans" 13 "github.com/terramate-io/tf/states" 14 "github.com/terramate-io/tf/terraform" 15 ) 16 17 // countHook is a hook that counts the number of resources 18 // added, removed, changed during the course of an apply. 19 type countHook struct { 20 Added int 21 Changed int 22 Removed int 23 Imported int 24 25 ToAdd int 26 ToChange int 27 ToRemove int 28 ToRemoveAndAdd int 29 30 pending map[string]plans.Action 31 32 sync.Mutex 33 terraform.NilHook 34 } 35 36 var _ terraform.Hook = (*countHook)(nil) 37 38 func (h *countHook) Reset() { 39 h.Lock() 40 defer h.Unlock() 41 42 h.pending = nil 43 h.Added = 0 44 h.Changed = 0 45 h.Removed = 0 46 h.Imported = 0 47 } 48 49 func (h *countHook) PreApply(addr addrs.AbsResourceInstance, gen states.Generation, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { 50 h.Lock() 51 defer h.Unlock() 52 53 if h.pending == nil { 54 h.pending = make(map[string]plans.Action) 55 } 56 57 h.pending[addr.String()] = action 58 59 return terraform.HookActionContinue, nil 60 } 61 62 func (h *countHook) PostApply(addr addrs.AbsResourceInstance, gen states.Generation, newState cty.Value, err error) (terraform.HookAction, error) { 63 h.Lock() 64 defer h.Unlock() 65 66 if h.pending != nil { 67 pendingKey := addr.String() 68 if action, ok := h.pending[pendingKey]; ok { 69 delete(h.pending, pendingKey) 70 71 if err == nil { 72 switch action { 73 case plans.CreateThenDelete, plans.DeleteThenCreate: 74 h.Added++ 75 h.Removed++ 76 case plans.Create: 77 h.Added++ 78 case plans.Delete: 79 h.Removed++ 80 case plans.Update: 81 h.Changed++ 82 } 83 } 84 } 85 } 86 87 return terraform.HookActionContinue, nil 88 } 89 90 func (h *countHook) PostDiff(addr addrs.AbsResourceInstance, gen states.Generation, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { 91 h.Lock() 92 defer h.Unlock() 93 94 // We don't count anything for data resources 95 if addr.Resource.Resource.Mode == addrs.DataResourceMode { 96 return terraform.HookActionContinue, nil 97 } 98 99 switch action { 100 case plans.CreateThenDelete, plans.DeleteThenCreate: 101 h.ToRemoveAndAdd += 1 102 case plans.Create: 103 h.ToAdd += 1 104 case plans.Delete: 105 h.ToRemove += 1 106 case plans.Update: 107 h.ToChange += 1 108 } 109 110 return terraform.HookActionContinue, nil 111 } 112 113 func (h *countHook) PostApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (terraform.HookAction, error) { 114 h.Lock() 115 defer h.Unlock() 116 117 h.Imported++ 118 return terraform.HookActionContinue, nil 119 }