Add support for configuration of IP route tables and rules

This commit is contained in:
Mark Goddard 2017-10-24 19:21:07 +01:00
parent af5a3e56e0
commit cd5605fa71
5 changed files with 107 additions and 6 deletions

View File

@ -125,6 +125,7 @@ def net_vlan(context, name, inventory_hostname=None):
net_mtu = _make_attr_filter('mtu')
net_routes = _make_attr_filter('routes')
net_rules = _make_attr_filter('rules')
net_physical_network = _make_attr_filter('physical_network')
@ -154,14 +155,21 @@ def _route_obj(route):
The returned dict is compatible with the route item of the
interfaces_ether_interfaces and interfaces_bridge_interfaces variables in
the MichaelRigaert.interfaces role.
the MichaelRigart.interfaces role.
"""
net = netaddr.IPNetwork(route['cidr'])
return {
route_obj = {
'network': str(net.network),
'netmask': str(net.netmask),
'gateway': route['gateway'],
}
optional = {
'gateway',
'table',
}
for option in optional:
if option in route:
route_obj[option] = route[option]
return route_obj
@jinja2.contextfilter
@ -187,6 +195,7 @@ def net_interface_obj(context, name, inventory_hostname=None):
routes = net_routes(context, name, inventory_hostname)
if routes:
routes = [_route_obj(route) for route in routes]
rules = net_rules(context, name, inventory_hostname)
interface = {
'device': device,
'address': ip,
@ -195,6 +204,7 @@ def net_interface_obj(context, name, inventory_hostname=None):
'vlan': vlan,
'mtu': mtu,
'route': routes,
'rules': rules,
'bootproto': 'static',
'onboot': 'yes',
}
@ -226,6 +236,7 @@ def net_bridge_obj(context, name, inventory_hostname=None):
routes = net_routes(context, name, inventory_hostname)
if routes:
routes = [_route_obj(route) for route in routes]
rules = net_rules(context, name, inventory_hostname)
interface = {
'device': device,
'address': ip,
@ -235,6 +246,7 @@ def net_bridge_obj(context, name, inventory_hostname=None):
'mtu': mtu,
'ports': ports,
'route': routes,
'rules': rules,
'bootproto': 'static',
'onboot': 'yes',
}
@ -268,6 +280,7 @@ def net_bond_obj(context, name, inventory_hostname=None):
routes = net_routes(context, name, inventory_hostname)
if routes:
routes = [_route_obj(route) for route in routes]
rules = net_rules(context, name, inventory_hostname)
interface = {
'device': device,
'address': ip,
@ -279,6 +292,7 @@ def net_bond_obj(context, name, inventory_hostname=None):
'bond_mode': mode,
'bond_miimon': miimon,
'route': routes,
'rules': rules,
'bootproto': 'static',
'onboot': 'yes',
}
@ -429,6 +443,7 @@ class FilterModule(object):
'net_vlan': net_vlan,
'net_mtu': net_mtu,
'net_routes': net_routes,
'net_rules': net_rules,
'net_physical_network': net_physical_network,
'net_interface_obj': net_interface_obj,
'net_bridge_obj': net_bridge_obj,

View File

@ -54,3 +54,10 @@ network_patch_suffix_phy: '-phy'
# Suffix for virtual patch link interface names when connected towards the
# OVS bridge.
network_patch_suffix_ovs: '-ovs'
###############################################################################
# Network routing table configuration.
# List of IP routing tables. Each item should be a dict containing 'id' and
# 'name' items. These tables will be added to /etc/iproute2/rt_tables.
network_route_tables: []

View File

@ -52,6 +52,7 @@
become: True
- role: MichaelRigart.interfaces
interfaces_route_tables: "{{ network_route_tables }}"
interfaces_ether_interfaces: >
{{ ether_interfaces |
map('net_interface_obj') |

View File

@ -41,8 +41,13 @@ supported:
Maximum Transmission Unit (MTU).
``routes``
List of static IP routes. Each item should be a dict containing the
items ``cidr`` and ``gateway``. ``cidr`` is the CIDR representation of the
route's destination. ``gateway`` is the IP address of the next hop.
item ``cidr``, and optionally ``gateway`` and ``table``. ``cidr`` is the CIDR
representation of the route's destination. ``gateway`` is the IP address of
the next hop. ``table`` is the name or ID of a routing table to which the
route will be added.
``rules``
List of IP routing rules. Each item should be an ``iproute2`` IP routing
rule.
``physical_network``
Name of the physical network on which this network exists. This aligns with
the physical network concept in neutron.
@ -86,7 +91,8 @@ Configuring Static IP Routes
Static IP routes may be configured by setting the ``routes`` attribute for a
network to a list of routes.
To configure a network called ``example`` with a single IP route:
To configure a network called ``example`` with a single IP route to the
``10.1.0.0/24`` subnet via ``10.0.0.1``:
.. code-block:: yaml
:caption: ``networks.yml``
@ -155,6 +161,71 @@ addresses for hosts ``host1`` and ``host2``:
host1: 10.0.0.1
host2: 10.0.0.2
Advanced: Policy-Based Routing
------------------------------
Policy-based routing can be useful in complex networking environments,
particularly where asymmetric routes exist, and strict reverse path filtering
is enabled.
Configuring IP Routing Tables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Custom IP routing tables may be configured by setting the global variable
``network_route_tables`` in ``${KAYOBE_CONFIG_PATH}/networks.yml`` to a list of
route tables. These route tables will be added to ``/etc/iproute2/rt_tables``.
To configure a routing table called ``exampleroutetable`` with ID ``1``:
.. code-block:: yaml
:caption: ``networks.yml``
network_route_tables:
- name: exampleroutetable
id: 1
To configure route tables on specific hosts, use a host or group variables
file.
Configuring IP Routing Policy Rules
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
IP routing policy rules may be configured by setting the ``rules`` attribute
for a network to a list of rules. The format of a rule is the string which
would be appended to ``ip rule <add|del>`` to create or delete the rule.
To configure a network called ``example`` with an IP routing policy rule to
handle traffic from the subnet ``10.1.0.0/24`` using the routing table
``exampleroutetable``:
.. code-block:: yaml
:caption: ``networks.yml``
example_rules:
- from 10.1.0.0/24 table exampleroutetable
These rules will be configured on all hosts to which the network is mapped.
Configuring IP Routes on Specific Tables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A route may be added to a specific routing table by adding the name or ID of
the table to a ``table`` attribute of the route:
To configure a network called ``example`` with a default route and a
'connected' (local subnet) route to the subnet ``10.1.0.0/24`` on the table
``exampleroutetable``:
.. code-block:: yaml
:caption: ``networks.yml``
example_routes:
- cidr: 0.0.0.0/0
gateway 10.1.0.1
table: exampleroutetable
- cidr: 10.1.0.0/24
table: exampleroutetable
Per-host Network Configuration
==============================

View File

@ -150,6 +150,13 @@
# OVS bridge.
#network_patch_suffix_ovs:
###############################################################################
# Network routing table configuration.
# List of IP routing tables. Each item should be a dict containing 'id' and
# 'name' items. These tables will be added to /etc/iproute2/rt_tables.
#network_route_tables:
###############################################################################
# Dummy variable to allow Ansible to accept this file.
workaround_ansible_issue_8743: yes