Skip to content

Commit 977c86c

Browse files
feat: google_datastream_private_connection resource network_attachement support via psc_interface_config (#13947) (#23091)
[upstream:c4369ef12e5825caaf44f58f122e56327a8d58a8] Signed-off-by: Modular Magician <[email protected]>
1 parent aad88fe commit 977c86c

File tree

5 files changed

+250
-40
lines changed

5 files changed

+250
-40
lines changed

.changelog/13947.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
datastream: `google_datastream_private_connection` resource `network_attachement` support via `psc_interface_config` attribute
3+
```

google/services/datastream/resource_datastream_private_connection.go

Lines changed: 95 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ func ResourceDatastreamPrivateConnection() *schema.Resource {
8181
},
8282

8383
Timeouts: &schema.ResourceTimeout{
84-
Create: schema.DefaultTimeout(20 * time.Minute),
85-
Update: schema.DefaultTimeout(20 * time.Minute),
86-
Delete: schema.DefaultTimeout(20 * time.Minute),
84+
Create: schema.DefaultTimeout(30 * time.Minute),
85+
Update: schema.DefaultTimeout(30 * time.Minute),
86+
Delete: schema.DefaultTimeout(30 * time.Minute),
8787
},
8888

8989
SchemaVersion: 1,
@@ -119,9 +119,50 @@ func ResourceDatastreamPrivateConnection() *schema.Resource {
119119
ForceNew: true,
120120
Description: `The private connectivity identifier.`,
121121
},
122+
"create_without_validation": {
123+
Type: schema.TypeBool,
124+
Optional: true,
125+
ForceNew: true,
126+
Description: `If set to true, will skip validations.`,
127+
Default: false,
128+
},
129+
"labels": {
130+
Type: schema.TypeMap,
131+
Optional: true,
132+
Description: `Labels.
133+
134+
**Note**: This field is non-authoritative, and will only manage the labels present in your configuration.
135+
Please refer to the field 'effective_labels' for all of the labels present on the resource.`,
136+
Elem: &schema.Schema{Type: schema.TypeString},
137+
},
138+
"psc_interface_config": {
139+
Type: schema.TypeList,
140+
Optional: true,
141+
ForceNew: true,
142+
Description: `The PSC Interface configuration is used to create PSC Interface
143+
between Datastream and the consumer's PSC.`,
144+
MaxItems: 1,
145+
Elem: &schema.Resource{
146+
Schema: map[string]*schema.Schema{
147+
"network_attachment": {
148+
Type: schema.TypeString,
149+
Required: true,
150+
ForceNew: true,
151+
Description: `Fully qualified name of the network attachment that Datastream will connect to.
152+
Format: projects/{project}/regions/{region}/networkAttachments/{name}
153+
154+
To get Datastream project for the accepted list:
155+
'gcloud datastream private-connections create [PC ID] --location=[LOCATION] --network-attachment=[NA URI] --validate-only --display-name=[ANY STRING]'
156+
Add Datastream project to the attachment accepted list:
157+
'gcloud compute network-attachments update [NA URI] --region=[NA region] --producer-accept-list=[TP from prev command]'`,
158+
},
159+
},
160+
},
161+
ExactlyOneOf: []string{"vpc_peering_config", "psc_interface_config"},
162+
},
122163
"vpc_peering_config": {
123164
Type: schema.TypeList,
124-
Required: true,
165+
Optional: true,
125166
ForceNew: true,
126167
Description: `The VPC Peering configuration is used to create VPC peering
127168
between Datastream and the consumer's VPC.`,
@@ -143,22 +184,7 @@ Format: projects/{project}/global/{networks}/{name}`,
143184
},
144185
},
145186
},
146-
},
147-
"create_without_validation": {
148-
Type: schema.TypeBool,
149-
Optional: true,
150-
ForceNew: true,
151-
Description: `If set to true, will skip validations.`,
152-
Default: false,
153-
},
154-
"labels": {
155-
Type: schema.TypeMap,
156-
Optional: true,
157-
Description: `Labels.
158-
159-
**Note**: This field is non-authoritative, and will only manage the labels present in your configuration.
160-
Please refer to the field 'effective_labels' for all of the labels present on the resource.`,
161-
Elem: &schema.Schema{Type: schema.TypeString},
187+
ExactlyOneOf: []string{"vpc_peering_config", "psc_interface_config"},
162188
},
163189
"effective_labels": {
164190
Type: schema.TypeMap,
@@ -235,6 +261,12 @@ func resourceDatastreamPrivateConnectionCreate(d *schema.ResourceData, meta inte
235261
} else if v, ok := d.GetOkExists("vpc_peering_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(vpcPeeringConfigProp)) && (ok || !reflect.DeepEqual(v, vpcPeeringConfigProp)) {
236262
obj["vpcPeeringConfig"] = vpcPeeringConfigProp
237263
}
264+
pscInterfaceConfigProp, err := expandDatastreamPrivateConnectionPscInterfaceConfig(d.Get("psc_interface_config"), d, config)
265+
if err != nil {
266+
return err
267+
} else if v, ok := d.GetOkExists("psc_interface_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(pscInterfaceConfigProp)) && (ok || !reflect.DeepEqual(v, pscInterfaceConfigProp)) {
268+
obj["pscInterfaceConfig"] = pscInterfaceConfigProp
269+
}
238270
labelsProp, err := expandDatastreamPrivateConnectionEffectiveLabels(d.Get("effective_labels"), d, config)
239271
if err != nil {
240272
return err
@@ -362,6 +394,9 @@ func resourceDatastreamPrivateConnectionRead(d *schema.ResourceData, meta interf
362394
if err := d.Set("vpc_peering_config", flattenDatastreamPrivateConnectionVpcPeeringConfig(res["vpcPeeringConfig"], d, config)); err != nil {
363395
return fmt.Errorf("Error reading PrivateConnection: %s", err)
364396
}
397+
if err := d.Set("psc_interface_config", flattenDatastreamPrivateConnectionPscInterfaceConfig(res["pscInterfaceConfig"], d, config)); err != nil {
398+
return fmt.Errorf("Error reading PrivateConnection: %s", err)
399+
}
365400
if err := d.Set("terraform_labels", flattenDatastreamPrivateConnectionTerraformLabels(res["labels"], d, config)); err != nil {
366401
return fmt.Errorf("Error reading PrivateConnection: %s", err)
367402
}
@@ -535,6 +570,23 @@ func flattenDatastreamPrivateConnectionVpcPeeringConfigSubnet(v interface{}, d *
535570
return v
536571
}
537572

573+
func flattenDatastreamPrivateConnectionPscInterfaceConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
574+
if v == nil {
575+
return nil
576+
}
577+
original := v.(map[string]interface{})
578+
if len(original) == 0 {
579+
return nil
580+
}
581+
transformed := make(map[string]interface{})
582+
transformed["network_attachment"] =
583+
flattenDatastreamPrivateConnectionPscInterfaceConfigNetworkAttachment(original["networkAttachment"], d, config)
584+
return []interface{}{transformed}
585+
}
586+
func flattenDatastreamPrivateConnectionPscInterfaceConfigNetworkAttachment(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
587+
return v
588+
}
589+
538590
func flattenDatastreamPrivateConnectionTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
539591
if v == nil {
540592
return v
@@ -592,6 +644,29 @@ func expandDatastreamPrivateConnectionVpcPeeringConfigSubnet(v interface{}, d tp
592644
return v, nil
593645
}
594646

647+
func expandDatastreamPrivateConnectionPscInterfaceConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
648+
l := v.([]interface{})
649+
if len(l) == 0 || l[0] == nil {
650+
return nil, nil
651+
}
652+
raw := l[0]
653+
original := raw.(map[string]interface{})
654+
transformed := make(map[string]interface{})
655+
656+
transformedNetworkAttachment, err := expandDatastreamPrivateConnectionPscInterfaceConfigNetworkAttachment(original["network_attachment"], d, config)
657+
if err != nil {
658+
return nil, err
659+
} else if val := reflect.ValueOf(transformedNetworkAttachment); val.IsValid() && !tpgresource.IsEmptyValue(val) {
660+
transformed["networkAttachment"] = transformedNetworkAttachment
661+
}
662+
663+
return transformed, nil
664+
}
665+
666+
func expandDatastreamPrivateConnectionPscInterfaceConfigNetworkAttachment(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
667+
return v, nil
668+
}
669+
595670
func expandDatastreamPrivateConnectionEffectiveLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) {
596671
if v == nil {
597672
return map[string]string{}, nil

google/services/datastream/resource_datastream_private_connection_generated_meta.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ fields:
1818
- field: 'name'
1919
- field: 'private_connection_id'
2020
provider_only: true
21+
- field: 'psc_interface_config.network_attachment'
2122
- field: 'state'
2223
- field: 'terraform_labels'
2324
provider_only: true

google/services/datastream/resource_datastream_private_connection_generated_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/hashicorp/terraform-plugin-testing/terraform"
2727

2828
"github.com/hashicorp/terraform-provider-google/google/acctest"
29+
"github.com/hashicorp/terraform-provider-google/google/envvar"
2930
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
3031
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
3132
)
@@ -78,6 +79,77 @@ resource "google_compute_network" "default" {
7879
`, context)
7980
}
8081

82+
func TestAccDatastreamPrivateConnection_datastreamPrivateConnectionPscInterfaceExample(t *testing.T) {
83+
t.Parallel()
84+
85+
context := map[string]interface{}{
86+
"billing_account": envvar.GetTestBillingAccountFromEnv(t),
87+
"org_id": envvar.GetTestOrgFromEnv(t),
88+
"project": envvar.GetTestProjectFromEnv(),
89+
"project_number": envvar.GetTestProjectNumberFromEnv(),
90+
"random_suffix": acctest.RandString(t, 10),
91+
}
92+
93+
acctest.VcrTest(t, resource.TestCase{
94+
PreCheck: func() { acctest.AccTestPreCheck(t) },
95+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
96+
CheckDestroy: testAccCheckDatastreamPrivateConnectionDestroyProducer(t),
97+
Steps: []resource.TestStep{
98+
{
99+
Config: testAccDatastreamPrivateConnection_datastreamPrivateConnectionPscInterfaceExample(context),
100+
},
101+
{
102+
ResourceName: "google_datastream_private_connection.default",
103+
ImportState: true,
104+
ImportStateVerify: true,
105+
ImportStateVerifyIgnore: []string{"create_without_validation", "labels", "location", "private_connection_id", "terraform_labels"},
106+
},
107+
},
108+
})
109+
}
110+
111+
func testAccDatastreamPrivateConnection_datastreamPrivateConnectionPscInterfaceExample(context map[string]interface{}) string {
112+
return acctest.Nprintf(`
113+
resource "google_datastream_private_connection" "default" {
114+
display_name = "Connection profile"
115+
location = "us-central1"
116+
private_connection_id = "tf-test-my-connection%{random_suffix}"
117+
118+
labels = {
119+
key = "value"
120+
}
121+
122+
psc_interface_config {
123+
network_attachment = google_compute_network_attachment.default.id
124+
}
125+
}
126+
127+
resource "google_compute_network_attachment" "default" {
128+
name = "tf-test-my-network-attachment%{random_suffix}"
129+
region = "us-central1"
130+
description = "basic network attachment description"
131+
connection_preference = "ACCEPT_AUTOMATIC"
132+
133+
subnetworks = [
134+
google_compute_subnetwork.default.self_link
135+
]
136+
}
137+
138+
resource "google_compute_network" "default" {
139+
name = "tf-test-my-network%{random_suffix}"
140+
auto_create_subnetworks = false
141+
}
142+
143+
resource "google_compute_subnetwork" "default" {
144+
name = "tf-test-my-subnetwork%{random_suffix}"
145+
region = "us-central1"
146+
147+
network = google_compute_network.default.id
148+
ip_cidr_range = "10.0.0.0/16"
149+
}
150+
`, context)
151+
}
152+
81153
func testAccCheckDatastreamPrivateConnectionDestroyProducer(t *testing.T) func(s *terraform.State) error {
82154
return func(s *terraform.State) error {
83155
for name, rs := range s.RootModule().Resources {

0 commit comments

Comments
 (0)