From 55d5f99ca42d79f1cf85850212326ad41a79f7ce 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 ++ .../google/import_compute_router_peer_test.go | 27 ++ .../google/import_compute_router_test.go | 28 ++ builtin/providers/google/provider.go | 7 + .../google/resource_compute_router.go | 251 +++++++++++++++ .../resource_compute_router_interface.go | 288 +++++++++++++++++ .../resource_compute_router_interface_test.go | 247 +++++++++++++++ .../google/resource_compute_router_peer.go | 290 ++++++++++++++++++ .../resource_compute_router_peer_test.go | 263 ++++++++++++++++ .../google/resource_compute_router_test.go | 176 +++++++++++ .../google/resource_compute_vpn_tunnel.go | 46 +++ .../resource_compute_vpn_tunnel_test.go | 80 +++++ 12 files changed, 1730 insertions(+) create mode 100644 builtin/providers/google/import_compute_router_interface_test.go create mode 100644 builtin/providers/google/import_compute_router_peer_test.go create mode 100644 builtin/providers/google/import_compute_router_test.go create mode 100644 builtin/providers/google/resource_compute_router.go create mode 100644 builtin/providers/google/resource_compute_router_interface.go create mode 100644 builtin/providers/google/resource_compute_router_interface_test.go create mode 100644 builtin/providers/google/resource_compute_router_peer.go create mode 100644 builtin/providers/google/resource_compute_router_peer_test.go create mode 100644 builtin/providers/google/resource_compute_router_test.go diff --git a/builtin/providers/google/import_compute_router_interface_test.go b/builtin/providers/google/import_compute_router_interface_test.go new file mode 100644 index 000000000..7a5f348f1 --- /dev/null +++ b/builtin/providers/google/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/builtin/providers/google/import_compute_router_peer_test.go b/builtin/providers/google/import_compute_router_peer_test.go new file mode 100644 index 000000000..f17d7d552 --- /dev/null +++ b/builtin/providers/google/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/builtin/providers/google/import_compute_router_test.go b/builtin/providers/google/import_compute_router_test.go new file mode 100644 index 000000000..9e81798e4 --- /dev/null +++ b/builtin/providers/google/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/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index ce33f7e45..1486d369c 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router.go b/builtin/providers/google/resource_compute_router.go new file mode 100644 index 000000000..e02c5602b --- /dev/null +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_interface.go b/builtin/providers/google/resource_compute_router_interface.go new file mode 100644 index 000000000..569102077 --- /dev/null +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_interface_test.go b/builtin/providers/google/resource_compute_router_interface_test.go new file mode 100644 index 000000000..ebd81ccfe --- /dev/null +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_peer.go b/builtin/providers/google/resource_compute_router_peer.go new file mode 100644 index 000000000..2585f31be --- /dev/null +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_peer_test.go b/builtin/providers/google/resource_compute_router_peer_test.go new file mode 100644 index 000000000..1afaa6f6f --- /dev/null +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_test.go b/builtin/providers/google/resource_compute_router_test.go new file mode 100644 index 000000000..cb22468d3 --- /dev/null +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_vpn_tunnel.go b/builtin/providers/google/resource_compute_vpn_tunnel.go index 42f477d92..68e5235bd 100644 --- a/builtin/providers/google/resource_compute_vpn_tunnel.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_vpn_tunnel_test.go b/builtin/providers/google/resource_compute_vpn_tunnel_test.go index dfd153e46..d8da36e24 100644 --- a/builtin/providers/google/resource_compute_vpn_tunnel_test.go +++ b/builtin/providers/google/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 4dddca3ace07468dafe0b8629588e7c378d8dece 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 +- .../google/import_compute_router_peer_test.go | 17 +- .../google/import_compute_router_test.go | 8 +- builtin/providers/google/provider.go | 4 + builtin/providers/google/provider_test.go | 23 + .../google/resource_compute_router.go | 26 +- .../resource_compute_router_interface.go | 150 +++---- .../resource_compute_router_interface_test.go | 368 +++++++++------- .../google/resource_compute_router_peer.go | 175 ++++---- .../resource_compute_router_peer_test.go | 401 ++++++++++-------- .../google/resource_compute_router_test.go | 164 ++++--- .../resource_compute_vpn_tunnel_test.go | 133 +++--- .../google/r/compute_router.html.markdown | 151 +++++++ .../r/compute_router_interface.html.markdown | 62 +++ .../r/compute_router_peer.html.markdown | 72 ++++ .../google/r/compute_vpn_tunnel.html.markdown | 4 + website/source/layouts/google.erb | 12 + 17 files changed, 1133 insertions(+), 653 deletions(-) create mode 100644 website/source/docs/providers/google/r/compute_router.html.markdown create mode 100644 website/source/docs/providers/google/r/compute_router_interface.html.markdown create mode 100644 website/source/docs/providers/google/r/compute_router_peer.html.markdown diff --git a/builtin/providers/google/import_compute_router_interface_test.go b/builtin/providers/google/import_compute_router_interface_test.go index 7a5f348f1..91be45fcb 100644 --- a/builtin/providers/google/import_compute_router_interface_test.go +++ b/builtin/providers/google/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/builtin/providers/google/import_compute_router_peer_test.go b/builtin/providers/google/import_compute_router_peer_test.go index f17d7d552..fc37e1bc5 100644 --- a/builtin/providers/google/import_compute_router_peer_test.go +++ b/builtin/providers/google/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/builtin/providers/google/import_compute_router_test.go b/builtin/providers/google/import_compute_router_test.go index 9e81798e4..97b91dd65 100644 --- a/builtin/providers/google/import_compute_router_test.go +++ b/builtin/providers/google/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/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index 1486d369c..c64c08661 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/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/builtin/providers/google/provider_test.go b/builtin/providers/google/provider_test.go index b6f6859e4..b69ee814b 100644 --- a/builtin/providers/google/provider_test.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router.go b/builtin/providers/google/resource_compute_router.go index e02c5602b..992b3797d 100644 --- a/builtin/providers/google/resource_compute_router.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_interface.go b/builtin/providers/google/resource_compute_router_interface.go index 569102077..2851cfb71 100644 --- a/builtin/providers/google/resource_compute_router_interface.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_interface_test.go b/builtin/providers/google/resource_compute_router_interface_test.go index ebd81ccfe..82e3378a4 100644 --- a/builtin/providers/google/resource_compute_router_interface_test.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_peer.go b/builtin/providers/google/resource_compute_router_peer.go index 2585f31be..cbbcea64b 100644 --- a/builtin/providers/google/resource_compute_router_peer.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_peer_test.go b/builtin/providers/google/resource_compute_router_peer_test.go index 1afaa6f6f..7e211f761 100644 --- a/builtin/providers/google/resource_compute_router_peer_test.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_test.go b/builtin/providers/google/resource_compute_router_test.go index cb22468d3..b391d1080 100644 --- a/builtin/providers/google/resource_compute_router_test.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_vpn_tunnel_test.go b/builtin/providers/google/resource_compute_vpn_tunnel_test.go index d8da36e24..659510e7f 100644 --- a/builtin/providers/google/resource_compute_vpn_tunnel_test.go +++ b/builtin/providers/google/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" { diff --git a/website/source/docs/providers/google/r/compute_router.html.markdown b/website/source/docs/providers/google/r/compute_router.html.markdown new file mode 100644 index 000000000..73e915656 --- /dev/null +++ b/website/source/docs/providers/google/r/compute_router.html.markdown @@ -0,0 +1,151 @@ +--- +layout: "google" +page_title: "Google: google_compute_router" +sidebar_current: "docs-google-compute-router" +description: |- + Manages a Cloud Router resource. +--- + +# google\_compute\_router + +Manages a Cloud Router resource. For more info, read the +[documentation](https://cloud.google.com/compute/docs/cloudrouter). + +## Example Usage + +```hcl +resource "google_compute_network" "foobar" { + name = "network-1" +} + +resource "google_compute_subnetwork" "foobar" { + name = "subnet-1" + network = "${google_compute_network.foobar.self_link}" + ip_cidr_range = "10.0.0.0/16" + region = "us-central1" +} + +resource "google_compute_address" "foobar" { + name = "vpn-gateway-1-address" + region = "${google_compute_subnetwork.foobar.region}" +} + +resource "google_compute_vpn_gateway" "foobar" { + name = "vpn-gateway-1" + network = "${google_compute_network.foobar.self_link}" + region = "${google_compute_subnetwork.foobar.region}" +} + +resource "google_compute_forwarding_rule" "foobar_esp" { + name = "vpn-gw-1-esp" + 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 = "vpn-gw-1-udp-500" + 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 = "vpn-gw-1-udp-4500" + 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 = "router-1" + region = "${google_compute_forwarding_rule.foobar_udp500.region}" + network = "${google_compute_network.foobar.self_link}" + + bgp { + asn = 64512 + } +} + +resource "google_compute_vpn_tunnel" "foobar" { + name = "vpn-tunnel-1" + 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-1" + router = "${google_compute_router.foobar.name}" + region = "${google_compute_router.foobar.region}" + ip_range = "169.254.1.1/30" + vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}" +} + +resource "google_compute_router_peer" "foobar" { + name = "peer-1" + router = "${google_compute_router.foobar.name}" + region = "${google_compute_router.foobar.region}" + peer_ip_address = "169.254.1.2" + peer_asn = 65513 + advertised_route_priority = 100 + interface = "${google_compute_router_interface.foobar.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) A unique name for the router, required by GCE. Changing + this forces a new router to be created. + +* `network` - (Required) The name or resource link to the network this Cloud Router + will use to learn and announce routes. Changing this forces a new router to be created. + +* `bgp` - (Required) BGP information specific to this router. + Changing this forces a new router to be created. + Structure is documented below. + +- - - + +* `description` - (Optional) A description of the resource. + Changing this forces a new router to be created. + +* `project` - (Optional) The project in which the resource belongs. If it + is not provided, the provider project is used. + Changing this forces a new router to be created. + +* `region` - (Optional) The region this router should sit in. If not specified, + the project region will be used. Changing this forces a new router to be + created. + +- - - + +The `bgp` block supports: + +* `asn` - (Required) Local BGP Autonomous System Number (ASN). Must be an + RFC6996 private ASN. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are +exported: + +* `self_link` - The URI of the created resource. + +## Import + +Routers can be imported using the `region` and `name`, e.g. + +``` +$ terraform import google_compute_router.router-1 us-central1/router-1 +``` + diff --git a/website/source/docs/providers/google/r/compute_router_interface.html.markdown b/website/source/docs/providers/google/r/compute_router_interface.html.markdown new file mode 100644 index 000000000..5c3a17b55 --- /dev/null +++ b/website/source/docs/providers/google/r/compute_router_interface.html.markdown @@ -0,0 +1,62 @@ +--- +layout: "google" +page_title: "Google: google_compute_router_interface" +sidebar_current: "docs-google-compute-router-interface" +description: |- + Manages a Cloud Router interface. +--- + +# google\_compute\_router_interface + +Manages a Cloud Router interface. For more info, read the +[documentation](https://cloud.google.com/compute/docs/cloudrouter). + +## Example Usage + +```hcl +resource "google_compute_router_interface" "foobar" { + name = "interface-1" + router = "router-1" + region = "us-central1" + ip_range = "169.254.1.1/30" + vpn_tunnel = "tunnel-1" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) A unique name for the interface, required by GCE. Changing + this forces a new interface to be created. + +* `router` - (Required) The name of the router this interface will be attached to. + Changing this forces a new interface to be created. + +* `vpn_tunnel` - (Required) The name or resource link to the VPN tunnel this + interface will be linked to. Changing this forces a new interface to be created. + +- - - + +* `ip_range` - (Optional) IP address and range of the interface. The IP range must be + in the RFC3927 link-local IP space. Changing this forces a new interface to be created. + +* `project` - (Optional) The project in which this interface's router belongs. If it + is not provided, the provider project is used. Changing this forces a new interface to be created. + +* `region` - (Optional) The region this interface's router sits in. If not specified, + the project region will be used. Changing this forces a new interface to be + created. + +## Attributes Reference + +Only the arguments listed above are exposed as attributes. + +## Import + +Router interfaces can be imported using the `region`, `router` and `name`, e.g. + +``` +$ terraform import google_compute_router_interface.interface-1 us-central1/router-1/interface-1 +``` + diff --git a/website/source/docs/providers/google/r/compute_router_peer.html.markdown b/website/source/docs/providers/google/r/compute_router_peer.html.markdown new file mode 100644 index 000000000..d5305be4e --- /dev/null +++ b/website/source/docs/providers/google/r/compute_router_peer.html.markdown @@ -0,0 +1,72 @@ +--- +layout: "google" +page_title: "Google: google_compute_router_peer" +sidebar_current: "docs-google-compute-router-peer" +description: |- + Manages a Cloud Router BGP peer. +--- + +# google\_compute\_router + +Manages a Cloud Router BGP peer. For more info, read the +[documentation](https://cloud.google.com/compute/docs/cloudrouter). + +## Example Usage + +```hcl +resource "google_compute_router_peer" "foobar" { + name = "peer-1" + router = "router-1" + region = "us-central1" + peer_ip_address = "169.254.1.2" + peer_asn = 65513 + advertised_route_priority = 100 + interface = "interface-1" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) A unique name for BGP peer, required by GCE. Changing + this forces a new peer to be created. + +* `router` - (Required) The name of the router in which this BGP peer will be configured. + Changing this forces a new peer to be created. + +* `interface` - (Required) The name of the interface the BGP peer is associated with. + Changing this forces a new peer to be created. + +* `peer_ip_address` - (Required) IP address of the BGP interface outside Google Cloud. + Changing this forces a new peer to be created. + +* `peer_asn` - (Required) Peer BGP Autonomous System Number (ASN). + Changing this forces a new peer to be created. + +- - - + +* `advertised_route_priority` - (Optional) The priority of routes advertised to this BGP peer. + Changing this forces a new peer to be created. + +* `project` - (Optional) The project in which this peer's router belongs. If it + is not provided, the provider project is used. Changing this forces a new peer to be created. + +* `region` - (Optional) The region this peer's router sits in. If not specified, + the project region will be used. Changing this forces a new peer to be + created. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are +exported: + +* `ip_address` - IP address of the interface inside Google Cloud Platform. + +## Import + +Router BGP peers can be imported using the `region`, `router` and `name`, e.g. + +``` +$ terraform import google_compute_router_peer.peer-1 us-central1/router-1/peer-1 +``` diff --git a/website/source/docs/providers/google/r/compute_vpn_tunnel.html.markdown b/website/source/docs/providers/google/r/compute_vpn_tunnel.html.markdown index 059527882..0fa53c89c 100644 --- a/website/source/docs/providers/google/r/compute_vpn_tunnel.html.markdown +++ b/website/source/docs/providers/google/r/compute_vpn_tunnel.html.markdown @@ -120,6 +120,10 @@ The following arguments are supported: custom subnetted network. Refer to Google documentation for more information. +* `router` - (Optional) Name of a Cloud Router in the same region + to be used for dynamic routing. Refer to Google documentation for more + information. + * `project` - (Optional) The project in which the resource belongs. If it is not provided, the provider project is used. diff --git a/website/source/layouts/google.erb b/website/source/layouts/google.erb index cbefd24f8..f6b59fd4e 100644 --- a/website/source/layouts/google.erb +++ b/website/source/layouts/google.erb @@ -138,6 +138,18 @@ google_compute_route + > + google_compute_router + + + > + google_compute_router_interface + + + > + google_compute_router_peer + + > google_compute_ssl_certificate From 6ab9d82cc536a807622c916d574b7e6d75cdf3f9 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 +-- .../google/import_compute_router_peer_test.go | 16 +-- .../google/import_compute_router_test.go | 8 +- builtin/providers/google/provider.go | 8 ++ .../google/resource_compute_router.go | 15 +-- .../resource_compute_router_interface.go | 21 ++- .../resource_compute_router_interface_test.go | 63 ++++----- .../google/resource_compute_router_peer.go | 11 +- .../resource_compute_router_peer_test.go | 68 ++++------ .../google/resource_compute_router_test.go | 120 +++++++++--------- .../resource_compute_vpn_tunnel_test.go | 34 ++--- 11 files changed, 160 insertions(+), 219 deletions(-) diff --git a/builtin/providers/google/import_compute_router_interface_test.go b/builtin/providers/google/import_compute_router_interface_test.go index 91be45fcb..29355ae1e 100644 --- a/builtin/providers/google/import_compute_router_interface_test.go +++ b/builtin/providers/google/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/builtin/providers/google/import_compute_router_peer_test.go b/builtin/providers/google/import_compute_router_peer_test.go index fc37e1bc5..71c2ed86c 100644 --- a/builtin/providers/google/import_compute_router_peer_test.go +++ b/builtin/providers/google/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/builtin/providers/google/import_compute_router_test.go b/builtin/providers/google/import_compute_router_test.go index 97b91dd65..e149fa836 100644 --- a/builtin/providers/google/import_compute_router_test.go +++ b/builtin/providers/google/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/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index 89b7f8c7c..a46311e27 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router.go b/builtin/providers/google/resource_compute_router.go index 992b3797d..7d0e53ed6 100644 --- a/builtin/providers/google/resource_compute_router.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_interface.go b/builtin/providers/google/resource_compute_router_interface.go index 2851cfb71..cdfa21f01 100644 --- a/builtin/providers/google/resource_compute_router_interface.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_interface_test.go b/builtin/providers/google/resource_compute_router_interface_test.go index 82e3378a4..7a762b91a 100644 --- a/builtin/providers/google/resource_compute_router_interface_test.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_peer.go b/builtin/providers/google/resource_compute_router_peer.go index cbbcea64b..0b1fcfa53 100644 --- a/builtin/providers/google/resource_compute_router_peer.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_peer_test.go b/builtin/providers/google/resource_compute_router_peer_test.go index 7e211f761..83d676d53 100644 --- a/builtin/providers/google/resource_compute_router_peer_test.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_router_test.go b/builtin/providers/google/resource_compute_router_test.go index b391d1080..aee7dfe2d 100644 --- a/builtin/providers/google/resource_compute_router_test.go +++ b/builtin/providers/google/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/builtin/providers/google/resource_compute_vpn_tunnel_test.go b/builtin/providers/google/resource_compute_vpn_tunnel_test.go index 659510e7f..d2399fa3e 100644 --- a/builtin/providers/google/resource_compute_vpn_tunnel_test.go +++ b/builtin/providers/google/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(`