github.com/opentofu/opentofu@v1.7.1/internal/checks/state_init.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package checks 7 8 import ( 9 "github.com/opentofu/opentofu/internal/addrs" 10 "github.com/opentofu/opentofu/internal/configs" 11 ) 12 13 func initialStatuses(cfg *configs.Config) addrs.Map[addrs.ConfigCheckable, *configCheckableState] { 14 ret := addrs.MakeMap[addrs.ConfigCheckable, *configCheckableState]() 15 if cfg == nil { 16 // This should not happen in normal use, but can arise in some 17 // unit tests that are not working with a full configuration and 18 // don't care about checks. 19 return ret 20 } 21 22 collectInitialStatuses(ret, cfg) 23 24 return ret 25 } 26 27 func collectInitialStatuses(into addrs.Map[addrs.ConfigCheckable, *configCheckableState], cfg *configs.Config) { 28 moduleAddr := cfg.Path 29 30 for _, rc := range cfg.Module.ManagedResources { 31 addr := rc.Addr().InModule(moduleAddr) 32 collectInitialStatusForResource(into, addr, rc) 33 } 34 for _, rc := range cfg.Module.DataResources { 35 addr := rc.Addr().InModule(moduleAddr) 36 collectInitialStatusForResource(into, addr, rc) 37 } 38 39 for _, oc := range cfg.Module.Outputs { 40 addr := oc.Addr().InModule(moduleAddr) 41 42 ct := len(oc.Preconditions) 43 if ct == 0 { 44 // We just ignore output values that don't declare any checks. 45 continue 46 } 47 48 st := &configCheckableState{} 49 50 st.checkTypes = map[addrs.CheckRuleType]int{ 51 addrs.OutputPrecondition: ct, 52 } 53 54 into.Put(addr, st) 55 } 56 57 for _, c := range cfg.Module.Checks { 58 addr := c.Addr().InModule(moduleAddr) 59 60 st := &configCheckableState{ 61 checkTypes: map[addrs.CheckRuleType]int{ 62 addrs.CheckAssertion: len(c.Asserts), 63 }, 64 } 65 66 if c.DataResource != nil { 67 st.checkTypes[addrs.CheckDataResource] = 1 68 } 69 70 into.Put(addr, st) 71 } 72 73 for _, v := range cfg.Module.Variables { 74 addr := v.Addr().InModule(moduleAddr) 75 76 vs := len(v.Validations) 77 if vs == 0 { 78 continue 79 } 80 81 st := &configCheckableState{} 82 st.checkTypes = map[addrs.CheckRuleType]int{ 83 addrs.InputValidation: vs, 84 } 85 86 into.Put(addr, st) 87 } 88 89 // Must also visit child modules to collect everything 90 for _, child := range cfg.Children { 91 collectInitialStatuses(into, child) 92 } 93 } 94 95 func collectInitialStatusForResource(into addrs.Map[addrs.ConfigCheckable, *configCheckableState], addr addrs.ConfigResource, rc *configs.Resource) { 96 if (len(rc.Preconditions) + len(rc.Postconditions)) == 0 { 97 // Don't bother with any resource that doesn't have at least 98 // one condition. 99 return 100 } 101 102 st := &configCheckableState{ 103 checkTypes: make(map[addrs.CheckRuleType]int), 104 } 105 106 if ct := len(rc.Preconditions); ct > 0 { 107 st.checkTypes[addrs.ResourcePrecondition] = ct 108 } 109 if ct := len(rc.Postconditions); ct > 0 { 110 st.checkTypes[addrs.ResourcePostcondition] = ct 111 } 112 113 into.Put(addr, st) 114 }