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_mtu = _make_attr_filter('mtu')
net_routes = _make_attr_filter('routes') net_routes = _make_attr_filter('routes')
net_rules = _make_attr_filter('rules')
net_physical_network = _make_attr_filter('physical_network') 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 The returned dict is compatible with the route item of the
interfaces_ether_interfaces and interfaces_bridge_interfaces variables in interfaces_ether_interfaces and interfaces_bridge_interfaces variables in
the MichaelRigaert.interfaces role. the MichaelRigart.interfaces role.
""" """
net = netaddr.IPNetwork(route['cidr']) net = netaddr.IPNetwork(route['cidr'])
return { route_obj = {
'network': str(net.network), 'network': str(net.network),
'netmask': str(net.netmask), '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 @jinja2.contextfilter
@ -187,6 +195,7 @@ def net_interface_obj(context, name, inventory_hostname=None):
routes = net_routes(context, name, inventory_hostname) routes = net_routes(context, name, inventory_hostname)
if routes: if routes:
routes = [_route_obj(route) for route in routes] routes = [_route_obj(route) for route in routes]
rules = net_rules(context, name, inventory_hostname)
interface = { interface = {
'device': device, 'device': device,
'address': ip, 'address': ip,
@ -195,6 +204,7 @@ def net_interface_obj(context, name, inventory_hostname=None):
'vlan': vlan, 'vlan': vlan,
'mtu': mtu, 'mtu': mtu,
'route': routes, 'route': routes,
'rules': rules,
'bootproto': 'static', 'bootproto': 'static',
'onboot': 'yes', 'onboot': 'yes',
} }
@ -226,6 +236,7 @@ def net_bridge_obj(context, name, inventory_hostname=None):
routes = net_routes(context, name, inventory_hostname) routes = net_routes(context, name, inventory_hostname)
if routes: if routes:
routes = [_route_obj(route) for route in routes] routes = [_route_obj(route) for route in routes]
rules = net_rules(context, name, inventory_hostname)
interface = { interface = {
'device': device, 'device': device,
'address': ip, 'address': ip,
@ -235,6 +246,7 @@ def net_bridge_obj(context, name, inventory_hostname=None):
'mtu': mtu, 'mtu': mtu,
'ports': ports, 'ports': ports,
'route': routes, 'route': routes,
'rules': rules,
'bootproto': 'static', 'bootproto': 'static',
'onboot': 'yes', 'onboot': 'yes',
} }
@ -268,6 +280,7 @@ def net_bond_obj(context, name, inventory_hostname=None):
routes = net_routes(context, name, inventory_hostname) routes = net_routes(context, name, inventory_hostname)
if routes: if routes:
routes = [_route_obj(route) for route in routes] routes = [_route_obj(route) for route in routes]
rules = net_rules(context, name, inventory_hostname)
interface = { interface = {
'device': device, 'device': device,
'address': ip, 'address': ip,
@ -279,6 +292,7 @@ def net_bond_obj(context, name, inventory_hostname=None):
'bond_mode': mode, 'bond_mode': mode,
'bond_miimon': miimon, 'bond_miimon': miimon,
'route': routes, 'route': routes,
'rules': rules,
'bootproto': 'static', 'bootproto': 'static',
'onboot': 'yes', 'onboot': 'yes',
} }
@ -429,6 +443,7 @@ class FilterModule(object):
'net_vlan': net_vlan, 'net_vlan': net_vlan,
'net_mtu': net_mtu, 'net_mtu': net_mtu,
'net_routes': net_routes, 'net_routes': net_routes,
'net_rules': net_rules,
'net_physical_network': net_physical_network, 'net_physical_network': net_physical_network,
'net_interface_obj': net_interface_obj, 'net_interface_obj': net_interface_obj,
'net_bridge_obj': net_bridge_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 # Suffix for virtual patch link interface names when connected towards the
# OVS bridge. # OVS bridge.
network_patch_suffix_ovs: '-ovs' 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 become: True
- role: MichaelRigart.interfaces - role: MichaelRigart.interfaces
interfaces_route_tables: "{{ network_route_tables }}"
interfaces_ether_interfaces: > interfaces_ether_interfaces: >
{{ ether_interfaces | {{ ether_interfaces |
map('net_interface_obj') | map('net_interface_obj') |

View File

@ -41,8 +41,13 @@ supported:
Maximum Transmission Unit (MTU). Maximum Transmission Unit (MTU).
``routes`` ``routes``
List of static IP routes. Each item should be a dict containing the List of static IP routes. Each item should be a dict containing the
items ``cidr`` and ``gateway``. ``cidr`` is the CIDR representation of the item ``cidr``, and optionally ``gateway`` and ``table``. ``cidr`` is the CIDR
route's destination. ``gateway`` is the IP address of the next hop. 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`` ``physical_network``
Name of the physical network on which this network exists. This aligns with Name of the physical network on which this network exists. This aligns with
the physical network concept in neutron. 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 Static IP routes may be configured by setting the ``routes`` attribute for a
network to a list of routes. 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 .. code-block:: yaml
:caption: ``networks.yml`` :caption: ``networks.yml``
@ -155,6 +161,71 @@ addresses for hosts ``host1`` and ``host2``:
host1: 10.0.0.1 host1: 10.0.0.1
host2: 10.0.0.2 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 Per-host Network Configuration
============================== ==============================

View File

@ -150,6 +150,13 @@
# OVS bridge. # OVS bridge.
#network_patch_suffix_ovs: #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. # Dummy variable to allow Ansible to accept this file.
workaround_ansible_issue_8743: yes workaround_ansible_issue_8743: yes