github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/internal/adapters/terraform/google/gke/adapt.go (about) 1 package gke 2 3 import ( 4 "github.com/google/uuid" 5 "github.com/khulnasoft-lab/defsec/pkg/providers/google/gke" 6 "github.com/khulnasoft-lab/defsec/pkg/terraform" 7 defsecTypes "github.com/khulnasoft-lab/defsec/pkg/types" 8 "github.com/zclconf/go-cty/cty" 9 ) 10 11 func Adapt(modules terraform.Modules) gke.GKE { 12 return gke.GKE{ 13 Clusters: (&adapter{ 14 modules: modules, 15 clusterMap: make(map[string]gke.Cluster), 16 }).adaptClusters(), 17 } 18 } 19 20 type adapter struct { 21 modules terraform.Modules 22 clusterMap map[string]gke.Cluster 23 } 24 25 func (a *adapter) adaptClusters() []gke.Cluster { 26 for _, module := range a.modules { 27 for _, resource := range module.GetResourcesByType("google_container_cluster") { 28 a.adaptCluster(resource, module) 29 } 30 } 31 32 a.adaptNodePools() 33 34 for id, cluster := range a.clusterMap { 35 if len(cluster.NodePools) > 0 { 36 cluster.NodeConfig = cluster.NodePools[0].NodeConfig 37 a.clusterMap[id] = cluster 38 } 39 } 40 41 var clusters []gke.Cluster 42 for _, cluster := range a.clusterMap { 43 clusters = append(clusters, cluster) 44 } 45 return clusters 46 } 47 48 func (a *adapter) adaptCluster(resource *terraform.Block, module *terraform.Module) { 49 50 cluster := gke.Cluster{ 51 Metadata: resource.GetMetadata(), 52 NodePools: nil, 53 IPAllocationPolicy: gke.IPAllocationPolicy{ 54 Metadata: resource.GetMetadata(), 55 Enabled: defsecTypes.BoolDefault(false, resource.GetMetadata()), 56 }, 57 MasterAuthorizedNetworks: gke.MasterAuthorizedNetworks{ 58 Metadata: resource.GetMetadata(), 59 Enabled: defsecTypes.BoolDefault(false, resource.GetMetadata()), 60 CIDRs: []defsecTypes.StringValue{}, 61 }, 62 NetworkPolicy: gke.NetworkPolicy{ 63 Metadata: resource.GetMetadata(), 64 Enabled: defsecTypes.BoolDefault(false, resource.GetMetadata()), 65 }, 66 PrivateCluster: gke.PrivateCluster{ 67 Metadata: resource.GetMetadata(), 68 EnablePrivateNodes: defsecTypes.BoolDefault(false, resource.GetMetadata()), 69 }, 70 LoggingService: defsecTypes.StringDefault("logging.googleapis.com/kubernetes", resource.GetMetadata()), 71 MonitoringService: defsecTypes.StringDefault("monitoring.googleapis.com/kubernetes", resource.GetMetadata()), 72 PodSecurityPolicy: gke.PodSecurityPolicy{ 73 Metadata: resource.GetMetadata(), 74 Enabled: defsecTypes.BoolDefault(false, resource.GetMetadata()), 75 }, 76 MasterAuth: gke.MasterAuth{ 77 Metadata: resource.GetMetadata(), 78 ClientCertificate: gke.ClientCertificate{ 79 Metadata: resource.GetMetadata(), 80 IssueCertificate: defsecTypes.BoolDefault(false, resource.GetMetadata()), 81 }, 82 Username: defsecTypes.StringDefault("", resource.GetMetadata()), 83 Password: defsecTypes.StringDefault("", resource.GetMetadata()), 84 }, 85 NodeConfig: gke.NodeConfig{ 86 Metadata: resource.GetMetadata(), 87 ImageType: defsecTypes.StringDefault("", resource.GetMetadata()), 88 WorkloadMetadataConfig: gke.WorkloadMetadataConfig{ 89 Metadata: resource.GetMetadata(), 90 NodeMetadata: defsecTypes.StringDefault("", resource.GetMetadata()), 91 }, 92 ServiceAccount: defsecTypes.StringDefault("", resource.GetMetadata()), 93 EnableLegacyEndpoints: defsecTypes.BoolDefault(true, resource.GetMetadata()), 94 }, 95 EnableShieldedNodes: defsecTypes.BoolDefault(true, resource.GetMetadata()), 96 EnableLegacyABAC: defsecTypes.BoolDefault(false, resource.GetMetadata()), 97 ResourceLabels: defsecTypes.MapDefault(make(map[string]string), resource.GetMetadata()), 98 RemoveDefaultNodePool: defsecTypes.BoolDefault(false, resource.GetMetadata()), 99 } 100 101 if allocBlock := resource.GetBlock("ip_allocation_policy"); allocBlock.IsNotNil() { 102 cluster.IPAllocationPolicy.Metadata = allocBlock.GetMetadata() 103 cluster.IPAllocationPolicy.Enabled = defsecTypes.Bool(true, allocBlock.GetMetadata()) 104 } 105 106 if blocks := resource.GetBlocks("master_authorized_networks_config"); len(blocks) > 0 { 107 cluster.MasterAuthorizedNetworks = adaptMasterAuthNetworksAsBlocks(resource, blocks) 108 } 109 110 if policyBlock := resource.GetBlock("network_policy"); policyBlock.IsNotNil() { 111 enabledAttr := policyBlock.GetAttribute("enabled") 112 cluster.NetworkPolicy.Metadata = policyBlock.GetMetadata() 113 cluster.NetworkPolicy.Enabled = enabledAttr.AsBoolValueOrDefault(false, policyBlock) 114 } 115 116 if privBlock := resource.GetBlock("private_cluster_config"); privBlock.IsNotNil() { 117 privateNodesEnabledAttr := privBlock.GetAttribute("enable_private_nodes") 118 cluster.PrivateCluster.Metadata = privBlock.GetMetadata() 119 cluster.PrivateCluster.EnablePrivateNodes = privateNodesEnabledAttr.AsBoolValueOrDefault(false, privBlock) 120 } 121 122 loggingAttr := resource.GetAttribute("logging_service") 123 cluster.LoggingService = loggingAttr.AsStringValueOrDefault("logging.googleapis.com/kubernetes", resource) 124 monitoringServiceAttr := resource.GetAttribute("monitoring_service") 125 cluster.MonitoringService = monitoringServiceAttr.AsStringValueOrDefault("monitoring.googleapis.com/kubernetes", resource) 126 127 if policyBlock := resource.GetBlock("pod_security_policy_config"); policyBlock.IsNotNil() { 128 enabledAttr := policyBlock.GetAttribute("enabled") 129 cluster.PodSecurityPolicy.Metadata = policyBlock.GetMetadata() 130 cluster.PodSecurityPolicy.Enabled = enabledAttr.AsBoolValueOrDefault(false, policyBlock) 131 } 132 133 if masterBlock := resource.GetBlock("master_auth"); masterBlock.IsNotNil() { 134 cluster.MasterAuth = adaptMasterAuth(masterBlock) 135 } 136 137 if configBlock := resource.GetBlock("node_config"); configBlock.IsNotNil() { 138 if configBlock.GetBlock("metadata").IsNotNil() { 139 cluster.NodeConfig.Metadata = configBlock.GetBlock("metadata").GetMetadata() 140 } 141 cluster.NodeConfig = adaptNodeConfig(configBlock) 142 } 143 144 cluster.EnableShieldedNodes = resource.GetAttribute("enable_shielded_nodes").AsBoolValueOrDefault(true, resource) 145 146 enableLegacyABACAttr := resource.GetAttribute("enable_legacy_abac") 147 cluster.EnableLegacyABAC = enableLegacyABACAttr.AsBoolValueOrDefault(false, resource) 148 149 resourceLabelsAttr := resource.GetAttribute("resource_labels") 150 if resourceLabelsAttr.IsNotNil() { 151 resourceLabels := make(map[string]string) 152 _ = resourceLabelsAttr.Each(func(key, val cty.Value) { 153 if key.Type() == cty.String && val.Type() == cty.String { 154 resourceLabels[key.AsString()] = val.AsString() 155 } 156 }) 157 cluster.ResourceLabels = defsecTypes.Map(resourceLabels, resourceLabelsAttr.GetMetadata()) 158 } 159 160 cluster.RemoveDefaultNodePool = resource.GetAttribute("remove_default_node_pool").AsBoolValueOrDefault(false, resource) 161 162 a.clusterMap[resource.ID()] = cluster 163 } 164 165 func (a *adapter) adaptNodePools() { 166 for _, nodePoolBlock := range a.modules.GetResourcesByType("google_container_node_pool") { 167 a.adaptNodePool(nodePoolBlock) 168 } 169 } 170 171 func (a *adapter) adaptNodePool(resource *terraform.Block) { 172 nodeConfig := gke.NodeConfig{ 173 Metadata: resource.GetMetadata(), 174 ImageType: defsecTypes.StringDefault("", resource.GetMetadata()), 175 WorkloadMetadataConfig: gke.WorkloadMetadataConfig{ 176 Metadata: resource.GetMetadata(), 177 NodeMetadata: defsecTypes.StringDefault("", resource.GetMetadata()), 178 }, 179 ServiceAccount: defsecTypes.StringDefault("", resource.GetMetadata()), 180 EnableLegacyEndpoints: defsecTypes.BoolDefault(true, resource.GetMetadata()), 181 } 182 183 management := gke.Management{ 184 Metadata: resource.GetMetadata(), 185 EnableAutoRepair: defsecTypes.BoolDefault(false, resource.GetMetadata()), 186 EnableAutoUpgrade: defsecTypes.BoolDefault(false, resource.GetMetadata()), 187 } 188 189 if resource.HasChild("management") { 190 management.Metadata = resource.GetBlock("management").GetMetadata() 191 192 autoRepairAttr := resource.GetBlock("management").GetAttribute("auto_repair") 193 management.EnableAutoRepair = autoRepairAttr.AsBoolValueOrDefault(false, resource.GetBlock("management")) 194 195 autoUpgradeAttr := resource.GetBlock("management").GetAttribute("auto_upgrade") 196 management.EnableAutoUpgrade = autoUpgradeAttr.AsBoolValueOrDefault(false, resource.GetBlock("management")) 197 } 198 199 if resource.HasChild("node_config") { 200 nodeConfig = adaptNodeConfig(resource.GetBlock("node_config")) 201 } 202 203 nodePool := gke.NodePool{ 204 Metadata: resource.GetMetadata(), 205 Management: management, 206 NodeConfig: nodeConfig, 207 } 208 209 clusterAttr := resource.GetAttribute("cluster") 210 if referencedCluster, err := a.modules.GetReferencedBlock(clusterAttr, resource); err == nil { 211 if referencedCluster.TypeLabel() == "google_container_cluster" { 212 if cluster, ok := a.clusterMap[referencedCluster.ID()]; ok { 213 cluster.NodePools = append(cluster.NodePools, nodePool) 214 a.clusterMap[referencedCluster.ID()] = cluster 215 return 216 } 217 } 218 } 219 220 // we didn't find a cluster to put the nodepool in, so create a placeholder 221 a.clusterMap[uuid.NewString()] = gke.Cluster{ 222 Metadata: defsecTypes.NewUnmanagedMetadata(), 223 NodePools: []gke.NodePool{nodePool}, 224 IPAllocationPolicy: gke.IPAllocationPolicy{ 225 Metadata: defsecTypes.NewUnmanagedMetadata(), 226 Enabled: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()), 227 }, 228 MasterAuthorizedNetworks: gke.MasterAuthorizedNetworks{ 229 Metadata: defsecTypes.NewUnmanagedMetadata(), 230 Enabled: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()), 231 CIDRs: nil, 232 }, 233 NetworkPolicy: gke.NetworkPolicy{ 234 Metadata: defsecTypes.NewUnmanagedMetadata(), 235 Enabled: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()), 236 }, 237 PrivateCluster: gke.PrivateCluster{ 238 Metadata: defsecTypes.NewUnmanagedMetadata(), 239 EnablePrivateNodes: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()), 240 }, 241 LoggingService: defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()), 242 MonitoringService: defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()), 243 PodSecurityPolicy: gke.PodSecurityPolicy{ 244 Metadata: defsecTypes.NewUnmanagedMetadata(), 245 Enabled: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()), 246 }, 247 MasterAuth: gke.MasterAuth{ 248 Metadata: defsecTypes.NewUnmanagedMetadata(), 249 ClientCertificate: gke.ClientCertificate{ 250 Metadata: defsecTypes.NewUnmanagedMetadata(), 251 IssueCertificate: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()), 252 }, 253 Username: defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()), 254 Password: defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()), 255 }, 256 NodeConfig: gke.NodeConfig{ 257 Metadata: defsecTypes.NewUnmanagedMetadata(), 258 ImageType: defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()), 259 WorkloadMetadataConfig: gke.WorkloadMetadataConfig{ 260 Metadata: defsecTypes.NewUnmanagedMetadata(), 261 NodeMetadata: defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()), 262 }, 263 ServiceAccount: defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()), 264 EnableLegacyEndpoints: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()), 265 }, 266 EnableShieldedNodes: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()), 267 EnableLegacyABAC: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()), 268 ResourceLabels: defsecTypes.MapDefault(nil, defsecTypes.NewUnmanagedMetadata()), 269 RemoveDefaultNodePool: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()), 270 } 271 } 272 273 func adaptNodeConfig(resource *terraform.Block) gke.NodeConfig { 274 275 config := gke.NodeConfig{ 276 Metadata: resource.GetMetadata(), 277 ImageType: resource.GetAttribute("image_type").AsStringValueOrDefault("", resource), 278 WorkloadMetadataConfig: gke.WorkloadMetadataConfig{ 279 Metadata: resource.GetMetadata(), 280 NodeMetadata: defsecTypes.StringDefault("UNSPECIFIED", resource.GetMetadata()), 281 }, 282 ServiceAccount: resource.GetAttribute("service_account").AsStringValueOrDefault("", resource), 283 EnableLegacyEndpoints: defsecTypes.BoolDefault(true, resource.GetMetadata()), 284 } 285 286 if metadata := resource.GetAttribute("metadata"); metadata.IsNotNil() { 287 legacyMetadata := metadata.MapValue("disable-legacy-endpoints") 288 if legacyMetadata.IsWhollyKnown() && legacyMetadata.Type() == cty.Bool { 289 config.EnableLegacyEndpoints = defsecTypes.Bool(legacyMetadata.False(), metadata.GetMetadata()) 290 } 291 } 292 293 workloadBlock := resource.GetBlock("workload_metadata_config") 294 if workloadBlock.IsNotNil() { 295 config.WorkloadMetadataConfig.Metadata = workloadBlock.GetMetadata() 296 modeAttr := workloadBlock.GetAttribute("node_metadata") 297 if modeAttr.IsNil() { 298 modeAttr = workloadBlock.GetAttribute("mode") // try newest version 299 } 300 config.WorkloadMetadataConfig.NodeMetadata = modeAttr.AsStringValueOrDefault("UNSPECIFIED", workloadBlock) 301 } 302 303 return config 304 } 305 306 func adaptMasterAuth(resource *terraform.Block) gke.MasterAuth { 307 clientCert := gke.ClientCertificate{ 308 Metadata: resource.GetMetadata(), 309 IssueCertificate: defsecTypes.BoolDefault(false, resource.GetMetadata()), 310 } 311 312 if resource.HasChild("client_certificate_config") { 313 clientCertAttr := resource.GetBlock("client_certificate_config").GetAttribute("issue_client_certificate") 314 clientCert.IssueCertificate = clientCertAttr.AsBoolValueOrDefault(false, resource.GetBlock("client_certificate_config")) 315 clientCert.Metadata = resource.GetBlock("client_certificate_config").GetMetadata() 316 } 317 318 username := resource.GetAttribute("username").AsStringValueOrDefault("", resource) 319 password := resource.GetAttribute("password").AsStringValueOrDefault("", resource) 320 321 return gke.MasterAuth{ 322 Metadata: resource.GetMetadata(), 323 ClientCertificate: clientCert, 324 Username: username, 325 Password: password, 326 } 327 } 328 329 func adaptMasterAuthNetworksAsBlocks(parent *terraform.Block, blocks terraform.Blocks) gke.MasterAuthorizedNetworks { 330 var cidrs []defsecTypes.StringValue 331 for _, block := range blocks { 332 for _, cidrBlock := range block.GetBlocks("cidr_blocks") { 333 if cidrAttr := cidrBlock.GetAttribute("cidr_block"); cidrAttr.IsNotNil() { 334 cidrs = append(cidrs, cidrAttr.AsStringValues()...) 335 } 336 } 337 } 338 enabled := defsecTypes.Bool(true, blocks[0].GetMetadata()) 339 return gke.MasterAuthorizedNetworks{ 340 Metadata: blocks[0].GetMetadata(), 341 Enabled: enabled, 342 CIDRs: cidrs, 343 } 344 }