Skip to content

Commit

Permalink
RouterBgpPeer BFD support (hashicorp#3258)
Browse files Browse the repository at this point in the history
Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician committed Nov 3, 2021
1 parent 31ae129 commit bbba281
Show file tree
Hide file tree
Showing 4 changed files with 405 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .changelog/3258.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
compute: Added `bfd` to `google_compute_router_peer`
```
140 changes: 140 additions & 0 deletions google-beta/resource_compute_router_bgp_peer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,49 @@ func TestAccComputeRouterPeer_enable(t *testing.T) {
})
}

func TestAccComputeRouterPeer_bfd(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: testAccComputeRouterPeerBfd(routerName, "DISABLED"),
Check: testAccCheckComputeRouterPeerExists(
t, "google_compute_router_peer.foobar"),
},
{
ResourceName: "google_compute_router_peer.foobar",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccComputeRouterPeerBasic(routerName),
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)
Expand Down Expand Up @@ -675,3 +718,100 @@ resource "google_compute_router_peer" "foobar" {
}
`, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, enable)
}

func testAccComputeRouterPeerBfd(routerName, bfdMode string) 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
ip_address = "169.254.3.1"
peer_ip_address = "169.254.3.2"
peer_asn = 65515
advertised_route_priority = 100
interface = google_compute_router_interface.foobar.name
bfd {
min_receive_interval = 2000
min_transmit_interval = 2000
multiplier = 6
session_initialization_mode = "%s"
}
}
`, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName, bfdMode)
}
194 changes: 194 additions & 0 deletions google-beta/resource_compute_router_peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,55 @@ CIDR-formatted string.`,
Where there is more than one matching route of maximum
length, the routes with the lowest priority value win.`,
},
"bfd": {
Type: schema.TypeList,
Computed: true,
Optional: true,
Description: `BFD configuration for the BGP peering.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"session_initialization_mode": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{"ACTIVE", "DISABLED", "PASSIVE"}, false),
Description: `The BFD session initialization mode for this BGP peer.
If set to 'ACTIVE', the Cloud Router will initiate the BFD session
for this BGP peer. If set to 'PASSIVE', the Cloud Router will wait
for the peer router to initiate the BFD session for this BGP peer.
If set to 'DISABLED', BFD is disabled for this BGP peer. Possible values: ["ACTIVE", "DISABLED", "PASSIVE"]`,
},
"min_receive_interval": {
Type: schema.TypeInt,
Optional: true,
Description: `The minimum interval, in milliseconds, between BFD control packets
received from the peer router. The actual value is negotiated
between the two routers and is equal to the greater of this value
and the transmit interval of the other router. If set, this value
must be between 1000 and 30000.`,
Default: 1000,
},
"min_transmit_interval": {
Type: schema.TypeInt,
Optional: true,
Description: `The minimum interval, in milliseconds, between BFD control packets
transmitted to the peer router. The actual value is negotiated
between the two routers and is equal to the greater of this value
and the corresponding receive interval of the other router. If set,
this value must be between 1000 and 30000.`,
Default: 1000,
},
"multiplier": {
Type: schema.TypeInt,
Optional: true,
Description: `The number of consecutive BFD packets that must be missed before
BFD declares that a peer is unavailable. If set, the value must
be a value between 5 and 16.`,
Default: 5,
},
},
},
},
"enable": {
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -252,6 +301,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
}
bfdProp, err := expandNestedComputeRouterBgpPeerBfd(d.Get("bfd"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("bfd"); !isEmptyValue(reflect.ValueOf(bfdProp)) && (ok || !reflect.DeepEqual(v, bfdProp)) {
obj["bfd"] = bfdProp
}
enableProp, err := expandNestedComputeRouterBgpPeerEnable(d.Get("enable"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -393,6 +448,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("bfd", flattenNestedComputeRouterBgpPeerBfd(res["bfd"], 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)
}
Expand Down Expand Up @@ -458,6 +516,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
}
bfdProp, err := expandNestedComputeRouterBgpPeerBfd(d.Get("bfd"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("bfd"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, bfdProp)) {
obj["bfd"] = bfdProp
}
enableProp, err := expandNestedComputeRouterBgpPeerEnable(d.Get("enable"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -679,6 +743,80 @@ func flattenNestedComputeRouterBgpPeerManagementType(v interface{}, d *schema.Re
return v
}

func flattenNestedComputeRouterBgpPeerBfd(v interface{}, d *schema.ResourceData, config *Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["session_initialization_mode"] =
flattenNestedComputeRouterBgpPeerBfdSessionInitializationMode(original["sessionInitializationMode"], d, config)
transformed["min_transmit_interval"] =
flattenNestedComputeRouterBgpPeerBfdMinTransmitInterval(original["minTransmitInterval"], d, config)
transformed["min_receive_interval"] =
flattenNestedComputeRouterBgpPeerBfdMinReceiveInterval(original["minReceiveInterval"], d, config)
transformed["multiplier"] =
flattenNestedComputeRouterBgpPeerBfdMultiplier(original["multiplier"], d, config)
return []interface{}{transformed}
}
func flattenNestedComputeRouterBgpPeerBfdSessionInitializationMode(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenNestedComputeRouterBgpPeerBfdMinTransmitInterval(v interface{}, d *schema.ResourceData, config *Config) interface{} {
// Handles the string fixed64 format
if strVal, ok := v.(string); ok {
if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil {
return intVal
}
}

// number values are represented as float64
if floatVal, ok := v.(float64); ok {
intVal := int(floatVal)
return intVal
}

return v // let terraform core handle it otherwise
}

func flattenNestedComputeRouterBgpPeerBfdMinReceiveInterval(v interface{}, d *schema.ResourceData, config *Config) interface{} {
// Handles the string fixed64 format
if strVal, ok := v.(string); ok {
if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil {
return intVal
}
}

// number values are represented as float64
if floatVal, ok := v.(float64); ok {
intVal := int(floatVal)
return intVal
}

return v // let terraform core handle it otherwise
}

func flattenNestedComputeRouterBgpPeerBfdMultiplier(v interface{}, d *schema.ResourceData, config *Config) interface{} {
// Handles the string fixed64 format
if strVal, ok := v.(string); ok {
if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil {
return intVal
}
}

// number values are represented as float64
if floatVal, ok := v.(float64); ok {
intVal := int(floatVal)
return intVal
}

return v // let terraform core handle it otherwise
}

func flattenNestedComputeRouterBgpPeerEnable(v interface{}, d *schema.ResourceData, config *Config) interface{} {
if v == nil {
return true
Expand Down Expand Up @@ -760,6 +898,62 @@ func expandNestedComputeRouterBgpPeerAdvertisedIpRangesDescription(v interface{}
return v, nil
}

func expandNestedComputeRouterBgpPeerBfd(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedSessionInitializationMode, err := expandNestedComputeRouterBgpPeerBfdSessionInitializationMode(original["session_initialization_mode"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedSessionInitializationMode); val.IsValid() && !isEmptyValue(val) {
transformed["sessionInitializationMode"] = transformedSessionInitializationMode
}

transformedMinTransmitInterval, err := expandNestedComputeRouterBgpPeerBfdMinTransmitInterval(original["min_transmit_interval"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedMinTransmitInterval); val.IsValid() && !isEmptyValue(val) {
transformed["minTransmitInterval"] = transformedMinTransmitInterval
}

transformedMinReceiveInterval, err := expandNestedComputeRouterBgpPeerBfdMinReceiveInterval(original["min_receive_interval"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedMinReceiveInterval); val.IsValid() && !isEmptyValue(val) {
transformed["minReceiveInterval"] = transformedMinReceiveInterval
}

transformedMultiplier, err := expandNestedComputeRouterBgpPeerBfdMultiplier(original["multiplier"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedMultiplier); val.IsValid() && !isEmptyValue(val) {
transformed["multiplier"] = transformedMultiplier
}

return transformed, nil
}

func expandNestedComputeRouterBgpPeerBfdSessionInitializationMode(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandNestedComputeRouterBgpPeerBfdMinTransmitInterval(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandNestedComputeRouterBgpPeerBfdMinReceiveInterval(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandNestedComputeRouterBgpPeerBfdMultiplier(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandNestedComputeRouterBgpPeerEnable(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
if v == nil {
return nil, nil
Expand Down
Loading

0 comments on commit bbba281

Please sign in to comment.