Skip to content

Commit

Permalink
Adding Cloud Composer Support For Resilience Mode Updates (#8263) (#1…
Browse files Browse the repository at this point in the history
…5238)

* Adding Support For resilience_mode field

* Adding new field RESILIENCE_MODE_UNSPECIFIED

* Added RESILIENCE_MODE_UNSPECIFIED in the docs

* Removing the resilience mode test as the API is not yet launched

* Adding test for high resilience and adding  mapping

* Fixing docs and flatten logic

* Fixing expand method

* Fixing flatten to accept empty Resilience_mode field

---------

Signed-off-by: Modular Magician <magic-modules@google.com>
Co-authored-by: Khaled Hassan <hkhaled@google.com>
  • Loading branch information
modular-magician and Khaled Hassan committed Jul 20, 2023
1 parent 179fb23 commit de747a8
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .changelog/8263.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
composer: added support for updating `resilience_mode` in `google_composer_environment`
```
99 changes: 99 additions & 0 deletions google/resource_composer_environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,42 @@ func TestAccComposerEnvironment_ComposerV2(t *testing.T) {
})
}

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

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() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: ProtoV5ProviderFactories(t),
CheckDestroy: testAccComposerEnvironmentDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccComposerEnvironment_composerV2HighResilience(envName, network, subnetwork),
},
{
Config: testAccComposerEnvironment_updateComposerV2StandardResilience(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_updateComposerV2StandardResilience(envName, network, subnetwork),
Check: testAccCheckClearComposerEnvironmentFirewalls(t, network),
},
},
})
}

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

Expand Down Expand Up @@ -1763,6 +1799,69 @@ resource "google_compute_subnetwork" "test" {
`, envName, compVersion, airflowVersion, network, subnetwork)
}

func testAccComposerEnvironment_updateComposerV2StandardResilience(envName, network, subnetwork string) string {
return fmt.Sprintf(`
resource "google_composer_environment" "test" {
name = "%s"
region = "us-east1"
config {
node_config {
network = google_compute_network.test.self_link
subnetwork = google_compute_subnetwork.test.self_link
}
software_config {
image_version = "composer-2-airflow-2"
}
workloads_config {
scheduler {
cpu = 1.25
memory_gb = 2.5
storage_gb = 5.4
count = 2
}
web_server {
cpu = 1.75
memory_gb = 3.0
storage_gb = 4.4
}
worker {
cpu = 0.5
memory_gb = 2.0
storage_gb = 3.4
min_count = 2
max_count = 5
}
}
environment_size = "ENVIRONMENT_SIZE_MEDIUM"
resilience_mode = "STANDARD_RESILIENCE"
private_environment_config {
enable_private_endpoint = true
cloud_composer_network_ipv4_cidr_block = "10.3.192.0/24"
master_ipv4_cidr_block = "172.16.194.0/23"
cloud_sql_ipv4_cidr_block = "10.3.224.0/20"
}
}
}
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-east1"
network = google_compute_network.test.self_link
private_ip_google_access = true
}
`, envName, network, subnetwork)
}

func testAccComposerEnvironment_MasterAuthNetworksUpdate(compVersion, airflowVersion, envName, network, subnetwork string) string {
return fmt.Sprintf(`
resource "google_composer_environment" "test" {
Expand Down
30 changes: 26 additions & 4 deletions google/services/composer/resource_composer_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -744,9 +744,9 @@ func ResourceComposerEnvironment() *schema.Resource {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ForceNew: false,
AtLeastOneOf: composerConfigKeys,
ValidateFunc: validation.StringInSlice([]string{"HIGH_RESILIENCE"}, false),
ValidateFunc: validation.StringInSlice([]string{"STANDARD_RESILIENCE", "HIGH_RESILIENCE"}, false),
Description: `Whether high resilience is enabled or not. This field is supported for Cloud Composer environments in versions composer-2.1.15-airflow-*.*.* and newer.`,
},
"master_authorized_networks_config": {
Expand Down Expand Up @@ -1081,6 +1081,20 @@ func resourceComposerEnvironmentUpdate(d *schema.ResourceData, meta interface{})
return err
}
}
if d.HasChange("config.0.resilience_mode") {
patchObj := &composer.Environment{Config: &composer.EnvironmentConfig{}}
if config != nil {
if config.ResilienceMode == "STANDARD_RESILIENCE" {
patchObj.Config.ResilienceMode = "RESILIENCE_MODE_UNSPECIFIED"
} else {
patchObj.Config.ResilienceMode = config.ResilienceMode
}
}
err = resourceComposerEnvironmentPatchField("config.ResilienceMode", userAgent, patchObj, d, tfConfig)
if err != nil {
return err
}
}
if d.HasChange("config.0.master_authorized_networks_config") {
patchObj := &composer.Environment{Config: &composer.EnvironmentConfig{}}
if config != nil {
Expand Down Expand Up @@ -1215,7 +1229,11 @@ func flattenComposerEnvironmentConfig(envCfg *composer.EnvironmentConfig) interf
transformed["workloads_config"] = flattenComposerEnvironmentConfigWorkloadsConfig(envCfg.WorkloadsConfig)
transformed["recovery_config"] = flattenComposerEnvironmentConfigRecoveryConfig(envCfg.RecoveryConfig)
transformed["environment_size"] = envCfg.EnvironmentSize
transformed["resilience_mode"] = envCfg.ResilienceMode
if envCfg.ResilienceMode == "RESILIENCE_MODE_UNSPECIFIED" || envCfg.ResilienceMode == "" {
transformed["resilience_mode"] = "STANDARD_RESILIENCE"
} else {
transformed["resilience_mode"] = envCfg.ResilienceMode
}
transformed["master_authorized_networks_config"] = flattenComposerEnvironmentConfigMasterAuthorizedNetworksConfig(envCfg.MasterAuthorizedNetworksConfig)
return []interface{}{transformed}
}
Expand Down Expand Up @@ -1536,7 +1554,11 @@ func expandComposerEnvironmentConfig(v interface{}, d *schema.ResourceData, conf
if err != nil {
return nil, err
}
transformed.ResilienceMode = transformedResilienceMode
if transformedResilienceMode == "STANDARD_RESILIENCE" {
transformed.ResilienceMode = "RESILIENCE_MODE_UNSPECIFIED"
} else {
transformed.ResilienceMode = transformedResilienceMode
}

transformedMasterAuthorizedNetworksConfig, err := expandComposerEnvironmentConfigMasterAuthorizedNetworksConfig(original["master_authorized_networks_config"], d, config)
if err != nil {
Expand Down
5 changes: 3 additions & 2 deletions website/docs/r/composer_environment.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -682,8 +682,9 @@ The `config` block supports:
* `resilience_mode` -
(Optional, Cloud Composer 2.1.15 or newer only)
The resilience mode states whether high resilience is enabled for
the environment or not. Value for resilience mode is `HIGH_RESILIENCE`.
If unspecified, defaults to standard resilience.
the environment or not. Values for resilience mode are `HIGH_RESILIENCE`
for high resilience and `STANDARD_RESILIENCE` for standard
resilience.

* `master_authorized_networks_config` -
(Optional)
Expand Down

0 comments on commit de747a8

Please sign in to comment.