Compare commits
2 commits
bb41d406f8
...
82b10e8133
Author | SHA1 | Date | |
---|---|---|---|
Timotej Lazar | 82b10e8133 | ||
Timotej Lazar | 99aef43574 |
14
filter_plugins/util.py
Normal file
14
filter_plugins/util.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
class FilterModule(object):
|
||||
'''Helper filters to make Ansible less unpleasant'''
|
||||
def filters(self):
|
||||
return {
|
||||
'list2dict': self.list2dict,
|
||||
}
|
||||
|
||||
def list2dict(self, items, key):
|
||||
'''
|
||||
Like items2dict but keep entire dictionaries as values.
|
||||
'''
|
||||
return {item[key]: item for item in items}
|
|
@ -13,3 +13,4 @@ query_filters:
|
|||
- role: 'compute-node'
|
||||
- role: 'firewall'
|
||||
- role: 'switch'
|
||||
- role: 'server'
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
class="${1}"
|
||||
name="${2}"
|
||||
state="${3}"
|
||||
|
||||
case "${state}" in
|
||||
"MASTER" | "FAULT")
|
||||
systemctl start "${name}"
|
||||
;;
|
||||
"BACKUP" | "STOP")
|
||||
systemctl stop "${name}"
|
||||
;;
|
||||
*)
|
||||
logger "keepalived unknown state for ${name}: ${state}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
|
@ -1,16 +1,17 @@
|
|||
# TODO rewrite task and templates into something sane once the old DHCP server is retired
|
||||
- set_fact:
|
||||
dhcp_servers: '{{ prefixes | selectattr("custom_fields.dhcp_server") | groupby(attribute="custom_fields.dhcp_server.address") }}'
|
||||
|
||||
- name: Install keepalived
|
||||
import_tasks: keepalived.yml
|
||||
|
||||
- name: Create keepalive notify script for systemd services
|
||||
copy:
|
||||
dest: /usr/local/bin/
|
||||
src: keepalive-service
|
||||
mode: 0755
|
||||
|
||||
- name: Configure DHCP relays
|
||||
template:
|
||||
dest: "/etc/default/isc-dhcp-relay"
|
||||
dest: '/etc/default/isc-dhcp-relay-{{ prefixes | selectattr("prefix", "==", item.0 | ipaddr("network/prefix")) | map(attribute="vrf.name") | first }}'
|
||||
src: isc-dhcp-relay.j2
|
||||
loop: '{{ dhcp_servers }}'
|
||||
loop_control:
|
||||
label: "{{ item.0 }}"
|
||||
notify: restart keepalived
|
||||
|
||||
- name: Set up keepalived
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
| selectattr('role') | selectattr('role.value', '==', 'loopback')
|
||||
| map(attribute='address') %}
|
||||
{% set inside_vrfs = interfaces | selectattr('parent') | selectattr('parent.name', '==', 'bridge')
|
||||
| selectattr('vrf') | map(attribute='vrf') | rejectattr('name', '==', 'outside') -%}
|
||||
| selectattr('vrf') | map(attribute='vrf.name') | reject('==', 'outside') | sort %}
|
||||
|
||||
frr defaults datacenter
|
||||
log syslog informational
|
||||
|
@ -158,7 +158,7 @@ router bgp {{ asn.asn }} vrf inside
|
|||
|
||||
redistribute connected route-map loopback-inside
|
||||
{% for vrf in inside_vrfs %}
|
||||
import vrf {{ vrf.name }}
|
||||
import vrf {{ vrf }}
|
||||
{% endfor %}
|
||||
import vrf default
|
||||
import vrf route-map inside-import
|
||||
|
@ -180,14 +180,14 @@ router bgp {{ asn.asn }} vrf inside
|
|||
|
||||
redistribute connected route-map loopback-inside
|
||||
{% for vrf in inside_vrfs %}
|
||||
import vrf {{ vrf.name }}
|
||||
import vrf {{ vrf }}
|
||||
{% endfor %}
|
||||
import vrf default
|
||||
import vrf route-map inside-import
|
||||
exit-address-family
|
||||
|
||||
|
||||
{% for vrf in inside_vrfs %}
|
||||
{% for vrf in vrfs.values() | selectattr('name', 'in', inside_vrfs) %}
|
||||
# VRF for L2 network {{ vrf.name }}. Imports gateway from inside VRF.
|
||||
router bgp {{ asn.asn }} vrf {{ vrf.name }}
|
||||
bgp bestpath as-path multipath-relax
|
||||
|
@ -195,13 +195,27 @@ router bgp {{ asn.asn }} vrf {{ vrf.name }}
|
|||
address-family ipv4 unicast
|
||||
redistribute connected
|
||||
import vrf inside
|
||||
{% if vrf.custom_fields.imports %}
|
||||
{% for import in vrf.custom_fields.imports %}
|
||||
import vrf {{ import.name }}
|
||||
{% endfor %}
|
||||
import vrf route-map {{ vrf.name }}-import
|
||||
{% else %}
|
||||
import vrf route-map office-import
|
||||
{% endif %}
|
||||
exit-address-family
|
||||
|
||||
address-family ipv6 unicast
|
||||
redistribute connected
|
||||
import vrf inside
|
||||
{% if vrf.custom_fields.imports %}
|
||||
{% for import in vrf.custom_fields.imports %}
|
||||
import vrf {{ import.name }}
|
||||
{% endfor %}
|
||||
import vrf route-map {{ vrf.name }}-import
|
||||
{% else %}
|
||||
import vrf route-map office-import
|
||||
{% endif %}
|
||||
exit-address-family
|
||||
|
||||
{% endfor %}
|
||||
|
@ -213,8 +227,8 @@ 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 prefix in vrf_prefixes
|
||||
| selectattr('vrf.id', 'in', inside_vrfs|map(attribute='id'))
|
||||
# common prefix list for all inside networks
|
||||
{% for prefix in vrf_prefixes | selectattr('vrf.name', 'in', inside_vrfs)
|
||||
| sort(attribute='family.value') | sort(attribute='vlan.vid') %}
|
||||
{% if prefix.family.value == 4 %}
|
||||
ip prefix-list office permit {{ prefix.prefix }} ge {{ prefix.prefix | ipaddr('prefix') }}
|
||||
|
@ -223,6 +237,16 @@ ipv6 prefix-list office permit {{ prefix.prefix }} ge {{ prefix.prefix | ipaddr(
|
|||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
# individual prefix lists for each inside network
|
||||
{% for prefix in vrf_prefixes | selectattr('vrf.name', 'in', inside_vrfs)
|
||||
| sort(attribute='family.value') | sort(attribute='vlan.vid') %}
|
||||
{% if prefix.family.value == 4 %}
|
||||
ip prefix-list {{ prefix.vrf.name }} permit {{ prefix.prefix }} ge {{ prefix.prefix | ipaddr('prefix') }}
|
||||
{% else %}
|
||||
ipv6 prefix-list {{ prefix.vrf.name }} permit {{ prefix.prefix }} ge {{ prefix.prefix | ipaddr('prefix') }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if wg_net is defined %}
|
||||
ip prefix-list vpn permit {{ wg_net | ipaddr('subnet') }}
|
||||
{% endif %}
|
||||
|
@ -278,6 +302,20 @@ route-map inside-import permit 20
|
|||
route-map inside-import permit 21
|
||||
match ipv6 address prefix-list office
|
||||
|
||||
{% for vrf in vrfs.values() | selectattr('custom_fields.imports') %}
|
||||
route-map {{ vrf.name }}-import permit 10
|
||||
match ip address prefix-list default
|
||||
route-map {{ vrf.name }}-import permit 11
|
||||
match ipv6 address prefix-list default
|
||||
{% for import in vrf.custom_fields.imports %}
|
||||
route-map {{ vrf.name }}-import permit {{ 100 + 10*loop.index0 }}
|
||||
match ip address prefix-list {{ import.name }}
|
||||
route-map {{ vrf.name }}-import permit {{ 101 + 10*loop.index0 }}
|
||||
match ipv6 address prefix-list {{ import.name }}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
# Route maps for advertised and received routes.
|
||||
# Default VRF ↔ fabric.
|
||||
route-map default->fabric permit 10
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
{% set dhcp_vlans = vrf_prefixes | selectattr('custom_fields.dhcp_ranges')
|
||||
| map(attribute='vlan.vid') | sort -%}
|
||||
{% set my_server = item.0 %}
|
||||
{% set my_vlans = item.1 | map(attribute='vlan.vid') | sort %}
|
||||
{% set my_prefix = prefixes | selectattr("prefix", "==", my_server | ipaddr("network/prefix")) | first -%}
|
||||
|
||||
# What servers should the DHCP relay forward requests to?
|
||||
SERVERS="{{ dhcp }}"
|
||||
|
||||
# On what interfaces should the DHCP relay (dhrelay) serve DHCP requests?
|
||||
# Always include the interface towards the DHCP server.
|
||||
# This variable requires a -i for each interface configured above.
|
||||
# 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_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?
|
||||
OPTIONS="-U outside"
|
||||
SERVERS="{{ my_server | ipaddr('address') }}"
|
||||
{% if my_prefix.vrf.name == 'outside' %}
|
||||
INTF_CMD="{{ my_vlans | map('regex_replace', '^', '-id bridge.') | join(' ') }} -iu {{ iface_uplink }} -iu peerlink.4 -U {{ my_prefix.vrf.name }}"
|
||||
OPTIONS=""
|
||||
{% else %}
|
||||
INTF_CMD="{{ my_vlans | map('regex_replace', '^', '-id bridge.') | join(' ') }} -U bridge.{{ my_prefix.vlan.vid }}"
|
||||
OPTIONS="--giaddr-src"
|
||||
{% endif %}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
{% set dhcrelays = prefixes | selectattr('prefix', 'in', dhcp_servers | map('first') | ipaddr("network/prefix"))
|
||||
| map(attribute="vrf.name") | map('regex_replace', '^', 'dhcrelay@') %}
|
||||
{% set exits = [inventory_hostname, peer]|sort -%}
|
||||
|
||||
global_defs {
|
||||
|
@ -18,5 +20,8 @@ vrrp_instance dhcrelay {
|
|||
@^{{ exit }} {{ "169.254.1.0/24" | ipaddr(loop.index + 1) | ipaddr('address') }}
|
||||
{% endfor %}
|
||||
}
|
||||
notify /usr/local/bin/keepalive-service
|
||||
notify_master "systemctl start {{ dhcrelays | join(' ') }}"
|
||||
notify_fault "systemctl start {{ dhcrelays | join(' ') }}"
|
||||
notify_backup "systemctl stop {{ dhcrelays | join(' ') }}"
|
||||
notify_stop "systemctl stop {{ dhcrelays | join(' ') }}"
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
set_fact:
|
||||
vlans: '{{ query("netbox.netbox.nb_lookup", "vlans", api_filter="group=new-net", raw_data=true)
|
||||
| sort(attribute="vid") }}'
|
||||
vrfs: '{{ query("netbox.netbox.nb_lookup", "vrfs", raw_data=true) | list2dict("name") }}'
|
||||
prefixes: '{{ query("netbox.netbox.nb_lookup", "prefixes", raw_data=true)
|
||||
| sort(attribute="prefix") | sort(attribute="family.value") }}'
|
||||
|
||||
|
|
Loading…
Reference in a new issue