Add support for bonded (LAG) host network interfaces
This is configured by setting the <network>_bond_slaves variable to a list of network interfaces to act as slaves.
This commit is contained in:
parent
b9e1243d7d
commit
2afc6fabae
@ -137,6 +137,11 @@ def net_bridge_ports(context, name, inventory_hostname=None):
|
||||
return net_attr(context, name, 'bridge_ports', inventory_hostname)
|
||||
|
||||
|
||||
net_bond_mode = _make_attr_filter('bond_mode')
|
||||
net_bond_slaves = _make_attr_filter('bond_slaves')
|
||||
net_bond_miimon = _make_attr_filter('bond_miimon')
|
||||
|
||||
|
||||
def _route_obj(route):
|
||||
"""Return a dict representation of an IP route.
|
||||
|
||||
@ -226,14 +231,82 @@ def net_bridge_obj(context, name, inventory_hostname=None):
|
||||
return interface
|
||||
|
||||
|
||||
@jinja2.contextfilter
|
||||
def net_bond_obj(context, name, inventory_hostname=None):
|
||||
"""Return a dict representation of a network bond interface.
|
||||
|
||||
The returned dict is compatible with the interfaces_bond_interfaces
|
||||
variable in the MichaelRigaert.interfaces role.
|
||||
"""
|
||||
device = net_interface(context, name, inventory_hostname)
|
||||
if not device:
|
||||
raise errors.AnsibleFilterError(
|
||||
"Network interface for network '%s' on host '%s' not found" %
|
||||
(name, inventory_hostname))
|
||||
ip = net_ip(context, name, inventory_hostname)
|
||||
cidr = net_cidr(context, name, inventory_hostname)
|
||||
netmask = net_mask(context, name, inventory_hostname)
|
||||
gateway = net_gateway(context, name, inventory_hostname)
|
||||
vlan = net_vlan(context, name, inventory_hostname)
|
||||
mtu = net_mtu(context, name, inventory_hostname)
|
||||
mode = net_bond_mode(context, name, inventory_hostname)
|
||||
slaves = net_bond_slaves(context, name, inventory_hostname)
|
||||
miimon = net_bond_miimon(context, name, inventory_hostname)
|
||||
routes = net_routes(context, name, inventory_hostname)
|
||||
if routes:
|
||||
routes = [_route_obj(route) for route in routes]
|
||||
interface = {
|
||||
'device': device,
|
||||
'address': ip,
|
||||
'netmask': netmask,
|
||||
'gateway': gateway,
|
||||
'vlan': vlan,
|
||||
'mtu': mtu,
|
||||
'bond_slaves': slaves,
|
||||
'bond_mode': mode,
|
||||
'bond_miimon': miimon,
|
||||
'route': routes,
|
||||
'bootproto': 'static',
|
||||
'onboot': 'yes',
|
||||
}
|
||||
interface = {k: v for k, v in interface.items() if v is not None}
|
||||
return interface
|
||||
|
||||
|
||||
def _net_interface_type(context, name, inventory_hostname):
|
||||
"""Return a string describing the network interface type.
|
||||
|
||||
Possible types include 'ether', 'bridge', 'bond'.
|
||||
"""
|
||||
bridge_ports = net_bridge_ports(context, name, inventory_hostname)
|
||||
bond_slaves = net_bond_slaves(context, name, inventory_hostname)
|
||||
if bridge_ports is not None and bond_slaves is not None:
|
||||
raise errors.AnsibleFilterError(
|
||||
"Network %s on host %s has both bridge ports and bond slaves "
|
||||
"defined" %
|
||||
(name,
|
||||
_get_hostvar(context, 'inventory_hostname', inventory_hostname)))
|
||||
if bridge_ports is None and bond_slaves is None:
|
||||
return 'ether'
|
||||
if bridge_ports is not None:
|
||||
return 'bridge'
|
||||
if bond_slaves is not None:
|
||||
return 'bond'
|
||||
|
||||
|
||||
@jinja2.contextfilter
|
||||
def net_is_ether(context, name, inventory_hostname=None):
|
||||
return net_bridge_ports(context, name) is None
|
||||
return _net_interface_type(context, name, inventory_hostname) == 'ether'
|
||||
|
||||
|
||||
@jinja2.contextfilter
|
||||
def net_is_bridge(context, name, inventory_hostname=None):
|
||||
return net_bridge_ports(context, name) is not None
|
||||
return _net_interface_type(context, name, inventory_hostname) == 'bridge'
|
||||
|
||||
|
||||
@jinja2.contextfilter
|
||||
def net_is_bond(context, name, inventory_hostname=None):
|
||||
return _net_interface_type(context, name, inventory_hostname) == 'bond'
|
||||
|
||||
|
||||
@jinja2.contextfilter
|
||||
@ -251,6 +324,11 @@ def net_select_bridges(context, names):
|
||||
return [name for name in names if net_is_bridge(context, name)]
|
||||
|
||||
|
||||
@jinja2.contextfilter
|
||||
def net_select_bonds(context, names):
|
||||
return [name for name in names if net_is_bond(context, name)]
|
||||
|
||||
|
||||
@jinja2.contextfilter
|
||||
def net_select_vlans(context, names):
|
||||
return [name for name in names if net_is_vlan(context, name)]
|
||||
@ -338,11 +416,14 @@ class FilterModule(object):
|
||||
'net_routes': net_routes,
|
||||
'net_interface_obj': net_interface_obj,
|
||||
'net_bridge_obj': net_bridge_obj,
|
||||
'net_bond_obj': net_bond_obj,
|
||||
'net_is_ether': net_is_ether,
|
||||
'net_is_bridge': net_is_bridge,
|
||||
'net_is_bond': net_is_bond,
|
||||
'net_is_vlan': net_is_vlan,
|
||||
'net_select_ethers': net_select_ethers,
|
||||
'net_select_bridges': net_select_bridges,
|
||||
'net_select_bonds': net_select_bonds,
|
||||
'net_select_vlans': net_select_vlans,
|
||||
'net_reject_vlans': net_reject_vlans,
|
||||
'net_configdrive_network_device': net_configdrive_network_device,
|
||||
|
@ -6,6 +6,7 @@
|
||||
vars:
|
||||
ether_interfaces: "{{ network_interfaces | net_select_ethers | list }}"
|
||||
bridge_interfaces: "{{ network_interfaces | net_select_bridges | list }}"
|
||||
bond_interfaces: "{{ network_interfaces | net_select_bonds | list }}"
|
||||
pre_tasks:
|
||||
- block:
|
||||
- name: Validate network interface configuration
|
||||
@ -23,6 +24,14 @@
|
||||
{{ item }}. This should be configured via '{{ item }}_interface'.
|
||||
with_items: "{{ bridge_interfaces }}"
|
||||
when: "{{ not item | net_interface }}"
|
||||
|
||||
- name: Validate bond interface configuration
|
||||
fail:
|
||||
msg: >
|
||||
Bond interface validation failed - no interface configured for
|
||||
{{ item }}. This should be configured via '{{ item }}_interface'.
|
||||
with_items: "{{ bond_interfaces }}"
|
||||
when: "{{ not item | net_interface }}"
|
||||
tags:
|
||||
- config-validation
|
||||
|
||||
@ -57,6 +66,10 @@
|
||||
{{ bridge_interfaces |
|
||||
map('net_bridge_obj') |
|
||||
list }}
|
||||
interfaces_bond_interfaces: >
|
||||
{{ bond_interfaces |
|
||||
map('net_bond_obj') |
|
||||
list }}
|
||||
become: True
|
||||
|
||||
- role: MichaelRigart.interfaces
|
||||
|
@ -168,6 +168,13 @@ The following attributes are supported:
|
||||
``bridge_ports``
|
||||
For bridge interfaces, a list of names of network interfaces to add to the
|
||||
bridge.
|
||||
``bond_mode``
|
||||
For bond interfaces, the bond's mode, e.g. 802.3ad.
|
||||
``bond_slaves``
|
||||
For bond interfaces, a list of names of network interfaces to act as slaves
|
||||
for the bond.
|
||||
``bond_miimon``
|
||||
For bond interfaces, the time in milliseconds between MII link monitoring.
|
||||
|
||||
In order to provide flexibility in the system's network topology, Kayobe maps
|
||||
the named networks to logical network roles. A single named network may
|
||||
|
@ -5,26 +5,32 @@
|
||||
# Overcloud provisioning network IP information.
|
||||
# provision_oc_net_interface:
|
||||
# provision_oc_net_bridge_ports:
|
||||
# provision_oc_net_bond_slaves:
|
||||
|
||||
# Workload provisioning network IP information.
|
||||
# provision_wl_net_interface:
|
||||
# provision_wl_net_bridge_ports:
|
||||
# provision_wl_net_bond_slaves:
|
||||
|
||||
# Internal network IP information.
|
||||
# internal_net_interface:
|
||||
# internal_net_bridge_ports:
|
||||
# internal_net_bond_slaves:
|
||||
|
||||
# External network IP information.
|
||||
# external_net_interface:
|
||||
# external_net_bridge_ports:
|
||||
# external_net_bond_slaves:
|
||||
|
||||
# Storage network IP information.
|
||||
# storage_net_interface:
|
||||
# storage_net_bridge_ports:
|
||||
# storage_net_bond_slaves:
|
||||
|
||||
# Storage management network IP information.
|
||||
# storage_mgmt_net_interface:
|
||||
# storage_mgmt_net_bridge_ports:
|
||||
# storage_mgmt_net_bond_slaves:
|
||||
|
||||
###############################################################################
|
||||
# Dummy variable to allow Ansible to accept this file.
|
||||
|
@ -5,26 +5,32 @@
|
||||
# Overcloud provisioning network IP information.
|
||||
# provision_oc_net_interface:
|
||||
# provision_oc_net_bridge_ports:
|
||||
# provision_oc_net_bond_slaves:
|
||||
|
||||
# Workload provisioning network IP information.
|
||||
# provision_wl_net_interface:
|
||||
# provision_wl_net_bridge_ports:
|
||||
# provision_wl_net_bond_slaves:
|
||||
|
||||
# Internal network IP information.
|
||||
# internal_net_interface:
|
||||
# internal_net_bridge_ports:
|
||||
# internal_net_bond_slaves:
|
||||
|
||||
# External network IP information.
|
||||
# external_net_interface:
|
||||
# external_net_bridge_ports:
|
||||
# external_net_bond_slaves:
|
||||
|
||||
# Storage network IP information.
|
||||
# storage_net_interface:
|
||||
# storage_net_bridge_ports:
|
||||
# storage_net_bond_slaves:
|
||||
|
||||
# Storage management network IP information.
|
||||
# storage_mgmt_net_interface:
|
||||
# storage_mgmt_net_bridge_ports:
|
||||
# storage_mgmt_net_bond_slaves:
|
||||
|
||||
###############################################################################
|
||||
# Dummy variable to allow Ansible to accept this file.
|
||||
|
Loading…
x
Reference in New Issue
Block a user