Skip to content

Commit ad2e089

Browse files
TF changes for AlloyDB Free trials (#11207) (#8042)
[upstream:8e79c4b6028a4e5ef7542e617388d7ae0eedfe87] Signed-off-by: Modular Magician <[email protected]>
1 parent 0dc0228 commit ad2e089

File tree

4 files changed

+337
-0
lines changed

4 files changed

+337
-0
lines changed

Diff for: .changelog/11207.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
alloydb: added `subscription_type` and `trial_metadata` field to `google_alloydb_cluster` resource
3+
```

Diff for: google-beta/services/alloydb/resource_alloydb_cluster.go

+101
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,13 @@ It is specified in the form: "projects/{projectNumber}/global/networks/{network_
481481
},
482482
},
483483
},
484+
"subscription_type": {
485+
Type: schema.TypeString,
486+
Computed: true,
487+
Optional: true,
488+
ValidateFunc: verify.ValidateEnum([]string{"TRIAL", "STANDARD", ""}),
489+
Description: `The subscrition type of cluster. Possible values: ["TRIAL", "STANDARD"]`,
490+
},
484491
"backup_source": {
485492
Type: schema.TypeList,
486493
Computed: true,
@@ -626,6 +633,35 @@ This can happen due to user-triggered updates or system actions like failover or
626633
and default labels configured on the provider.`,
627634
Elem: &schema.Schema{Type: schema.TypeString},
628635
},
636+
"trial_metadata": {
637+
Type: schema.TypeList,
638+
Computed: true,
639+
Description: `Contains information and all metadata related to TRIAL clusters.`,
640+
Elem: &schema.Resource{
641+
Schema: map[string]*schema.Schema{
642+
"end_time": {
643+
Type: schema.TypeString,
644+
Optional: true,
645+
Description: `End time of the trial cluster.`,
646+
},
647+
"grace_end_time": {
648+
Type: schema.TypeString,
649+
Optional: true,
650+
Description: `Grace end time of the trial cluster.`,
651+
},
652+
"start_time": {
653+
Type: schema.TypeString,
654+
Optional: true,
655+
Description: `Start time of the trial cluster.`,
656+
},
657+
"upgrade_time": {
658+
Type: schema.TypeString,
659+
Optional: true,
660+
Description: `Upgrade time of the trial cluster to standard cluster.`,
661+
},
662+
},
663+
},
664+
},
629665
"uid": {
630666
Type: schema.TypeString,
631667
Computed: true,
@@ -742,6 +778,12 @@ func resourceAlloydbClusterCreate(d *schema.ResourceData, meta interface{}) erro
742778
} else if v, ok := d.GetOkExists("maintenance_update_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(maintenanceUpdatePolicyProp)) && (ok || !reflect.DeepEqual(v, maintenanceUpdatePolicyProp)) {
743779
obj["maintenanceUpdatePolicy"] = maintenanceUpdatePolicyProp
744780
}
781+
subscriptionTypeProp, err := expandAlloydbClusterSubscriptionType(d.Get("subscription_type"), d, config)
782+
if err != nil {
783+
return err
784+
} else if v, ok := d.GetOkExists("subscription_type"); !tpgresource.IsEmptyValue(reflect.ValueOf(subscriptionTypeProp)) && (ok || !reflect.DeepEqual(v, subscriptionTypeProp)) {
785+
obj["subscriptionType"] = subscriptionTypeProp
786+
}
745787
labelsProp, err := expandAlloydbClusterEffectiveLabels(d.Get("effective_labels"), d, config)
746788
if err != nil {
747789
return err
@@ -986,6 +1028,12 @@ func resourceAlloydbClusterRead(d *schema.ResourceData, meta interface{}) error
9861028
if err := d.Set("maintenance_update_policy", flattenAlloydbClusterMaintenanceUpdatePolicy(res["maintenanceUpdatePolicy"], d, config)); err != nil {
9871029
return fmt.Errorf("Error reading Cluster: %s", err)
9881030
}
1031+
if err := d.Set("subscription_type", flattenAlloydbClusterSubscriptionType(res["subscriptionType"], d, config)); err != nil {
1032+
return fmt.Errorf("Error reading Cluster: %s", err)
1033+
}
1034+
if err := d.Set("trial_metadata", flattenAlloydbClusterTrialMetadata(res["trialMetadata"], d, config)); err != nil {
1035+
return fmt.Errorf("Error reading Cluster: %s", err)
1036+
}
9891037
if err := d.Set("terraform_labels", flattenAlloydbClusterTerraformLabels(res["labels"], d, config)); err != nil {
9901038
return fmt.Errorf("Error reading Cluster: %s", err)
9911039
}
@@ -1087,6 +1135,12 @@ func resourceAlloydbClusterUpdate(d *schema.ResourceData, meta interface{}) erro
10871135
} else if v, ok := d.GetOkExists("maintenance_update_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, maintenanceUpdatePolicyProp)) {
10881136
obj["maintenanceUpdatePolicy"] = maintenanceUpdatePolicyProp
10891137
}
1138+
subscriptionTypeProp, err := expandAlloydbClusterSubscriptionType(d.Get("subscription_type"), d, config)
1139+
if err != nil {
1140+
return err
1141+
} else if v, ok := d.GetOkExists("subscription_type"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, subscriptionTypeProp)) {
1142+
obj["subscriptionType"] = subscriptionTypeProp
1143+
}
10901144
labelsProp, err := expandAlloydbClusterEffectiveLabels(d.Get("effective_labels"), d, config)
10911145
if err != nil {
10921146
return err
@@ -1157,6 +1211,10 @@ func resourceAlloydbClusterUpdate(d *schema.ResourceData, meta interface{}) erro
11571211
updateMask = append(updateMask, "maintenanceUpdatePolicy")
11581212
}
11591213

1214+
if d.HasChange("subscription_type") {
1215+
updateMask = append(updateMask, "subscriptionType")
1216+
}
1217+
11601218
if d.HasChange("effective_labels") {
11611219
updateMask = append(updateMask, "labels")
11621220
}
@@ -2013,6 +2071,45 @@ func flattenAlloydbClusterMaintenanceUpdatePolicyMaintenanceWindowsStartTimeNano
20132071
return v // let terraform core handle it otherwise
20142072
}
20152073

2074+
func flattenAlloydbClusterSubscriptionType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2075+
return v
2076+
}
2077+
2078+
func flattenAlloydbClusterTrialMetadata(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2079+
if v == nil {
2080+
return nil
2081+
}
2082+
original := v.(map[string]interface{})
2083+
if len(original) == 0 {
2084+
return nil
2085+
}
2086+
transformed := make(map[string]interface{})
2087+
transformed["start_time"] =
2088+
flattenAlloydbClusterTrialMetadataStartTime(original["startTime"], d, config)
2089+
transformed["end_time"] =
2090+
flattenAlloydbClusterTrialMetadataEndTime(original["endTime"], d, config)
2091+
transformed["upgrade_time"] =
2092+
flattenAlloydbClusterTrialMetadataUpgradeTime(original["upgradeTime"], d, config)
2093+
transformed["grace_end_time"] =
2094+
flattenAlloydbClusterTrialMetadataGraceEndTime(original["graceEndTime"], d, config)
2095+
return []interface{}{transformed}
2096+
}
2097+
func flattenAlloydbClusterTrialMetadataStartTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2098+
return v
2099+
}
2100+
2101+
func flattenAlloydbClusterTrialMetadataEndTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2102+
return v
2103+
}
2104+
2105+
func flattenAlloydbClusterTrialMetadataUpgradeTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2106+
return v
2107+
}
2108+
2109+
func flattenAlloydbClusterTrialMetadataGraceEndTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2110+
return v
2111+
}
2112+
20162113
func flattenAlloydbClusterTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
20172114
if v == nil {
20182115
return v
@@ -2667,6 +2764,10 @@ func expandAlloydbClusterMaintenanceUpdatePolicyMaintenanceWindowsStartTimeNanos
26672764
return v, nil
26682765
}
26692766

2767+
func expandAlloydbClusterSubscriptionType(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
2768+
return v, nil
2769+
}
2770+
26702771
func expandAlloydbClusterEffectiveLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) {
26712772
if v == nil {
26722773
return map[string]string{}, nil

Diff for: google-beta/services/alloydb/resource_alloydb_cluster_test.go

+206
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ func TestAccAlloydbCluster_update(t *testing.T) {
2424
Steps: []resource.TestStep{
2525
{
2626
Config: testAccAlloydbCluster_alloydbClusterBasicExample(context),
27+
Check: resource.ComposeTestCheckFunc(
28+
resource.TestCheckResourceAttr("google_alloydb_cluster.default", "subscription_type", "STANDARD"),
29+
),
2730
},
2831
{
2932
ResourceName: "google_alloydb_cluster.default",
@@ -74,6 +77,94 @@ resource "google_compute_network" "default" {
7477
`, context)
7578
}
7679

80+
// Trial cluster creation should succeed with subscription type field set to Trial.
81+
func TestAccAlloydbCluster_withSubscriptionTypeTrial(t *testing.T) {
82+
t.Parallel()
83+
84+
context := map[string]interface{}{
85+
"random_suffix": acctest.RandString(t, 10),
86+
}
87+
88+
acctest.VcrTest(t, resource.TestCase{
89+
PreCheck: func() { acctest.AccTestPreCheck(t) },
90+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
91+
CheckDestroy: testAccCheckAlloydbClusterDestroyProducer(t),
92+
Steps: []resource.TestStep{
93+
{
94+
Config: testAccAlloydbCluster_withSubscriptionTypeTrial(context),
95+
Check: resource.ComposeTestCheckFunc(
96+
resource.TestCheckResourceAttr("google_alloydb_cluster.default", "subscription_type", "TRIAL"),
97+
resource.TestMatchResourceAttr("google_alloydb_cluster.default", "trial_metadata.0.start_time", regexp.MustCompile(".+")),
98+
resource.TestMatchResourceAttr("google_alloydb_cluster.default", "trial_metadata.0.end_time", regexp.MustCompile(".+")),
99+
),
100+
},
101+
},
102+
})
103+
}
104+
105+
func testAccAlloydbCluster_withSubscriptionTypeTrial(context map[string]interface{}) string {
106+
return acctest.Nprintf(`
107+
resource "google_alloydb_cluster" "default" {
108+
cluster_id = "tf-test-alloydb-cluster%{random_suffix}"
109+
location = "us-central1"
110+
subscription_type = "TRIAL"
111+
network_config {
112+
network = "projects/${data.google_project.project.number}/global/networks/${google_compute_network.default.name}"
113+
}
114+
}
115+
116+
data "google_project" "project" {
117+
}
118+
119+
resource "google_compute_network" "default" {
120+
name = "tf-test-alloydb-cluster%{random_suffix}"
121+
}
122+
`, context)
123+
}
124+
125+
// Standard cluster creation should succeed with subscription type field set to Standard.
126+
func TestAccAlloydbCluster_withSubscriptionTypeStandard(t *testing.T) {
127+
t.Parallel()
128+
129+
context := map[string]interface{}{
130+
"random_suffix": acctest.RandString(t, 10),
131+
}
132+
133+
acctest.VcrTest(t, resource.TestCase{
134+
PreCheck: func() { acctest.AccTestPreCheck(t) },
135+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
136+
CheckDestroy: testAccCheckAlloydbClusterDestroyProducer(t),
137+
Steps: []resource.TestStep{
138+
{
139+
Config: testAccAlloydbCluster_withSubscriptionTypeStandard(context),
140+
Check: resource.ComposeTestCheckFunc(
141+
resource.TestCheckResourceAttr("google_alloydb_cluster.default", "subscription_type", "STANDARD"),
142+
),
143+
},
144+
},
145+
})
146+
}
147+
148+
func testAccAlloydbCluster_withSubscriptionTypeStandard(context map[string]interface{}) string {
149+
return acctest.Nprintf(`
150+
resource "google_alloydb_cluster" "default" {
151+
cluster_id = "tf-test-alloydb-cluster%{random_suffix}"
152+
location = "us-central1"
153+
subscription_type = "STANDARD"
154+
network_config {
155+
network = "projects/${data.google_project.project.number}/global/networks/${google_compute_network.default.name}"
156+
}
157+
}
158+
159+
data "google_project" "project" {
160+
}
161+
162+
resource "google_compute_network" "default" {
163+
name = "tf-test-alloydb-cluster%{random_suffix}"
164+
}
165+
`, context)
166+
}
167+
77168
// Test if adding automatedBackupPolicy AND initialUser re-creates the cluster.
78169
// Ideally, cluster shouldn't be re-created. This test will only pass if the cluster
79170
// isn't re-created but updated in-place.
@@ -1365,3 +1456,118 @@ resource "google_alloydb_cluster" "default" {
13651456
data "google_project" "project" {}
13661457
`, context)
13671458
}
1459+
1460+
// Ensures cluster update from unspecified to standard and standard to standard works with no change in config.
1461+
func TestAccAlloydbCluster_standardClusterUpdate(t *testing.T) {
1462+
t.Parallel()
1463+
1464+
context := map[string]interface{}{
1465+
"random_suffix": acctest.RandString(t, 10),
1466+
}
1467+
1468+
acctest.VcrTest(t, resource.TestCase{
1469+
PreCheck: func() { acctest.AccTestPreCheck(t) },
1470+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
1471+
CheckDestroy: testAccCheckAlloydbClusterDestroyProducer(t),
1472+
Steps: []resource.TestStep{
1473+
{
1474+
Config: testAccAlloydbCluster_alloydbClusterBasicExample(context),
1475+
Check: resource.ComposeTestCheckFunc(
1476+
resource.TestCheckResourceAttr("google_alloydb_cluster.default", "subscription_type", "STANDARD"),
1477+
),
1478+
},
1479+
{
1480+
ResourceName: "google_alloydb_cluster.default",
1481+
ImportState: true,
1482+
ImportStateVerify: true,
1483+
ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location"},
1484+
},
1485+
{
1486+
Config: testAccAlloydbCluster_withSubscriptionTypeStandard(context),
1487+
},
1488+
{
1489+
ResourceName: "google_alloydb_cluster.default",
1490+
ImportState: true,
1491+
ImportStateVerify: true,
1492+
ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location"},
1493+
},
1494+
{
1495+
Config: testAccAlloydbCluster_withSubscriptionTypeStandard(context),
1496+
},
1497+
{
1498+
ResourceName: "google_alloydb_cluster.default",
1499+
ImportState: true,
1500+
ImportStateVerify: true,
1501+
ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location"},
1502+
},
1503+
},
1504+
})
1505+
}
1506+
1507+
// Ensures cluster update succeeds with subscription type from trial to standard and trial to trial results in no change in config.
1508+
func TestAccAlloydbCluster_trialClusterUpdate(t *testing.T) {
1509+
t.Parallel()
1510+
1511+
context := map[string]interface{}{
1512+
"random_suffix": acctest.RandString(t, 10),
1513+
}
1514+
1515+
acctest.VcrTest(t, resource.TestCase{
1516+
PreCheck: func() { acctest.AccTestPreCheck(t) },
1517+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
1518+
CheckDestroy: testAccCheckAlloydbClusterDestroyProducer(t),
1519+
Steps: []resource.TestStep{
1520+
{
1521+
Config: testAccAlloydbCluster_withSubscriptionTypeTrial(context),
1522+
},
1523+
{
1524+
ResourceName: "google_alloydb_cluster.default",
1525+
ImportState: true,
1526+
ImportStateVerify: true,
1527+
ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location"},
1528+
},
1529+
{
1530+
Config: testAccAlloydbCluster_withSubscriptionTypeTrial(context),
1531+
},
1532+
{
1533+
ResourceName: "google_alloydb_cluster.default",
1534+
ImportState: true,
1535+
ImportStateVerify: true,
1536+
ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location"},
1537+
},
1538+
{
1539+
Config: testAccAlloydbCluster_withSubscriptionTypeStandard(context),
1540+
},
1541+
{
1542+
ResourceName: "google_alloydb_cluster.default",
1543+
ImportState: true,
1544+
ImportStateVerify: true,
1545+
ImportStateVerifyIgnore: []string{"initial_user", "cluster_id", "location"},
1546+
},
1547+
},
1548+
})
1549+
}
1550+
1551+
// Ensures cluster update throws expected errors for subscription update from standard to trial.
1552+
func TestAccAlloydbCluster_standardClusterUpdateFailure(t *testing.T) {
1553+
t.Parallel()
1554+
errorPattern := `.*The request was invalid: invalid subscription_type update`
1555+
context := map[string]interface{}{
1556+
"random_suffix": acctest.RandString(t, 10),
1557+
}
1558+
1559+
acctest.VcrTest(t, resource.TestCase{
1560+
PreCheck: func() { acctest.AccTestPreCheck(t) },
1561+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
1562+
CheckDestroy: testAccCheckAlloydbClusterDestroyProducer(t),
1563+
Steps: []resource.TestStep{
1564+
{
1565+
Config: testAccAlloydbCluster_withSubscriptionTypeStandard(context),
1566+
},
1567+
{
1568+
Config: testAccAlloydbCluster_withSubscriptionTypeTrial(context),
1569+
ExpectError: regexp.MustCompile(errorPattern),
1570+
},
1571+
},
1572+
})
1573+
}

0 commit comments

Comments
 (0)