Skip to content

Commit

Permalink
Added upgrade_settings with validation for SURGE strategy with promot…
Browse files Browse the repository at this point in the history
…ing min_cpu_platform to GA (#6815) (#13199)

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

Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
modular-magician authored Dec 8, 2022
1 parent d075c82 commit a7fa41b
Show file tree
Hide file tree
Showing 4 changed files with 419 additions and 7 deletions.
6 changes: 6 additions & 0 deletions .changelog/6815.txt
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
}
Loading

0 comments on commit a7fa41b

Please sign in to comment.