Skip to content

Commit 9792611

Browse files
authoredApr 8, 2025
feat(misconf): support auto_provisioning_defaults in google_container_cluster (#8705)
Signed-off-by: nikpivkin <[email protected]>
1 parent 13608ea commit 9792611

File tree

4 files changed

+135
-46
lines changed

4 files changed

+135
-46
lines changed
 

‎pkg/iac/adapters/terraform/google/gke/adapt.go

+48-26
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ type adapter struct {
2626
func (a *adapter) adaptClusters() []gke.Cluster {
2727
for _, module := range a.modules {
2828
for _, resource := range module.GetResourcesByType("google_container_cluster") {
29-
a.adaptCluster(resource, module)
29+
a.adaptCluster(resource)
3030
}
3131
}
3232

@@ -46,7 +46,7 @@ func (a *adapter) adaptClusters() []gke.Cluster {
4646
return clusters
4747
}
4848

49-
func (a *adapter) adaptCluster(resource *terraform.Block, module *terraform.Module) {
49+
func (a *adapter) adaptCluster(resource *terraform.Block) {
5050

5151
cluster := gke.Cluster{
5252
Metadata: resource.GetMetadata(),
@@ -104,7 +104,7 @@ func (a *adapter) adaptCluster(resource *terraform.Block, module *terraform.Modu
104104
}
105105

106106
if blocks := resource.GetBlocks("master_authorized_networks_config"); len(blocks) > 0 {
107-
cluster.MasterAuthorizedNetworks = adaptMasterAuthNetworksAsBlocks(resource, blocks)
107+
cluster.MasterAuthorizedNetworks = adaptMasterAuthNetworksAsBlocks(blocks)
108108
}
109109

110110
if policyBlock := resource.GetBlock("network_policy"); policyBlock.IsNotNil() {
@@ -129,12 +129,24 @@ func (a *adapter) adaptCluster(resource *terraform.Block, module *terraform.Modu
129129
}
130130

131131
if configBlock := resource.GetBlock("node_config"); configBlock.IsNotNil() {
132-
if configBlock.GetBlock("metadata").IsNotNil() {
133-
cluster.NodeConfig.Metadata = configBlock.GetBlock("metadata").GetMetadata()
134-
}
135132
cluster.NodeConfig = adaptNodeConfig(configBlock)
136133
}
137134

135+
if autoScalingBlock := resource.GetBlock("cluster_autoscaling"); autoScalingBlock.IsNotNil() {
136+
cluster.AutoScaling = gke.AutoScaling{
137+
Metadata: autoScalingBlock.GetMetadata(),
138+
Enabled: autoScalingBlock.GetAttribute("enabled").AsBoolValueOrDefault(false, autoScalingBlock),
139+
}
140+
141+
if b := autoScalingBlock.GetBlock("auto_provisioning_defaults"); b.IsNotNil() {
142+
cluster.AutoScaling.AutoProvisioningDefaults = gke.AutoProvisioningDefaults{
143+
Metadata: b.GetMetadata(),
144+
ServiceAccount: b.GetAttribute("service_account").AsStringValueOrDefault("", b),
145+
Management: adaptManagement(b),
146+
ImageType: b.GetAttribute("image_type").AsStringValueOrDefault("", b),
147+
}
148+
}
149+
}
138150
cluster.EnableShieldedNodes = resource.GetAttribute("enable_shielded_nodes").AsBoolValueOrDefault(true, resource)
139151

140152
enableLegacyABACAttr := resource.GetAttribute("enable_legacy_abac")
@@ -152,6 +164,23 @@ func (a *adapter) adaptCluster(resource *terraform.Block, module *terraform.Modu
152164
a.clusterMap[resource.ID()] = cluster
153165
}
154166

167+
func adaptManagement(parent *terraform.Block) gke.Management {
168+
b := parent.GetBlock("management")
169+
if b.IsNil() {
170+
return gke.Management{
171+
Metadata: parent.GetMetadata(),
172+
EnableAutoRepair: iacTypes.BoolDefault(false, parent.GetMetadata()),
173+
EnableAutoUpgrade: iacTypes.BoolDefault(false, parent.GetMetadata()),
174+
}
175+
}
176+
177+
return gke.Management{
178+
Metadata: b.GetMetadata(),
179+
EnableAutoRepair: b.GetAttribute("auto_repair").AsBoolValueOrDefault(false, b),
180+
EnableAutoUpgrade: b.GetAttribute("auto_upgrade").AsBoolValueOrDefault(false, b),
181+
}
182+
}
183+
155184
func (a *adapter) adaptNodePools() {
156185
for _, nodePoolBlock := range a.modules.GetResourcesByType("google_container_node_pool") {
157186
a.adaptNodePool(nodePoolBlock)
@@ -170,28 +199,13 @@ func (a *adapter) adaptNodePool(resource *terraform.Block) {
170199
EnableLegacyEndpoints: iacTypes.BoolDefault(true, resource.GetMetadata()),
171200
}
172201

173-
management := gke.Management{
174-
Metadata: resource.GetMetadata(),
175-
EnableAutoRepair: iacTypes.BoolDefault(false, resource.GetMetadata()),
176-
EnableAutoUpgrade: iacTypes.BoolDefault(false, resource.GetMetadata()),
177-
}
178-
179-
if managementBlock := resource.GetBlock("management"); managementBlock.IsNotNil() {
180-
management.Metadata = managementBlock.GetMetadata()
181-
autoRepairAttr := managementBlock.GetAttribute("auto_repair")
182-
management.EnableAutoRepair = autoRepairAttr.AsBoolValueOrDefault(false, managementBlock)
183-
184-
autoUpgradeAttr := managementBlock.GetAttribute("auto_upgrade")
185-
management.EnableAutoUpgrade = autoUpgradeAttr.AsBoolValueOrDefault(false, managementBlock)
186-
}
187-
188202
if nodeConfigBlock := resource.GetBlock("node_config"); nodeConfigBlock.IsNotNil() {
189203
nodeConfig = adaptNodeConfig(nodeConfigBlock)
190204
}
191205

192206
nodePool := gke.NodePool{
193207
Metadata: resource.GetMetadata(),
194-
Management: management,
208+
Management: adaptManagement(resource),
195209
NodeConfig: nodeConfig,
196210
}
197211

@@ -270,9 +284,17 @@ func adaptNodeConfig(resource *terraform.Block) gke.NodeConfig {
270284
}
271285

272286
if metadata := resource.GetAttribute("metadata"); metadata.IsNotNil() {
273-
legacyMetadata := metadata.MapValue("disable-legacy-endpoints")
274-
if legacyMetadata.IsWhollyKnown() && legacyMetadata.Type() == cty.Bool {
275-
config.EnableLegacyEndpoints = iacTypes.Bool(legacyMetadata.False(), metadata.GetMetadata())
287+
disableLegacy := metadata.MapValue("disable-legacy-endpoints")
288+
if disableLegacy.IsKnown() {
289+
var enableLegacyEndpoints bool
290+
switch disableLegacy.Type() {
291+
case cty.Bool:
292+
enableLegacyEndpoints = disableLegacy.False()
293+
case cty.String:
294+
enableLegacyEndpoints = disableLegacy.AsString() == "false"
295+
}
296+
297+
config.EnableLegacyEndpoints = iacTypes.Bool(enableLegacyEndpoints, metadata.GetMetadata())
276298
}
277299
}
278300

@@ -312,7 +334,7 @@ func adaptMasterAuth(resource *terraform.Block) gke.MasterAuth {
312334
}
313335
}
314336

315-
func adaptMasterAuthNetworksAsBlocks(parent *terraform.Block, blocks terraform.Blocks) gke.MasterAuthorizedNetworks {
337+
func adaptMasterAuthNetworksAsBlocks(blocks terraform.Blocks) gke.MasterAuthorizedNetworks {
316338
var cidrs []iacTypes.StringValue
317339
for _, block := range blocks {
318340
for _, cidrBlock := range block.GetBlocks("cidr_blocks") {

‎pkg/iac/adapters/terraform/google/gke/adapt_test.go

+31-20
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@ resource "google_container_cluster" "example" {
7777
enable_autopilot = true
7878
7979
datapath_provider = "ADVANCED_DATAPATH"
80+
81+
cluster_autoscaling {
82+
enabled = true
83+
auto_provisioning_defaults {
84+
service_account = "test"
85+
image_type = "COS_CONTAINERD"
86+
management {
87+
auto_repair = true
88+
auto_upgrade = true
89+
}
90+
}
91+
}
8092
}
8193
8294
resource "google_container_node_pool" "primary_preemptible_nodes" {
@@ -102,9 +114,7 @@ resource "google_container_node_pool" "primary_preemptible_nodes" {
102114
expected: gke.GKE{
103115
Clusters: []gke.Cluster{
104116
{
105-
Metadata: iacTypes.NewTestMetadata(),
106117
NodeConfig: gke.NodeConfig{
107-
Metadata: iacTypes.NewTestMetadata(),
108118
ImageType: iacTypes.String("COS_CONTAINERD", iacTypes.NewTestMetadata()),
109119
WorkloadMetadataConfig: gke.WorkloadMetadataConfig{
110120
Metadata: iacTypes.NewTestMetadata(),
@@ -113,9 +123,19 @@ resource "google_container_node_pool" "primary_preemptible_nodes" {
113123
ServiceAccount: iacTypes.String("", iacTypes.NewTestMetadata()),
114124
EnableLegacyEndpoints: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
115125
},
126+
AutoScaling: gke.AutoScaling{
127+
Enabled: iacTypes.BoolTest(true),
128+
AutoProvisioningDefaults: gke.AutoProvisioningDefaults{
129+
ImageType: iacTypes.StringTest("COS_CONTAINERD"),
130+
ServiceAccount: iacTypes.StringTest("test"),
131+
Management: gke.Management{
132+
EnableAutoRepair: iacTypes.BoolTest(true),
133+
EnableAutoUpgrade: iacTypes.BoolTest(true),
134+
},
135+
},
136+
},
116137
NodePools: []gke.NodePool{
117138
{
118-
Metadata: iacTypes.NewTestMetadata(),
119139
Management: gke.Management{
120140
Metadata: iacTypes.NewTestMetadata(),
121141
EnableAutoRepair: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
@@ -134,19 +154,16 @@ resource "google_container_node_pool" "primary_preemptible_nodes" {
134154
},
135155
},
136156
IPAllocationPolicy: gke.IPAllocationPolicy{
137-
Metadata: iacTypes.NewTestMetadata(),
138-
Enabled: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
157+
Enabled: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
139158
},
140159
MasterAuthorizedNetworks: gke.MasterAuthorizedNetworks{
141-
Metadata: iacTypes.NewTestMetadata(),
142-
Enabled: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
160+
Enabled: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
143161
CIDRs: []iacTypes.StringValue{
144162
iacTypes.String("10.10.128.0/24", iacTypes.NewTestMetadata()),
145163
},
146164
},
147165
NetworkPolicy: gke.NetworkPolicy{
148-
Metadata: iacTypes.NewTestMetadata(),
149-
Enabled: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
166+
Enabled: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
150167
},
151168
DatapathProvider: iacTypes.String("ADVANCED_DATAPATH", iacTypes.NewTestMetadata()),
152169
PrivateCluster: gke.PrivateCluster{
@@ -156,7 +173,6 @@ resource "google_container_node_pool" "primary_preemptible_nodes" {
156173
LoggingService: iacTypes.String("logging.googleapis.com/kubernetes", iacTypes.NewTestMetadata()),
157174
MonitoringService: iacTypes.String("monitoring.googleapis.com/kubernetes", iacTypes.NewTestMetadata()),
158175
MasterAuth: gke.MasterAuth{
159-
Metadata: iacTypes.NewTestMetadata(),
160176
ClientCertificate: gke.ClientCertificate{
161177
Metadata: iacTypes.NewTestMetadata(),
162178
IssueCertificate: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
@@ -182,7 +198,7 @@ resource "google_container_cluster" "example" {
182198
node_config {
183199
service_account = "service-account"
184200
metadata = {
185-
disable-legacy-endpoints = true
201+
disable-legacy-endpoints = "true"
186202
}
187203
image_type = "COS"
188204
workload_metadata_config {
@@ -194,7 +210,6 @@ resource "google_container_cluster" "example" {
194210
expected: gke.GKE{
195211
Clusters: []gke.Cluster{
196212
{
197-
Metadata: iacTypes.NewTestMetadata(),
198213
NodeConfig: gke.NodeConfig{
199214
Metadata: iacTypes.NewTestMetadata(),
200215
ImageType: iacTypes.String("COS", iacTypes.NewTestMetadata()),
@@ -207,17 +222,14 @@ resource "google_container_cluster" "example" {
207222
},
208223

209224
IPAllocationPolicy: gke.IPAllocationPolicy{
210-
Metadata: iacTypes.NewTestMetadata(),
211-
Enabled: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
225+
Enabled: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
212226
},
213227
MasterAuthorizedNetworks: gke.MasterAuthorizedNetworks{
214-
Metadata: iacTypes.NewTestMetadata(),
215-
Enabled: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
216-
CIDRs: []iacTypes.StringValue{},
228+
Enabled: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
229+
CIDRs: []iacTypes.StringValue{},
217230
},
218231
NetworkPolicy: gke.NetworkPolicy{
219-
Metadata: iacTypes.NewTestMetadata(),
220-
Enabled: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
232+
Enabled: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
221233
},
222234
DatapathProvider: iacTypes.StringDefault("DATAPATH_PROVIDER_UNSPECIFIED", iacTypes.NewTestMetadata()),
223235
PrivateCluster: gke.PrivateCluster{
@@ -227,7 +239,6 @@ resource "google_container_cluster" "example" {
227239
LoggingService: iacTypes.String("logging.googleapis.com/kubernetes", iacTypes.NewTestMetadata()),
228240
MonitoringService: iacTypes.String("monitoring.googleapis.com/kubernetes", iacTypes.NewTestMetadata()),
229241
MasterAuth: gke.MasterAuth{
230-
Metadata: iacTypes.NewTestMetadata(),
231242
ClientCertificate: gke.ClientCertificate{
232243
Metadata: iacTypes.NewTestMetadata(),
233244
IssueCertificate: iacTypes.Bool(false, iacTypes.NewTestMetadata()),

‎pkg/iac/providers/google/gke/gke.go

+14
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type Cluster struct {
1919
MonitoringService iacTypes.StringValue
2020
MasterAuth MasterAuth
2121
NodeConfig NodeConfig
22+
AutoScaling AutoScaling
2223
EnableShieldedNodes iacTypes.BoolValue
2324
EnableLegacyABAC iacTypes.BoolValue
2425
ResourceLabels iacTypes.MapValue
@@ -35,6 +36,19 @@ type NodeConfig struct {
3536
EnableLegacyEndpoints iacTypes.BoolValue
3637
}
3738

39+
type AutoScaling struct {
40+
Metadata iacTypes.Metadata
41+
Enabled iacTypes.BoolValue
42+
AutoProvisioningDefaults AutoProvisioningDefaults
43+
}
44+
45+
type AutoProvisioningDefaults struct {
46+
Metadata iacTypes.Metadata
47+
ImageType iacTypes.StringValue
48+
ServiceAccount iacTypes.StringValue
49+
Management Management
50+
}
51+
3852
type WorkloadMetadataConfig struct {
3953
Metadata iacTypes.Metadata
4054
NodeMetadata iacTypes.StringValue

‎pkg/iac/rego/schemas/cloud.json

+42
Original file line numberDiff line numberDiff line change
@@ -6450,6 +6450,44 @@
64506450
}
64516451
}
64526452
},
6453+
"github.com.aquasecurity.trivy.pkg.iac.providers.google.gke.AutoProvisioningDefaults": {
6454+
"type": "object",
6455+
"properties": {
6456+
"__defsec_metadata": {
6457+
"type": "object",
6458+
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.Metadata"
6459+
},
6460+
"imagetype": {
6461+
"type": "object",
6462+
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.StringValue"
6463+
},
6464+
"management": {
6465+
"type": "object",
6466+
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.google.gke.Management"
6467+
},
6468+
"serviceaccount": {
6469+
"type": "object",
6470+
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.StringValue"
6471+
}
6472+
}
6473+
},
6474+
"github.com.aquasecurity.trivy.pkg.iac.providers.google.gke.AutoScaling": {
6475+
"type": "object",
6476+
"properties": {
6477+
"__defsec_metadata": {
6478+
"type": "object",
6479+
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.Metadata"
6480+
},
6481+
"autoprovisioningdefaults": {
6482+
"type": "object",
6483+
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.google.gke.AutoProvisioningDefaults"
6484+
},
6485+
"enabled": {
6486+
"type": "object",
6487+
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.BoolValue"
6488+
}
6489+
}
6490+
},
64536491
"github.com.aquasecurity.trivy.pkg.iac.providers.google.gke.ClientCertificate": {
64546492
"type": "object",
64556493
"properties": {
@@ -6470,6 +6508,10 @@
64706508
"type": "object",
64716509
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.Metadata"
64726510
},
6511+
"autoscaling": {
6512+
"type": "object",
6513+
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.google.gke.AutoScaling"
6514+
},
64736515
"datapathprovider": {
64746516
"type": "object",
64756517
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.StringValue"

0 commit comments

Comments
 (0)