Skip to content

Commit

Permalink
Adding replication field for Filestore Instance (#11897) (#21194)
Browse files Browse the repository at this point in the history
[upstream:383b394588fdd1b7d971a7f5b6f0321dd1c65d5d]

Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician authored Jan 31, 2025
1 parent 77dc585 commit b8e279c
Show file tree
Hide file tree
Showing 6 changed files with 260 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .changelog/11897.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
filestore: added `initial_replication` field for peer instance configuration and `effective_replication` output for replication configuration output to `google_filestore_instance`
```
119 changes: 119 additions & 0 deletions google/services/filestore/resource_filestore_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,39 @@ Possible values include: STANDARD, PREMIUM, BASIC_HDD, BASIC_SSD, HIGH_SCALE_SSD
Optional: true,
Description: `A description of the instance.`,
},
"initial_replication": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Description: `Replication configuration, once set, this cannot be updated.
Addtionally this should be specified on the replica instance only, indicating the active as the peer_instance`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"replicas": {
Type: schema.TypeList,
Optional: true,
Description: `The replication role.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"peer_instance": {
Type: schema.TypeString,
Required: true,
Description: `The peer instance.`,
},
},
},
},
"role": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: verify.ValidateEnum([]string{"ROLE_UNSPECIFIED", "ACTIVE", "STANDBY", ""}),
Description: `The replication role. Default value: "STANDBY" Possible values: ["ROLE_UNSPECIFIED", "ACTIVE", "STANDBY"]`,
Default: "STANDBY",
},
},
},
},
"kms_key_name": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -353,6 +386,44 @@ resource, see the 'google_tags_tag_value' resource.`,
Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`,
Elem: &schema.Schema{Type: schema.TypeString},
},
"effective_replication": {
Type: schema.TypeList,
Computed: true,
Description: `Output only fields for replication configuration.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"replicas": {
Type: schema.TypeList,
Optional: true,
Description: `The replication role.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"last_active_sync_time": {
Type: schema.TypeString,
Computed: true,
Description: `Output only. The timestamp of the latest replication snapshot taken on the active instance and is already replicated safely.
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits.
Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z"`,
},
"state": {
Type: schema.TypeString,
Computed: true,
Description: `Output only. The replica state`,
},
"state_reasons": {
Type: schema.TypeList,
Computed: true,
Description: `Output only. Additional information about the replication state, if available.`,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
},
},
},
"etag": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -615,6 +686,9 @@ func resourceFilestoreInstanceRead(d *schema.ResourceData, meta interface{}) err
if err := d.Set("performance_config", flattenFilestoreInstancePerformanceConfig(res["performanceConfig"], d, config)); err != nil {
return fmt.Errorf("Error reading Instance: %s", err)
}
if err := d.Set("effective_replication", flattenFilestoreInstanceEffectiveReplication(res["replication"], d, config)); err != nil {
return fmt.Errorf("Error reading Instance: %s", err)
}
if err := d.Set("terraform_labels", flattenFilestoreInstanceTerraformLabels(res["labels"], d, config)); err != nil {
return fmt.Errorf("Error reading Instance: %s", err)
}
Expand Down Expand Up @@ -1117,6 +1191,51 @@ func flattenFilestoreInstancePerformanceConfigFixedIopsMaxIops(v interface{}, d
return v // let terraform core handle it otherwise
}

func flattenFilestoreInstanceEffectiveReplication(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["replicas"] =
flattenFilestoreInstanceEffectiveReplicationReplicas(original["replicas"], d, config)
return []interface{}{transformed}
}
func flattenFilestoreInstanceEffectiveReplicationReplicas(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return v
}
l := v.([]interface{})
transformed := make([]interface{}, 0, len(l))
for _, raw := range l {
original := raw.(map[string]interface{})
if len(original) < 1 {
// Do not include empty json objects coming back from the api
continue
}
transformed = append(transformed, map[string]interface{}{
"state": flattenFilestoreInstanceEffectiveReplicationReplicasState(original["state"], d, config),
"state_reasons": flattenFilestoreInstanceEffectiveReplicationReplicasStateReasons(original["stateReasons"], d, config),
"last_active_sync_time": flattenFilestoreInstanceEffectiveReplicationReplicasLastActiveSyncTime(original["lastActiveSyncTime"], d, config),
})
}
return transformed
}
func flattenFilestoreInstanceEffectiveReplicationReplicasState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenFilestoreInstanceEffectiveReplicationReplicasStateReasons(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenFilestoreInstanceEffectiveReplicationReplicasLastActiveSyncTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenFilestoreInstanceTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return v
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ fields:
- field: 'description'
- field: 'effective_labels'
provider_only: true
- field: 'effective_replication.replicas.last_active_sync_time'
api_field: 'replication.replicas.last_active_sync_time'
- field: 'effective_replication.replicas.state'
api_field: 'replication.replicas.state'
- field: 'effective_replication.replicas.state_reasons'
api_field: 'replication.replicas.state_reasons'
- field: 'etag'
- field: 'file_shares.capacity_gb'
- field: 'file_shares.name'
Expand All @@ -19,6 +25,10 @@ fields:
- field: 'file_shares.nfs_export_options.ip_ranges'
- field: 'file_shares.nfs_export_options.squash_mode'
- field: 'file_shares.source_backup'
- field: 'initial_replication.replicas.peer_instance'
provider_only: true
- field: 'initial_replication.role'
provider_only: true
- field: 'kms_key_name'
- field: 'labels'
- field: 'location'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func TestAccFilestoreInstance_filestoreInstanceBasicExample(t *testing.T) {
ResourceName: "google_filestore_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"labels", "location", "name", "tags", "terraform_labels", "zone"},
ImportStateVerifyIgnore: []string{"initial_replication", "labels", "location", "name", "tags", "terraform_labels", "zone"},
},
},
})
Expand Down Expand Up @@ -94,7 +94,7 @@ func TestAccFilestoreInstance_filestoreInstanceFullExample(t *testing.T) {
ResourceName: "google_filestore_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"labels", "location", "name", "tags", "terraform_labels", "zone"},
ImportStateVerifyIgnore: []string{"initial_replication", "labels", "location", "name", "tags", "terraform_labels", "zone"},
},
},
})
Expand Down Expand Up @@ -154,7 +154,7 @@ func TestAccFilestoreInstance_filestoreInstanceProtocolExample(t *testing.T) {
ResourceName: "google_filestore_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"labels", "location", "name", "tags", "terraform_labels", "zone"},
ImportStateVerifyIgnore: []string{"initial_replication", "labels", "location", "name", "tags", "terraform_labels", "zone"},
},
},
})
Expand Down
71 changes: 71 additions & 0 deletions google/services/filestore/resource_filestore_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,3 +462,74 @@ tags = {`, name)
l += fmt.Sprintf("}\n}")
return r + l
}

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

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
"location_1": "us-central1",
"location_2": "us-west1",
"tier": "ENTERPRISE",
}
acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccCheckFilestoreInstanceDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccFilestoreInstance_replication(context),
},
{
ResourceName: "google_filestore_instance.replica-instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"zone", "initial_replication"},
},
},
})
}

func testAccFilestoreInstance_replication(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_filestore_instance" "instance" {
name = "tf-instance-%{random_suffix}"
location = "%{location_1}"
tier = "%{tier}"
description = "An instance created during testing."
file_shares {
capacity_gb = 1024
name = "share"
}
networks {
network = "default"
modes = ["MODE_IPV4"]
}
}
resource "google_filestore_instance" "replica-instance" {
name = "tf-rinstance-%{random_suffix}"
location = "%{location_2}"
tier = "%{tier}"
description = "An replica instance created during testing."
file_shares {
capacity_gb = 1024
name = "share"
}
networks {
network = "default"
modes = ["MODE_IPV4"]
}
initial_replication {
replicas {
peer_instance = google_filestore_instance.instance.id
}
}
}
`, context)
}
54 changes: 54 additions & 0 deletions website/docs/r/filestore_instance.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,12 @@ The following arguments are supported:
will trigger recreation. To apply tags to an existing
resource, see the `google_tags_tag_value` resource.

* `initial_replication` -
(Optional)
Replication configuration, once set, this cannot be updated.
Addtionally this should be specified on the replica instance only, indicating the active as the peer_instance
Structure is [documented below](#nested_initial_replication).

* `zone` -
(Optional, Deprecated)
The name of the Filestore zone of the instance.
Expand Down Expand Up @@ -369,6 +375,26 @@ The following arguments are supported:
The number of IOPS to provision for the instance.
max_iops must be in multiple of 1000.

<a name="nested_initial_replication"></a>The `initial_replication` block supports:

* `role` -
(Optional)
The replication role.
Default value is `STANDBY`.
Possible values are: `ROLE_UNSPECIFIED`, `ACTIVE`, `STANDBY`.

* `replicas` -
(Optional)
The replication role.
Structure is [documented below](#nested_initial_replication_replicas).


<a name="nested_initial_replication_replicas"></a>The `replicas` block supports:

* `peer_instance` -
(Required)
The peer instance.

## Attributes Reference

In addition to the arguments listed above, the following computed attributes are exported:
Expand All @@ -382,6 +408,10 @@ In addition to the arguments listed above, the following computed attributes are
Server-specified ETag for the instance resource to prevent
simultaneous updates from overwriting each other.

* `effective_replication` -
Output only fields for replication configuration.
Structure is [documented below](#nested_effective_replication).

* `terraform_labels` -
The combination of labels configured directly on the resource
and default labels configured on the provider.
Expand All @@ -390,6 +420,30 @@ In addition to the arguments listed above, the following computed attributes are
All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.


<a name="nested_effective_replication"></a>The `effective_replication` block contains:

* `replicas` -
(Optional)
The replication role.
Structure is [documented below](#nested_effective_replication_replicas).


<a name="nested_effective_replication_replicas"></a>The `replicas` block supports:

* `state` -
(Output)
Output only. The replica state

* `state_reasons` -
(Output)
Output only. Additional information about the replication state, if available.

* `last_active_sync_time` -
(Output)
Output only. The timestamp of the latest replication snapshot taken on the active instance and is already replicated safely.
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits.
Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z"

## Timeouts

This resource provides the following
Expand Down

0 comments on commit b8e279c

Please # to comment.