Skip to content

Commit

Permalink
Add support for Composer maintenance window configuration (GoogleClou…
Browse files Browse the repository at this point in the history
…dPlatform#4961)

* Add support for Composer maintenance window configuration

* Add support for Composer maintenance window configuration
  • Loading branch information
gor-obr authored and khajduczenia committed Oct 12, 2021
1 parent 4440617 commit eedbb36
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 -%>
}

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 -%>
}

Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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{} {
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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(`
Expand Down Expand Up @@ -923,7 +986,6 @@ resource "google_composer_environment" "test" {
}
}
}

depends_on = [google_project_iam_member.composer-worker]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down Expand Up @@ -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

Expand Down

0 comments on commit eedbb36

Please sign in to comment.