Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added upgrade_settings with validation for SURGE strategy with promoting min_cpu_platform to GA #13199

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changelog/6815.txt
@@ -0,0 +1,6 @@
```release-note:enhancement
container: added `auto_provisioning_defaults.cluster_autoscaling.upgrade_settings` in `google_container_cluster`
```
```release-note:enhancement
container: promoted `min_cpu_platform` in `google_container_cluster` to GA
```
221 changes: 214 additions & 7 deletions google/resource_container_cluster.go
Expand Up @@ -171,6 +171,7 @@ func resourceContainerCluster() *schema.Resource {
containerClusterAutopilotCustomizeDiff,
containerClusterNodeVersionRemoveDefaultCustomizeDiff,
containerClusterNetworkPolicyEmptyCustomizeDiff,
containerClusterSurgeSettingsCustomizeDiff,
),

Timeouts: &schema.ResourceTimeout{
Expand Down Expand Up @@ -458,6 +459,12 @@ func resourceContainerCluster() *schema.Resource {
DiffSuppressFunc: suppressDiffForAutopilot,
ValidateFunc: validation.StringInSlice([]string{"COS_CONTAINERD", "COS", "UBUNTU_CONTAINERD", "UBUNTU"}, false),
},
"min_cpu_platform": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: emptyOrDefaultStringSuppress("automatic"),
Description: `Minimum CPU platform to be used by this instance. The instance may be scheduled on the specified or newer CPU platform. Applicable values are the friendly names of CPU platforms, such as Intel Haswell.`,
},
"boot_disk_kms_key": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -536,6 +543,93 @@ func resourceContainerCluster() *schema.Resource {
},
},
},
"upgrade_settings": {
Type: schema.TypeList,
Optional: true,
Description: `Specifies the upgrade settings for NAP created node pools`,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"max_surge": {
Type: schema.TypeInt,
Optional: true,
Description: `The maximum number of nodes that can be created beyond the current size of the node pool during the upgrade process.`,
},
"max_unavailable": {
Type: schema.TypeInt,
Optional: true,
Description: `The maximum number of nodes that can be simultaneously unavailable during the upgrade process.`,
},
"strategy": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: `Update strategy of the node pool.`,
ValidateFunc: validation.StringInSlice([]string{"NODE_POOL_UPDATE_STRATEGY_UNSPECIFIED", "BLUE_GREEN", "SURGE"}, false),
},
"blue_green_settings": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Description: `Settings for blue-green upgrade strategy.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"node_pool_soak_duration": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: `Time needed after draining entire blue pool. After this period, blue pool will be cleaned up.

A duration in seconds with up to nine fractional digits, ending with 's'. Example: "3.5s".`,
},
"standard_rollout_policy": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Description: `Standard policy for the blue-green upgrade.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"batch_percentage": {
Type: schema.TypeFloat,
Optional: true,
Computed: true,
ValidateFunc: validation.FloatBetween(0.0, 1.0),
ExactlyOneOf: []string{
"cluster_autoscaling.0.auto_provisioning_defaults.0.upgrade_settings.0.blue_green_settings.0.standard_rollout_policy.0.batch_percentage",
"cluster_autoscaling.0.auto_provisioning_defaults.0.upgrade_settings.0.blue_green_settings.0.standard_rollout_policy.0.batch_node_count",
},
Description: `Percentage of the bool pool nodes to drain in a batch. The range of this field should be (0.0, 1.0].`,
},
"batch_node_count": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ExactlyOneOf: []string{
"cluster_autoscaling.0.auto_provisioning_defaults.0.upgrade_settings.0.blue_green_settings.0.standard_rollout_policy.0.batch_percentage",
"cluster_autoscaling.0.auto_provisioning_defaults.0.upgrade_settings.0.blue_green_settings.0.standard_rollout_policy.0.batch_node_count",
},
Description: `Number of blue nodes to drain in a batch.`,
},
"batch_soak_duration": {
Type: schema.TypeString,
Optional: true,
Default: "0s",
Description: `Soak time after each batch gets drained.

A duration in seconds with up to nine fractional digits, ending with 's'. Example: "3.5s".`,
},
},
},
},
},
},
},
},
},
},
},
},
},
Expand Down Expand Up @@ -3448,13 +3542,14 @@ func expandAutoProvisioningDefaults(configured interface{}, d *schema.ResourceDa
config := l[0].(map[string]interface{})

npd := &container.AutoprovisioningNodePoolDefaults{
OauthScopes: convertStringArr(config["oauth_scopes"].([]interface{})),
ServiceAccount: config["service_account"].(string),
DiskSizeGb: int64(config["disk_size"].(int)),
DiskType: config["disk_type"].(string),
ImageType: config["image_type"].(string),
BootDiskKmsKey: config["boot_disk_kms_key"].(string),
Management: expandManagement(config["management"]),
OauthScopes: convertStringArr(config["oauth_scopes"].([]interface{})),
ServiceAccount: config["service_account"].(string),
DiskSizeGb: int64(config["disk_size"].(int)),
DiskType: config["disk_type"].(string),
ImageType: config["image_type"].(string),
BootDiskKmsKey: config["boot_disk_kms_key"].(string),
Management: expandManagement(config["management"]),
UpgradeSettings: expandUpgradeSettings(config["upgrade_settings"]),
}

if v, ok := config["shielded_instance_config"]; ok && len(v.([]interface{})) > 0 {
Expand All @@ -3465,9 +3560,64 @@ func expandAutoProvisioningDefaults(configured interface{}, d *schema.ResourceDa
}
}

cpu := config["min_cpu_platform"].(string)
// the only way to unset the field is to pass "automatic" as its value
if cpu == "" {
cpu = "automatic"
}
npd.MinCpuPlatform = cpu

return npd
}

func expandUpgradeSettings(configured interface{}) *container.UpgradeSettings {
l, ok := configured.([]interface{})
if !ok || l == nil || len(l) == 0 || l[0] == nil {
return &container.UpgradeSettings{}
}
config := l[0].(map[string]interface{})

upgradeSettings := &container.UpgradeSettings{
MaxSurge: int64(config["max_surge"].(int)),
MaxUnavailable: int64(config["max_unavailable"].(int)),
Strategy: config["strategy"].(string),
BlueGreenSettings: expandBlueGreenSettings(config["blue_green_settings"]),
}

return upgradeSettings
}

func expandBlueGreenSettings(configured interface{}) *container.BlueGreenSettings {
l, ok := configured.([]interface{})
if !ok || l == nil || len(l) == 0 || l[0] == nil {
return &container.BlueGreenSettings{}
}
config := l[0].(map[string]interface{})

blueGreenSettings := &container.BlueGreenSettings{
NodePoolSoakDuration: config["node_pool_soak_duration"].(string),
StandardRolloutPolicy: expandStandardRolloutPolicy(config["standard_rollout_policy"]),
}

return blueGreenSettings
}

func expandStandardRolloutPolicy(configured interface{}) *container.StandardRolloutPolicy {
l, ok := configured.([]interface{})
if !ok || l == nil || len(l) == 0 || l[0] == nil {
return &container.StandardRolloutPolicy{}
}

config := l[0].(map[string]interface{})
standardRolloutPolicy := &container.StandardRolloutPolicy{
BatchPercentage: config["batch_percentage"].(float64),
BatchNodeCount: int64(config["batch_node_count"].(int)),
BatchSoakDuration: config["batch_soak_duration"].(string),
}

return standardRolloutPolicy
}

func expandManagement(configured interface{}) *container.NodeManagement {
l, ok := configured.([]interface{})
if !ok || l == nil || len(l) == 0 || l[0] == nil {
Expand Down Expand Up @@ -4304,9 +4454,49 @@ func flattenAutoProvisioningDefaults(a *container.AutoprovisioningNodePoolDefaul
r["disk_size"] = a.DiskSizeGb
r["disk_type"] = a.DiskType
r["image_type"] = a.ImageType
r["min_cpu_platform"] = a.MinCpuPlatform
r["boot_disk_kms_key"] = a.BootDiskKmsKey
r["shielded_instance_config"] = flattenShieldedInstanceConfig(a.ShieldedInstanceConfig)
r["management"] = flattenManagement(a.Management)
r["upgrade_settings"] = flattenUpgradeSettings(a.UpgradeSettings)

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

func flattenUpgradeSettings(a *container.UpgradeSettings) []map[string]interface{} {
if a == nil {
return nil
}
r := make(map[string]interface{})
r["max_surge"] = a.MaxSurge
r["max_unavailable"] = a.MaxUnavailable
r["strategy"] = a.Strategy
r["blue_green_settings"] = flattenBlueGreenSettings(a.BlueGreenSettings)

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

func flattenBlueGreenSettings(a *container.BlueGreenSettings) []map[string]interface{} {
if a == nil {
return nil
}

r := make(map[string]interface{})
r["node_pool_soak_duration"] = a.NodePoolSoakDuration
r["standard_rollout_policy"] = flattenStandardRolloutPolicy(a.StandardRolloutPolicy)

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

func flattenStandardRolloutPolicy(a *container.StandardRolloutPolicy) []map[string]interface{} {
if a == nil {
return nil
}

r := make(map[string]interface{})
r["batch_percentage"] = a.BatchPercentage
r["batch_node_count"] = a.BatchNodeCount
r["batch_soak_duration"] = a.BatchSoakDuration

return []map[string]interface{}{r}
}
Expand Down Expand Up @@ -4667,3 +4857,20 @@ func BinaryAuthorizationDiffSuppress(k, old, new string, r *schema.ResourceData)

return false
}

func containerClusterSurgeSettingsCustomizeDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error {
if v, ok := d.GetOk("cluster_autoscaling.0.auto_provisioning_defaults.0.upgrade_settings.0.strategy"); ok {
if v != "SURGE" {
if _, maxSurgeIsPresent := d.GetOk("cluster_autoscaling.0.auto_provisioning_defaults.0.upgrade_settings.0.max_surge"); maxSurgeIsPresent {
return fmt.Errorf("Surge upgrade settings max_surge/max_unavailable can only be used when strategy is set to SURGE")
}
}
if v != "SURGE" {
if _, maxSurgeIsPresent := d.GetOk("cluster_autoscaling.0.auto_provisioning_defaults.0.upgrade_settings.0.max_unavailable"); maxSurgeIsPresent {
return fmt.Errorf("Surge upgrade settings max_surge/max_unavailable can only be used when strategy is set to SURGE")
}
}
}

return nil
}