Query prefixes once for all hosts
And group them into vrf_prefixes for VLAN networks and bgp_prefixes for servers plugged directly into fabric. This should reduce the number of queries to NetBox when configuring firewalls and exit switches. Not sure but I think set_fact helps to avoid queries (as opposed to setting group_vars).
This commit is contained in:
parent
1c0709a6a6
commit
457ab7d3b7
|
@ -1 +0,0 @@
|
|||
vlans: "{{ query('netbox.netbox.nb_lookup', 'vlans', api_filter='group=new-net', raw_data=true) | sort(attribute='vid') }}"
|
|
@ -213,17 +213,15 @@ ipv6 prefix-list default permit ::/0
|
|||
ip prefix-list fabric permit 10.34.0.0/24 ge 32
|
||||
ipv6 prefix-list fabric permit 2001:1470:fffd:3400::/64 ge 128
|
||||
|
||||
{% for vrf in inside_vrfs %}
|
||||
{% set prefixes = query('netbox.netbox.nb_lookup', 'prefixes', api_filter='vrf_id='~vrf.id, raw_data=true)
|
||||
| sort(attribute='family.value') %}
|
||||
{% for prefix in prefixes %}
|
||||
{% for prefix in vrf_prefixes
|
||||
| selectattr('vrf.id', 'in', inside_vrfs|map(attribute='id'))
|
||||
| sort(attribute='family.value') | sort(attribute='vlan.vid') %}
|
||||
{% if prefix.family.value == 4 %}
|
||||
ip prefix-list office permit {{ prefix.prefix }} ge 24
|
||||
{% else %}
|
||||
ipv6 prefix-list office permit {{ prefix.prefix }} ge 64
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% if wg_net is defined %}
|
||||
ip prefix-list vpn permit {{ wg_net | ipaddr('subnet') }}
|
||||
|
@ -237,7 +235,7 @@ ip prefix-list nat permit {{ wg_ip | ipaddr('host') }}
|
|||
ip prefix-list nat permit {{ network }}
|
||||
{% endfor %}
|
||||
|
||||
{% for prefix in query('netbox.netbox.nb_lookup', 'prefixes', raw_data=true, api_filter='role=bgp') | selectattr('tenant') %}
|
||||
{% for prefix in bgp_prefixes | sort(attribute='family.value') %}
|
||||
{% if prefix.family.value == 4 %}
|
||||
ip prefix-list dc permit {{ prefix.prefix }} ge 32
|
||||
{% else %}
|
||||
|
@ -281,7 +279,7 @@ route-map inside-import permit 21
|
|||
match ipv6 address prefix-list office
|
||||
|
||||
# Route maps for advertised and received routes.
|
||||
# Inside ↔ fabric.
|
||||
# Default VRF ↔ fabric.
|
||||
route-map default->fabric permit 10
|
||||
match ip address prefix-list default
|
||||
route-map default->fabric permit 11
|
||||
|
@ -296,7 +294,7 @@ route-map fabric->default permit 20
|
|||
route-map fabric->default permit 21
|
||||
match ipv6 address prefix-list dc
|
||||
|
||||
# Inside ↔ firewall.
|
||||
# Inside VRF ↔ firewall.
|
||||
route-map inside->firewall permit 1
|
||||
match interface lo
|
||||
route-map inside->firewall permit 20
|
||||
|
@ -313,7 +311,7 @@ route-map firewall->inside permit 10
|
|||
route-map firewall->inside permit 11
|
||||
match ipv6 address prefix-list default
|
||||
|
||||
# Outside ↔ firewall.
|
||||
# Outside VRF ↔ firewall.
|
||||
route-map outside->firewall permit 10
|
||||
match ip address prefix-list default
|
||||
route-map outside->firewall permit 11
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% set dhcp_networks = query('netbox.netbox.nb_lookup', 'prefixes', api_filter='role=dhcp-pool', raw_data=true)
|
||||
| selectattr('vlan') | map(attribute='vlan.vid') | sort -%}
|
||||
{% set dhcp_vlans = vrf_prefixes | selectattr('custom_fields.dhcp_ranges')
|
||||
| map(attribute='vlan.vid') | sort -%}
|
||||
|
||||
# What servers should the DHCP relay forward requests to?
|
||||
SERVERS="{{ dhcp }}"
|
||||
|
@ -10,7 +10,7 @@ SERVERS="{{ dhcp }}"
|
|||
# This will be used in the actual dhcrelay command
|
||||
# For example, "-i eth0 -i eth1"
|
||||
INTF_CMD="{{ interfaces | selectattr('parent') | selectattr('parent.name', '==', 'bridge')
|
||||
| selectattr('untagged_vlan') | selectattr('untagged_vlan.vid', 'in', dhcp_networks)
|
||||
| selectattr('untagged_vlan') | selectattr('untagged_vlan.vid', 'in', dhcp_vlans)
|
||||
| map(attribute='name') | sort | map('regex_replace', '^', '-id ') | join(' ') }} -iu {{ iface_uplink }} -iu peerlink.4"
|
||||
|
||||
# Additional options that are passed to the DHCP relay daemon?
|
||||
|
|
16
roles/facts/tasks/main.yml
Normal file
16
roles/facts/tasks/main.yml
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Make expensive lookups to NetBox once for later reference by any host.
|
||||
- name: Lookup networks and prefixes
|
||||
set_fact:
|
||||
vlans: '{{ query("netbox.netbox.nb_lookup", "vlans", api_filter="group=new-net", raw_data=true)
|
||||
| sort(attribute="vid") }}'
|
||||
prefixes: '{{ query("netbox.netbox.nb_lookup", "prefixes", raw_data=true)
|
||||
| sort(attribute="prefix") | sort(attribute="family.value") }}'
|
||||
|
||||
- name: Select VLAN and BGP prefixes
|
||||
set_fact:
|
||||
vrf_prefixes: '{{ prefixes | selectattr("vrf")
|
||||
| selectattr("vlan") | selectattr("vlan.id", "in", vlans|map(attribute="id"))
|
||||
| sort(attribute="vlan.vid") }}'
|
||||
bgp_prefixes: '{{ prefixes | selectattr("tenant")
|
||||
| selectattr("role") | selectattr("role.slug", "==", "bgp")
|
||||
| sort(attribute="tenant.slug") }}'
|
|
@ -82,16 +82,13 @@ ipv6 prefix-list default permit ::/0
|
|||
|
||||
ip prefix-list fabric permit 10.34.0.0/24 ge 32
|
||||
|
||||
{% for vlan in vlans %}
|
||||
{% for prefix in query('netbox.netbox.nb_lookup', 'prefixes', api_filter='vlan_id='~vlan.id, raw_data=true) %}
|
||||
{% if prefix.vrf and prefix.vrf.name != 'outside' %}
|
||||
{% for prefix in vrf_prefixes | rejectattr('vrf.name', '==', 'outside')
|
||||
| sort(attribute='family.value') %}
|
||||
{% if prefix.family.value == 4 %}
|
||||
ip prefix-list office permit {{ prefix.prefix }} ge 24
|
||||
{% elif prefix.family.value == 6 %}
|
||||
ipv6 prefix-list office permit {{ prefix.prefix }} ge 64
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% if wg_net is defined %}
|
||||
|
|
|
@ -1,18 +1,9 @@
|
|||
{% for vlan in vlans %}
|
||||
{% set prefixes = query('netbox.netbox.nb_lookup', 'prefixes', api_filter='vlan_id='~vlan.id, raw_data=true) %}
|
||||
{% set prefixes4 = prefixes | selectattr('family.value', '==', 4) | map(attribute='prefix') %}
|
||||
{% set prefixes6 = prefixes | selectattr('family.value', '==', 6) | map(attribute='prefix') %}
|
||||
set {{ vlan.name }} {
|
||||
type ipv4_addr; flags interval
|
||||
{% if prefixes4 %}
|
||||
elements = { {{ prefixes4 | join(', ') }} }
|
||||
{% endif %}
|
||||
}
|
||||
set {{ vlan.name }}/6 {
|
||||
type ipv6_addr; flags interval
|
||||
{% if prefixes6 %}
|
||||
elements = { {{ prefixes6 | join(', ') }} }
|
||||
{% endif %}
|
||||
{% for family, family_prefixes in vrf_prefixes | groupby('family.value') %}
|
||||
{% for vlan, vlan_prefixes in family_prefixes | groupby('vlan.vid') %}
|
||||
set {{ vlan_prefixes[0].vlan.name }}{% if family == 6 %}/6{% endif %} {
|
||||
type ipv{{ family }}_addr; flags interval
|
||||
elements = { {{ vlan_prefixes | map(attribute='prefix') | join(',') }} }
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
|
|
|
@ -81,13 +81,13 @@ table inet filter {
|
|||
comment "Forward DNAT traffic for servers and suchlike"
|
||||
|
||||
# Forward IPv4 to/from VPN users in the same network.
|
||||
{% for vlan in vlans %}
|
||||
iif @inside ip saddr @{{ vlan.name }} ip daddr @{{ vlan.name }} accept
|
||||
{% for vlan in vrf_prefixes | selectattr('family.value', '==', 4) | map(attribute='vlan.name') | unique %}
|
||||
iif @inside ip saddr @{{ vlan }} ip daddr @{{ vlan }} accept
|
||||
{% endfor %}
|
||||
|
||||
# Forward IPv6 to/from VPN users in the same network.
|
||||
{% for vlan in vlans %}
|
||||
iif @inside ip6 saddr @{{ vlan.name }}/6 ip6 daddr @{{ vlan.name }}/6 accept
|
||||
{% for vlan in vrf_prefixes | selectattr('family.value', '==', 6) | map(attribute='vlan.name') | unique %}
|
||||
iif @inside ip6 saddr @{{ vlan }}/6 ip6 daddr @{{ vlan }}/6 accept
|
||||
{% endfor %}
|
||||
|
||||
include "/etc/nftables.d/forward.nft*"
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
{% set prefixes = query('netbox.netbox.nb_lookup', 'prefixes', raw_data=true) -%}
|
||||
|
||||
{
|
||||
{% for vlan in vlans %}
|
||||
{% set vlan_prefixes = prefixes | selectattr('vlan') | selectattr('vlan.id', '==', vlan.id) | map(attribute='prefix') %}
|
||||
"{{ vlan.name }}": {
|
||||
"ip": {{ vlan_prefixes | ipv4 | to_json }},
|
||||
"ip6": {{ vlan_prefixes | ipv6 | to_json }}
|
||||
{% for vlan, addrs in vrf_prefixes | groupby('vlan.vid') %}
|
||||
"{{ addrs[0].vlan.name }}": {
|
||||
"ip": {{ addrs | selectattr('family.value', '==', 4) | map(attribute='prefix') | to_json }},
|
||||
"ip6": {{ addrs | selectattr('family.value', '==', 6) | map(attribute='prefix') | to_json }}
|
||||
}{% if not loop.last %},{% endif +%}
|
||||
{% endfor %}
|
||||
}
|
||||
|
|
|
@ -78,16 +78,13 @@ route-map loopbacks permit 10
|
|||
ip prefix-list default permit 0.0.0.0/0
|
||||
ipv6 prefix-list default permit ::/0
|
||||
|
||||
{% for tenant in my_tenants %}
|
||||
{% for prefix in query('netbox.netbox.nb_lookup', 'prefixes', raw_data=true, api_filter='tenant='~tenant)
|
||||
| selectattr('role') | selectattr('role.slug', '==', 'bgp') | rejectattr('vlan') %}
|
||||
{% for prefix in bgp_prefixes | selectattr('tenant.slug', 'in', my_tenants) %}
|
||||
{% if prefix.family.value == 4 %}
|
||||
ip prefix-list dc-{{ tenant }} permit {{ prefix.prefix }} ge 32
|
||||
ip prefix-list dc-{{ prefix.tenant.slug }} permit {{ prefix.prefix }} ge 32
|
||||
{% else %}
|
||||
ipv6 prefix-list dc-{{ tenant }} permit {{ prefix.prefix }} ge 64
|
||||
ipv6 prefix-list dc-{{ prefix.tenant.slug }} permit {{ prefix.prefix }} ge 64
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
# We only announce the default route to DC servers.
|
||||
route-map default->dc permit 10
|
||||
|
|
Loading…
Reference in a new issue