diff --git a/.changelog/5063.txt b/.changelog/5063.txt new file mode 100644 index 00000000000..b8f7ff7ab23 --- /dev/null +++ b/.changelog/5063.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +compute: Added `enable` attribute to `google_compute_router_peer` +``` diff --git a/google/resource_compute_router_bgp_peer_test.go b/google/resource_compute_router_bgp_peer_test.go index 85e1abe6836..3a7d76751ae 100644 --- a/google/resource_compute_router_bgp_peer_test.go +++ b/google/resource_compute_router_bgp_peer_test.go @@ -69,6 +69,49 @@ func TestAccComputeRouterPeer_advertiseMode(t *testing.T) { }) } +func TestAccComputeRouterPeer_enable(t *testing.T) { + t.Parallel() + + routerName := fmt.Sprintf("tf-test-router-%s", randString(t, 10)) + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeRouterPeerDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeRouterPeerBasic(routerName), + Check: testAccCheckComputeRouterPeerExists( + t, "google_compute_router_peer.foobar"), + }, + { + ResourceName: "google_compute_router_peer.foobar", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccComputeRouterPeerEnable(routerName, false), + Check: testAccCheckComputeRouterPeerExists( + t, "google_compute_router_peer.foobar"), + }, + { + ResourceName: "google_compute_router_peer.foobar", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccComputeRouterPeerEnable(routerName, true), + Check: testAccCheckComputeRouterPeerExists( + t, "google_compute_router_peer.foobar"), + }, + { + ResourceName: "google_compute_router_peer.foobar", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckComputeRouterPeerDestroyProducer(t *testing.T) func(s *terraform.State) error { return func(s *terraform.State) error { config := googleProviderConfig(t) @@ -195,6 +238,7 @@ func testAccComputeRouterPeerBasic(routerName string) string { return fmt.Sprintf(` resource "google_compute_network" "foobar" { name = "%s-net" + auto_create_subnetworks = false } resource "google_compute_subnetwork" "foobar" { @@ -283,6 +327,7 @@ func testAccComputeRouterPeerKeepRouter(routerName string) string { return fmt.Sprintf(` resource "google_compute_network" "foobar" { name = "%s-net" + auto_create_subnetworks = false } resource "google_compute_subnetwork" "foobar" { @@ -361,6 +406,7 @@ func testAccComputeRouterPeerAdvertiseMode(routerName string) string { return fmt.Sprintf(` resource "google_compute_network" "foobar" { name = "%s-net" + auto_create_subnetworks = false } resource "google_compute_subnetwork" "foobar" { @@ -449,6 +495,7 @@ func testAccComputeRouterPeerAdvertiseModeUpdate(routerName string) string { return fmt.Sprintf(` resource "google_compute_network" "foobar" { name = "%s-net" + auto_create_subnetworks = false } resource "google_compute_subnetwork" "foobar" { @@ -537,3 +584,93 @@ resource "google_compute_router_peer" "foobar" { } `, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName) } + +func testAccComputeRouterPeerEnable(routerName string, enable bool) string { + return fmt.Sprintf(` +resource "google_compute_network" "foobar" { + name = "%s-net" + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork" "foobar" { + name = "%s-subnet" + 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-gateway" + network = google_compute_network.foobar.self_link + region = google_compute_subnetwork.foobar.region +} + +resource "google_compute_forwarding_rule" "foobar_esp" { + name = "%s-frfr1" + 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-fr2" + 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-fr3" + 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 + enable = %v +} +`, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, enable) +} diff --git a/google/resource_compute_router_peer.go b/google/resource_compute_router_peer.go index 884258660f9..0cfb8d2ffd3 100644 --- a/google/resource_compute_router_peer.go +++ b/google/resource_compute_router_peer.go @@ -19,6 +19,7 @@ import ( "log" "reflect" "strconv" + "strings" "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -139,6 +140,15 @@ CIDR-formatted string.`, Where there is more than one matching route of maximum length, the routes with the lowest priority value win.`, }, + "enable": { + Type: schema.TypeBool, + Optional: true, + Description: `The status of the BGP peer connection. If set to false, any active session +with the peer is terminated and all associated routing information is removed. +If set to true, the peer connection can be established with routing information. +The default is true.`, + Default: true, + }, "region": { Type: schema.TypeString, Computed: true, @@ -235,6 +245,12 @@ func resourceComputeRouterBgpPeerCreate(d *schema.ResourceData, meta interface{} } else if v, ok := d.GetOkExists("advertised_ip_ranges"); ok || !reflect.DeepEqual(v, advertisedIpRangesProp) { obj["advertisedIpRanges"] = advertisedIpRangesProp } + enableProp, err := expandNestedComputeRouterBgpPeerEnable(d.Get("enable"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enable"); ok || !reflect.DeepEqual(v, enableProp) { + obj["enable"] = enableProp + } lockName, err := replaceVars(d, config, "router/{{region}}/{{router}}") if err != nil { @@ -370,6 +386,9 @@ func resourceComputeRouterBgpPeerRead(d *schema.ResourceData, meta interface{}) if err := d.Set("management_type", flattenNestedComputeRouterBgpPeerManagementType(res["managementType"], d, config)); err != nil { return fmt.Errorf("Error reading RouterBgpPeer: %s", err) } + if err := d.Set("enable", flattenNestedComputeRouterBgpPeerEnable(res["enable"], d, config)); err != nil { + return fmt.Errorf("Error reading RouterBgpPeer: %s", err) + } return nil } @@ -426,6 +445,12 @@ func resourceComputeRouterBgpPeerUpdate(d *schema.ResourceData, meta interface{} } else if v, ok := d.GetOkExists("advertised_ip_ranges"); ok || !reflect.DeepEqual(v, advertisedIpRangesProp) { obj["advertisedIpRanges"] = advertisedIpRangesProp } + enableProp, err := expandNestedComputeRouterBgpPeerEnable(d.Get("enable"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enable"); ok || !reflect.DeepEqual(v, enableProp) { + obj["enable"] = enableProp + } lockName, err := replaceVars(d, config, "router/{{region}}/{{router}}") if err != nil { @@ -641,6 +666,15 @@ func flattenNestedComputeRouterBgpPeerManagementType(v interface{}, d *schema.Re return v } +func flattenNestedComputeRouterBgpPeerEnable(v interface{}, d *schema.ResourceData, config *Config) interface{} { + b, err := strconv.ParseBool(v.(string)) + if err != nil { + // If we can't convert it into a bool return value as is and let caller handle it + return v + } + return b +} + func expandNestedComputeRouterBgpPeerName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } @@ -706,6 +740,14 @@ func expandNestedComputeRouterBgpPeerAdvertisedIpRangesDescription(v interface{} return v, nil } +func expandNestedComputeRouterBgpPeerEnable(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + if v == nil { + return nil, nil + } + + return strings.ToUpper(strconv.FormatBool(v.(bool))), nil +} + func flattenNestedComputeRouterBgpPeer(d *schema.ResourceData, meta interface{}, res map[string]interface{}) (map[string]interface{}, error) { var v interface{} var ok bool diff --git a/website/docs/r/compute_router_peer.html.markdown b/website/docs/r/compute_router_peer.html.markdown index 232575a008f..84ffa1101ca 100644 --- a/website/docs/r/compute_router_peer.html.markdown +++ b/website/docs/r/compute_router_peer.html.markdown @@ -49,6 +49,21 @@ resource "google_compute_router_peer" "peer" { interface = "interface-1" } ``` +## Example Usage - Router Peer Disabled + + +```hcl +resource "google_compute_router_peer" "peer" { + name = "my-router-peer" + router = "my-router" + region = "us-central1" + peer_ip_address = "169.254.1.2" + peer_asn = 65513 + advertised_route_priority = 100 + interface = "interface-1" + enable = false + } +``` ## Argument Reference @@ -121,6 +136,13 @@ The following arguments are supported: Leave this field blank to advertise no custom IP ranges. Structure is documented below. +* `enable` - + (Optional) + The status of the BGP peer connection. If set to false, any active session + with the peer is terminated and all associated routing information is removed. + If set to true, the peer connection can be established with routing information. + The default is true. + * `region` - (Optional) Region where the router and BgpPeer reside.