Skip to content

Commit

Permalink
[AlloyDB] Private Service Connect Support (#10783) (#7429)
Browse files Browse the repository at this point in the history
[upstream:3963065a1e467a9482cee7e3ac5134dfd95fd558]

Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician committed May 28, 2024
1 parent f1b32a5 commit 2e60089
Show file tree
Hide file tree
Showing 6 changed files with 349 additions and 2 deletions.
78 changes: 76 additions & 2 deletions google-beta/services/alloydb/resource_alloydb_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ Please refer to the field 'effective_labels' for all of the labels present on th
Description: `The relative resource name of the VPC network on which the instance can be accessed. It is specified in the following form:
"projects/{projectNumber}/global/networks/{network_id}".`,
ExactlyOneOf: []string{"network", "network_config.0.network"},
ExactlyOneOf: []string{"network", "network_config.0.network", "psc_config.0.psc_enabled"},
},
"network_config": {
Type: schema.TypeList,
Expand All @@ -414,7 +414,22 @@ If set, the instance IPs for this cluster will be created in the allocated range
DiffSuppressFunc: tpgresource.ProjectNumberDiffSuppress,
Description: `The resource link for the VPC network in which cluster resources are created and from which they are accessible via Private IP. The network must belong to the same project as the cluster.
It is specified in the form: "projects/{projectNumber}/global/networks/{network_id}".`,
ExactlyOneOf: []string{"network", "network_config.0.network"},
ExactlyOneOf: []string{"network", "network_config.0.network", "psc_config.0.psc_enabled"},
},
},
},
},
"psc_config": {
Type: schema.TypeList,
Optional: true,
Description: `Configuration for Private Service Connect (PSC) for the cluster.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"psc_enabled": {
Type: schema.TypeBool,
Optional: true,
Description: `Create an instance that allows connections from Private Service Connect endpoints to the instance.`,
},
},
},
Expand Down Expand Up @@ -690,6 +705,12 @@ func resourceAlloydbClusterCreate(d *schema.ResourceData, meta interface{}) erro
} else if v, ok := d.GetOkExists("database_version"); !tpgresource.IsEmptyValue(reflect.ValueOf(databaseVersionProp)) && (ok || !reflect.DeepEqual(v, databaseVersionProp)) {
obj["databaseVersion"] = databaseVersionProp
}
pscConfigProp, err := expandAlloydbClusterPscConfig(d.Get("psc_config"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("psc_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(pscConfigProp)) && (ok || !reflect.DeepEqual(v, pscConfigProp)) {
obj["pscConfig"] = pscConfigProp
}
initialUserProp, err := expandAlloydbClusterInitialUser(d.Get("initial_user"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -961,6 +982,9 @@ func resourceAlloydbClusterRead(d *schema.ResourceData, meta interface{}) error
if err := d.Set("database_version", flattenAlloydbClusterDatabaseVersion(res["databaseVersion"], d, config)); err != nil {
return fmt.Errorf("Error reading Cluster: %s", err)
}
if err := d.Set("psc_config", flattenAlloydbClusterPscConfig(res["pscConfig"], d, config)); err != nil {
return fmt.Errorf("Error reading Cluster: %s", err)
}
if err := d.Set("continuous_backup_config", flattenAlloydbClusterContinuousBackupConfig(res["continuousBackupConfig"], d, config)); err != nil {
return fmt.Errorf("Error reading Cluster: %s", err)
}
Expand Down Expand Up @@ -1047,6 +1071,12 @@ func resourceAlloydbClusterUpdate(d *schema.ResourceData, meta interface{}) erro
} else if v, ok := d.GetOkExists("database_version"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, databaseVersionProp)) {
obj["databaseVersion"] = databaseVersionProp
}
pscConfigProp, err := expandAlloydbClusterPscConfig(d.Get("psc_config"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("psc_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, pscConfigProp)) {
obj["pscConfig"] = pscConfigProp
}
initialUserProp, err := expandAlloydbClusterInitialUser(d.Get("initial_user"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -1129,6 +1159,10 @@ func resourceAlloydbClusterUpdate(d *schema.ResourceData, meta interface{}) erro
updateMask = append(updateMask, "databaseVersion")
}

if d.HasChange("psc_config") {
updateMask = append(updateMask, "pscConfig")
}

if d.HasChange("initial_user") {
updateMask = append(updateMask, "initialUser")
}
Expand Down Expand Up @@ -1535,6 +1569,23 @@ func flattenAlloydbClusterDatabaseVersion(v interface{}, d *schema.ResourceData,
return v
}

func flattenAlloydbClusterPscConfig(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["psc_enabled"] =
flattenAlloydbClusterPscConfigPscEnabled(original["pscEnabled"], d, config)
return []interface{}{transformed}
}
func flattenAlloydbClusterPscConfigPscEnabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenAlloydbClusterContinuousBackupConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
Expand Down Expand Up @@ -2092,6 +2143,29 @@ func expandAlloydbClusterDatabaseVersion(v interface{}, d tpgresource.TerraformR
return v, nil
}

func expandAlloydbClusterPscConfig(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{})

transformedPscEnabled, err := expandAlloydbClusterPscConfigPscEnabled(original["psc_enabled"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedPscEnabled); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["pscEnabled"] = transformedPscEnabled
}

return transformed, nil
}

func expandAlloydbClusterPscConfigPscEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandAlloydbClusterInitialUser(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
Expand Down
36 changes: 36 additions & 0 deletions google-beta/services/alloydb/resource_alloydb_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1297,3 +1297,39 @@ resource "google_compute_network" "default" {
data "google_project" "project" {}
`, context)
}

// Ensures cluster creation succeeds for a Private Service Connect enabled cluster.
func TestAccAlloydbCluster_withPrivateServiceConnect(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccCheckAlloydbClusterDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccAlloydbCluster_withPrivateServiceConnect(context),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("google_alloydb_cluster.default", "psc_config.0.psc_enabled", "true"),
),
},
},
})
}

func testAccAlloydbCluster_withPrivateServiceConnect(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_alloydb_cluster" "default" {
cluster_id = "tf-test-alloydb-cluster%{random_suffix}"
location = "us-central1"
psc_config {
psc_enabled = true
}
}
data "google_project" "project" {}
`, context)
}
126 changes: 126 additions & 0 deletions google-beta/services/alloydb/resource_alloydb_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,39 @@ the same instance.`,
},
},
},
"psc_instance_config": {
Type: schema.TypeList,
Optional: true,
Description: `Configuration for Private Service Connect (PSC) for the instance.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"allowed_consumer_projects": {
Type: schema.TypeList,
Optional: true,
Description: `List of consumer projects that are allowed to create PSC endpoints to service-attachments to this instance.
These should be specified as project numbers only.`,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: verify.ValidateRegexp(`^\d+$`),
},
},
"psc_dns_name": {
Type: schema.TypeString,
Computed: true,
Description: `The DNS name of the instance for PSC connectivity.
Name convention: <uid>.<uid>.<region>.alloydb-psc.goog`,
},
"service_attachment_link": {
Type: schema.TypeString,
Computed: true,
Description: `The service attachment created when Private Service Connect (PSC) is enabled for the instance.
The name of the resource will be in the format of
'projects/<alloydb-tenant-project-number>/regions/<region-name>/serviceAttachments/<service-attachment-name>'`,
},
},
},
},
"query_insights_config": {
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -390,6 +423,12 @@ func resourceAlloydbInstanceCreate(d *schema.ResourceData, meta interface{}) err
} else if v, ok := d.GetOkExists("client_connection_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(clientConnectionConfigProp)) && (ok || !reflect.DeepEqual(v, clientConnectionConfigProp)) {
obj["clientConnectionConfig"] = clientConnectionConfigProp
}
pscInstanceConfigProp, err := expandAlloydbInstancePscInstanceConfig(d.Get("psc_instance_config"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("psc_instance_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(pscInstanceConfigProp)) && (ok || !reflect.DeepEqual(v, pscInstanceConfigProp)) {
obj["pscInstanceConfig"] = pscInstanceConfigProp
}
networkConfigProp, err := expandAlloydbInstanceNetworkConfig(d.Get("network_config"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -606,6 +645,9 @@ func resourceAlloydbInstanceRead(d *schema.ResourceData, meta interface{}) error
if err := d.Set("client_connection_config", flattenAlloydbInstanceClientConnectionConfig(res["clientConnectionConfig"], d, config)); err != nil {
return fmt.Errorf("Error reading Instance: %s", err)
}
if err := d.Set("psc_instance_config", flattenAlloydbInstancePscInstanceConfig(res["pscInstanceConfig"], d, config)); err != nil {
return fmt.Errorf("Error reading Instance: %s", err)
}
if err := d.Set("network_config", flattenAlloydbInstanceNetworkConfig(res["networkConfig"], d, config)); err != nil {
return fmt.Errorf("Error reading Instance: %s", err)
}
Expand Down Expand Up @@ -684,6 +726,12 @@ func resourceAlloydbInstanceUpdate(d *schema.ResourceData, meta interface{}) err
} else if v, ok := d.GetOkExists("client_connection_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, clientConnectionConfigProp)) {
obj["clientConnectionConfig"] = clientConnectionConfigProp
}
pscInstanceConfigProp, err := expandAlloydbInstancePscInstanceConfig(d.Get("psc_instance_config"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("psc_instance_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, pscInstanceConfigProp)) {
obj["pscInstanceConfig"] = pscInstanceConfigProp
}
networkConfigProp, err := expandAlloydbInstanceNetworkConfig(d.Get("network_config"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -744,6 +792,10 @@ func resourceAlloydbInstanceUpdate(d *schema.ResourceData, meta interface{}) err
updateMask = append(updateMask, "clientConnectionConfig")
}

if d.HasChange("psc_instance_config") {
updateMask = append(updateMask, "pscInstanceConfig")
}

if d.HasChange("network_config") {
updateMask = append(updateMask, "networkConfig")
}
Expand Down Expand Up @@ -1118,6 +1170,35 @@ func flattenAlloydbInstanceClientConnectionConfigSslConfigSslMode(v interface{},
return v
}

func flattenAlloydbInstancePscInstanceConfig(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["service_attachment_link"] =
flattenAlloydbInstancePscInstanceConfigServiceAttachmentLink(original["serviceAttachmentLink"], d, config)
transformed["allowed_consumer_projects"] =
flattenAlloydbInstancePscInstanceConfigAllowedConsumerProjects(original["allowedConsumerProjects"], d, config)
transformed["psc_dns_name"] =
flattenAlloydbInstancePscInstanceConfigPscDnsName(original["pscDnsName"], d, config)
return []interface{}{transformed}
}
func flattenAlloydbInstancePscInstanceConfigServiceAttachmentLink(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

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

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

func flattenAlloydbInstanceNetworkConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
Expand Down Expand Up @@ -1368,6 +1449,51 @@ func expandAlloydbInstanceClientConnectionConfigSslConfigSslMode(v interface{},
return v, nil
}

func expandAlloydbInstancePscInstanceConfig(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{})

transformedServiceAttachmentLink, err := expandAlloydbInstancePscInstanceConfigServiceAttachmentLink(original["service_attachment_link"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedServiceAttachmentLink); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["serviceAttachmentLink"] = transformedServiceAttachmentLink
}

transformedAllowedConsumerProjects, err := expandAlloydbInstancePscInstanceConfigAllowedConsumerProjects(original["allowed_consumer_projects"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedAllowedConsumerProjects); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["allowedConsumerProjects"] = transformedAllowedConsumerProjects
}

transformedPscDnsName, err := expandAlloydbInstancePscInstanceConfigPscDnsName(original["psc_dns_name"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedPscDnsName); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["pscDnsName"] = transformedPscDnsName
}

return transformed, nil
}

func expandAlloydbInstancePscInstanceConfigServiceAttachmentLink(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandAlloydbInstancePscInstanceConfigAllowedConsumerProjects(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandAlloydbInstancePscInstanceConfigPscDnsName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandAlloydbInstanceNetworkConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
Expand Down
Loading

0 comments on commit 2e60089

Please sign in to comment.