4597 lines
224 KiB
Python
4597 lines
224 KiB
Python
# Copyright (c) 2017-2024 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
|
|
from __future__ import print_function
|
|
|
|
import os
|
|
import uuid
|
|
import yaml
|
|
import mock
|
|
import netaddr
|
|
import json
|
|
|
|
from sysinv.common import utils
|
|
from sysinv.common import constants
|
|
from sysinv.puppet import interface
|
|
from sysinv.puppet import puppet
|
|
from sysinv.objects import base as objbase
|
|
|
|
from sysinv.tests.db import base as dbbase
|
|
from sysinv.tests.db import utils as dbutils
|
|
from sysinv.tests.puppet import base
|
|
from sysinv.db import api as db_api
|
|
from collections import defaultdict
|
|
|
|
|
|
NETWORKTYPES_WITH_V4_ADDRESSES = [constants.NETWORK_TYPE_MGMT,
|
|
constants.NETWORK_TYPE_OAM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST,
|
|
constants.NETWORK_TYPE_PXEBOOT]
|
|
|
|
NETWORKTYPES_WITH_V6_ADDRESSES = [constants.NETWORK_TYPE_DATA]
|
|
|
|
NETWORKTYPES_WITH_V4_ROUTES = [constants.NETWORK_TYPE_DATA]
|
|
|
|
NETWORKTYPES_WITH_V6_ROUTES = [constants.NETWORK_TYPE_DATA]
|
|
|
|
|
|
class InterfaceTestCaseMixin(base.PuppetTestCaseMixin):
|
|
""" This InterfaceTestCaseMixin needs to be used with a subclass
|
|
of BaseHostTestCase
|
|
"""
|
|
|
|
def assertIn(self, needle, haystack, message=''):
|
|
"""Custom assertIn that handles object comparison"""
|
|
if isinstance(needle, objbase.SysinvObject):
|
|
# compare objects based on unique DB identifier
|
|
needle = needle.id
|
|
haystack = [o.id for o in haystack]
|
|
super(InterfaceTestCaseMixin, self).assertIn(needle, haystack, message)
|
|
|
|
def assertEqual(self, expected, observed, message=''):
|
|
"""Custom assertEqual that handles object comparison"""
|
|
if (isinstance(expected, objbase.SysinvObject) and
|
|
isinstance(observed, objbase.SysinvObject)):
|
|
expected = expected.id
|
|
observed = observed.id
|
|
super(InterfaceTestCaseMixin, self).assertEqual(expected, observed, message)
|
|
|
|
def _get_network_type_list(self, networktype):
|
|
if isinstance(networktype, list):
|
|
networktypelist = networktype
|
|
elif networktype:
|
|
networktypelist = [networktype]
|
|
else:
|
|
networktypelist = []
|
|
return networktypelist
|
|
|
|
def _get_network_ids_by_type(self, networktype):
|
|
networktypelist = self._get_network_type_list(networktype)
|
|
networks = []
|
|
for network_type in networktypelist:
|
|
network = self._find_network_by_type(network_type)
|
|
if network:
|
|
networks.append(str(network['id']))
|
|
return networks
|
|
|
|
def _create_ethernet_test(self, ifname=None, ifclass=None,
|
|
networktype=None, hostname=None,
|
|
**kwargs):
|
|
interface_id = len(self.interfaces)
|
|
if not ifname:
|
|
ifname = (networktype or 'eth') + str(interface_id)
|
|
if not ifclass:
|
|
ifclass = constants.INTERFACE_CLASS_NONE
|
|
if ifclass == constants.INTERFACE_CLASS_PLATFORM:
|
|
networks = self._get_network_ids_by_type(networktype)
|
|
else:
|
|
networks = []
|
|
interface = {'id': interface_id,
|
|
'uuid': str(uuid.uuid4()),
|
|
'forihostid': self.host.id,
|
|
'ifname': ifname,
|
|
'iftype': constants.INTERFACE_TYPE_ETHERNET,
|
|
'imac': '02:11:22:33:44:' + str(10 + interface_id),
|
|
'uses': [],
|
|
'used_by': [],
|
|
'ifclass': ifclass,
|
|
'networks': networks,
|
|
'networktype': networktype,
|
|
'imtu': 1500,
|
|
'sriov_numvfs': kwargs.get('sriov_numvfs', 0),
|
|
'sriov_vf_driver': kwargs.get('iface_sriov_vf_driver', None),
|
|
'max_tx_rate': kwargs.get('max_tx_rate', None),
|
|
'ipv4_mode': kwargs.get('ipv4_mode', None),
|
|
'ipv6_mode': kwargs.get('ipv6_mode', None)}
|
|
db_interface = dbutils.create_test_interface(**interface)
|
|
for network in networks:
|
|
dbutils.create_test_interface_network_assign(db_interface['id'], network)
|
|
self.interfaces.append(db_interface)
|
|
|
|
port_id = len(self.ports)
|
|
port = {'id': port_id,
|
|
'uuid': str(uuid.uuid4()),
|
|
'name': 'eth' + str(port_id),
|
|
'interface_id': interface_id,
|
|
'host_id': self.host.id,
|
|
'mac': interface['imac'],
|
|
'driver': kwargs.get('driver', 'ixgbe'),
|
|
'dpdksupport': kwargs.get('dpdksupport', True),
|
|
'pdevice': kwargs.get('pdevice',
|
|
"Ethernet Controller X710 for 10GbE SFP+ [1572]"),
|
|
'pciaddr': kwargs.get('pciaddr',
|
|
'0000:00:00.' + str(port_id + 1)),
|
|
'dev_id': kwargs.get('dev_id', 0),
|
|
'sriov_vf_driver': kwargs.get('port_sriov_vf_driver', None),
|
|
'sriov_vf_pdevice_id': kwargs.get('sriov_vf_pdevice_id', None),
|
|
'sriov_vfs_pci_address': kwargs.get('sriov_vfs_pci_address', '')}
|
|
db_port = dbutils.create_test_ethernet_port(**port)
|
|
self.ports.append(db_port)
|
|
if hostname:
|
|
self._assign_addresses_to_interface(hostname, db_interface, networktype)
|
|
db_interface.networktypelist = self._get_network_type_list(networktype)
|
|
return db_port, db_interface
|
|
|
|
def _create_vlan_test(self, ifname, ifclass, networktype, vlan_id,
|
|
lower_iface=None, hostname=None, **kwargs):
|
|
if not lower_iface:
|
|
lower_port, lower_iface = self._create_ethernet_test()
|
|
if not ifname:
|
|
ifname = 'vlan' + str(vlan_id)
|
|
if not ifclass:
|
|
ifclass = constants.INTERFACE_CLASS_NONE
|
|
if ifclass == constants.INTERFACE_CLASS_PLATFORM:
|
|
networks = self._get_network_ids_by_type(networktype)
|
|
else:
|
|
networks = []
|
|
interface_id = len(self.interfaces)
|
|
interface = {'id': interface_id,
|
|
'uuid': str(uuid.uuid4()),
|
|
'forihostid': self.host.id,
|
|
'ifname': ifname,
|
|
'iftype': constants.INTERFACE_TYPE_VLAN,
|
|
'vlan_id': vlan_id,
|
|
'imac': '02:11:22:33:44:' + str(10 + interface_id),
|
|
'uses': [lower_iface['ifname']],
|
|
'used_by': [],
|
|
'ifclass': ifclass,
|
|
'networks': networks,
|
|
'networktype': networktype,
|
|
'imtu': 1500,
|
|
'ipv4_mode': kwargs.get('ipv4_mode', None),
|
|
'ipv6_mode': kwargs.get('ipv6_mode', None)}
|
|
lower_iface['used_by'].append(interface['ifname'])
|
|
db_interface = dbutils.create_test_interface(**interface)
|
|
for network in networks:
|
|
dbutils.create_test_interface_network_assign(db_interface['id'], network)
|
|
self.interfaces.append(db_interface)
|
|
if hostname:
|
|
self._assign_addresses_to_interface(hostname, db_interface, networktype)
|
|
db_interface.networktypelist = self._get_network_type_list(networktype)
|
|
return db_interface
|
|
|
|
def _create_bond_test(self, ifname, ifclass=None, networktype=None, hostname=None, **kwargs):
|
|
iface1 = kwargs.get('iface1', None)
|
|
if not iface1:
|
|
port1, iface1 = self._create_ethernet_test()
|
|
iface2 = kwargs.get('iface2', None)
|
|
if not iface2:
|
|
port2, iface2 = self._create_ethernet_test()
|
|
interface_id = len(self.interfaces)
|
|
if not ifname:
|
|
ifname = 'bond' + str(interface_id)
|
|
if not ifclass:
|
|
ifclass = constants.INTERFACE_CLASS_NONE
|
|
if ifclass == constants.INTERFACE_CLASS_PLATFORM:
|
|
networks = self._get_network_ids_by_type(networktype)
|
|
else:
|
|
networks = []
|
|
interface = {'id': interface_id,
|
|
'uuid': str(uuid.uuid4()),
|
|
'forihostid': self.host.id,
|
|
'ifname': ifname,
|
|
'iftype': constants.INTERFACE_TYPE_AE,
|
|
'imac': '02:11:22:33:44:' + str(10 + interface_id),
|
|
'uses': [iface1['ifname'], iface2['ifname']],
|
|
'used_by': [],
|
|
'ifclass': ifclass,
|
|
'networks': networks,
|
|
'networktype': networktype,
|
|
'imtu': 1500,
|
|
'txhashpolicy': 'layer2',
|
|
'primary_reselect': kwargs.get('primary_reselect', None),
|
|
'ipv4_mode': kwargs.get('ipv4_mode', None),
|
|
'ipv6_mode': kwargs.get('ipv6_mode', None)}
|
|
|
|
aemode = kwargs.get('aemode', None)
|
|
if aemode:
|
|
interface['aemode'] = aemode
|
|
else:
|
|
lacp_types = [constants.NETWORK_TYPE_MGMT,
|
|
constants.NETWORK_TYPE_PXEBOOT]
|
|
if networktype in lacp_types:
|
|
interface['aemode'] = '802.3ad'
|
|
else:
|
|
interface['aemode'] = 'balanced'
|
|
|
|
iface1['used_by'].append(interface['ifname'])
|
|
iface2['used_by'].append(interface['ifname'])
|
|
db_interface = dbutils.create_test_interface(**interface)
|
|
for network in networks:
|
|
dbutils.create_test_interface_network_assign(db_interface['id'], network)
|
|
self.interfaces.append(db_interface)
|
|
if hostname:
|
|
self._assign_addresses_to_interface(hostname, db_interface, networktype)
|
|
db_interface.networktypelist = self._get_network_type_list(networktype)
|
|
return db_interface
|
|
|
|
def _create_vf_test(self, ifname, num_vfs, vf_driver=None,
|
|
lower_iface=None, max_tx_rate=None):
|
|
if not lower_iface:
|
|
lower_port, lower_iface = self._create_ethernet_test(
|
|
'sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
if not ifname:
|
|
ifname = 'vf-' + lower_iface['ifname']
|
|
if not num_vfs:
|
|
num_vfs = 1
|
|
|
|
networks = []
|
|
|
|
ifclass = constants.INTERFACE_CLASS_PCI_SRIOV
|
|
interface_id = len(self.interfaces)
|
|
interface = {'id': interface_id,
|
|
'uuid': str(uuid.uuid4()),
|
|
'forihostid': self.host.id,
|
|
'ifname': ifname,
|
|
'iftype': constants.INTERFACE_TYPE_VF,
|
|
'imac': '02:11:22:33:44:' + str(10 + interface_id),
|
|
'uses': [lower_iface['ifname']],
|
|
'used_by': [],
|
|
'ifclass': ifclass,
|
|
'networks': networks,
|
|
'networktype': constants.NETWORK_TYPE_PCI_SRIOV,
|
|
'imtu': 1500,
|
|
'sriov_numvfs': num_vfs,
|
|
'sriov_vf_driver': vf_driver,
|
|
'max_tx_rate': max_tx_rate}
|
|
lower_iface['used_by'].append(interface['ifname'])
|
|
db_interface = dbutils.create_test_interface(**interface)
|
|
self.interfaces.append(db_interface)
|
|
return db_interface
|
|
|
|
def _create_test_host(self, personality, subfunction=None):
|
|
subfunctions = [personality]
|
|
if subfunction:
|
|
subfunctions.append(subfunction)
|
|
|
|
host = {'personality': personality,
|
|
'hostname': '%s-0' % personality,
|
|
'forisystemid': self.system.id,
|
|
'subfunctions': ",".join(subfunctions)}
|
|
|
|
return dbutils.create_test_ihost(**host)
|
|
|
|
def _create_address_for_interface(self, iface, networktype=None, family=None):
|
|
|
|
if not networktype:
|
|
if len(iface.networktypelist) > 0:
|
|
networktype = iface.networktypelist[0]
|
|
|
|
network = None
|
|
if networktype:
|
|
network = self._find_network_by_type(networktype)
|
|
|
|
addrpool = None
|
|
if network:
|
|
addrpools = self._find_network_address_pools(network.id)
|
|
if family:
|
|
for pool in addrpools:
|
|
if pool.family == family:
|
|
addrpool = pool
|
|
break
|
|
elif len(addrpools) > 0:
|
|
addrpool = addrpools[0]
|
|
|
|
if addrpool:
|
|
next_address = netaddr.IPAddress(addrpool.network) + 10
|
|
address_fields = {'interface_id': iface['id'],
|
|
'address_pool_id': addrpool.id,
|
|
'family': addrpool.family,
|
|
'prefix': addrpool.prefix,
|
|
'address': str(next_address)}
|
|
else:
|
|
if family == constants.IPV6_FAMILY:
|
|
address_fields = {'family': constants.IPV6_FAMILY,
|
|
'prefix': 64,
|
|
'address': 'fd08::a'}
|
|
else:
|
|
address_fields = {'family': constants.IPV4_FAMILY,
|
|
'prefix': 24,
|
|
'address': '192.168.1.10'}
|
|
address_fields['interface_id'] = iface['id']
|
|
|
|
address = dbutils.create_test_address(**address_fields)
|
|
self.addresses.append(address)
|
|
|
|
return network, address
|
|
|
|
def _assign_addresses_to_pool(self):
|
|
|
|
dbapi = db_api.get_instance()
|
|
|
|
network_names = {
|
|
'oam': 'oam',
|
|
'mgmt': 'management',
|
|
'cluster-host': 'cluster-host',
|
|
'pxeboot': 'pxeboot',
|
|
'admin': 'admin'
|
|
}
|
|
|
|
addrpool_index = {}
|
|
addrpools = dbapi.address_pools_get_all()
|
|
for addrpool in addrpools:
|
|
if addrpool.name:
|
|
addrpool_index[addrpool.name] = (
|
|
addrpool,
|
|
netaddr.IPNetwork(str(addrpool.network) + '/' + str(addrpool.prefix))
|
|
)
|
|
|
|
addresses = dbapi.addresses_get_all()
|
|
for addr in addresses:
|
|
if not addr.name:
|
|
continue
|
|
for network_type, network_name in network_names.items():
|
|
if addr.name.endswith("-" + network_type):
|
|
pool_name = f"{network_name}-ipv{addr.family}"
|
|
addrpool = addrpool_index.get(pool_name, None)
|
|
if not addrpool:
|
|
break
|
|
ipaddr = netaddr.IPAddress(addr.address)
|
|
if ipaddr not in addrpool[1]:
|
|
break
|
|
dbapi.address_update(addr.uuid, {'address_pool_id': addrpool[0].id})
|
|
break
|
|
|
|
def _assign_addresses_to_interface(self, hostname, interface, networktypes):
|
|
if isinstance(networktypes, list):
|
|
networktypelist = networktypes
|
|
elif networktypes:
|
|
networktypelist = [networktypes]
|
|
else:
|
|
networktypelist = []
|
|
|
|
dbapi = db_api.get_instance()
|
|
|
|
addresses = dbapi.addresses_get_all()
|
|
|
|
name_index = {
|
|
hostname + "-oam": constants.NETWORK_TYPE_OAM,
|
|
hostname + "-mgmt": constants.NETWORK_TYPE_MGMT,
|
|
hostname + "-cluster-host": constants.NETWORK_TYPE_CLUSTER_HOST,
|
|
hostname + "-pxeboot": constants.NETWORK_TYPE_PXEBOOT,
|
|
hostname + "-admin": constants.NETWORK_TYPE_ADMIN,
|
|
}
|
|
|
|
for network_type in networktypelist:
|
|
for addr in addresses:
|
|
if not (addr.name):
|
|
continue
|
|
try:
|
|
if (name_index.get(addr.name, None) == network_type
|
|
or (addr.ifname == interface.ifname and addr.interface_id is None)):
|
|
dbapi.address_update(addr.uuid, {'interface_id': interface.id})
|
|
except Exception as ex:
|
|
print(f"Failed to link address {addr.name} to interface "
|
|
f"{interface.ifname}: {ex}")
|
|
|
|
@puppet.puppet_context
|
|
def _update_context(self):
|
|
# interface is added as an operator by systemconfig.puppet_plugins
|
|
self.context = \
|
|
self.operator.interface._create_interface_context(self.host) # pylint: disable=no-member
|
|
|
|
# Update the puppet context with generated interface context
|
|
self.operator.context.update(self.context)
|
|
|
|
def _setup_context(self):
|
|
self.ports = []
|
|
self.interfaces = []
|
|
self.addresses = []
|
|
self.routes = []
|
|
self._setup_configuration()
|
|
self._update_context()
|
|
|
|
def _setup_configuration(self):
|
|
pass
|
|
|
|
|
|
class InterfaceTestCase1(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|
|
|
def setUp(self):
|
|
super(InterfaceTestCase1, self).setUp()
|
|
self._setup_context()
|
|
|
|
def _setup_configuration(self):
|
|
self.host = self._create_test_host(constants.CONTROLLER)
|
|
self.port, self.iface = self._create_ethernet_test(
|
|
"mgmt0", constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self.mgmt_gateway_address = self.mgmt_subnet[1]
|
|
self.oam_gateway_address = self.oam_subnet[1]
|
|
|
|
def _update_context(self):
|
|
super(InterfaceTestCase1, self)._update_context()
|
|
|
|
def test_get_port_interface_id_index(self):
|
|
index = self.operator.interface._get_port_interface_id_index(self.host) # pylint: disable=no-member
|
|
for port in self.ports:
|
|
self.assertTrue(port['interface_id'] in index)
|
|
self.assertEqual(index[port['interface_id']], port)
|
|
|
|
def test_get_port_pciaddr_index(self):
|
|
index = self.operator.interface._get_port_pciaddr_index(self.host) # pylint: disable=no-member
|
|
for port in self.ports:
|
|
self.assertTrue(port['pciaddr'] in index)
|
|
self.assertIn(port, index[port['pciaddr']])
|
|
|
|
def test_get_network_type_index(self):
|
|
index = self.operator.interface._get_network_type_index() # pylint: disable=no-member
|
|
for network in self._get_all_networks():
|
|
self.assertTrue(network['type'] in index)
|
|
self.assertEqual(index[network['type']], network)
|
|
|
|
def test_get_address_interface_name_index(self):
|
|
index = self.operator.interface._get_address_interface_name_index(self.host) # pylint: disable=no-member
|
|
for address in self.addresses:
|
|
self.assertTrue(address['ifname'] in index)
|
|
self.assertIn(address, index[address['ifname']])
|
|
|
|
def test_get_routes_interface_name_index(self):
|
|
index = self.operator.interface._get_routes_interface_name_index(self.host) # pylint: disable=no-member
|
|
for route in self.routes:
|
|
self.assertTrue(route['ifname'] in index)
|
|
self.assertIn(route, index[route['ifname']])
|
|
|
|
def test_get_interface_mtu(self):
|
|
value = interface.get_interface_mtu(self.context, self.iface)
|
|
self.assertEqual(value, self.iface['imtu'])
|
|
|
|
def test_get_interface_port(self):
|
|
value = interface.get_interface_port(self.context, self.iface)
|
|
self.assertEqual(value, self.port)
|
|
|
|
def test_get_interface_port_name(self):
|
|
value = interface.get_interface_port_name(self.context, self.iface)
|
|
self.assertEqual(value, self.port['name'])
|
|
|
|
def test_get_interface_os_ifname_ethernet(self):
|
|
value = interface.get_interface_os_ifname(self.context, self.iface)
|
|
self.assertEqual(value, self.port['name'])
|
|
|
|
def test_get_interface_os_ifname_bond(self):
|
|
self.iface['iftype'] = constants.INTERFACE_TYPE_AE
|
|
value = interface.get_interface_os_ifname(self.context, self.iface)
|
|
self.assertEqual(value, self.iface['ifname'])
|
|
|
|
def _get_route_config(self, name='default', ensure='present',
|
|
gateway='1.2.3.1', interface='eth0',
|
|
netmask='0.0.0.0', network='default',
|
|
metric=1):
|
|
config = {'name': name,
|
|
'ensure': ensure,
|
|
'gateway': gateway,
|
|
'interface': interface,
|
|
'netmask': netmask,
|
|
'network': network,
|
|
'options': 'metric ' + str(metric)}
|
|
return config
|
|
|
|
def test_get_route_config(self):
|
|
route = {'network': '1.2.3.0',
|
|
'prefix': 24,
|
|
'gateway': '1.2.3.1',
|
|
'metric': 20}
|
|
config = interface.get_route_config(route, "eth0")
|
|
expected = self._get_route_config(
|
|
name='1.2.3.0/24', network='1.2.3.0',
|
|
netmask='255.255.255.0', metric=20)
|
|
self.assertEqual(expected, config)
|
|
|
|
def test_get_route_config_default(self):
|
|
route = {'network': '0.0.0.0',
|
|
'prefix': 0,
|
|
'gateway': '1.2.3.1',
|
|
'metric': 1}
|
|
config = interface.get_route_config(route, "eth0")
|
|
expected = self._get_route_config()
|
|
self.assertEqual(expected, config)
|
|
|
|
def test_is_an_n3000_i40_device_false(self):
|
|
self.assertFalse(
|
|
interface.is_an_n3000_i40_device(self.context, self.iface))
|
|
|
|
def test_find_sriov_interfaces_by_driver_none(self):
|
|
ifaces = interface.find_sriov_interfaces_by_driver(
|
|
self.context, constants.DRIVER_MLX_CX4)
|
|
self.assertTrue(not ifaces)
|
|
|
|
|
|
class InterfaceTestCase2(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|
|
|
def setUp(self):
|
|
super(InterfaceTestCase2, self).setUp()
|
|
self._setup_context()
|
|
|
|
def _setup_configuration(self):
|
|
pass
|
|
|
|
def _update_context(self):
|
|
# skip automatic context update, context updates will be invoked individually
|
|
# in each test function, via the self._do_update_context() method
|
|
pass
|
|
|
|
def _do_update_context(self):
|
|
super(InterfaceTestCase2, self)._update_context()
|
|
|
|
def _create_host(self, personality, subfunction=None):
|
|
self.host = self._create_test_host(personality, subfunction)
|
|
|
|
def _create_host_and_interface(self, ifclass, networktype, **kwargs):
|
|
self.host = self._create_test_host(
|
|
kwargs.get('personality', constants.CONTROLLER),
|
|
kwargs.get('subfunction', None))
|
|
self.port, self.iface = self._create_ethernet_test(
|
|
kwargs.get('name', 'mgmt0'), ifclass, networktype, **kwargs)
|
|
|
|
def _set_address_mode(self, iface, ipv4_mode=constants.IPV4_DISABLED,
|
|
ipv6_mode=constants.IPV6_DISABLED):
|
|
self.dbapi.address_mode_update(iface.id,
|
|
{'family': constants.IPV4_FAMILY, 'mode': ipv4_mode})
|
|
self.dbapi.address_mode_update(iface.id,
|
|
{'family': constants.IPV6_FAMILY, 'mode': ipv6_mode})
|
|
iface.ipv4_mode = ipv4_mode
|
|
iface.ipv6_mode = ipv6_mode
|
|
|
|
def test_is_platform_network_type_true(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._do_update_context()
|
|
result = interface.is_platform_network_type(self.iface)
|
|
self.assertTrue(result)
|
|
|
|
def test_is_platform_network_type_false(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA)
|
|
self._do_update_context()
|
|
result = interface.is_platform_network_type(self.iface)
|
|
self.assertFalse(result)
|
|
|
|
def test_is_worker_subfunction_true(self):
|
|
self._create_host(constants.WORKER)
|
|
self._do_update_context()
|
|
self.assertTrue(interface.is_worker_subfunction(self.context))
|
|
|
|
def test_is_worker_subfunction_true_cpe(self):
|
|
self._create_host(constants.CONTROLLER, constants.WORKER)
|
|
self._do_update_context()
|
|
self.assertTrue(interface.is_worker_subfunction(self.context))
|
|
|
|
def test_is_worker_subfunction_false(self):
|
|
self._create_host(constants.STORAGE)
|
|
self._do_update_context()
|
|
self.assertFalse(interface.is_worker_subfunction(self.context))
|
|
|
|
def test_is_worker_subfunction_false_cpe(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
self._do_update_context()
|
|
self.assertFalse(interface.is_worker_subfunction(self.context))
|
|
|
|
def test_is_pci_interface_true(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._do_update_context()
|
|
self.assertTrue(interface.is_pci_interface(self.iface))
|
|
|
|
def test_is_pci_interface_false(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA)
|
|
self._do_update_context()
|
|
self.assertFalse(interface.is_pci_interface(self.iface))
|
|
|
|
def test_get_lower_interface_vlan(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
vlan = self._create_vlan_test(
|
|
"cluster-host", constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 1, self.iface)
|
|
self._do_update_context()
|
|
value = interface.get_lower_interface(self.context, vlan)
|
|
self.assertEqual(value, self.iface)
|
|
|
|
def test_get_lower_interface_vf(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
name='sriov1', sriov_numvfs=2)
|
|
vf = self._create_vf_test("vf1", 1, None, lower_iface=self.iface)
|
|
self._do_update_context()
|
|
value = interface.get_lower_interface(self.context, vf)
|
|
self.assertEqual(value, self.iface)
|
|
|
|
def test_get_interface_os_ifname_vlan_over_ethernet(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
vlan1 = self._create_vlan_test(
|
|
"cluster-host", constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 1, self.iface)
|
|
vlan2 = self._create_vlan_test(
|
|
"testvlan", constants.INTERFACE_CLASS_NONE,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 1, self.iface)
|
|
vlan3 = self._create_vlan_test(
|
|
"vlan999", constants.INTERFACE_CLASS_NONE,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 1, self.iface)
|
|
vlan4 = self._create_vlan_test(
|
|
"testvlan.999", constants.INTERFACE_CLASS_NONE,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 1, self.iface)
|
|
self._do_update_context()
|
|
self.assertEqual(interface.get_interface_os_ifname(self.context, vlan1),
|
|
"vlan1")
|
|
self.assertEqual(interface.get_interface_os_ifname(self.context, vlan2),
|
|
"testvlan")
|
|
self.assertEqual(interface.get_interface_os_ifname(self.context, vlan3),
|
|
"vlan#999")
|
|
self.assertEqual(interface.get_interface_os_ifname(self.context, vlan4),
|
|
"testvlan#999")
|
|
|
|
def test_get_interface_os_ifname_vlan_over_bond(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
bond = self._create_bond_test("none")
|
|
vlan = self._create_vlan_test(
|
|
"cluster-host", constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 1, bond)
|
|
self._do_update_context()
|
|
value = interface.get_interface_os_ifname(self.context, vlan)
|
|
self.assertEqual(value, "vlan1")
|
|
|
|
def test_get_gateway_address_oam(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM)
|
|
network, address = self._create_address_for_interface(self.iface)
|
|
self._do_update_context()
|
|
gateway = interface.get_gateway_address(self.context, network, address)
|
|
expected = str(self.oam_subnet[1])
|
|
self.assertEqual(gateway, expected)
|
|
|
|
def test_get_gateway_address_mgmt(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
network, address = self._create_address_for_interface(self.iface)
|
|
self._do_update_context()
|
|
gateway = interface.get_gateway_address(self.context, network, address)
|
|
expected = str(self.mgmt_subnet[1])
|
|
self.assertEqual(gateway, expected)
|
|
|
|
def test_get_interface_address_method_for_none(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_NONE,
|
|
constants.NETWORK_TYPE_NONE)
|
|
self._do_update_context()
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface)
|
|
self.assertEqual(method, 'manual')
|
|
|
|
def test_get_interface_address_method_for_data(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA)
|
|
_, address_ipv4 = self._create_address_for_interface(
|
|
self.iface, family=constants.IPV4_FAMILY)
|
|
_, address_ipv6 = self._create_address_for_interface(
|
|
self.iface, family=constants.IPV6_FAMILY)
|
|
self._do_update_context()
|
|
|
|
self.iface['ipv4_mode'] = constants.IPV4_DISABLED
|
|
self.iface['ipv6_mode'] = constants.IPV6_DISABLED
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface)
|
|
self.assertEqual(method, 'manual')
|
|
|
|
self.iface['ipv4_mode'] = constants.IPV4_STATIC
|
|
self.iface['ipv6_mode'] = constants.IPV6_DISABLED
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface)
|
|
self.assertEqual(method, 'manual')
|
|
|
|
self.iface['ipv4_mode'] = constants.IPV4_DISABLED
|
|
self.iface['ipv6_mode'] = constants.IPV6_STATIC
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface)
|
|
self.assertEqual(method, 'manual')
|
|
|
|
self.iface['ipv4_mode'] = constants.IPV4_STATIC
|
|
self.iface['ipv6_mode'] = constants.IPV6_STATIC
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface)
|
|
self.assertEqual(method, 'manual')
|
|
|
|
self.iface['ipv4_mode'] = constants.IPV4_DISABLED
|
|
self.iface['ipv6_mode'] = constants.IPV6_DISABLED
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, None, address_ipv4)
|
|
self.assertEqual(method, 'manual')
|
|
|
|
self.iface['ipv4_mode'] = constants.IPV4_STATIC
|
|
self.iface['ipv6_mode'] = constants.IPV6_DISABLED
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, None, address_ipv4)
|
|
self.assertEqual(method, 'static')
|
|
|
|
self.iface['ipv4_mode'] = constants.IPV4_DISABLED
|
|
self.iface['ipv6_mode'] = constants.IPV6_STATIC
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, None, address_ipv4)
|
|
self.assertEqual(method, 'manual')
|
|
|
|
self.iface['ipv4_mode'] = constants.IPV4_STATIC
|
|
self.iface['ipv6_mode'] = constants.IPV6_STATIC
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, None, address_ipv4)
|
|
self.assertEqual(method, 'static')
|
|
|
|
self.iface['ipv4_mode'] = constants.IPV4_DISABLED
|
|
self.iface['ipv6_mode'] = constants.IPV6_DISABLED
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, None, address_ipv6)
|
|
self.assertEqual(method, 'manual')
|
|
|
|
self.iface['ipv4_mode'] = constants.IPV4_STATIC
|
|
self.iface['ipv6_mode'] = constants.IPV6_DISABLED
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, None, address_ipv6)
|
|
self.assertEqual(method, 'manual')
|
|
|
|
self.iface['ipv4_mode'] = constants.IPV4_DISABLED
|
|
self.iface['ipv6_mode'] = constants.IPV6_STATIC
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, None, address_ipv6)
|
|
self.assertEqual(method, 'static')
|
|
|
|
self.iface['ipv4_mode'] = constants.IPV4_STATIC
|
|
self.iface['ipv6_mode'] = constants.IPV6_STATIC
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, None, address_ipv6)
|
|
self.assertEqual(method, 'static')
|
|
|
|
def test_get_interface_address_method_for_pci_sriov(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._do_update_context()
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface)
|
|
self.assertEqual(method, 'manual')
|
|
|
|
def test_get_interface_address_method_for_pci_pthru(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
self._do_update_context()
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface)
|
|
self.assertEqual(method, 'manual')
|
|
|
|
def test_get_interface_address_method_for_pxeboot_worker(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT,
|
|
personality=constants.WORKER)
|
|
self._do_update_context()
|
|
network = self._find_network_by_type(constants.NETWORK_TYPE_PXEBOOT)
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, network)
|
|
self.assertEqual(method, 'dhcp')
|
|
|
|
def test_get_interface_address_method_for_pxeboot_storage(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT,
|
|
personality=constants.STORAGE)
|
|
self._do_update_context()
|
|
network = self._find_network_by_type(constants.NETWORK_TYPE_PXEBOOT)
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, network)
|
|
self.assertEqual(method, 'dhcp')
|
|
|
|
def test_get_interface_address_method_for_pxeboot_controller(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT)
|
|
self._do_update_context()
|
|
network = self._find_network_by_type(constants.NETWORK_TYPE_PXEBOOT)
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, network)
|
|
self.assertEqual(method, 'static')
|
|
|
|
def test_get_interface_address_method_for_mgmt_worker(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT,
|
|
personality=constants.WORKER)
|
|
self._do_update_context()
|
|
network = self._find_network_by_type(constants.NETWORK_TYPE_MGMT)
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, network)
|
|
self.assertEqual(method, 'static')
|
|
|
|
def test_get_interface_address_method_for_mgmt_storage(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT,
|
|
personality=constants.STORAGE)
|
|
self._do_update_context()
|
|
network = self._find_network_by_type(constants.NETWORK_TYPE_MGMT)
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, network)
|
|
self.assertEqual(method, 'static')
|
|
|
|
def test_get_interface_address_method_for_mgmt_controller(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._do_update_context()
|
|
network = self._find_network_by_type(constants.NETWORK_TYPE_MGMT)
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, network)
|
|
self.assertEqual(method, 'static')
|
|
|
|
def test_get_interface_address_method_for_cluster_host_worker(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT,
|
|
personality=constants.WORKER)
|
|
self._do_update_context()
|
|
network = self._find_network_by_type(constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, network)
|
|
self.assertEqual(method, 'static')
|
|
|
|
def test_get_interface_address_method_for_cluster_host_storage(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST,
|
|
personality=constants.STORAGE)
|
|
self._do_update_context()
|
|
network = self._find_network_by_type(constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, network)
|
|
self.assertEqual(method, 'static')
|
|
|
|
def test_get_interface_address_method_for_cluster_host_controller(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
self._do_update_context()
|
|
network = self._find_network_by_type(constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, network)
|
|
self.assertEqual(method, 'static')
|
|
|
|
def test_get_interface_address_method_for_oam_controller(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM)
|
|
self._do_update_context()
|
|
network = self._find_network_by_type(constants.NETWORK_TYPE_OAM)
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, network)
|
|
self.assertEqual(method, 'static')
|
|
|
|
def test_get_interface_address_method_for_platform_ipv4(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_NONE)
|
|
network, address = self._create_address_for_interface(self.iface)
|
|
self._set_address_mode(self.iface, ipv4_mode=constants.IPV4_STATIC)
|
|
self._do_update_context()
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, network, address)
|
|
self.assertEqual(method, 'static')
|
|
|
|
def test_get_interface_address_method_for_platform_ipv6(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_NONE)
|
|
network, address = self._create_address_for_interface(
|
|
self.iface, family=constants.IPV6_FAMILY)
|
|
self._set_address_mode(self.iface, ipv6_mode=constants.IPV6_STATIC)
|
|
self._do_update_context()
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, network, address)
|
|
self.assertEqual(method, 'static')
|
|
|
|
def test_get_interface_address_method_for_platform_base(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
[constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST])
|
|
self._do_update_context()
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface)
|
|
self.assertEqual(method, 'manual')
|
|
|
|
def test_get_interface_address_method_for_platform_invalid(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM,
|
|
personality=constants.WORKER)
|
|
self._set_address_mode(self.iface, ipv4_mode=constants.IPV4_STATIC)
|
|
self._do_update_context()
|
|
network = self._find_network_by_type(constants.NETWORK_TYPE_OAM)
|
|
method = interface.get_interface_address_method(
|
|
self.context, self.iface, network)
|
|
self.assertEqual(method, 'dhcp')
|
|
|
|
def test_get_interface_traffic_classifier_for_mgmt(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._do_update_context()
|
|
classifier = interface.get_interface_traffic_classifier(
|
|
self.context, self.iface)
|
|
expected = ('%s %s %s %s > /dev/null' %
|
|
(constants.TRAFFIC_CONTROL_SCRIPT,
|
|
self.port['name'], constants.NETWORK_TYPE_MGMT,
|
|
constants.LINK_SPEED_10G))
|
|
self.assertEqual(classifier, expected)
|
|
|
|
def test_get_interface_traffic_classifier_for_cluster_host(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
self._do_update_context()
|
|
classifier = interface.get_interface_traffic_classifier(
|
|
self.context, self.iface)
|
|
self.assertIsNone(classifier)
|
|
|
|
def test_get_interface_traffic_classifier_for_oam(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM)
|
|
self._do_update_context()
|
|
classifier = interface.get_interface_traffic_classifier(
|
|
self.context, self.iface)
|
|
self.assertIsNone(classifier)
|
|
|
|
def test_get_interface_traffic_classifier_for_none(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_NONE,
|
|
constants.NETWORK_TYPE_NONE)
|
|
self._do_update_context()
|
|
classifier = interface.get_interface_traffic_classifier(
|
|
self.context, self.iface)
|
|
self.assertIsNone(classifier)
|
|
|
|
def test_get_sriov_interface_device_id(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
name='sriov1', sriov_numvfs=2)
|
|
self._do_update_context()
|
|
value = interface.get_sriov_interface_device_id(self.context, self.iface)
|
|
self.assertEqual(value, '1572')
|
|
|
|
def test_get_sriov_interface_port(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
name='sriov1', sriov_numvfs=2)
|
|
vf = self._create_vf_test("vf1", 1, None, lower_iface=self.iface)
|
|
self._do_update_context()
|
|
value = interface.get_sriov_interface_port(self.context, vf)
|
|
self.assertEqual(value, self.port)
|
|
|
|
def test_get_sriov_interface_port_invalid(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH,
|
|
name='pthru')
|
|
self._do_update_context()
|
|
self.assertRaises(AssertionError,
|
|
interface.get_sriov_interface_port,
|
|
self.context,
|
|
self.iface)
|
|
|
|
def test_get_sriov_interface_vf_addrs(self):
|
|
vf_addr1 = "0000:81:00.0"
|
|
vf_addr2 = "0000:81:01.0"
|
|
vf_addr_list = [vf_addr1, vf_addr2]
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
name='sriov1', sriov_numvfs=2)
|
|
vf1 = self._create_vf_test("vf1", 1, None, lower_iface=self.iface)
|
|
self._do_update_context()
|
|
addrs1 = interface.get_sriov_interface_vf_addrs(
|
|
self.context, self.iface, vf_addr_list)
|
|
self.assertEqual(len(addrs1), 1)
|
|
addrs2 = interface.get_sriov_interface_vf_addrs(
|
|
self.context, vf1, vf_addr_list)
|
|
self.assertEqual(len(addrs2), 1)
|
|
|
|
def test_get_sriov_interface_vf_addrs_multiple_children(self):
|
|
vf_addr1 = "0000:81:00.0"
|
|
vf_addr2 = "0000:81:01.0"
|
|
vf_addr3 = "0000:81:02.0"
|
|
vf_addr_list = [vf_addr1, vf_addr2, vf_addr3]
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
name='sriov1', sriov_numvfs=3)
|
|
vf1 = self._create_vf_test("vf1", 1, None, lower_iface=self.iface)
|
|
vf2 = self._create_vf_test("vf2", 1, None, lower_iface=self.iface)
|
|
self._do_update_context()
|
|
addrs1 = interface.get_sriov_interface_vf_addrs(
|
|
self.context, vf1, vf_addr_list)
|
|
self.assertEqual(len(addrs1), 1)
|
|
addrs2 = interface.get_sriov_interface_vf_addrs(
|
|
self.context, vf2, vf_addr_list)
|
|
self.assertEqual(len(addrs2), 1)
|
|
addrs3 = interface.get_sriov_interface_vf_addrs(
|
|
self.context, self.iface, vf_addr_list)
|
|
self.assertEqual(len(addrs3), 1)
|
|
|
|
def test_get_sriov_interface_vf_addrs_multiple_parents(self):
|
|
vf_addr1 = "0000:81:00.0"
|
|
vf_addr2 = "0000:81:01.0"
|
|
vf_addr3 = "0000:81:02.0"
|
|
vf_addr_list = [vf_addr1, vf_addr2, vf_addr3]
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
name='sriov1', sriov_numvfs=3)
|
|
vf1 = self._create_vf_test("vf1", 2, None, lower_iface=self.iface)
|
|
vf2 = self._create_vf_test("vf2", 1, None, lower_iface=vf1)
|
|
self._do_update_context()
|
|
addrs1 = interface.get_sriov_interface_vf_addrs(
|
|
self.context, vf1, vf_addr_list)
|
|
self.assertEqual(len(addrs1), 1)
|
|
addrs2 = interface.get_sriov_interface_vf_addrs(
|
|
self.context, vf2, vf_addr_list)
|
|
self.assertEqual(len(addrs2), 1)
|
|
addrs3 = interface.get_sriov_interface_vf_addrs(
|
|
self.context, self.iface, vf_addr_list)
|
|
self.assertEqual(len(addrs3), 1)
|
|
|
|
def test_get_bridge_interface_name_none_dpdk_supported(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
dpdksupport=True)
|
|
self._do_update_context()
|
|
ifname = interface.get_bridge_interface_name(self.context, self.iface)
|
|
self.assertIsNone(ifname)
|
|
|
|
def test_get_bridge_interface_name_none_not_data(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._do_update_context()
|
|
ifname = interface.get_bridge_interface_name(self.context, self.iface)
|
|
self.assertIsNone(ifname)
|
|
|
|
def test_get_bridge_interface_name(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
dpdksupport=False)
|
|
self._do_update_context()
|
|
ifname = interface.get_bridge_interface_name(self.context, self.iface)
|
|
self.assertEqual(ifname, 'br-' + self.port['name'])
|
|
|
|
def test_needs_interface_config_kernel_mgmt(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertTrue(needed)
|
|
|
|
def test_needs_interface_config_kernel_cluster_host(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertTrue(needed)
|
|
|
|
def test_needs_interface_config_kernel_oam(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertTrue(needed)
|
|
|
|
def test_needs_interface_config_data(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
dpdksupport=True)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertFalse(needed)
|
|
|
|
def test_needs_interface_config_data_slow(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
dpdksupport=False)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertFalse(needed)
|
|
|
|
def test_needs_interface_config_data_mlx5(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
driver=constants.DRIVER_MLX_CX4)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertFalse(needed)
|
|
|
|
def test_needs_interface_config_data_slow_worker(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
personality=constants.WORKER,
|
|
dpdksupport=False)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertTrue(needed)
|
|
|
|
def test_needs_interface_config_data_mlx5_worker(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
personality=constants.WORKER,
|
|
driver=constants.DRIVER_MLX_CX4)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertTrue(needed)
|
|
|
|
def test_needs_interface_config_sriov_worker(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
personality=constants.WORKER)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertTrue(needed)
|
|
|
|
def test_needs_interface_config_pthru_worker(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH,
|
|
personality=constants.WORKER)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertTrue(needed)
|
|
|
|
def test_needs_interface_config_data_cpe_worker(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
personality=constants.CONTROLLER,
|
|
subfunction=constants.WORKER,
|
|
dpdksupport=True)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertFalse(needed)
|
|
|
|
def test_needs_interface_config_data_slow_cpe_worker(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
personality=constants.CONTROLLER,
|
|
subfunction=constants.WORKER,
|
|
dpdksupport=False)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertTrue(needed)
|
|
|
|
def test_needs_interface_config_data_mlx5_cpe_worker(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
personality=constants.CONTROLLER,
|
|
subfunction=constants.WORKER,
|
|
driver=constants.DRIVER_MLX_CX4)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertTrue(needed)
|
|
|
|
def test_needs_interface_config_sriov_cpe(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertFalse(needed)
|
|
|
|
def test_needs_interface_config_sriov_cpe_worker(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
personality=constants.CONTROLLER,
|
|
subfunction=constants.WORKER)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertTrue(needed)
|
|
|
|
def test_needs_interface_config_pthru_cpe_worker(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH,
|
|
personality=constants.CONTROLLER,
|
|
subfunction=constants.WORKER)
|
|
self._do_update_context()
|
|
needed = interface.needs_interface_config(self.context, self.iface)
|
|
self.assertTrue(needed)
|
|
|
|
def _get_network_config_ifupdown(self, ifname='eth0', ensure='present',
|
|
family='inet', method='dhcp',
|
|
hotplug='false', onboot='true',
|
|
ipaddress=None, netmask=None,
|
|
options=None):
|
|
config = {'ifname': ifname,
|
|
'ensure': ensure,
|
|
'family': family,
|
|
'method': method,
|
|
'hotplug': hotplug,
|
|
'onboot': onboot}
|
|
if ipaddress:
|
|
config['ipaddress'] = ipaddress
|
|
if netmask:
|
|
config['netmask'] = netmask
|
|
config['options'] = options or {}
|
|
return config
|
|
|
|
def _get_static_network_config_ifupdown(self, **kwargs):
|
|
ifname = kwargs.pop('ifname', 'eth0')
|
|
method = kwargs.pop('method', 'static')
|
|
ipaddress = kwargs.pop('ipaddress', '192.168.1.2')
|
|
netmask = kwargs.pop('netmask', '255.255.255.0')
|
|
return self._get_network_config_ifupdown(
|
|
ifname=ifname, method=method,
|
|
ipaddress=ipaddress, netmask=netmask, **kwargs)
|
|
|
|
def _get_sriov_config(self, ifname='default',
|
|
vf_driver=constants.SRIOV_DRIVER_TYPE_VFIO,
|
|
num_vfs=2, pf_addr=None, device_id='1572',
|
|
port_name="eth0", up_requirement=False,
|
|
vf_config=None):
|
|
if vf_config is None:
|
|
vf_config = {}
|
|
config = {'ifname': ifname,
|
|
'addr': pf_addr if pf_addr else self.port['pciaddr'],
|
|
'device_id': device_id,
|
|
'num_vfs': num_vfs,
|
|
'port_name': port_name,
|
|
'up_requirement': up_requirement,
|
|
'vf_config': vf_config}
|
|
|
|
return config
|
|
|
|
def _get_fpga_config(self, portname='eth1', device_id='0d58', vlans=None):
|
|
config = {
|
|
'ifname': portname,
|
|
'device_id': device_id,
|
|
'used_by': vlans
|
|
}
|
|
|
|
return config
|
|
|
|
def _get_loopback_config(self):
|
|
network_config = self._get_network_config_ifupdown(
|
|
ifname=interface.LOOPBACK_IFNAME, method=interface.LOOPBACK_METHOD)
|
|
return interface.format_network_config(network_config)
|
|
|
|
def _get_ipv6_autoconf_off(self, os_ifname):
|
|
autoconf_off = 'echo 0 > /proc/sys/net/ipv6/conf/{}/autoconf'.format(os_ifname)
|
|
accept_ra_off = 'echo 0 > /proc/sys/net/ipv6/conf/{}/accept_ra'.format(os_ifname)
|
|
accept_redir_off = 'echo 0 > /proc/sys/net/ipv6/conf/{}/accept_redirects'.format(os_ifname)
|
|
ipv6_autocnf_off = '{}; {}; {}'.format(autoconf_off, accept_ra_off, accept_redir_off)
|
|
return ipv6_autocnf_off
|
|
|
|
def _get_postup_mtu(self, os_ifname, mtu):
|
|
set_mtu = '/usr/sbin/ip link set dev {} mtu {}'.format(os_ifname, mtu)
|
|
postup_mtu = '{};'.format(set_mtu)
|
|
return postup_mtu
|
|
|
|
def test_generate_loopback_config(self):
|
|
config = {
|
|
interface.NETWORK_CONFIG_RESOURCE: {},
|
|
}
|
|
interface.generate_loopback_config(config)
|
|
expected = self._get_loopback_config()
|
|
result = config[interface.NETWORK_CONFIG_RESOURCE].get(
|
|
interface.LOOPBACK_IFNAME)
|
|
self.assertEqual(result, expected)
|
|
|
|
def test_get_controller_ethernet_config_oam_ifupdown(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM)
|
|
network, address = self._create_address_for_interface(self.iface)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(
|
|
self.context, self.iface, network)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(self.port['name'])
|
|
options = {'stx-description': 'ifname:mgmt0,net:oam',
|
|
'post-up': '{}'.format(ipv6_autocnf_off),
|
|
'mtu': '1500',
|
|
'gateway': '10.10.10.1'}
|
|
expected = self._get_static_network_config_ifupdown(
|
|
ipaddress='10.10.10.10',
|
|
ifname=f"{self.port['name']}:{network.id}-{address.id}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_ethernet_config_mgmt_ifupdown(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
network, address = self._create_address_for_interface(self.iface)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(
|
|
self.context, self.iface, network)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(self.port['name'])
|
|
options = {'post-up': '%s' % ipv6_autocnf_off,
|
|
'mtu': '1500',
|
|
'stx-description': 'ifname:mgmt0,net:mgmt',
|
|
'gateway': '192.168.204.1'}
|
|
expected = self._get_static_network_config_ifupdown(
|
|
ipaddress='192.168.204.10',
|
|
ifname=f"{self.port['name']}:{network.id}-{address.id}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_ethernet_config_cluster_host_ifupdown(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
network, address = self._create_address_for_interface(self.iface)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(
|
|
self.context, self.iface, network)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(self.port['name'])
|
|
options = {'stx-description': 'ifname:mgmt0,net:cluster-host',
|
|
'post-up': '{}'.format(ipv6_autocnf_off),
|
|
'mtu': '1500',
|
|
'gateway': '192.168.206.1'}
|
|
expected = self._get_static_network_config_ifupdown(
|
|
ipaddress='192.168.206.10',
|
|
ifname=f"{self.port['name']}:{network.id}-{address.id}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_ethernet_config_slave_ifupdown(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
bond = self._create_bond_test("bond0")
|
|
self._do_update_context()
|
|
iface = self.context['interfaces'][bond['uses'][0]]
|
|
port = self.context['ports'][iface['id']]
|
|
configs = interface.get_interface_network_configs(self.context, iface)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(port['name'])
|
|
options = {'allow-bond0': port['name'],
|
|
'bond-master': 'bond0',
|
|
'stx-description': 'ifname:eth0,net:None',
|
|
'pre-up': '/usr/sbin/ip link set dev {} promisc on; {}'.format(port['name'],
|
|
ipv6_autocnf_off),
|
|
'mtu': '1500'}
|
|
expected = self._get_network_config_ifupdown(
|
|
ifname=port['name'], method='manual', options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_ethernet_config_slave_sriov_bond(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
port1, iface1 = self._create_ethernet_test(
|
|
ifclass=constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
sriov_numvfs=16)
|
|
port2, iface2 = self._create_ethernet_test(
|
|
ifclass=constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
sriov_numvfs=16)
|
|
self._create_bond_test("bond0",
|
|
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
|
iface1=iface1,
|
|
iface2=iface2,
|
|
aemode='active_standby',
|
|
primary_reselect=constants.PRIMARY_RESELECT_ALWAYS)
|
|
self._do_update_context()
|
|
|
|
iface = iface1
|
|
port = port1
|
|
configs = interface.get_interface_network_configs(self.context, iface)
|
|
numvfs_path = '/sys/class/net/{}/device/sriov_numvfs'.format(port['name'])
|
|
numvfs_cmd = 'echo 0 > {0}; echo 16 > {0}'.format(numvfs_path)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(port['name'])
|
|
options = {'allow-bond0': port['name'],
|
|
'bond-master': 'bond0',
|
|
'stx-description': 'ifname:{},net:None'.format(iface.ifname),
|
|
'pre-up': '/usr/sbin/ip link set dev {} promisc on; {}; {}'.format(
|
|
port['name'], numvfs_cmd, ipv6_autocnf_off),
|
|
'mtu': '1500'}
|
|
expected = self._get_network_config_ifupdown(ifname=port['name'], method='manual',
|
|
options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
iface = iface2
|
|
port = port2
|
|
configs = interface.get_interface_network_configs(self.context, iface)
|
|
numvfs_path = '/sys/class/net/{}/device/sriov_numvfs'.format(port['name'])
|
|
numvfs_cmd = 'echo 0 > {0}; echo 16 > {0}'.format(numvfs_path)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(port['name'])
|
|
options = {'allow-bond0': port['name'],
|
|
'bond-master': 'bond0',
|
|
'stx-description': 'ifname:{},net:None'.format(iface.ifname),
|
|
'pre-up': '/usr/sbin/ip link set dev {} promisc on; {}; {}'.format(
|
|
port['name'], numvfs_cmd, ipv6_autocnf_off),
|
|
'mtu': '1500'}
|
|
expected = self._get_network_config_ifupdown(ifname=port['name'], method='manual',
|
|
options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_bond_config_duplex_ifupdown(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
system_dict = self.system.as_dict()
|
|
system_dict['system_mode'] = constants.SYSTEM_MODE_DUPLEX
|
|
self.dbapi.isystem_update(self.system.uuid, system_dict)
|
|
bond = self._create_bond_test(
|
|
"bond0", ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
|
networktype=constants.NETWORK_TYPE_MGMT)
|
|
network, address = self._create_address_for_interface(bond)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(self.context, bond, network)
|
|
options = {'bond-lacp-rate': 'fast',
|
|
'bond-miimon': '100',
|
|
'bond-mode': '802.3ad',
|
|
'bond-slaves': 'eth0 eth1 ',
|
|
'bond-xmit-hash-policy': 'layer2',
|
|
'stx-description': 'ifname:bond0,net:mgmt',
|
|
'gateway': '192.168.204.1',
|
|
'hwaddress': '02:11:22:33:44:12',
|
|
'mtu': '1500',
|
|
'post-up': 'echo 0 > /proc/sys/net/ipv6/conf/bond0/autoconf; echo '
|
|
'0 > /proc/sys/net/ipv6/conf/bond0/accept_ra; echo 0 > '
|
|
'/proc/sys/net/ipv6/conf/bond0/accept_redirects',
|
|
'up': 'sleep 10'}
|
|
expected = self._get_static_network_config_ifupdown(
|
|
ipaddress='192.168.204.10',
|
|
ifname=f"{bond['ifname']}:{network.id}-{address.id}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_bond_config_duplex_direct_ifupdown(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
system_dict = self.system.as_dict()
|
|
system_dict['system_mode'] = constants.SYSTEM_MODE_DUPLEX_DIRECT
|
|
self.dbapi.isystem_update(self.system.uuid, system_dict)
|
|
bond = self._create_bond_test(
|
|
"bond0", ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
|
networktype=constants.NETWORK_TYPE_MGMT)
|
|
network, address = self._create_address_for_interface(bond)
|
|
self._do_update_context()
|
|
network = self.dbapi.network_get_by_type(constants.NETWORK_TYPE_MGMT)
|
|
|
|
configs = interface.get_interface_network_configs(self.context, bond)
|
|
options = {'bond-lacp-rate': 'fast',
|
|
'bond-miimon': '100',
|
|
'bond-mode': '802.3ad',
|
|
'bond-slaves': 'eth0 eth1 ',
|
|
'bond-xmit-hash-policy': 'layer2',
|
|
'stx-description': 'ifname:bond0,net:None',
|
|
'hwaddress': '02:11:22:33:44:12',
|
|
'mtu': '1500',
|
|
'post-up': '/usr/local/bin/tc_setup.sh bond0 mgmt 10000 > /dev/null; '
|
|
'echo 0 > /proc/sys/net/ipv6/conf/bond0/autoconf; echo '
|
|
'0 > /proc/sys/net/ipv6/conf/bond0/accept_ra; echo 0 > '
|
|
'/proc/sys/net/ipv6/conf/bond0/accept_redirects',
|
|
'pre-up': '/sbin/modprobe bonding; grep bond0 '
|
|
'/sys/class/net/bonding_masters || echo +bond0 > '
|
|
'/sys/class/net/bonding_masters; sysctl -wq '
|
|
'net.ipv6.conf.bond0.accept_dad=0',
|
|
'up': 'sleep 10'}
|
|
expected = self._get_network_config_ifupdown(
|
|
method='manual', ifname=f"{bond['ifname']}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
configs = interface.get_interface_network_configs(self.context, bond, network)
|
|
options = {'bond-lacp-rate': 'fast',
|
|
'bond-miimon': '100',
|
|
'bond-mode': '802.3ad',
|
|
'bond-slaves': 'eth0 eth1 ',
|
|
'bond-xmit-hash-policy': 'layer2',
|
|
'stx-description': 'ifname:bond0,net:mgmt',
|
|
'gateway': '192.168.204.1',
|
|
'hwaddress': '02:11:22:33:44:12',
|
|
'mtu': '1500',
|
|
'post-up': 'echo 0 > /proc/sys/net/ipv6/conf/bond0/autoconf; echo '
|
|
'0 > /proc/sys/net/ipv6/conf/bond0/accept_ra; echo 0 > '
|
|
'/proc/sys/net/ipv6/conf/bond0/accept_redirects',
|
|
'up': 'sleep 10'}
|
|
expected = self._get_static_network_config_ifupdown(
|
|
ipaddress='192.168.204.10',
|
|
ifname=f"{bond['ifname']}:{network.id}-{address.id}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_bond_config_balanced_ifupdown(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
bond = self._create_bond_test("bond0")
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(self.context, bond)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(bond['ifname'])
|
|
options = {'bond-miimon': '100',
|
|
'bond-slaves': 'eth0 eth1 ',
|
|
'bond-mode': 'balance-xor',
|
|
'bond-xmit-hash-policy': 'layer2',
|
|
'stx-description': 'ifname:bond0,net:None',
|
|
'hwaddress': bond['imac'],
|
|
'mtu': '1500',
|
|
'post-up': '{}'.format(ipv6_autocnf_off),
|
|
'up': 'sleep 10'}
|
|
expected = self._get_network_config_ifupdown(
|
|
ifname=bond['ifname'], method='manual', options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_bond_config_8023ad_ifupdown(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
bond = self._create_bond_test("bond0", aemode='802.3ad')
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(self.context, bond)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(bond['ifname'])
|
|
options = {'bond-lacp-rate': 'fast',
|
|
'bond-miimon': '100',
|
|
'bond-mode': '802.3ad',
|
|
'bond-slaves': 'eth0 eth1 ',
|
|
'bond-xmit-hash-policy': 'layer2',
|
|
'stx-description': 'ifname:bond0,net:None',
|
|
'hwaddress': bond['imac'],
|
|
'mtu': '1500',
|
|
'post-up': '{}'.format(ipv6_autocnf_off),
|
|
'up': 'sleep 10'}
|
|
expected = self._get_network_config_ifupdown(
|
|
ifname=bond['ifname'], method='manual', options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_bond_config_active_standby_ifupdown(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
bond = self._create_bond_test(
|
|
"bond0",
|
|
aemode='active_standby',
|
|
primary_reselect=constants.PRIMARY_RESELECT_ALWAYS)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(self.context, bond)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(bond['ifname'])
|
|
options = {'bond-miimon': '100',
|
|
'bond-mode': 'active-backup',
|
|
'bond-slaves': 'eth0 eth1 ',
|
|
'bond-primary': 'eth0',
|
|
'bond-primary-reselect': 'always',
|
|
'stx-description': 'ifname:bond0,net:None',
|
|
'hwaddress': bond['imac'],
|
|
'mtu': '1500',
|
|
'post-up': '{}'.format(ipv6_autocnf_off),
|
|
'up': 'sleep 10'}
|
|
expected = self._get_network_config_ifupdown(
|
|
ifname=bond['ifname'], method='manual', options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_bond_config_active_standby_primary_reselect_ifupdown(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
bond = self._create_bond_test(
|
|
"bond0",
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT,
|
|
aemode='active_standby',
|
|
primary_reselect=constants.PRIMARY_RESELECT_BETTER)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(self.context, bond)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(bond['ifname'])
|
|
options = {'bond-miimon': '100',
|
|
'bond-mode': 'active-backup',
|
|
'bond-slaves': 'eth0 eth1 ',
|
|
'bond-primary': 'eth0',
|
|
'bond-primary-reselect': 'better',
|
|
'stx-description': 'ifname:bond0,net:None',
|
|
'hwaddress': bond['imac'],
|
|
'mtu': '1500',
|
|
'post-up': '/usr/local/bin/tc_setup.sh bond0 mgmt 10000 > /dev/null; ' +
|
|
'{}'.format(ipv6_autocnf_off),
|
|
'up': 'sleep 10'}
|
|
expected = self._get_network_config_ifupdown(
|
|
ifname=bond['ifname'], method='manual', options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_vlan_config_ifupdown(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
vlan = self._create_vlan_test("vlan1", None, None, 1, self.iface)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(self.context, vlan)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off("vlan#1")
|
|
mtu = '1500'
|
|
set_mtu = self._get_postup_mtu("vlan#1", mtu)
|
|
options = {'stx-description': 'ifname:vlan1,net:None',
|
|
'mtu': mtu,
|
|
'post-down': 'ip link del vlan#1',
|
|
'pre-up': '/sbin/modprobe -q 8021q; ip link add link '
|
|
'{} name vlan#1 type vlan id 1'.format(
|
|
self.port['name']),
|
|
'post-up': '{} {}'.format(set_mtu, ipv6_autocnf_off),
|
|
'vlan-raw-device': '{}'.format(self.port['name'])}
|
|
expected = self._get_network_config_ifupdown(
|
|
ifname="vlan#1", method='manual', options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_vlan_config_ifname_with_dot(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
vlan = self._create_vlan_test("vlan.dot", None, None, 1, self.iface)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(self.context, vlan)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off("vlan.dot")
|
|
mtu = '1500'
|
|
set_mtu = self._get_postup_mtu("vlan.dot", mtu)
|
|
options = {'stx-description': 'ifname:vlan.dot,net:None',
|
|
'mtu': mtu,
|
|
'post-down': 'ip link del vlan.dot',
|
|
'pre-up': '/sbin/modprobe -q 8021q; ip link add link '
|
|
'{} name vlan.dot type vlan id 1'.format(
|
|
self.port['name']),
|
|
'post-up': '{} {}'.format(set_mtu, ipv6_autocnf_off),
|
|
'vlan-raw-device': '{}'.format(self.port['name'])}
|
|
expected = self._get_network_config_ifupdown(
|
|
ifname="vlan.dot", method='manual', options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_vlan_config_duplex_direct_ifupdown(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_NONE,
|
|
constants.NETWORK_TYPE_NONE)
|
|
system_dict = self.system.as_dict()
|
|
system_dict['system_mode'] = constants.SYSTEM_MODE_DUPLEX_DIRECT
|
|
self.dbapi.isystem_update(self.system.uuid, system_dict)
|
|
vlan = self._create_vlan_test(
|
|
"vlan100", constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT, 100, self.iface)
|
|
network, address = self._create_address_for_interface(vlan)
|
|
self._do_update_context()
|
|
|
|
configs = interface.get_interface_network_configs(self.context, vlan)
|
|
options = {'stx-description': 'ifname:vlan100,net:None',
|
|
'mtu': '1500',
|
|
'post-down': 'ip link del vlan100',
|
|
'post-up': '/usr/local/bin/tc_setup.sh vlan100 mgmt 10000 > /dev/null; '
|
|
'/usr/sbin/ip link set dev vlan100 mtu 1500; echo 0 > '
|
|
'/proc/sys/net/ipv6/conf/vlan100/autoconf; echo 0 '
|
|
'> /proc/sys/net/ipv6/conf/vlan100/accept_ra; echo 0 > '
|
|
'/proc/sys/net/ipv6/conf/vlan100/accept_redirects',
|
|
'pre-up': '/sbin/modprobe -q 8021q; ip link add link '
|
|
'{} name vlan100 type vlan id 100; '.format(
|
|
self.port['name']) +
|
|
'sysctl -wq net.ipv6.conf.vlan100.accept_dad=0',
|
|
'vlan-raw-device': '{}'.format(self.port['name'])}
|
|
expected = self._get_network_config_ifupdown(
|
|
method='manual', ifname="vlan100", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
configs = interface.get_interface_network_configs(self.context, vlan, network)
|
|
options = {'stx-description': 'ifname:vlan100,net:mgmt',
|
|
'gateway': '192.168.204.1',
|
|
'mtu': '1500',
|
|
'post-up': '/usr/sbin/ip link set dev vlan100 mtu 1500; echo 0 > '
|
|
'/proc/sys/net/ipv6/conf/vlan100/autoconf; echo 0 '
|
|
'> /proc/sys/net/ipv6/conf/vlan100/accept_ra; echo 0 > '
|
|
'/proc/sys/net/ipv6/conf/vlan100/accept_redirects',
|
|
'pre-up': '/sbin/modprobe -q 8021q',
|
|
'vlan-raw-device': '{}'.format(self.port['name'])}
|
|
expected = self._get_static_network_config_ifupdown(
|
|
ipaddress='192.168.204.10',
|
|
ifname=f"vlan100:{network.id}-{address.id}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_is_disable_dad_required(self):
|
|
self._create_host_and_interface(constants.INTERFACE_CLASS_NONE, constants.NETWORK_TYPE_NONE)
|
|
bond = self._create_bond_test("bond0", constants.INTERFACE_CLASS_PLATFORM)
|
|
vlan = self._create_vlan_test("vlan100", constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT, 100, self.iface)
|
|
mgmt_network = self._find_network_by_type(constants.NETWORK_TYPE_MGMT)
|
|
clhost_network = self._find_network_by_type(constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
|
|
# Ethernet
|
|
self.iface.networktypelist = [constants.NETWORK_TYPE_MGMT]
|
|
self.assertTrue(interface.is_disable_dad_required(self.iface, None))
|
|
self.assertFalse(interface.is_disable_dad_required(self.iface, mgmt_network))
|
|
|
|
self.iface.networktypelist = [constants.NETWORK_TYPE_CLUSTER_HOST]
|
|
self.assertTrue(interface.is_disable_dad_required(self.iface, None))
|
|
self.assertFalse(interface.is_disable_dad_required(self.iface, clhost_network))
|
|
|
|
self.iface.networktypelist = [constants.NETWORK_TYPE_MGMT,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST]
|
|
self.assertTrue(interface.is_disable_dad_required(self.iface, None))
|
|
self.assertFalse(interface.is_disable_dad_required(self.iface, mgmt_network))
|
|
self.assertFalse(interface.is_disable_dad_required(self.iface, clhost_network))
|
|
|
|
# Bond
|
|
bond.networktypelist = [constants.NETWORK_TYPE_MGMT]
|
|
self.assertTrue(interface.is_disable_dad_required(bond, None))
|
|
self.assertFalse(interface.is_disable_dad_required(bond, mgmt_network))
|
|
|
|
bond.networktypelist = [constants.NETWORK_TYPE_CLUSTER_HOST]
|
|
self.assertTrue(interface.is_disable_dad_required(bond, None))
|
|
self.assertFalse(interface.is_disable_dad_required(bond, clhost_network))
|
|
|
|
bond.networktypelist = [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST]
|
|
self.assertTrue(interface.is_disable_dad_required(bond, None))
|
|
self.assertFalse(interface.is_disable_dad_required(bond, mgmt_network))
|
|
self.assertFalse(interface.is_disable_dad_required(bond, clhost_network))
|
|
|
|
# VLAN
|
|
vlan.networktypelist = [constants.NETWORK_TYPE_MGMT]
|
|
self.assertTrue(interface.is_disable_dad_required(vlan, None))
|
|
self.assertFalse(interface.is_disable_dad_required(vlan, mgmt_network))
|
|
|
|
vlan.networktypelist = [constants.NETWORK_TYPE_CLUSTER_HOST]
|
|
self.assertTrue(interface.is_disable_dad_required(vlan, None))
|
|
self.assertFalse(interface.is_disable_dad_required(vlan, clhost_network))
|
|
|
|
vlan.networktypelist = [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST]
|
|
self.assertTrue(interface.is_disable_dad_required(vlan, None))
|
|
self.assertFalse(interface.is_disable_dad_required(vlan, mgmt_network))
|
|
self.assertFalse(interface.is_disable_dad_required(vlan, clhost_network))
|
|
|
|
def test_get_controller_ethernet_config_duplex_direct_mgmt_only(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
system_dict = self.system.as_dict()
|
|
system_dict['system_mode'] = constants.SYSTEM_MODE_DUPLEX_DIRECT
|
|
self.dbapi.isystem_update(self.system.uuid, system_dict)
|
|
network, address = self._create_address_for_interface(self.iface)
|
|
self._do_update_context()
|
|
|
|
configs = interface.get_interface_network_configs(
|
|
self.context, self.iface)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(self.port['name'])
|
|
options = {'post-up': '/usr/local/bin/tc_setup.sh eth0 mgmt 10000 > /dev/null; ' +
|
|
'{}'.format(ipv6_autocnf_off),
|
|
'pre-up': 'sysctl -wq net.ipv6.conf.{}.accept_dad=0'.format(self.port['name']),
|
|
'mtu': '1500',
|
|
'stx-description': 'ifname:mgmt0,net:None'}
|
|
expected = self._get_network_config_ifupdown(
|
|
method='manual', ifname=f"{self.port['name']}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
configs = interface.get_interface_network_configs(
|
|
self.context, self.iface, network)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(self.port['name'])
|
|
options = {'post-up': '%s' % ipv6_autocnf_off,
|
|
'mtu': '1500',
|
|
'stx-description': 'ifname:mgmt0,net:mgmt',
|
|
'gateway': '192.168.204.1'}
|
|
expected = self._get_static_network_config_ifupdown(
|
|
ipaddress='192.168.204.10',
|
|
ifname=f"{self.port['name']}:{network.id}-{address.id}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_ethernet_config_duplex_direct_mgmt_plus_cluster_host(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
[constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST])
|
|
system_dict = self.system.as_dict()
|
|
system_dict['system_mode'] = constants.SYSTEM_MODE_DUPLEX_DIRECT
|
|
self.dbapi.isystem_update(self.system.uuid, system_dict)
|
|
mgmt_network, mgmt_address = self._create_address_for_interface(self.iface,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
clhost_network, clhost_address = self._create_address_for_interface(self.iface,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
self._do_update_context()
|
|
|
|
configs = interface.get_interface_network_configs(
|
|
self.context, self.iface)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(self.port['name'])
|
|
options = {'post-up': '/usr/local/bin/tc_setup.sh eth0 mgmt 10000 > /dev/null; ' +
|
|
'{}'.format(ipv6_autocnf_off),
|
|
'pre-up': 'sysctl -wq net.ipv6.conf.{}.accept_dad=0'.format(self.port['name']),
|
|
'mtu': '1500',
|
|
'stx-description': 'ifname:mgmt0,net:None'}
|
|
expected = self._get_network_config_ifupdown(
|
|
method='manual', ifname=f"{self.port['name']}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
configs = interface.get_interface_network_configs(
|
|
self.context, self.iface, mgmt_network)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(self.port['name'])
|
|
options = {'post-up': '%s' % ipv6_autocnf_off,
|
|
'mtu': '1500',
|
|
'stx-description': 'ifname:mgmt0,net:mgmt',
|
|
'gateway': '192.168.204.1'}
|
|
expected = self._get_static_network_config_ifupdown(
|
|
ipaddress='192.168.204.10',
|
|
ifname=f"{self.port['name']}:{mgmt_network.id}-{mgmt_address.id}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
configs = interface.get_interface_network_configs(
|
|
self.context, self.iface, clhost_network)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(self.port['name'])
|
|
options = {'post-up': '%s' % ipv6_autocnf_off,
|
|
'mtu': '1500',
|
|
'stx-description': 'ifname:mgmt0,net:cluster-host',
|
|
'gateway': '192.168.206.1'}
|
|
expected = self._get_static_network_config_ifupdown(
|
|
ipaddress='192.168.206.10',
|
|
ifname=f"{self.port['name']}:{clhost_network.id}-{clhost_address.id}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_controller_vlan_config_over_bond_ifupdown(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
bond = self._create_bond_test("bond0")
|
|
vlan = self._create_vlan_test("vlan1", None, None, 1, bond)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(self.context, vlan)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off("vlan#1")
|
|
mtu = '1500'
|
|
set_mtu = self._get_postup_mtu("vlan#1", mtu)
|
|
options = {'stx-description': 'ifname:vlan1,net:None',
|
|
'post-down': 'ip link del vlan#1',
|
|
'mtu': mtu,
|
|
'pre-up': '/sbin/modprobe -q 8021q; ip link add link '
|
|
'{} name vlan#1 type vlan id 1'.format(
|
|
bond['ifname']),
|
|
'post-up': '{} {}'.format(set_mtu, ipv6_autocnf_off),
|
|
'vlan-raw-device': '{}'.format(bond['ifname'])}
|
|
expected = self._get_network_config_ifupdown(
|
|
ifname="vlan#1", method='manual', options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_worker_ethernet_config_mgmt_ifupdown(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT,
|
|
personality=constants.WORKER)
|
|
network, address = self._create_address_for_interface(self.iface)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(
|
|
self.context, self.iface, network)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(self.port['name'])
|
|
options = {'stx-description': 'ifname:mgmt0,net:mgmt',
|
|
'mtu': '1500',
|
|
'gateway': '192.168.204.2',
|
|
'post-up': '{}'.format(ipv6_autocnf_off)}
|
|
expected = self._get_static_network_config_ifupdown(
|
|
ipaddress='192.168.204.10',
|
|
ifname=f"{self.port['name']}:{network.id}-{address.id}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_worker_ethernet_config_cluster_host_ifupdown(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST,
|
|
personality=constants.WORKER)
|
|
network, address = self._create_address_for_interface(self.iface)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(
|
|
self.context, self.iface, network)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(self.port['name'])
|
|
options = {'stx-description': 'ifname:mgmt0,net:cluster-host',
|
|
'mtu': '1500',
|
|
'gateway': '192.168.206.1',
|
|
'post-up': '{}'.format(ipv6_autocnf_off)}
|
|
expected = self._get_static_network_config_ifupdown(
|
|
ipaddress='192.168.206.10',
|
|
ifname=f"{self.port['name']}:{network.id}-{address.id}", options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_worker_ethernet_config_pci_sriov_ifupdown(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
personality=constants.WORKER)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(
|
|
self.context, self.iface)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(self.port['name'])
|
|
options = {'stx-description': 'ifname:mgmt0,net:None',
|
|
'mtu': '1500',
|
|
'pre-up': 'echo 0 > /sys/class/net/{}/device/sriov_numvfs;'
|
|
' echo 0 > /sys/class/net/{}/device/sriov_numvfs'.format(
|
|
self.port['name'], self.port['name']),
|
|
'post-up': '{}'.format(ipv6_autocnf_off)}
|
|
expected = self._get_network_config_ifupdown(
|
|
ifname=self.port['name'], method='manual', options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_worker_ethernet_config_pci_pthru_ifupdown(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH,
|
|
personality=constants.WORKER)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(
|
|
self.context, self.iface)
|
|
ipv6_autocnf_off = self._get_ipv6_autoconf_off(self.port['name'])
|
|
options = {'stx-description': 'ifname:mgmt0,net:None',
|
|
'mtu': '1500',
|
|
'pre-up':
|
|
'if [ -f /sys/class/net/{}/device/sriov_numvfs ];'
|
|
' then echo 0 > /sys/class/net/{}/device/sriov_numvfs; fi'.format(
|
|
self.port['name'], self.port['name']),
|
|
'post-up': '{}'.format(ipv6_autocnf_off)}
|
|
expected = self._get_network_config_ifupdown(
|
|
ifname=self.port['name'], method='manual', options=options)
|
|
self.assertEqual(expected, configs[0])
|
|
|
|
def test_get_worker_ethernet_config_pci_sriov_vf(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
name='sriov1', sriov_numvfs=2)
|
|
vf = self._create_vf_test("vf", 1, None, lower_iface=self.iface)
|
|
self._do_update_context()
|
|
configs = interface.get_interface_network_configs(self.context, vf)
|
|
expected = []
|
|
self.assertEqual(expected, configs)
|
|
|
|
def _create_sriov_vf_config(self, iface_vf_driver, port_vf_driver,
|
|
vf_addr_list, num_vfs, max_tx_rate=None):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
name='sriov1',
|
|
iface_sriov_vf_driver=iface_vf_driver,
|
|
sriov_numvfs=num_vfs,
|
|
max_tx_rate=max_tx_rate,
|
|
port_sriov_vf_driver=port_vf_driver,
|
|
sriov_vfs_pci_address=vf_addr_list)
|
|
self._do_update_context()
|
|
|
|
config = interface.get_sriov_config(self.context, self.iface)
|
|
return config
|
|
|
|
def test_get_sriov_config_netdevice(self):
|
|
vf_addr1 = "0000:81:00.0"
|
|
vf_addr2 = "0000:81:01.0"
|
|
device_id = '1572'
|
|
port_name = 'eth0'
|
|
vf_addr_list = "{},{}".format(vf_addr1, vf_addr2)
|
|
num_vfs = 2
|
|
|
|
config = self._create_sriov_vf_config(
|
|
constants.SRIOV_DRIVER_TYPE_NETDEVICE, 'i40evf', vf_addr_list,
|
|
num_vfs)
|
|
expected_vf_config = {
|
|
'0000:81:00.0': {'addr': '0000:81:00.0', 'driver': 'i40evf'},
|
|
'0000:81:01.0': {'addr': '0000:81:01.0', 'driver': 'i40evf'}
|
|
}
|
|
expected = self._get_sriov_config(
|
|
ifname=self.iface['ifname'],
|
|
vf_driver='i40evf',
|
|
num_vfs=num_vfs,
|
|
device_id=device_id,
|
|
port_name=port_name,
|
|
vf_config=expected_vf_config,)
|
|
self.assertEqual(expected, config)
|
|
|
|
def test_get_sriov_config_vfio(self):
|
|
vf_addr1 = "0000:81:00.0"
|
|
vf_addr2 = "0000:81:01.0"
|
|
device_id = '1572'
|
|
port_name = 'eth0'
|
|
vf_addr_list = "{},{}".format(vf_addr1, vf_addr2)
|
|
num_vfs = 4
|
|
|
|
config = self._create_sriov_vf_config(
|
|
constants.SRIOV_DRIVER_TYPE_VFIO, 'i40evf', vf_addr_list,
|
|
num_vfs)
|
|
expected_vf_config = {
|
|
'0000:81:00.0': {'addr': '0000:81:00.0', 'driver': 'vfio-pci'},
|
|
'0000:81:01.0': {'addr': '0000:81:01.0', 'driver': 'vfio-pci'}
|
|
}
|
|
expected = self._get_sriov_config(
|
|
ifname=self.iface['ifname'],
|
|
vf_driver='vfio-pci',
|
|
num_vfs=num_vfs,
|
|
device_id=device_id,
|
|
port_name=port_name,
|
|
vf_config=expected_vf_config)
|
|
self.assertEqual(expected, config)
|
|
|
|
def test_get_sriov_config_default(self):
|
|
vf_addr1 = "0000:81:00.0"
|
|
vf_addr2 = "0000:81:01.0"
|
|
device_id = '1572'
|
|
port_name = 'eth0'
|
|
vf_addr_list = "{},{}".format(vf_addr1, vf_addr2)
|
|
num_vfs = 1
|
|
|
|
config = self._create_sriov_vf_config(
|
|
None, 'i40evf', vf_addr_list, num_vfs)
|
|
expected_vf_config = {
|
|
'0000:81:00.0': {'addr': '0000:81:00.0', 'driver': None},
|
|
'0000:81:01.0': {'addr': '0000:81:01.0', 'driver': None}
|
|
}
|
|
expected = self._get_sriov_config(
|
|
ifname=self.iface['ifname'],
|
|
vf_driver=None,
|
|
device_id=device_id,
|
|
port_name=port_name,
|
|
num_vfs=num_vfs,
|
|
vf_config=expected_vf_config)
|
|
self.assertEqual(expected, config)
|
|
|
|
def test_get_sriov_config_iftype_vf(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
name='sriov1',
|
|
sriov_numvfs=4,
|
|
iface_sriov_vf_driver=None,
|
|
port_sriov_vf_driver="iavf",
|
|
sriov_vfs_pci_address="0000:b1:02.0,0000:b1:02.1,0000:b1:02.2,0000:b1:02.3")
|
|
self._create_vf_test("vf1", 1, 'vfio', lower_iface=self.iface)
|
|
self._do_update_context()
|
|
|
|
config = interface.get_sriov_config(self.context, self.iface)
|
|
|
|
expected_vf_config = {
|
|
'0000:b1:02.0': {'addr': '0000:b1:02.0', 'driver': None},
|
|
'0000:b1:02.1': {'addr': '0000:b1:02.1', 'driver': None},
|
|
'0000:b1:02.2': {'addr': '0000:b1:02.2', 'driver': None},
|
|
'0000:b1:02.3': {'addr': '0000:b1:02.3', 'driver': 'vfio-pci'}
|
|
}
|
|
expected = self._get_sriov_config(
|
|
self.iface['ifname'], None,
|
|
num_vfs=4, pf_addr=self.port['pciaddr'],
|
|
port_name="eth0",
|
|
vf_config=expected_vf_config)
|
|
self.assertEqual(expected, config)
|
|
|
|
def test_get_sriov_config_iftype_vf_nested(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
name='sriov1',
|
|
sriov_numvfs=4,
|
|
iface_sriov_vf_driver=None,
|
|
port_sriov_vf_driver="iavf",
|
|
sriov_vfs_pci_address="0000:b1:02.0,0000:b1:02.1,0000:b1:02.2,0000:b1:02.3")
|
|
vf1 = self._create_vf_test("vf1", 2, 'vfio', lower_iface=self.iface)
|
|
self._create_vf_test("vf2", 1, 'netdevice', lower_iface=vf1)
|
|
self._do_update_context()
|
|
|
|
config = interface.get_sriov_config(self.context, self.iface)
|
|
|
|
expected_vf_config = {
|
|
'0000:b1:02.0': {'addr': '0000:b1:02.0', 'driver': None},
|
|
'0000:b1:02.1': {'addr': '0000:b1:02.1', 'driver': None},
|
|
'0000:b1:02.2': {'addr': '0000:b1:02.2', 'driver': 'vfio-pci'},
|
|
'0000:b1:02.3': {'addr': '0000:b1:02.3', 'driver': 'iavf'}
|
|
}
|
|
expected = self._get_sriov_config(
|
|
self.iface['ifname'], None,
|
|
num_vfs=4, pf_addr=self.port['pciaddr'],
|
|
port_name="eth0",
|
|
vf_config=expected_vf_config)
|
|
self.assertEqual(expected, config)
|
|
|
|
def test_get_sriov_config_iftype_vf_sibling(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
name='sriov1',
|
|
sriov_numvfs=4,
|
|
iface_sriov_vf_driver=None,
|
|
port_sriov_vf_driver="iavf",
|
|
sriov_vfs_pci_address="0000:b1:02.0,0000:b1:02.1,0000:b1:02.2,0000:b1:02.3")
|
|
self._create_vf_test("vf1", 2, 'vfio', lower_iface=self.iface)
|
|
self._create_vf_test("vf2", 1, 'netdevice', lower_iface=self.iface)
|
|
self._do_update_context()
|
|
|
|
config = interface.get_sriov_config(self.context, self.iface)
|
|
|
|
expected_vf_config = {
|
|
'0000:b1:02.0': {'addr': '0000:b1:02.0', 'driver': None},
|
|
'0000:b1:02.1': {'addr': '0000:b1:02.1', 'driver': 'iavf'},
|
|
'0000:b1:02.2': {'addr': '0000:b1:02.2', 'driver': 'vfio-pci'},
|
|
'0000:b1:02.3': {'addr': '0000:b1:02.3', 'driver': 'vfio-pci'}
|
|
}
|
|
expected = self._get_sriov_config(
|
|
self.iface['ifname'], None,
|
|
num_vfs=4, pf_addr=self.port['pciaddr'],
|
|
port_name="eth0",
|
|
vf_config=expected_vf_config)
|
|
self.assertEqual(expected, config)
|
|
|
|
@mock.patch.object(utils, 'get_sriov_vf_index')
|
|
def test_get_sriov_config_with_ratelimit(self, mock_get_sriov_vf_index):
|
|
vf_addr1 = "0000:81:00.0"
|
|
vf_addr2 = "0000:81:01.0"
|
|
device_id = '1572'
|
|
port_name = 'eth0'
|
|
vf_addr_list = "{},{}".format(vf_addr1, vf_addr2)
|
|
num_vfs = 4
|
|
max_tx_rate = 1000
|
|
|
|
mock_get_sriov_vf_index.side_effect = [0, 1]
|
|
config = self._create_sriov_vf_config(
|
|
constants.SRIOV_DRIVER_TYPE_VFIO, 'i40evf', vf_addr_list,
|
|
num_vfs, max_tx_rate)
|
|
expected_vf_config = {
|
|
'0000:81:00.0': {'addr': '0000:81:00.0', 'driver': 'vfio-pci', 'max_tx_rate': 1000,
|
|
'vfnumber': 0},
|
|
'0000:81:01.0': {'addr': '0000:81:01.0', 'driver': 'vfio-pci', 'max_tx_rate': 1000,
|
|
'vfnumber': 1}
|
|
}
|
|
expected = self._get_sriov_config(
|
|
ifname=self.iface['ifname'],
|
|
vf_driver='vfio-pci',
|
|
num_vfs=num_vfs,
|
|
device_id=device_id,
|
|
port_name=port_name,
|
|
vf_config=expected_vf_config)
|
|
self.assertEqual(expected, config)
|
|
|
|
def test_get_sriov_config_vf_sibling_with_ratelimit(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
name='sriov1',
|
|
sriov_numvfs=4,
|
|
iface_sriov_vf_driver=None,
|
|
port_sriov_vf_driver="iavf",
|
|
sriov_vfs_pci_address="0000:b1:02.0,0000:b1:02.1,0000:b1:02.2,0000:b1:02.3")
|
|
self._create_vf_test("vf1", 2, 'vfio', lower_iface=self.iface)
|
|
self._create_vf_test("vf2", 1, 'netdevice', lower_iface=self.iface, max_tx_rate=1000)
|
|
self._do_update_context()
|
|
|
|
config = interface.get_sriov_config(self.context, self.iface)
|
|
|
|
expected_vf_config = {
|
|
'0000:b1:02.0': {'addr': '0000:b1:02.0', 'driver': None},
|
|
'0000:b1:02.1': {'addr': '0000:b1:02.1', 'driver': 'iavf', 'max_tx_rate': 1000,
|
|
'vfnumber': 1},
|
|
'0000:b1:02.2': {'addr': '0000:b1:02.2', 'driver': 'vfio-pci'},
|
|
'0000:b1:02.3': {'addr': '0000:b1:02.3', 'driver': 'vfio-pci'}
|
|
}
|
|
expected = self._get_sriov_config(
|
|
self.iface['ifname'], None,
|
|
num_vfs=4, pf_addr=self.port['pciaddr'],
|
|
port_name="eth0",
|
|
vf_config=expected_vf_config)
|
|
self.assertEqual(expected, config)
|
|
|
|
def test_get_fpga_config(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
name='n3000',
|
|
sriov_numvfs=4,
|
|
iface_sriov_vf_driver=None,
|
|
port_sriov_vf_driver="iavf",
|
|
sriov_vfs_pci_address="0000:b1:02.0,0000:b1:02.1,0000:b1:02.2,0000:b1:02.3",
|
|
pdevice="Ethernet Controller [0d58]")
|
|
self._create_vf_test("vf1", 2, 'vfio', lower_iface=self.iface)
|
|
self._create_vlan_test('oam', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM, 1, lower_iface=self.iface)
|
|
self._do_update_context()
|
|
|
|
config = interface.get_fpga_config(self.context, self.iface)
|
|
|
|
# Since the interface's fpga config is used to determine whether
|
|
# any upper vlan interfaces need to be brought up after an
|
|
# n3000 device is reset, we ensure that no virtual (VF)
|
|
# type interfaces are in the dict.
|
|
expected = self._get_fpga_config(
|
|
portname='eth0', device_id='0d58', vlans=["vlan1"])
|
|
self.assertEqual(expected, config)
|
|
|
|
def test_is_an_n3000_i40_device_true(self):
|
|
self._create_host_and_interface(
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT,
|
|
pdevice="Ethernet Controller [0d58]")
|
|
self._do_update_context()
|
|
self.assertTrue(
|
|
interface.is_an_n3000_i40_device(self.context, self.iface))
|
|
|
|
def test_find_sriov_interfaces_by_driver_one(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
|
|
expected = ['sriov_cx4_0']
|
|
vf_num = 2
|
|
|
|
for ifname in expected:
|
|
self._create_sriov_cx4_if_test(ifname, vf_num)
|
|
self._do_update_context()
|
|
|
|
ifaces = interface.find_sriov_interfaces_by_driver(
|
|
self.context, constants.DRIVER_MLX_CX4)
|
|
|
|
results = [iface['ifname'] for iface in ifaces]
|
|
self.assertEqual(sorted(results), sorted(expected))
|
|
|
|
def test_find_sriov_interfaces_by_driver_two(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
|
|
expected = ['sriov_cx4_0', 'sriov_cx4_1']
|
|
vf_num = 2
|
|
|
|
for ifname in expected:
|
|
self._create_sriov_cx4_if_test(ifname, vf_num)
|
|
self._do_update_context()
|
|
|
|
ifaces = interface.find_sriov_interfaces_by_driver(
|
|
self.context, constants.DRIVER_MLX_CX4)
|
|
|
|
results = [iface['ifname'] for iface in ifaces]
|
|
self.assertEqual(sorted(results), sorted(expected))
|
|
|
|
def _create_sriov_cx4_if_test(self, name, vf_num, **kwargs):
|
|
port, iface = self._create_ethernet_test(
|
|
name, constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
driver=constants.DRIVER_MLX_CX4, sriov_numvfs=vf_num, **kwargs)
|
|
return port, iface
|
|
|
|
|
|
class InterfaceHostTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|
|
|
def setUp(self):
|
|
super(InterfaceHostTestCase, self).setUp()
|
|
self._setup_context()
|
|
self.expected_platform_interfaces = []
|
|
self.expected_data_interfaces = []
|
|
self.expected_pci_interfaces = []
|
|
self.expected_slow_interfaces = []
|
|
self.expected_bridged_interfaces = []
|
|
self.expected_slave_interfaces = []
|
|
self.expected_mlx_interfaces = []
|
|
self.expected_bmc_interface = None
|
|
self._assign_addresses_to_pool()
|
|
self.exp_yaml_config = {}
|
|
|
|
def _setup_configuration(self):
|
|
# Personality is set to worker to avoid issues due to missing OAM
|
|
# interface in this empty/dummy configuration
|
|
self.host = self._create_test_host(constants.WORKER)
|
|
|
|
def _update_context(self):
|
|
# ensure DB entries are updated prior to updating the context which
|
|
# will re-read the entries from the DB.
|
|
self.host.save(self.admin_context)
|
|
super(InterfaceHostTestCase, self)._update_context()
|
|
|
|
def _create_hieradata_directory(self):
|
|
hiera_path = os.path.join(os.environ['VIRTUAL_ENV'], 'hieradata')
|
|
if not os.path.exists(hiera_path):
|
|
os.mkdir(hiera_path, 0o755)
|
|
return hiera_path
|
|
|
|
def _get_config_filename(self, hiera_directory):
|
|
class_name = self.__class__.__name__
|
|
return os.path.join(hiera_directory, class_name) + ".yaml"
|
|
|
|
def test_generate_interface_config_ifupdown(self):
|
|
hieradata_directory = self._create_hieradata_directory()
|
|
config_filename = self._get_config_filename(hieradata_directory)
|
|
with open(config_filename, 'w') as config_file:
|
|
config = self.operator.interface.get_host_config(self.host) # pylint: disable=no-member
|
|
self.assertIsNotNone(config)
|
|
yaml.dump(config, config_file, default_flow_style=False)
|
|
|
|
def test_interface_config_yaml_data_validation(self):
|
|
hieradata_directory = self._create_hieradata_directory()
|
|
config_filename = self._get_config_filename(hieradata_directory)
|
|
with open(config_filename, 'w') as config_file:
|
|
config = self.operator.interface.get_host_config(self.host) # pylint: disable=no-member
|
|
self.assertIsNotNone(config)
|
|
yaml.dump(config, config_file, default_flow_style=False)
|
|
|
|
hiera_data = dict()
|
|
with open(config_filename, 'r') as config_file:
|
|
hiera_data = yaml.safe_load(config_file)
|
|
|
|
self.assertTrue('platform::network::interfaces::network_config' in hiera_data.keys())
|
|
|
|
if len(self.exp_yaml_config):
|
|
intf_cfg = hiera_data['platform::network::interfaces::network_config']
|
|
for exp_intf in self.exp_yaml_config:
|
|
self.assertTrue(exp_intf in intf_cfg.keys())
|
|
if exp_intf != 'lo':
|
|
self.assertEqual(self.exp_yaml_config[exp_intf]['family'],
|
|
intf_cfg[exp_intf]['family'])
|
|
self.assertEqual(self.exp_yaml_config[exp_intf]['method'],
|
|
intf_cfg[exp_intf]['method'])
|
|
self.assertEqual(self.exp_yaml_config[exp_intf]['stx-description'],
|
|
intf_cfg[exp_intf]['options']['stx-description'])
|
|
if self.exp_yaml_config[exp_intf]['tc']:
|
|
self.assertTrue('tc_setup.sh' in intf_cfg[exp_intf]['options']['post-up'])
|
|
else:
|
|
if 'post-up' in intf_cfg[exp_intf]['options'].keys():
|
|
self.assertFalse('tc_setup.sh' in intf_cfg[exp_intf]['options']['post-up'])
|
|
|
|
def test_create_interface_context(self):
|
|
context = self.operator.interface._create_interface_context(self.host) # pylint: disable=no-member
|
|
self.assertIn('personality', context)
|
|
self.assertIn('subfunctions', context)
|
|
self.assertIn('devices', context)
|
|
self.assertIn('ports', context)
|
|
self.assertIn('interfaces', context)
|
|
self.assertIn('addresses', context)
|
|
self.assertIn('routes', context)
|
|
|
|
def test_is_platform_interface(self):
|
|
if not self.expected_platform_interfaces:
|
|
self.assertTrue(True)
|
|
return
|
|
for iface in self.interfaces:
|
|
expected = bool(iface['ifname'] in self.expected_platform_interfaces)
|
|
if interface.is_platform_interface(self.context,
|
|
iface) != expected:
|
|
print("iface %s is %sa kernel interface" % (
|
|
iface['ifname'], ('not ' if expected else '')))
|
|
|
|
self.assertFalse(True)
|
|
|
|
def test_is_data_interface(self):
|
|
if not self.expected_data_interfaces:
|
|
self.assertTrue(True)
|
|
return
|
|
for iface in self.interfaces:
|
|
expected = bool(iface['ifname'] in self.expected_data_interfaces)
|
|
if interface.is_data_interface(self.context, iface) != expected:
|
|
print("iface %s is %sa data interface" % (
|
|
iface['ifname'], ('not ' if expected else '')))
|
|
self.assertFalse(True)
|
|
|
|
def test_is_pci_interface(self):
|
|
if not self.expected_pci_interfaces:
|
|
self.assertTrue(True)
|
|
return
|
|
for iface in self.interfaces:
|
|
expected = bool(iface['ifname'] in self.expected_pci_interfaces)
|
|
if interface.is_pci_interface(iface) != expected:
|
|
print("iface %s is %sa pci interface" % (
|
|
iface['ifname'], ('not ' if expected else '')))
|
|
self.assertFalse(True)
|
|
|
|
def test_is_a_mellanox_device(self):
|
|
if not self.expected_mlx_interfaces:
|
|
self.assertTrue(True)
|
|
return
|
|
for iface in self.interfaces:
|
|
if (iface['iftype'] not in
|
|
[constants.INTERFACE_TYPE_ETHERNET, constants.INTERFACE_TYPE_VF]):
|
|
continue
|
|
expected = bool(iface['ifname'] in self.expected_mlx_interfaces)
|
|
if interface.is_a_mellanox_device(self.context,
|
|
iface) != expected:
|
|
print("iface %s is %sa mellanox device" % (
|
|
iface['ifname'], ('not ' if expected else '')))
|
|
self.assertFalse(True)
|
|
|
|
def test_is_dpdk_compatible_false(self):
|
|
if not self.expected_slow_interfaces:
|
|
self.assertTrue(True)
|
|
return
|
|
for iface in self.interfaces:
|
|
expected = bool(iface['ifname'] in self.expected_slow_interfaces)
|
|
if interface.is_dpdk_compatible(self.context, iface) == expected:
|
|
print("iface %s is %sdpdk compatible" % (
|
|
iface['ifname'], ('not ' if not expected else '')))
|
|
self.assertFalse(True)
|
|
|
|
def test_is_bridged_interface(self):
|
|
if not self.expected_bridged_interfaces:
|
|
self.assertTrue(True)
|
|
return
|
|
for iface in self.interfaces:
|
|
expected = bool(
|
|
iface['ifname'] in self.expected_bridged_interfaces)
|
|
if interface.is_bridged_interface(self.context,
|
|
iface) != expected:
|
|
print("iface %s is %sa bridged interface" % (
|
|
iface['ifname'], ('not ' if expected else '')))
|
|
self.assertFalse(True)
|
|
|
|
def test_is_slave_interface(self):
|
|
if not self.expected_slave_interfaces:
|
|
self.assertTrue(True)
|
|
return
|
|
for iface in self.interfaces:
|
|
expected = bool(iface['ifname'] in self.expected_slave_interfaces)
|
|
if interface.is_slave_interface(self.context, iface) != expected:
|
|
print("iface %s is %sa slave interface" % (
|
|
iface['ifname'], ('not ' if expected else '')))
|
|
self.assertFalse(True)
|
|
|
|
def test_needs_interface_config(self):
|
|
expected_configured = (self.expected_platform_interfaces +
|
|
[self.expected_bmc_interface])
|
|
if interface.is_worker_subfunction(self.context):
|
|
expected_configured += (self.expected_pci_interfaces +
|
|
self.expected_slow_interfaces +
|
|
self.expected_mlx_interfaces)
|
|
if (expected_configured == [None]):
|
|
self.assertTrue(True)
|
|
return
|
|
for iface in self.interfaces:
|
|
expected = bool(iface['ifname'] in expected_configured)
|
|
actual = interface.needs_interface_config(self.context, iface)
|
|
if expected != actual:
|
|
print("iface %s is %sconfigured" % (
|
|
iface['ifname'], ('not ' if expected else '')))
|
|
self.assertFalse(True)
|
|
|
|
|
|
class InterfaceControllerEthernet(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where all platform interfaces are
|
|
# ethernet interfaces.
|
|
self.host = self._create_test_host(constants.CONTROLLER)
|
|
self._create_ethernet_test('oam', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('none')
|
|
|
|
def setUp(self):
|
|
super(InterfaceControllerEthernet, self).setUp()
|
|
self.expected_bmc_interface = 'mgmt'
|
|
self.expected_platform_interfaces = ['oam', 'mgmt', 'cluster-host']
|
|
self.exp_yaml_config = {
|
|
"eth0": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:oam,net:{constants.NETWORK_TYPE_OAM}',
|
|
'tc': False},
|
|
"eth1": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:mgmt,net:{None}', 'tc': True},
|
|
"eth1:1-3": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt,net:{constants.NETWORK_TYPE_PXEBOOT}',
|
|
'tc': False},
|
|
"eth1:2-7": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt,net:{constants.NETWORK_TYPE_MGMT}',
|
|
'tc': False},
|
|
"eth2": {'family': 'inet', 'method': 'static',
|
|
'stx-description': 'ifname:cluster-host,'
|
|
f'net:{constants.NETWORK_TYPE_CLUSTER_HOST}',
|
|
'tc': False},
|
|
"lo": {'family': 'inet', 'method': 'loopback', 'stx-description': '',
|
|
'tc': False},
|
|
}
|
|
|
|
|
|
class InterfaceControllerEthernetCfg2(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where all platform interfaces are
|
|
# ethernet interfaces. In this case the management is assigned
|
|
# to management and cluster-host networks
|
|
|
|
self.host = self._create_test_host(constants.CONTROLLER)
|
|
|
|
self._create_ethernet_test('oam0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM,
|
|
hostname=self.host.hostname)
|
|
|
|
self._create_ethernet_test('mgmt0', constants.INTERFACE_CLASS_PLATFORM,
|
|
[constants.NETWORK_TYPE_MGMT,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST],
|
|
hostname=self.host.hostname)
|
|
|
|
self._create_ethernet_test('none')
|
|
|
|
def setUp(self):
|
|
super(InterfaceControllerEthernetCfg2, self).setUp()
|
|
self.expected_bmc_interface = 'mgmt0'
|
|
self.expected_platform_interfaces = ['oam0', 'mgmt0']
|
|
self.exp_yaml_config = {
|
|
"eth0": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:oam0,net:{constants.NETWORK_TYPE_OAM}',
|
|
'tc': False},
|
|
"eth1": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:mgmt0,net:{None}', 'tc': True},
|
|
"eth1:1-3": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt0,net:{constants.NETWORK_TYPE_PXEBOOT}',
|
|
'tc': False},
|
|
"eth1:2-7": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt0,net:{constants.NETWORK_TYPE_MGMT}',
|
|
'tc': False},
|
|
"eth1:4-15": {'family': 'inet', 'method': 'static',
|
|
'stx-description': 'ifname:mgmt0,'
|
|
f'net:{constants.NETWORK_TYPE_CLUSTER_HOST}',
|
|
'tc': False},
|
|
"lo": {'family': 'inet', 'method': 'loopback', 'stx-description': '',
|
|
'tc': False},
|
|
}
|
|
|
|
|
|
class InterfaceControllerEthernetCfg3(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where all platform interfaces are
|
|
# ethernet interfaces. In this case the management is assigned
|
|
# to management, pxeboot and cluster-host networks
|
|
|
|
self.host = self._create_test_host(constants.CONTROLLER)
|
|
|
|
self._create_ethernet_test('oam0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM,
|
|
hostname=self.host.hostname)
|
|
|
|
self._create_ethernet_test('mgmt0', constants.INTERFACE_CLASS_PLATFORM,
|
|
[constants.NETWORK_TYPE_MGMT,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST,
|
|
constants.NETWORK_TYPE_PXEBOOT],
|
|
hostname=self.host.hostname)
|
|
|
|
self._create_ethernet_test('none')
|
|
|
|
def setUp(self):
|
|
super(InterfaceControllerEthernetCfg3, self).setUp()
|
|
self.expected_bmc_interface = 'mgmt0'
|
|
self.expected_platform_interfaces = ['oam0', 'mgmt0']
|
|
self.exp_yaml_config = {
|
|
"eth0": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:oam0,net:{constants.NETWORK_TYPE_OAM}',
|
|
'tc': False},
|
|
"eth1": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:mgmt0,net:{None}', 'tc': True},
|
|
"eth1:1-3": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt0,net:{constants.NETWORK_TYPE_PXEBOOT}',
|
|
'tc': False},
|
|
"eth1:2-7": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt0,net:{constants.NETWORK_TYPE_MGMT}',
|
|
'tc': False},
|
|
"eth1:4-15": {'family': 'inet', 'method': 'static',
|
|
'stx-description': 'ifname:mgmt0,'
|
|
f'net:{constants.NETWORK_TYPE_CLUSTER_HOST}',
|
|
'tc': False},
|
|
"lo": {'family': 'inet', 'method': 'loopback', 'stx-description': '',
|
|
'tc': False},
|
|
}
|
|
|
|
|
|
class InterfaceControllerBond(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where all platform interfaces are
|
|
# aggregated ethernet interfaces.
|
|
self.host = self._create_test_host(constants.CONTROLLER)
|
|
|
|
self._create_bond_test('oam0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM,
|
|
hostname=self.host.hostname)
|
|
|
|
self._create_bond_test('mgmt0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT,
|
|
hostname=self.host.hostname)
|
|
|
|
self._create_bond_test('cluster-host0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST,
|
|
hostname=self.host.hostname)
|
|
|
|
def setUp(self):
|
|
super(InterfaceControllerBond, self).setUp()
|
|
self.expected_bmc_interface = 'mgmt'
|
|
self.expected_platform_interfaces = ['eth0', 'eth1', 'oam0',
|
|
'eth3', 'eth4', 'mgmt0',
|
|
'eth6', 'eth7', 'cluster-host0']
|
|
self.expected_slave_interfaces = ['eth0', 'eth1',
|
|
'eth3', 'eth4',
|
|
'eth6', 'eth7']
|
|
# the slave interfaces do not match the linux name created by the test database
|
|
# port:eth0 => ifname:eth0, port:eth1 => ifname:eth1
|
|
# port:eth2 => ifname:eth3, port:eth3 => ifname:eth4 (differ)
|
|
# port:eth4 => ifname:eth6, port:eth5 => ifname:eth7 (differ)
|
|
self.exp_yaml_config = {
|
|
"eth0": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth0,net:{None}', 'tc': False},
|
|
"eth1": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth1,net:{None}', 'tc': False},
|
|
"eth2": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth3,net:{None}', 'tc': False},
|
|
"eth3": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth4,net:{None}', 'tc': False},
|
|
"eth4": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth6,net:{None}', 'tc': False},
|
|
"eth5": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth7,net:{None}', 'tc': False},
|
|
"oam0": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:oam0,net:{constants.NETWORK_TYPE_OAM}',
|
|
'tc': False},
|
|
"mgmt0": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:mgmt0,net:{None}', 'tc': True},
|
|
"mgmt0:1-3": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt0,net:{constants.NETWORK_TYPE_PXEBOOT}',
|
|
'tc': False},
|
|
"mgmt0:2-7": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt0,net:{constants.NETWORK_TYPE_MGMT}',
|
|
'tc': False},
|
|
"cluster-host0": {'family': 'inet', 'method': 'static',
|
|
'stx-description': 'ifname:cluster-host0,'
|
|
f'net:{constants.NETWORK_TYPE_CLUSTER_HOST}',
|
|
'tc': False},
|
|
"lo": {'family': 'inet', 'method': 'loopback', 'stx-description': '',
|
|
'tc': False},
|
|
}
|
|
|
|
|
|
class InterfaceControllerVlanOverBond(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where all platform interfaces are
|
|
# vlan interfaces over aggregated ethernet interfaces
|
|
self.host = self._create_test_host(constants.CONTROLLER)
|
|
bond = self._create_bond_test('pxeboot0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT,
|
|
hostname=self.host.hostname)
|
|
|
|
self._create_vlan_test('oam0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM, 1, bond,
|
|
hostname=self.host.hostname)
|
|
|
|
self._create_vlan_test('mgmt0',
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT, 2, bond,
|
|
hostname=self.host.hostname)
|
|
|
|
self._create_vlan_test('cluster-host0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 3, bond,
|
|
hostname=self.host.hostname)
|
|
|
|
self._create_ethernet_test('none')
|
|
|
|
def setUp(self):
|
|
super(InterfaceControllerVlanOverBond, self).setUp()
|
|
self.expected_bmc_interface = 'pxeboot'
|
|
self.expected_platform_interfaces = ['eth0', 'eth1', 'pxeboot0',
|
|
'oam0', 'mgmt0', 'cluster-host0']
|
|
self.expected_slave_interfaces = ['eth0', 'eth1']
|
|
self.exp_yaml_config = {
|
|
"eth0": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth0,net:{None}', 'tc': False},
|
|
"eth1": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth1,net:{None}', 'tc': False},
|
|
"pxeboot0": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:pxeboot0,net:{constants.NETWORK_TYPE_PXEBOOT}',
|
|
'tc': False},
|
|
"vlan1": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:oam0,net:{constants.NETWORK_TYPE_OAM}',
|
|
'tc': False},
|
|
"vlan2": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt0,net:{constants.NETWORK_TYPE_MGMT}',
|
|
'tc': True},
|
|
"vlan3": {'family': 'inet', 'method': 'static',
|
|
'stx-description': 'ifname:cluster-host0,'
|
|
f'net:{constants.NETWORK_TYPE_CLUSTER_HOST}',
|
|
'tc': False},
|
|
"lo": {'family': 'inet', 'method': 'loopback', 'stx-description': '',
|
|
'tc': False},
|
|
}
|
|
|
|
|
|
class InterfaceControllerVlanOverEthernet(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where all platform interfaces are
|
|
# vlan interfaces over ethernet interfaces
|
|
self.host = self._create_test_host(constants.CONTROLLER)
|
|
|
|
port, iface = self._create_ethernet_test(
|
|
'pxeboot', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT, hostname=self.host.hostname)
|
|
|
|
self._create_vlan_test('oam', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM, 1, iface,
|
|
hostname=self.host.hostname)
|
|
|
|
self._create_vlan_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT, 2, iface,
|
|
hostname=self.host.hostname)
|
|
|
|
self._create_vlan_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 3, iface,
|
|
hostname=self.host.hostname)
|
|
|
|
self._create_ethernet_test('none')
|
|
|
|
def setUp(self):
|
|
super(InterfaceControllerVlanOverEthernet, self).setUp()
|
|
self.expected_bmc_interface = 'pxeboot'
|
|
self.expected_platform_interfaces = ['eth0', 'pxeboot', 'oam',
|
|
'mgmt', 'cluster-host']
|
|
|
|
|
|
class InterfaceComputeEthernet(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# worker and all interfaces are ethernet interfaces. Do not explicit
|
|
# attach the PXEboot network
|
|
self.host = self._create_test_host(constants.WORKER)
|
|
_, if_mgmt = self._create_ethernet_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT,
|
|
hostname=self.host.hostname)
|
|
_, if_clhost = self._create_ethernet_test('cluster-host',
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('data', constants.INTERFACE_CLASS_DATA,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('slow', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
dpdksupport=False,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('mlx5', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
driver=constants.DRIVER_MLX_CX4,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('none')
|
|
|
|
self._create_address_for_interface(if_mgmt)
|
|
self._create_address_for_interface(if_clhost)
|
|
|
|
def setUp(self):
|
|
super(InterfaceComputeEthernet, self).setUp()
|
|
self.expected_bmc_interface = 'mgmt'
|
|
self.expected_platform_interfaces = ['mgmt', 'cluster-host']
|
|
self.expected_data_interfaces = ['slow', 'data', 'mlx5']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
self.expected_slow_interfaces = ['slow']
|
|
self.expected_bridged_interfaces = ['slow']
|
|
self.expected_slave_interfaces = []
|
|
self.expected_mlx_interfaces = ['mlx5']
|
|
self.exp_yaml_config = {
|
|
"eth0": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:mgmt,net:{None}', 'tc': True},
|
|
"eth0:1-0": {'family': 'inet', 'method': 'dhcp',
|
|
'stx-description': f'ifname:mgmt,net:{constants.NETWORK_TYPE_PXEBOOT}',
|
|
'tc': False},
|
|
"eth0:2-37": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt,net:{constants.NETWORK_TYPE_MGMT}',
|
|
'tc': False},
|
|
"eth1": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:cluster-host,'
|
|
f'net:{constants.NETWORK_TYPE_CLUSTER_HOST}', 'tc': False},
|
|
"eth3": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:sriov,net:{None}', 'tc': False},
|
|
"eth4": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:pthru,net:{None}', 'tc': False},
|
|
"eth5": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:slow,net:{None}', 'tc': False},
|
|
"eth6": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:mlx5,net:{None}', 'tc': False},
|
|
"lo": {'family': 'inet', 'method': 'loopback', 'stx-description': '',
|
|
'tc': False},
|
|
}
|
|
|
|
|
|
class InterfaceComputeEthernetCfg2(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# worker and all interfaces are ethernet interfaces.
|
|
# Explicitly assign PXEboot network with the management network
|
|
self.host = self._create_test_host(constants.WORKER)
|
|
_, if_mgmt = self._create_ethernet_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
[constants.NETWORK_TYPE_MGMT,
|
|
constants.NETWORK_TYPE_PXEBOOT],
|
|
hostname=self.host.hostname)
|
|
_, if_clhost = self._create_ethernet_test('cluster-host',
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('data', constants.INTERFACE_CLASS_DATA,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('slow', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
dpdksupport=False,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('mlx5', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
driver=constants.DRIVER_MLX_CX4,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('none')
|
|
|
|
self._create_address_for_interface(if_mgmt)
|
|
self._create_address_for_interface(if_clhost)
|
|
|
|
def setUp(self):
|
|
super(InterfaceComputeEthernetCfg2, self).setUp()
|
|
self.expected_bmc_interface = 'mgmt'
|
|
self.expected_platform_interfaces = ['mgmt', 'cluster-host']
|
|
self.expected_data_interfaces = ['slow', 'data', 'mlx5']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
self.expected_slow_interfaces = ['slow']
|
|
self.expected_bridged_interfaces = ['slow']
|
|
self.expected_slave_interfaces = []
|
|
self.expected_mlx_interfaces = ['mlx5']
|
|
self.exp_yaml_config = {
|
|
"eth0": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:mgmt,net:{None}', 'tc': True},
|
|
"eth0:1-0": {'family': 'inet', 'method': 'dhcp',
|
|
'stx-description': f'ifname:mgmt,net:{constants.NETWORK_TYPE_PXEBOOT}',
|
|
'tc': False},
|
|
"eth0:2-37": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt,net:{constants.NETWORK_TYPE_MGMT}',
|
|
'tc': False},
|
|
"eth1": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:cluster-host,'
|
|
f'net:{constants.NETWORK_TYPE_CLUSTER_HOST}', 'tc': False},
|
|
"eth3": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:sriov,net:{None}', 'tc': False},
|
|
"eth4": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:pthru,net:{None}', 'tc': False},
|
|
"eth5": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:slow,net:{None}', 'tc': False},
|
|
"eth6": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:mlx5,net:{None}', 'tc': False},
|
|
"lo": {'family': 'inet', 'method': 'loopback', 'stx-description': '',
|
|
'tc': False},
|
|
}
|
|
|
|
|
|
class InterfaceComputeEthernetCfg3(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# worker and all interfaces are ethernet interfaces.
|
|
# explicitly assign pxeboot network with the cluster-host network
|
|
self.host = self._create_test_host(constants.WORKER)
|
|
_, if_mgmt = self._create_ethernet_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
[constants.NETWORK_TYPE_MGMT],
|
|
hostname=self.host.hostname)
|
|
_, if_clhost = self._create_ethernet_test('cluster-host',
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
[constants.NETWORK_TYPE_CLUSTER_HOST,
|
|
constants.NETWORK_TYPE_PXEBOOT],
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('data', constants.INTERFACE_CLASS_DATA,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('slow', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
dpdksupport=False,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('mlx5', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
driver=constants.DRIVER_MLX_CX4,
|
|
hostname=self.host.hostname)
|
|
self._create_ethernet_test('none')
|
|
|
|
self._create_address_for_interface(if_mgmt)
|
|
self._create_address_for_interface(if_clhost)
|
|
|
|
def setUp(self):
|
|
super(InterfaceComputeEthernetCfg3, self).setUp()
|
|
self.expected_bmc_interface = 'mgmt'
|
|
self.expected_platform_interfaces = ['mgmt', 'cluster-host']
|
|
self.expected_data_interfaces = ['slow', 'data', 'mlx5']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
self.expected_slow_interfaces = ['slow']
|
|
self.expected_bridged_interfaces = ['slow']
|
|
self.expected_slave_interfaces = []
|
|
self.expected_mlx_interfaces = ['mlx5']
|
|
self.exp_yaml_config = {
|
|
"eth0": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt,net:{constants.NETWORK_TYPE_MGMT}',
|
|
'tc': True},
|
|
"eth1": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:cluster-host,net:{None}', 'tc': False},
|
|
"eth1:1-0": {'family': 'inet', 'method': 'dhcp',
|
|
'stx-description': f'ifname:cluster-host,net:{constants.NETWORK_TYPE_PXEBOOT}',
|
|
'tc': False},
|
|
"eth1:4-38": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:cluster-host,'
|
|
f'net:{constants.NETWORK_TYPE_CLUSTER_HOST}', 'tc': False},
|
|
"eth3": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:sriov,net:{None}', 'tc': False},
|
|
"eth4": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:pthru,net:{None}', 'tc': False},
|
|
"eth5": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:slow,net:{None}', 'tc': False},
|
|
"eth6": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:mlx5,net:{None}', 'tc': False},
|
|
"lo": {'family': 'inet', 'method': 'loopback', 'stx-description': '',
|
|
'tc': False},
|
|
}
|
|
|
|
|
|
class InterfaceComputeVlanOverEthernet(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# worker and all interfaces are vlan interfaces over ethernet
|
|
# interfaces.
|
|
self.host = self._create_test_host(constants.WORKER)
|
|
port, iface = self._create_ethernet_test(
|
|
'pxeboot', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT)
|
|
self._create_vlan_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT, 2, iface)
|
|
self._create_vlan_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 3)
|
|
# since the system vswitch_type is ovs-dpdk, it will not generate config for 'data'
|
|
self._create_vlan_test('data', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA, 5)
|
|
self._create_ethernet_test('sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
|
|
def setUp(self):
|
|
super(InterfaceComputeVlanOverEthernet, self).setUp()
|
|
self.expected_bmc_interface = 'pxeboot'
|
|
self.expected_platform_interfaces = ['pxeboot', 'mgmt',
|
|
'eth2', 'cluster-host']
|
|
self.expected_data_interfaces = ['eth4', 'data']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
self.exp_yaml_config = {
|
|
"eth0": {'family': 'inet', 'method': 'dhcp',
|
|
'stx-description': f'ifname:pxeboot,net:{constants.NETWORK_TYPE_PXEBOOT}',
|
|
'tc': False},
|
|
"eth1": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth2,net:{None}', 'tc': False},
|
|
"vlan2": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt,net:{constants.NETWORK_TYPE_MGMT}',
|
|
'tc': True},
|
|
"vlan3": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:cluster-host,'
|
|
f'net:{constants.NETWORK_TYPE_CLUSTER_HOST}',
|
|
'tc': False},
|
|
"eth3": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:sriov,net:{None}', 'tc': False},
|
|
"eth4": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:pthru,net:{None}', 'tc': False},
|
|
"lo": {'family': 'inet', 'method': 'loopback', 'stx-description': '',
|
|
'tc': False},
|
|
}
|
|
|
|
|
|
class InterfaceComputeVlanOverEthernetCfg2(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# worker and all interfaces are vlan interfaces over ethernet
|
|
# interfaces, mgmt interface handles mgmt and cluster-hos networks
|
|
self.host = self._create_test_host(constants.WORKER)
|
|
|
|
system_dict = self.system.as_dict()
|
|
system_dict['capabilities']['vswitch_type'] = constants.VSWITCH_TYPE_NONE
|
|
dbutils.update_test_isystem(system_dict)
|
|
|
|
port, iface = self._create_ethernet_test(
|
|
'pxeboot', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT)
|
|
if_mgmt = self._create_vlan_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
[constants.NETWORK_TYPE_MGMT,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST],
|
|
2, iface)
|
|
self._create_vlan_test('data', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA, 5)
|
|
self._create_ethernet_test('sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
|
|
self._create_address_for_interface(if_mgmt, constants.NETWORK_TYPE_MGMT)
|
|
self._create_address_for_interface(if_mgmt, constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
|
|
def setUp(self):
|
|
super(InterfaceComputeVlanOverEthernetCfg2, self).setUp()
|
|
self.exp_yaml_config = {
|
|
"data": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:data,net:{None}', 'tc': False},
|
|
"eth0": {'family': 'inet', 'method': 'dhcp',
|
|
'stx-description': f'ifname:pxeboot,net:{constants.NETWORK_TYPE_PXEBOOT}',
|
|
'tc': False},
|
|
"eth1": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth2,net:{None}', 'tc': False},
|
|
"vlan2": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:mgmt,net:{None}', 'tc': True},
|
|
"vlan2:2-37": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt,net:{constants.NETWORK_TYPE_MGMT}',
|
|
'tc': False},
|
|
"vlan2:4-38": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt,'
|
|
f'net:{constants.NETWORK_TYPE_CLUSTER_HOST}',
|
|
'tc': False},
|
|
"eth2": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:sriov,net:{None}', 'tc': False},
|
|
"eth3": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:pthru,net:{None}', 'tc': False},
|
|
"lo": {'family': 'inet', 'method': 'loopback', 'stx-description': '',
|
|
'tc': False},
|
|
}
|
|
|
|
|
|
class InterfaceComputeVfOverSriov(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# worker and all interfaces are ethernet interfaces, aside from
|
|
# a VF interface over SR-IOV
|
|
self.host = self._create_test_host(constants.WORKER)
|
|
self._create_ethernet_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._create_ethernet_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
self._create_ethernet_test('data', constants.INTERFACE_CLASS_DATA)
|
|
port, iface = self._create_ethernet_test(
|
|
'sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV, sriov_numvfs=2,
|
|
sriov_vf_driver=None)
|
|
self._create_vf_test("vf", 1, None, lower_iface=iface)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
|
|
# Mellanox devices should be identified correctly whether they are
|
|
# the SR-IOV interface or a VF interface on top of another.
|
|
# Driver can also be a string of different comma separated driver
|
|
# names, this also tests for that
|
|
port, iface = self._create_ethernet_test(
|
|
'mlx5', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV, sriov_numvfs=2,
|
|
driver=('%s,%s' % (constants.DRIVER_MLX_CX4, constants.DRIVER_MLX_CX4)))
|
|
self._create_vf_test('vf_mlx5', 1, None, lower_iface=iface)
|
|
|
|
def setUp(self):
|
|
super(InterfaceComputeVfOverSriov, self).setUp()
|
|
self.expected_bmc_interface = 'pxeboot'
|
|
self.expected_platform_interfaces = ['pxeboot', 'mgmt',
|
|
'eth2', 'cluster-host']
|
|
self.expected_data_interfaces = ['eth4', 'data']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru', 'vf', 'mlx5', 'vf_mlx5']
|
|
self.expected_mlx_interfaces = ['mlx5', 'vf_mlx5']
|
|
|
|
|
|
class InterfaceComputeBond(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# worker and all interfaces are aggregated ethernet interfaces.
|
|
self.host = self._create_test_host(constants.WORKER)
|
|
if_mgmt = self._create_bond_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
if_clhost = self._create_bond_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
self._create_bond_test('data', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA)
|
|
self._create_ethernet_test('sriov',
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._create_ethernet_test('pthru',
|
|
constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
|
|
self._create_address_for_interface(if_mgmt)
|
|
self._create_address_for_interface(if_clhost)
|
|
|
|
def setUp(self):
|
|
super(InterfaceComputeBond, self).setUp()
|
|
self.expected_bmc_interface = 'mgmt'
|
|
self.expected_platform_interfaces = ['eth0', 'eth1', 'mgmt',
|
|
'eth3', 'eth4', 'cluster-host']
|
|
self.expected_data_interfaces = ['eth6', 'eth7', 'data',
|
|
'eth12', 'eth13', 'ex']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
self.expected_slave_interfaces = ['eth0', 'eth1', 'eth3', 'eth4',
|
|
'eth6', 'eth7', 'eth9', 'eth10',
|
|
'eth12', 'eth13']
|
|
self.exp_yaml_config = {
|
|
"eth0": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth0,net:{None}', 'tc': False},
|
|
"eth1": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth1,net:{None}', 'tc': False},
|
|
"mgmt": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:mgmt,net:{None}', 'tc': True},
|
|
"mgmt:1-0": {'family': 'inet', 'method': 'dhcp',
|
|
'stx-description': f'ifname:mgmt,net:{constants.NETWORK_TYPE_PXEBOOT}',
|
|
'tc': False},
|
|
"mgmt:2-37": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt,net:{constants.NETWORK_TYPE_MGMT}',
|
|
'tc': False},
|
|
"eth2": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth3,net:{None}', 'tc': False},
|
|
"eth3": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth4,net:{None}', 'tc': False},
|
|
"cluster-host": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:cluster-host,'
|
|
f'net:{constants.NETWORK_TYPE_CLUSTER_HOST}',
|
|
'tc': False},
|
|
"eth6": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:sriov,net:{None}', 'tc': False},
|
|
"eth7": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:pthru,net:{None}', 'tc': False},
|
|
"lo": {'family': 'inet', 'method': 'loopback', 'stx-description': '',
|
|
'tc': False},
|
|
}
|
|
|
|
|
|
class InterfaceComputeVlanOverBond(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# worker and all interfaces are vlan interfaces over ethernet
|
|
# interfaces.
|
|
self.host = self._create_test_host(constants.WORKER)
|
|
bond = self._create_bond_test('pxeboot',
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT)
|
|
self._create_vlan_test('oam', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM, 1, bond)
|
|
self._create_vlan_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT, 2, bond)
|
|
self._create_vlan_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 3, bond)
|
|
bond2 = self._create_bond_test('bond2')
|
|
self._create_vlan_test('data', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA, 5, bond2)
|
|
self._create_ethernet_test('sriov',
|
|
constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._create_ethernet_test('pthru',
|
|
constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
|
|
def setUp(self):
|
|
super(InterfaceComputeVlanOverBond, self).setUp()
|
|
self.expected_platform_interfaces = ['eth0', 'eth1', 'pxeboot',
|
|
'oam', 'mgmt', 'cluster-host']
|
|
self.expected_data_interfaces = ['eth6', 'eth7', 'bond2', 'data',
|
|
'eth14', 'eth15']
|
|
self.expected_slave_interfaces = ['eth0', 'eth1',
|
|
'eth6', 'eth7',
|
|
'eth10', 'eth11']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
self.exp_yaml_config = {
|
|
"eth0": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth0,net:{None}', 'tc': False},
|
|
"eth1": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:eth1,net:{None}', 'tc': False},
|
|
"pxeboot": {'family': 'inet', 'method': 'dhcp',
|
|
'stx-description': f'ifname:pxeboot,net:{constants.NETWORK_TYPE_PXEBOOT}',
|
|
'tc': False},
|
|
"vlan1": {'family': 'inet', 'method': 'dhcp',
|
|
'stx-description': f'ifname:oam,net:{constants.NETWORK_TYPE_OAM}',
|
|
'tc': False},
|
|
"vlan2": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:mgmt,net:{constants.NETWORK_TYPE_MGMT}',
|
|
'tc': True},
|
|
"vlan3": {'family': 'inet', 'method': 'static',
|
|
'stx-description': f'ifname:cluster-host,'
|
|
f'net:{constants.NETWORK_TYPE_CLUSTER_HOST}',
|
|
'tc': False},
|
|
"eth4": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:sriov,net:{None}', 'tc': False},
|
|
"eth5": {'family': 'inet', 'method': 'manual',
|
|
'stx-description': f'ifname:pthru,net:{None}', 'tc': False},
|
|
"lo": {'family': 'inet', 'method': 'loopback', 'stx-description': '',
|
|
'tc': False},
|
|
}
|
|
|
|
|
|
class InterfaceCpeEthernet(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# controller with a controller subfunction and all interfaces are
|
|
# ethernet interfaces.
|
|
self.host = self._create_test_host(constants.CONTROLLER)
|
|
self._create_ethernet_test('oam', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM)
|
|
self._create_ethernet_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._create_ethernet_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
self._create_ethernet_test('data', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA)
|
|
self._create_ethernet_test('sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
port, iface = (
|
|
self._create_ethernet_test('slow', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
dpdksupport=False))
|
|
port, iface = (
|
|
self._create_ethernet_test('mlx5', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
driver=constants.DRIVER_MLX_CX4))
|
|
self._create_ethernet_test('none')
|
|
|
|
def setUp(self):
|
|
super(InterfaceCpeEthernet, self).setUp()
|
|
self.expected_bmc_interface = 'mgmt'
|
|
self.expected_platform_interfaces = ['oam', 'mgmt', 'cluster-host']
|
|
self.expected_data_interfaces = ['slow', 'data', 'mlx5']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
self.expected_slow_interfaces = ['slow']
|
|
self.expected_bridged_interfaces = ['slow']
|
|
self.expected_slave_interfaces = []
|
|
self.expected_mlx_interfaces = ['mlx5']
|
|
|
|
|
|
class InterfaceCpeVlanOverEthernet(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# controller with a controller subfunction and all interfaces are
|
|
# vlan interfaces over ethernet interfaces.
|
|
self.host = self._create_test_host(constants.CONTROLLER)
|
|
port, iface = self._create_ethernet_test(
|
|
'pxeboot', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT)
|
|
self._create_vlan_test('oam', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM, 1, iface)
|
|
self._create_vlan_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT, 2, iface)
|
|
self._create_vlan_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 3)
|
|
self._create_vlan_test('data', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA, 5)
|
|
self._create_ethernet_test('sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
|
|
def setUp(self):
|
|
super(InterfaceCpeVlanOverEthernet, self).setUp()
|
|
self.expected_bmc_interface = 'pxeboot'
|
|
self.expected_platform_interfaces = ['pxeboot', 'mgmt', 'oam',
|
|
'eth3', 'cluster-host']
|
|
self.expected_data_interfaces = ['eth5', 'data']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
|
|
|
|
class InterfaceCpeBond(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# controller with a controller subfunction and all interfaces are
|
|
# aggregated ethernet interfaces.
|
|
self.host = self._create_test_host(constants.CONTROLLER)
|
|
self._create_bond_test('oam', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM)
|
|
self._create_bond_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._create_bond_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
self._create_bond_test('data', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA)
|
|
self._create_ethernet_test('sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
|
|
def setUp(self):
|
|
super(InterfaceCpeBond, self).setUp()
|
|
self.expected_bmc_interface = 'mgmt'
|
|
self.expected_platform_interfaces = ['eth0', 'eth1', 'oam',
|
|
'eth3', 'eth4', 'mgmt',
|
|
'eth6', 'eth7', 'cluster-host']
|
|
self.expected_data_interfaces = ['eth9', 'eth10', 'data']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
self.expected_slave_interfaces = ['eth0', 'eth1', 'eth3', 'eth4',
|
|
'eth6', 'eth7', 'eth9', 'eth10',
|
|
'eth12', 'eth13']
|
|
|
|
|
|
class InterfaceCpeVlanOverBond(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# controller with a controller subfunction and all interfaces are
|
|
# vlan interfaces over aggregated ethernet interfaces.
|
|
self.host = self._create_test_host(constants.CONTROLLER)
|
|
bond = self._create_bond_test('pxeboot', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT)
|
|
self._create_vlan_test('oam', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM, 1, bond)
|
|
self._create_vlan_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT, 2, bond)
|
|
self._create_vlan_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 3, bond)
|
|
bond2 = self._create_bond_test('bond4')
|
|
self._create_vlan_test('data', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA, 5,
|
|
bond2)
|
|
self._create_ethernet_test('sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
|
|
def setUp(self):
|
|
super(InterfaceCpeVlanOverBond, self).setUp()
|
|
self.expected_platform_interfaces = ['eth0', 'eth1', 'pxeboot',
|
|
'oam', 'mgmt', 'cluster-host']
|
|
self.expected_data_interfaces = ['eth6', 'eth7', 'bond4', 'data']
|
|
self.expected_slave_interfaces = ['eth0', 'eth1',
|
|
'eth6', 'eth7']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
|
|
|
|
class InterfaceCpeComputeEthernet(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# controller with a worker subfunction and all interfaces are
|
|
# ethernet interfaces.
|
|
self.host = self._create_test_host(constants.CONTROLLER, constants.WORKER)
|
|
self._create_ethernet_test('data', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA)
|
|
self._create_ethernet_test('sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
self._create_ethernet_test('oam', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM)
|
|
self._create_ethernet_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._create_ethernet_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
port, iface = (
|
|
self._create_ethernet_test('slow', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
dpdksupport=False))
|
|
port, iface = (
|
|
self._create_ethernet_test('mlx5', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA,
|
|
driver=constants.DRIVER_MLX_CX4))
|
|
self._create_ethernet_test('none')
|
|
|
|
def setUp(self):
|
|
super(InterfaceCpeComputeEthernet, self).setUp()
|
|
self.expected_bmc_interface = 'mgmt'
|
|
self.expected_platform_interfaces = ['oam', 'mgmt', 'cluster-host']
|
|
self.expected_data_interfaces = ['slow', 'data', 'mlx5']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
self.expected_slow_interfaces = ['slow']
|
|
self.expected_bridged_interfaces = ['slow']
|
|
self.expected_slave_interfaces = []
|
|
self.expected_mlx_interfaces = ['mlx5']
|
|
|
|
|
|
class InterfaceCpeComputeVlanOverEthernet(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# controller with a worker subfunction and all interfaces are
|
|
# vlan interfaces over ethernet interfaces.
|
|
self.host = self._create_test_host(constants.CONTROLLER, constants.WORKER)
|
|
port, iface = self._create_ethernet_test(
|
|
'pxeboot', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT)
|
|
self._create_vlan_test('oam', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM, 1, iface)
|
|
self._create_vlan_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT, 2, iface)
|
|
self._create_vlan_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 3)
|
|
self._create_vlan_test('data', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA, 5)
|
|
self._create_ethernet_test('sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
|
|
def setUp(self):
|
|
super(InterfaceCpeComputeVlanOverEthernet, self).setUp()
|
|
self.expected_bmc_interface = 'pxeboot'
|
|
self.expected_platform_interfaces = ['pxeboot', 'oam', 'mgmt',
|
|
'eth3', 'cluster-host']
|
|
self.expected_data_interfaces = ['eth5', 'data']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
|
|
|
|
class InterfaceCpeComputeBond(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# controller with a worker subfunction and all interfaces are
|
|
# aggregated ethernet interfaces.
|
|
self.host = self._create_test_host(constants.CONTROLLER, constants.WORKER)
|
|
self._create_bond_test('oam', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM)
|
|
self._create_bond_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._create_bond_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
self._create_bond_test('data', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA)
|
|
self._create_ethernet_test('sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
|
|
def setUp(self):
|
|
super(InterfaceCpeComputeBond, self).setUp()
|
|
self.expected_bmc_interface = 'mgmt'
|
|
self.expected_platform_interfaces = ['eth0', 'eth1', 'oam',
|
|
'eth3', 'eth4', 'mgmt',
|
|
'eth6', 'eth7', 'cluster-host']
|
|
self.expected_data_interfaces = ['eth9', 'eth10', 'data']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
self.expected_slave_interfaces = ['eth0', 'eth1', 'eth3', 'eth4',
|
|
'eth6', 'eth7', 'eth9', 'eth10',
|
|
'eth12', 'eth13']
|
|
|
|
|
|
class InterfaceCpeComputeVlanOverBond(InterfaceHostTestCase):
|
|
def _setup_configuration(self):
|
|
# Setup a sample configuration where the personality is set to a
|
|
# controller with a worker subfunction and all interfaces are
|
|
# vlan interfaces over aggregated ethernet interfaces.
|
|
self.host = self._create_test_host(constants.CONTROLLER, constants.WORKER)
|
|
bond = self._create_bond_test('pxeboot',
|
|
constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT)
|
|
self._create_vlan_test('oam', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_OAM, 1, bond)
|
|
self._create_vlan_test('mgmt', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT, 2, bond)
|
|
self._create_vlan_test('cluster-host', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST, 3, bond)
|
|
bond2 = self._create_bond_test('bond2')
|
|
self._create_vlan_test('data', constants.INTERFACE_CLASS_DATA,
|
|
constants.NETWORK_TYPE_DATA, 5,
|
|
bond2)
|
|
self._create_ethernet_test('sriov', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._create_ethernet_test('pthru', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
|
|
def setUp(self):
|
|
super(InterfaceCpeComputeVlanOverBond, self).setUp()
|
|
self.expected_platform_interfaces = ['eth0', 'eth1', 'pxeboot',
|
|
'oam', 'mgmt', 'cluster-host']
|
|
self.expected_data_interfaces = ['eth6', 'eth7', 'bond2', 'data']
|
|
self.expected_slave_interfaces = ['eth0', 'eth1',
|
|
'eth6', 'eth7']
|
|
self.expected_pci_interfaces = ['sriov', 'pthru']
|
|
|
|
|
|
# Mnemonics for building expected interface configs
|
|
NET = 'net' # Expected network type, constants.NETWORK_TYPE_<type> or None
|
|
FAMILY = 'family' # Expected family, INET or INET6
|
|
INET = 'inet' # Value 'inet' for expected FAMILY
|
|
INET6 = 'inet6' # Value 'inet6' for expected FAMILY
|
|
METHOD = 'method' # Expected method, STATIC or MANUAL
|
|
STATIC = 'static' # Value 'static' for expected METHOD
|
|
MANUAL = 'manual' # Value 'manual' for expected METHOD
|
|
DHCP = 'dhcp' # Value 'dhcp' for expected METHOD
|
|
OPTIONS = 'options' # Expected options, dictionary
|
|
GATEWAY = 'gateway' # Option 'gateway', True if gateway address must be present
|
|
ALLOW = 'allow' # Option 'allow-<master>' for bond slaves, True if must be present
|
|
UP = 'up' # Option 'up' operation, should be a list of command mnemonics
|
|
PRE_UP = 'pre-up' # Option 'pre-up' operation, should be a list of command mnemonics
|
|
POST_UP = 'post-up' # Option 'post-up' operation, should be a list of command mnemonics
|
|
DOWN = 'down' # Option 'down' operation, should be a list of command mnemonics
|
|
PRE_DOWN = 'pre-down' # Option 'pre-down' operation, should be a list of command mnemonics
|
|
POST_DOWN = 'post-down' # Option 'post-down' operation, should be a list of command mnemonics
|
|
IPV6_CFG = 'ipv6-cfg' # Operation command to set IPv6 autoconf, accept_ra and accept_redirects
|
|
SET_MTU = 'set-mtu' # Operation command to set MTU
|
|
SET_TC = 'set-tc' # Operation command to configure traffic classifier
|
|
VLAN_MOD = 'vlan-mod' # Operation command to add vlan kernel module
|
|
VLAN_ADD = 'vlan-add' # Operation command to create vlan
|
|
VLAN_DEL = 'vlan-del' # Operation command to remove vlan
|
|
PROMISC_ON = 'prmsc-on' # Operation command to enable promiscuous mode
|
|
UNDEPR = 'undepr' # Operation command to undeprecate IPv6 address
|
|
SRIOV = 'sriov' # Operation command to setup sriov
|
|
PTHROUGH = 'pthrough' # Operation command to setup pass-through
|
|
SLEEP = 'sleep' # Operation command to sleep for 10 seconds
|
|
BOND_SETUP = 'bond-stp' # Operation command to setup bond
|
|
DIS_DAD = 'disable-dad' # Operation command to disable DAD
|
|
MODES = 'modes' # List of modes where this configuration is expected, all if unspecified
|
|
SS_IPV4 = 'ss-ipv4' # Configuration is expected for Single Stack IPv4 mode
|
|
SS_IPV6 = 'ss-ipv6' # Configuration is expected for Single Stack IPv6 mode
|
|
DS_IPV4 = 'ds-ipv4' # Configuration is expected for Dual Stack / Primary IPv4 mode
|
|
DS_IPV6 = 'ds-ipv6' # Configuration is expected for Dual Stack / Primary IPv6 mode
|
|
OPERATIONS = [UP, PRE_UP, POST_UP, DOWN, PRE_DOWN, POST_DOWN]
|
|
|
|
|
|
class InterfaceConfigTestMixin(InterfaceTestCaseMixin):
|
|
def setUp(self):
|
|
super(InterfaceConfigTestMixin, self).setUp()
|
|
self._setup_context()
|
|
|
|
def _setup_configuration(self):
|
|
self.interface_index = {}
|
|
self.new_address_index = {}
|
|
|
|
def _update_context(self):
|
|
# skip automatic context update
|
|
pass
|
|
|
|
def _do_update_context(self):
|
|
super(InterfaceConfigTestMixin, self)._update_context()
|
|
|
|
debuglevel = int(os.environ.get('TOX_DEBUG_LEVEL', '0'))
|
|
|
|
def _include_interface(self, iface, info):
|
|
iface_dict = {
|
|
'interface': iface,
|
|
'info': info,
|
|
'networks': {
|
|
None: {
|
|
'network': None,
|
|
'addresses': {
|
|
constants.IPV4_FAMILY: [],
|
|
constants.IPV6_FAMILY: [],
|
|
}
|
|
}
|
|
},
|
|
'gateways': {}
|
|
}
|
|
self.interface_index[iface.ifname] = iface_dict
|
|
return iface_dict
|
|
|
|
def _include_network(self, iface, network):
|
|
self.interface_index[iface.ifname]['networks'][network.id] = {
|
|
'network': network,
|
|
'addresses': {
|
|
constants.IPV4_FAMILY: [],
|
|
constants.IPV6_FAMILY: [],
|
|
}
|
|
}
|
|
|
|
def _include_address(self, iface, network, address):
|
|
network_id = network.id if network else None
|
|
(self.interface_index[iface.ifname]['networks'][network_id]['addresses']
|
|
[address.family]).append(address)
|
|
|
|
def _include_gateway(self, iface, address, gateway):
|
|
self.interface_index[iface.ifname]['gateways'][address.id] = gateway
|
|
|
|
def _get_new_address(self, addrpool, family=None):
|
|
id = addrpool.id if addrpool else -int(family)
|
|
entry = self.new_address_index.get(id, None)
|
|
if not entry:
|
|
if addrpool:
|
|
ipnetwork = netaddr.IPNetwork(addrpool.network + '/' + str(addrpool.prefix))
|
|
else:
|
|
if family == constants.IPV6_FAMILY:
|
|
ipnetwork = netaddr.IPNetwork('fda0::/64')
|
|
else:
|
|
ipnetwork = netaddr.IPNetwork('192.168.100.0/24')
|
|
entry = {'ipnetwork': ipnetwork, 'offset': 10}
|
|
self.new_address_index[id] = entry
|
|
offset = entry['offset']
|
|
entry['offset'] += 1
|
|
return str(entry['ipnetwork'][offset]), entry['ipnetwork'].prefixlen
|
|
|
|
def _get_new_pool_address(self, addrpool):
|
|
return self._get_new_address(addrpool)
|
|
|
|
def _get_new_detached_address(self, family):
|
|
return self._get_new_address(None, family)
|
|
|
|
def _setup_detached_address(self, iface, family):
|
|
addr, prefixlen = self._get_new_detached_address(family)
|
|
address = self._create_test_address(
|
|
name=f"{iface.ifname}-detached-ipv{family}",
|
|
family=family,
|
|
prefix=prefixlen,
|
|
address=addr,
|
|
interface_id=iface.id)
|
|
if (family == constants.IPV4_FAMILY and iface.ipv4_mode == constants.IPV4_STATIC or
|
|
family == constants.IPV6_FAMILY and iface.ipv6_mode == constants.IPV6_STATIC):
|
|
self._include_address(iface, None, address)
|
|
|
|
def _setup_detached_addresses(self, iface):
|
|
iface_info = self.interface_index[iface.ifname]['info']
|
|
for _ in range(iface_info['ipv4_addresses']):
|
|
self._setup_detached_address(iface, constants.IPV4_FAMILY)
|
|
for _ in range(iface_info['ipv6_addresses']):
|
|
self._setup_detached_address(iface, constants.IPV6_FAMILY)
|
|
|
|
def _assign_address_to_interface(self, iface, address):
|
|
dbapi = db_api.get_instance()
|
|
dbapi.address_update(address.uuid, {'interface_id': iface.id})
|
|
address.interface_id = iface.id
|
|
address.ifname = iface.ifname
|
|
|
|
def _get_controller_pool_address(self, iface, addrpool):
|
|
self.assertIsNotNone(addrpool.controller0_address_id)
|
|
address = self._find_address_by_id(addrpool.controller0_address_id)
|
|
self._assign_address_to_interface(iface, address)
|
|
return address
|
|
|
|
def _create_non_controller_pool_address(self, iface, network, addrpool):
|
|
addr, prefixlen = self._get_new_pool_address(addrpool)
|
|
return self._create_test_address(
|
|
name=utils.format_address_name(self.host.hostname, network.type),
|
|
family=addrpool.family,
|
|
prefix=prefixlen,
|
|
address=addr,
|
|
interface_id=iface.id,
|
|
address_pool_id=addrpool.id)
|
|
|
|
def _setup_gateway(self, iface, network, addrpool, address):
|
|
if (network and network.type == constants.NETWORK_TYPE_MGMT and
|
|
self.host.personality in [constants.WORKER, constants.STORAGE]):
|
|
gateway_address = addrpool.floating_address
|
|
else:
|
|
gateway_address = addrpool.gateway_address
|
|
self._include_gateway(iface, address, gateway_address)
|
|
|
|
def _setup_pool_address(self, iface, network, addrpool):
|
|
if self.host.personality == constants.CONTROLLER:
|
|
address = self._get_controller_pool_address(iface, addrpool)
|
|
else:
|
|
address = self._create_non_controller_pool_address(iface, network, addrpool)
|
|
self._include_address(iface, network, address)
|
|
self._setup_gateway(iface, network, addrpool, address)
|
|
|
|
def _setup_network_and_addresses(self, iface, networktype):
|
|
network = self._find_network_by_type(networktype)
|
|
self._include_network(iface, network)
|
|
if self.host.personality != constants.CONTROLLER:
|
|
if networktype not in [constants.NETWORK_TYPE_MGMT,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST,
|
|
constants.NETWORK_TYPE_STORAGE,
|
|
constants.NETWORK_TYPE_ADMIN]:
|
|
return
|
|
addrpools = self._find_network_address_pools(network.id)
|
|
for addrpool in addrpools:
|
|
self._setup_pool_address(iface, network, addrpool)
|
|
|
|
def _setup_networks_and_addresses(self, iface):
|
|
for networktype in iface.networktypelist:
|
|
self._setup_network_and_addresses(iface, networktype)
|
|
|
|
def _setup_addresses(self, iface):
|
|
if iface.ifclass == constants.INTERFACE_CLASS_DATA:
|
|
self._setup_detached_addresses(iface)
|
|
elif iface.ifclass == constants.INTERFACE_CLASS_PLATFORM:
|
|
if iface.networktypelist:
|
|
self._setup_networks_and_addresses(iface)
|
|
else:
|
|
self._setup_detached_addresses(iface)
|
|
|
|
def _setup_interface(self, iface, interface_info):
|
|
self._include_interface(iface, interface_info)
|
|
self._setup_addresses(iface)
|
|
|
|
def _build_interface_info(self, **kwargs):
|
|
return {'kernel_name': kwargs.get('kernel_name', None),
|
|
'upper_device': kwargs.get('upper_device', None),
|
|
'bond_slaves': kwargs.get('bond_slaves', None),
|
|
'bond_primary': kwargs.get('bond_primary', None),
|
|
'dpdksupport': kwargs.get('dpdksupport', True),
|
|
'driver': kwargs.get('driver', None),
|
|
'ipv4_addresses': kwargs.get('ipv4_addresses', 0),
|
|
'ipv6_addresses': kwargs.get('ipv6_addresses', 0)}
|
|
|
|
def _setup_bond_slave(self, port, iface, master_info):
|
|
|
|
interface_info = self._build_interface_info(
|
|
kernel_name=port.name,
|
|
upper_device=master_info['kernel_name'],
|
|
is_slave=True)
|
|
|
|
self._setup_interface(iface, interface_info)
|
|
|
|
def _get_address_netmask(self, address):
|
|
network = netaddr.IPNetwork(address.address + '/' + str(address.prefix))
|
|
if network.version == constants.IPV6_FAMILY:
|
|
return str(network.prefixlen)
|
|
else:
|
|
return str(network.netmask)
|
|
|
|
def _get_stx_description(self, iface, network):
|
|
networktext = network.type if network else 'None'
|
|
return f"ifname:{iface.ifname},net:{networktext}"
|
|
|
|
def _get_traffic_classifier_cmd(self, iface, kernel_name):
|
|
if constants.NETWORK_TYPE_MGMT in iface.networktypelist:
|
|
cmd = '%s %s %s %s > /dev/null' % (constants.TRAFFIC_CONTROL_SCRIPT,
|
|
kernel_name,
|
|
constants.NETWORK_TYPE_MGMT,
|
|
constants.LINK_SPEED_10G)
|
|
return [cmd]
|
|
return []
|
|
|
|
def _get_cmd_ipv6_autoconf_off(self, os_ifname):
|
|
return ['echo 0 > /proc/sys/net/ipv6/conf/{}/autoconf'.format(os_ifname),
|
|
'echo 0 > /proc/sys/net/ipv6/conf/{}/accept_ra'.format(os_ifname),
|
|
'echo 0 > /proc/sys/net/ipv6/conf/{}/accept_redirects'.format(os_ifname)]
|
|
|
|
def _get_cmd_postup_mtu(self, os_ifname, mtu):
|
|
return ['/usr/sbin/ip link set dev {} mtu {}'.format(os_ifname, mtu)]
|
|
|
|
def _get_cmd_vlan_kernel_module(self):
|
|
return ['/sbin/modprobe -q 8021q']
|
|
|
|
def _get_cmd_vlan_creation(self, raw_device, kernel_name, vlan_id):
|
|
return ['ip link add link {} name {} type vlan id {}'.format(
|
|
raw_device, kernel_name, vlan_id)]
|
|
|
|
def _get_cmd_vlan_removal(self, kernel_name):
|
|
return ['ip link del {}'.format(kernel_name)]
|
|
|
|
def _get_promisc_cmd(self, kernel_name):
|
|
return ['/usr/sbin/ip link set dev {} promisc on'.format(kernel_name)]
|
|
|
|
def _get_undeprecate_cmd(self, kernel_name, address):
|
|
return ['ip -6 addr replace {}/{} dev {} preferred_lft forever'.format(
|
|
address.address, address.prefix, kernel_name)]
|
|
|
|
def _get_sriov_numvfs_path(self, port):
|
|
return '/sys/class/net/{}/device/sriov_numvfs'.format(port)
|
|
|
|
def _get_sriov_numvfs_cmd(self, port, numvfs):
|
|
sriovfs_path = self._get_sriov_numvfs_path(port)
|
|
return ['echo 0 > {}'.format(sriovfs_path),
|
|
'echo {} > {}'.format(numvfs, sriovfs_path)]
|
|
|
|
def _get_pci_passthrough_numvfs_cmd(self, port):
|
|
sriovfs_path = self._get_sriov_numvfs_path(port)
|
|
return ['if [ -f {0} ]; then echo 0 > {0}; fi'.format(sriovfs_path)]
|
|
|
|
def _get_sleep_cmd(self):
|
|
return ['sleep 10']
|
|
|
|
def _get_bonding_setup_cmd(self, kernel_name):
|
|
return ['/sbin/modprobe bonding',
|
|
'grep %s /sys/class/net/bonding_masters || '
|
|
'echo +%s > /sys/class/net/bonding_masters' % (kernel_name, kernel_name)]
|
|
|
|
def _get_disable_dad_cmd(self, kernel_name):
|
|
return ["sysctl -wq net.ipv6.conf.%s.accept_dad=0" % kernel_name]
|
|
|
|
def _get_operations(self, iface_dict, commands, address):
|
|
iface = iface_dict['interface']
|
|
kernel_name = iface_dict['info']['kernel_name']
|
|
operation_list = []
|
|
for command in commands:
|
|
if command == IPV6_CFG:
|
|
operation_list.extend(self._get_cmd_ipv6_autoconf_off(kernel_name))
|
|
elif command == SET_MTU:
|
|
operation_list.extend(self._get_cmd_postup_mtu(kernel_name, iface.imtu))
|
|
elif command == SET_TC:
|
|
operation_list.extend(self._get_traffic_classifier_cmd(iface, kernel_name))
|
|
elif command == VLAN_MOD:
|
|
operation_list.extend(self._get_cmd_vlan_kernel_module())
|
|
elif command == VLAN_ADD:
|
|
operation_list.extend(self._get_cmd_vlan_creation(
|
|
iface_dict['info']['upper_device'], kernel_name, iface.vlan_id))
|
|
elif command == VLAN_DEL:
|
|
operation_list.extend(self._get_cmd_vlan_removal(kernel_name))
|
|
elif command == PROMISC_ON:
|
|
operation_list.extend(self._get_promisc_cmd(kernel_name))
|
|
elif command == UNDEPR:
|
|
operation_list.extend(self._get_undeprecate_cmd(kernel_name, address))
|
|
elif command == SRIOV:
|
|
operation_list.extend(self._get_sriov_numvfs_cmd(kernel_name, iface.sriov_numvfs))
|
|
elif command == PTHROUGH:
|
|
operation_list.extend(self._get_pci_passthrough_numvfs_cmd(kernel_name))
|
|
elif command == SLEEP:
|
|
operation_list.extend(self._get_sleep_cmd())
|
|
elif command == BOND_SETUP:
|
|
operation_list.extend(self._get_bonding_setup_cmd(kernel_name))
|
|
elif command == DIS_DAD:
|
|
operation_list.extend(self._get_disable_dad_cmd(kernel_name))
|
|
return '; '.join(operation_list)
|
|
|
|
def _get_ifcfg_options(self, iface_dict, network, address, exp_cfg):
|
|
iface = iface_dict['interface']
|
|
exp_options = exp_cfg[OPTIONS]
|
|
|
|
options = {'mtu': str(iface_dict['interface'].imtu),
|
|
'stx-description': self._get_stx_description(iface, network)}
|
|
|
|
if exp_options.pop('vlan-raw-device', False):
|
|
self.assertEqual(iface.iftype, constants.INTERFACE_TYPE_VLAN,
|
|
f"Interface {iface.ifname} is not VLAN")
|
|
options['vlan-raw-device'] = iface_dict['info']['upper_device']
|
|
|
|
if exp_options.pop('hwaddress', False):
|
|
options['hwaddress'] = iface.imac.rstrip()
|
|
if exp_options.pop('bond-primary', False):
|
|
options['bond-primary'] = iface_dict['info']['bond_primary']
|
|
if exp_options.pop('bond-slaves', False):
|
|
options['bond-slaves'] = iface_dict['info']['bond_slaves']
|
|
if exp_options.pop('bond-master', False):
|
|
options['bond-master'] = iface_dict['info']['upper_device']
|
|
if exp_options.pop(ALLOW, False):
|
|
key = 'allow-{}'.format(iface_dict['info']['upper_device'])
|
|
options[key] = iface_dict['info']['kernel_name']
|
|
|
|
for oper in OPERATIONS:
|
|
oper_list = exp_options.pop(oper, None)
|
|
if oper_list:
|
|
options[oper] = self._get_operations(iface_dict, oper_list, address)
|
|
|
|
options.update(exp_options)
|
|
|
|
return options
|
|
|
|
def _get_expected_interface_config(self, iface_dict, network, address, exp_cfg, base):
|
|
iface = iface_dict['interface']
|
|
|
|
has_gateway = exp_cfg[OPTIONS].pop(GATEWAY, False)
|
|
|
|
config = {
|
|
'ensure': 'present',
|
|
'onboot': 'true',
|
|
'hotplug': 'false',
|
|
'family': exp_cfg[FAMILY],
|
|
'method': exp_cfg[METHOD],
|
|
'options': self._get_ifcfg_options(iface_dict, network, address, exp_cfg)}
|
|
|
|
if exp_cfg[METHOD] == STATIC:
|
|
self.assertIsNotNone(address,
|
|
f"Address expected for interface {iface.ifname} / "
|
|
f"network {network.type if network else None}, but not present")
|
|
config['ipaddress'] = address.address
|
|
config['netmask'] = self._get_address_netmask(address)
|
|
if has_gateway:
|
|
gateway = iface_dict['gateways'].get(address.id, None)
|
|
self.assertIsNotNone(gateway,
|
|
f"Gateway expected for interface {iface.ifname} / "
|
|
f"network {network.type if network else None} / "
|
|
f"address {address.address} but not present")
|
|
config['options']['gateway'] = gateway
|
|
|
|
kernelname = iface_dict['info']['kernel_name']
|
|
if base:
|
|
ifname = kernelname
|
|
else:
|
|
ifname = f"{kernelname}:{network.id if network else 0}-{address.id if address else 0}"
|
|
|
|
return {ifname: config}
|
|
|
|
def _get_address(self, iface_dict, network, family, index):
|
|
network_id = network.id if network else None
|
|
self.assertIn(network_id, iface_dict['networks'],
|
|
f"Network '{network.type if network else None}' is not associated"
|
|
f"with interface '{iface_dict['interface'].ifname}'")
|
|
addr_list = iface_dict['networks'][network_id]['addresses'][family]
|
|
self.assertGreater(len(addr_list), index,
|
|
f"There are only {len(addr_list)} IPv{family} addresses associated with interface "
|
|
f"{iface_dict['interface'].ifname} for network {network.type if network else None},"
|
|
f" index {index + 1} is out of bounds")
|
|
return addr_list[index]
|
|
|
|
def _is_config_included(self, exp_cfg):
|
|
modes = exp_cfg.pop(MODES, None)
|
|
if not modes:
|
|
return True
|
|
return self.system_mode in modes
|
|
|
|
def _get_expected_interface_configs(self, ifname, expected_iface_configs):
|
|
self.assertIn(ifname, self.interface_index, f"Interface {ifname} was not created")
|
|
iface_dict = self.interface_index[ifname]
|
|
address_index = defaultdict(lambda: defaultdict(int))
|
|
base = True
|
|
interface_configs = {}
|
|
for exp_cfg in expected_iface_configs:
|
|
if not self._is_config_included(exp_cfg):
|
|
continue
|
|
network = self._find_network_by_type(exp_cfg[NET])
|
|
network_id = network.id if network else None
|
|
if network_id not in iface_dict['networks']:
|
|
if (network.type == constants.NETWORK_TYPE_PXEBOOT and
|
|
constants.NETWORK_TYPE_MGMT in iface_dict['interface'].networktypelist):
|
|
self._setup_network_and_addresses(iface_dict['interface'], network.type)
|
|
address = None
|
|
if exp_cfg[METHOD] == STATIC:
|
|
if exp_cfg[FAMILY] == INET6:
|
|
family = constants.IPV6_FAMILY
|
|
else:
|
|
family = constants.IPV4_FAMILY
|
|
address = self._get_address(iface_dict, network, family,
|
|
address_index[network_id][family])
|
|
address_index[network_id][family] += 1
|
|
config = self._get_expected_interface_config(iface_dict, network,
|
|
address, exp_cfg, base)
|
|
interface_configs.update(config)
|
|
base = False
|
|
return interface_configs
|
|
|
|
def _add_loopback_config(self, interface_configs):
|
|
interface_configs['lo'] = {'ensure': 'present',
|
|
'family': 'inet',
|
|
'hotplug': 'false',
|
|
'method': 'loopback',
|
|
'onboot': 'true',
|
|
'options': {}}
|
|
|
|
def _get_expected_config(self, expected_configs):
|
|
interface_configs = {}
|
|
for ifname, expected_iface_configs in expected_configs.items():
|
|
configs = self._get_expected_interface_configs(ifname, expected_iface_configs)
|
|
interface_configs.update(configs)
|
|
self._add_loopback_config(interface_configs)
|
|
return interface_configs
|
|
|
|
def _get_generated_config(self):
|
|
hiera_data = self.operator.interface.get_host_config(self.host)
|
|
self.assertIn('platform::network::interfaces::network_config', hiera_data)
|
|
return hiera_data['platform::network::interfaces::network_config']
|
|
|
|
def _remove_non_serializable_elements(self, object_vars):
|
|
object_vars.pop('_changed_fields', None)
|
|
object_vars.pop('_created_at', None)
|
|
object_vars.pop('_updated_at', None)
|
|
return object_vars
|
|
|
|
# Prints interface index contents for debug purposes
|
|
def _print_interface_index(self):
|
|
printable_interface_index = {}
|
|
for interface_dict in self.interface_index.values():
|
|
interface = interface_dict['interface']
|
|
printable_network_dict = {}
|
|
for network_dict in interface_dict['networks'].values():
|
|
network = network_dict['network']
|
|
printable_address_index = defaultdict(list)
|
|
for family, addresses in network_dict['addresses'].items():
|
|
for address in addresses:
|
|
printable_address_index[family].append(
|
|
self._remove_non_serializable_elements(vars(address)))
|
|
printable_network_dict[network.id if network else 0] = {
|
|
'network': (self._remove_non_serializable_elements(vars(network)) if network
|
|
else None),
|
|
'addresses': printable_address_index}
|
|
printable_interface_index[interface.ifname] = {
|
|
'interface': self._remove_non_serializable_elements(vars(interface)),
|
|
'info': interface_dict['info'],
|
|
'networks': printable_network_dict}
|
|
print(json.dumps(printable_interface_index, sort_keys=True, indent=4))
|
|
|
|
def _create_host(self, personality=constants.CONTROLLER, subfunction=None):
|
|
self.host = self._create_test_host(personality, subfunction)
|
|
|
|
def _add_ethernet(self, ifname=None, ifclass=None, networktype=None, **kwargs):
|
|
port, iface = self._create_ethernet_test(ifname, ifclass, networktype, **kwargs)
|
|
|
|
driver = kwargs.get('driver', 'ixgbe')
|
|
|
|
interface_info = self._build_interface_info(
|
|
kernel_name=port.name,
|
|
dpdksupport=kwargs.get('dpdksupport', True),
|
|
driver=driver,
|
|
ipv4_addresses=kwargs.get('ipv4_addresses', 0),
|
|
ipv6_addresses=kwargs.get('ipv6_addresses', 0))
|
|
|
|
self._setup_interface(iface, interface_info)
|
|
|
|
return iface
|
|
|
|
def _add_bond(self, ifname=None, ifclass=None, networktype=None, **kwargs):
|
|
port1, slave1 = self._create_ethernet_test()
|
|
port2, slave2 = self._create_ethernet_test()
|
|
|
|
iface = self._create_bond_test(ifname, ifclass, networktype,
|
|
iface1=slave1, iface2=slave2, **kwargs)
|
|
|
|
interface_info = self._build_interface_info(
|
|
kernel_name=iface.ifname,
|
|
bond_slaves='{} {} '.format(port1.name, port2.name),
|
|
bond_primary=port1.name,
|
|
ipv4_addresses=kwargs.get('ipv4_addresses', 0),
|
|
ipv6_addresses=kwargs.get('ipv6_addresses', 0))
|
|
|
|
self._setup_interface(iface, interface_info)
|
|
|
|
self._setup_bond_slave(port1, slave1, interface_info)
|
|
self._setup_bond_slave(port2, slave2, interface_info)
|
|
|
|
return iface
|
|
|
|
def _add_vlan(self, lower_iface, vlan_id, ifname=None, ifclass=None,
|
|
networktype=None, **kwargs):
|
|
iface = self._create_vlan_test(ifname, ifclass, networktype, vlan_id, lower_iface, **kwargs)
|
|
|
|
lower_iface_dict = self.interface_index[lower_iface.ifname]
|
|
lower_iface_info = lower_iface_dict['info']
|
|
|
|
interface_info = self._build_interface_info(
|
|
kernel_name=interface.get_vlan_os_ifname(iface),
|
|
upper_device=lower_iface_info['kernel_name'],
|
|
ipv4_addresses=kwargs.get('ipv4_addresses', 0),
|
|
ipv6_addresses=kwargs.get('ipv6_addresses', 0))
|
|
|
|
self._setup_interface(iface, interface_info)
|
|
|
|
return iface
|
|
|
|
def _validate_config(self, expected):
|
|
self._do_update_context()
|
|
expected_config = self._get_expected_config(expected)
|
|
if self.debuglevel >= 2:
|
|
self._print_interface_index()
|
|
generated_config = self._get_generated_config()
|
|
self.assertEqual(expected_config, generated_config)
|
|
if self.debuglevel >= 1:
|
|
print(json.dumps(generated_config, sort_keys=True, indent=4))
|
|
|
|
def test_controller_ethernet_oam(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
self._add_ethernet('oam0', constants.INTERFACE_CLASS_PLATFORM, constants.NETWORK_TYPE_OAM)
|
|
expected = {
|
|
'oam0': [
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_OAM, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6],
|
|
NET: constants.NETWORK_TYPE_OAM, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_OAM, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
def test_controller_ethernet_separate_nets_pxeboot_unassigned(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
self._add_ethernet('mgmt0', constants.INTERFACE_CLASS_PLATFORM, constants.NETWORK_TYPE_MGMT)
|
|
self._add_ethernet('clhost0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
self._add_ethernet('none')
|
|
expected = {
|
|
'mgmt0': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{NET: constants.NETWORK_TYPE_PXEBOOT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, UNDEPR]}}],
|
|
'clhost0': [
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{MODES: [SS_IPV4],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, UNDEPR]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
def test_controller_ethernet_joined_nets_pxeboot_unassigned(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
self._add_ethernet('mgmt0', constants.INTERFACE_CLASS_PLATFORM,
|
|
[constants.NETWORK_TYPE_MGMT,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST])
|
|
self._add_ethernet('none')
|
|
expected = {
|
|
'mgmt0': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{NET: constants.NETWORK_TYPE_PXEBOOT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, UNDEPR]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
def test_controller_ethernet_joined_nets_pxeboot_assigned(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
self._add_ethernet('mgmt0', constants.INTERFACE_CLASS_PLATFORM,
|
|
[constants.NETWORK_TYPE_MGMT,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST,
|
|
constants.NETWORK_TYPE_PXEBOOT])
|
|
self._add_ethernet('none')
|
|
expected = {
|
|
'mgmt0': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{NET: constants.NETWORK_TYPE_PXEBOOT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, UNDEPR]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
def test_controller_ethernet_separate_nets_pxeboot_assigned(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
self._add_ethernet('pxe0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT)
|
|
self._add_ethernet('mgmt0', constants.INTERFACE_CLASS_PLATFORM,
|
|
[constants.NETWORK_TYPE_MGMT,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST])
|
|
self._add_ethernet('none')
|
|
expected = {
|
|
'pxe0': [
|
|
{NET: constants.NETWORK_TYPE_PXEBOOT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}}],
|
|
'mgmt0': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, UNDEPR]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
def test_controller_vlan_over_bond(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
pxe0 = self._add_bond('pxe0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT)
|
|
self._add_vlan(pxe0, 100, 'mgmt0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._add_vlan(pxe0, 200, 'clhost0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
expected = {
|
|
'pxe0': [
|
|
{NET: constants.NETWORK_TYPE_PXEBOOT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'bond-lacp-rate': 'fast', 'bond-miimon': '100',
|
|
'bond-mode': '802.3ad', 'bond-slaves': True,
|
|
'bond-xmit-hash-policy': 'layer2', 'hwaddress': True,
|
|
POST_UP: [SET_TC, IPV6_CFG], UP: [SLEEP]}}],
|
|
'eth0': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {ALLOW: True, 'bond-master': True, PRE_UP: [PROMISC_ON, IPV6_CFG]}}],
|
|
'eth1': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {ALLOW: True, 'bond-master': True, PRE_UP: [PROMISC_ON, IPV6_CFG]}}],
|
|
'mgmt0': [
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {'vlan-raw-device': True, PRE_UP: [VLAN_MOD],
|
|
POST_UP: [SET_TC, SET_MTU, IPV6_CFG]}},
|
|
{MODES: [SS_IPV4],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'vlan-raw-device': True, PRE_UP: [VLAN_MOD],
|
|
POST_UP: [SET_MTU, IPV6_CFG, SET_TC]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'vlan-raw-device': True, PRE_UP: [VLAN_MOD],
|
|
POST_UP: [SET_MTU, IPV6_CFG]}},
|
|
{MODES: [SS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'vlan-raw-device': True, PRE_UP: [VLAN_MOD],
|
|
POST_UP: [SET_MTU, IPV6_CFG, SET_TC]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'vlan-raw-device': True, PRE_UP: [VLAN_MOD],
|
|
POST_UP: [SET_MTU, IPV6_CFG, UNDEPR]}}],
|
|
'clhost0': [
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {'vlan-raw-device': True, PRE_UP: [VLAN_MOD],
|
|
POST_UP: [SET_TC, SET_MTU, IPV6_CFG]}},
|
|
{MODES: [SS_IPV4],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'vlan-raw-device': True, PRE_UP: [VLAN_MOD],
|
|
POST_UP: [SET_MTU, IPV6_CFG, SET_TC]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'vlan-raw-device': True, PRE_UP: [VLAN_MOD],
|
|
POST_UP: [SET_MTU, IPV6_CFG]}},
|
|
{MODES: [SS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'vlan-raw-device': True, PRE_UP: [VLAN_MOD],
|
|
POST_UP: [SET_MTU, IPV6_CFG, SET_TC]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'vlan-raw-device': True, PRE_UP: [VLAN_MOD],
|
|
POST_UP: [SET_MTU, IPV6_CFG, UNDEPR]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
def test_controller_duplex_direct_ethernet(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
system_dict = self.system.as_dict()
|
|
system_dict['system_mode'] = constants.SYSTEM_MODE_DUPLEX_DIRECT
|
|
self.dbapi.isystem_update(self.system.uuid, system_dict)
|
|
self._add_ethernet('mgmt0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._add_ethernet('clhost0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
expected = {
|
|
'mgmt0': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {PRE_UP: [DIS_DAD], POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{NET: constants.NETWORK_TYPE_PXEBOOT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, UNDEPR]}}],
|
|
'clhost0': [
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {PRE_UP: [DIS_DAD], POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{MODES: [SS_IPV4],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, PRE_UP: [DIS_DAD], POST_UP: [IPV6_CFG]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, PRE_UP: [DIS_DAD], POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, UNDEPR]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
def test_controller_duplex_direct_vlan_over_bond(self):
|
|
self._create_host(constants.CONTROLLER)
|
|
system_dict = self.system.as_dict()
|
|
system_dict['system_mode'] = constants.SYSTEM_MODE_DUPLEX_DIRECT
|
|
self.dbapi.isystem_update(self.system.uuid, system_dict)
|
|
pxe0 = self._add_ethernet('pxe0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_PXEBOOT)
|
|
self._add_bond('mgmt0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._add_vlan(pxe0, 200, 'clhost0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
expected = {
|
|
'pxe0': [
|
|
{NET: constants.NETWORK_TYPE_PXEBOOT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}}],
|
|
'mgmt0': [
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {'bond-lacp-rate': 'fast', 'bond-miimon': '100',
|
|
'bond-mode': '802.3ad', 'bond-slaves': True,
|
|
'bond-xmit-hash-policy': 'layer2', 'hwaddress': True,
|
|
PRE_UP: [BOND_SETUP, DIS_DAD], POST_UP: [SET_TC, IPV6_CFG],
|
|
UP: [SLEEP]}},
|
|
{MODES: [SS_IPV4],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'bond-lacp-rate': 'fast', 'bond-miimon': '100',
|
|
'bond-mode': '802.3ad', 'bond-slaves': True,
|
|
'bond-xmit-hash-policy': 'layer2', 'hwaddress': True,
|
|
PRE_UP: [BOND_SETUP, DIS_DAD], POST_UP: [IPV6_CFG, SET_TC],
|
|
UP: [SLEEP]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'bond-lacp-rate': 'fast', 'bond-miimon': '100',
|
|
'bond-mode': '802.3ad', 'bond-slaves': True,
|
|
'bond-xmit-hash-policy': 'layer2', 'hwaddress': True,
|
|
POST_UP: [IPV6_CFG], UP: [SLEEP]}},
|
|
{MODES: [SS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'bond-lacp-rate': 'fast', 'bond-miimon': '100',
|
|
'bond-mode': '802.3ad', 'bond-slaves': True,
|
|
'bond-xmit-hash-policy': 'layer2', 'hwaddress': True,
|
|
PRE_UP: [BOND_SETUP, DIS_DAD], POST_UP: [IPV6_CFG, SET_TC],
|
|
UP: [SLEEP]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'bond-lacp-rate': 'fast', 'bond-miimon': '100',
|
|
'bond-mode': '802.3ad', 'bond-slaves': True,
|
|
'bond-xmit-hash-policy': 'layer2', 'hwaddress': True,
|
|
POST_UP: [IPV6_CFG, UNDEPR],
|
|
UP: [SLEEP]}}],
|
|
'eth1': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {ALLOW: True, 'bond-master': True, PRE_UP: [PROMISC_ON, IPV6_CFG]}}],
|
|
'eth2': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {ALLOW: True, 'bond-master': True, PRE_UP: [PROMISC_ON, IPV6_CFG]}}],
|
|
'clhost0': [
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {'vlan-raw-device': True,
|
|
PRE_UP: [VLAN_MOD, VLAN_ADD, DIS_DAD], POST_UP: [SET_MTU, IPV6_CFG],
|
|
POST_DOWN: [VLAN_DEL]}},
|
|
{MODES: [SS_IPV4],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'vlan-raw-device': True,
|
|
PRE_UP: [VLAN_MOD, VLAN_ADD, DIS_DAD],
|
|
POST_UP: [SET_MTU, IPV6_CFG], POST_DOWN: [VLAN_DEL]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'vlan-raw-device': True,
|
|
PRE_UP: [VLAN_MOD], POST_UP: [SET_MTU, IPV6_CFG]}},
|
|
{MODES: [SS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'vlan-raw-device': True,
|
|
PRE_UP: [VLAN_MOD, VLAN_ADD, DIS_DAD],
|
|
POST_UP: [SET_MTU, IPV6_CFG], POST_DOWN: [VLAN_DEL]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, 'vlan-raw-device': True,
|
|
PRE_UP: [VLAN_MOD], POST_UP: [SET_MTU, IPV6_CFG, UNDEPR]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
def test_worker_ethernet_pxe_unassigned(self):
|
|
self._create_host(constants.WORKER)
|
|
self._add_ethernet('mgmt0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_MGMT)
|
|
self._add_ethernet('clhost0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
self._add_ethernet('none')
|
|
expected = {
|
|
'mgmt0': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{NET: constants.NETWORK_TYPE_PXEBOOT, FAMILY: INET, METHOD: DHCP,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, UNDEPR]}}],
|
|
'clhost0': [
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{MODES: [SS_IPV4],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, UNDEPR]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
def test_worker_ethernet_pxe_with_mgmt(self):
|
|
self._create_host(constants.WORKER)
|
|
self._add_ethernet('mgmt0', constants.INTERFACE_CLASS_PLATFORM,
|
|
[constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_PXEBOOT])
|
|
self._add_ethernet('clhost0', constants.INTERFACE_CLASS_PLATFORM,
|
|
constants.NETWORK_TYPE_CLUSTER_HOST)
|
|
self._add_ethernet('none')
|
|
expected = {
|
|
'mgmt0': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{NET: constants.NETWORK_TYPE_PXEBOOT, FAMILY: INET, METHOD: DHCP,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, UNDEPR]}}],
|
|
'clhost0': [
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{MODES: [SS_IPV4],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, UNDEPR]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
def test_worker_ethernet_pxe_with_cluster_host(self):
|
|
self._create_host(constants.WORKER)
|
|
self._add_ethernet('mgmt0', constants.INTERFACE_CLASS_PLATFORM, constants.NETWORK_TYPE_MGMT)
|
|
self._add_ethernet('clhost0', constants.INTERFACE_CLASS_PLATFORM,
|
|
[constants.NETWORK_TYPE_CLUSTER_HOST, constants.NETWORK_TYPE_PXEBOOT])
|
|
self._add_ethernet('none')
|
|
expected = {
|
|
'mgmt0': [
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{MODES: [SS_IPV4],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, SET_TC]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, SET_TC]}},
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, UNDEPR]}}],
|
|
'clhost0': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [SET_TC, IPV6_CFG]}},
|
|
{NET: constants.NETWORK_TYPE_PXEBOOT, FAMILY: INET, METHOD: DHCP,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {GATEWAY: True, POST_UP: [IPV6_CFG, UNDEPR]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
def test_worker_sriov_and_pci_passthrough(self):
|
|
self._create_host(constants.WORKER)
|
|
self._add_ethernet('sriov0', constants.INTERFACE_CLASS_PCI_SRIOV,
|
|
constants.NETWORK_TYPE_PCI_SRIOV)
|
|
self._add_ethernet('pthru0', constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
|
constants.NETWORK_TYPE_PCI_PASSTHROUGH)
|
|
expected = {
|
|
'sriov0': [
|
|
{NET: constants.NETWORK_TYPE_PCI_SRIOV, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {PRE_UP: [SRIOV], POST_UP: [IPV6_CFG]}}],
|
|
'pthru0': [
|
|
{NET: constants.NETWORK_TYPE_PCI_PASSTHROUGH, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {PRE_UP: [PTHROUGH], POST_UP: [IPV6_CFG]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
def test_worker_data_over_ethernet(self):
|
|
self._create_host(constants.WORKER)
|
|
self._add_ethernet('data0', constants.INTERFACE_CLASS_DATA, constants.NETWORK_TYPE_DATA)
|
|
self._add_ethernet('slow0', constants.INTERFACE_CLASS_DATA, constants.NETWORK_TYPE_DATA,
|
|
dpdksupport=False)
|
|
self._add_ethernet('mlx0', constants.INTERFACE_CLASS_DATA, constants.NETWORK_TYPE_DATA,
|
|
driver=constants.DRIVER_MLX_CX4)
|
|
expected = {
|
|
'slow0': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}}],
|
|
'mlx0': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
def _get_static_address_args(self, static_enabled, addr_count):
|
|
families = [self.primary_address_family]
|
|
if self.secondary_address_family:
|
|
families.append(self.secondary_address_family)
|
|
kwargs = {}
|
|
if constants.IPV4_FAMILY in families:
|
|
if static_enabled:
|
|
kwargs['ipv4_mode'] = constants.IPV4_STATIC
|
|
kwargs['ipv4_addresses'] = addr_count
|
|
if constants.IPV6_FAMILY in families:
|
|
if static_enabled:
|
|
kwargs['ipv6_mode'] = constants.IPV6_STATIC
|
|
kwargs['ipv6_addresses'] = addr_count
|
|
return kwargs
|
|
|
|
def test_worker_data_over_ethernet_static_addresses(self):
|
|
self._create_host(constants.WORKER)
|
|
system_dict = self.system.as_dict()
|
|
system_dict['capabilities']['vswitch_type'] = constants.VSWITCH_TYPE_NONE
|
|
self.dbapi.isystem_update(self.system.uuid, system_dict)
|
|
self._add_ethernet('data0', constants.INTERFACE_CLASS_DATA, constants.NETWORK_TYPE_DATA)
|
|
self._add_ethernet('data1', constants.INTERFACE_CLASS_DATA, constants.NETWORK_TYPE_DATA,
|
|
**self._get_static_address_args(False, 1))
|
|
self._add_ethernet('data2', constants.INTERFACE_CLASS_DATA, constants.NETWORK_TYPE_DATA,
|
|
**self._get_static_address_args(True, 0))
|
|
self._add_ethernet('data3', constants.INTERFACE_CLASS_DATA, constants.NETWORK_TYPE_DATA,
|
|
**self._get_static_address_args(True, 1))
|
|
self._add_ethernet('data4', constants.INTERFACE_CLASS_DATA, constants.NETWORK_TYPE_DATA,
|
|
**self._get_static_address_args(True, 2))
|
|
expected = {
|
|
'data0': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}}],
|
|
'data1': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}}],
|
|
'data2': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}}],
|
|
'data3': [
|
|
{MODES: [DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}}],
|
|
'data4': [
|
|
{NET: None, FAMILY: INET, METHOD: MANUAL,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV4, DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET, METHOD: STATIC,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}},
|
|
{MODES: [SS_IPV6, DS_IPV4, DS_IPV6],
|
|
NET: None, FAMILY: INET6, METHOD: STATIC,
|
|
OPTIONS: {POST_UP: [IPV6_CFG]}}],
|
|
}
|
|
self._validate_config(expected)
|
|
|
|
|
|
class InterfaceConfigTestIPv4(InterfaceConfigTestMixin,
|
|
dbbase.BaseHostTestCase):
|
|
system_mode = SS_IPV4
|
|
|
|
|
|
class InterfaceConfigTestIPv6(InterfaceConfigTestMixin,
|
|
dbbase.BaseIPv6Mixin,
|
|
dbbase.BaseHostTestCase):
|
|
system_mode = SS_IPV6
|
|
|
|
|
|
class InterfaceConfigTestDualStackPrimaryIPv4(InterfaceConfigTestMixin,
|
|
dbbase.BaseDualStackPrimaryIPv4Mixin,
|
|
dbbase.BaseHostTestCase):
|
|
system_mode = DS_IPV4
|
|
|
|
|
|
class InterfaceConfigTestDualStackPrimaryIPv6(InterfaceConfigTestMixin,
|
|
dbbase.BaseDualStackPrimaryIPv6Mixin,
|
|
dbbase.BaseHostTestCase):
|
|
system_mode = DS_IPV6
|