From eedbb36caa0f2ec23fb4ccc5db528e606644805b Mon Sep 17 00:00:00 2001 From: gor-obr <62857127+gor-obr@users.noreply.github.com> Date: Tue, 20 Jul 2021 00:11:31 +0200 Subject: [PATCH] Add support for Composer maintenance window configuration (#4961) * Add support for Composer maintenance window configuration * Add support for Composer maintenance window configuration --- .../resource_composer_environment.go.erb | 90 +++++++++++++++++-- .../resource_composer_environment_test.go.erb | 64 ++++++++++++- .../docs/r/composer_environment.html.markdown | 20 +++++ 3 files changed, 168 insertions(+), 6 deletions(-) diff --git a/mmv1/third_party/terraform/resources/resource_composer_environment.go.erb b/mmv1/third_party/terraform/resources/resource_composer_environment.go.erb index 3e6613c61ac8..96b3273a1b62 100644 --- a/mmv1/third_party/terraform/resources/resource_composer_environment.go.erb +++ b/mmv1/third_party/terraform/resources/resource_composer_environment.go.erb @@ -52,11 +52,10 @@ var ( "config.0.private_environment_config", <% unless version == "ga" -%> "config.0.web_server_network_access_control", -<% end -%> -<% unless version == "ga" -%> "config.0.database_config", "config.0.web_server_config", - "config.0.encryption_config", + "config.0.encryption_config", + "config.0.maintenance_window", <% end -%> } @@ -461,6 +460,36 @@ func resourceComposerEnvironment() *schema.Resource { }, }, }, + "maintenance_window": { + Type: schema.TypeList, + Optional: true, + Computed: true, + AtLeastOneOf: composerConfigKeys, + MaxItems: 1, + Description: `The configuration for Cloud Composer maintenance window.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "start_time": { + Type: schema.TypeString, + Required: true, + ForceNew: false, + Description: `Start time of the first recurrence of the maintenance window.`, + }, + "end_time": { + Type: schema.TypeString, + Required: true, + ForceNew: false, + Description: `Maintenance window end time. It is used only to calculate the duration of the maintenance window. The value for end-time must be in the future, relative to 'start_time'.`, + }, + "recurrence": { + Type: schema.TypeString, + Required: true, + ForceNew: false, + Description: `Maintenance window recurrence. Format is a subset of RFC-5545 (https://tools.ietf.org/html/rfc5545) 'RRULE'. The only allowed values for 'FREQ' field are 'FREQ=DAILY' and 'FREQ=WEEKLY;BYDAY=...'. Example values: 'FREQ=WEEKLY;BYDAY=TU,WE', 'FREQ=DAILY'.`, + }, + }, + }, + }, <% end -%> "airflow_uri": { Type: schema.TypeString, @@ -729,6 +758,17 @@ func resourceComposerEnvironmentUpdate(d *schema.ResourceData, meta interface{}) return err } } + + if d.HasChange("config.0.maintenance_window") { + patchObj := &composer.Environment{Config: &composer.EnvironmentConfig{}} + if config != nil { + patchObj.Config.MaintenanceWindow = config.MaintenanceWindow + } + err = resourceComposerEnvironmentPatchField("config.maintenanceWindow", userAgent, patchObj, d, tfConfig) + if err != nil { + return err + } + } <% end -%> } @@ -850,11 +890,10 @@ func flattenComposerEnvironmentConfig(envCfg *composer.EnvironmentConfig) interf transformed["private_environment_config"] = flattenComposerEnvironmentConfigPrivateEnvironmentConfig(envCfg.PrivateEnvironmentConfig) <% unless version == "ga" -%> transformed["web_server_network_access_control"] = flattenComposerEnvironmentConfigWebServerNetworkAccessControl(envCfg.WebServerNetworkAccessControl) -<% end -%> -<% unless version == "ga" -%> transformed["database_config"] = flattenComposerEnvironmentConfigDatabaseConfig(envCfg.DatabaseConfig) transformed["web_server_config"] = flattenComposerEnvironmentConfigWebServerConfig(envCfg.WebServerConfig) transformed["encryption_config"] = flattenComposerEnvironmentConfigEncryptionConfig(envCfg.EncryptionConfig) + transformed["maintenance_window"] = flattenComposerEnvironmentConfigMaintenanceWindow(envCfg.MaintenanceWindow) <% end -%> return []interface{}{transformed} @@ -916,6 +955,19 @@ func flattenComposerEnvironmentConfigEncryptionConfig(encryptionCfg *composer.En return []interface{}{transformed} } + +func flattenComposerEnvironmentConfigMaintenanceWindow(maintenanceWindow *composer.MaintenanceWindow) interface{} { + if maintenanceWindow == nil { + return nil + } + + transformed := make(map[string]interface{}) + transformed["start_time"] = maintenanceWindow.StartTime + transformed["end_time"] = maintenanceWindow.EndTime + transformed["recurrence"] = maintenanceWindow.Recurrence + + return []interface{}{transformed} +} <% end -%> func flattenComposerEnvironmentConfigPrivateEnvironmentConfig(envCfg *composer.PrivateEnvironmentConfig) interface{} { @@ -1055,6 +1107,11 @@ func expandComposerEnvironmentConfig(v interface{}, d *schema.ResourceData, conf } transformed.EncryptionConfig = transformedEncryptionConfig + transformedMaintenanceWindow, err := expandComposerEnvironmentConfigMaintenanceWindow(original["maintenance_window"], d, config) + if err != nil { + return nil, err + } + transformed.MaintenanceWindow = transformedMaintenanceWindow <% end -%> return transformed, nil } @@ -1144,6 +1201,29 @@ func expandComposerEnvironmentConfigEncryptionConfig(v interface{}, d *schema.Re return transformed, nil } +func expandComposerEnvironmentConfigMaintenanceWindow(v interface{}, d *schema.ResourceData, config *Config) (*composer.MaintenanceWindow, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := &composer.MaintenanceWindow{} + + if v, ok := original["start_time"]; ok { + transformed.StartTime = v.(string) + } + + if v, ok := original["end_time"]; ok { + transformed.EndTime = v.(string) + } + + if v, ok := original["recurrence"]; ok { + transformed.Recurrence = v.(string) + } + + return transformed, nil +} <% end -%> func expandComposerEnvironmentConfigPrivateEnvironmentConfig(v interface{}, d *schema.ResourceData, config *Config) (*composer.PrivateEnvironmentConfig, error) { diff --git a/mmv1/third_party/terraform/tests/resource_composer_environment_test.go.erb b/mmv1/third_party/terraform/tests/resource_composer_environment_test.go.erb index fe1d447a3898..99e65e4a9223 100644 --- a/mmv1/third_party/terraform/tests/resource_composer_environment_test.go.erb +++ b/mmv1/third_party/terraform/tests/resource_composer_environment_test.go.erb @@ -329,6 +329,40 @@ func TestAccComposerEnvironment_withEncryptionConfig(t *testing.T) { }, }) } + +func TestAccComposerEnvironment_withMaintenanceWindow(t *testing.T) { + t.Parallel() + + pid := getTestProjectFromEnv() + envName := fmt.Sprintf("%s-%d", testComposerEnvironmentPrefix, randInt(t)) + network := fmt.Sprintf("%s-%d", testComposerNetworkPrefix, randInt(t)) + subnetwork := network + "-1" + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccComposerEnvironmentDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComposerEnvironment_maintenanceWindow(pid, envName, network, subnetwork), + }, + { + ResourceName: "google_composer_environment.test", + ImportState: true, + ImportStateVerify: true, + }, + // This is a terrible clean-up step in order to get destroy to succeed, + // due to dangling firewall rules left by the Composer Environment blocking network deletion. + // TODO(dzarmola): Remove this check if firewall rules bug gets fixed by Composer. + { + PlanOnly: true, + ExpectNonEmptyPlan: false, + Config: testAccComposerEnvironment_maintenanceWindow(pid, envName, network, subnetwork), + Check: testAccCheckClearComposerEnvironmentFirewalls(t, network), + }, + }, + }) +} <% end -%> // Checks behavior of node config, including dependencies on Compute resources. func TestAccComposerEnvironment_withNodeConfig(t *testing.T) { @@ -836,6 +870,35 @@ resource "google_compute_subnetwork" "test" { } `, pid, kmsKey, name, kmsKey, network, subnetwork) } + +func testAccComposerEnvironment_maintenanceWindow(pid, envName, network, subnetwork string) string { + return fmt.Sprintf(` +resource "google_composer_environment" "test" { + name = "%s" + region = "us-central1" + config { + maintenance_window { + start_time = "2019-08-01T01:00:00Z" + end_time = "2019-08-01T07:00:00Z" + recurrence = "FREQ=WEEKLY;BYDAY=TU,WE" + } + } +} + +resource "google_compute_network" "test" { + name = "%s" + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork" "test" { + name = "%s" + ip_cidr_range = "10.2.0.0/16" + region = "us-central1" + network = google_compute_network.test.self_link +} + +`, envName, network, subnetwork) +} <% end -%> func testAccComposerEnvironment_update(name, network, subnetwork string) string { return fmt.Sprintf(` @@ -923,7 +986,6 @@ resource "google_composer_environment" "test" { } } } - depends_on = [google_project_iam_member.composer-worker] } diff --git a/mmv1/third_party/terraform/website/docs/r/composer_environment.html.markdown b/mmv1/third_party/terraform/website/docs/r/composer_environment.html.markdown index 18a4459ae6f9..f93ca38f04f6 100644 --- a/mmv1/third_party/terraform/website/docs/r/composer_environment.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/composer_environment.html.markdown @@ -182,6 +182,10 @@ The `config` block supports: * `encryption_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) The encryption options for the Cloud Composer environment and its dependencies. + +* `maintenance_window` - + (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) + The configuration settings for Cloud Composer maintenance window. The `node_config` block supports: @@ -410,6 +414,22 @@ The `encryption_config` block supports: be the fully qualified resource name, i.e. projects/project-id/locations/location/keyRings/keyring/cryptoKeys/key. Cannot be updated. +The `maintenance_window` block supports: + +* `start_time` - + (Required) + Start time of the first recurrence of the maintenance window. + +* `end_time` - + (Required) + Maintenance window end time. It is used only to calculate the duration of the maintenance window. + The value for end-time must be in the future, relative to 'start_time'. + +* `recurrence` - + (Required) + Maintenance window recurrence. Format is a subset of RFC-5545 (https://tools.ietf.org/html/rfc5545) 'RRULE'. + The only allowed values for 'FREQ' field are 'FREQ=DAILY' and 'FREQ=WEEKLY;BYDAY=...'. + Example values: 'FREQ=WEEKLY;BYDAY=TU,WE', 'FREQ=DAILY'. ## Attributes Reference