Skip to content

Commit 93a5e1b

Browse files
Add exclusion scope in the maintenance exclusion (#5914) (#11662)
Signed-off-by: Modular Magician <[email protected]>
1 parent fd4a387 commit 93a5e1b

7 files changed

+308
-12
lines changed

.changelog/5914.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
container: added field `exclusion_options` to `google_container_cluster`
3+
```

google/resource_clouddeploy_delivery_pipeline_generated_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ resource "google_clouddeploy_delivery_pipeline" "primary" {
6767
name = "tf-test-pipeline%{random_suffix}"
6868
6969
annotations = {
70-
my_first_annotation = "example-annotation-1"
71-
7270
my_second_annotation = "example-annotation-2"
71+
72+
my_first_annotation = "example-annotation-1"
7373
}
7474
7575
description = "basic description"
@@ -106,9 +106,9 @@ resource "google_clouddeploy_delivery_pipeline" "primary" {
106106
name = "tf-test-pipeline%{random_suffix}"
107107
108108
annotations = {
109-
my_second_annotation = "updated-example-annotation-2"
110-
111109
my_third_annotation = "example-annotation-3"
110+
111+
my_second_annotation = "updated-example-annotation-2"
112112
}
113113
114114
description = "updated description"

google/resource_clouddeploy_target_generated_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,9 @@ resource "google_clouddeploy_target" "primary" {
136136
}
137137
138138
labels = {
139-
my_third_label = "example-label-3"
140-
141139
my_second_label = "updated-example-label-2"
140+
141+
my_third_label = "example-label-3"
142142
}
143143
144144
project = "%{project_name}"
@@ -241,9 +241,9 @@ resource "google_clouddeploy_target" "primary" {
241241
name = "tf-test-target%{random_suffix}"
242242
243243
annotations = {
244-
my_second_annotation = "updated-example-annotation-2"
245-
246244
my_third_annotation = "example-annotation-3"
245+
246+
my_second_annotation = "updated-example-annotation-2"
247247
}
248248
249249
description = "updated description"

google/resource_container_cluster.go

+42-2
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,22 @@ func resourceContainerCluster() *schema.Resource {
545545
Required: true,
546546
ValidateFunc: validateRFC3339Date,
547547
},
548+
"exclusion_options": {
549+
Type: schema.TypeList,
550+
Optional: true,
551+
MaxItems: 1,
552+
Description: `Maintenance exclusion related options.`,
553+
Elem: &schema.Resource{
554+
Schema: map[string]*schema.Schema{
555+
"scope": {
556+
Type: schema.TypeString,
557+
Required: true,
558+
ValidateFunc: validation.StringInSlice([]string{"NO_UPGRADES", "NO_MINOR_UPGRADES", "NO_MINOR_OR_NODE_UPGRADES"}, false),
559+
Description: `The scope of automatic upgrades to restrict in the exclusion window.`,
560+
},
561+
},
562+
},
563+
},
548564
},
549565
},
550566
},
@@ -2697,6 +2713,15 @@ func expandMaintenancePolicy(d *schema.ResourceData, meta interface{}) *containe
26972713
StartTime: exclusion["start_time"].(string),
26982714
EndTime: exclusion["end_time"].(string),
26992715
}
2716+
if exclusionOptions, ok := exclusion["exclusion_options"]; ok && len(exclusionOptions.([]interface{})) > 0 {
2717+
meo := exclusionOptions.([]interface{})[0].(map[string]interface{})
2718+
mex := exclusions[exclusion["exclusion_name"].(string)]
2719+
mex.MaintenanceExclusionOptions = &container.MaintenanceExclusionOptions{
2720+
Scope: meo["scope"].(string),
2721+
ForceSendFields: []string{"Scope"},
2722+
}
2723+
exclusions[exclusion["exclusion_name"].(string)] = mex
2724+
}
27002725
}
27012726
}
27022727

@@ -3260,11 +3285,26 @@ func flattenMaintenancePolicy(mp *container.MaintenancePolicy) []map[string]inte
32603285
exclusions := []map[string]interface{}{}
32613286
if mp.Window.MaintenanceExclusions != nil {
32623287
for wName, window := range mp.Window.MaintenanceExclusions {
3263-
exclusions = append(exclusions, map[string]interface{}{
3288+
exclusion := map[string]interface{}{
32643289
"start_time": window.StartTime,
32653290
"end_time": window.EndTime,
32663291
"exclusion_name": wName,
3267-
})
3292+
}
3293+
if window.MaintenanceExclusionOptions != nil {
3294+
// When the scope is set to NO_UPGRADES which is the default value,
3295+
// the maintenance exclusion returned by GCP will be empty.
3296+
// This seems like a bug. To workaround this, assign NO_UPGRADES to the scope explicitly
3297+
scope := "NO_UPGRADES"
3298+
if window.MaintenanceExclusionOptions.Scope != "" {
3299+
scope = window.MaintenanceExclusionOptions.Scope
3300+
}
3301+
exclusion["exclusion_options"] = []map[string]interface{}{
3302+
{
3303+
"scope": scope,
3304+
},
3305+
}
3306+
}
3307+
exclusions = append(exclusions, exclusion)
32683308
}
32693309
}
32703310

google/resource_container_cluster_test.go

+240
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,147 @@ func TestAccContainerCluster_withMaintenanceExclusionWindow(t *testing.T) {
12621262
})
12631263
}
12641264

1265+
func TestAccContainerCluster_withMaintenanceExclusionOptions(t *testing.T) {
1266+
t.Parallel()
1267+
cluster := fmt.Sprintf("tf-test-cluster-%s", randString(t, 10))
1268+
resourceName := "google_container_cluster.with_maintenance_exclusion_options"
1269+
1270+
vcrTest(t, resource.TestCase{
1271+
PreCheck: func() { testAccPreCheck(t) },
1272+
Providers: testAccProviders,
1273+
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
1274+
Steps: []resource.TestStep{
1275+
{
1276+
Config: testAccContainerCluster_withExclusionOptions_RecurringMaintenanceWindow(
1277+
cluster, "2019-01-01T00:00:00Z", "2019-01-02T00:00:00Z", "2019-05-01T00:00:00Z", "2019-05-02T00:00:00Z", "NO_MINOR_UPGRADES", "NO_MINOR_OR_NODE_UPGRADES"),
1278+
Check: resource.ComposeTestCheckFunc(
1279+
resource.TestCheckResourceAttr(resourceName,
1280+
"maintenance_policy.0.maintenance_exclusion.0.exclusion_options.0.scope", "NO_MINOR_UPGRADES"),
1281+
resource.TestCheckResourceAttr(resourceName,
1282+
"maintenance_policy.0.maintenance_exclusion.1.exclusion_options.0.scope", "NO_MINOR_OR_NODE_UPGRADES"),
1283+
),
1284+
},
1285+
{
1286+
ResourceName: resourceName,
1287+
ImportStateIdPrefix: "us-central1-a/",
1288+
ImportState: true,
1289+
ImportStateVerify: true,
1290+
},
1291+
},
1292+
})
1293+
}
1294+
1295+
func TestAccContainerCluster_deleteMaintenanceExclusionOptions(t *testing.T) {
1296+
t.Parallel()
1297+
cluster := fmt.Sprintf("tf-test-cluster-%s", randString(t, 10))
1298+
resourceName := "google_container_cluster.with_maintenance_exclusion_options"
1299+
1300+
vcrTest(t, resource.TestCase{
1301+
PreCheck: func() { testAccPreCheck(t) },
1302+
Providers: testAccProviders,
1303+
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
1304+
Steps: []resource.TestStep{
1305+
{
1306+
Config: testAccContainerCluster_withExclusionOptions_RecurringMaintenanceWindow(
1307+
cluster, "2019-01-01T00:00:00Z", "2019-01-02T00:00:00Z", "2019-05-01T00:00:00Z", "2019-05-02T00:00:00Z", "NO_UPGRADES", "NO_MINOR_OR_NODE_UPGRADES"),
1308+
Check: resource.ComposeTestCheckFunc(
1309+
resource.TestCheckResourceAttr(resourceName,
1310+
"maintenance_policy.0.maintenance_exclusion.0.exclusion_options.0.scope", "NO_UPGRADES"),
1311+
resource.TestCheckResourceAttr(resourceName,
1312+
"maintenance_policy.0.maintenance_exclusion.1.exclusion_options.0.scope", "NO_MINOR_OR_NODE_UPGRADES"),
1313+
),
1314+
},
1315+
{
1316+
ResourceName: resourceName,
1317+
ImportStateIdPrefix: "us-central1-a/",
1318+
ImportState: true,
1319+
ImportStateVerify: true,
1320+
},
1321+
{
1322+
Config: testAccContainerCluster_NoExclusionOptions_RecurringMaintenanceWindow(
1323+
cluster, "2019-01-01T00:00:00Z", "2019-01-02T00:00:00Z", "2019-05-01T00:00:00Z", "2019-05-02T00:00:00Z"),
1324+
Check: resource.ComposeTestCheckFunc(
1325+
resource.TestCheckNoResourceAttr(resourceName,
1326+
"maintenance_policy.0.maintenance_exclusion.0.exclusion_options.0.scope"),
1327+
resource.TestCheckNoResourceAttr(resourceName,
1328+
"maintenance_policy.0.maintenance_exclusion.1.exclusion_options.0.scope"),
1329+
),
1330+
},
1331+
{
1332+
ResourceName: resourceName,
1333+
ImportStateIdPrefix: "us-central1-a/",
1334+
ImportState: true,
1335+
ImportStateVerify: true,
1336+
},
1337+
},
1338+
})
1339+
}
1340+
1341+
func TestAccContainerCluster_updateMaintenanceExclusionOptions(t *testing.T) {
1342+
t.Parallel()
1343+
cluster := fmt.Sprintf("tf-test-cluster-%s", randString(t, 10))
1344+
resourceName := "google_container_cluster.with_maintenance_exclusion_options"
1345+
1346+
// step1: create a new cluster and initialize the maintenceExclusion without exclusion scopes,
1347+
// step2: add exclusion scopes to the maintenancePolicy,
1348+
// step3: update the maintenceExclusion with new scopes
1349+
vcrTest(t, resource.TestCase{
1350+
PreCheck: func() { testAccPreCheck(t) },
1351+
Providers: testAccProviders,
1352+
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
1353+
Steps: []resource.TestStep{
1354+
{
1355+
Config: testAccContainerCluster_NoExclusionOptions_RecurringMaintenanceWindow(
1356+
cluster, "2019-01-01T00:00:00Z", "2019-01-02T00:00:00Z", "2019-05-01T00:00:00Z", "2019-05-02T00:00:00Z"),
1357+
Check: resource.ComposeTestCheckFunc(
1358+
resource.TestCheckNoResourceAttr(resourceName,
1359+
"maintenance_policy.0.maintenance_exclusion.0.exclusion_options.0.scope"),
1360+
resource.TestCheckNoResourceAttr(resourceName,
1361+
"maintenance_policy.0.maintenance_exclusion.1.exclusion_options.0.scope"),
1362+
),
1363+
},
1364+
{
1365+
ResourceName: resourceName,
1366+
ImportStateIdPrefix: "us-central1-a/",
1367+
ImportState: true,
1368+
ImportStateVerify: true,
1369+
},
1370+
{
1371+
Config: testAccContainerCluster_withExclusionOptions_RecurringMaintenanceWindow(
1372+
cluster, "2019-01-01T00:00:00Z", "2019-01-02T00:00:00Z", "2019-05-01T00:00:00Z", "2019-05-02T00:00:00Z", "NO_MINOR_UPGRADES", "NO_MINOR_OR_NODE_UPGRADES"),
1373+
Check: resource.ComposeTestCheckFunc(
1374+
resource.TestCheckResourceAttr(resourceName,
1375+
"maintenance_policy.0.maintenance_exclusion.0.exclusion_options.0.scope", "NO_MINOR_UPGRADES"),
1376+
resource.TestCheckResourceAttr(resourceName,
1377+
"maintenance_policy.0.maintenance_exclusion.1.exclusion_options.0.scope", "NO_MINOR_OR_NODE_UPGRADES"),
1378+
),
1379+
},
1380+
{
1381+
ResourceName: resourceName,
1382+
ImportStateIdPrefix: "us-central1-a/",
1383+
ImportState: true,
1384+
ImportStateVerify: true,
1385+
},
1386+
{
1387+
Config: testAccContainerCluster_updateExclusionOptions_RecurringMaintenanceWindow(
1388+
cluster, "2019-01-01T00:00:00Z", "2019-01-02T00:00:00Z", "2019-05-01T00:00:00Z", "2019-05-02T00:00:00Z", "NO_UPGRADES", "NO_MINOR_UPGRADES"),
1389+
Check: resource.ComposeTestCheckFunc(
1390+
resource.TestCheckResourceAttr(resourceName,
1391+
"maintenance_policy.0.maintenance_exclusion.0.exclusion_options.0.scope", "NO_UPGRADES"),
1392+
resource.TestCheckResourceAttr(resourceName,
1393+
"maintenance_policy.0.maintenance_exclusion.1.exclusion_options.0.scope", "NO_MINOR_UPGRADES"),
1394+
),
1395+
},
1396+
{
1397+
ResourceName: resourceName,
1398+
ImportStateIdPrefix: "us-central1-a/",
1399+
ImportState: true,
1400+
ImportStateVerify: true,
1401+
},
1402+
},
1403+
})
1404+
}
1405+
12651406
func TestAccContainerCluster_deleteExclusionWindow(t *testing.T) {
12661407
t.Parallel()
12671408
cluster := fmt.Sprintf("tf-test-cluster-%s", randString(t, 10))
@@ -3283,6 +3424,105 @@ resource "google_container_cluster" "with_maintenance_exclusion_window" {
32833424
`, clusterName, w1startTime, w1endTime, w1startTime, w1endTime, w2startTime, w2endTime)
32843425
}
32853426

3427+
func testAccContainerCluster_withExclusionOptions_RecurringMaintenanceWindow(cclusterName string, w1startTime, w1endTime, w2startTime, w2endTime string, scope1, scope2 string) string {
3428+
3429+
return fmt.Sprintf(`
3430+
resource "google_container_cluster" "with_maintenance_exclusion_options" {
3431+
name = "%s"
3432+
location = "us-central1-a"
3433+
initial_node_count = 1
3434+
3435+
maintenance_policy {
3436+
recurring_window {
3437+
start_time = "%s"
3438+
end_time = "%s"
3439+
recurrence = "FREQ=DAILY"
3440+
}
3441+
maintenance_exclusion {
3442+
exclusion_name = "batch job"
3443+
start_time = "%s"
3444+
end_time = "%s"
3445+
exclusion_options {
3446+
scope = "%s"
3447+
}
3448+
}
3449+
maintenance_exclusion {
3450+
exclusion_name = "holiday data load"
3451+
start_time = "%s"
3452+
end_time = "%s"
3453+
exclusion_options {
3454+
scope = "%s"
3455+
}
3456+
}
3457+
}
3458+
}
3459+
`, cclusterName, w1startTime, w1endTime, w1startTime, w1endTime, scope1, w2startTime, w2endTime, scope2)
3460+
}
3461+
3462+
func testAccContainerCluster_NoExclusionOptions_RecurringMaintenanceWindow(cclusterName string, w1startTime, w1endTime, w2startTime, w2endTime string) string {
3463+
3464+
return fmt.Sprintf(`
3465+
resource "google_container_cluster" "with_maintenance_exclusion_options" {
3466+
name = "%s"
3467+
location = "us-central1-a"
3468+
initial_node_count = 1
3469+
3470+
maintenance_policy {
3471+
recurring_window {
3472+
start_time = "%s"
3473+
end_time = "%s"
3474+
recurrence = "FREQ=DAILY"
3475+
}
3476+
maintenance_exclusion {
3477+
exclusion_name = "batch job"
3478+
start_time = "%s"
3479+
end_time = "%s"
3480+
}
3481+
maintenance_exclusion {
3482+
exclusion_name = "holiday data load"
3483+
start_time = "%s"
3484+
end_time = "%s"
3485+
}
3486+
}
3487+
}
3488+
`, cclusterName, w1startTime, w1endTime, w1startTime, w1endTime, w2startTime, w2endTime)
3489+
}
3490+
3491+
func testAccContainerCluster_updateExclusionOptions_RecurringMaintenanceWindow(cclusterName string, w1startTime, w1endTime, w2startTime, w2endTime string, scope1, scope2 string) string {
3492+
3493+
return fmt.Sprintf(`
3494+
resource "google_container_cluster" "with_maintenance_exclusion_options" {
3495+
name = "%s"
3496+
location = "us-central1-a"
3497+
initial_node_count = 1
3498+
3499+
maintenance_policy {
3500+
recurring_window {
3501+
start_time = "%s"
3502+
end_time = "%s"
3503+
recurrence = "FREQ=DAILY"
3504+
}
3505+
maintenance_exclusion {
3506+
exclusion_name = "batch job"
3507+
start_time = "%s"
3508+
end_time = "%s"
3509+
exclusion_options {
3510+
scope = "%s"
3511+
}
3512+
}
3513+
maintenance_exclusion {
3514+
exclusion_name = "holiday data load"
3515+
start_time = "%s"
3516+
end_time = "%s"
3517+
exclusion_options {
3518+
scope = "%s"
3519+
}
3520+
}
3521+
}
3522+
}
3523+
`, cclusterName, w1startTime, w1endTime, w1startTime, w1endTime, scope1, w2startTime, w2endTime, scope2)
3524+
}
3525+
32863526
func testAccContainerCluster_withExclusion_NoMaintenanceWindow(clusterName string, w1startTime, w1endTime string) string {
32873527

32883528
return fmt.Sprintf(`

website/docs/r/clouddeploy_delivery_pipeline.html.markdown

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ resource "google_clouddeploy_delivery_pipeline" "primary" {
3333
name = "pipeline"
3434
3535
annotations = {
36-
my_first_annotation = "example-annotation-1"
37-
3836
my_second_annotation = "example-annotation-2"
37+
38+
my_first_annotation = "example-annotation-1"
3939
}
4040
4141
description = "basic description"

0 commit comments

Comments
 (0)