Skip to content

Commit

Permalink
Added support for workload-vulnerability-scanning and workload-config…
Browse files Browse the repository at this point in the history
…-audit (#7310)

* Added support for workload-vulnerability-scanning and workload-config-audit

Fixes hashicorp/terraform-provider-google#12778

* Made google_container_cluster protect_config field optional

* made container_cluster protect_config.workload_config.audit_mode required

* Made fields inside protect_config as atleastOneOf in container_cluster resource.

---------

Co-authored-by: Avinash Kumar <avikuma@google.com>
  • Loading branch information
avinash84 and Avinash Kumar authored Feb 27, 2023
1 parent 02108d4 commit 974faae
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 0 deletions.
118 changes: 118 additions & 0 deletions mmv1/third_party/terraform/resources/resource_container_cluster.go.erb
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,50 @@ func ResourceContainerCluster() *schema.Resource {
},
},

<% unless version == 'ga' -%>
"protect_config": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Description: `The notification config for sending cluster upgrade notifications`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"workload_config": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Description: `WorkloadConfig defines the flags to enable or disable the workload configurations for the cluster.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"audit_mode": {
Type: schema.TypeString,
Required: true,
Description: `Mode defines how to audit the workload configs. Accepted values are MODE_UNSPECIFIED, DISABLED, BASIC.`,
},
},
},
AtLeastOneOf: []string{
"protect_config.0.workload_config",
"protect_config.0.workload_vulnerability_mode",
},
},
"workload_vulnerability_mode": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: `WorkloadVulnerabilityMode defines mode to perform vulnerability scanning. Accepted values are WORKLOAD_VULNERABILITY_MODE_UNSPECIFIED, DISABLED, BASIC.`,
AtLeastOneOf: []string{
"protect_config.0.workload_config",
"protect_config.0.workload_vulnerability_mode",
},
},
},
},
},
<% end -%>


"monitoring_config": {
Type: schema.TypeList,
Expand Down Expand Up @@ -1978,6 +2022,7 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
ResourceLabels: expandStringMap(d, "resource_labels"),
<% unless version == 'ga' -%>
NodePoolAutoConfig: expandNodePoolAutoConfig(d.Get("node_pool_auto_config")),
ProtectConfig: expandProtectConfig(d.Get("protect_config")),
<% end -%>
CostManagementConfig: expandCostManagementConfig(d.Get("cost_management_config")),
}
Expand Down Expand Up @@ -2516,6 +2561,12 @@ func resourceContainerClusterRead(d *schema.ResourceData, meta interface{}) erro
return err
}

<% unless version == 'ga' -%>
if err := d.Set("protect_config", flattenProtectConfig(cluster.ProtectConfig)); err != nil {
return err
}
<% end -%>

return nil
}

Expand Down Expand Up @@ -3636,6 +3687,22 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
return err
}

<% unless version == 'ga' -%>
if d.HasChange("protect_config") {
req := &container.UpdateClusterRequest{
Update: &container.ClusterUpdate{
DesiredProtectConfig: expandProtectConfig(d.Get("protect_config")),
},
}
updateF := updateFunc(req, "updating GKE cluster master protect_config")
if err := lockedCall(lockKey, updateF); err != nil {
return err
}

log.Printf("[INFO] GKE cluster %s Protect Config has been updated to %#v", d.Id(), req.Update.DesiredProtectConfig)
}
<% end -%>

return resourceContainerClusterRead(d, meta)
}

Expand Down Expand Up @@ -4201,6 +4268,57 @@ func expandAuthenticatorGroupsConfig(configured interface{}) *container.Authenti
return result
}

<% unless version == 'ga' -%>
func expandProtectConfig(configured interface{}) *container.ProtectConfig {
l := configured.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil
}

pc := &container.ProtectConfig{}
protectConfig := l[0].(map[string]interface{})
pc.WorkloadConfig = expandProtectConfigWorkloadConfig(protectConfig["workload_config"])
if v, ok := protectConfig["workload_vulnerability_mode"]; ok {
pc.WorkloadVulnerabilityMode = v.(string)
}
return pc
}

func expandProtectConfigWorkloadConfig(configured interface{}) *container.WorkloadConfig {
l := configured.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil
}
workloadConfig := l[0].(map[string]interface{})
return &container.WorkloadConfig{
AuditMode: workloadConfig["audit_mode"].(string),
}
}

func flattenProtectConfig(pc *container.ProtectConfig) []map[string]interface{} {
if pc == nil {
return nil
}

result := make(map[string]interface{})

result["workload_config"] = flattenProtectConfigWorkloadConfig(pc.WorkloadConfig)
result["workload_vulnerability_mode"] = pc.WorkloadVulnerabilityMode

return []map[string]interface{}{result}
}

func flattenProtectConfigWorkloadConfig(wc *container.WorkloadConfig) []map[string]interface{} {
if wc == nil {
return nil
}

result := make(map[string]interface{})
result["audit_mode"] = wc.AuditMode

return []map[string]interface{}{result}
}
<% end -%>

func expandNotificationConfig(configured interface{}) *container.NotificationConfig {
l := configured.([]interface{})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3500,6 +3500,38 @@ func TestAccContainerCluster_withTPUConfig(t *testing.T) {
},
})
}

func TestAccContainerCluster_withProtectConfig(t *testing.T) {
t.Parallel()

clusterName := fmt.Sprintf("tf-test-cluster-%s", randString(t, 10))

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccContainerCluster_withProtectConfig(clusterName),
},
{
ResourceName: "google_container_cluster.primary",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"min_master_version"},
},
{
Config: testAccContainerCluster_withProtectConfigUpdated(clusterName),
},
{
ResourceName: "google_container_cluster.primary",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"min_master_version"},
},
},
})
}
<% end -%>

func testAccContainerCluster_masterAuthorizedNetworksDisabled(t *testing.T, resource_name string) resource.TestCheckFunc {
Expand Down Expand Up @@ -7318,6 +7350,43 @@ resource "google_container_cluster" "primary" {
}`, cluster, project, project)
}

<% unless version == 'ga' -%>
func testAccContainerCluster_withProtectConfig(name string) string {
return fmt.Sprintf(`
resource "google_container_cluster" "primary" {
name = "%s"
location = "us-central1-a"
initial_node_count = 1

protect_config {
workload_config {
audit_mode = "BASIC"
}
workload_vulnerability_mode = "BASIC"
}
}
`, name)
}

func testAccContainerCluster_withProtectConfigUpdated(name string) string {
return fmt.Sprintf(`
resource "google_container_cluster" "primary" {
name = "%s"
location = "us-central1-a"
initial_node_count = 1

protect_config {
workload_config {
audit_mode = "DISABLED"
}
workload_vulnerability_mode = "DISABLED"
}
}
`, name)
}
<% end -%>


<% unless version == 'ga' -%>
func TestValidateNodePoolAutoConfig(t *testing.T) {
withTags := &container.NodePoolAutoConfig{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,9 @@ subnetwork in which the cluster's instances are launched.
* `gateway_api_config` - (Optional)
Configuration for [GKE Gateway API controller](https://cloud.google.com/kubernetes-engine/docs/concepts/gateway-api). Structure is [documented below](#nested_gateway_api_config).

* `protect_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html))
Enable/Disable Protect API features for the cluster. Structure is [documented below](#nested_protect_config).

<a name="nested_default_snat_status"></a>The `default_snat_status` block supports

* `disabled` - (Required) Whether the cluster disables default in-node sNAT rules. In-node sNAT rules will be disabled when defaultSnatStatus is disabled.When disabled is set to false, default IP masquerade rules will be applied to the nodes to prevent sNAT on cluster internal traffic
Expand Down Expand Up @@ -1141,6 +1144,16 @@ and all pods running on the nodes. Specified as a map from the key, such as

* `channel` - (Required) Which Gateway Api channel should be used. `CHANNEL_DISABLED` or `CHANNEL_STANDARD`.

<a name="nested_protect_config"></a>The `protect_config` block supports:

* `workload_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) WorkloadConfig defines which actions are enabled for a cluster's workload configurations. Structure is [documented below](#nested_workload_config)

* `workload_vulnerability_mode` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Sets which mode to use for Protect workload vulnerability scanning feature. Accepted values are WORKLOAD_VULNERABILITY_MODE_UNSPECIFIED, DISABLED, BASIC.

<a name="nested_workload_config"></a>The `protect_config.workload_config` block supports:

* `auditMode` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) WorkloadConfig defines the flags to enable or disable the workload configurations for the cluster. Accepted values are MODE_UNSPECIFIED, DISABLED, BASIC.

## Attributes Reference

In addition to the arguments listed above, the following computed attributes are
Expand Down

0 comments on commit 974faae

Please sign in to comment.