From 808cbd35ddc4949be4b0a27964532ab4ed398aa0 Mon Sep 17 00:00:00 2001 From: Roberto Jung Drebes Date: Fri, 27 Jan 2017 15:32:42 +0100 Subject: [PATCH 1/3] providers/google: cloud_router --- import_compute_router_interface_test.go | 27 ++ import_compute_router_peer_test.go | 27 ++ import_compute_router_test.go | 28 +++ provider.go | 7 + resource_compute_router.go | 251 +++++++++++++++++++ resource_compute_router_interface.go | 288 +++++++++++++++++++++ resource_compute_router_interface_test.go | 247 ++++++++++++++++++ resource_compute_router_peer.go | 290 ++++++++++++++++++++++ resource_compute_router_peer_test.go | 263 ++++++++++++++++++++ resource_compute_router_test.go | 176 +++++++++++++ resource_compute_vpn_tunnel.go | 46 ++++ resource_compute_vpn_tunnel_test.go | 80 ++++++ 12 files changed, 1730 insertions(+) create mode 100644 import_compute_router_interface_test.go create mode 100644 import_compute_router_peer_test.go create mode 100644 import_compute_router_test.go create mode 100644 resource_compute_router.go create mode 100644 resource_compute_router_interface.go create mode 100644 resource_compute_router_interface_test.go create mode 100644 resource_compute_router_peer.go create mode 100644 resource_compute_router_peer_test.go create mode 100644 resource_compute_router_test.go diff --git a/import_compute_router_interface_test.go b/import_compute_router_interface_test.go new file mode 100644 index 00000000..7a5f348f --- /dev/null +++ b/import_compute_router_interface_test.go @@ -0,0 +1,27 @@ +package google + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccComputeRouterInterface_import(t *testing.T) { + resourceName := "google_compute_router_interface.foobar" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeRouterInterface_basic, + }, + + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/import_compute_router_peer_test.go b/import_compute_router_peer_test.go new file mode 100644 index 00000000..f17d7d55 --- /dev/null +++ b/import_compute_router_peer_test.go @@ -0,0 +1,27 @@ +package google + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccComputeRouterPeer_import(t *testing.T) { + resourceName := "google_compute_router_peer.foobar" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeRouterPeer_basic, + }, + + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/import_compute_router_test.go b/import_compute_router_test.go new file mode 100644 index 00000000..9e81798e --- /dev/null +++ b/import_compute_router_test.go @@ -0,0 +1,28 @@ +package google + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccComputeRouter_import(t *testing.T) { + resourceName := "google_compute_router.foobar" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeRouterDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeRouter_networkLink, + }, + + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/provider.go b/provider.go index ce33f7e4..1486d369 100644 --- a/provider.go +++ b/provider.go @@ -5,12 +5,16 @@ import ( "fmt" "strings" + "github.com/hashicorp/terraform/helper/mutexkv" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" "google.golang.org/api/compute/v1" "google.golang.org/api/googleapi" ) +// Global MutexKV +var mutexKV = mutexkv.NewMutexKV() + // Provider returns a terraform.ResourceProvider. func Provider() terraform.ResourceProvider { return &schema.Provider{ @@ -76,6 +80,9 @@ func Provider() terraform.ResourceProvider { "google_compute_project_metadata": resourceComputeProjectMetadata(), "google_compute_region_backend_service": resourceComputeRegionBackendService(), "google_compute_route": resourceComputeRoute(), + "google_compute_router": resourceComputeRouter(), + "google_compute_router_interface": resourceComputeRouterInterface(), + "google_compute_router_peer": resourceComputeRouterPeer(), "google_compute_ssl_certificate": resourceComputeSslCertificate(), "google_compute_subnetwork": resourceComputeSubnetwork(), "google_compute_target_http_proxy": resourceComputeTargetHttpProxy(), diff --git a/resource_compute_router.go b/resource_compute_router.go new file mode 100644 index 00000000..e02c5602 --- /dev/null +++ b/resource_compute_router.go @@ -0,0 +1,251 @@ +package google + +import ( + "fmt" + "log" + + "strings" + + "github.com/hashicorp/terraform/helper/schema" + "google.golang.org/api/compute/v1" + "google.golang.org/api/googleapi" +) + +func resourceComputeRouter() *schema.Resource { + return &schema.Resource{ + Create: resourceComputeRouterCreate, + Read: resourceComputeRouterRead, + Delete: resourceComputeRouterDelete, + Importer: &schema.ResourceImporter{ + State: resourceComputeRouterImportState, + }, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "network": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "project": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "region": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + + "bgp": &schema.Schema{ + Type: schema.TypeList, + MaxItems: 1, + Required: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + + "asn": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + }, + }, + }, + + "self_link": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceComputeRouterCreate(d *schema.ResourceData, meta interface{}) error { + + config := meta.(*Config) + + region, err := getRegion(d, config) + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + + name := d.Get("name").(string) + + routerId := fmt.Sprintf("router/%s/%s", region, name) + mutexKV.Lock(routerId) + defer mutexKV.Unlock(routerId) + + network, err := getNetworkLink(d, config, "network") + if err != nil { + return err + } + routersService := compute.NewRoutersService(config.clientCompute) + + router := &compute.Router{ + Name: name, + Network: network, + } + + if v, ok := d.GetOk("description"); ok { + router.Description = v.(string) + } + + if _, ok := d.GetOk("bgp"); ok { + prefix := "bgp.0" + if v, ok := d.GetOk(prefix + ".asn"); ok { + asn := v.(int) + bgp := &compute.RouterBgp{ + Asn: int64(asn), + } + router.Bgp = bgp + } + } + + op, err := routersService.Insert(project, region, router).Do() + if err != nil { + return fmt.Errorf("Error Inserting Router %s into network %s: %s", name, network, err) + } + + err = computeOperationWaitRegion(config, op, project, region, "Inserting Router") + if err != nil { + return fmt.Errorf("Error Waiting to Insert Router %s into network %s: %s", name, network, err) + } + + return resourceComputeRouterRead(d, meta) +} + +func resourceComputeRouterRead(d *schema.ResourceData, meta interface{}) error { + + config := meta.(*Config) + + region, err := getRegion(d, config) + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + + name := d.Get("name").(string) + routersService := compute.NewRoutersService(config.clientCompute) + router, err := routersService.Get(project, region, name).Do() + + if err != nil { + if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { + log.Printf("[WARN] Removing Router %q because it's gone", d.Get("name").(string)) + d.SetId("") + + return nil + } + + return fmt.Errorf("Error Reading Router %s: %s", name, err) + } + + d.Set("self_link", router.SelfLink) + + // if we don't have a network (when importing), set it to the URI returned from the server + if _, ok := d.GetOk("network"); !ok { + d.Set("network", router.Network) + } + + d.Set("region", region) + d.Set("bgp", flattenAsn(router.Bgp.Asn)) + d.SetId(fmt.Sprintf("%s/%s", region, name)) + + return nil +} + +func resourceComputeRouterDelete(d *schema.ResourceData, meta interface{}) error { + + config := meta.(*Config) + + region, err := getRegion(d, config) + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + + name := d.Get("name").(string) + + routerId := fmt.Sprintf("router/%s/%s", region, name) + mutexKV.Lock(routerId) + defer mutexKV.Unlock(routerId) + + routersService := compute.NewRoutersService(config.clientCompute) + + op, err := routersService.Delete(project, region, name).Do() + if err != nil { + return fmt.Errorf("Error Reading Router %s: %s", name, err) + } + + err = computeOperationWaitRegion(config, op, project, region, "Deleting Router") + if err != nil { + return fmt.Errorf("Error Waiting to Delete Router %s: %s", name, err) + } + + return nil +} + +func resourceComputeRouterImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + parts := strings.Split(d.Id(), "/") + if len(parts) != 2 { + return nil, fmt.Errorf("Invalid router specifier. Expecting {region}/{name}") + } + + d.Set("region", parts[0]) + d.Set("name", parts[1]) + + return []*schema.ResourceData{d}, nil +} + +func getRouterLink(config *Config, project string, region string, router string) (string, error) { + + if !strings.HasPrefix(router, "https://www.googleapis.com/compute/") { + // Router value provided is just the name, lookup the router SelfLink + routerData, err := config.clientCompute.Routers.Get( + project, region, router).Do() + if err != nil { + return "", fmt.Errorf("Error reading router: %s", err) + } + router = routerData.SelfLink + } + + return router, nil + +} + +func flattenAsn(asn int64) []map[string]interface{} { + result := make([]map[string]interface{}, 0, 1) + r := make(map[string]interface{}) + r["asn"] = asn + result = append(result, r) + return result +} diff --git a/resource_compute_router_interface.go b/resource_compute_router_interface.go new file mode 100644 index 00000000..56910207 --- /dev/null +++ b/resource_compute_router_interface.go @@ -0,0 +1,288 @@ +package google + +import ( + "fmt" + "log" + + "strings" + + "github.com/hashicorp/terraform/helper/schema" + "google.golang.org/api/compute/v1" + "google.golang.org/api/googleapi" +) + +func resourceComputeRouterInterface() *schema.Resource { + return &schema.Resource{ + Create: resourceComputeRouterInterfaceCreate, + Read: resourceComputeRouterInterfaceRead, + Delete: resourceComputeRouterInterfaceDelete, + Importer: &schema.ResourceImporter{ + State: resourceComputeRouterInterfaceImportState, + }, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "router": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "vpn_tunnel": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "ip_range": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "project": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "region": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + } +} + +func resourceComputeRouterInterfaceCreate(d *schema.ResourceData, meta interface{}) error { + + config := meta.(*Config) + + region, err := getRegion(d, config) + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + + routerName := d.Get("router").(string) + ifaceName := d.Get("name").(string) + + routerId := fmt.Sprintf("router/%s/%s", region, routerName) + mutexKV.Lock(routerId) + defer mutexKV.Unlock(routerId) + + routersService := compute.NewRoutersService(config.clientCompute) + router, err := routersService.Get(project, region, routerName).Do() + if err != nil { + if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { + log.Printf("[WARN] Removing router interface because its router %s/%s is gone", region, routerName) + d.SetId("") + + return nil + } + + return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err) + } + + var ifaceExists bool = false + + var ifaces []*compute.RouterInterface = router.Interfaces + for _, iface := range ifaces { + + if iface.Name == ifaceName { + ifaceExists = true + break + } + } + + if !ifaceExists { + + vpnTunnel, err := getVpnTunnelLink(config, project, region, d.Get("vpn_tunnel").(string)) + if err != nil { + return err + } + + iface := &compute.RouterInterface{Name: ifaceName, + LinkedVpnTunnel: vpnTunnel} + + if v, ok := d.GetOk("ip_range"); ok { + iface.IpRange = v.(string) + } + + log.Printf( + "[INFO] Adding interface %s", ifaceName) + ifaces = append(ifaces, iface) + patchRouter := &compute.Router{ + Interfaces: ifaces, + } + + log.Printf("[DEBUG] Updating router %s/%s with interfaces: %+v", region, routerName, ifaces) + op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() + if err != nil { + return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) + } + + err = computeOperationWaitRegion(config, op, project, region, "Patching router") + if err != nil { + return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) + } + + d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, ifaceName)) + + } else { + log.Printf("[DEBUG] Router %s has interface %s already", routerName, ifaceName) + } + + return resourceComputeRouterInterfaceRead(d, meta) +} + +func resourceComputeRouterInterfaceRead(d *schema.ResourceData, meta interface{}) error { + + config := meta.(*Config) + + region, err := getRegion(d, config) + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + + routerName := d.Get("router").(string) + ifaceName := d.Get("name").(string) + + routersService := compute.NewRoutersService(config.clientCompute) + router, err := routersService.Get(project, region, routerName).Do() + if err != nil { + if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { + log.Printf("[WARN] Removing router interface because its router %s/%s is gone", region, routerName) + d.SetId("") + + return nil + } + + return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err) + } + + var ifaceFound bool = false + + var ifaces []*compute.RouterInterface = router.Interfaces + for _, iface := range ifaces { + + if iface.Name == ifaceName { + ifaceFound = true + d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, ifaceName)) + // if we don't have a tunnel (when importing), set it to the URI returned from the server + if _, ok := d.GetOk("vpn_tunnel"); !ok { + vpnTunnelName, err := getVpnTunnelName(iface.LinkedVpnTunnel) + if err != nil { + return err + } + d.Set("vpn_tunnel", vpnTunnelName) + } + d.Set("ip_range", iface.IpRange) + } + } + if !ifaceFound { + log.Printf("[WARN] Removing router interface %s/%s/%s because it is gone", region, routerName, ifaceName) + d.SetId("") + } + + return nil +} + +func resourceComputeRouterInterfaceDelete(d *schema.ResourceData, meta interface{}) error { + + config := meta.(*Config) + + region, err := getRegion(d, config) + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + + routerName := d.Get("router").(string) + ifaceName := d.Get("name").(string) + + routerId := fmt.Sprintf("router/%s/%s", region, routerName) + mutexKV.Lock(routerId) + defer mutexKV.Unlock(routerId) + + routersService := compute.NewRoutersService(config.clientCompute) + router, err := routersService.Get(project, region, routerName).Do() + if err != nil { + if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { + log.Printf("[WARN] Removing router interface because its router %d is gone", d.Get("router").(string)) + + return nil + } + + return fmt.Errorf("Error Reading Router %s: %s", routerName, err) + } + + var ifaceFound bool = false + + var oldIfaces []*compute.RouterInterface = router.Interfaces + var newIfaces []*compute.RouterInterface = make([]*compute.RouterInterface, len(router.Interfaces)) + for _, iface := range oldIfaces { + + if iface.Name == ifaceName { + ifaceFound = true + continue + } else { + newIfaces = append(newIfaces, iface) + } + } + + if ifaceFound { + + log.Printf( + "[INFO] Removing interface %s", ifaceName) + patchRouter := &compute.Router{ + Interfaces: newIfaces, + } + + log.Printf("[DEBUG] Updating router %s/%s with interfaces: %+v", region, routerName, newIfaces) + op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() + if err != nil { + return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) + } + + err = computeOperationWaitRegion(config, op, project, region, "Patching router") + if err != nil { + return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) + } + + } else { + log.Printf("[DEBUG] Router %s/%s had no interface %s already", region, routerName, ifaceName) + } + + return nil +} + +func resourceComputeRouterInterfaceImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + parts := strings.Split(d.Id(), "/") + if len(parts) != 3 { + return nil, fmt.Errorf("Invalid router specifier. Expecting {region}/{router}") + } + + d.Set("region", parts[0]) + d.Set("router", parts[1]) + d.Set("name", parts[2]) + + return []*schema.ResourceData{d}, nil +} diff --git a/resource_compute_router_interface_test.go b/resource_compute_router_interface_test.go new file mode 100644 index 00000000..ebd81ccf --- /dev/null +++ b/resource_compute_router_interface_test.go @@ -0,0 +1,247 @@ +package google + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + + "google.golang.org/api/compute/v1" +) + +func TestAccComputeRouterInterface_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeRouterInterface_basic, + Check: testAccCheckComputeRouterInterfaceExists( + "google_compute_router_interface.foobar"), + }, + resource.TestStep{ + Config: testAccComputeRouterInterface_keepRouter, + Check: testAccCheckComputeRouterInterfaceDestroy( + "google_compute_router_interface.foobar"), + }, + }, + }) +} + +func testAccCheckComputeRouterInterfaceDestroy(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + project := config.Project + + routersService := compute.NewRoutersService(config.clientCompute) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "google_compute_router_interface" { + continue + } + + region := rs.Primary.Attributes["region"] + name := rs.Primary.Attributes["name"] + routerName := rs.Primary.Attributes["router"] + + router, err := routersService.Get(project, region, routerName).Do() + + if err != nil { + return fmt.Errorf("Error Reading Router %s: %s", routerName, err) + } + + var ifaceExists bool = false + + var ifaces []*compute.RouterInterface = router.Interfaces + for _, iface := range ifaces { + + if iface.Name == name { + ifaceExists = true + break + } + } + + if ifaceExists { + return fmt.Errorf("Interface %s still exists on router %s", name, router.Name) + } + + } + + return nil + } +} + +func testAccCheckComputeRouterInterfaceExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + name := rs.Primary.Attributes["name"] + routerName := rs.Primary.Attributes["router"] + region := rs.Primary.Attributes["region"] + project := config.Project + + routersService := compute.NewRoutersService(config.clientCompute) + router, err := routersService.Get(project, region, routerName).Do() + + if err != nil { + return fmt.Errorf("Error Reading Router %s: %s", routerName, err) + } + + var ifaceExists bool = false + + var ifaces []*compute.RouterInterface = router.Interfaces + for _, iface := range ifaces { + + if iface.Name == name { + ifaceExists = true + break + } + } + + if !ifaceExists { + return fmt.Errorf("Interface %s not found for router %s", name, router.Name) + } + + return nil + } +} + +var testAccComputeRouterInterface_basic = fmt.Sprintf(` +resource "google_compute_network" "foobar" { + name = "interface-test-%s" +} +resource "google_compute_subnetwork" "foobar" { + name = "interface-test-%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" +} +resource "google_compute_address" "foobar" { + name = "interface-test-%s" + region = "${google_compute_subnetwork.foobar.region}" +} +resource "google_compute_vpn_gateway" "foobar" { + name = "interface-test-%s" + network = "${google_compute_network.foobar.self_link}" + region = "${google_compute_subnetwork.foobar.region}" +} +resource "google_compute_forwarding_rule" "foobar_esp" { + name = "interface-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 = "interface-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 = "interface-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_router" "foobar"{ + name = "interface-test-%s" + region = "${google_compute_forwarding_rule.foobar_udp500.region}" + network = "${google_compute_network.foobar.self_link}" + bgp { + asn = 64514 + } +} +resource "google_compute_vpn_tunnel" "foobar" { + name = "interface-test-%s" + region = "${google_compute_forwarding_rule.foobar_udp4500.region}" + target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" + shared_secret = "unguessable" + peer_ip = "8.8.8.8" + router = "${google_compute_router.foobar.name}" +} +resource "google_compute_router_interface" "foobar" { + name = "interface-test-%s" + router = "${google_compute_router.foobar.name}" + region = "${google_compute_router.foobar.region}" + ip_range = "169.254.3.1/30" + vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}" +}`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), + acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), + acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), + acctest.RandString(10)) + +var testAccComputeRouterInterface_keepRouter = fmt.Sprintf(` +resource "google_compute_network" "foobar" { + name = "interface-test-%s" +} +resource "google_compute_subnetwork" "foobar" { + name = "interface-test-%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" +} +resource "google_compute_address" "foobar" { + name = "interface-test-%s" + region = "${google_compute_subnetwork.foobar.region}" +} +resource "google_compute_vpn_gateway" "foobar" { + name = "interface-test-%s" + network = "${google_compute_network.foobar.self_link}" + region = "${google_compute_subnetwork.foobar.region}" +} +resource "google_compute_forwarding_rule" "foobar_esp" { + name = "interface-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 = "interface-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 = "interface-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_router" "foobar"{ + name = "interface-test-%s" + region = "${google_compute_forwarding_rule.foobar_udp500.region}" + network = "${google_compute_network.foobar.self_link}" + bgp { + asn = 64514 + } +} +resource "google_compute_vpn_tunnel" "foobar" { + name = "interface-test-%s" + region = "${google_compute_forwarding_rule.foobar_udp4500.region}" + target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" + shared_secret = "unguessable" + peer_ip = "8.8.8.8" + router = "${google_compute_router.foobar.name}" +}`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), + acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), + acctest.RandString(10), acctest.RandString(10), acctest.RandString(10)) diff --git a/resource_compute_router_peer.go b/resource_compute_router_peer.go new file mode 100644 index 00000000..2585f31b --- /dev/null +++ b/resource_compute_router_peer.go @@ -0,0 +1,290 @@ +package google + +import ( + "fmt" + "log" + + "strings" + + "github.com/hashicorp/terraform/helper/schema" + "google.golang.org/api/compute/v1" + "google.golang.org/api/googleapi" +) + +func resourceComputeRouterPeer() *schema.Resource { + return &schema.Resource{ + Create: resourceComputeRouterPeerCreate, + Read: resourceComputeRouterPeerRead, + Delete: resourceComputeRouterPeerDelete, + Importer: &schema.ResourceImporter{ + State: resourceComputeRouterPeerImportState, + }, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "router": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "interface": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "ip_address": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "asn": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + + "project": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "region": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + } +} + +func resourceComputeRouterPeerCreate(d *schema.ResourceData, meta interface{}) error { + + config := meta.(*Config) + + region, err := getRegion(d, config) + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + + routerName := d.Get("router").(string) + peerName := d.Get("name").(string) + + routerId := fmt.Sprintf("router/%s/%s", region, routerName) + mutexKV.Lock(routerId) + defer mutexKV.Unlock(routerId) + + routersService := compute.NewRoutersService(config.clientCompute) + router, err := routersService.Get(project, region, routerName).Do() + if err != nil { + if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { + log.Printf("[WARN] Removing router peer because its router %s/%s is gone", region, routerName) + d.SetId("") + + return nil + } + + return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err) + } + + var peerExists bool = false + + var peers []*compute.RouterBgpPeer = router.BgpPeers + for _, peer := range peers { + + if peer.Name == peerName { + peerExists = true + break + } + } + + if !peerExists { + + ifaceName := d.Get("interface").(string) + + peer := &compute.RouterBgpPeer{Name: peerName, + InterfaceName: ifaceName} + + if v, ok := d.GetOk("ip_address"); ok { + peer.PeerIpAddress = v.(string) + } + + if v, ok := d.GetOk("asn"); ok { + peer.PeerAsn = int64(v.(int)) + } + + log.Printf( + "[INFO] Adding peer %s", peerName) + peers = append(peers, peer) + patchRouter := &compute.Router{ + BgpPeers: peers, + } + + log.Printf("[DEBUG] Updating router %s/%s with peers: %+v", region, routerName, peers) + op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() + if err != nil { + return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) + } + + err = computeOperationWaitRegion(config, op, project, region, "Patching router") + if err != nil { + return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) + } + + d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, peerName)) + + } else { + log.Printf("[DEBUG] Router %s has peer %s already", routerName, peerName) + } + + return resourceComputeRouterPeerRead(d, meta) +} + +func resourceComputeRouterPeerRead(d *schema.ResourceData, meta interface{}) error { + + config := meta.(*Config) + + region, err := getRegion(d, config) + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + + routerName := d.Get("router").(string) + peerName := d.Get("name").(string) + + routersService := compute.NewRoutersService(config.clientCompute) + router, err := routersService.Get(project, region, routerName).Do() + if err != nil { + if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { + log.Printf("[WARN] Removing router peer because its router %s/%s is gone", region, routerName) + d.SetId("") + + return nil + } + + return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err) + } + + var peerFound bool = false + + var peers []*compute.RouterBgpPeer = router.BgpPeers + for _, peer := range peers { + + if peer.Name == peerName { + peerFound = true + d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, peerName)) + d.Set("interface", peer.InterfaceName) + d.Set("ip_address", peer.PeerIpAddress) + d.Set("asn", peer.PeerAsn) + } + } + if !peerFound { + log.Printf("[WARN] Removing router peer %s/%s/%s because it is gone", region, routerName, peerName) + d.SetId("") + } + + return nil +} + +func resourceComputeRouterPeerDelete(d *schema.ResourceData, meta interface{}) error { + + config := meta.(*Config) + + region, err := getRegion(d, config) + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + + routerName := d.Get("router").(string) + peerName := d.Get("name").(string) + + routerId := fmt.Sprintf("router/%s/%s", region, routerName) + mutexKV.Lock(routerId) + defer mutexKV.Unlock(routerId) + + routersService := compute.NewRoutersService(config.clientCompute) + router, err := routersService.Get(project, region, routerName).Do() + if err != nil { + if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { + log.Printf("[WARN] Removing router peer because its router %d is gone", d.Get("router").(string)) + + return nil + } + + return fmt.Errorf("Error Reading Router %s: %s", routerName, err) + } + + var peerFound bool = false + + var oldIfaces []*compute.RouterBgpPeer = router.BgpPeers + var newIfaces []*compute.RouterBgpPeer = make([]*compute.RouterBgpPeer, len(router.BgpPeers)) + for _, peer := range oldIfaces { + + if peer.Name == peerName { + peerFound = true + continue + } else { + newIfaces = append(newIfaces, peer) + } + } + + if peerFound { + + log.Printf( + "[INFO] Removing peer %s", peerName) + patchRouter := &compute.Router{ + BgpPeers: newIfaces, + } + + log.Printf("[DEBUG] Updating router %s/%s with peers: %+v", region, routerName, newIfaces) + op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() + if err != nil { + return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) + } + + err = computeOperationWaitRegion(config, op, project, region, "Patching router") + if err != nil { + return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) + } + + } else { + log.Printf("[DEBUG] Router %s/%s had no peer %s already", region, routerName, peerName) + } + + return nil +} + +func resourceComputeRouterPeerImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + parts := strings.Split(d.Id(), "/") + if len(parts) != 3 { + return nil, fmt.Errorf("Invalid router specifier. Expecting {region}/{router}") + } + + d.Set("region", parts[0]) + d.Set("router", parts[1]) + d.Set("name", parts[2]) + + return []*schema.ResourceData{d}, nil +} diff --git a/resource_compute_router_peer_test.go b/resource_compute_router_peer_test.go new file mode 100644 index 00000000..1afaa6f6 --- /dev/null +++ b/resource_compute_router_peer_test.go @@ -0,0 +1,263 @@ +package google + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + + "google.golang.org/api/compute/v1" +) + +func TestAccComputeRouterPeer_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeRouterPeer_basic, + Check: testAccCheckComputeRouterPeerExists( + "google_compute_router_peer.foobar"), + }, + resource.TestStep{ + Config: testAccComputeRouterPeer_keepRouter, + Check: testAccCheckComputeRouterPeerDestroy( + "google_compute_router_peer.foobar"), + }, + }, + }) +} + +func testAccCheckComputeRouterPeerDestroy(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + project := config.Project + + routersService := compute.NewRoutersService(config.clientCompute) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "google_compute_router_peer" { + continue + } + + region := rs.Primary.Attributes["region"] + name := rs.Primary.Attributes["name"] + routerName := rs.Primary.Attributes["router"] + + router, err := routersService.Get(project, region, routerName).Do() + + if err != nil { + return fmt.Errorf("Error Reading Router %s: %s", routerName, err) + } + + var peerExists bool = false + + var peers []*compute.RouterBgpPeer = router.BgpPeers + for _, peer := range peers { + + if peer.Name == name { + peerExists = true + break + } + } + + if peerExists { + return fmt.Errorf("Peer %s still exists on router %s", name, router.Name) + } + + } + + return nil + } +} + +func testAccCheckComputeRouterPeerExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + name := rs.Primary.Attributes["name"] + routerName := rs.Primary.Attributes["router"] + region := rs.Primary.Attributes["region"] + project := config.Project + + routersService := compute.NewRoutersService(config.clientCompute) + router, err := routersService.Get(project, region, routerName).Do() + + if err != nil { + return fmt.Errorf("Error Reading Router %s: %s", routerName, err) + } + + var peerExists bool = false + + var peers []*compute.RouterBgpPeer = router.BgpPeers + for _, peer := range peers { + + if peer.Name == name { + peerExists = true + break + } + } + + if !peerExists { + return fmt.Errorf("Peer %s not found for router %s", name, router.Name) + } + + return nil + } +} + +var testAccComputeRouterPeer_basic = fmt.Sprintf(` +resource "google_compute_network" "foobar" { + name = "peer-test-%s" +} +resource "google_compute_subnetwork" "foobar" { + name = "peer-test-%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" +} +resource "google_compute_address" "foobar" { + name = "peer-test-%s" + region = "${google_compute_subnetwork.foobar.region}" +} +resource "google_compute_vpn_gateway" "foobar" { + name = "peer-test-%s" + network = "${google_compute_network.foobar.self_link}" + region = "${google_compute_subnetwork.foobar.region}" +} +resource "google_compute_forwarding_rule" "foobar_esp" { + name = "peer-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 = "peer-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 = "peer-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_router" "foobar"{ + name = "peer-test-%s" + region = "${google_compute_forwarding_rule.foobar_udp500.region}" + network = "${google_compute_network.foobar.self_link}" + bgp { + asn = 64514 + } +} +resource "google_compute_vpn_tunnel" "foobar" { + name = "peer-test-%s" + region = "${google_compute_forwarding_rule.foobar_udp4500.region}" + target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" + shared_secret = "unguessable" + peer_ip = "8.8.8.8" + router = "${google_compute_router.foobar.name}" +} +resource "google_compute_router_interface" "foobar" { + name = "peer-test-%s" + router = "${google_compute_router.foobar.name}" + region = "${google_compute_router.foobar.region}" + ip_range = "169.254.3.1/30" + vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}" +} +resource "google_compute_router_peer" "foobar" { + name = "peer-test-%s" + router = "${google_compute_router.foobar.name}" + region = "${google_compute_router.foobar.region}" + ip_address = "169.254.3.2" + asn = 65515 + interface = "${google_compute_router_interface.foobar.name}" +}`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), + acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), + acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), + acctest.RandString(10), acctest.RandString(10)) + +var testAccComputeRouterPeer_keepRouter = fmt.Sprintf(` +resource "google_compute_network" "foobar" { + name = "peer-test-%s" +} +resource "google_compute_subnetwork" "foobar" { + name = "peer-test-%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" +} +resource "google_compute_address" "foobar" { + name = "peer-test-%s" + region = "${google_compute_subnetwork.foobar.region}" +} +resource "google_compute_vpn_gateway" "foobar" { + name = "peer-test-%s" + network = "${google_compute_network.foobar.self_link}" + region = "${google_compute_subnetwork.foobar.region}" +} +resource "google_compute_forwarding_rule" "foobar_esp" { + name = "peer-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 = "peer-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 = "peer-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_router" "foobar"{ + name = "peer-test-%s" + region = "${google_compute_forwarding_rule.foobar_udp500.region}" + network = "${google_compute_network.foobar.self_link}" + bgp { + asn = 64514 + } +} +resource "google_compute_vpn_tunnel" "foobar" { + name = "peer-test-%s" + region = "${google_compute_forwarding_rule.foobar_udp4500.region}" + target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" + shared_secret = "unguessable" + peer_ip = "8.8.8.8" + router = "${google_compute_router.foobar.name}" +} +resource "google_compute_router_interface" "foobar" { + name = "peer-test-%s" + router = "${google_compute_router.foobar.name}" + region = "${google_compute_router.foobar.region}" + ip_range = "169.254.3.1/30" + vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}" +}`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), + acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), + acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), + acctest.RandString(10)) diff --git a/resource_compute_router_test.go b/resource_compute_router_test.go new file mode 100644 index 00000000..cb22468d --- /dev/null +++ b/resource_compute_router_test.go @@ -0,0 +1,176 @@ +package google + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + + "google.golang.org/api/compute/v1" +) + +func TestAccComputeRouter_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeRouterDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeRouter_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeRouterExists( + "google_compute_router.foobar"), + resource.TestCheckResourceAttr( + "google_compute_router.foobar", "region", "europe-west1"), + ), + }, + }, + }) +} + +func TestAccComputeRouter_noRegion(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeRouterDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeRouter_noRegion, + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeRouterExists( + "google_compute_router.foobar"), + resource.TestCheckResourceAttr( + "google_compute_router.foobar", "region", "us-central1"), + ), + }, + }, + }) +} + +func TestAccComputeRouter_networkLink(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeRouterDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeRouter_networkLink, + Check: testAccCheckComputeRouterExists( + "google_compute_router.foobar"), + }, + }, + }) +} + +func testAccCheckComputeRouterDestroy(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + project := config.Project + + routersService := compute.NewRoutersService(config.clientCompute) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "google_compute_router" { + continue + } + + region := rs.Primary.Attributes["region"] + name := rs.Primary.Attributes["name"] + + _, err := routersService.Get(project, region, name).Do() + + if err == nil { + return fmt.Errorf("Error, Router %s in region %s still exists", + name, region) + } + } + + return nil +} + +func testAccCheckComputeRouterExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + name := rs.Primary.Attributes["name"] + region := rs.Primary.Attributes["region"] + project := config.Project + + routersService := compute.NewRoutersService(config.clientCompute) + _, err := routersService.Get(project, region, name).Do() + + if err != nil { + return fmt.Errorf("Error Reading Router %s: %s", name, err) + } + + return nil + } +} + +var testAccComputeRouter_basic = fmt.Sprintf(` +resource "google_compute_network" "foobar" { + name = "router-test-%s" +} +resource "google_compute_subnetwork" "foobar" { + name = "router-test-%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "europe-west1" +} +resource "google_compute_router" "foobar" { + name = "router-test-%s" + region = "${google_compute_subnetwork.foobar.region}" + network = "${google_compute_network.foobar.name}" + bgp { + asn = 64514 + } +} +`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10)) + +var testAccComputeRouter_noRegion = fmt.Sprintf(` +resource "google_compute_network" "foobar" { + name = "router-test-%s" +} +resource "google_compute_subnetwork" "foobar" { + name = "router-test-%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" +} +resource "google_compute_router" "foobar" { + name = "router-test-%s" + network = "${google_compute_network.foobar.name}" + bgp { + asn = 64514 + } +} +`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10)) + +var testAccComputeRouter_networkLink = fmt.Sprintf(` +resource "google_compute_network" "foobar" { + name = "router-test-%s" +} +resource "google_compute_subnetwork" "foobar" { + name = "router-test-%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" +} +resource "google_compute_router" "foobar" { + name = "router-test-%s" + region = "${google_compute_subnetwork.foobar.region}" + network = "${google_compute_network.foobar.self_link}" + bgp { + asn = 64514 + } +} +`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10)) diff --git a/resource_compute_vpn_tunnel.go b/resource_compute_vpn_tunnel.go index 42f477d9..68e5235b 100644 --- a/resource_compute_vpn_tunnel.go +++ b/resource_compute_vpn_tunnel.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "net" + "strings" "github.com/hashicorp/terraform/helper/schema" @@ -77,6 +78,7 @@ func resourceComputeVpnTunnel() *schema.Resource { Type: schema.TypeSet, Optional: true, ForceNew: true, + Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, @@ -93,6 +95,12 @@ func resourceComputeVpnTunnel() *schema.Resource { ForceNew: true, }, + "router": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "self_link": &schema.Schema{ Type: schema.TypeString, Computed: true, @@ -157,6 +165,14 @@ func resourceComputeVpnTunnelCreate(d *schema.ResourceData, meta interface{}) er vpnTunnel.Description = v.(string) } + if v, ok := d.GetOk("router"); ok { + routerLink, err := getRouterLink(config, project, region, v.(string)) + if err != nil { + return err + } + vpnTunnel.Router = routerLink + } + op, err := vpnTunnelsService.Insert(project, region, vpnTunnel).Do() if err != nil { return fmt.Errorf("Error Inserting VPN Tunnel %s : %s", name, err) @@ -335,3 +351,33 @@ var invalidPeerAddrs = []struct { to: net.ParseIP("255.255.255.255"), }, } + +func getVpnTunnelLink(config *Config, project string, region string, tunnel string) (string, error) { + + if !strings.HasPrefix(tunnel, "https://www.googleapis.com/compute/") { + // Tunnel value provided is just the name, lookup the tunnel SelfLink + tunnelData, err := config.clientCompute.VpnTunnels.Get( + project, region, tunnel).Do() + if err != nil { + return "", fmt.Errorf("Error reading tunnel: %s", err) + } + tunnel = tunnelData.SelfLink + } + + return tunnel, nil + +} + +func getVpnTunnelName(vpntunnel string) (string, error) { + + if strings.HasPrefix(vpntunnel, "https://www.googleapis.com/compute/") { + // extract the VPN tunnel name from SelfLink URL + vpntunnelName := vpntunnel[strings.LastIndex(vpntunnel, "/")+1:] + if vpntunnelName == "" { + return "", fmt.Errorf("VPN tunnel url not valid") + } + return vpntunnelName, nil + } + + return vpntunnel, nil +} diff --git a/resource_compute_vpn_tunnel_test.go b/resource_compute_vpn_tunnel_test.go index dfd153e4..d8da36e2 100644 --- a/resource_compute_vpn_tunnel_test.go +++ b/resource_compute_vpn_tunnel_test.go @@ -32,6 +32,25 @@ func TestAccComputeVpnTunnel_basic(t *testing.T) { }) } +func TestAccComputeVpnTunnel_router(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeVpnTunnelDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeVpnTunnel_router, + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeVpnTunnelExists( + "google_compute_vpn_tunnel.foobar"), + resource.TestCheckResourceAttr( + "google_compute_vpn_tunnel.foobar", "router", "tunnel-test-router"), + ), + }, + }, + }) +} + func TestAccComputeVpnTunnel_defaultTrafficSelectors(t *testing.T) { resource.Test(t, resource.TestCase{ @@ -154,6 +173,67 @@ resource "google_compute_vpn_tunnel" "foobar" { acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), acctest.RandString(10)) +var testAccComputeVpnTunnel_router = fmt.Sprintf(` +resource "google_compute_network" "foobar" { + name = "tunnel-test-%s" +} +resource "google_compute_subnetwork" "foobar" { + name = "tunnel-test-%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" +} +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_router" "foobar"{ + name = "tunnel-test-router" + region = "${google_compute_forwarding_rule.foobar_udp500.region}" + network = "${google_compute_network.foobar.self_link}" + bgp { + asn = 64514 + } +} +resource "google_compute_vpn_tunnel" "foobar" { + name = "tunnel-test-%s" + region = "${google_compute_forwarding_rule.foobar_udp4500.region}" + target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" + shared_secret = "unguessable" + peer_ip = "8.8.8.8" + router = "${google_compute_router.foobar.name}" +}`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), + acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), + acctest.RandString(10), acctest.RandString(10)) + var testAccComputeVpnTunnelDefaultTrafficSelectors = fmt.Sprintf(` resource "google_compute_network" "foobar" { name = "tunnel-test-%s" From 4aa863b26b136a04f9c6a7f9d526848e6fc31b89 Mon Sep 17 00:00:00 2001 From: Roberto Jung Drebes Date: Fri, 28 Apr 2017 21:17:08 +0200 Subject: [PATCH 2/3] wip: review changes: - config.clientCompute.Routers - peer fields renamed - more consistent logging - better handling of SetId for error handling - function for router locks - test configs as functions - simplify exists logic - use getProject, getRegion logic on acceptance tests - CheckDestroy for peers an interfaces - dynamic router name for tunnel test - extra fields for BgpPeer - resource documentation --- import_compute_router_interface_test.go | 16 +- import_compute_router_peer_test.go | 17 +- import_compute_router_test.go | 8 +- provider.go | 4 + provider_test.go | 23 ++ resource_compute_router.go | 26 +- resource_compute_router_interface.go | 150 ++++---- resource_compute_router_interface_test.go | 368 +++++++++++--------- resource_compute_router_peer.go | 175 +++++----- resource_compute_router_peer_test.go | 401 ++++++++++++---------- resource_compute_router_test.go | 164 +++++---- resource_compute_vpn_tunnel_test.go | 133 +++---- 12 files changed, 832 insertions(+), 653 deletions(-) diff --git a/import_compute_router_interface_test.go b/import_compute_router_interface_test.go index 7a5f348f..91be45fc 100644 --- a/import_compute_router_interface_test.go +++ b/import_compute_router_interface_test.go @@ -1,20 +1,32 @@ package google import ( + "fmt" "testing" + "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" ) func TestAccComputeRouterInterface_import(t *testing.T) { resourceName := "google_compute_router_interface.foobar" - + network := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) + subnet := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) + address := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) + gateway := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) + espRule := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) + udp500Rule := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) + udp4500Rule := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) + router := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) + tunnel := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) + iface := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouterInterface_basic, + Config: testAccComputeRouterInterfaceBasic(network, subnet, address, gateway, espRule, udp500Rule, + udp4500Rule, router, tunnel, iface), }, resource.TestStep{ diff --git a/import_compute_router_peer_test.go b/import_compute_router_peer_test.go index f17d7d55..fc37e1bc 100644 --- a/import_compute_router_peer_test.go +++ b/import_compute_router_peer_test.go @@ -1,20 +1,33 @@ package google import ( + "fmt" "testing" + "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" ) func TestAccComputeRouterPeer_import(t *testing.T) { resourceName := "google_compute_router_peer.foobar" - + network := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) + subnet := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) + address := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) + gateway := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) + espRule := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) + udp500Rule := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) + udp4500Rule := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) + router := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) + tunnel := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) + iface := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) + peer := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouterPeer_basic, + Config: testAccComputeRouterPeerBasic(network, subnet, address, gateway, espRule, udp500Rule, + udp4500Rule, router, tunnel, iface, peer), }, resource.TestStep{ diff --git a/import_compute_router_test.go b/import_compute_router_test.go index 9e81798e..97b91dd6 100644 --- a/import_compute_router_test.go +++ b/import_compute_router_test.go @@ -1,21 +1,25 @@ package google import ( + "fmt" "testing" + "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" ) func TestAccComputeRouter_import(t *testing.T) { resourceName := "google_compute_router.foobar" - + network := fmt.Sprintf("router-import-test-%s", acctest.RandString(10)) + subnet := fmt.Sprintf("router-import-test-%s", acctest.RandString(10)) + router := fmt.Sprintf("router-import-test-%s", acctest.RandString(10)) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckComputeRouterDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouter_networkLink, + Config: testAccComputeRouterNetworkLink(network, subnet, router), }, resource.TestStep{ diff --git a/provider.go b/provider.go index 1486d369..c64c0866 100644 --- a/provider.go +++ b/provider.go @@ -256,3 +256,7 @@ func getNetworkNameFromSelfLink(network string) (string, error) { return network, nil } + +func getRouterLockName(region string, router string) string { + return fmt.Sprintf("router/%s/%s", region, router) +} diff --git a/provider_test.go b/provider_test.go index b6f6859e..b69ee814 100644 --- a/provider_test.go +++ b/provider_test.go @@ -1,6 +1,7 @@ package google import ( + "fmt" "io/ioutil" "os" "strings" @@ -87,3 +88,25 @@ func TestProvider_getRegionFromZone(t *testing.T) { t.Fatalf("Region (%s) did not match expected value: %s", actual, expected) } } + +// getTestRegion has the same logic as the provider's getRegion, to be used in tests. +func getTestRegion(is *terraform.InstanceState, config *Config) (string, error) { + if res, ok := is.Attributes["region"]; ok { + return res, nil + } + if config.Region != "" { + return config.Region, nil + } + return "", fmt.Errorf("%q: required field is not set", "region") +} + +// getTestProject has the same logic as the provider's getProject, to be used in tests. +func getTestProject(is *terraform.InstanceState, config *Config) (string, error) { + if res, ok := is.Attributes["project"]; ok { + return res, nil + } + if config.Project != "" { + return config.Project, nil + } + return "", fmt.Errorf("%q: required field is not set", "project") +} diff --git a/resource_compute_router.go b/resource_compute_router.go index e02c5602..992b3797 100644 --- a/resource_compute_router.go +++ b/resource_compute_router.go @@ -93,15 +93,15 @@ func resourceComputeRouterCreate(d *schema.ResourceData, meta interface{}) error name := d.Get("name").(string) - routerId := fmt.Sprintf("router/%s/%s", region, name) - mutexKV.Lock(routerId) - defer mutexKV.Unlock(routerId) + routerLock := getRouterLockName(region, name) + mutexKV.Lock(routerLock) + defer mutexKV.Unlock(routerLock) network, err := getNetworkLink(d, config, "network") if err != nil { return err } - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers router := &compute.Router{ Name: name, @@ -127,9 +127,10 @@ func resourceComputeRouterCreate(d *schema.ResourceData, meta interface{}) error if err != nil { return fmt.Errorf("Error Inserting Router %s into network %s: %s", name, network, err) } - + d.SetId(fmt.Sprintf("%s/%s", region, name)) err = computeOperationWaitRegion(config, op, project, region, "Inserting Router") if err != nil { + d.SetId("") return fmt.Errorf("Error Waiting to Insert Router %s into network %s: %s", name, network, err) } @@ -151,12 +152,12 @@ func resourceComputeRouterRead(d *schema.ResourceData, meta interface{}) error { } name := d.Get("name").(string) - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers router, err := routersService.Get(project, region, name).Do() if err != nil { if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { - log.Printf("[WARN] Removing Router %q because it's gone", d.Get("name").(string)) + log.Printf("[WARN] Removing router %s/%s because it is gone", region, name) d.SetId("") return nil @@ -172,6 +173,8 @@ func resourceComputeRouterRead(d *schema.ResourceData, meta interface{}) error { d.Set("network", router.Network) } + d.Set("name", router.Name) + d.Set("description", router.Description) d.Set("region", region) d.Set("bgp", flattenAsn(router.Bgp.Asn)) d.SetId(fmt.Sprintf("%s/%s", region, name)) @@ -195,11 +198,11 @@ func resourceComputeRouterDelete(d *schema.ResourceData, meta interface{}) error name := d.Get("name").(string) - routerId := fmt.Sprintf("router/%s/%s", region, name) - mutexKV.Lock(routerId) - defer mutexKV.Unlock(routerId) + routerLock := getRouterLockName(region, name) + mutexKV.Lock(routerLock) + defer mutexKV.Unlock(routerLock) - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers op, err := routersService.Delete(project, region, name).Do() if err != nil { @@ -211,6 +214,7 @@ func resourceComputeRouterDelete(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error Waiting to Delete Router %s: %s", name, err) } + d.SetId("") return nil } diff --git a/resource_compute_router_interface.go b/resource_compute_router_interface.go index 56910207..2851cfb7 100644 --- a/resource_compute_router_interface.go +++ b/resource_compute_router_interface.go @@ -75,15 +75,15 @@ func resourceComputeRouterInterfaceCreate(d *schema.ResourceData, meta interface routerName := d.Get("router").(string) ifaceName := d.Get("name").(string) - routerId := fmt.Sprintf("router/%s/%s", region, routerName) - mutexKV.Lock(routerId) - defer mutexKV.Unlock(routerId) + routerLock := getRouterLockName(region, routerName) + mutexKV.Lock(routerLock) + defer mutexKV.Unlock(routerLock) - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers router, err := routersService.Get(project, region, routerName).Do() if err != nil { if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { - log.Printf("[WARN] Removing router interface because its router %s/%s is gone", region, routerName) + log.Printf("[WARN] Removing router interface %s because its router %s/%s is gone", ifaceName, region, routerName) d.SetId("") return nil @@ -92,53 +92,42 @@ func resourceComputeRouterInterfaceCreate(d *schema.ResourceData, meta interface return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err) } - var ifaceExists bool = false - - var ifaces []*compute.RouterInterface = router.Interfaces + ifaces := router.Interfaces for _, iface := range ifaces { - if iface.Name == ifaceName { - ifaceExists = true - break + d.SetId("") + return fmt.Errorf("Router %s has interface %s already", routerName, ifaceName) } } - if !ifaceExists { + vpnTunnel, err := getVpnTunnelLink(config, project, region, d.Get("vpn_tunnel").(string)) + if err != nil { + return err + } - vpnTunnel, err := getVpnTunnelLink(config, project, region, d.Get("vpn_tunnel").(string)) - if err != nil { - return err - } + iface := &compute.RouterInterface{Name: ifaceName, + LinkedVpnTunnel: vpnTunnel} - iface := &compute.RouterInterface{Name: ifaceName, - LinkedVpnTunnel: vpnTunnel} + if v, ok := d.GetOk("ip_range"); ok { + iface.IpRange = v.(string) + } - if v, ok := d.GetOk("ip_range"); ok { - iface.IpRange = v.(string) - } + log.Printf("[INFO] Adding interface %s", ifaceName) + ifaces = append(ifaces, iface) + patchRouter := &compute.Router{ + Interfaces: ifaces, + } - log.Printf( - "[INFO] Adding interface %s", ifaceName) - ifaces = append(ifaces, iface) - patchRouter := &compute.Router{ - Interfaces: ifaces, - } - - log.Printf("[DEBUG] Updating router %s/%s with interfaces: %+v", region, routerName, ifaces) - op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() - if err != nil { - return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) - } - - err = computeOperationWaitRegion(config, op, project, region, "Patching router") - if err != nil { - return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) - } - - d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, ifaceName)) - - } else { - log.Printf("[DEBUG] Router %s has interface %s already", routerName, ifaceName) + log.Printf("[DEBUG] Updating router %s/%s with interfaces: %+v", region, routerName, ifaces) + op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() + if err != nil { + return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) + } + d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, ifaceName)) + err = computeOperationWaitRegion(config, op, project, region, "Patching router") + if err != nil { + d.SetId("") + return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) } return resourceComputeRouterInterfaceRead(d, meta) @@ -161,11 +150,11 @@ func resourceComputeRouterInterfaceRead(d *schema.ResourceData, meta interface{} routerName := d.Get("router").(string) ifaceName := d.Get("name").(string) - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers router, err := routersService.Get(project, region, routerName).Do() if err != nil { if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { - log.Printf("[WARN] Removing router interface because its router %s/%s is gone", region, routerName) + log.Printf("[WARN] Removing router interface %s because its router %s/%s is gone", ifaceName, region, routerName) d.SetId("") return nil @@ -174,13 +163,9 @@ func resourceComputeRouterInterfaceRead(d *schema.ResourceData, meta interface{} return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err) } - var ifaceFound bool = false - - var ifaces []*compute.RouterInterface = router.Interfaces - for _, iface := range ifaces { + for _, iface := range router.Interfaces { if iface.Name == ifaceName { - ifaceFound = true d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, ifaceName)) // if we don't have a tunnel (when importing), set it to the URI returned from the server if _, ok := d.GetOk("vpn_tunnel"); !ok { @@ -191,13 +176,12 @@ func resourceComputeRouterInterfaceRead(d *schema.ResourceData, meta interface{} d.Set("vpn_tunnel", vpnTunnelName) } d.Set("ip_range", iface.IpRange) + return nil } } - if !ifaceFound { - log.Printf("[WARN] Removing router interface %s/%s/%s because it is gone", region, routerName, ifaceName) - d.SetId("") - } + log.Printf("[WARN] Removing router interface %s/%s/%s because it is gone", region, routerName, ifaceName) + d.SetId("") return nil } @@ -218,15 +202,15 @@ func resourceComputeRouterInterfaceDelete(d *schema.ResourceData, meta interface routerName := d.Get("router").(string) ifaceName := d.Get("name").(string) - routerId := fmt.Sprintf("router/%s/%s", region, routerName) - mutexKV.Lock(routerId) - defer mutexKV.Unlock(routerId) + routerLock := getRouterLockName(region, routerName) + mutexKV.Lock(routerLock) + defer mutexKV.Unlock(routerLock) - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers router, err := routersService.Get(project, region, routerName).Do() if err != nil { if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { - log.Printf("[WARN] Removing router interface because its router %d is gone", d.Get("router").(string)) + log.Printf("[WARN] Removing router interface %s because its router %s/%s is gone", ifaceName, region, routerName) return nil } @@ -234,11 +218,10 @@ func resourceComputeRouterInterfaceDelete(d *schema.ResourceData, meta interface return fmt.Errorf("Error Reading Router %s: %s", routerName, err) } - var ifaceFound bool = false + var ifaceFound bool - var oldIfaces []*compute.RouterInterface = router.Interfaces - var newIfaces []*compute.RouterInterface = make([]*compute.RouterInterface, len(router.Interfaces)) - for _, iface := range oldIfaces { + newIfaces := make([]*compute.RouterInterface, 0, len(router.Interfaces)) + for _, iface := range router.Interfaces { if iface.Name == ifaceName { ifaceFound = true @@ -248,29 +231,30 @@ func resourceComputeRouterInterfaceDelete(d *schema.ResourceData, meta interface } } - if ifaceFound { - - log.Printf( - "[INFO] Removing interface %s", ifaceName) - patchRouter := &compute.Router{ - Interfaces: newIfaces, - } - - log.Printf("[DEBUG] Updating router %s/%s with interfaces: %+v", region, routerName, newIfaces) - op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() - if err != nil { - return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) - } - - err = computeOperationWaitRegion(config, op, project, region, "Patching router") - if err != nil { - return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) - } - - } else { + if !ifaceFound { log.Printf("[DEBUG] Router %s/%s had no interface %s already", region, routerName, ifaceName) + d.SetId("") + return nil } + log.Printf( + "[INFO] Removing interface %s from router %s/%s", ifaceName, region, routerName) + patchRouter := &compute.Router{ + Interfaces: newIfaces, + } + + log.Printf("[DEBUG] Updating router %s/%s with interfaces: %+v", region, routerName, newIfaces) + op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() + if err != nil { + return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) + } + + err = computeOperationWaitRegion(config, op, project, region, "Patching router") + if err != nil { + return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) + } + + d.SetId("") return nil } diff --git a/resource_compute_router_interface_test.go b/resource_compute_router_interface_test.go index ebd81ccf..82e3378a 100644 --- a/resource_compute_router_interface_test.go +++ b/resource_compute_router_interface_test.go @@ -7,42 +7,94 @@ import ( "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - - "google.golang.org/api/compute/v1" ) func TestAccComputeRouterInterface_basic(t *testing.T) { + network := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + subnet := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + address := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + gateway := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + espRule := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + udp500Rule := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + udp4500Rule := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + router := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + tunnel := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + iface := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeRouterInterfaceDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouterInterface_basic, + Config: testAccComputeRouterInterfaceBasic(network, subnet, address, gateway, espRule, udp500Rule, + udp4500Rule, router, tunnel, iface), Check: testAccCheckComputeRouterInterfaceExists( "google_compute_router_interface.foobar"), }, resource.TestStep{ - Config: testAccComputeRouterInterface_keepRouter, - Check: testAccCheckComputeRouterInterfaceDestroy( + Config: testAccComputeRouterInterfaceKeepRouter(network, subnet, address, gateway, espRule, udp500Rule, + udp4500Rule, router, tunnel), + Check: testAccCheckComputeRouterInterfaceDelete( "google_compute_router_interface.foobar"), }, }, }) } -func testAccCheckComputeRouterInterfaceDestroy(n string) resource.TestCheckFunc { +func testAccCheckComputeRouterInterfaceDestroy(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + + routersService := config.clientCompute.Routers + + for _, rs := range s.RootModule().Resources { + if rs.Type != "google_compute_router" { + continue + } + + project, err := getTestProject(rs.Primary, config) + if err != nil { + return err + } + + region, err := getTestRegion(rs.Primary, config) + if err != nil { + return err + } + + routerName := rs.Primary.Attributes["router"] + + _, err = routersService.Get(project, region, routerName).Do() + + if err == nil { + return fmt.Errorf("Error, Router %s in region %s still exists", + routerName, region) + } + } + + return nil +} + +func testAccCheckComputeRouterInterfaceDelete(n string) resource.TestCheckFunc { return func(s *terraform.State) error { config := testAccProvider.Meta().(*Config) - project := config.Project - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers for _, rs := range s.RootModule().Resources { if rs.Type != "google_compute_router_interface" { continue } - region := rs.Primary.Attributes["region"] + project, err := getTestProject(rs.Primary, config) + if err != nil { + return err + } + + region, err := getTestRegion(rs.Primary, config) + if err != nil { + return err + } + name := rs.Primary.Attributes["name"] routerName := rs.Primary.Attributes["router"] @@ -52,21 +104,13 @@ func testAccCheckComputeRouterInterfaceDestroy(n string) resource.TestCheckFunc return fmt.Errorf("Error Reading Router %s: %s", routerName, err) } - var ifaceExists bool = false - - var ifaces []*compute.RouterInterface = router.Interfaces + ifaces := router.Interfaces for _, iface := range ifaces { if iface.Name == name { - ifaceExists = true - break + return fmt.Errorf("Interface %s still exists on router %s/%s", name, region, router.Name) } } - - if ifaceExists { - return fmt.Errorf("Interface %s still exists on router %s", name, router.Name) - } - } return nil @@ -85,163 +129,165 @@ func testAccCheckComputeRouterInterfaceExists(n string) resource.TestCheckFunc { } config := testAccProvider.Meta().(*Config) + + project, err := getTestProject(rs.Primary, config) + if err != nil { + return err + } + + region, err := getTestRegion(rs.Primary, config) + if err != nil { + return err + } + name := rs.Primary.Attributes["name"] routerName := rs.Primary.Attributes["router"] - region := rs.Primary.Attributes["region"] - project := config.Project - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers router, err := routersService.Get(project, region, routerName).Do() if err != nil { return fmt.Errorf("Error Reading Router %s: %s", routerName, err) } - var ifaceExists bool = false - - var ifaces []*compute.RouterInterface = router.Interfaces - for _, iface := range ifaces { + for _, iface := range router.Interfaces { if iface.Name == name { - ifaceExists = true - break + return nil } } - if !ifaceExists { - return fmt.Errorf("Interface %s not found for router %s", name, router.Name) - } - - return nil + return fmt.Errorf("Interface %s not found for router %s", name, router.Name) } } -var testAccComputeRouterInterface_basic = fmt.Sprintf(` -resource "google_compute_network" "foobar" { - name = "interface-test-%s" +func testAccComputeRouterInterfaceBasic(network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel, iface string) string { + return fmt.Sprintf(` + resource "google_compute_network" "foobar" { + name = "%s" + } + resource "google_compute_subnetwork" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" + } + resource "google_compute_address" "foobar" { + name = "%s" + region = "${google_compute_subnetwork.foobar.region}" + } + resource "google_compute_vpn_gateway" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.self_link}" + region = "${google_compute_subnetwork.foobar.region}" + } + resource "google_compute_forwarding_rule" "foobar_esp" { + name = "%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 = "%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 = "%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_router" "foobar"{ + name = "%s" + region = "${google_compute_forwarding_rule.foobar_udp500.region}" + network = "${google_compute_network.foobar.self_link}" + bgp { + asn = 64514 + } + } + resource "google_compute_vpn_tunnel" "foobar" { + name = "%s" + region = "${google_compute_forwarding_rule.foobar_udp4500.region}" + target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" + shared_secret = "unguessable" + peer_ip = "8.8.8.8" + router = "${google_compute_router.foobar.name}" + } + resource "google_compute_router_interface" "foobar" { + name = "%s" + router = "${google_compute_router.foobar.name}" + region = "${google_compute_router.foobar.region}" + ip_range = "169.254.3.1/30" + vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}" + } + `, network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel, iface) } -resource "google_compute_subnetwork" "foobar" { - name = "interface-test-%s" - network = "${google_compute_network.foobar.self_link}" - ip_cidr_range = "10.0.0.0/16" - region = "us-central1" -} -resource "google_compute_address" "foobar" { - name = "interface-test-%s" - region = "${google_compute_subnetwork.foobar.region}" -} -resource "google_compute_vpn_gateway" "foobar" { - name = "interface-test-%s" - network = "${google_compute_network.foobar.self_link}" - region = "${google_compute_subnetwork.foobar.region}" -} -resource "google_compute_forwarding_rule" "foobar_esp" { - name = "interface-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 = "interface-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 = "interface-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_router" "foobar"{ - name = "interface-test-%s" - region = "${google_compute_forwarding_rule.foobar_udp500.region}" - network = "${google_compute_network.foobar.self_link}" - bgp { - asn = 64514 - } -} -resource "google_compute_vpn_tunnel" "foobar" { - name = "interface-test-%s" - region = "${google_compute_forwarding_rule.foobar_udp4500.region}" - target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" - shared_secret = "unguessable" - peer_ip = "8.8.8.8" - router = "${google_compute_router.foobar.name}" -} -resource "google_compute_router_interface" "foobar" { - name = "interface-test-%s" - router = "${google_compute_router.foobar.name}" - region = "${google_compute_router.foobar.region}" - ip_range = "169.254.3.1/30" - vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}" -}`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), - acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), - acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), - acctest.RandString(10)) -var testAccComputeRouterInterface_keepRouter = fmt.Sprintf(` -resource "google_compute_network" "foobar" { - name = "interface-test-%s" +func testAccComputeRouterInterfaceKeepRouter(network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel string) string { + return fmt.Sprintf(` + resource "google_compute_network" "foobar" { + name = "%s" + } + resource "google_compute_subnetwork" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" + } + resource "google_compute_address" "foobar" { + name = "%s" + region = "${google_compute_subnetwork.foobar.region}" + } + resource "google_compute_vpn_gateway" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.self_link}" + region = "${google_compute_subnetwork.foobar.region}" + } + resource "google_compute_forwarding_rule" "foobar_esp" { + name = "%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 = "%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 = "%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_router" "foobar"{ + name = "%s" + region = "${google_compute_forwarding_rule.foobar_udp500.region}" + network = "${google_compute_network.foobar.self_link}" + bgp { + asn = 64514 + } + } + resource "google_compute_vpn_tunnel" "foobar" { + name = "%s" + region = "${google_compute_forwarding_rule.foobar_udp4500.region}" + target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" + shared_secret = "unguessable" + peer_ip = "8.8.8.8" + router = "${google_compute_router.foobar.name}" + } + `, network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel) } -resource "google_compute_subnetwork" "foobar" { - name = "interface-test-%s" - network = "${google_compute_network.foobar.self_link}" - ip_cidr_range = "10.0.0.0/16" - region = "us-central1" -} -resource "google_compute_address" "foobar" { - name = "interface-test-%s" - region = "${google_compute_subnetwork.foobar.region}" -} -resource "google_compute_vpn_gateway" "foobar" { - name = "interface-test-%s" - network = "${google_compute_network.foobar.self_link}" - region = "${google_compute_subnetwork.foobar.region}" -} -resource "google_compute_forwarding_rule" "foobar_esp" { - name = "interface-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 = "interface-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 = "interface-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_router" "foobar"{ - name = "interface-test-%s" - region = "${google_compute_forwarding_rule.foobar_udp500.region}" - network = "${google_compute_network.foobar.self_link}" - bgp { - asn = 64514 - } -} -resource "google_compute_vpn_tunnel" "foobar" { - name = "interface-test-%s" - region = "${google_compute_forwarding_rule.foobar_udp4500.region}" - target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" - shared_secret = "unguessable" - peer_ip = "8.8.8.8" - router = "${google_compute_router.foobar.name}" -}`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), - acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), - acctest.RandString(10), acctest.RandString(10), acctest.RandString(10)) diff --git a/resource_compute_router_peer.go b/resource_compute_router_peer.go index 2585f31b..cbbcea64 100644 --- a/resource_compute_router_peer.go +++ b/resource_compute_router_peer.go @@ -37,18 +37,29 @@ func resourceComputeRouterPeer() *schema.Resource { ForceNew: true, }, - "ip_address": &schema.Schema{ + "peer_ip_address": &schema.Schema{ Type: schema.TypeString, Optional: true, ForceNew: true, }, - "asn": &schema.Schema{ + "peer_asn": &schema.Schema{ Type: schema.TypeInt, Required: true, ForceNew: true, }, + "advertised_route_priority": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + + "ip_address": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "project": &schema.Schema{ Type: schema.TypeString, Optional: true, @@ -82,15 +93,15 @@ func resourceComputeRouterPeerCreate(d *schema.ResourceData, meta interface{}) e routerName := d.Get("router").(string) peerName := d.Get("name").(string) - routerId := fmt.Sprintf("router/%s/%s", region, routerName) - mutexKV.Lock(routerId) - defer mutexKV.Unlock(routerId) + routerLock := getRouterLockName(region, routerName) + mutexKV.Lock(routerLock) + defer mutexKV.Unlock(routerLock) - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers router, err := routersService.Get(project, region, routerName).Do() if err != nil { if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { - log.Printf("[WARN] Removing router peer because its router %s/%s is gone", region, routerName) + log.Printf("[WARN] Removing router peer %s because its router %s/%s is gone", peerName, region, routerName) d.SetId("") return nil @@ -99,54 +110,47 @@ func resourceComputeRouterPeerCreate(d *schema.ResourceData, meta interface{}) e return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err) } - var peerExists bool = false - - var peers []*compute.RouterBgpPeer = router.BgpPeers + peers := router.BgpPeers for _, peer := range peers { - if peer.Name == peerName { - peerExists = true - break + d.SetId("") + return fmt.Errorf("Router %s has peer %s already", routerName, peerName) } } - if !peerExists { + ifaceName := d.Get("interface").(string) - ifaceName := d.Get("interface").(string) + peer := &compute.RouterBgpPeer{Name: peerName, + InterfaceName: ifaceName} - peer := &compute.RouterBgpPeer{Name: peerName, - InterfaceName: ifaceName} + if v, ok := d.GetOk("peer_ip_address"); ok { + peer.PeerIpAddress = v.(string) + } - if v, ok := d.GetOk("ip_address"); ok { - peer.PeerIpAddress = v.(string) - } + if v, ok := d.GetOk("peer_asn"); ok { + peer.PeerAsn = int64(v.(int)) + } - if v, ok := d.GetOk("asn"); ok { - peer.PeerAsn = int64(v.(int)) - } + if v, ok := d.GetOk("advertised_route_priority"); ok { + peer.AdvertisedRoutePriority = int64(v.(int)) + } - log.Printf( - "[INFO] Adding peer %s", peerName) - peers = append(peers, peer) - patchRouter := &compute.Router{ - BgpPeers: peers, - } + log.Printf("[INFO] Adding peer %s", peerName) + peers = append(peers, peer) + patchRouter := &compute.Router{ + BgpPeers: peers, + } - log.Printf("[DEBUG] Updating router %s/%s with peers: %+v", region, routerName, peers) - op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() - if err != nil { - return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) - } - - err = computeOperationWaitRegion(config, op, project, region, "Patching router") - if err != nil { - return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) - } - - d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, peerName)) - - } else { - log.Printf("[DEBUG] Router %s has peer %s already", routerName, peerName) + log.Printf("[DEBUG] Updating router %s/%s with peers: %+v", region, routerName, peers) + op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() + if err != nil { + return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) + } + d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, peerName)) + err = computeOperationWaitRegion(config, op, project, region, "Patching router") + if err != nil { + d.SetId("") + return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) } return resourceComputeRouterPeerRead(d, meta) @@ -169,11 +173,11 @@ func resourceComputeRouterPeerRead(d *schema.ResourceData, meta interface{}) err routerName := d.Get("router").(string) peerName := d.Get("name").(string) - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers router, err := routersService.Get(project, region, routerName).Do() if err != nil { if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { - log.Printf("[WARN] Removing router peer because its router %s/%s is gone", region, routerName) + log.Printf("[WARN] Removing router peer %s because its router %s/%s is gone", peerName, region, routerName) d.SetId("") return nil @@ -182,24 +186,21 @@ func resourceComputeRouterPeerRead(d *schema.ResourceData, meta interface{}) err return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err) } - var peerFound bool = false - - var peers []*compute.RouterBgpPeer = router.BgpPeers - for _, peer := range peers { + for _, peer := range router.BgpPeers { if peer.Name == peerName { - peerFound = true d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, peerName)) d.Set("interface", peer.InterfaceName) - d.Set("ip_address", peer.PeerIpAddress) - d.Set("asn", peer.PeerAsn) + d.Set("peer_ip_address", peer.PeerIpAddress) + d.Set("peer_asn", peer.PeerAsn) + d.Set("advertised_route_priority", peer.AdvertisedRoutePriority) + d.Set("ip_address", peer.IpAddress) + return nil } } - if !peerFound { - log.Printf("[WARN] Removing router peer %s/%s/%s because it is gone", region, routerName, peerName) - d.SetId("") - } + log.Printf("[WARN] Removing router peer %s/%s/%s because it is gone", region, routerName, peerName) + d.SetId("") return nil } @@ -220,15 +221,15 @@ func resourceComputeRouterPeerDelete(d *schema.ResourceData, meta interface{}) e routerName := d.Get("router").(string) peerName := d.Get("name").(string) - routerId := fmt.Sprintf("router/%s/%s", region, routerName) - mutexKV.Lock(routerId) - defer mutexKV.Unlock(routerId) + routerLock := getRouterLockName(region, routerName) + mutexKV.Lock(routerLock) + defer mutexKV.Unlock(routerLock) - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers router, err := routersService.Get(project, region, routerName).Do() if err != nil { if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { - log.Printf("[WARN] Removing router peer because its router %d is gone", d.Get("router").(string)) + log.Printf("[WARN] Removing router peer %s because its router %s/%s is gone", peerName, region, routerName) return nil } @@ -236,43 +237,43 @@ func resourceComputeRouterPeerDelete(d *schema.ResourceData, meta interface{}) e return fmt.Errorf("Error Reading Router %s: %s", routerName, err) } - var peerFound bool = false + var peerFound bool - var oldIfaces []*compute.RouterBgpPeer = router.BgpPeers - var newIfaces []*compute.RouterBgpPeer = make([]*compute.RouterBgpPeer, len(router.BgpPeers)) - for _, peer := range oldIfaces { + var newPeers []*compute.RouterBgpPeer = make([]*compute.RouterBgpPeer, 0, len(router.BgpPeers)) + for _, peer := range router.BgpPeers { if peer.Name == peerName { peerFound = true continue } else { - newIfaces = append(newIfaces, peer) + newPeers = append(newPeers, peer) } } - if peerFound { - - log.Printf( - "[INFO] Removing peer %s", peerName) - patchRouter := &compute.Router{ - BgpPeers: newIfaces, - } - - log.Printf("[DEBUG] Updating router %s/%s with peers: %+v", region, routerName, newIfaces) - op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() - if err != nil { - return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) - } - - err = computeOperationWaitRegion(config, op, project, region, "Patching router") - if err != nil { - return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) - } - - } else { + if !peerFound { log.Printf("[DEBUG] Router %s/%s had no peer %s already", region, routerName, peerName) + d.SetId("") + return nil } + log.Printf( + "[INFO] Removing peer %s from router %s/%s", peerName, region, routerName) + patchRouter := &compute.Router{ + BgpPeers: newPeers, + } + + log.Printf("[DEBUG] Updating router %s/%s with peers: %+v", region, routerName, newPeers) + op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() + if err != nil { + return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) + } + + err = computeOperationWaitRegion(config, op, project, region, "Patching router") + if err != nil { + return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) + } + + d.SetId("") return nil } diff --git a/resource_compute_router_peer_test.go b/resource_compute_router_peer_test.go index 1afaa6f6..7e211f76 100644 --- a/resource_compute_router_peer_test.go +++ b/resource_compute_router_peer_test.go @@ -7,42 +7,95 @@ import ( "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - - "google.golang.org/api/compute/v1" ) func TestAccComputeRouterPeer_basic(t *testing.T) { + network := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) + subnet := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) + address := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) + gateway := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) + espRule := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) + udp500Rule := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) + udp4500Rule := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) + router := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) + tunnel := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) + iface := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) + peer := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeRouterPeerDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouterPeer_basic, + Config: testAccComputeRouterPeerBasic(network, subnet, address, gateway, espRule, udp500Rule, + udp4500Rule, router, tunnel, iface, peer), Check: testAccCheckComputeRouterPeerExists( "google_compute_router_peer.foobar"), }, resource.TestStep{ - Config: testAccComputeRouterPeer_keepRouter, - Check: testAccCheckComputeRouterPeerDestroy( + Config: testAccComputeRouterPeerKeepRouter(network, subnet, address, gateway, espRule, udp500Rule, + udp4500Rule, router, tunnel, iface), + Check: testAccCheckComputeRouterPeerDelete( "google_compute_router_peer.foobar"), }, }, }) } -func testAccCheckComputeRouterPeerDestroy(n string) resource.TestCheckFunc { +func testAccCheckComputeRouterPeerDestroy(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + + routersService := config.clientCompute.Routers + + for _, rs := range s.RootModule().Resources { + if rs.Type != "google_compute_router" { + continue + } + + project, err := getTestProject(rs.Primary, config) + if err != nil { + return err + } + + region, err := getTestRegion(rs.Primary, config) + if err != nil { + return err + } + + routerName := rs.Primary.Attributes["router"] + + _, err = routersService.Get(project, region, routerName).Do() + + if err == nil { + return fmt.Errorf("Error, Router %s in region %s still exists", + routerName, region) + } + } + + return nil +} + +func testAccCheckComputeRouterPeerDelete(n string) resource.TestCheckFunc { return func(s *terraform.State) error { config := testAccProvider.Meta().(*Config) - project := config.Project - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers for _, rs := range s.RootModule().Resources { if rs.Type != "google_compute_router_peer" { continue } - region := rs.Primary.Attributes["region"] + project, err := getTestProject(rs.Primary, config) + if err != nil { + return err + } + + region, err := getTestRegion(rs.Primary, config) + if err != nil { + return err + } + name := rs.Primary.Attributes["name"] routerName := rs.Primary.Attributes["router"] @@ -52,21 +105,13 @@ func testAccCheckComputeRouterPeerDestroy(n string) resource.TestCheckFunc { return fmt.Errorf("Error Reading Router %s: %s", routerName, err) } - var peerExists bool = false - - var peers []*compute.RouterBgpPeer = router.BgpPeers + peers := router.BgpPeers for _, peer := range peers { if peer.Name == name { - peerExists = true - break + return fmt.Errorf("Peer %s still exists on router %s/%s", name, region, router.Name) } } - - if peerExists { - return fmt.Errorf("Peer %s still exists on router %s", name, router.Name) - } - } return nil @@ -85,179 +130,181 @@ func testAccCheckComputeRouterPeerExists(n string) resource.TestCheckFunc { } config := testAccProvider.Meta().(*Config) + + project, err := getTestProject(rs.Primary, config) + if err != nil { + return err + } + + region, err := getTestRegion(rs.Primary, config) + if err != nil { + return err + } + name := rs.Primary.Attributes["name"] routerName := rs.Primary.Attributes["router"] - region := rs.Primary.Attributes["region"] - project := config.Project - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers router, err := routersService.Get(project, region, routerName).Do() if err != nil { return fmt.Errorf("Error Reading Router %s: %s", routerName, err) } - var peerExists bool = false - - var peers []*compute.RouterBgpPeer = router.BgpPeers - for _, peer := range peers { + for _, peer := range router.BgpPeers { if peer.Name == name { - peerExists = true - break + return nil } } - if !peerExists { - return fmt.Errorf("Peer %s not found for router %s", name, router.Name) - } - - return nil + return fmt.Errorf("Peer %s not found for router %s", name, router.Name) } } -var testAccComputeRouterPeer_basic = fmt.Sprintf(` -resource "google_compute_network" "foobar" { - name = "peer-test-%s" +func testAccComputeRouterPeerBasic(network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel, iface, peer string) string { + return fmt.Sprintf(` + resource "google_compute_network" "foobar" { + name = "%s" + } + resource "google_compute_subnetwork" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" + } + resource "google_compute_address" "foobar" { + name = "%s" + region = "${google_compute_subnetwork.foobar.region}" + } + resource "google_compute_vpn_gateway" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.self_link}" + region = "${google_compute_subnetwork.foobar.region}" + } + resource "google_compute_forwarding_rule" "foobar_esp" { + name = "%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 = "%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 = "%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_router" "foobar"{ + name = "%s" + region = "${google_compute_forwarding_rule.foobar_udp500.region}" + network = "${google_compute_network.foobar.self_link}" + bgp { + asn = 64514 + } + } + resource "google_compute_vpn_tunnel" "foobar" { + name = "%s" + region = "${google_compute_forwarding_rule.foobar_udp4500.region}" + target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" + shared_secret = "unguessable" + peer_ip = "8.8.8.8" + router = "${google_compute_router.foobar.name}" + } + resource "google_compute_router_interface" "foobar" { + name = "%s" + router = "${google_compute_router.foobar.name}" + region = "${google_compute_router.foobar.region}" + ip_range = "169.254.3.1/30" + vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}" + } + resource "google_compute_router_peer" "foobar" { + name = "%s" + router = "${google_compute_router.foobar.name}" + region = "${google_compute_router.foobar.region}" + peer_ip_address = "169.254.3.2" + peer_asn = 65515 + advertised_route_priority = 100 + interface = "${google_compute_router_interface.foobar.name}" + } + `, network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel, iface, peer) } -resource "google_compute_subnetwork" "foobar" { - name = "peer-test-%s" - network = "${google_compute_network.foobar.self_link}" - ip_cidr_range = "10.0.0.0/16" - region = "us-central1" -} -resource "google_compute_address" "foobar" { - name = "peer-test-%s" - region = "${google_compute_subnetwork.foobar.region}" -} -resource "google_compute_vpn_gateway" "foobar" { - name = "peer-test-%s" - network = "${google_compute_network.foobar.self_link}" - region = "${google_compute_subnetwork.foobar.region}" -} -resource "google_compute_forwarding_rule" "foobar_esp" { - name = "peer-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 = "peer-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 = "peer-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_router" "foobar"{ - name = "peer-test-%s" - region = "${google_compute_forwarding_rule.foobar_udp500.region}" - network = "${google_compute_network.foobar.self_link}" - bgp { - asn = 64514 - } -} -resource "google_compute_vpn_tunnel" "foobar" { - name = "peer-test-%s" - region = "${google_compute_forwarding_rule.foobar_udp4500.region}" - target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" - shared_secret = "unguessable" - peer_ip = "8.8.8.8" - router = "${google_compute_router.foobar.name}" -} -resource "google_compute_router_interface" "foobar" { - name = "peer-test-%s" - router = "${google_compute_router.foobar.name}" - region = "${google_compute_router.foobar.region}" - ip_range = "169.254.3.1/30" - vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}" -} -resource "google_compute_router_peer" "foobar" { - name = "peer-test-%s" - router = "${google_compute_router.foobar.name}" - region = "${google_compute_router.foobar.region}" - ip_address = "169.254.3.2" - asn = 65515 - interface = "${google_compute_router_interface.foobar.name}" -}`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), - acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), - acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), - acctest.RandString(10), acctest.RandString(10)) -var testAccComputeRouterPeer_keepRouter = fmt.Sprintf(` -resource "google_compute_network" "foobar" { - name = "peer-test-%s" +func testAccComputeRouterPeerKeepRouter(network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel, iface string) string { + return fmt.Sprintf(` + resource "google_compute_network" "foobar" { + name = "%s" + } + resource "google_compute_subnetwork" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" + } + resource "google_compute_address" "foobar" { + name = "%s" + region = "${google_compute_subnetwork.foobar.region}" + } + resource "google_compute_vpn_gateway" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.self_link}" + region = "${google_compute_subnetwork.foobar.region}" + } + resource "google_compute_forwarding_rule" "foobar_esp" { + name = "%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 = "%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 = "%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_router" "foobar"{ + name = "%s" + region = "${google_compute_forwarding_rule.foobar_udp500.region}" + network = "${google_compute_network.foobar.self_link}" + bgp { + asn = 64514 + } + } + resource "google_compute_vpn_tunnel" "foobar" { + name = "%s" + region = "${google_compute_forwarding_rule.foobar_udp4500.region}" + target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" + shared_secret = "unguessable" + peer_ip = "8.8.8.8" + router = "${google_compute_router.foobar.name}" + } + resource "google_compute_router_interface" "foobar" { + name = "%s" + router = "${google_compute_router.foobar.name}" + region = "${google_compute_router.foobar.region}" + ip_range = "169.254.3.1/30" + vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}" + } + `, network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel, iface) } -resource "google_compute_subnetwork" "foobar" { - name = "peer-test-%s" - network = "${google_compute_network.foobar.self_link}" - ip_cidr_range = "10.0.0.0/16" - region = "us-central1" -} -resource "google_compute_address" "foobar" { - name = "peer-test-%s" - region = "${google_compute_subnetwork.foobar.region}" -} -resource "google_compute_vpn_gateway" "foobar" { - name = "peer-test-%s" - network = "${google_compute_network.foobar.self_link}" - region = "${google_compute_subnetwork.foobar.region}" -} -resource "google_compute_forwarding_rule" "foobar_esp" { - name = "peer-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 = "peer-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 = "peer-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_router" "foobar"{ - name = "peer-test-%s" - region = "${google_compute_forwarding_rule.foobar_udp500.region}" - network = "${google_compute_network.foobar.self_link}" - bgp { - asn = 64514 - } -} -resource "google_compute_vpn_tunnel" "foobar" { - name = "peer-test-%s" - region = "${google_compute_forwarding_rule.foobar_udp4500.region}" - target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" - shared_secret = "unguessable" - peer_ip = "8.8.8.8" - router = "${google_compute_router.foobar.name}" -} -resource "google_compute_router_interface" "foobar" { - name = "peer-test-%s" - router = "${google_compute_router.foobar.name}" - region = "${google_compute_router.foobar.region}" - ip_range = "169.254.3.1/30" - vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}" -}`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), - acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), - acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), - acctest.RandString(10)) diff --git a/resource_compute_router_test.go b/resource_compute_router_test.go index cb22468d..b391d108 100644 --- a/resource_compute_router_test.go +++ b/resource_compute_router_test.go @@ -7,18 +7,19 @@ import ( "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - - "google.golang.org/api/compute/v1" ) func TestAccComputeRouter_basic(t *testing.T) { + network := fmt.Sprintf("router-test-%s", acctest.RandString(10)) + subnet := fmt.Sprintf("router-test-%s", acctest.RandString(10)) + router := fmt.Sprintf("router-test-%s", acctest.RandString(10)) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckComputeRouterDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouter_basic, + Config: testAccComputeRouterBasic(network, subnet, router), Check: resource.ComposeTestCheckFunc( testAccCheckComputeRouterExists( "google_compute_router.foobar"), @@ -31,13 +32,16 @@ func TestAccComputeRouter_basic(t *testing.T) { } func TestAccComputeRouter_noRegion(t *testing.T) { + network := fmt.Sprintf("router-test-%s", acctest.RandString(10)) + subnet := fmt.Sprintf("router-test-%s", acctest.RandString(10)) + router := fmt.Sprintf("router-test-%s", acctest.RandString(10)) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckComputeRouterDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouter_noRegion, + Config: testAccComputeRouterNoRegion(network, subnet, router), Check: resource.ComposeTestCheckFunc( testAccCheckComputeRouterExists( "google_compute_router.foobar"), @@ -50,13 +54,16 @@ func TestAccComputeRouter_noRegion(t *testing.T) { } func TestAccComputeRouter_networkLink(t *testing.T) { + network := fmt.Sprintf("router-test-%s", acctest.RandString(10)) + subnet := fmt.Sprintf("router-test-%s", acctest.RandString(10)) + router := fmt.Sprintf("router-test-%s", acctest.RandString(10)) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckComputeRouterDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouter_networkLink, + Config: testAccComputeRouterNetworkLink(network, subnet, router), Check: testAccCheckComputeRouterExists( "google_compute_router.foobar"), }, @@ -66,19 +73,27 @@ func TestAccComputeRouter_networkLink(t *testing.T) { func testAccCheckComputeRouterDestroy(s *terraform.State) error { config := testAccProvider.Meta().(*Config) - project := config.Project - routersService := compute.NewRoutersService(config.clientCompute) + routersService := config.clientCompute.Routers for _, rs := range s.RootModule().Resources { if rs.Type != "google_compute_router" { continue } - region := rs.Primary.Attributes["region"] + project, err := getTestProject(rs.Primary, config) + if err != nil { + return err + } + + region, err := getTestRegion(rs.Primary, config) + if err != nil { + return err + } + name := rs.Primary.Attributes["name"] - _, err := routersService.Get(project, region, name).Do() + _, err = routersService.Get(project, region, name).Do() if err == nil { return fmt.Errorf("Error, Router %s in region %s still exists", @@ -101,12 +116,21 @@ func testAccCheckComputeRouterExists(n string) resource.TestCheckFunc { } config := testAccProvider.Meta().(*Config) - name := rs.Primary.Attributes["name"] - region := rs.Primary.Attributes["region"] - project := config.Project - routersService := compute.NewRoutersService(config.clientCompute) - _, err := routersService.Get(project, region, name).Do() + project, err := getTestProject(rs.Primary, config) + if err != nil { + return err + } + + region, err := getTestRegion(rs.Primary, config) + if err != nil { + return err + } + + name := rs.Primary.Attributes["name"] + + routersService := config.clientCompute.Routers + _, err = routersService.Get(project, region, name).Do() if err != nil { return fmt.Errorf("Error Reading Router %s: %s", name, err) @@ -116,61 +140,67 @@ func testAccCheckComputeRouterExists(n string) resource.TestCheckFunc { } } -var testAccComputeRouter_basic = fmt.Sprintf(` -resource "google_compute_network" "foobar" { - name = "router-test-%s" +func testAccComputeRouterBasic(network, subnet, router string) string { + return fmt.Sprintf(` + resource "google_compute_network" "foobar" { + name = "%s" + } + resource "google_compute_subnetwork" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "europe-west1" + } + resource "google_compute_router" "foobar" { + name = "%s" + region = "${google_compute_subnetwork.foobar.region}" + network = "${google_compute_network.foobar.name}" + bgp { + asn = 64514 + } + } + `, network, subnet, router) } -resource "google_compute_subnetwork" "foobar" { - name = "router-test-%s" - network = "${google_compute_network.foobar.self_link}" - ip_cidr_range = "10.0.0.0/16" - region = "europe-west1" -} -resource "google_compute_router" "foobar" { - name = "router-test-%s" - region = "${google_compute_subnetwork.foobar.region}" - network = "${google_compute_network.foobar.name}" - bgp { - asn = 64514 - } -} -`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10)) -var testAccComputeRouter_noRegion = fmt.Sprintf(` -resource "google_compute_network" "foobar" { - name = "router-test-%s" +func testAccComputeRouterNoRegion(network, subnet, router string) string { + return fmt.Sprintf(` + resource "google_compute_network" "foobar" { + name = "%s" + } + resource "google_compute_subnetwork" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" + } + resource "google_compute_router" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.name}" + bgp { + asn = 64514 + } + } + `, network, subnet, router) } -resource "google_compute_subnetwork" "foobar" { - name = "router-test-%s" - network = "${google_compute_network.foobar.self_link}" - ip_cidr_range = "10.0.0.0/16" - region = "us-central1" -} -resource "google_compute_router" "foobar" { - name = "router-test-%s" - network = "${google_compute_network.foobar.name}" - bgp { - asn = 64514 - } -} -`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10)) -var testAccComputeRouter_networkLink = fmt.Sprintf(` -resource "google_compute_network" "foobar" { - name = "router-test-%s" +func testAccComputeRouterNetworkLink(network, subnet, router string) string { + return fmt.Sprintf(` + resource "google_compute_network" "foobar" { + name = "%s" + } + resource "google_compute_subnetwork" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" + } + resource "google_compute_router" "foobar" { + name = "%s" + region = "${google_compute_subnetwork.foobar.region}" + network = "${google_compute_network.foobar.self_link}" + bgp { + asn = 64514 + } + } + `, network, subnet, router) } -resource "google_compute_subnetwork" "foobar" { - name = "router-test-%s" - network = "${google_compute_network.foobar.self_link}" - ip_cidr_range = "10.0.0.0/16" - region = "us-central1" -} -resource "google_compute_router" "foobar" { - name = "router-test-%s" - region = "${google_compute_subnetwork.foobar.region}" - network = "${google_compute_network.foobar.self_link}" - bgp { - asn = 64514 - } -} -`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10)) diff --git a/resource_compute_vpn_tunnel_test.go b/resource_compute_vpn_tunnel_test.go index d8da36e2..659510e7 100644 --- a/resource_compute_vpn_tunnel_test.go +++ b/resource_compute_vpn_tunnel_test.go @@ -33,18 +33,28 @@ func TestAccComputeVpnTunnel_basic(t *testing.T) { } func TestAccComputeVpnTunnel_router(t *testing.T) { + network := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + subnet := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + address := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + gateway := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + espRule := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + udp500Rule := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + udp4500Rule := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + router := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + tunnel := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckComputeVpnTunnelDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeVpnTunnel_router, + Config: testAccComputeVpnTunnelRouter(network, subnet, address, gateway, espRule, udp500Rule, + udp4500Rule, router, tunnel), Check: resource.ComposeTestCheckFunc( testAccCheckComputeVpnTunnelExists( "google_compute_vpn_tunnel.foobar"), resource.TestCheckResourceAttr( - "google_compute_vpn_tunnel.foobar", "router", "tunnel-test-router"), + "google_compute_vpn_tunnel.foobar", "router", router), ), }, }, @@ -173,66 +183,67 @@ resource "google_compute_vpn_tunnel" "foobar" { acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), acctest.RandString(10)) -var testAccComputeVpnTunnel_router = fmt.Sprintf(` -resource "google_compute_network" "foobar" { - name = "tunnel-test-%s" +func testAccComputeVpnTunnelRouter(network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel string) string { + return fmt.Sprintf(` + resource "google_compute_network" "foobar" { + name = "%s" + } + resource "google_compute_subnetwork" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" + } + resource "google_compute_address" "foobar" { + name = "%s" + region = "${google_compute_subnetwork.foobar.region}" + } + resource "google_compute_vpn_gateway" "foobar" { + name = "%s" + network = "${google_compute_network.foobar.self_link}" + region = "${google_compute_subnetwork.foobar.region}" + } + resource "google_compute_forwarding_rule" "foobar_esp" { + name = "%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 = "%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 = "%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_router" "foobar"{ + name = "%s" + region = "${google_compute_forwarding_rule.foobar_udp500.region}" + network = "${google_compute_network.foobar.self_link}" + bgp { + asn = 64514 + } + } + resource "google_compute_vpn_tunnel" "foobar" { + name = "%s" + region = "${google_compute_forwarding_rule.foobar_udp4500.region}" + target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" + shared_secret = "unguessable" + peer_ip = "8.8.8.8" + router = "${google_compute_router.foobar.name}" + } + `, network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel) } -resource "google_compute_subnetwork" "foobar" { - name = "tunnel-test-%s" - network = "${google_compute_network.foobar.self_link}" - ip_cidr_range = "10.0.0.0/16" - region = "us-central1" -} -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_router" "foobar"{ - name = "tunnel-test-router" - region = "${google_compute_forwarding_rule.foobar_udp500.region}" - network = "${google_compute_network.foobar.self_link}" - bgp { - asn = 64514 - } -} -resource "google_compute_vpn_tunnel" "foobar" { - name = "tunnel-test-%s" - region = "${google_compute_forwarding_rule.foobar_udp4500.region}" - target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" - shared_secret = "unguessable" - peer_ip = "8.8.8.8" - router = "${google_compute_router.foobar.name}" -}`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), - acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), - acctest.RandString(10), acctest.RandString(10)) var testAccComputeVpnTunnelDefaultTrafficSelectors = fmt.Sprintf(` resource "google_compute_network" "foobar" { From 3ffa8f1b725c8ac2442182a8e604d12e6dd09fee Mon Sep 17 00:00:00 2001 From: Roberto Jung Drebes Date: Fri, 19 May 2017 20:18:23 +0200 Subject: [PATCH 3/3] wip: review changes: - test arguments - set region, project in state - fix import error messages - get rid of peerFound - linkDiffSuppress --- import_compute_router_interface_test.go | 15 +-- import_compute_router_peer_test.go | 16 +-- import_compute_router_test.go | 8 +- provider.go | 8 ++ resource_compute_router.go | 15 ++- resource_compute_router_interface.go | 21 ++-- resource_compute_router_interface_test.go | 63 +++++------- resource_compute_router_peer.go | 11 +- resource_compute_router_peer_test.go | 68 +++++------- resource_compute_router_test.go | 120 +++++++++++----------- resource_compute_vpn_tunnel_test.go | 34 +++--- 11 files changed, 160 insertions(+), 219 deletions(-) diff --git a/import_compute_router_interface_test.go b/import_compute_router_interface_test.go index 91be45fc..29355ae1 100644 --- a/import_compute_router_interface_test.go +++ b/import_compute_router_interface_test.go @@ -1,7 +1,6 @@ package google import ( - "fmt" "testing" "github.com/hashicorp/terraform/helper/acctest" @@ -10,23 +9,13 @@ import ( func TestAccComputeRouterInterface_import(t *testing.T) { resourceName := "google_compute_router_interface.foobar" - network := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) - subnet := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) - address := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) - gateway := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) - espRule := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) - udp500Rule := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) - udp4500Rule := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) - router := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) - tunnel := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) - iface := fmt.Sprintf("router-interface-import-test-%s", acctest.RandString(10)) + testId := acctest.RandString(10) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouterInterfaceBasic(network, subnet, address, gateway, espRule, udp500Rule, - udp4500Rule, router, tunnel, iface), + Config: testAccComputeRouterInterfaceBasic(testId), }, resource.TestStep{ diff --git a/import_compute_router_peer_test.go b/import_compute_router_peer_test.go index fc37e1bc..71c2ed86 100644 --- a/import_compute_router_peer_test.go +++ b/import_compute_router_peer_test.go @@ -1,7 +1,6 @@ package google import ( - "fmt" "testing" "github.com/hashicorp/terraform/helper/acctest" @@ -10,24 +9,13 @@ import ( func TestAccComputeRouterPeer_import(t *testing.T) { resourceName := "google_compute_router_peer.foobar" - network := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) - subnet := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) - address := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) - gateway := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) - espRule := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) - udp500Rule := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) - udp4500Rule := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) - router := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) - tunnel := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) - iface := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) - peer := fmt.Sprintf("router-peer-import-test-%s", acctest.RandString(10)) + testId := acctest.RandString(10) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouterPeerBasic(network, subnet, address, gateway, espRule, udp500Rule, - udp4500Rule, router, tunnel, iface, peer), + Config: testAccComputeRouterPeerBasic(testId), }, resource.TestStep{ diff --git a/import_compute_router_test.go b/import_compute_router_test.go index 97b91dd6..e149fa83 100644 --- a/import_compute_router_test.go +++ b/import_compute_router_test.go @@ -1,25 +1,21 @@ package google import ( - "fmt" "testing" - "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" ) func TestAccComputeRouter_import(t *testing.T) { resourceName := "google_compute_router.foobar" - network := fmt.Sprintf("router-import-test-%s", acctest.RandString(10)) - subnet := fmt.Sprintf("router-import-test-%s", acctest.RandString(10)) - router := fmt.Sprintf("router-import-test-%s", acctest.RandString(10)) + resourceRegion := "europe-west1" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckComputeRouterDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouterNetworkLink(network, subnet, router), + Config: testAccComputeRouterBasic(resourceRegion), }, resource.TestStep{ diff --git a/provider.go b/provider.go index 89b7f8c7..a46311e2 100644 --- a/provider.go +++ b/provider.go @@ -275,3 +275,11 @@ func handleNotFoundError(err error, d *schema.ResourceData, resource string) err return fmt.Errorf("Error reading %s: %s", resource, err) } + +func linkDiffSuppress(k, old, new string, d *schema.ResourceData) bool { + parts := strings.Split(old, "/") + if parts[len(parts)-1] == new { + return true + } + return false +} diff --git a/resource_compute_router.go b/resource_compute_router.go index 992b3797..7d0e53ed 100644 --- a/resource_compute_router.go +++ b/resource_compute_router.go @@ -28,9 +28,10 @@ func resourceComputeRouter() *schema.Resource { }, "network": &schema.Schema{ - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: linkDiffSuppress, }, "description": &schema.Schema{ @@ -42,6 +43,7 @@ func resourceComputeRouter() *schema.Resource { "project": &schema.Schema{ Type: schema.TypeString, Optional: true, + Computed: true, ForceNew: true, }, @@ -167,15 +169,12 @@ func resourceComputeRouterRead(d *schema.ResourceData, meta interface{}) error { } d.Set("self_link", router.SelfLink) - - // if we don't have a network (when importing), set it to the URI returned from the server - if _, ok := d.GetOk("network"); !ok { - d.Set("network", router.Network) - } + d.Set("network", router.Network) d.Set("name", router.Name) d.Set("description", router.Description) d.Set("region", region) + d.Set("project", project) d.Set("bgp", flattenAsn(router.Bgp.Asn)) d.SetId(fmt.Sprintf("%s/%s", region, name)) diff --git a/resource_compute_router_interface.go b/resource_compute_router_interface.go index 2851cfb7..cdfa21f0 100644 --- a/resource_compute_router_interface.go +++ b/resource_compute_router_interface.go @@ -32,9 +32,10 @@ func resourceComputeRouterInterface() *schema.Resource { ForceNew: true, }, "vpn_tunnel": &schema.Schema{ - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: linkDiffSuppress, }, "ip_range": &schema.Schema{ @@ -45,6 +46,7 @@ func resourceComputeRouterInterface() *schema.Resource { "project": &schema.Schema{ Type: schema.TypeString, Optional: true, + Computed: true, ForceNew: true, }, @@ -167,15 +169,10 @@ func resourceComputeRouterInterfaceRead(d *schema.ResourceData, meta interface{} if iface.Name == ifaceName { d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, ifaceName)) - // if we don't have a tunnel (when importing), set it to the URI returned from the server - if _, ok := d.GetOk("vpn_tunnel"); !ok { - vpnTunnelName, err := getVpnTunnelName(iface.LinkedVpnTunnel) - if err != nil { - return err - } - d.Set("vpn_tunnel", vpnTunnelName) - } + d.Set("vpn_tunnel", iface.LinkedVpnTunnel) d.Set("ip_range", iface.IpRange) + d.Set("region", region) + d.Set("project", project) return nil } } @@ -261,7 +258,7 @@ func resourceComputeRouterInterfaceDelete(d *schema.ResourceData, meta interface func resourceComputeRouterInterfaceImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { parts := strings.Split(d.Id(), "/") if len(parts) != 3 { - return nil, fmt.Errorf("Invalid router specifier. Expecting {region}/{router}") + return nil, fmt.Errorf("Invalid router interface specifier. Expecting {region}/{router}/{interface}") } d.Set("region", parts[0]) diff --git a/resource_compute_router_interface_test.go b/resource_compute_router_interface_test.go index 82e3378a..7a762b91 100644 --- a/resource_compute_router_interface_test.go +++ b/resource_compute_router_interface_test.go @@ -10,30 +10,19 @@ import ( ) func TestAccComputeRouterInterface_basic(t *testing.T) { - network := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - subnet := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - address := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - gateway := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - espRule := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - udp500Rule := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - udp4500Rule := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - router := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - tunnel := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - iface := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + testId := acctest.RandString(10) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckComputeRouterInterfaceDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouterInterfaceBasic(network, subnet, address, gateway, espRule, udp500Rule, - udp4500Rule, router, tunnel, iface), + Config: testAccComputeRouterInterfaceBasic(testId), Check: testAccCheckComputeRouterInterfaceExists( "google_compute_router_interface.foobar"), }, resource.TestStep{ - Config: testAccComputeRouterInterfaceKeepRouter(network, subnet, address, gateway, espRule, udp500Rule, - udp4500Rule, router, tunnel), + Config: testAccComputeRouterInterfaceKeepRouter(testId), Check: testAccCheckComputeRouterInterfaceDelete( "google_compute_router_interface.foobar"), }, @@ -161,35 +150,35 @@ func testAccCheckComputeRouterInterfaceExists(n string) resource.TestCheckFunc { } } -func testAccComputeRouterInterfaceBasic(network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel, iface string) string { +func testAccComputeRouterInterfaceBasic(testId string) string { return fmt.Sprintf(` resource "google_compute_network" "foobar" { - name = "%s" + name = "router-interface-test-%s" } resource "google_compute_subnetwork" "foobar" { - name = "%s" + name = "router-interface-test-%s" network = "${google_compute_network.foobar.self_link}" ip_cidr_range = "10.0.0.0/16" region = "us-central1" } resource "google_compute_address" "foobar" { - name = "%s" + name = "router-interface-test-%s" region = "${google_compute_subnetwork.foobar.region}" } resource "google_compute_vpn_gateway" "foobar" { - name = "%s" + name = "router-interface-test-%s" network = "${google_compute_network.foobar.self_link}" region = "${google_compute_subnetwork.foobar.region}" } resource "google_compute_forwarding_rule" "foobar_esp" { - name = "%s" + name = "router-interface-test-%s-1" 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 = "%s" + name = "router-interface-test-%s-2" region = "${google_compute_forwarding_rule.foobar_esp.region}" ip_protocol = "UDP" port_range = "500-500" @@ -197,7 +186,7 @@ func testAccComputeRouterInterfaceBasic(network, subnet, address, gateway, espFw target = "${google_compute_vpn_gateway.foobar.self_link}" } resource "google_compute_forwarding_rule" "foobar_udp4500" { - name = "%s" + name = "router-interface-test-%s-3" region = "${google_compute_forwarding_rule.foobar_udp500.region}" ip_protocol = "UDP" port_range = "4500-4500" @@ -205,7 +194,7 @@ func testAccComputeRouterInterfaceBasic(network, subnet, address, gateway, espFw target = "${google_compute_vpn_gateway.foobar.self_link}" } resource "google_compute_router" "foobar"{ - name = "%s" + name = "router-interface-test-%s" region = "${google_compute_forwarding_rule.foobar_udp500.region}" network = "${google_compute_network.foobar.self_link}" bgp { @@ -213,7 +202,7 @@ func testAccComputeRouterInterfaceBasic(network, subnet, address, gateway, espFw } } resource "google_compute_vpn_tunnel" "foobar" { - name = "%s" + name = "router-interface-test-%s" region = "${google_compute_forwarding_rule.foobar_udp4500.region}" target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" shared_secret = "unguessable" @@ -221,44 +210,44 @@ func testAccComputeRouterInterfaceBasic(network, subnet, address, gateway, espFw router = "${google_compute_router.foobar.name}" } resource "google_compute_router_interface" "foobar" { - name = "%s" + name = "router-interface-test-%s" router = "${google_compute_router.foobar.name}" region = "${google_compute_router.foobar.region}" ip_range = "169.254.3.1/30" vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}" } - `, network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel, iface) + `, testId, testId, testId, testId, testId, testId, testId, testId, testId, testId) } -func testAccComputeRouterInterfaceKeepRouter(network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel string) string { +func testAccComputeRouterInterfaceKeepRouter(testId string) string { return fmt.Sprintf(` resource "google_compute_network" "foobar" { - name = "%s" + name = "router-interface-test-%s" } resource "google_compute_subnetwork" "foobar" { - name = "%s" + name = "router-interface-test-%s" network = "${google_compute_network.foobar.self_link}" ip_cidr_range = "10.0.0.0/16" region = "us-central1" } resource "google_compute_address" "foobar" { - name = "%s" + name = "router-interface-test-%s" region = "${google_compute_subnetwork.foobar.region}" } resource "google_compute_vpn_gateway" "foobar" { - name = "%s" + name = "router-interface-test-%s" network = "${google_compute_network.foobar.self_link}" region = "${google_compute_subnetwork.foobar.region}" } resource "google_compute_forwarding_rule" "foobar_esp" { - name = "%s" + name = "router-interface-test-%s-1" 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 = "%s" + name = "router-interface-test-%s-2" region = "${google_compute_forwarding_rule.foobar_esp.region}" ip_protocol = "UDP" port_range = "500-500" @@ -266,7 +255,7 @@ func testAccComputeRouterInterfaceKeepRouter(network, subnet, address, gateway, target = "${google_compute_vpn_gateway.foobar.self_link}" } resource "google_compute_forwarding_rule" "foobar_udp4500" { - name = "%s" + name = "router-interface-test-%s-3" region = "${google_compute_forwarding_rule.foobar_udp500.region}" ip_protocol = "UDP" port_range = "4500-4500" @@ -274,7 +263,7 @@ func testAccComputeRouterInterfaceKeepRouter(network, subnet, address, gateway, target = "${google_compute_vpn_gateway.foobar.self_link}" } resource "google_compute_router" "foobar"{ - name = "%s" + name = "router-interface-test-%s" region = "${google_compute_forwarding_rule.foobar_udp500.region}" network = "${google_compute_network.foobar.self_link}" bgp { @@ -282,12 +271,12 @@ func testAccComputeRouterInterfaceKeepRouter(network, subnet, address, gateway, } } resource "google_compute_vpn_tunnel" "foobar" { - name = "%s" + name = "router-interface-test-%s" region = "${google_compute_forwarding_rule.foobar_udp4500.region}" target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" shared_secret = "unguessable" peer_ip = "8.8.8.8" router = "${google_compute_router.foobar.name}" } - `, network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel) + `, testId, testId, testId, testId, testId, testId, testId, testId, testId) } diff --git a/resource_compute_router_peer.go b/resource_compute_router_peer.go index cbbcea64..0b1fcfa5 100644 --- a/resource_compute_router_peer.go +++ b/resource_compute_router_peer.go @@ -63,6 +63,7 @@ func resourceComputeRouterPeer() *schema.Resource { "project": &schema.Schema{ Type: schema.TypeString, Optional: true, + Computed: true, ForceNew: true, }, @@ -195,6 +196,8 @@ func resourceComputeRouterPeerRead(d *schema.ResourceData, meta interface{}) err d.Set("peer_asn", peer.PeerAsn) d.Set("advertised_route_priority", peer.AdvertisedRoutePriority) d.Set("ip_address", peer.IpAddress) + d.Set("region", region) + d.Set("project", project) return nil } } @@ -237,20 +240,16 @@ func resourceComputeRouterPeerDelete(d *schema.ResourceData, meta interface{}) e return fmt.Errorf("Error Reading Router %s: %s", routerName, err) } - var peerFound bool - var newPeers []*compute.RouterBgpPeer = make([]*compute.RouterBgpPeer, 0, len(router.BgpPeers)) for _, peer := range router.BgpPeers { - if peer.Name == peerName { - peerFound = true continue } else { newPeers = append(newPeers, peer) } } - if !peerFound { + if len(newPeers) == len(router.BgpPeers) { log.Printf("[DEBUG] Router %s/%s had no peer %s already", region, routerName, peerName) d.SetId("") return nil @@ -280,7 +279,7 @@ func resourceComputeRouterPeerDelete(d *schema.ResourceData, meta interface{}) e func resourceComputeRouterPeerImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { parts := strings.Split(d.Id(), "/") if len(parts) != 3 { - return nil, fmt.Errorf("Invalid router specifier. Expecting {region}/{router}") + return nil, fmt.Errorf("Invalid router peer specifier. Expecting {region}/{router}/{peer}") } d.Set("region", parts[0]) diff --git a/resource_compute_router_peer_test.go b/resource_compute_router_peer_test.go index 7e211f76..83d676d5 100644 --- a/resource_compute_router_peer_test.go +++ b/resource_compute_router_peer_test.go @@ -10,31 +10,19 @@ import ( ) func TestAccComputeRouterPeer_basic(t *testing.T) { - network := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) - subnet := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) - address := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) - gateway := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) - espRule := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) - udp500Rule := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) - udp4500Rule := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) - router := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) - tunnel := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) - iface := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) - peer := fmt.Sprintf("router-peer-test-%s", acctest.RandString(10)) + testId := acctest.RandString(10) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckComputeRouterPeerDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouterPeerBasic(network, subnet, address, gateway, espRule, udp500Rule, - udp4500Rule, router, tunnel, iface, peer), + Config: testAccComputeRouterPeerBasic(testId), Check: testAccCheckComputeRouterPeerExists( "google_compute_router_peer.foobar"), }, resource.TestStep{ - Config: testAccComputeRouterPeerKeepRouter(network, subnet, address, gateway, espRule, udp500Rule, - udp4500Rule, router, tunnel, iface), + Config: testAccComputeRouterPeerKeepRouter(testId), Check: testAccCheckComputeRouterPeerDelete( "google_compute_router_peer.foobar"), }, @@ -162,35 +150,35 @@ func testAccCheckComputeRouterPeerExists(n string) resource.TestCheckFunc { } } -func testAccComputeRouterPeerBasic(network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel, iface, peer string) string { +func testAccComputeRouterPeerBasic(testId string) string { return fmt.Sprintf(` resource "google_compute_network" "foobar" { - name = "%s" + name = "router-peer-test-%s" } resource "google_compute_subnetwork" "foobar" { - name = "%s" + name = "router-peer-test-%s" network = "${google_compute_network.foobar.self_link}" ip_cidr_range = "10.0.0.0/16" region = "us-central1" } resource "google_compute_address" "foobar" { - name = "%s" + name = "router-peer-test-%s" region = "${google_compute_subnetwork.foobar.region}" } resource "google_compute_vpn_gateway" "foobar" { - name = "%s" + name = "router-peer-test-%s" network = "${google_compute_network.foobar.self_link}" region = "${google_compute_subnetwork.foobar.region}" } resource "google_compute_forwarding_rule" "foobar_esp" { - name = "%s" + name = "router-peer-test-%s-1" 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 = "%s" + name = "router-peer-test-%s-2" region = "${google_compute_forwarding_rule.foobar_esp.region}" ip_protocol = "UDP" port_range = "500-500" @@ -198,7 +186,7 @@ func testAccComputeRouterPeerBasic(network, subnet, address, gateway, espFwRule, target = "${google_compute_vpn_gateway.foobar.self_link}" } resource "google_compute_forwarding_rule" "foobar_udp4500" { - name = "%s" + name = "router-peer-test-%s-3" region = "${google_compute_forwarding_rule.foobar_udp500.region}" ip_protocol = "UDP" port_range = "4500-4500" @@ -206,7 +194,7 @@ func testAccComputeRouterPeerBasic(network, subnet, address, gateway, espFwRule, target = "${google_compute_vpn_gateway.foobar.self_link}" } resource "google_compute_router" "foobar"{ - name = "%s" + name = "router-peer-test-%s" region = "${google_compute_forwarding_rule.foobar_udp500.region}" network = "${google_compute_network.foobar.self_link}" bgp { @@ -214,7 +202,7 @@ func testAccComputeRouterPeerBasic(network, subnet, address, gateway, espFwRule, } } resource "google_compute_vpn_tunnel" "foobar" { - name = "%s" + name = "router-peer-test-%s" region = "${google_compute_forwarding_rule.foobar_udp4500.region}" target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" shared_secret = "unguessable" @@ -222,14 +210,14 @@ func testAccComputeRouterPeerBasic(network, subnet, address, gateway, espFwRule, router = "${google_compute_router.foobar.name}" } resource "google_compute_router_interface" "foobar" { - name = "%s" + name = "router-peer-test-%s" router = "${google_compute_router.foobar.name}" region = "${google_compute_router.foobar.region}" ip_range = "169.254.3.1/30" vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}" } resource "google_compute_router_peer" "foobar" { - name = "%s" + name = "router-peer-test-%s" router = "${google_compute_router.foobar.name}" region = "${google_compute_router.foobar.region}" peer_ip_address = "169.254.3.2" @@ -237,38 +225,38 @@ func testAccComputeRouterPeerBasic(network, subnet, address, gateway, espFwRule, advertised_route_priority = 100 interface = "${google_compute_router_interface.foobar.name}" } - `, network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel, iface, peer) + `, testId, testId, testId, testId, testId, testId, testId, testId, testId, testId, testId) } -func testAccComputeRouterPeerKeepRouter(network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel, iface string) string { +func testAccComputeRouterPeerKeepRouter(testId string) string { return fmt.Sprintf(` resource "google_compute_network" "foobar" { - name = "%s" + name = "router-peer-test-%s" } resource "google_compute_subnetwork" "foobar" { - name = "%s" + name = "router-peer-test-%s" network = "${google_compute_network.foobar.self_link}" ip_cidr_range = "10.0.0.0/16" region = "us-central1" } resource "google_compute_address" "foobar" { - name = "%s" + name = "router-peer-test-%s" region = "${google_compute_subnetwork.foobar.region}" } resource "google_compute_vpn_gateway" "foobar" { - name = "%s" + name = "router-peer-test-%s" network = "${google_compute_network.foobar.self_link}" region = "${google_compute_subnetwork.foobar.region}" } resource "google_compute_forwarding_rule" "foobar_esp" { - name = "%s" + name = "router-peer-test-%s-1" 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 = "%s" + name = "router-peer-test-%s-2" region = "${google_compute_forwarding_rule.foobar_esp.region}" ip_protocol = "UDP" port_range = "500-500" @@ -276,7 +264,7 @@ func testAccComputeRouterPeerKeepRouter(network, subnet, address, gateway, espFw target = "${google_compute_vpn_gateway.foobar.self_link}" } resource "google_compute_forwarding_rule" "foobar_udp4500" { - name = "%s" + name = "router-peer-test-%s-3" region = "${google_compute_forwarding_rule.foobar_udp500.region}" ip_protocol = "UDP" port_range = "4500-4500" @@ -284,7 +272,7 @@ func testAccComputeRouterPeerKeepRouter(network, subnet, address, gateway, espFw target = "${google_compute_vpn_gateway.foobar.self_link}" } resource "google_compute_router" "foobar"{ - name = "%s" + name = "router-peer-test-%s" region = "${google_compute_forwarding_rule.foobar_udp500.region}" network = "${google_compute_network.foobar.self_link}" bgp { @@ -292,7 +280,7 @@ func testAccComputeRouterPeerKeepRouter(network, subnet, address, gateway, espFw } } resource "google_compute_vpn_tunnel" "foobar" { - name = "%s" + name = "router-peer-test-%s" region = "${google_compute_forwarding_rule.foobar_udp4500.region}" target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" shared_secret = "unguessable" @@ -300,11 +288,11 @@ func testAccComputeRouterPeerKeepRouter(network, subnet, address, gateway, espFw router = "${google_compute_router.foobar.name}" } resource "google_compute_router_interface" "foobar" { - name = "%s" + name = "router-peer-test-%s" router = "${google_compute_router.foobar.name}" region = "${google_compute_router.foobar.region}" ip_range = "169.254.3.1/30" vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}" } - `, network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel, iface) + `, testId, testId, testId, testId, testId, testId, testId, testId, testId, testId) } diff --git a/resource_compute_router_test.go b/resource_compute_router_test.go index b391d108..aee7dfe2 100644 --- a/resource_compute_router_test.go +++ b/resource_compute_router_test.go @@ -10,21 +10,19 @@ import ( ) func TestAccComputeRouter_basic(t *testing.T) { - network := fmt.Sprintf("router-test-%s", acctest.RandString(10)) - subnet := fmt.Sprintf("router-test-%s", acctest.RandString(10)) - router := fmt.Sprintf("router-test-%s", acctest.RandString(10)) + resourceRegion := "europe-west1" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckComputeRouterDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouterBasic(network, subnet, router), + Config: testAccComputeRouterBasic(resourceRegion), Check: resource.ComposeTestCheckFunc( testAccCheckComputeRouterExists( "google_compute_router.foobar"), resource.TestCheckResourceAttr( - "google_compute_router.foobar", "region", "europe-west1"), + "google_compute_router.foobar", "region", resourceRegion), ), }, }, @@ -32,21 +30,19 @@ func TestAccComputeRouter_basic(t *testing.T) { } func TestAccComputeRouter_noRegion(t *testing.T) { - network := fmt.Sprintf("router-test-%s", acctest.RandString(10)) - subnet := fmt.Sprintf("router-test-%s", acctest.RandString(10)) - router := fmt.Sprintf("router-test-%s", acctest.RandString(10)) + providerRegion := "us-central1" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckComputeRouterDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouterNoRegion(network, subnet, router), + Config: testAccComputeRouterNoRegion(providerRegion), Check: resource.ComposeTestCheckFunc( testAccCheckComputeRouterExists( "google_compute_router.foobar"), resource.TestCheckResourceAttr( - "google_compute_router.foobar", "region", "us-central1"), + "google_compute_router.foobar", "region", providerRegion), ), }, }, @@ -54,16 +50,13 @@ func TestAccComputeRouter_noRegion(t *testing.T) { } func TestAccComputeRouter_networkLink(t *testing.T) { - network := fmt.Sprintf("router-test-%s", acctest.RandString(10)) - subnet := fmt.Sprintf("router-test-%s", acctest.RandString(10)) - router := fmt.Sprintf("router-test-%s", acctest.RandString(10)) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckComputeRouterDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeRouterNetworkLink(network, subnet, router), + Config: testAccComputeRouterNetworkLink(), Check: testAccCheckComputeRouterExists( "google_compute_router.foobar"), }, @@ -140,67 +133,70 @@ func testAccCheckComputeRouterExists(n string) resource.TestCheckFunc { } } -func testAccComputeRouterBasic(network, subnet, router string) string { +func testAccComputeRouterBasic(resourceRegion string) string { + testId := acctest.RandString(10) return fmt.Sprintf(` resource "google_compute_network" "foobar" { - name = "%s" + name = "router-test-%s" } resource "google_compute_subnetwork" "foobar" { - name = "%s" + name = "router-test-%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "%s" + } + resource "google_compute_router" "foobar" { + name = "router-test-%s" + region = "${google_compute_subnetwork.foobar.region}" + network = "${google_compute_network.foobar.name}" + bgp { + asn = 64514 + } + } + `, testId, testId, resourceRegion, testId) +} + +func testAccComputeRouterNoRegion(providerRegion string) string { + testId := acctest.RandString(10) + return fmt.Sprintf(` + resource "google_compute_network" "foobar" { + name = "router-test-%s" + } + resource "google_compute_subnetwork" "foobar" { + name = "router-test-%s" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "%s" + } + resource "google_compute_router" "foobar" { + name = "router-test-%s" + network = "${google_compute_network.foobar.name}" + bgp { + asn = 64514 + } + } + `, testId, testId, providerRegion, testId) +} + +func testAccComputeRouterNetworkLink() string { + testId := acctest.RandString(10) + return fmt.Sprintf(` + resource "google_compute_network" "foobar" { + name = "router-test-%s" + } + resource "google_compute_subnetwork" "foobar" { + name = "router-test-%s" network = "${google_compute_network.foobar.self_link}" ip_cidr_range = "10.0.0.0/16" region = "europe-west1" } resource "google_compute_router" "foobar" { - name = "%s" - region = "${google_compute_subnetwork.foobar.region}" - network = "${google_compute_network.foobar.name}" - bgp { - asn = 64514 - } - } - `, network, subnet, router) -} - -func testAccComputeRouterNoRegion(network, subnet, router string) string { - return fmt.Sprintf(` - resource "google_compute_network" "foobar" { - name = "%s" - } - resource "google_compute_subnetwork" "foobar" { - name = "%s" - network = "${google_compute_network.foobar.self_link}" - ip_cidr_range = "10.0.0.0/16" - region = "us-central1" - } - resource "google_compute_router" "foobar" { - name = "%s" - network = "${google_compute_network.foobar.name}" - bgp { - asn = 64514 - } - } - `, network, subnet, router) -} - -func testAccComputeRouterNetworkLink(network, subnet, router string) string { - return fmt.Sprintf(` - resource "google_compute_network" "foobar" { - name = "%s" - } - resource "google_compute_subnetwork" "foobar" { - name = "%s" - network = "${google_compute_network.foobar.self_link}" - ip_cidr_range = "10.0.0.0/16" - region = "us-central1" - } - resource "google_compute_router" "foobar" { - name = "%s" + name = "router-test-%s" region = "${google_compute_subnetwork.foobar.region}" network = "${google_compute_network.foobar.self_link}" bgp { asn = 64514 } } - `, network, subnet, router) + `, testId, testId, testId) } diff --git a/resource_compute_vpn_tunnel_test.go b/resource_compute_vpn_tunnel_test.go index 659510e7..d2399fa3 100644 --- a/resource_compute_vpn_tunnel_test.go +++ b/resource_compute_vpn_tunnel_test.go @@ -33,23 +33,14 @@ func TestAccComputeVpnTunnel_basic(t *testing.T) { } func TestAccComputeVpnTunnel_router(t *testing.T) { - network := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - subnet := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - address := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - gateway := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - espRule := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - udp500Rule := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - udp4500Rule := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - router := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) - tunnel := fmt.Sprintf("router-interface-test-%s", acctest.RandString(10)) + router := fmt.Sprintf("tunnel-test-router-%s", acctest.RandString(10)) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckComputeVpnTunnelDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccComputeVpnTunnelRouter(network, subnet, address, gateway, espRule, udp500Rule, - udp4500Rule, router, tunnel), + Config: testAccComputeVpnTunnelRouter(router), Check: resource.ComposeTestCheckFunc( testAccCheckComputeVpnTunnelExists( "google_compute_vpn_tunnel.foobar"), @@ -183,35 +174,36 @@ resource "google_compute_vpn_tunnel" "foobar" { acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), acctest.RandString(10), acctest.RandString(10)) -func testAccComputeVpnTunnelRouter(network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel string) string { +func testAccComputeVpnTunnelRouter(router string) string { + testId := acctest.RandString(10) return fmt.Sprintf(` resource "google_compute_network" "foobar" { - name = "%s" + name = "tunnel-test-%s" } resource "google_compute_subnetwork" "foobar" { - name = "%s" + name = "tunnel-test-%s" network = "${google_compute_network.foobar.self_link}" ip_cidr_range = "10.0.0.0/16" region = "us-central1" } resource "google_compute_address" "foobar" { - name = "%s" + name = "tunnel-test-%s" region = "${google_compute_subnetwork.foobar.region}" } resource "google_compute_vpn_gateway" "foobar" { - name = "%s" + 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 = "%s" + name = "tunnel-test-%s-1" 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 = "%s" + name = "tunnel-test-%s-2" region = "${google_compute_forwarding_rule.foobar_esp.region}" ip_protocol = "UDP" port_range = "500-500" @@ -219,7 +211,7 @@ func testAccComputeVpnTunnelRouter(network, subnet, address, gateway, espFwRule, target = "${google_compute_vpn_gateway.foobar.self_link}" } resource "google_compute_forwarding_rule" "foobar_udp4500" { - name = "%s" + name = "tunnel-test-%s-3" region = "${google_compute_forwarding_rule.foobar_udp500.region}" ip_protocol = "UDP" port_range = "4500-4500" @@ -235,14 +227,14 @@ func testAccComputeVpnTunnelRouter(network, subnet, address, gateway, espFwRule, } } resource "google_compute_vpn_tunnel" "foobar" { - name = "%s" + name = "tunnel-test-%s" region = "${google_compute_forwarding_rule.foobar_udp4500.region}" target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}" shared_secret = "unguessable" peer_ip = "8.8.8.8" router = "${google_compute_router.foobar.name}" } - `, network, subnet, address, gateway, espFwRule, udp500FwRule, udp4500FwRule, router, tunnel) + `, testId, testId, testId, testId, testId, testId, testId, router, testId) } var testAccComputeVpnTunnelDefaultTrafficSelectors = fmt.Sprintf(`