From dc231d4ba37c4a33aa83bcd1c5bc3e15ce7e07e3 Mon Sep 17 00:00:00 2001
From: Dana Hoffman <danahoffman@google.com>
Date: Wed, 12 Dec 2018 01:18:44 +0000
Subject: [PATCH] extract vpn tunnel region/project from vpn gateway

---
 google/resource_compute_vpn_tunnel.go         | 20 +++++
 google/resource_compute_vpn_tunnel_test.go    | 85 +++++++++++++++++++
 .../docs/r/compute_vpn_tunnel.html.markdown   |  2 +-
 3 files changed, 106 insertions(+), 1 deletion(-)

diff --git a/google/resource_compute_vpn_tunnel.go b/google/resource_compute_vpn_tunnel.go
index 15b8f384525..1fd50a005ac 100644
--- a/google/resource_compute_vpn_tunnel.go
+++ b/google/resource_compute_vpn_tunnel.go
@@ -326,6 +326,11 @@ func resourceComputeVpnTunnelCreate(d *schema.ResourceData, meta interface{}) er
 		obj["region"] = regionProp
 	}
 
+	obj, err = resourceComputeVpnTunnelEncoder(d, meta, obj)
+	if err != nil {
+		return err
+	}
+
 	url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/vpnTunnels")
 	if err != nil {
 		return err
@@ -694,3 +699,18 @@ func expandComputeVpnTunnelRegion(v interface{}, d *schema.ResourceData, config
 	}
 	return f.RelativeLink(), nil
 }
+
+func resourceComputeVpnTunnelEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
+	config := meta.(*Config)
+	f, err := parseRegionalFieldValue("targetVpnGateways", d.Get("target_vpn_gateway").(string), "project", "region", "zone", d, config, true)
+	if err != nil {
+		return nil, err
+	}
+	if _, ok := d.GetOk("project"); !ok {
+		d.Set("project", f.Project)
+	}
+	if _, ok := d.GetOk("region"); !ok {
+		d.Set("region", f.Region)
+	}
+	return obj, nil
+}
diff --git a/google/resource_compute_vpn_tunnel_test.go b/google/resource_compute_vpn_tunnel_test.go
index eed67655508..436fb5f1f57 100644
--- a/google/resource_compute_vpn_tunnel_test.go
+++ b/google/resource_compute_vpn_tunnel_test.go
@@ -29,6 +29,34 @@ func TestAccComputeVpnTunnel_basic(t *testing.T) {
 	})
 }
 
+func TestAccComputeVpnTunnel_regionFromGateway(t *testing.T) {
+	t.Parallel()
+	region := "us-central1"
+	if getTestRegionFromEnv() == region {
+		// Make sure we choose a region that isn't the provider default
+		// in order to test getting the region from the gateway and not the
+		// provider.
+		region = "us-west1"
+	}
+
+	resource.Test(t, resource.TestCase{
+		PreCheck:     func() { testAccPreCheck(t) },
+		Providers:    testAccProviders,
+		CheckDestroy: testAccCheckComputeVpnTunnelDestroy,
+		Steps: []resource.TestStep{
+			resource.TestStep{
+				Config: testAccComputeVpnTunnel_regionFromGateway(region),
+			},
+			resource.TestStep{
+				ResourceName:            "google_compute_vpn_tunnel.foobar",
+				ImportState:             true,
+				ImportStateVerify:       true,
+				ImportStateVerifyIgnore: []string{"shared_secret"},
+			},
+		},
+	})
+}
+
 func TestAccComputeVpnTunnel_router(t *testing.T) {
 	t.Parallel()
 
@@ -128,6 +156,63 @@ resource "google_compute_vpn_tunnel" "foobar" {
 		acctest.RandString(10), acctest.RandString(10))
 }
 
+func testAccComputeVpnTunnel_regionFromGateway(region string) string {
+	return fmt.Sprintf(`
+resource "google_compute_network" "foobar" {
+	name = "tunnel-test-%s"
+}
+resource "google_compute_subnetwork" "foobar" {
+	name = "tunnel-test-subnetwork-%s"
+	network = "${google_compute_network.foobar.self_link}"
+	ip_cidr_range = "10.0.0.0/16"
+	region = "%s"
+}
+resource "google_compute_address" "foobar" {
+	name = "tunnel-test-%s"
+	region = "${google_compute_subnetwork.foobar.region}"
+}
+resource "google_compute_vpn_gateway" "foobar" {
+	name = "tunnel-test-%s"
+	network = "${google_compute_network.foobar.self_link}"
+	region = "${google_compute_subnetwork.foobar.region}"
+}
+resource "google_compute_forwarding_rule" "foobar_esp" {
+	name = "tunnel-test-%s"
+	region = "${google_compute_vpn_gateway.foobar.region}"
+	ip_protocol = "ESP"
+	ip_address = "${google_compute_address.foobar.address}"
+	target = "${google_compute_vpn_gateway.foobar.self_link}"
+}
+resource "google_compute_forwarding_rule" "foobar_udp500" {
+	name = "tunnel-test-%s"
+	region = "${google_compute_forwarding_rule.foobar_esp.region}"
+	ip_protocol = "UDP"
+	port_range = "500-500"
+	ip_address = "${google_compute_address.foobar.address}"
+	target = "${google_compute_vpn_gateway.foobar.self_link}"
+}
+resource "google_compute_forwarding_rule" "foobar_udp4500" {
+	name = "tunnel-test-%s"
+	region = "${google_compute_forwarding_rule.foobar_udp500.region}"
+	ip_protocol = "UDP"
+	port_range = "4500-4500"
+	ip_address = "${google_compute_address.foobar.address}"
+	target = "${google_compute_vpn_gateway.foobar.self_link}"
+}
+resource "google_compute_vpn_tunnel" "foobar" {
+	name = "tunnel-test-%s"
+	target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}"
+	shared_secret = "unguessable"
+	peer_ip = "8.8.8.8"
+	local_traffic_selector = ["${google_compute_subnetwork.foobar.ip_cidr_range}"]
+	remote_traffic_selector = ["192.168.0.0/24", "192.168.1.0/24"]
+
+	depends_on = ["google_compute_forwarding_rule.foobar_udp4500"]
+}`, acctest.RandString(10), acctest.RandString(10), region, acctest.RandString(10),
+		acctest.RandString(10), acctest.RandString(10), acctest.RandString(10),
+		acctest.RandString(10), acctest.RandString(10))
+}
+
 func testAccComputeVpnTunnelRouter(router string) string {
 	testId := acctest.RandString(10)
 	return fmt.Sprintf(`
diff --git a/website/docs/r/compute_vpn_tunnel.html.markdown b/website/docs/r/compute_vpn_tunnel.html.markdown
index 05df2a91209..f7b1aa033ae 100644
--- a/website/docs/r/compute_vpn_tunnel.html.markdown
+++ b/website/docs/r/compute_vpn_tunnel.html.markdown
@@ -171,7 +171,7 @@ The following arguments are supported:
 
 * `region` -
   (Optional)
-  The region where the tunnel is located.
+  The region where the tunnel is located. If unset, is set to the region of `target_vpn_gateway`.
 * `project` - (Optional) The ID of the project in which the resource belongs.
     If it is not provided, the provider project is used.