Skip to content

Commit

Permalink
added maintenance exclusions to GKE (#4197) (#7830)
Browse files Browse the repository at this point in the history
* added maintenance exclusions to GKE

* exclusion name added to the schema

* PR comments implemented

* spacing corrected in doc

Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
modular-magician authored Nov 17, 2020
1 parent f7f9db2 commit 88766e5
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 4 deletions.
4 changes: 4 additions & 0 deletions .changelog/4197.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
```release-note:enhancement
container : added maintenance_exclusions_window to `resource_google_container_cluster`

```
48 changes: 48 additions & 0 deletions google/resource_container_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,30 @@ func resourceContainerCluster() *schema.Resource {
},
},
},
"maintenance_exclusion": {
Type: schema.TypeSet,
Optional: true,
MaxItems: 3,
Description: `Exceptions to maintenance window. Non-emergency maintenance should not occur in these windows.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"exclusion_name": {
Type: schema.TypeString,
Required: true,
},
"start_time": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateRFC3339Date,
},
"end_time": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateRFC3339Date,
},
},
},
},
},
},
},
Expand Down Expand Up @@ -2353,6 +2377,16 @@ func expandMaintenancePolicy(d *schema.ResourceData, meta interface{}) *containe
}
maintenancePolicy := l[0].(map[string]interface{})

if maintenanceExclusions, ok := maintenancePolicy["maintenance_exclusion"]; ok && len(maintenanceExclusions.(*schema.Set).List()) > 0 {
for _, me := range maintenanceExclusions.(*schema.Set).List() {
exclusion := me.(map[string]interface{})
exclusions[exclusion["exclusion_name"].(string)] = containerBeta.TimeWindow{
StartTime: exclusion["start_time"].(string),
EndTime: exclusion["end_time"].(string),
}
}
}

if dailyMaintenanceWindow, ok := maintenancePolicy["daily_maintenance_window"]; ok && len(dailyMaintenanceWindow.([]interface{})) > 0 {
dmw := dailyMaintenanceWindow.([]interface{})[0].(map[string]interface{})
startTime := dmw["start_time"].(string)
Expand Down Expand Up @@ -2782,6 +2816,18 @@ func flattenMaintenancePolicy(mp *containerBeta.MaintenancePolicy) []map[string]
if mp == nil || mp.Window == nil {
return nil
}

exclusions := []map[string]interface{}{}
if mp.Window.MaintenanceExclusions != nil {
for wName, window := range mp.Window.MaintenanceExclusions {
exclusions = append(exclusions, map[string]interface{}{
"start_time": window.StartTime,
"end_time": window.EndTime,
"exclusion_name": wName,
})
}
}

if mp.Window.DailyMaintenanceWindow != nil {
return []map[string]interface{}{
{
Expand All @@ -2791,6 +2837,7 @@ func flattenMaintenancePolicy(mp *containerBeta.MaintenancePolicy) []map[string]
"duration": mp.Window.DailyMaintenanceWindow.Duration,
},
},
"maintenance_exclusion": exclusions,
},
}
}
Expand All @@ -2804,6 +2851,7 @@ func flattenMaintenancePolicy(mp *containerBeta.MaintenancePolicy) []map[string]
"recurrence": mp.Window.RecurringWindow.Recurrence,
},
},
"maintenance_exclusion": exclusions,
},
}
}
Expand Down
88 changes: 88 additions & 0 deletions google/resource_container_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,38 @@ func TestAccContainerCluster_withRecurringMaintenanceWindow(t *testing.T) {
})
}

func TestAccContainerCluster_withMaintenanceExclusionWindow(t *testing.T) {
t.Parallel()
cluster := fmt.Sprintf("tf-test-cluster-%s", randString(t, 10))
resourceName := "google_container_cluster.with_maintenance_exclusion_window"

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccContainerCluster_withExclusion_RecurringMaintenanceWindow(cluster, "2019-01-01T00:00:00Z", "2019-01-02T00:00:00Z", "2019-05-01T00:00:00Z", "2019-05-02T00:00:00Z"),
},
{
ResourceName: resourceName,
ImportStateIdPrefix: "us-central1-a/",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccContainerCluster_withExclusion_DailyMaintenanceWindow(cluster, "2020-01-01T00:00:00Z", "2020-01-02T00:00:00Z", "2020-05-01T00:00:00Z", "2020-05-02T00:00:00Z"),
},
{
ResourceName: resourceName,
ImportStateIdPrefix: "us-central1-a/",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

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

Expand Down Expand Up @@ -2791,6 +2823,62 @@ resource "google_container_cluster" "with_recurring_maintenance_window" {

}

func testAccContainerCluster_withExclusion_RecurringMaintenanceWindow(clusterName string, w1startTime, w1endTime, w2startTime, w2endTime string) string {

return fmt.Sprintf(`
resource "google_container_cluster" "with_maintenance_exclusion_window" {
name = "%s"
location = "us-central1-a"
initial_node_count = 1
maintenance_policy {
recurring_window {
start_time = "%s"
end_time = "%s"
recurrence = "FREQ=DAILY"
}
maintenance_exclusion {
exclusion_name = "batch job"
start_time = "%s"
end_time = "%s"
}
maintenance_exclusion {
exclusion_name = "holiday data load"
start_time = "%s"
end_time = "%s"
}
}
}
`, clusterName, w1startTime, w1endTime, w1startTime, w1endTime, w2startTime, w2endTime)
}

func testAccContainerCluster_withExclusion_DailyMaintenanceWindow(clusterName string, w1startTime, w1endTime, w2startTime, w2endTime string) string {

return fmt.Sprintf(`
resource "google_container_cluster" "with_maintenance_exclusion_window" {
name = "%s"
location = "us-central1-a"
initial_node_count = 1
maintenance_policy {
daily_maintenance_window {
start_time = "03:00"
}
maintenance_exclusion {
exclusion_name = "batch job"
start_time = "%s"
end_time = "%s"
}
maintenance_exclusion {
exclusion_name = "holiday data load"
start_time = "%s"
end_time = "%s"
}
}
}
`, clusterName, w1startTime, w1endTime, w2startTime, w2endTime)
}

func testAccContainerCluster_withIPAllocationPolicy_existingSecondaryRanges(containerNetName string, clusterName string) string {
return fmt.Sprintf(`
resource "google_compute_network" "container_network" {
Expand Down
40 changes: 36 additions & 4 deletions website/docs/r/container_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -449,11 +449,17 @@ The `authenticator_groups_config` block supports:
* `security_group` - (Required) The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format `[email protected]`.

The `maintenance_policy` block supports:
* `daily_maintenance_window` - (Optional) structure documented below.
* `recurring_window` - (Optional) structure documented below
* `maintenance_exclusion` - (Optional) structure documented below

* `daily_maintenance_window` - (Required in GA, Optional in Beta) Time window specified for daily maintenance operations.
In beta, one or the other of `recurring_window` and `daily_maintenance_window` is required if a `maintenance_policy` block is supplied.

* `daily_maintenance_window` - Time window specified for daily maintenance operations.
Specify `start_time` in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) format "HH:MM”,
where HH : \[00-23\] and MM : \[00-59\] GMT. For example:

Examples:
```hcl
maintenance_policy {
daily_maintenance_window {
Expand All @@ -462,8 +468,7 @@ maintenance_policy {
}
```

* `recurring_window` - (Optional) Time window for
recurring maintenance operations.
* `recurring_window` - Time window for recurring maintenance operations.

Specify `start_time` and `end_time` in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) "Zulu" date format. The start time's date is
the initial date that the window starts, and the end time is used for calculating duration. Specify `recurrence` in
Expand Down Expand Up @@ -491,7 +496,34 @@ maintenance_policy {
}
```

In beta, one or the other of `recurring_window` and `daily_maintenance_window` is required if a `maintenance_policy` block is supplied.
* `maintenance_exclusion` - Exceptions to maintenance window. Non-emergency maintenance should not occur in these windows. A cluster can have up to three maintenance exclusions at a time [Maintenance Window and Exclusions](https://cloud.google.com/kubernetes-engine/docs/concepts/maintenance-windows-and-exclusions)

Specify `start_time` and `end_time` in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) "Zulu" date format. The start time's date is
the initial date that the window starts, and the end time is used for calculating duration.Specify `recurrence` in
[RFC5545](https://tools.ietf.org/html/rfc5545#section-3.8.5.3) RRULE format, to specify when this recurs.
Note that GKE may accept other formats, but will return values in UTC, causing a permanent diff.

Examples:

```
maintenance_policy {
recurring_window {
start_time = "2019-01-01T00:00:00Z"
end_time = "2019-01-02T00:00:00Z"
recurrence = "FREQ=DAILY"
}
maintenance_exclusion{
exclusion_name = "batch job"
start_time = "2019-01-01T00:00:00Z"
end_time = "2019-01-02T00:00:00Z"
}
maintenance_exclusion{
exclusion_name = "holiday data load"
start_time = "2019-05-01T00:00:00Z"
end_time = "2019-05-02T00:00:00Z"
}
}
```

The `ip_allocation_policy` block supports:

Expand Down

0 comments on commit 88766e5

Please sign in to comment.