Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding replication field for Filestore Instance #9200

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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-beta/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
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