Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support MicroBFD #102

Merged
merged 4 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 54 additions & 46 deletions aci_tenants.tf
Original file line number Diff line number Diff line change
Expand Up @@ -1164,6 +1164,8 @@ locals {
elag = try(path.elag, null)
floating_ip = path.floating_ip
}]
micro_bfd_destination_ip = try(int.micro_bfd.destination_ip, null)
micro_bfd_start_timer = try(int.micro_bfd.start_timer, null)
}]
}
]
Expand Down Expand Up @@ -1196,29 +1198,31 @@ module "aci_l3out_interface_profile_manual" {
qos_class = each.value.qos_class
custom_qos_policy = each.value.custom_qos_policy
interfaces = [for int in try(each.value.interfaces, []) : {
ip = int.ip
svi = int.svi
floating_svi = int.floating_svi
autostate = int.autostate
vlan = int.vlan
description = int.description
type = int.type
mac = int.mac
mtu = int.mtu
mode = int.mode
node_id = int.node_id
node2_id = int.node2_id == "vpc" ? [for pg in local.leaf_interface_policy_group_mapping : try(pg.node_ids, []) if pg.name == int.channel][0][1] : int.node2_id
pod_id = int.pod_id == null ? try([for node in local.node_policies.nodes : node.pod if node.id == int.node_id][0], local.defaults.apic.tenants.l3outs.node_profiles.interface_profiles.interfaces.pod) : int.pod_id
module = int.module
port = int.port
channel = int.channel
ip_a = int.ip_a
ip_b = int.ip_b
ip_shared = int.ip_shared
bgp_peers = int.bgp_peers
paths = int.paths
scope = int.scope
multipod_direct = int.multipod_direct
ip = int.ip
svi = int.svi
floating_svi = int.floating_svi
autostate = int.autostate
vlan = int.vlan
description = int.description
type = int.type
mac = int.mac
mtu = int.mtu
mode = int.mode
node_id = int.node_id
node2_id = int.node2_id == "vpc" ? [for pg in local.leaf_interface_policy_group_mapping : try(pg.node_ids, []) if pg.name == int.channel][0][1] : int.node2_id
pod_id = int.pod_id == null ? try([for node in local.node_policies.nodes : node.pod if node.id == int.node_id][0], local.defaults.apic.tenants.l3outs.node_profiles.interface_profiles.interfaces.pod) : int.pod_id
module = int.module
port = int.port
channel = int.channel
ip_a = int.ip_a
ip_b = int.ip_b
ip_shared = int.ip_shared
bgp_peers = int.bgp_peers
paths = int.paths
scope = int.scope
multipod_direct = int.multipod_direct
micro_bfd_destination_ip = int.micro_bfd_destination_ip
micro_bfd_start_timer = int.micro_bfd_start_timer
}]

depends_on = [
Expand Down Expand Up @@ -1307,6 +1311,8 @@ locals {
elag = try(path.elag, null)
floating_ip = path.floating_ip
}]
micro_bfd_destination_ip = try(int.micro_bfd.destination_ip, null)
micro_bfd_start_timer = try(int.micro_bfd.start_timer, null)
}
]])
} if length(try(l3out.nodes, [])) != 0
Expand Down Expand Up @@ -1337,29 +1343,31 @@ module "aci_l3out_interface_profile_auto" {
qos_class = each.value.qos_class
custom_qos_policy = each.value.custom_qos_policy
interfaces = [for int in try(each.value.interfaces, []) : {
ip = int.ip
svi = int.svi
autostate = int.autostate
floating_svi = int.floating_svi
vlan = int.vlan
description = int.description
type = int.type
mac = int.mac
mtu = int.mtu
mode = int.mode
node_id = int.node_id
node2_id = int.node2_id == "vpc" ? [for pg in local.leaf_interface_policy_group_mapping : try(pg.node_ids, []) if pg.name == int.channel][0][1] : int.node2_id
pod_id = int.pod_id
module = int.module
port = int.port
channel = int.channel
ip_a = int.ip_a
ip_b = int.ip_b
ip_shared = int.ip_shared
bgp_peers = int.bgp_peers
paths = int.paths
scope = int.scope
multipod_direct = int.multipod_direct
ip = int.ip
svi = int.svi
autostate = int.autostate
floating_svi = int.floating_svi
vlan = int.vlan
description = int.description
type = int.type
mac = int.mac
mtu = int.mtu
mode = int.mode
node_id = int.node_id
node2_id = int.node2_id == "vpc" ? [for pg in local.leaf_interface_policy_group_mapping : try(pg.node_ids, []) if pg.name == int.channel][0][1] : int.node2_id
pod_id = int.pod_id
module = int.module
port = int.port
channel = int.channel
ip_a = int.ip_a
ip_b = int.ip_b
ip_shared = int.ip_shared
bgp_peers = int.bgp_peers
paths = int.paths
scope = int.scope
multipod_direct = int.multipod_direct
micro_bfd_destination_ip = int.micro_bfd_destination_ip
micro_bfd_start_timer = int.micro_bfd_start_timer
}]

depends_on = [
Expand Down
3 changes: 2 additions & 1 deletion modules/terraform-aci-l3out-interface-profile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ module "aci_l3out_interface_profile" {
| <a name="input_igmp_interface_policy"></a> [igmp\_interface\_policy](#input\_igmp\_interface\_policy) | IGMP interface policy name. | `string` | `""` | no |
| <a name="input_qos_class"></a> [qos\_class](#input\_qos\_class) | QoS class. Choices: `level1`, `level2`, `level3`, `level4`, `level5`, `level6`, `unspecified`. | `string` | `"unspecified"` | no |
| <a name="input_custom_qos_policy"></a> [custom\_qos\_policy](#input\_custom\_qos\_policy) | Custom QoS policy name. | `string` | `""` | no |
| <a name="input_interfaces"></a> [interfaces](#input\_interfaces) | List of interfaces. Default value `svi`: false. Default value `floating_svi`: false. Choices `type`. `access`, `pc`, `vpc`. Default value `type`: `access`. Allowed values `vlan`: 1-4096. Format `mac`: `12:34:56:78:9A:BC`. `mtu`: Allowed values are `inherit` or a number between 576 and 9216. Allowed values `node_id`, `node2_id`: 1-4000. Allowed values `pod_id`: 1-255. Default value `pod_id`: 1. Allowed values `module`: 1-9. Default value `module`: 1. Allowed values `port`: 1-127. Default value `bgp_peers.bfd`: false. Allowed values `bgp_peers.ttl`: 1-255. Default value `bgp_peers.ttl`: 1. Allowed values `bgp_peers.weight`: 0-65535. Default value `bgp_peers.weight`: 0. Allowed values `bgp_peers.remote_as`: 0-4294967295. | <pre>list(object({<br> description = optional(string, "")<br> type = optional(string, "access")<br> node_id = number<br> node2_id = optional(number)<br> pod_id = optional(number, 1)<br> module = optional(number, 1)<br> port = optional(number)<br> channel = optional(string)<br> ip = optional(string)<br> svi = optional(bool, false)<br> autostate = optional(bool, false)<br> floating_svi = optional(bool, false)<br> vlan = optional(number)<br> mac = optional(string, "00:22:BD:F8:19:FF")<br> mtu = optional(string, "inherit")<br> mode = optional(string, "regular")<br> ip_a = optional(string)<br> ip_b = optional(string)<br> ip_shared = optional(string)<br> scope = optional(string, "local")<br> multipod_direct = optional(bool, false)<br> bgp_peers = optional(list(object({<br> ip = string<br> remote_as = string<br> description = optional(string, "")<br> allow_self_as = optional(bool, false)<br> as_override = optional(bool, false)<br> disable_peer_as_check = optional(bool, false)<br> next_hop_self = optional(bool, false)<br> send_community = optional(bool, false)<br> send_ext_community = optional(bool, false)<br> password = optional(string)<br> allowed_self_as_count = optional(number, 3)<br> bfd = optional(bool, false)<br> disable_connected_check = optional(bool, false)<br> ttl = optional(number, 1)<br> weight = optional(number, 0)<br> remove_all_private_as = optional(bool, false)<br> remove_private_as = optional(bool, false)<br> replace_private_as_with_local_as = optional(bool, false)<br> unicast_address_family = optional(bool, true)<br> multicast_address_family = optional(bool, true)<br> admin_state = optional(bool, true)<br> local_as = optional(number)<br> as_propagate = optional(string, "none")<br> peer_prefix_policy = optional(string)<br> export_route_control = optional(string)<br> import_route_control = optional(string)<br> })), [])<br> paths = optional(list(object({<br> physical_domain = optional(string)<br> vmware_vmm_domain = optional(string)<br> elag = optional(string)<br> floating_ip = string<br> })), [])<br> }))</pre> | `[]` | no |
| <a name="input_interfaces"></a> [interfaces](#input\_interfaces) | List of interfaces. Default value `svi`: false. Default value `floating_svi`: false. Choices `type`. `access`, `pc`, `vpc`. Default value `type`: `access`. Allowed values `vlan`: 1-4096. Format `mac`: `12:34:56:78:9A:BC`. `mtu`: Allowed values are `inherit` or a number between 576 and 9216. Allowed values `node_id`, `node2_id`: 1-4000. Allowed values `pod_id`: 1-255. Default value `pod_id`: 1. Allowed values `module`: 1-9. Default value `module`: 1. Allowed values `port`: 1-127. Default value `bgp_peers.bfd`: false. Allowed values `bgp_peers.ttl`: 1-255. Default value `bgp_peers.ttl`: 1. Allowed values `bgp_peers.weight`: 0-65535. Default value `bgp_peers.weight`: 0. Allowed values `bgp_peers.remote_as`: 0-4294967295. | <pre>list(object({<br> description = optional(string, "")<br> type = optional(string, "access")<br> node_id = number<br> node2_id = optional(number)<br> pod_id = optional(number, 1)<br> module = optional(number, 1)<br> port = optional(number)<br> channel = optional(string)<br> ip = optional(string)<br> svi = optional(bool, false)<br> autostate = optional(bool, false)<br> floating_svi = optional(bool, false)<br> vlan = optional(number)<br> mac = optional(string, "00:22:BD:F8:19:FF")<br> mtu = optional(string, "inherit")<br> mode = optional(string, "regular")<br> ip_a = optional(string)<br> ip_b = optional(string)<br> ip_shared = optional(string)<br> scope = optional(string, "local")<br> multipod_direct = optional(bool, false)<br> bgp_peers = optional(list(object({<br> ip = string<br> remote_as = string<br> description = optional(string, "")<br> allow_self_as = optional(bool, false)<br> as_override = optional(bool, false)<br> disable_peer_as_check = optional(bool, false)<br> next_hop_self = optional(bool, false)<br> send_community = optional(bool, false)<br> send_ext_community = optional(bool, false)<br> password = optional(string)<br> allowed_self_as_count = optional(number, 3)<br> bfd = optional(bool, false)<br> disable_connected_check = optional(bool, false)<br> ttl = optional(number, 1)<br> weight = optional(number, 0)<br> remove_all_private_as = optional(bool, false)<br> remove_private_as = optional(bool, false)<br> replace_private_as_with_local_as = optional(bool, false)<br> unicast_address_family = optional(bool, true)<br> multicast_address_family = optional(bool, true)<br> admin_state = optional(bool, true)<br> local_as = optional(number)<br> as_propagate = optional(string, "none")<br> peer_prefix_policy = optional(string)<br> export_route_control = optional(string)<br> import_route_control = optional(string)<br> })), [])<br> paths = optional(list(object({<br> physical_domain = optional(string)<br> vmware_vmm_domain = optional(string)<br> elag = optional(string)<br> floating_ip = string<br> })), [])<br> micro_bfd_destination_ip = optional(string, "")<br> micro_bfd_start_timer = optional(number, 0)<br> }))</pre> | `[]` | no |
| <a name="input_multipod"></a> [multipod](#input\_multipod) | Multipod L3out flag. | `bool` | `false` | no |
| <a name="input_remote_leaf"></a> [remote\_leaf](#input\_remote\_leaf) | Remote leaf L3out flag. | `bool` | `false` | no |
| <a name="input_sr_mpls"></a> [sr\_mpls](#input\_sr\_mpls) | SR MPLS L3out flag. | `bool` | `false` | no |
Expand All @@ -128,6 +128,7 @@ module "aci_l3out_interface_profile" {
| Name | Type |
|------|------|
| [aci_rest_managed.bfdIfP](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.bfdMicroBfdP](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.bfdRsIfPol](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.bgpAsP](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.bgpAsP_floating](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
Expand Down
55 changes: 34 additions & 21 deletions modules/terraform-aci-l3out-interface-profile/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,29 @@ locals {
for int in var.interfaces : {
key = int.type == "vpc" ? "topology/pod-${int.pod_id}/protpaths-${int.node_id}-${int.node2_id}/pathep-[${int.channel}]" : (int.type == "pc" ? "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[${int.channel}]" : "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[eth${int.module}/${int.port}]")
value = {
ip = int.type != "vpc" ? int.ip : "0.0.0.0"
svi = int.svi == true ? "yes" : "no"
description = int.description
type = int.type
vlan = int.vlan
autostate = int.autostate ? "enabled" : "disabled"
mac = int.mac
mode = int.mode
mtu = int.mtu
node_id = int.node_id
node2_id = int.node2_id
module = int.module
pod_id = int.pod_id
port = int.port
channel = int.channel
ip_a = int.ip_a
ip_b = int.ip_b
ip_shared = int.ip_shared
tDn = int.type == "vpc" ? "topology/pod-${int.pod_id}/protpaths-${int.node_id}-${int.node2_id}/pathep-[${int.channel}]" : (int.type == "pc" ? "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[${int.channel}]" : "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[eth${int.module}/${int.port}]")
multipod_direct = int.multipod_direct
scope = int.scope
ip = int.type != "vpc" ? int.ip : "0.0.0.0"
svi = int.svi == true ? "yes" : "no"
description = int.description
type = int.type
vlan = int.vlan
autostate = int.autostate ? "enabled" : "disabled"
mac = int.mac
mode = int.mode
mtu = int.mtu
node_id = int.node_id
node2_id = int.node2_id
module = int.module
pod_id = int.pod_id
port = int.port
channel = int.channel
ip_a = int.ip_a
ip_b = int.ip_b
ip_shared = int.ip_shared
tDn = int.type == "vpc" ? "topology/pod-${int.pod_id}/protpaths-${int.node_id}-${int.node2_id}/pathep-[${int.channel}]" : (int.type == "pc" ? "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[${int.channel}]" : "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[eth${int.module}/${int.port}]")
multipod_direct = int.multipod_direct
scope = int.scope
micro_bfd_destination_ip = int.micro_bfd_destination_ip
micro_bfd_start_timer = int.micro_bfd_start_timer
}
} if int.floating_svi == false
])
Expand Down Expand Up @@ -326,6 +328,17 @@ resource "aci_rest_managed" "l3extIp_B" {
}
}

resource "aci_rest_managed" "bfdMicroBfdP" {
for_each = { for item in local.interfaces : item.key => item.value if item.value.micro_bfd_destination_ip != "" && item.value.micro_bfd_destination_ip != null }
dn = "${aci_rest_managed.l3extRsPathL3OutAtt[each.key].dn}/microBfdP"
class_name = "bfdMicroBfdP"
content = {
adminState = "yes"
dst = each.value.micro_bfd_destination_ip
stTm = each.value.micro_bfd_start_timer
}
}

resource "aci_rest_managed" "l3extVirtualLIfP" {
for_each = { for item in local.floating_interfaces : item.key => item.value }
dn = "${aci_rest_managed.l3extLIfP.dn}/vlifp-[topology/pod-${each.value.pod_id}/node-${each.value.node_id}]-[vlan-${each.value.vlan}]"
Expand Down
9 changes: 9 additions & 0 deletions modules/terraform-aci-l3out-interface-profile/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ variable "interfaces" {
elag = optional(string)
floating_ip = string
})), [])
micro_bfd_destination_ip = optional(string, "")
micro_bfd_start_timer = optional(number, 0)
}))
default = []

Expand Down Expand Up @@ -398,6 +400,13 @@ variable "interfaces" {
]))
error_message = "`paths.elag`: Allowed characters: `a`-`z`, `A`-`Z`, `0`-`9`, `_`, `.`, `:`, `-`. Maximum characters: 64."
}

validation {
condition = alltrue([
for i in var.interfaces : i.micro_bfd_start_timer == null || try(i.micro_bfd_start_timer == 0 || try(i.micro_bfd_start_timer >= 60 && i.micro_bfd_start_timer <= 3600, false), false)
])
error_message = "`interfaces.micro_bfd_start_timer`: Minimum value: `60`. Maximum value: `3600`."
}
}

variable "multipod" {
Expand Down