github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/pkg/terraform/module.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 type Module struct { 9 blocks Blocks 10 blockMap map[string]Blocks 11 rootPath string 12 modulePath string 13 ignores Ignores 14 } 15 16 func NewModule(rootPath string, modulePath string, blocks Blocks, ignores Ignores) *Module { 17 18 blockMap := make(map[string]Blocks) 19 20 for _, b := range blocks { 21 if b.NameLabel() != "" { 22 blockMap[b.TypeLabel()] = append(blockMap[b.TypeLabel()], b) 23 } 24 } 25 26 return &Module{ 27 blocks: blocks, 28 ignores: ignores, 29 blockMap: blockMap, 30 rootPath: rootPath, 31 modulePath: modulePath, 32 } 33 } 34 35 func (c *Module) RootPath() string { 36 return c.rootPath 37 } 38 39 func (c *Module) Ignores() Ignores { 40 return c.ignores 41 } 42 43 func (c *Module) GetBlocks() Blocks { 44 return c.blocks 45 } 46 47 func (h *Module) GetBlocksByTypeLabel(typeLabel string) Blocks { 48 return h.blockMap[typeLabel] 49 } 50 51 func (c *Module) getBlocksByType(blockType string, labels ...string) Blocks { 52 if blockType == "module" { 53 return c.getModuleBlocks() 54 } 55 var results Blocks 56 for _, label := range labels { 57 for _, block := range c.blockMap[label] { 58 if block.Type() == blockType { 59 results = append(results, block) 60 } 61 } 62 } 63 return results 64 } 65 66 func (c *Module) getModuleBlocks() Blocks { 67 var results Blocks 68 for _, block := range c.blocks { 69 if block.Type() == "module" { 70 results = append(results, block) 71 } 72 } 73 return results 74 } 75 76 func (c *Module) GetResourcesByType(labels ...string) Blocks { 77 return c.getBlocksByType("resource", labels...) 78 } 79 80 func (c *Module) GetResourcesByIDs(ids ...string) Blocks { 81 var blocks Blocks 82 83 for _, id := range ids { 84 if block := c.blocks.WithID(id); block != nil { 85 blocks = append(blocks, block) 86 } 87 } 88 return blocks 89 } 90 91 func (c *Module) GetDatasByType(label string) Blocks { 92 return c.getBlocksByType("data", label) 93 } 94 95 func (c *Module) GetProviderBlocksByProvider(providerName string, alias string) Blocks { 96 var results Blocks 97 for _, block := range c.blocks { 98 if block.Type() == "provider" && len(block.Labels()) > 0 && block.TypeLabel() == providerName { 99 if alias != "" { 100 if block.HasChild("alias") && block.GetAttribute("alias").Equals(strings.ReplaceAll(alias, fmt.Sprintf("%s.", providerName), "")) { 101 results = append(results, block) 102 103 } 104 } else if block.MissingChild("alias") { 105 results = append(results, block) 106 } 107 } 108 } 109 return results 110 } 111 112 func (c *Module) GetReferencedBlock(referringAttr *Attribute, parentBlock *Block) (*Block, error) { 113 for _, ref := range referringAttr.AllReferences() { 114 if ref.TypeLabel() == "each" { 115 if forEachAttr := parentBlock.GetAttribute("for_each"); forEachAttr.IsNotNil() { 116 if b, err := c.GetReferencedBlock(forEachAttr, parentBlock); err == nil { 117 return b, nil 118 } 119 } 120 } 121 for _, block := range c.blocks { 122 if ref.RefersTo(block.reference) { 123 return block, nil 124 } 125 kref := *ref 126 kref.SetKey(parentBlock.reference.RawKey()) 127 if kref.RefersTo(block.reference) { 128 return block, nil 129 } 130 } 131 } 132 return nil, fmt.Errorf("no referenced block found in '%s'", referringAttr.Name()) 133 } 134 135 func (c *Module) GetBlockByID(id string) (*Block, error) { 136 found := c.blocks.WithID(id) 137 if found == nil { 138 return nil, fmt.Errorf("no block found with id '%s'", id) 139 } 140 return found, nil 141 } 142 143 func (c *Module) GetReferencingResources(originalBlock *Block, referencingLabel string, referencingAttributeName string) Blocks { 144 return c.GetReferencingBlocks(originalBlock, "resource", referencingLabel, referencingAttributeName) 145 } 146 147 func (c *Module) GetsModulesBySource(moduleSource string) (Blocks, error) { 148 var results Blocks 149 150 modules := c.getModuleBlocks() 151 for _, module := range modules { 152 if module.HasChild("source") && module.GetAttribute("source").Equals(moduleSource) { 153 results = append(results, module) 154 } 155 } 156 return results, nil 157 } 158 159 func (c *Module) GetReferencingBlocks(originalBlock *Block, referencingType string, referencingLabel string, referencingAttributeName string) Blocks { 160 blocks := c.getBlocksByType(referencingType, referencingLabel) 161 var results Blocks 162 for _, block := range blocks { 163 attr := block.GetAttribute(referencingAttributeName) 164 if attr == nil { 165 continue 166 } 167 if attr.References(originalBlock.reference) { 168 results = append(results, block) 169 } else { 170 for _, ref := range attr.AllReferences() { 171 if ref.TypeLabel() == "each" { 172 fe := block.GetAttribute("for_each") 173 if fe.References(originalBlock.reference) { 174 results = append(results, block) 175 } 176 } 177 } 178 } 179 } 180 return results 181 }