From bb6e6f7621fbe801fc1b3b1e36700a2d8d6af2b4 Mon Sep 17 00:00:00 2001 From: Walter Fender Date: Mon, 25 Mar 2024 17:29:53 +0000 Subject: [PATCH] Backport Add cross-region replication support to AlloyDB Backport https://github.com/hashicorp/terraform-provider-google-beta/pull/6474 To Create a Secondary Cluster, `cluster_type` and `secondary_config` are the additional fields to be mentioned in the cluster. The secondary cluster is dependent on the primary instance and the same needs to be added in the config using the `depends_on` field. The field continuous_backup_config.enabled needs to be set false as continuous backup is not supported for secondary clusters. The deletion_policy is set to FORCE as the secondary instance that will be created in the secondary cluster can not be deleted independently, but instead the entire secondary cluster needs to be deleted forcefully along with its secondary instance. ``` cluster_type = "SECONDARY" deletion_policy = "FORCE" secondary_config { primary_cluster_name = // Eg: primary_cluster_name = google_alloydb_cluster..name } continuous_backup_config { enabled = false } depends_on = [google_alloydb_instance.] ``` Part of [hashicorp/terraform-provider-google#13251](https://github.com/hashicorp/terraform-provider-google/issues/13251) **Release Note Template for Downstream PRs (will be copied)** ``` alloydb: added `cluster_type` and `secondary_config` fields to support secondary clusters in `google_alloydb_cluster` resource. ``` Derived from [GoogleCloudPlatform/magic-modules#9012](https://github.com/GoogleCloudPlatform/magic-modules/pull/9012) --- ...lusters.alloydb.cnrm.cloud.google.com.yaml | 36 +++++++++++++++++++ .../alloydb/v1beta1/alloydbcluster_types.go | 14 ++++++++ .../alloydb/v1beta1/zz_generated.deepcopy.go | 26 ++++++++++++++ .../resource-docs/alloydb/alloydbcluster.md | 34 ++++++++++++++++++ .../alloydb/resource_alloydb_cluster.go | 26 ++++++++++++++ 5 files changed, 136 insertions(+) diff --git a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbclusters.alloydb.cnrm.cloud.google.com.yaml b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbclusters.alloydb.cnrm.cloud.google.com.yaml index 749fd88439..07164a7f31 100644 --- a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbclusters.alloydb.cnrm.cloud.google.com.yaml +++ b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbclusters.alloydb.cnrm.cloud.google.com.yaml @@ -178,6 +178,11 @@ spec: - startTimes type: object type: object + clusterType: + description: 'Immutable. The type of cluster. If not set, defaults + to PRIMARY. Default value: "PRIMARY" Possible values: ["PRIMARY", + "SECONDARY"].' + type: string continuousBackupConfig: description: |- The continuous backup config for this cluster. @@ -505,6 +510,19 @@ spec: - clusterRef - pointInTime type: object + secondaryConfig: + description: Configuration of the secondary cluster for Cross Region + Replication. This should be set if and only if the cluster is of + type SECONDARY. + properties: + primaryClusterName: + description: |- + Immutable. Name of the primary cluster must be in the format + 'projects/{project}/locations/{location}/clusters/{cluster_id}'. + type: string + required: + - primaryClusterName + type: object required: - location - projectRef @@ -796,6 +814,11 @@ spec: - startTimes type: object type: object + clusterType: + description: 'Immutable. The type of cluster. If not set, defaults + to PRIMARY. Default value: "PRIMARY" Possible values: ["PRIMARY", + "SECONDARY"].' + type: string continuousBackupConfig: description: |- The continuous backup config for this cluster. @@ -1123,6 +1146,19 @@ spec: - clusterRef - pointInTime type: object + secondaryConfig: + description: Configuration of the secondary cluster for Cross Region + Replication. This should be set if and only if the cluster is of + type SECONDARY. + properties: + primaryClusterName: + description: |- + Immutable. Name of the primary cluster must be in the format + 'projects/{project}/locations/{location}/clusters/{cluster_id}'. + type: string + required: + - primaryClusterName + type: object required: - location - projectRef diff --git a/pkg/clients/generated/apis/alloydb/v1beta1/alloydbcluster_types.go b/pkg/clients/generated/apis/alloydb/v1beta1/alloydbcluster_types.go index 00aab99586..ac18171943 100644 --- a/pkg/clients/generated/apis/alloydb/v1beta1/alloydbcluster_types.go +++ b/pkg/clients/generated/apis/alloydb/v1beta1/alloydbcluster_types.go @@ -146,6 +146,12 @@ type ClusterRestoreContinuousBackupSource struct { PointInTime string `json:"pointInTime"` } +type ClusterSecondaryConfig struct { + /* Immutable. Name of the primary cluster must be in the format + 'projects/{project}/locations/{location}/clusters/{cluster_id}'. */ + PrimaryClusterName string `json:"primaryClusterName"` +} + type ClusterStartTimes struct { /* Hours of day in 24 hour format. Should be from 0 to 23. An API may choose to allow the value "24:00:00" for scenarios like business closing time. */ // +optional @@ -191,6 +197,10 @@ type AlloyDBClusterSpec struct { // +optional AutomatedBackupPolicy *ClusterAutomatedBackupPolicy `json:"automatedBackupPolicy,omitempty"` + /* Immutable. The type of cluster. If not set, defaults to PRIMARY. Default value: "PRIMARY" Possible values: ["PRIMARY", "SECONDARY"]. */ + // +optional + ClusterType *string `json:"clusterType,omitempty"` + /* The continuous backup config for this cluster. If no policy is provided then the default policy will be used. The default policy takes one backup a day and retains backups for 14 days. */ @@ -236,6 +246,10 @@ type AlloyDBClusterSpec struct { /* Immutable. The source when restoring via point in time recovery (PITR). Conflicts with 'restore_backup_source', both can't be set together. */ // +optional RestoreContinuousBackupSource *ClusterRestoreContinuousBackupSource `json:"restoreContinuousBackupSource,omitempty"` + + /* Configuration of the secondary cluster for Cross Region Replication. This should be set if and only if the cluster is of type SECONDARY. */ + // +optional + SecondaryConfig *ClusterSecondaryConfig `json:"secondaryConfig,omitempty"` } type ClusterBackupSourceStatus struct { diff --git a/pkg/clients/generated/apis/alloydb/v1beta1/zz_generated.deepcopy.go b/pkg/clients/generated/apis/alloydb/v1beta1/zz_generated.deepcopy.go index c58f2c8c32..fc546dc096 100644 --- a/pkg/clients/generated/apis/alloydb/v1beta1/zz_generated.deepcopy.go +++ b/pkg/clients/generated/apis/alloydb/v1beta1/zz_generated.deepcopy.go @@ -260,6 +260,11 @@ func (in *AlloyDBClusterSpec) DeepCopyInto(out *AlloyDBClusterSpec) { *out = new(ClusterAutomatedBackupPolicy) (*in).DeepCopyInto(*out) } + if in.ClusterType != nil { + in, out := &in.ClusterType, &out.ClusterType + *out = new(string) + **out = **in + } if in.ContinuousBackupConfig != nil { in, out := &in.ContinuousBackupConfig, &out.ContinuousBackupConfig *out = new(ClusterContinuousBackupConfig) @@ -306,6 +311,11 @@ func (in *AlloyDBClusterSpec) DeepCopyInto(out *AlloyDBClusterSpec) { *out = new(ClusterRestoreContinuousBackupSource) **out = **in } + if in.SecondaryConfig != nil { + in, out := &in.SecondaryConfig, &out.SecondaryConfig + *out = new(ClusterSecondaryConfig) + **out = **in + } return } @@ -1097,6 +1107,22 @@ func (in *ClusterRestoreContinuousBackupSource) DeepCopy() *ClusterRestoreContin return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterSecondaryConfig) DeepCopyInto(out *ClusterSecondaryConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSecondaryConfig. +func (in *ClusterSecondaryConfig) DeepCopy() *ClusterSecondaryConfig { + if in == nil { + return nil + } + out := new(ClusterSecondaryConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterStartTimes) DeepCopyInto(out *ClusterStartTimes) { *out = *in diff --git a/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbcluster.md b/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbcluster.md index 45ee47ad59..f1dd4b0f08 100644 --- a/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbcluster.md +++ b/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbcluster.md @@ -100,6 +100,7 @@ automatedBackupPolicy: minutes: integer nanos: integer seconds: integer +clusterType: string continuousBackupConfig: enabled: boolean encryptionConfig: @@ -149,6 +150,8 @@ restoreContinuousBackupSource: name: string namespace: string pointInTime: string +secondaryConfig: + primaryClusterName: string ``` @@ -393,6 +396,16 @@ A duration in seconds with up to nine fractional digits, terminated by 's'. Exam

{% verbatim %}Seconds of minutes of the time. Currently, only the value 0 is supported.{% endverbatim %}

+ + + + + + + + + + + +
+

clusterType

+

Optional

+
+

string

+

{% verbatim %}Immutable. The type of cluster. If not set, defaults to PRIMARY. Default value: "PRIMARY" Possible values: ["PRIMARY", "SECONDARY"].{% endverbatim %}

+

continuousBackupConfig

@@ -892,6 +905,27 @@ projects/{project}/global/networks/{network_id}.{% endverbatim %}

{% verbatim %}Immutable. The point in time that this cluster is restored to, in RFC 3339 format.{% endverbatim %}

+

secondaryConfig

+

Optional

+
+

object

+

{% verbatim %}Configuration of the secondary cluster for Cross Region Replication. This should be set if and only if the cluster is of type SECONDARY.{% endverbatim %}

+
+

secondaryConfig.primaryClusterName

+

Required*

+
+

string

+

{% verbatim %}Immutable. Name of the primary cluster must be in the format +'projects/{project}/locations/{location}/clusters/{cluster_id}'.{% endverbatim %}

+
diff --git a/third_party/github.com/hashicorp/terraform-provider-google-beta/google-beta/services/alloydb/resource_alloydb_cluster.go b/third_party/github.com/hashicorp/terraform-provider-google-beta/google-beta/services/alloydb/resource_alloydb_cluster.go index 70c8b6c4a5..622772dca3 100644 --- a/third_party/github.com/hashicorp/terraform-provider-google-beta/google-beta/services/alloydb/resource_alloydb_cluster.go +++ b/third_party/github.com/hashicorp/terraform-provider-google-beta/google-beta/services/alloydb/resource_alloydb_cluster.go @@ -2012,3 +2012,29 @@ func expandAlloydbClusterAutomatedBackupPolicyEnabled(v interface{}, d tpgresour return v, nil } +func expandAlloydbClusterClusterType(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandAlloydbClusterSecondaryConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedPrimaryClusterName, err := expandAlloydbClusterSecondaryConfigPrimaryClusterName(original["primary_cluster_name"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPrimaryClusterName); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["primaryClusterName"] = transformedPrimaryClusterName + } + + return transformed, nil +} + +func expandAlloydbClusterSecondaryConfigPrimaryClusterName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +}