Skip to content

Commit

Permalink
Add field node_pool_defaults to resource_container_cluster. (#6488)…
Browse files Browse the repository at this point in the history
… (#4648)

* Support enabling GKE image streaming at the cluster level. See hashicorp/terraform-provider-google#10509

* minor fix to schemaGcfsConfig method.

* Support update node pool default configuration at the cluster level.

* Address comments from GoogleCloudPlatform/magic-modules#6488.

Signed-off-by: Modular Magician <[email protected]>

Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
modular-magician authored Sep 1, 2022
1 parent 4741227 commit 5dd6527
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 17 deletions.
4 changes: 4 additions & 0 deletions .changelog/6488.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
```release-note:enhancement
container: added field `node_pool_defaults` to `resource_container_cluster`.

```
68 changes: 51 additions & 17 deletions google-beta/node_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,26 @@ var defaultOauthScopes = []string{
"https://www.googleapis.com/auth/trace.append",
}

func schemaGcfsConfig(forceNew bool) *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: `GCFS configuration for this node.`,
ForceNew: forceNew,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"enabled": {
Type: schema.TypeBool,
Required: true,
ForceNew: forceNew,
Description: `Whether or not GCFS is enabled`,
},
},
},
}
}

func schemaNodeConfig() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Expand Down Expand Up @@ -126,23 +146,7 @@ func schemaNodeConfig() *schema.Schema {
},
},

"gcfs_config": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: `GCFS configuration for this node.`,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"enabled": {
Type: schema.TypeBool,
Required: true,
ForceNew: true,
Description: `Whether or not GCFS is enabled`,
},
},
},
},
"gcfs_config": schemaGcfsConfig(true),

"gvnic": {
Type: schema.TypeList,
Expand Down Expand Up @@ -427,6 +431,23 @@ func schemaNodeConfig() *schema.Schema {
}
}

func expandNodeConfigDefaults(configured interface{}) *container.NodeConfigDefaults {
configs := configured.([]interface{})
if len(configs) == 0 || configs[0] == nil {
return nil
}
config := configs[0].(map[string]interface{})

nodeConfigDefaults := &container.NodeConfigDefaults{}
if v, ok := config["gcfs_config"]; ok && len(v.([]interface{})) > 0 {
gcfsConfig := v.([]interface{})[0].(map[string]interface{})
nodeConfigDefaults.GcfsConfig = &container.GcfsConfig{
Enabled: gcfsConfig["enabled"].(bool),
}
}
return nodeConfigDefaults
}

func expandNodeConfig(v interface{}) *container.NodeConfig {
nodeConfigs := v.([]interface{})
nc := &container.NodeConfig{
Expand Down Expand Up @@ -679,6 +700,19 @@ func expandLinuxNodeConfig(v interface{}) *container.LinuxNodeConfig {
}
}

func flattenNodeConfigDefaults(c *container.NodeConfigDefaults) []map[string]interface{} {
result := make([]map[string]interface{}, 0, 1)

if c == nil {
return result
}

result = append(result, map[string]interface{}{
"gcfs_config": flattenGcfsConfig(c.GcfsConfig),
})
return result
}

func flattenNodeConfig(c *container.NodeConfig) []map[string]interface{} {
config := make([]map[string]interface{}, 0, 1)

Expand Down
82 changes: 82 additions & 0 deletions google-beta/resource_container_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,33 @@ func clusterSchemaNodeConfig() *schema.Schema {
return nodeConfigSch
}

// Defines default nodel pool settings for the entire cluster. These settings are
// overridden if specified on the specific NodePool object.
func clusterSchemaNodePoolDefaults() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Optional: true,
DiffSuppressFunc: emptyOrUnsetBlockDiffSuppress,
Description: `The default nodel pool settings for the entire cluster.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"node_config_defaults": {
Type: schema.TypeList,
Optional: true,
Description: `Subset of NodeConfig message that has defaults.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"gcfs_config": schemaGcfsConfig(false),
},
},
},
},
},
}
}

func rfc5545RecurrenceDiffSuppress(k, o, n string, d *schema.ResourceData) bool {
// This diff gets applied in the cloud console if you specify
// "FREQ=DAILY" in your config and add a maintenance exclusion.
Expand Down Expand Up @@ -983,6 +1010,8 @@ func resourceContainerCluster() *schema.Resource {
ConflictsWith: []string{"enable_autopilot"},
},

"node_pool_defaults": clusterSchemaNodePoolDefaults(),

"node_pool_auto_config": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -1719,6 +1748,10 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
cluster.NodeConfig = expandNodeConfig([]interface{}{})
}

if v, ok := d.GetOk("node_pool_defaults"); ok {
cluster.NodePoolDefaults = expandNodePoolDefaults(v)
}

if v, ok := d.GetOk("node_config"); ok {
cluster.NodeConfig = expandNodeConfig(v)
}
Expand Down Expand Up @@ -2143,6 +2176,10 @@ func resourceContainerClusterRead(d *schema.ResourceData, meta interface{}) erro
return err
}

if err := d.Set("node_pool_defaults", flattenNodePoolDefaults(cluster.NodePoolDefaults)); err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -3094,6 +3131,27 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
log.Printf("[INFO] GKE cluster %s resource usage export config has been updated", d.Id())
}

if d.HasChange("node_pool_defaults") && d.HasChange("node_pool_defaults.0.node_config_defaults.0.gcfs_config") {
if v, ok := d.GetOk("node_pool_defaults.0.node_config_defaults.0.gcfs_config"); ok {
gcfsConfig := v.([]interface{})[0].(map[string]interface{})
req := &container.UpdateClusterRequest{
Update: &container.ClusterUpdate{
DesiredGcfsConfig: &container.GcfsConfig{
Enabled: gcfsConfig["enabled"].(bool),
},
},
}

updateF := updateFunc(req, "updating GKE cluster desired gcfs config.")
// Call update serially.
if err := lockedCall(lockKey, updateF); err != nil {
return err
}

log.Printf("[INFO] GKE cluster %s default gcfs config has been updated", d.Id())
}
}

if d.HasChange("node_pool_auto_config.0.network_tags.0.tags") {
tags := d.Get("node_pool_auto_config.0.network_tags.0.tags").([]interface{})

Expand Down Expand Up @@ -4017,6 +4075,30 @@ func expandContainerClusterAuthenticatorGroupsConfig(configured interface{}) *co
}
}

func expandNodePoolDefaults(configured interface{}) *container.NodePoolDefaults {
l, ok := configured.([]interface{})
if !ok || l == nil || len(l) == 0 || l[0] == nil {
return nil
}
nodePoolDefaults := &container.NodePoolDefaults{}
config := l[0].(map[string]interface{})
if v, ok := config["node_config_defaults"]; ok && len(v.([]interface{})) > 0 {
nodePoolDefaults.NodeConfigDefaults = expandNodeConfigDefaults(v)
}
return nodePoolDefaults
}

func flattenNodePoolDefaults(c *container.NodePoolDefaults) []map[string]interface{} {
if c == nil {
return nil
}
result := make(map[string]interface{})
if c.NodeConfigDefaults != nil && c.NodeConfigDefaults.GcfsConfig != nil {
result["node_config_defaults"] = flattenNodeConfigDefaults(c.NodeConfigDefaults)
}
return []map[string]interface{}{result}
}

func expandNodePoolAutoConfig(configured interface{}) *container.NodePoolAutoConfig {
l := configured.([]interface{})
if len(l) == 0 || l[0] == nil {
Expand Down
71 changes: 71 additions & 0 deletions google-beta/resource_container_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,59 @@ func TestAccContainerCluster_withNodeConfig(t *testing.T) {
})
}

func TestAccContainerCluster_withNodePoolDefaults(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_basic(clusterName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckNoResourceAttr("google_container_cluster.primary",
"node_pool_defaults.0.node_config_defaults.0.gcfs_config.0.enabled"),
),
},
{
ResourceName: "google_container_cluster.primary",
ImportStateId: fmt.Sprintf("us-central1-a/%s", clusterName),
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccContainerCluster_withNodePoolDefaults(clusterName, "true"),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("google_container_cluster.with_node_pool_defaults",
"node_pool_defaults.0.node_config_defaults.0.gcfs_config.#", "1"),
resource.TestCheckResourceAttr("google_container_cluster.with_node_pool_defaults",
"node_pool_defaults.0.node_config_defaults.0.gcfs_config.0.enabled", "true"),
),
},
{
ResourceName: "google_container_cluster.with_node_pool_defaults",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccContainerCluster_withNodePoolDefaults(clusterName, "false"),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("google_container_cluster.with_node_pool_defaults",
"node_pool_defaults.0.node_config_defaults.0.gcfs_config.#", "1"),
resource.TestCheckResourceAttr("google_container_cluster.with_node_pool_defaults",
"node_pool_defaults.0.node_config_defaults.0.gcfs_config.0.enabled", "false"),
),
},
{
ResourceName: "google_container_cluster.with_node_pool_defaults",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

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

Expand Down Expand Up @@ -3852,6 +3905,24 @@ resource "google_container_cluster" "with_node_config" {
`, clusterName)
}

func testAccContainerCluster_withNodePoolDefaults(clusterName, enabled string) string {
return fmt.Sprintf(`
resource "google_container_cluster" "with_node_pool_defaults" {
name = "%s"
location = "us-central1-f"
initial_node_count = 1
node_pool_defaults {
node_config_defaults {
gcfs_config {
enabled = "%s"
}
}
}
}
`, clusterName, enabled)
}

func testAccContainerCluster_withNodeConfigUpdate(clusterName string) string {
return fmt.Sprintf(`
resource "google_container_cluster" "with_node_config" {
Expand Down
9 changes: 9 additions & 0 deletions website/docs/r/container_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ region are guaranteed to support the same version.
[autopilot](https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview#comparison) clusters and
[node auto-provisioning](https://cloud.google.com/kubernetes-engine/docs/how-to/node-auto-provisioning)-enabled clusters. Structure is [documented below](#nested_node_pool_auto_config).

* `node_pool_defaults` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Default NodePool settings for the entire cluster. These settings are overridden if specified on the specific NodePool object. Structure is [documented below](#nested_node_pool_defaults).

* `node_version` - (Optional) The Kubernetes version on the nodes. Must either be unset
or set to the same value as `min_master_version` on create. Defaults to the default
version set by GKE which is not necessarily the latest version. This only affects
Expand Down Expand Up @@ -867,6 +869,13 @@ node_pool_auto_config {
}
```

<a name="nested_node_pool_defaults"></a>The `node_pool_defaults` block supports:
* `node_config_defaults` (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) - Subset of NodeConfig message that has defaults.

The `node_config_defaults` block supports:

* `gcfs_config` (Optional) The default Google Container Filesystem (GCFS) configuration at the cluster level. e.g. enable [image streaming](https://cloud.google.com/kubernetes-engine/docs/how-to/image-streaming) across all the node pools within the cluster. Structure is [documented below](#nested_gcfs_config).

<a name="nested_notification_config"></a>The `notification_config` block supports:

* `pubsub` (Required) - The pubsub config for the cluster's upgrade notifications.
Expand Down

0 comments on commit 5dd6527

Please sign in to comment.