Merge "Clean up interface network assignment"
This commit is contained in:
commit
c7e73429e6
@ -2406,7 +2406,6 @@ itemNotFound (404)
|
||||
"aemode (Optional)", "plain", "xsd:string", "Only applicable if ``iftype : ae``, this attribute indicates the basic mode of operation for the AE/LAG interface. Supported modes are: balanced round robin, active-backup, balanced xor, broadcast, 802.3ad, balance-tlb, balance-alb. NOTE only balanced xor and active-standby modes are supported by interfaces of ifclass=data."
|
||||
"txhashpolicy (Optional)", "plain", "xsd:string", "Only applicable if ``iftype : ae`` and ``aemode : balanced``, this attribute indicates what packet headers the AE/LAG is using to distribute packets across the different links/ports of the AE/LAG group; ``layer2``, ``layer2+3`` or ``layer3+4``."
|
||||
"vlan_id (Optional)", "plain", "xsd:integer", "Only applicable if ``iftype : vlan``, this attribute indicates that the vlan interface id. A vlan id between 1 and 4094 (inclusive) must be selected. NOTE The vlan id must be unique for the host interface."
|
||||
"networks (Optional)", "plain", "xsd:list", "Only applicable if ``ifclass : platform``, this attribute provides a list of platform networks that this interface is attached to."
|
||||
"datanetworks (Optional)", "plain", "xsd:list", "Only applicable if ``ifclass : data``, this attribute provides a list of data networks that this ``data`` interface is attached to."
|
||||
"imac (Optional)", "plain", "xsd:string", "The MAC Address being used by the interface. In the case of AE/LAG, the MAC address of one of the physical ports of the AE/LAG group is used."
|
||||
"imtu (Optional)", "plain", "xsd:integer", "The Maximum Transmission Unit (MTU) of the interface, in bytes."
|
||||
@ -2447,7 +2446,6 @@ itemNotFound (404)
|
||||
"vlan_id": null,
|
||||
"imtu": 1500,
|
||||
"aemode": null,
|
||||
"networks": ["1"],
|
||||
"datanetworks": [],
|
||||
"ifclass": "platform"
|
||||
"ifname": "eth1"
|
||||
@ -2480,7 +2478,6 @@ itemNotFound (404)
|
||||
|
||||
],
|
||||
"aemode": "balanced",
|
||||
"networks": [],
|
||||
"datanetworks": ["physnet-0,physnet-1"],
|
||||
"ifclass": "data"
|
||||
"ifname": "data1"
|
||||
@ -2526,7 +2523,6 @@ itemNotFound (404)
|
||||
"aemode (Optional)", "plain", "xsd:string", "Only applicable if ``iftype : ae``, this attribute indicates the basic mode of operation for the AE/LAG interface. Supported modes are: balanced round robin, active-backup, balanced xor, broadcast, 802.3ad, balance-tlb, balance-alb. NOTE only balanced xor and active-standby modes are supported by interfaces of ifclass=data."
|
||||
"txhashpolicy (Optional)", "plain", "xsd:string", "Only applicable if ``iftype : ae`` and ``aemode : balanced``, this attribute indicates what packet headers the AE/LAG is using to distribute packets across the different links/ports of the AE/LAG group; ``layer2``, ``layer2+3`` or ``layer3+4``."
|
||||
"vlan_id (Optional)", "plain", "xsd:integer", "Only applicable if ``iftype : vlan``, this attribute indicates that the vlan interface id. A vlan id between 1 and 4094 (inclusive) must be selected. NOTE The vlan id must be unique for the host interface."
|
||||
"networks (Optional)", "plain", "xsd:list", "Only applicable if ``ifclass : platform``, this attribute provides a list of platform networks that this interface is attached to."
|
||||
"datanetworks (Optional)", "plain", "xsd:list", "Only applicable if ``ifclass : data``, this attribute provides a list of data networks that this ``data`` interface is attached to."
|
||||
"imac (Optional)", "plain", "xsd:string", "The MAC Address being used by the interface. In the case of AE/LAG, the MAC address of one of the physical ports of the AE/LAG group is used."
|
||||
"imtu (Optional)", "plain", "xsd:integer", "The Maximum Transmission Unit (MTU) of the interface, in bytes."
|
||||
@ -2557,7 +2553,6 @@ itemNotFound (404)
|
||||
}
|
||||
],
|
||||
"datanetworks" : ["physnet-0,physnet-1"],
|
||||
"networks": [],
|
||||
"txhashpolicy" : "layer2",
|
||||
"schedpolicy" : null,
|
||||
"uuid" : "740a5bec-b7a8-4645-93ed-aea0d4cfbf86",
|
||||
@ -2622,7 +2617,6 @@ badMediaType (415)
|
||||
"aemode (Optional)", "plain", "xsd:string", "Only applicable if ``iftype : ae``, this attribute specifies whether the AE/LAG should operate as ``balanced`` or ``active_standby`` or ``802.3ad`` across its links. The ``balanced`` and ``active_standby`` are the only modes supported by ``data`` type interface. For ``mgmt`` type interface the ``802.3ad`` option must be selected."
|
||||
"txhashpolicy (Optional)", "plain", "xsd:string", "Only applicable if ``iftype : ae`` and ``aemode : balanced``, this attribute specifies what packet headers the AE/LAG should use to distribute packets across the different links/ports of the AE/LAG group; ``layer2``, ``layer2+3`` or ``layer3+4``."
|
||||
"vlan_id (Optional)", "plain", "xsd:integer", "Only applicable if ``iftype : vlan``, this attribute specifies a virtual lan id for a vlan interface type."
|
||||
"networks (Optional)", "plain", "xsd:list", "Only applicable if ``ifclass : platform``, this attribute provides a list of platform networks that this interface is attached to."
|
||||
"datanetworks (Optional)", "plain", "xsd:list", "Only applicable if ``ifclass : data``, this attribute specifies a list of data networks that this ``data`` interface is attached to."
|
||||
"ports (Optional)", "plain", "xsd:list", "This attribute specifies a comma-separated list of ports that this interface contains. If ``iftype : ethernet`` then only one port is allowed."
|
||||
"uses (Optional)", "plain", "xsd:list", "Only applicable if ``iftype : ae`` or ``iftype: vlan``, this attribute specifies a comma-separated list of interfaces that this interface uses."
|
||||
@ -2643,7 +2637,6 @@ badMediaType (415)
|
||||
"aemode (Optional)", "plain", "xsd:string", "Only applicable if ``iftype : ae``, this attribute indicates the basic mode of operation for the AE/LAG interface. Supported modes are: balanced round robin, active-backup, balanced xor, broadcast, 802.3ad, balance-tlb, balance-alb. NOTE only balanced xor and active-standby modes are supported by interfaces of ifclass=data."
|
||||
"txhashpolicy (Optional)", "plain", "xsd:string", "Only applicable if ``iftype : ae`` and ``aemode : balanced``, this attribute indicates what packet headers the AE/LAG is using to distribute packets across the different links/ports of the AE/LAG group; ``layer2``, ``layer2+3`` or ``layer3+4``."
|
||||
"vlan_id (Optional)", "plain", "xsd:integer", "Only applicable if ``iftype : vlan``, this attribute indicates that the vlan interface id. A vlan id between 1 and 4094 (inclusive) must be selected. NOTE The vlan id must be unique for the host interface."
|
||||
"networks (Optional)", "plain", "xsd:list", "Only applicable if ``ifclass : platform``, this attribute provides a list of platform networks that this interface is attached to."
|
||||
"datanetworks (Optional)", "plain", "xsd:list", "Only applicable if ``ifclass : data``, this attribute provides a list of data networks that this ``data`` interface is attached to."
|
||||
"imac (Optional)", "plain", "xsd:string", "The MAC Address being used by the interface. In the case of AE/LAG, the MAC address of one of the physical ports of the AE/LAG group is used."
|
||||
"imtu (Optional)", "plain", "xsd:integer", "The Maximum Transmission Unit (MTU) of the interface, in bytes."
|
||||
@ -2667,7 +2660,6 @@ badMediaType (415)
|
||||
"txhashpolicy": "layer2",
|
||||
"ihost_uuid": "ff453a51-1d3b-437f-a65e-b2d163f79f85",
|
||||
"imtu": "1500",
|
||||
"networks": [],
|
||||
"datanetworks": "physnet-0,physnet1",
|
||||
"ifclass": "data",
|
||||
"ifname": "data1",
|
||||
@ -2722,7 +2714,6 @@ badMediaType (415)
|
||||
],
|
||||
"aemode": "balanced",
|
||||
"sriov_numvfs": 0,
|
||||
'networks": [],
|
||||
"datanetworks": ["physnet-0,physnet-1"],
|
||||
"ifclass": "data",
|
||||
"ifname": "data1",
|
||||
@ -2757,7 +2748,6 @@ badMediaType (415)
|
||||
"aemode (Optional)", "plain", "xsd:string", "Only applicable if ``iftype : ae``, this attribute specifies whether the AE/LAG should operate as ``balanced`` or ``active_standby`` across its links. These are the only modes supported by ``data`` type interface."
|
||||
"txhashpolicy (Optional)", "plain", "xsd:string", "Only applicable if ``iftype : ae`` and ``aemode : balanced``, this attribute specifies what packet headers the AE/LAG should use to distribute packets across the different links/ports of the AE/LAG group; ``layer2``, ``layer2+3`` or ``layer3+4``."
|
||||
"vlan_id (Optional)", "plain", "xsd:integer", "Only applicable if ``iftype : vlan``, this attribute specifies a virtual lan id for a vlan interface type."
|
||||
"networks (Optional)", "plain", "xsd:list", "Only applicable if ``ifclass : platform``, this attribute provides a list of platform networks that this interface is attached to."
|
||||
"datanetworks (Optional)", "plain", "xsd:list", "Only applicable if ``ifclass : data``, this attribute specifies a list of data networks that this ``data`` interface is attached to."
|
||||
"ports (Optional)", "plain", "xsd:list", "This attribute specifies a comma-separated list of ports that this interface contains. If ``iftype : ethernet`` then only one port is allowed."
|
||||
"uses (Optional)", "plain", "xsd:list", "Only applicable if ``iftype : ae`` or ``iftype: vlan``, this attribute specifies a comma-separated list of interfaces that this interface uses."
|
||||
@ -2777,7 +2767,6 @@ badMediaType (415)
|
||||
"aemode (Optional)", "plain", "xsd:string", "Only applicable if ``iftype : ae``, this attribute indicates the basic mode of operation for the AE/LAG interface. Supported modes are: balanced round robin, active-backup, balanced xor, broadcast, 802.3ad, balance-tlb, balance-alb. NOTE only balanced xor and active-standby modes are supported by interfaces of ifclass=data."
|
||||
"txhashpolicy (Optional)", "plain", "xsd:string", "Only applicable if ``iftype : ae`` and ``aemode : balanced``, this attribute indicates what packet headers the AE/LAG is using to distribute packets across the different links/ports of the AE/LAG group; ``layer2``, ``layer2+3`` or ``layer3+4``."
|
||||
"vlan_id (Optional)", "plain", "xsd:integer", "Only applicable if ``iftype : vlan``, this attribute indicates that the vlan interface id. A vlan id between 1 and 4094 (inclusive) must be selected. NOTE The vlan id must be unique for the host interface."
|
||||
"networks (Optional)", "plain", "xsd:list", "Only applicable if ``ifclass : platform``, this attribute provides a list of platform networks that this interface is attached to."
|
||||
"datanetworks (Optional)", "plain", "xsd:list", "Only applicable if ``ifclass : data``, this attribute provides a list of data networks that this ``data`` interface is attached to."
|
||||
"imac (Optional)", "plain", "xsd:string", "The MAC Address being used by the interface. In the case of AE/LAG, the MAC address of one of the physical ports of the AE/LAG group is used."
|
||||
"imtu (Optional)", "plain", "xsd:integer", "The Maximum Transmission Unit (MTU) of the interface, in bytes."
|
||||
@ -2870,7 +2859,6 @@ badMediaType (415)
|
||||
|
||||
],
|
||||
"aemode": "active_standby",
|
||||
"networks": [],
|
||||
"datanetworks": ["physnet-0,physnet-1"],
|
||||
"ifclass": "data",
|
||||
"ifname": "data1",
|
||||
|
@ -14,8 +14,9 @@
|
||||
# Use shell instead of command module as source is an internal shell command
|
||||
shell: "{{ item }}"
|
||||
with_items:
|
||||
- source /etc/platform/openrc; system host-if-add controller-0 lo virtual none lo -c platform --networks mgmt -m 1500
|
||||
- source /etc/platform/openrc; system host-if-modify controller-0 -c platform --networks cluster-host lo
|
||||
- source /etc/platform/openrc; system host-if-add controller-0 lo virtual none lo -c platform -m 1500
|
||||
- source /etc/platform/openrc; system interface-network-assign controller-0 lo mgmt
|
||||
- source /etc/platform/openrc; system interface-network-assign controller-0 lo cluster-host
|
||||
- ip addr add {{ cluster_virtual }} brd {{ cluster_broadcast }} dev lo scope host label lo:5
|
||||
- ip addr add {{ mgmt_virtual }} brd {{ management_broadcast }} dev lo scope host label lo:1
|
||||
- ip addr add {{ pxe_virtual }} dev lo scope host
|
||||
|
@ -13,25 +13,17 @@ from cgtsclient.common import utils
|
||||
from cgtsclient import exc
|
||||
from cgtsclient.v1 import ihost as ihost_utils
|
||||
from cgtsclient.v1 import iinterface as iinterface_utils
|
||||
from cgtsclient.v1 import network as network_utils
|
||||
|
||||
|
||||
def _print_iinterface_show(cc, iinterface):
|
||||
fields = ['ifname', 'iftype', 'ports', 'datanetworks',
|
||||
'imac', 'imtu', 'ifclass', 'networks',
|
||||
'imac', 'imtu', 'ifclass',
|
||||
'aemode', 'schedpolicy', 'txhashpolicy',
|
||||
'uuid', 'ihost_uuid',
|
||||
'vlan_id', 'uses', 'used_by',
|
||||
'created_at', 'updated_at', 'sriov_numvfs', 'sriov_vf_driver']
|
||||
optional_fields = ['ipv4_mode', 'ipv6_mode', 'ipv4_pool', 'ipv6_pool']
|
||||
rename_fields = [{'field': 'dpdksupport', 'label': 'accelerated'}]
|
||||
network_names = ""
|
||||
networks = getattr(iinterface, 'networks', [])
|
||||
for n in networks:
|
||||
network = network_utils._find_network(cc, n)
|
||||
network_names += "{},".format(network.name)
|
||||
network_names = network_names.strip(',')
|
||||
setattr(iinterface, 'networks', network_names)
|
||||
data = [(f, getattr(iinterface, f, '')) for f in fields]
|
||||
data += [(f, getattr(iinterface, f, '')) for f in optional_fields
|
||||
if hasattr(iinterface, f)]
|
||||
@ -153,9 +145,6 @@ def do_host_if_delete(cc, args):
|
||||
metavar='<class>',
|
||||
choices=['platform', 'data', 'pci-passthrough', 'pci-sriov', 'none'],
|
||||
help='The class of the interface')
|
||||
@utils.arg('--networks',
|
||||
metavar='<network name or id>',
|
||||
help="Name or ID of network")
|
||||
@utils.arg('portsorifaces',
|
||||
metavar='<portsorifaces>',
|
||||
nargs='+',
|
||||
@ -177,7 +166,7 @@ def do_host_if_delete(cc, args):
|
||||
def do_host_if_add(cc, args):
|
||||
"""Add an interface."""
|
||||
|
||||
field_list = ['ifname', 'iftype', 'imtu', 'ifclass', 'networks', 'aemode',
|
||||
field_list = ['ifname', 'iftype', 'imtu', 'ifclass', 'aemode',
|
||||
'txhashpolicy', 'datanetworks', 'vlan_id',
|
||||
'ipv4_mode', 'ipv6_mode', 'ipv4_pool', 'ipv6_pool']
|
||||
|
||||
@ -204,10 +193,6 @@ def do_host_if_add(cc, args):
|
||||
user_specified_fields['datanetworks'] = \
|
||||
user_specified_fields['datanetworks'].split(',')
|
||||
|
||||
if 'networks' in user_specified_fields.keys():
|
||||
network = network_utils._find_network(cc, args.networks)
|
||||
user_specified_fields['networks'] = [str(network.id)]
|
||||
|
||||
user_specified_fields['ihost_uuid'] = ihost.uuid
|
||||
user_specified_fields['ports'] = portnamesoruuids
|
||||
user_specified_fields['uses'] = uses
|
||||
@ -251,9 +236,6 @@ def do_host_if_add(cc, args):
|
||||
@utils.arg('-c', '--ifclass',
|
||||
metavar='<class>',
|
||||
help='The class of the interface')
|
||||
@utils.arg('--networks',
|
||||
metavar='<network name or id>',
|
||||
help="Name or ID of network")
|
||||
@utils.arg('--ipv4-mode',
|
||||
metavar='<ipv4_mode>',
|
||||
choices=['disabled', 'static', 'pool'],
|
||||
@ -281,7 +263,7 @@ def do_host_if_modify(cc, args):
|
||||
"""Modify interface attributes."""
|
||||
|
||||
rwfields = ['iftype', 'ifname', 'imtu', 'aemode', 'txhashpolicy',
|
||||
'datanetworks', 'providernetworks', 'ports', 'ifclass', 'networks',
|
||||
'datanetworks', 'providernetworks', 'ports', 'ifclass',
|
||||
'ipv4_mode', 'ipv6_mode', 'ipv4_pool', 'ipv6_pool',
|
||||
'sriov_numvfs', 'sriov_vf_driver']
|
||||
|
||||
@ -303,10 +285,6 @@ def do_host_if_modify(cc, args):
|
||||
fields = interface.__dict__
|
||||
fields.update(user_specified_fields)
|
||||
|
||||
if 'networks' in user_specified_fields.keys():
|
||||
network = network_utils._find_network(cc, args.networks)
|
||||
user_specified_fields['networks'] = str(network.id)
|
||||
|
||||
# Allow setting an interface back to a None type
|
||||
if 'ifclass' in user_specified_fields.keys():
|
||||
if args.ifclass == 'none':
|
||||
|
@ -56,3 +56,11 @@ class InterfaceNetworkManager(base.Manager):
|
||||
def remove(self, interface_network_uuid):
|
||||
path = '/v1/interface_networks/%s' % interface_network_uuid
|
||||
return self._delete(path)
|
||||
|
||||
|
||||
def get_network_names(cc, interface):
|
||||
network_names = []
|
||||
ifnets = cc.interface_network.list_by_interface(interface.uuid)
|
||||
for ifnet in ifnets:
|
||||
network_names.append(getattr(ifnet, 'network_name'))
|
||||
return network_names
|
||||
|
@ -16,6 +16,7 @@ from cgtsclient import exc
|
||||
from cgtsclient.v1 import ethernetport as ethernetport_utils
|
||||
from cgtsclient.v1 import icpu as icpu_utils
|
||||
from cgtsclient.v1 import ihost as ihost_utils
|
||||
from cgtsclient.v1 import interface_network as ifnet_utils
|
||||
from cgtsclient.v1 import iprofile as iprofile_utils
|
||||
import math
|
||||
|
||||
@ -58,11 +59,13 @@ def get_portconfig(iprofile):
|
||||
return pstr
|
||||
|
||||
|
||||
def get_interfaceconfig(iprofile):
|
||||
def get_interfaceconfig(cc, iprofile):
|
||||
istr = ''
|
||||
for interface in iprofile.interfaces:
|
||||
istr = istr + "%s: %s" % (interface.ifname, interface.networktype)
|
||||
if interface.networktype == 'data':
|
||||
if interface.ifclass == 'platform':
|
||||
network_names = ifnet_utils.get_network_names(cc, interface)
|
||||
istr = istr + "%s: %s" % (interface.ifname, network_names)
|
||||
elif interface.ifclass == 'data':
|
||||
istr = istr + "( %s )" % interface.datanetworks
|
||||
_get_interface_ports_interfaces(iprofile, interface)
|
||||
if interface.ports:
|
||||
@ -83,7 +86,7 @@ def get_ifprofile_data(cc, iprofile):
|
||||
if iprofile.ports: # an 'interface' profile
|
||||
iprofile.portconfig = get_portconfig(iprofile)
|
||||
iprofile.interfaces = cc.iprofile.list_iinterface(iprofile.uuid)
|
||||
iprofile.interfaceconfig = get_interfaceconfig(iprofile)
|
||||
iprofile.interfaceconfig = get_interfaceconfig(cc, iprofile)
|
||||
|
||||
|
||||
def do_ifprofile_list(cc, args):
|
||||
@ -91,7 +94,7 @@ def do_ifprofile_list(cc, args):
|
||||
profiles = cc.iprofile.list_interface_profiles()
|
||||
for profile in profiles:
|
||||
profile.portconfig = get_portconfig(profile)
|
||||
profile.interfaceconfig = get_interfaceconfig(profile)
|
||||
profile.interfaceconfig = get_interfaceconfig(cc, profile)
|
||||
|
||||
field_labels = ['uuid', 'name', 'port config', 'interface config']
|
||||
fields = ['uuid', 'profilename', 'portconfig', 'interfaceconfig']
|
||||
|
@ -213,22 +213,22 @@ class AgentManager(service.PeriodicService):
|
||||
# do not bother with alarms since that adds too much noise.
|
||||
LOG.info("Cross-numa performance degradation over port %s "
|
||||
"on processor %d on host %s. Better performance "
|
||||
"if you configure %s interface on port "
|
||||
"if you configure platform interface on port "
|
||||
"residing on processor 0, or configure a platform "
|
||||
"core on processor %d." %
|
||||
(info['name'], info['numa_node'], self.host,
|
||||
info['networktype'], info['numa_node']))
|
||||
info['numa_node']))
|
||||
|
||||
LOG.info("Affine %s interface %s with cpulist %s" %
|
||||
(info['networktype'], info['name'], cpulist))
|
||||
LOG.info("Affine platform interface %s with cpulist %s" %
|
||||
(info['name'], cpulist))
|
||||
cmd = '/usr/bin/affine-interrupts.sh %s %s' % \
|
||||
(info['name'], cpulist)
|
||||
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
|
||||
proc.communicate()
|
||||
LOG.info("%s return %d" % (cmd, proc.returncode))
|
||||
if proc.returncode == 1:
|
||||
LOG.error("Failed to affine %s %s interrupts with %s" %
|
||||
(info['networktype'], info['name'], cpulist))
|
||||
LOG.error("Failed to affine platform interface %s interrupts with %s" %
|
||||
(info['name'], cpulist))
|
||||
|
||||
def _update_ttys_dcd_status(self, context, host_id):
|
||||
# Retrieve the serial line carrier detect flag
|
||||
|
@ -246,11 +246,13 @@ class AddressController(rest.RestController):
|
||||
|
||||
def _check_interface_type(self, interface_id):
|
||||
interface = pecan.request.dbapi.iinterface_get(interface_id)
|
||||
if not interface.networktype:
|
||||
raise exception.InterfaceNetworkTypeNotSet()
|
||||
if interface.networktype not in ALLOWED_NETWORK_TYPES:
|
||||
raise exception.UnsupportedInterfaceNetworkType(
|
||||
networktype=interface.networktype)
|
||||
if (interface['ifclass'] == constants.INTERFACE_TYPE_PLATFORM and
|
||||
interface['networktypelist'] is None):
|
||||
raise exception.InterfaceNetworkNotSet()
|
||||
for nt in interface['networktypelist']:
|
||||
if nt not in ALLOWED_NETWORK_TYPES:
|
||||
raise exception.UnsupportedInterfaceNetworkType(
|
||||
networktype=nt)
|
||||
return
|
||||
|
||||
def _check_address_mode(self, interface_id, family):
|
||||
@ -292,10 +294,9 @@ class AddressController(rest.RestController):
|
||||
|
||||
def _check_address_count(self, interface_id, host_id):
|
||||
interface = pecan.request.dbapi.iinterface_get(interface_id)
|
||||
networktype = interface['networktype']
|
||||
sdn_enabled = utils.get_sdn_enabled()
|
||||
|
||||
if networktype == constants.NETWORK_TYPE_DATA and not sdn_enabled:
|
||||
if interface['ifclass'] == constants.INTERFACE_CLASS_DATA and not sdn_enabled:
|
||||
# Is permitted to add multiple addresses only
|
||||
# if SDN L3 mode is not enabled.
|
||||
return
|
||||
@ -309,12 +310,12 @@ class AddressController(rest.RestController):
|
||||
# skip the one we came in with
|
||||
if uuid == interface_id:
|
||||
continue
|
||||
if iface['ifclass'] == constants.NETWORK_TYPE_DATA:
|
||||
if iface['ifclass'] == constants.INTERFACE_CLASS_DATA:
|
||||
addresses = (
|
||||
pecan.request.dbapi.addresses_get_by_interface(uuid))
|
||||
if len(addresses) != 0:
|
||||
raise exception.\
|
||||
AddressLimitedToOneWithSDN(iftype=networktype)
|
||||
raise exception.AddressLimitedToOneWithSDN(
|
||||
iftype=constants.INTERFACE_CLASS_DATA)
|
||||
|
||||
def _check_address_conflicts(self, host_id, interface_id, address):
|
||||
self._check_address_count(interface_id, host_id)
|
||||
@ -357,13 +358,14 @@ class AddressController(rest.RestController):
|
||||
def _check_managed_addr(self, host_id, interface_id):
|
||||
# Check that static address alloc is enabled
|
||||
interface = pecan.request.dbapi.iinterface_get(interface_id)
|
||||
networktype = interface['networktype']
|
||||
if networktype not in [constants.NETWORK_TYPE_MGMT,
|
||||
constants.NETWORK_TYPE_OAM]:
|
||||
return
|
||||
network = pecan.request.dbapi.network_get_by_type(networktype)
|
||||
if network.dynamic:
|
||||
raise exception.StaticAddressNotConfigured()
|
||||
if interface['networktypelist']:
|
||||
for networktype in interface['networktypelist']:
|
||||
if networktype not in [constants.NETWORK_TYPE_MGMT,
|
||||
constants.NETWORK_TYPE_OAM]:
|
||||
continue
|
||||
network = pecan.request.dbapi.network_get_by_type(networktype)
|
||||
if network.dynamic:
|
||||
raise exception.StaticAddressNotConfigured()
|
||||
host = pecan.request.dbapi.ihost_get(host_id)
|
||||
if host['personality'] in [constants.STORAGE]:
|
||||
raise exception.ManagedIPAddress()
|
||||
|
@ -3106,8 +3106,8 @@ class HostController(rest.RestController):
|
||||
"""
|
||||
count = 0
|
||||
|
||||
if interface.networktype not in address_api.ALLOWED_NETWORK_TYPES:
|
||||
return
|
||||
if not any(nt in address_api.ALLOWED_NETWORK_TYPES for nt in interface.networktypelist):
|
||||
return
|
||||
# Check IPv4 address presence
|
||||
addresses = pecan.request.dbapi.addresses_get_by_interface(
|
||||
interface['id'], family=constants.IPV4_FAMILY)
|
||||
@ -3134,9 +3134,9 @@ class HostController(rest.RestController):
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
if min_count and (count < min_count):
|
||||
msg = (_("Expecting at least %(min)s IP address(es) on "
|
||||
"%(networktype)s interface %(ifname)s; found %(count)s") %
|
||||
"%(ifclass)s interface %(ifname)s; found %(count)s") %
|
||||
{'min': min_count,
|
||||
'networktype': interface.networktype,
|
||||
'ifclass': interface.ifclass,
|
||||
'ifname': interface.ifname,
|
||||
'count': count})
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
@ -3220,7 +3220,7 @@ class HostController(rest.RestController):
|
||||
interfaces = (
|
||||
pecan.request.dbapi.iinterface_get_by_ihost(ihost['uuid']))
|
||||
for interface in interfaces:
|
||||
if interface.networktype == constants.NETWORK_TYPE_OAM:
|
||||
if constants.NETWORK_TYPE_OAM in interface.networktypelist:
|
||||
break
|
||||
else:
|
||||
msg = _("Can not unlock a controller host without an oam "
|
||||
@ -3333,7 +3333,7 @@ class HostController(rest.RestController):
|
||||
address_count = 0
|
||||
interfaces = pecan.request.dbapi.iinterface_get_by_ihost(ihost['uuid'])
|
||||
for iface in interfaces:
|
||||
if iface.networktype != constants.NETWORK_TYPE_DATA:
|
||||
if iface.ifclass != constants.INTERFACE_TYPE_DATA:
|
||||
continue
|
||||
addresses = (
|
||||
pecan.request.dbapi.addresses_get_by_interface(iface['uuid']))
|
||||
@ -5900,11 +5900,10 @@ class HostController(rest.RestController):
|
||||
# controller/worker/storage
|
||||
ihost_iinterfaces = pecan.request.dbapi.iinterface_get_by_ihost(
|
||||
ihost['uuid'])
|
||||
network = pecan.request.dbapi.network_get_by_type(
|
||||
constants.NETWORK_TYPE_MGMT)
|
||||
mgmt_interface_configured = False
|
||||
for iif in ihost_iinterfaces:
|
||||
if iif.networks and str(network.id) in iif.networks:
|
||||
if (iif.networktypelist and
|
||||
constants.NETWORK_TYPE_MGMT in iif.networktypelist):
|
||||
mgmt_interface_configured = True
|
||||
|
||||
if not mgmt_interface_configured:
|
||||
@ -5917,10 +5916,9 @@ class HostController(rest.RestController):
|
||||
# controller/worker/storage
|
||||
host_interfaces = pecan.request.dbapi.iinterface_get_by_ihost(
|
||||
ihost['uuid'])
|
||||
network = pecan.request.dbapi.network_get_by_type(
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST)
|
||||
for iif in host_interfaces:
|
||||
if iif.networks and str(network.id) in iif.networks:
|
||||
if (iif.networktypelist and
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST in iif.networktypelist):
|
||||
break
|
||||
else:
|
||||
msg = _("Cannot unlock host %s "
|
||||
@ -5969,15 +5967,9 @@ class HostController(rest.RestController):
|
||||
# updated management interfaces
|
||||
idata = {}
|
||||
for iif in ihost_iinterfaces:
|
||||
iif_networktype = []
|
||||
if iif.networktype:
|
||||
iif_networktype = [network.strip() for network in iif.networktype.split(",")]
|
||||
if any(network in [constants.NETWORK_TYPE_MGMT] for network in iif_networktype):
|
||||
if constants.NETWORK_TYPE_MGMT in iif.networktypelist:
|
||||
for ila in interface_list_active:
|
||||
ila_networktype = []
|
||||
if ila.networktype:
|
||||
ila_networktype = [network.strip() for network in ila.networktype.split(",")]
|
||||
if any(network in ila_networktype for network in iif_networktype):
|
||||
if constants.NETWORK_TYPE_MGMT in ila.networktypelist:
|
||||
idata['imtu'] = ila.imtu
|
||||
pecan.request.dbapi.iinterface_update(iif.uuid, idata)
|
||||
break
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -200,8 +200,10 @@ class InterfaceDataNetworkController(rest.RestController):
|
||||
pecan.request.dbapi.iinterface_update(interface_obj.uuid, values)
|
||||
return
|
||||
else:
|
||||
# Allow ifclass data to assign another; disallow other ifclass
|
||||
if interface_obj.ifclass != constants.INTERFACE_CLASS_DATA:
|
||||
# Allow ifclass data, pcipt and sriov to assign data networks
|
||||
if interface_obj.ifclass not in [constants.INTERFACE_CLASS_DATA,
|
||||
constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
||||
constants.INTERFACE_CLASS_PCI_SRIOV]:
|
||||
msg = _("An interface with interface class '%s' "
|
||||
"cannot assign datanetworks." %
|
||||
interface_obj.ifclass)
|
||||
|
@ -19,6 +19,7 @@
|
||||
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||
#
|
||||
|
||||
import os
|
||||
import uuid
|
||||
import wsme
|
||||
import pecan
|
||||
@ -26,6 +27,7 @@ from pecan import rest
|
||||
from wsme import types as wtypes
|
||||
import wsmeext.pecan as wsme_pecan
|
||||
|
||||
from sysinv.api.controllers.v1 import address_pool
|
||||
from sysinv.api.controllers.v1 import base
|
||||
from sysinv.api.controllers.v1 import collection
|
||||
from sysinv.api.controllers.v1 import types
|
||||
@ -134,8 +136,10 @@ class InterfaceNetworkController(rest.RestController):
|
||||
interface_uuid = interface_network_dict.pop('interface_uuid')
|
||||
network_uuid = interface_network_dict.pop('network_uuid')
|
||||
|
||||
interface_id = self._get_interface_id(interface_uuid)
|
||||
interface_obj = pecan.request.dbapi.iinterface_get(interface_uuid)
|
||||
interface_id = interface_obj.id
|
||||
network_id, network_type = self._get_network_id_and_type(network_uuid)
|
||||
host = pecan.request.dbapi.ihost_get(interface_obj.ihost_uuid)
|
||||
|
||||
interface_network_dict['interface_id'] = interface_id
|
||||
interface_network_dict['network_id'] = network_id
|
||||
@ -143,16 +147,51 @@ class InterfaceNetworkController(rest.RestController):
|
||||
self._check_interface_class(interface_uuid)
|
||||
self._check_assigned_network_type(network_type)
|
||||
self._check_duplicate_interface_network(interface_network_dict)
|
||||
self._check_duplicate_type(interface_id, network_type)
|
||||
self._check_duplicate_type(host, interface_uuid, network_type)
|
||||
self._check_pxeboot_network(interface_id, network_type)
|
||||
self._check_oam_network(interface_id, network_type)
|
||||
self._check_network_type_and_host_type(host, network_type)
|
||||
self._check_network_type_and_interface_type(interface_obj, network_type)
|
||||
self._check_cluster_host_on_controller(host, interface_obj, network_type)
|
||||
|
||||
result = pecan.request.dbapi.interface_network_create(interface_network_dict)
|
||||
|
||||
interface = pecan.request.dbapi.iinterface_get(interface_uuid)
|
||||
if not interface.networktype:
|
||||
values = {'networktype': network_type}
|
||||
pecan.request.dbapi.iinterface_update(interface_uuid, values)
|
||||
# Update address mode based on network type
|
||||
if network_type in [constants.NETWORK_TYPE_MGMT,
|
||||
constants.NETWORK_TYPE_OAM,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST]:
|
||||
pool_uuid = pecan.request.dbapi.network_get_by_type(network_type).pool_uuid
|
||||
pool = pecan.request.dbapi.address_pool_get(pool_uuid)
|
||||
if pool.family == constants.IPV4_FAMILY:
|
||||
utils.update_address_mode(interface_obj, constants.IPV4_FAMILY,
|
||||
constants.IPV4_STATIC, None)
|
||||
utils.update_address_mode(interface_obj, constants.IPV6_FAMILY,
|
||||
constants.IPV6_DISABLED, None)
|
||||
else:
|
||||
utils.update_address_mode(interface_obj, constants.IPV6_FAMILY,
|
||||
constants.IPV6_STATIC, None)
|
||||
utils.update_address_mode(interface_obj, constants.IPV4_FAMILY,
|
||||
constants.IPV4_DISABLED, None)
|
||||
|
||||
# Assign an address to the interface
|
||||
if host.recordtype != "profile":
|
||||
_update_host_address(host, interface_obj, network_type)
|
||||
if network_type == constants.NETWORK_TYPE_MGMT:
|
||||
ethernet_port_mac = None
|
||||
if not interface_obj.uses:
|
||||
# Get the ethernet port associated with the interface
|
||||
interface_ports = pecan.request.dbapi.ethernet_port_get_by_interface(
|
||||
interface_obj.uuid)
|
||||
for p in interface_ports:
|
||||
if p is not None:
|
||||
ethernet_port_mac = p.mac
|
||||
break
|
||||
else:
|
||||
tmp_interface = interface_obj.as_dict()
|
||||
ethernet_port_mac = tmp_interface['imac']
|
||||
_update_host_mgmt_mac(host, ethernet_port_mac)
|
||||
cutils.perform_distributed_cloud_config(pecan.request.dbapi,
|
||||
interface_id)
|
||||
|
||||
return InterfaceNetwork.convert_with_links(result)
|
||||
|
||||
@ -218,16 +257,15 @@ class InterfaceNetworkController(rest.RestController):
|
||||
% (interface_network['interface_id'], interface_network['network_id']))
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
|
||||
def _check_duplicate_type(self, interface_id, network_type):
|
||||
def _check_duplicate_type(self, host, interface_uuid, network_type):
|
||||
if network_type in NONDUPLICATE_NETWORK_TYPES:
|
||||
interface_networks = pecan.request.dbapi.interface_network_get_all()
|
||||
for i in interface_networks:
|
||||
if i.interface_id == interface_id and i.network_type == network_type:
|
||||
msg = _("An interface with network type '%s' is "
|
||||
"already provisioned on this node." % network_type)
|
||||
interfaces = pecan.request.dbapi.iinterface_get_by_ihost(host['uuid'])
|
||||
for host_interface in interfaces:
|
||||
if (network_type in host_interface['networktypelist'] and
|
||||
host_interface['uuid'] != interface_uuid):
|
||||
msg = _("An interface with '%s' network type is "
|
||||
"already provisioned on this node" % network_type)
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
else:
|
||||
return
|
||||
|
||||
def _check_assigned_network_type(self, network_type):
|
||||
if network_type not in NONASSIGNABLE_NETWORK_TYPES:
|
||||
@ -275,6 +313,56 @@ class InterfaceNetworkController(rest.RestController):
|
||||
% (i.network_type, network_type))
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
|
||||
def _check_network_type_and_host_type(self, ihost, network_type):
|
||||
if (network_type == constants.NETWORK_TYPE_OAM and
|
||||
ihost['personality'] != constants.CONTROLLER):
|
||||
msg = _("The '%s' network type is only supported on controller nodes." %
|
||||
constants.NETWORK_TYPE_OAM)
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
|
||||
def _check_network_type_and_interface_type(self, interface, network_type):
|
||||
# Make sure network type 'mgmt', with if type 'ae',
|
||||
# can only be in ae mode 'active_standby' or '802.3ad'
|
||||
if (network_type == constants.NETWORK_TYPE_MGMT):
|
||||
valid_mgmt_aemode = [constants.AE_MODE_LACP,
|
||||
constants.AE_MODE_ACTIVE_STANDBY]
|
||||
if (interface.iftype == constants.INTERFACE_TYPE_AE and
|
||||
interface.aemode not in valid_mgmt_aemode):
|
||||
msg = _("Device interface with network type {}, and interface "
|
||||
"type 'aggregated ethernet' must be in mode {}").format(
|
||||
network_type, ', '.join(valid_mgmt_aemode))
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
# Make sure network type 'oam' or 'cluster-host', with if type 'ae',
|
||||
# can only be in ae mode 'active_standby' or 'balanced' or '802.3ad'
|
||||
elif (network_type in [constants.NETWORK_TYPE_OAM,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST] and
|
||||
interface.iftype == constants.INTERFACE_TYPE_AE and
|
||||
(interface.aemode not in constants.VALID_AEMODE_LIST)):
|
||||
msg = _("Device interface with network type '%s', and interface "
|
||||
"type 'aggregated ethernet' must be in mode 'active_standby' "
|
||||
"or 'balanced' or '802.3ad'." % network_type)
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
|
||||
def _check_cluster_host_on_controller(self, host, interface, network_type):
|
||||
# Check if cluster-host exists on controller, if it doesn't then fail
|
||||
if (host['personality'] != constants.CONTROLLER and
|
||||
network_type == constants.NETWORK_TYPE_CLUSTER_HOST):
|
||||
host_list = pecan.request.dbapi.ihost_get_by_personality(
|
||||
personality=constants.CONTROLLER)
|
||||
cluster_host_on_controller = False
|
||||
for h in host_list:
|
||||
interfaces = pecan.request.dbapi.iinterface_get_by_ihost(ihost=h['uuid'])
|
||||
for host_interface in interfaces:
|
||||
if (host_interface['ifclass'] == constants.INTERFACE_CLASS_PLATFORM and
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST in host_interface['networktypelist']):
|
||||
cluster_host_on_controller = True
|
||||
break
|
||||
if not cluster_host_on_controller:
|
||||
msg = _("Interface %s does not have associated"
|
||||
" cluster-host interface on controller." %
|
||||
interface['ifname'])
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
|
||||
def _get_interface_id(self, interface_uuid):
|
||||
interface = pecan.request.dbapi.iinterface_get(interface_uuid)
|
||||
return interface['id']
|
||||
@ -301,4 +389,125 @@ class InterfaceNetworkController(rest.RestController):
|
||||
@cutils.synchronized(LOCK_NAME)
|
||||
@wsme_pecan.wsexpose(None, types.uuid, status_code=204)
|
||||
def delete(self, interface_network_uuid):
|
||||
# Delete address allocated to the interface
|
||||
if_network_obj = pecan.request.dbapi.interface_network_get(
|
||||
interface_network_uuid)
|
||||
network = pecan.request.dbapi.network_get(if_network_obj.network_uuid)
|
||||
pool_uuid = pecan.request.dbapi.network_get_by_type(network.type).pool_uuid
|
||||
address = None
|
||||
try:
|
||||
address = pecan.request.dbapi.addresses_get_by_interface_pool(
|
||||
if_network_obj.interface_uuid, pool_uuid)
|
||||
except exception.AddressNotFoundByInterfacePool:
|
||||
pass
|
||||
if address:
|
||||
pecan.request.dbapi.address_remove_interface(address.uuid)
|
||||
|
||||
pecan.request.dbapi.interface_network_destroy(interface_network_uuid)
|
||||
|
||||
|
||||
def _update_host_address(host, interface, network_type):
|
||||
if network_type == constants.NETWORK_TYPE_MGMT:
|
||||
_update_host_mgmt_address(host, interface)
|
||||
elif network_type == constants.NETWORK_TYPE_CLUSTER_HOST:
|
||||
_update_host_cluster_address(host, interface)
|
||||
elif network_type == constants.NETWORK_TYPE_IRONIC:
|
||||
_update_host_ironic_address(host, interface)
|
||||
if host.personality == constants.CONTROLLER:
|
||||
if network_type == constants.NETWORK_TYPE_OAM:
|
||||
_update_host_oam_address(host, interface)
|
||||
elif network_type == constants.NETWORK_TYPE_PXEBOOT:
|
||||
_update_host_pxeboot_address(host, interface)
|
||||
|
||||
|
||||
def _dynamic_address_allocation():
|
||||
mgmt_network = pecan.request.dbapi.network_get_by_type(
|
||||
constants.NETWORK_TYPE_MGMT)
|
||||
return mgmt_network.dynamic
|
||||
|
||||
|
||||
def _allocate_pool_address(interface_id, pool_uuid, address_name=None):
|
||||
address_pool.AddressPoolController.assign_address(
|
||||
interface_id, pool_uuid, address_name)
|
||||
|
||||
|
||||
def _update_host_mgmt_address(host, interface):
|
||||
"""Check if the host has a static management IP address assigned
|
||||
and ensure the address is populated against the interface. Otherwise,
|
||||
if using dynamic address allocation, then allocate an address
|
||||
"""
|
||||
|
||||
mgmt_ip = utils.lookup_static_ip_address(
|
||||
host.hostname, constants.NETWORK_TYPE_MGMT)
|
||||
|
||||
if mgmt_ip:
|
||||
pecan.request.rpcapi.mgmt_ip_set_by_ihost(
|
||||
pecan.request.context, host.uuid, interface['id'], mgmt_ip)
|
||||
elif _dynamic_address_allocation():
|
||||
mgmt_pool_uuid = pecan.request.dbapi.network_get_by_type(
|
||||
constants.NETWORK_TYPE_MGMT
|
||||
).pool_uuid
|
||||
address_name = cutils.format_address_name(host.hostname,
|
||||
constants.NETWORK_TYPE_MGMT)
|
||||
_allocate_pool_address(interface['id'], mgmt_pool_uuid, address_name)
|
||||
|
||||
|
||||
def _update_host_oam_address(host, interface):
|
||||
if utils.get_system_mode() == constants.SYSTEM_MODE_SIMPLEX:
|
||||
address_name = cutils.format_address_name(constants.CONTROLLER_HOSTNAME,
|
||||
constants.NETWORK_TYPE_OAM)
|
||||
else:
|
||||
address_name = cutils.format_address_name(host.hostname,
|
||||
constants.NETWORK_TYPE_OAM)
|
||||
address = pecan.request.dbapi.address_get_by_name(address_name)
|
||||
updates = {'interface_id': interface['id']}
|
||||
pecan.request.dbapi.address_update(address.uuid, updates)
|
||||
|
||||
|
||||
def _update_host_pxeboot_address(host, interface):
|
||||
address_name = cutils.format_address_name(host.hostname,
|
||||
constants.NETWORK_TYPE_PXEBOOT)
|
||||
address = pecan.request.dbapi.address_get_by_name(address_name)
|
||||
updates = {'interface_id': interface['id']}
|
||||
pecan.request.dbapi.address_update(address.uuid, updates)
|
||||
|
||||
|
||||
def _update_host_cluster_address(host, interface):
|
||||
"""
|
||||
Check if the host has a cluster-host IP address assigned
|
||||
and the address is populated against the interface.
|
||||
Otherwise, allocate an address from the pool.
|
||||
"""
|
||||
address_name = cutils.format_address_name(
|
||||
host.hostname, constants.NETWORK_TYPE_CLUSTER_HOST)
|
||||
try:
|
||||
address = pecan.request.dbapi.address_get_by_name(address_name)
|
||||
updates = {'interface_id': interface['id']}
|
||||
pecan.request.dbapi.address_update(address.uuid, updates)
|
||||
except exception.AddressNotFoundByName:
|
||||
cluster_host_pool_uuid = pecan.request.dbapi.network_get_by_type(
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST
|
||||
).pool_uuid
|
||||
_allocate_pool_address(interface['id'], cluster_host_pool_uuid,
|
||||
address_name)
|
||||
|
||||
|
||||
def _update_host_ironic_address(host, interface):
|
||||
address_name = cutils.format_address_name(host.hostname,
|
||||
constants.NETWORK_TYPE_IRONIC)
|
||||
address = pecan.request.dbapi.address_get_by_name(address_name)
|
||||
updates = {'interface_id': interface['id']}
|
||||
pecan.request.dbapi.address_update(address.uuid, updates)
|
||||
|
||||
|
||||
def _update_host_mgmt_mac(host, mgmt_mac):
|
||||
"""Update host mgmt mac to reflect interface change.
|
||||
"""
|
||||
|
||||
if (os.path.isfile(constants.ANSIBLE_BOOTSTRAP_FLAG) and
|
||||
mgmt_mac is not None):
|
||||
# This must be called during management interface provisioning
|
||||
# following controller-0 bootstrap.
|
||||
if host['mgmt_mac'] != mgmt_mac:
|
||||
pecan.request.rpcapi.mgmt_mac_set_by_ihost(
|
||||
pecan.request.context, host, mgmt_mac)
|
||||
|
@ -35,6 +35,7 @@ from sysinv.api.controllers.v1 import cpu as cpu_api
|
||||
from sysinv.api.controllers.v1 import disk as disk_api
|
||||
from sysinv.api.controllers.v1 import partition as partition_api
|
||||
from sysinv.api.controllers.v1 import interface as interface_api
|
||||
from sysinv.api.controllers.v1 import interface_network as ifnet_api
|
||||
from sysinv.api.controllers.v1 import memory as memory_api
|
||||
from sysinv.api.controllers.v1 import node as node_api
|
||||
from sysinv.api.controllers.v1 import storage as storage_api
|
||||
@ -2022,6 +2023,13 @@ def ifprofile_copy_data(host, profile):
|
||||
pdict = {k: v for (k, v) in p.as_dict().items() if k in ethernet_port_fields}
|
||||
pecan.request.dbapi.ethernet_port_create(iprofile_id, pdict)
|
||||
|
||||
interface_networks = pecan.request.dbapi.interface_network_get_by_interface(i.id)
|
||||
for ifnet in interface_networks:
|
||||
ifnetdict = {}
|
||||
ifnetdict['interface_id'] = newIf.id
|
||||
ifnetdict['network_id'] = ifnet.network_id
|
||||
pecan.request.dbapi.interface_network_create(ifnetdict)
|
||||
|
||||
# Generate the uses/used_by relationships
|
||||
for i in newIfList:
|
||||
uses_list = []
|
||||
@ -2614,6 +2622,14 @@ def ifprofile_apply_to_host(host, profile):
|
||||
|
||||
if interface_found is False:
|
||||
hinterface = interface_api._create(data, from_profile=True)
|
||||
interface_networks = pecan.request.dbapi.interface_network_get_by_interface(interface.id)
|
||||
for ifnet in interface_networks:
|
||||
ifnetdict = {}
|
||||
ifnetdict['interface_id'] = hinterface.id
|
||||
ifnetdict['network_id'] = ifnet.network_id
|
||||
pecan.request.dbapi.interface_network_create(ifnetdict)
|
||||
network = pecan.request.dbapi.network_get_by_id(ifnet.network_id)
|
||||
ifnet_api._update_host_address(host, hinterface, network.type)
|
||||
|
||||
except Exception as e:
|
||||
# Delete all Host's interfaces
|
||||
@ -2678,6 +2694,15 @@ def ifprofile_apply_to_host(host, profile):
|
||||
data['forihostid'] = host.id
|
||||
hinterface = interface_api._create(data, from_profile=True)
|
||||
|
||||
interface_networks = pecan.request.dbapi.interface_network_get_by_interface(i.id)
|
||||
for ifnet in interface_networks:
|
||||
ifnetdict = {}
|
||||
ifnetdict['interface_id'] = hinterface.id
|
||||
ifnetdict['network_id'] = ifnet.network_id
|
||||
pecan.request.dbapi.interface_network_create(ifnetdict)
|
||||
network = pecan.request.dbapi.network_get_by_id(ifnet.network_id)
|
||||
ifnet_api._update_host_address(host, hinterface, network.type)
|
||||
|
||||
for r in profile.routes.get(i.uuid, []):
|
||||
pecan.request.dbapi.route_create(hinterface.id, r)
|
||||
|
||||
|
@ -263,9 +263,12 @@ class RouteController(rest.RestController):
|
||||
|
||||
def _check_interface_type(self, interface_id):
|
||||
interface = pecan.request.dbapi.iinterface_get(interface_id)
|
||||
networktype = interface['networktype']
|
||||
if networktype not in ALLOWED_NETWORK_TYPES:
|
||||
raise exception.RoutesNotSupportedOnInterfaces(iftype=networktype)
|
||||
if (interface['ifclass'] == constants.INTERFACE_TYPE_PLATFORM and
|
||||
interface['networktypelist'] is None):
|
||||
raise exception.InterfaceNetworkNotSet()
|
||||
for nt in interface['networktypelist']:
|
||||
if nt not in ALLOWED_NETWORK_TYPES:
|
||||
raise exception.RoutesNotSupportedOnInterfaces(type=nt)
|
||||
return
|
||||
|
||||
def _check_duplicate_route(self, host_id, route):
|
||||
|
@ -598,11 +598,9 @@ class SystemController(rest.RestController):
|
||||
host_id = controller['id']
|
||||
interface_list = pecan.request.dbapi.iinterface_get_by_ihost(host_id)
|
||||
for interface in interface_list:
|
||||
for network_id in interface['networks']:
|
||||
network = pecan.request.dbapi.network_get_by_id(network_id)
|
||||
if network.type == constants.NETWORK_TYPE_MGMT:
|
||||
if 'vlan_id' not in interface:
|
||||
return 0
|
||||
else:
|
||||
return interface['vlan_id']
|
||||
if constants.NETWORK_TYPE_MGMT in interface['networktypelist']:
|
||||
if 'vlan_id' not in interface:
|
||||
return 0
|
||||
else:
|
||||
return interface['vlan_id']
|
||||
return None
|
||||
|
@ -326,6 +326,28 @@ def lookup_static_ip_address(name, networktype):
|
||||
return None
|
||||
|
||||
|
||||
def update_address_mode(interface, family, mode, pool):
|
||||
interface_id = interface['id']
|
||||
pool_id = pecan.request.dbapi.address_pool_get(pool)['id'] if pool else None
|
||||
try:
|
||||
# retrieve the existing value and compare
|
||||
existing = pecan.request.dbapi.address_mode_query(
|
||||
interface_id, family)
|
||||
if existing.mode == mode:
|
||||
if (mode != 'pool' or existing.pool_uuid == pool):
|
||||
return
|
||||
if existing.mode == 'pool' or (not mode or mode == 'disabled'):
|
||||
pecan.request.dbapi.routes_destroy_by_interface(
|
||||
interface_id, family)
|
||||
pecan.request.dbapi.addresses_destroy_by_interface(
|
||||
interface_id, family)
|
||||
except exception.AddressModeNotFoundByFamily:
|
||||
# continue and update DB with new record
|
||||
pass
|
||||
updates = {'family': family, 'mode': mode, 'address_pool_id': pool_id}
|
||||
pecan.request.dbapi.address_mode_update(interface_id, updates)
|
||||
|
||||
|
||||
class SystemHelper(object):
|
||||
@staticmethod
|
||||
def get_product_build():
|
||||
|
@ -650,6 +650,13 @@ INTERFACE_CLASS_DATA = 'data'
|
||||
INTERFACE_CLASS_PCI_PASSTHROUGH = 'pci-passthrough'
|
||||
INTERFACE_CLASS_PCI_SRIOV = 'pci-sriov'
|
||||
|
||||
AE_MODE_ACTIVE_STANDBY = 'active_standby'
|
||||
AE_MODE_BALANCED = 'balanced'
|
||||
AE_MODE_LACP = '802.3ad'
|
||||
VALID_AEMODE_LIST = [AE_MODE_ACTIVE_STANDBY,
|
||||
AE_MODE_BALANCED,
|
||||
AE_MODE_LACP]
|
||||
|
||||
SM_MULTICAST_MGMT_IP_NAME = "sm-mgmt-ip"
|
||||
MTCE_MULTICAST_MGMT_IP_NAME = "mtce-mgmt-ip"
|
||||
PATCH_CONTROLLER_MULTICAST_MGMT_IP_NAME = "patch-controller-mgmt-ip"
|
||||
|
@ -331,9 +331,8 @@ class InterfaceNameAlreadyExists(Conflict):
|
||||
message = _("Interface with name %(name)s already exists.")
|
||||
|
||||
|
||||
class InterfaceNetworkTypeNotSet(Conflict):
|
||||
message = _("The Interface must have a networktype configured to "
|
||||
"support addresses. (data or infra)")
|
||||
class InterfaceNetworkNotSet(Conflict):
|
||||
message = _("The Interface does not have any network assigned to it.")
|
||||
|
||||
|
||||
class AddressInUseByRouteGateway(Conflict):
|
||||
@ -372,7 +371,7 @@ class RouteGatewayCannotBeLocal(Conflict):
|
||||
|
||||
class RoutesNotSupportedOnInterfaces(Conflict):
|
||||
message = _("Routes may not be configured against interfaces with network "
|
||||
"type '%(iftype)s'")
|
||||
"type '%(type)s'")
|
||||
|
||||
|
||||
class DefaultRouteNotAllowedOnVRSInterface(Conflict):
|
||||
@ -699,6 +698,11 @@ class AddressNotFoundByName(NotFound):
|
||||
message = _("Address could not be found for %(name)s")
|
||||
|
||||
|
||||
class AddressNotFoundByInterfacePool(NotFound):
|
||||
message = _("Address could not be found for interface %(interface)s "
|
||||
"pool %(pool)s")
|
||||
|
||||
|
||||
class AddressModeAlreadyExists(Conflict):
|
||||
message = _("An AddressMode with UUID %(uuid)s already exists.")
|
||||
|
||||
|
@ -1027,51 +1027,6 @@ def get_required_platform_reserved_memory(ihost, numa_node, low_core=False):
|
||||
return required_reserved
|
||||
|
||||
|
||||
def get_network_type_list(interface):
|
||||
if interface['networktype']:
|
||||
return [n.strip() for n in interface['networktype'].split(",")]
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def is_pci_network_types(networktypelist):
|
||||
"""
|
||||
Check if the network type consists of the combined PCI passthrough
|
||||
and SRIOV network types.
|
||||
"""
|
||||
return (len(constants.PCI_NETWORK_TYPES) == len(networktypelist) and
|
||||
all(i in networktypelist for i in constants.PCI_NETWORK_TYPES))
|
||||
|
||||
|
||||
def get_primary_network_type(interface):
|
||||
"""
|
||||
An interface can be associated with up to 2 network types but it can only
|
||||
have 1 primary network type. The additional network type can only be
|
||||
'data' and is used as a placeholder to indicate that there is at least one
|
||||
VLAN based neutron provider network associated to the interface. This
|
||||
information is used to determine whether the vswitch on the worker needs
|
||||
to control the interface or not. This function examines the list of
|
||||
network types, discards the secondary type (if any) and returns the primary
|
||||
network type.
|
||||
"""
|
||||
if not interface['ifclass'] or interface['ifclass'] == constants.INTERFACE_CLASS_NONE:
|
||||
return None
|
||||
primary_network_type = None
|
||||
if interface['ifclass'] == constants.INTERFACE_CLASS_DATA:
|
||||
primary_network_type = constants.NETWORK_TYPE_DATA
|
||||
elif interface['ifclass'] == constants.INTERFACE_CLASS_PCI_PASSTHROUGH:
|
||||
primary_network_type = constants.NETWORK_TYPE_PCI_PASSTHROUGH
|
||||
elif interface['ifclass'] == constants.INTERFACE_CLASS_PCI_SRIOV:
|
||||
primary_network_type = constants.NETWORK_TYPE_PCI_SRIOV
|
||||
elif interface['ifclass'] == constants.INTERFACE_CLASS_PLATFORM:
|
||||
if not interface['networktype'] or interface[
|
||||
'networktype'] == constants.NETWORK_TYPE_NONE:
|
||||
return None
|
||||
primary_network_type = interface['networktype']
|
||||
|
||||
return primary_network_type
|
||||
|
||||
|
||||
def get_sw_version():
|
||||
return SW_VERSION
|
||||
|
||||
@ -1502,7 +1457,7 @@ def perform_distributed_cloud_config(dbapi, mgmt_iface_id):
|
||||
mate_interfaces = dbapi.iinterface_get_all(
|
||||
forihostid=mate_controller_id)
|
||||
for interface in mate_interfaces:
|
||||
if interface.networktype == constants.NETWORK_TYPE_MGMT:
|
||||
if constants.NETWORK_TYPE_MGMT in interface.networktypelist:
|
||||
mate_mgmt_iface = interface
|
||||
break
|
||||
else:
|
||||
|
@ -1196,7 +1196,7 @@ class ConductorManager(service.PeriodicService):
|
||||
port_list = self.dbapi.port_get_all(host_id)
|
||||
ports = dict((p['interface_id'], p) for p in port_list)
|
||||
for interface in interface_list:
|
||||
if interface.networktype == network_type:
|
||||
if network_type in interface.networktypelist:
|
||||
return cutils.get_interface_os_ifname(interface, ifaces, ports)
|
||||
|
||||
def _find_local_mgmt_interface_vlan_id(self):
|
||||
@ -1204,7 +1204,7 @@ class ConductorManager(service.PeriodicService):
|
||||
host_id = self.get_my_host_id()
|
||||
interface_list = self.dbapi.iinterface_get_all(host_id, expunge=True)
|
||||
for interface in interface_list:
|
||||
if interface.networktype == constants.NETWORK_TYPE_MGMT:
|
||||
if constants.NETWORK_TYPE_MGMT in interface.networktypelist:
|
||||
if 'vlan_id' not in interface:
|
||||
return 0
|
||||
else:
|
||||
@ -1820,7 +1820,7 @@ class ConductorManager(service.PeriodicService):
|
||||
expunge=True)
|
||||
|
||||
for i in iinterfaces:
|
||||
if i.networktype == constants.NETWORK_TYPE_MGMT:
|
||||
if constants.NETWORK_TYPE_MGMT in i.networktypelist:
|
||||
break
|
||||
|
||||
cloning = False
|
||||
@ -1923,7 +1923,6 @@ class ConductorManager(service.PeriodicService):
|
||||
'imtu': mtu,
|
||||
'iftype': 'ethernet',
|
||||
'ifclass': ifclass,
|
||||
'networktype': networktype
|
||||
}
|
||||
|
||||
# autocreate untagged interface
|
||||
@ -1940,6 +1939,7 @@ class ConductorManager(service.PeriodicService):
|
||||
})
|
||||
if networktype in [constants.NETWORK_TYPE_MGMT,
|
||||
constants.NETWORK_TYPE_PXEBOOT]:
|
||||
new_interface_networktype = networktype
|
||||
network = self.dbapi.network_get_by_type(networktype)
|
||||
# create interface network association
|
||||
ifnet_dict = {
|
||||
@ -1960,6 +1960,7 @@ class ConductorManager(service.PeriodicService):
|
||||
|
||||
if create_tagged_interface:
|
||||
# autocreate tagged management interface
|
||||
network = self.dbapi.network_get_by_type(constants.NETWORK_TYPE_MGMT)
|
||||
interface_dict = {
|
||||
'forihostid': ihost['id'],
|
||||
'ifname': 'mgmt0',
|
||||
@ -1967,7 +1968,6 @@ class ConductorManager(service.PeriodicService):
|
||||
'imtu': constants.DEFAULT_MTU,
|
||||
'iftype': 'vlan',
|
||||
'ifclass': constants.INTERFACE_CLASS_PLATFORM,
|
||||
'networktype': constants.NETWORK_TYPE_MGMT,
|
||||
'uses': [ifname],
|
||||
'vlan_id': vlan_id,
|
||||
}
|
||||
@ -1978,6 +1978,7 @@ class ConductorManager(service.PeriodicService):
|
||||
new_interface = self.dbapi.iinterface_create(
|
||||
ihost['id'], interface_dict
|
||||
)
|
||||
new_interface_networktype = constants.NETWORK_TYPE_MGMT
|
||||
network = self.dbapi.network_get_by_type(
|
||||
constants.NETWORK_TYPE_MGMT
|
||||
)
|
||||
@ -2057,7 +2058,7 @@ class ConductorManager(service.PeriodicService):
|
||||
values = {'interface_id': new_interface['id']}
|
||||
try:
|
||||
addr_name = cutils.format_address_name(
|
||||
ihost.hostname, new_interface['networktype'])
|
||||
ihost.hostname, new_interface_networktype)
|
||||
address = self.dbapi.address_get_by_name(addr_name)
|
||||
self.dbapi.address_update(address['uuid'], values)
|
||||
except exception.AddressNotFoundByName:
|
||||
@ -8449,7 +8450,8 @@ class ConductorManager(service.PeriodicService):
|
||||
|
||||
if nettype:
|
||||
iinterfaces[:] = [i for i in iinterfaces if
|
||||
i.networktype == nettype]
|
||||
nettype in i.networktypelist]
|
||||
|
||||
return iinterfaces
|
||||
|
||||
def mgmt_ip_set_by_ihost(self,
|
||||
@ -8604,13 +8606,12 @@ class ConductorManager(service.PeriodicService):
|
||||
|
||||
return ilvgs
|
||||
|
||||
def _add_port_to_list(self, interface_id, networktype, port_list):
|
||||
def _add_port_to_list(self, interface_id, port_list):
|
||||
info = {}
|
||||
ports = self.dbapi.port_get_all(interfaceid=interface_id)
|
||||
if ports:
|
||||
info['name'] = ports[0]['name']
|
||||
info['numa_node'] = ports[0]['numa_node']
|
||||
info['networktype'] = networktype
|
||||
if info not in port_list:
|
||||
port_list.append(info)
|
||||
return port_list
|
||||
@ -8622,30 +8623,22 @@ class ConductorManager(service.PeriodicService):
|
||||
info_list = []
|
||||
interface_list = self.dbapi.iinterface_get_all(ihost_id, expunge=True)
|
||||
for interface in interface_list:
|
||||
ntype = interface['networktype']
|
||||
if (ntype == constants.NETWORK_TYPE_CLUSTER_HOST or
|
||||
ntype == constants.NETWORK_TYPE_MGMT):
|
||||
if interface['iftype'] == 'vlan' or \
|
||||
interface['iftype'] == 'ae':
|
||||
if interface['ifclass'] == constants.INTERFACE_CLASS_PLATFORM:
|
||||
if interface['iftype'] == constants.INTERFACE_TYPE_VLAN or \
|
||||
interface['iftype'] == constants.INTERFACE_TYPE_AE:
|
||||
for uses_if in interface['uses']:
|
||||
for i in interface_list:
|
||||
if i['ifname'] == str(uses_if):
|
||||
if i['iftype'] == 'ethernet':
|
||||
info_list = self._add_port_to_list(i['id'],
|
||||
ntype,
|
||||
lower_iface = self.dbapi.iinterface_get(uses_if, ihost_id)
|
||||
if lower_iface['iftype'] == constants.INTERFACE_TYPE_ETHERNET:
|
||||
info_list = self._add_port_to_list(lower_iface['id'],
|
||||
info_list)
|
||||
elif lower_iface['iftype'] == constants.INTERFACE_TYPE_AE:
|
||||
for lower_uses_if in lower_iface['uses']:
|
||||
ll_iface = self.dbapi.iinterface_get(lower_uses_if, ihost_id)
|
||||
if ll_iface['iftype'] == constants.INTERFACE_TYPE_ETHERNET:
|
||||
info_list = self._add_port_to_list(ll_iface['id'],
|
||||
info_list)
|
||||
elif i['iftype'] == 'ae':
|
||||
for uses in i['uses']:
|
||||
for a in interface_list:
|
||||
if a['ifname'] == str(uses) and \
|
||||
a['iftype'] == 'ethernet':
|
||||
info_list = self._add_port_to_list(
|
||||
a['id'],
|
||||
ntype,
|
||||
info_list)
|
||||
elif interface['iftype'] == 'ethernet':
|
||||
elif interface['iftype'] == constants.INTERFACE_TYPE_ETHERNET:
|
||||
info_list = self._add_port_to_list(interface['id'],
|
||||
ntype,
|
||||
info_list)
|
||||
|
||||
LOG.info("platform_interfaces host_id=%s info_list=%s" %
|
||||
|
@ -842,7 +842,6 @@ class Connection(object):
|
||||
{
|
||||
'uuid': uuidutils.generate_uuid(),
|
||||
'ifname': 'bond1',
|
||||
'networktype': constants.NETWORK_TYPE_DATA,
|
||||
'aemode': 'balanced',
|
||||
'schedpolicy': 'xor',
|
||||
'txhashpolicy': 'L2',
|
||||
@ -934,7 +933,6 @@ class Connection(object):
|
||||
{
|
||||
'uuid': uuidutils.generate_uuid(),
|
||||
'ifname': 'eth1',
|
||||
'networktype': constants.NETWORK_TYPE_MGMT,
|
||||
'extra': { ... },
|
||||
}
|
||||
:returns: An EthernetInterface.
|
||||
|
@ -2085,14 +2085,13 @@ class Connection(api.Connection):
|
||||
query, models.ihost, [forihostid])
|
||||
return query.all()
|
||||
|
||||
def _iinterface_get(self, iinterface_id, ihost=None, network=None):
|
||||
def _iinterface_get(self, iinterface_id, ihost=None):
|
||||
entity = with_polymorphic(models.Interfaces, '*')
|
||||
query = model_query(entity)
|
||||
query = add_interface_filter(query, iinterface_id)
|
||||
if ihost is not None:
|
||||
query = add_interface_filter_by_ihost(query, ihost)
|
||||
if network is not None:
|
||||
query = query.filter_by(networktype=network)
|
||||
|
||||
try:
|
||||
result = query.one()
|
||||
except NoResultFound:
|
||||
@ -2106,7 +2105,7 @@ class Connection(api.Connection):
|
||||
|
||||
@objects.objectify(objects.interface)
|
||||
def iinterface_get(self, iinterface_id, ihost=None, network=None):
|
||||
return self._iinterface_get(iinterface_id, ihost, network)
|
||||
return self._iinterface_get(iinterface_id, ihost)
|
||||
|
||||
@objects.objectify(objects.interface)
|
||||
def iinterface_get_list(self, limit=None, marker=None,
|
||||
@ -2155,16 +2154,6 @@ class Connection(api.Connection):
|
||||
return _paginate_query(models.Interfaces, limit, marker,
|
||||
sort_key, sort_dir, query)
|
||||
|
||||
@objects.objectify(objects.interface)
|
||||
def iinterface_get_by_network(self, network,
|
||||
limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None):
|
||||
entity = with_polymorphic(models.Interfaces, '*')
|
||||
query = model_query(entity)
|
||||
query = query.filter_by(networktype=network)
|
||||
return _paginate_query(models.Interfaces, limit, marker,
|
||||
sort_key, sort_dir, query)
|
||||
|
||||
@objects.objectify(objects.interface)
|
||||
def iinterface_update(self, iinterface_id, values):
|
||||
with _session_for_write() as session:
|
||||
@ -2237,13 +2226,6 @@ class Connection(api.Connection):
|
||||
if obj.id is None:
|
||||
obj.id = temp_id
|
||||
|
||||
# Ensure networktype results are None when they
|
||||
# are specified as 'none'. Otherwise the 'none' value is written to
|
||||
# the database which causes issues with checks that expects it to be
|
||||
# the None type
|
||||
if getattr(obj, 'networktype', None) == constants.NETWORK_TYPE_NONE:
|
||||
setattr(obj, 'networktype', None)
|
||||
|
||||
try:
|
||||
session.add(obj)
|
||||
session.flush()
|
||||
@ -2318,8 +2300,6 @@ class Connection(api.Connection):
|
||||
obj = self._interface_get(models.Interfaces, interface_id)
|
||||
|
||||
for k, v in list(values.items()):
|
||||
if k == 'networktype' and v == constants.NETWORK_TYPE_NONE:
|
||||
v = None
|
||||
if k == 'datanetworks' and v == 'none':
|
||||
v = None
|
||||
if k == 'uses':
|
||||
@ -4952,6 +4932,26 @@ class Connection(api.Connection):
|
||||
limit, marker,
|
||||
sort_key, sort_dir)
|
||||
|
||||
@objects.objectify(objects.address)
|
||||
def addresses_get_by_interface_pool(self, interface_uuid, pool_uuid,
|
||||
limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None):
|
||||
interface_id = self.iinterface_get(interface_uuid).id
|
||||
pool_id = self.address_pool_get(pool_uuid).id
|
||||
query = model_query(models.Addresses)
|
||||
query = (query.
|
||||
join(models.AddressPools,
|
||||
models.AddressPools.id == pool_id).
|
||||
join(models.Interfaces,
|
||||
models.Interfaces.id == interface_id).
|
||||
filter(models.Addresses.interface_id == interface_id).
|
||||
filter(models.Addresses.address_pool_id == pool_id))
|
||||
try:
|
||||
result = query.one()
|
||||
except NoResultFound:
|
||||
raise exception.AddressNotFoundByInterfacePool(interface=interface_uuid, pool=pool_uuid)
|
||||
return result
|
||||
|
||||
def address_destroy(self, address_uuid):
|
||||
query = model_query(models.Addresses)
|
||||
query = add_identity_filter(query, address_uuid)
|
||||
|
@ -0,0 +1,26 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# Copyright (c) 2019 Wind River Systems, Inc.
|
||||
#
|
||||
# The right to copy, distribute, modify, or otherwise make use
|
||||
# of this software may be licensed only pursuant to the terms
|
||||
# of an applicable Wind River license agreement.
|
||||
#
|
||||
|
||||
from sqlalchemy import MetaData, Table
|
||||
|
||||
ENGINE = 'InnoDB'
|
||||
CHARSET = 'utf8'
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
interface = Table('interfaces', meta, autoload=True)
|
||||
interface.drop_column('networktype')
|
||||
return True
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
raise NotImplementedError('SysInv database downgrade is unsupported.')
|
@ -339,7 +339,6 @@ class Interfaces(Base):
|
||||
|
||||
ifname = Column(String(255))
|
||||
ifclass = Column(String(255))
|
||||
networktype = Column(String(255))
|
||||
ifcapabilities = Column(JSONEncodedDict)
|
||||
farend = Column(JSONEncodedDict)
|
||||
sriov_numvfs = Column(Integer)
|
||||
|
@ -355,12 +355,10 @@ class NeutronHelm(openstack.OpenstackBaseHelm):
|
||||
return ml2_config
|
||||
|
||||
def _is_data_network_type(self, iface):
|
||||
networktypelist = utils.get_network_type_list(iface)
|
||||
return bool(any(n in DATA_NETWORK_TYPES for n in networktypelist))
|
||||
return iface.ifclass == constants.INTERFACE_CLASS_DATA
|
||||
|
||||
def _is_sriov_network_type(self, iface):
|
||||
networktypelist = utils.get_network_type_list(iface)
|
||||
return bool(any(n in SRIOV_NETWORK_TYPES for n in networktypelist))
|
||||
return iface.ifclass == constants.INTERFACE_CLASS_PCI_SRIOV
|
||||
|
||||
def _get_interface_datanets(self, iface):
|
||||
"""
|
||||
|
@ -24,7 +24,6 @@ class Address(base.SysinvObject):
|
||||
'forihostid': utils.int_or_none,
|
||||
'interface_uuid': utils.uuid_or_none,
|
||||
'pool_uuid': utils.uuid_or_none,
|
||||
'networktype': utils.str_or_none,
|
||||
'ifname': utils.str_or_none,
|
||||
'family': utils.int_or_none,
|
||||
'address': utils.ip_str_or_none(),
|
||||
@ -36,8 +35,7 @@ class Address(base.SysinvObject):
|
||||
_foreign_fields = {'interface_uuid': 'interface:uuid',
|
||||
'pool_uuid': 'address_pool:uuid',
|
||||
'ifname': 'interface:ifname',
|
||||
'forihostid': 'interface:forihostid',
|
||||
'networktype': 'interface:networktype'}
|
||||
'forihostid': 'interface:forihostid'}
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_uuid(cls, context, uuid):
|
||||
|
@ -78,12 +78,12 @@ def get_host_uuid(field, db_server):
|
||||
return host_uuid
|
||||
|
||||
|
||||
def get_networks(field, db_object):
|
||||
def get_networktypes(field, db_object):
|
||||
result = []
|
||||
try:
|
||||
if getattr(db_object, 'interface_networks', None):
|
||||
for entry in getattr(db_object, 'interface_networks', []):
|
||||
id_str = str(entry.network_id)
|
||||
id_str = str(entry.network.type)
|
||||
result.append(id_str)
|
||||
except exc.DetachedInstanceError:
|
||||
# instrument and return empty network
|
||||
@ -126,11 +126,10 @@ class Interface(base.SysinvObject):
|
||||
'ifclass': utils.str_or_none,
|
||||
'imac': utils.str_or_none,
|
||||
'imtu': utils.int_or_none,
|
||||
'networktype': utils.str_or_none,
|
||||
'aemode': utils.str_or_none,
|
||||
'schedpolicy': utils.str_or_none,
|
||||
'txhashpolicy': utils.str_or_none,
|
||||
'networks': utils.list_of_strings_or_none,
|
||||
'networktypelist': utils.list_of_strings_or_none,
|
||||
'datanetworks': utils.list_of_strings_or_none,
|
||||
|
||||
'ifcapabilities': utils.dict_or_none,
|
||||
@ -156,7 +155,7 @@ class Interface(base.SysinvObject):
|
||||
'ipv4_pool': get_ipv4_address_pool,
|
||||
'ipv6_pool': get_ipv6_address_pool,
|
||||
'ihost_uuid': get_host_uuid,
|
||||
'networks': get_networks,
|
||||
'networktypelist': get_networktypes,
|
||||
'datanetworks': get_datanetworks}
|
||||
|
||||
_optional_fields = ['aemode', 'txhashpolicy', 'schedpolicy',
|
||||
|
@ -24,7 +24,6 @@ class Route(base.SysinvObject):
|
||||
'forihostid': utils.int_or_none,
|
||||
'interface_uuid': utils.uuid_or_none,
|
||||
'interface_id': int,
|
||||
'networktype': utils.str_or_none,
|
||||
'ifname': utils.str_or_none,
|
||||
'family': utils.str_or_none,
|
||||
'network': utils.ip_str_or_none(),
|
||||
@ -36,8 +35,7 @@ class Route(base.SysinvObject):
|
||||
_foreign_fields = {'interface_uuid': 'interface:uuid',
|
||||
'interface_id': 'interface:id',
|
||||
'ifname': 'interface:ifname',
|
||||
'forihostid': 'interface:forihostid',
|
||||
'networktype': 'interface:networktype'}
|
||||
'forihostid': 'interface:forihostid'}
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_uuid(cls, context, uuid):
|
||||
|
@ -99,8 +99,7 @@ def list_of_strings_or_none(val):
|
||||
if not isinstance(val, list):
|
||||
raise ValueError(_('A list of strings is required here'))
|
||||
if not all([isinstance(x, six.string_types) for x in val]):
|
||||
raise ValueError(_('Invalid values found in list '
|
||||
'(strings are required)'))
|
||||
raise ValueError(_('Invalid values %s found in list (strings are required)') % val)
|
||||
return val
|
||||
|
||||
|
||||
|
@ -934,7 +934,7 @@ def get_common_network_config(context, iface, config, network_id=None):
|
||||
layer interface (i.e., an interface that is used to terminate IP traffic).
|
||||
"""
|
||||
LOG.debug("get_common_network_config %s %s network_id=%s" %
|
||||
(iface.ifname, iface.networks, network_id))
|
||||
(iface.ifname, iface.networktypelist, network_id))
|
||||
traffic_classifier = get_interface_traffic_classifier(context, iface,
|
||||
network_id)
|
||||
if traffic_classifier:
|
||||
@ -967,7 +967,7 @@ def get_interface_network_config(context, iface, network_id=None):
|
||||
|
||||
# setup an alias interface if there are multiple addresses assigned
|
||||
# NOTE: DHCP will only operate over a non-alias interface
|
||||
if len(iface.networks) > 1 and network_id and method != DHCP_METHOD:
|
||||
if len(iface.networktypelist) > 1 and network_id and method != DHCP_METHOD:
|
||||
ifname = "%s:%d" % (os_ifname, network_id)
|
||||
else:
|
||||
ifname = os_ifname
|
||||
@ -1012,8 +1012,9 @@ def generate_network_config(context, config, iface):
|
||||
net_config['ifname']: format_network_config(net_config)
|
||||
})
|
||||
|
||||
for net_id in iface.networks:
|
||||
net_config = get_interface_network_config(context, iface, int(net_id))
|
||||
for net_type in iface.networktypelist:
|
||||
net_id = find_network_id_by_networktype(context, net_type)
|
||||
net_config = get_interface_network_config(context, iface, net_id)
|
||||
config[NETWORK_CONFIG_RESOURCE].update({
|
||||
net_config['ifname']: format_network_config(net_config)
|
||||
})
|
||||
@ -1060,8 +1061,7 @@ def find_interface_by_type(context, networktype):
|
||||
mgmt, cluster-host, pxeboot, bmc).
|
||||
"""
|
||||
for ifname, iface in six.iteritems(context['interfaces']):
|
||||
for net_id in iface.networks:
|
||||
net_type = find_networktype_by_network_id(context, int(net_id))
|
||||
for net_type in iface.networktypelist:
|
||||
if networktype == net_type:
|
||||
return iface
|
||||
|
||||
|
@ -723,16 +723,12 @@ class PlatformPuppet(base.BasePuppet):
|
||||
# Calculate the optimal NFS r/w size based on the network mtu based
|
||||
# on the configured network(s)
|
||||
mtu = constants.DEFAULT_MTU
|
||||
mgmt_network = self.dbapi.network_get_by_type(
|
||||
constants.NETWORK_TYPE_MGMT)
|
||||
network_id = mgmt_network.id
|
||||
interfaces = self.dbapi.iinterface_get_by_ihost(host.uuid)
|
||||
for interface in interfaces:
|
||||
if interface['ifclass'] == constants.INTERFACE_CLASS_PLATFORM:
|
||||
for net_id in interface['networks']:
|
||||
if int(net_id) == network_id:
|
||||
mtu = interface.imtu
|
||||
break
|
||||
if constants.NETWORK_TYPE_MGMT in interface['networktypelist']:
|
||||
mtu = interface.imtu
|
||||
break
|
||||
|
||||
if self._get_address_by_name(
|
||||
constants.CONTROLLER_PLATFORM_NFS,
|
||||
|
@ -148,6 +148,7 @@ class InterfaceTestCase(base.FunctionalTest):
|
||||
def setUp(self):
|
||||
super(InterfaceTestCase, self).setUp()
|
||||
self.dbapi = db_api.get_instance()
|
||||
|
||||
p = mock.patch.object(api_if_v1, '_get_lower_interface_macs')
|
||||
self.mock_lower_macs = p.start()
|
||||
self.mock_lower_macs.return_value = {'enp0s18': '08:00:27:8a:87:48',
|
||||
@ -281,29 +282,13 @@ class InterfaceTestCase(base.FunctionalTest):
|
||||
|
||||
def _create_ethernet(self, ifname=None, networktype=None, ifclass=None,
|
||||
datanetworks=None, host=None, expect_errors=False):
|
||||
if not isinstance(networktype, list):
|
||||
networktypelist = [networktype]
|
||||
else:
|
||||
networktypelist = networktype
|
||||
networktype = ','.join(networktype)
|
||||
interface_id = len(self.profile['interfaces']) + 1
|
||||
networks = []
|
||||
if not ifname:
|
||||
ifname = (networktype or 'eth') + str(interface_id)
|
||||
if not host:
|
||||
host = self.controller
|
||||
if all(network_type in constants.PLATFORM_NETWORK_TYPES
|
||||
for network_type in networktypelist):
|
||||
if not ifclass and networktype in constants.PLATFORM_NETWORK_TYPES:
|
||||
ifclass = constants.INTERFACE_CLASS_PLATFORM
|
||||
for network_type in networktypelist:
|
||||
network = self.dbapi.network_get_by_type(network_type)
|
||||
networks.append(str(network.id))
|
||||
elif ifclass == constants.INTERFACE_CLASS_PLATFORM and \
|
||||
any(network_type not in constants.PLATFORM_NETWORK_TYPES
|
||||
for network_type in networktypelist):
|
||||
ifclass = networktype
|
||||
if not ifclass and networktype:
|
||||
ifclass = networktype
|
||||
port_id = len(self.profile['ports'])
|
||||
port = dbutils.create_test_ethernet_port(
|
||||
id=port_id,
|
||||
@ -317,22 +302,23 @@ class InterfaceTestCase(base.FunctionalTest):
|
||||
if not networktype:
|
||||
interface = dbutils.create_test_interface(ifname=ifname,
|
||||
forihostid=host.id,
|
||||
ihost_uuid=host.uuid,
|
||||
networks=networks)
|
||||
ihost_uuid=host.uuid)
|
||||
interface_uuid = interface.uuid
|
||||
else:
|
||||
interface = dbutils.post_get_test_interface(
|
||||
ifname=ifname,
|
||||
ifclass=ifclass,
|
||||
networktype=networktype,
|
||||
networks=networks,
|
||||
datanetworks=datanetworks,
|
||||
forihostid=host.id, ihost_uuid=host.uuid)
|
||||
|
||||
response = self._post_and_check(interface, expect_errors)
|
||||
if expect_errors is False:
|
||||
interface_uuid = response.json['uuid']
|
||||
interface['uuid'] = interface_uuid
|
||||
if ifclass == constants.INTERFACE_CLASS_PLATFORM and networktype:
|
||||
network = self.dbapi.network_get_by_type(networktype)
|
||||
dbutils.create_test_interface_network(
|
||||
interface_id=interface_uuid,
|
||||
network_id=network.id)
|
||||
|
||||
self.profile['interfaces'].append(interface)
|
||||
self.profile['ports'].append(port)
|
||||
@ -341,11 +327,6 @@ class InterfaceTestCase(base.FunctionalTest):
|
||||
|
||||
def _create_bond(self, ifname, networktype=None, ifclass=None,
|
||||
datanetworks=None, host=None, expect_errors=False):
|
||||
if not isinstance(networktype, list):
|
||||
networktypelist = [networktype]
|
||||
else:
|
||||
networktypelist = networktype
|
||||
networktype = ','.join(networktype)
|
||||
if not host:
|
||||
host = self.controller
|
||||
port1, iface1 = self._create_ethernet(host=host)
|
||||
@ -353,26 +334,13 @@ class InterfaceTestCase(base.FunctionalTest):
|
||||
interface_id = len(self.profile['interfaces'])
|
||||
if not ifname:
|
||||
ifname = (networktype or 'eth') + str(interface_id)
|
||||
networks = []
|
||||
if all(network_type in constants.PLATFORM_NETWORK_TYPES
|
||||
for network_type in networktypelist):
|
||||
if not ifclass and networktype in constants.PLATFORM_NETWORK_TYPES:
|
||||
ifclass = constants.INTERFACE_CLASS_PLATFORM
|
||||
for network_type in networktypelist:
|
||||
network = self.dbapi.network_get_by_type(network_type)
|
||||
networks.append(str(network.id))
|
||||
elif ifclass == constants.INTERFACE_CLASS_PLATFORM and \
|
||||
any(network_type not in constants.PLATFORM_NETWORK_TYPES
|
||||
for network_type in networktypelist):
|
||||
ifclass = networktype
|
||||
if not ifclass and networktype:
|
||||
ifclass = networktype
|
||||
interface = dbutils.post_get_test_interface(
|
||||
id=interface_id,
|
||||
ifname=ifname,
|
||||
iftype=constants.INTERFACE_TYPE_AE,
|
||||
ifclass=ifclass,
|
||||
networktype=networktype,
|
||||
networks=networks,
|
||||
uses=[iface1['ifname'], iface2['ifname']],
|
||||
txhashpolicy='layer2',
|
||||
datanetworks=datanetworks,
|
||||
@ -403,42 +371,30 @@ class InterfaceTestCase(base.FunctionalTest):
|
||||
def _create_vlan(self, ifname, networktype, ifclass, vlan_id,
|
||||
lower_iface=None, datanetworks=None, host=None,
|
||||
expect_errors=False):
|
||||
if not isinstance(networktype, list):
|
||||
networktypelist = [networktype]
|
||||
else:
|
||||
networktypelist = networktype
|
||||
networktype = ','.join(networktype)
|
||||
if not host:
|
||||
host = self.controller
|
||||
if not lower_iface:
|
||||
lower_port, lower_iface = self._create_ethernet(host=host)
|
||||
if not ifname:
|
||||
ifname = 'vlan' + str(vlan_id)
|
||||
networks = []
|
||||
if all(network_type in constants.PLATFORM_NETWORK_TYPES
|
||||
for network_type in networktypelist):
|
||||
if not ifclass and networktype in constants.PLATFORM_NETWORK_TYPES:
|
||||
ifclass = constants.INTERFACE_CLASS_PLATFORM
|
||||
for network_type in networktypelist:
|
||||
network = self.dbapi.network_get_by_type(network_type)
|
||||
networks.append(str(network.id))
|
||||
elif ifclass == constants.INTERFACE_CLASS_PLATFORM and \
|
||||
any(network_type not in constants.PLATFORM_NETWORK_TYPES
|
||||
for network_type in networktypelist):
|
||||
ifclass = networktype
|
||||
if not ifclass and networktype:
|
||||
ifclass = networktype
|
||||
interface = dbutils.post_get_test_interface(
|
||||
ifname=ifname,
|
||||
iftype=constants.INTERFACE_TYPE_VLAN,
|
||||
ifclass=ifclass,
|
||||
networktype=networktype,
|
||||
networks=networks,
|
||||
vlan_id=vlan_id,
|
||||
uses=[lower_iface['ifname']],
|
||||
datanetworks=datanetworks,
|
||||
forihostid=host.id, ihost_uuid=host.uuid)
|
||||
|
||||
self._post_and_check(interface, expect_errors)
|
||||
response = self._post_and_check(interface, expect_errors)
|
||||
if expect_errors is False:
|
||||
if ifclass == constants.INTERFACE_CLASS_PLATFORM and networktype:
|
||||
interface['uuid'] = response.json['uuid']
|
||||
network = self.dbapi.network_get_by_type(networktype)
|
||||
dbutils.create_test_interface_network(
|
||||
interface_id=interface['uuid'],
|
||||
network_id=network.id)
|
||||
self.profile['interfaces'].append(interface)
|
||||
return interface
|
||||
|
||||
@ -1131,7 +1087,6 @@ class TestPatch(InterfaceTestCase):
|
||||
sriov_vf_driver='i40evf')
|
||||
response = self.patch_dict_json(
|
||||
'%s' % self._get_path(interface['uuid']),
|
||||
networktype=constants.NETWORK_TYPE_PCI_SRIOV,
|
||||
ifclass=constants.INTERFACE_CLASS_PCI_SRIOV,
|
||||
sriov_numvfs=1,
|
||||
sriov_vf_driver=vf_driver,
|
||||
@ -1174,12 +1129,6 @@ class TestPost(InterfaceTestCase):
|
||||
self._create_host(constants.WORKER, admin=constants.ADMIN_LOCKED)
|
||||
self._create_datanetworks()
|
||||
|
||||
# Expected error: The oam network type is only supported on controller nodes
|
||||
def test_invalid_oam_on_worker(self):
|
||||
self._create_ethernet('oam', constants.NETWORK_TYPE_OAM,
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
host=self.worker, expect_errors=True)
|
||||
|
||||
# Expected error: The pci-passthrough, pci-sriov network types are only
|
||||
# valid on Ethernet interfaces
|
||||
def test_invalid_iftype_for_pci_network_type(self):
|
||||
@ -1237,8 +1186,6 @@ class TestPost(InterfaceTestCase):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.controller.uuid,
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_MGMT,
|
||||
networks=['1'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_ETHERNET,
|
||||
ipv4_mode=constants.IPV4_POOL,
|
||||
@ -1251,7 +1198,6 @@ class TestPost(InterfaceTestCase):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.worker.uuid,
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_PCI_PASSTHROUGH,
|
||||
ifclass=constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
|
||||
iftype=constants.INTERFACE_TYPE_ETHERNET,
|
||||
ipv4_mode=constants.IPV4_STATIC,
|
||||
@ -1266,8 +1212,6 @@ class TestPost(InterfaceTestCase):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.controller.uuid,
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
networks=['2'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_ETHERNET,
|
||||
ipv4_mode=constants.IPV4_DISABLED,
|
||||
@ -1281,8 +1225,6 @@ class TestPost(InterfaceTestCase):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.controller.uuid,
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_MGMT,
|
||||
networks=['1'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_ETHERNET,
|
||||
ipv4_mode=constants.IPV4_DISABLED,
|
||||
@ -1296,7 +1238,6 @@ class TestPost(InterfaceTestCase):
|
||||
ihost_uuid=self.controller.uuid,
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_MGMT,
|
||||
networks=['1'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_ETHERNET,
|
||||
ipv6_mode=constants.IPV6_DISABLED,
|
||||
@ -1308,8 +1249,6 @@ class TestPost(InterfaceTestCase):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.worker.uuid,
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_MGMT,
|
||||
networks=['1'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_ETHERNET,
|
||||
ipv4_mode=constants.IPV4_POOL,
|
||||
@ -1321,8 +1260,6 @@ class TestPost(InterfaceTestCase):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.worker.uuid,
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_MGMT,
|
||||
networks=['1'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_ETHERNET,
|
||||
ipv4_mode=constants.IPV4_POOL,
|
||||
@ -1335,8 +1272,6 @@ class TestPost(InterfaceTestCase):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.worker.uuid,
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_MGMT,
|
||||
networks=['1'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_ETHERNET,
|
||||
ipv4_mode=constants.IPV4_POOL,
|
||||
@ -1350,8 +1285,6 @@ class TestPost(InterfaceTestCase):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.worker.uuid,
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_MGMT,
|
||||
networks=['1'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_ETHERNET,
|
||||
ipv4_mode=constants.IPV4_POOL,
|
||||
@ -1367,7 +1300,6 @@ class TestPost(InterfaceTestCase):
|
||||
ihost_uuid=self.worker.uuid,
|
||||
datanetworks='group0-data0',
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_DATA,
|
||||
ifclass=constants.INTERFACE_CLASS_DATA,
|
||||
iftype='AE',
|
||||
aemode='active_standby',
|
||||
@ -1381,7 +1313,6 @@ class TestPost(InterfaceTestCase):
|
||||
ihost_uuid=self.worker.uuid,
|
||||
datanetworks='group0-data0',
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_DATA,
|
||||
ifclass=constants.INTERFACE_CLASS_DATA,
|
||||
iftype=constants.INTERFACE_TYPE_AE,
|
||||
aemode='active_standby',
|
||||
@ -1394,7 +1325,6 @@ class TestPost(InterfaceTestCase):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.worker.uuid,
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_DATA,
|
||||
ifclass=constants.INTERFACE_CLASS_DATA,
|
||||
iftype=constants.INTERFACE_TYPE_AE,
|
||||
aemode='balanced',
|
||||
@ -1408,7 +1338,6 @@ class TestPost(InterfaceTestCase):
|
||||
ihost_uuid=self.worker.uuid,
|
||||
datanetworks='group0-data0',
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_DATA,
|
||||
ifclass=constants.INTERFACE_CLASS_DATA,
|
||||
iftype=constants.INTERFACE_TYPE_AE,
|
||||
aemode='802.3ad',
|
||||
@ -1419,28 +1348,12 @@ class TestPost(InterfaceTestCase):
|
||||
ihost_uuid=self.worker.uuid,
|
||||
datanetworks='group0-data0',
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_DATA,
|
||||
ifclass=constants.INTERFACE_CLASS_DATA,
|
||||
iftype=constants.INTERFACE_TYPE_AE,
|
||||
aemode='balanced',
|
||||
txhashpolicy=None)
|
||||
self._post_and_check_failure(ndict)
|
||||
|
||||
# Expected error: Device interface with network type ___, and interface type
|
||||
# 'aggregated ethernet' must be in mode '802.3ad'
|
||||
def test_aemode_invalid_mgmt(self):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.worker.uuid,
|
||||
datanetworks='group0-data0',
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_MGMT,
|
||||
networks=['1'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_AE,
|
||||
aemode='balanced',
|
||||
txhashpolicy='layer2')
|
||||
self._post_and_check_failure(ndict)
|
||||
|
||||
# Device interface with network type ___, and interface type
|
||||
# 'aggregated ethernet' must be in mode 'active_standby' or 'balanced' or
|
||||
# '802.3ad'.
|
||||
@ -1449,57 +1362,26 @@ class TestPost(InterfaceTestCase):
|
||||
ihost_uuid=self.worker.uuid,
|
||||
datanetworks='group0-data0',
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_DATA,
|
||||
ifclass=constants.INTERFACE_CLASS_DATA,
|
||||
iftype=constants.INTERFACE_TYPE_AE,
|
||||
aemode='bad_aemode',
|
||||
txhashpolicy='layer2')
|
||||
self._post_and_check_failure(ndict)
|
||||
|
||||
def test_aemode_invalid_oam(self):
|
||||
def test_aemode_invalid_platform(self):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.controller.uuid,
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_OAM,
|
||||
networks=['3'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_AE,
|
||||
aemode='bad_aemode',
|
||||
txhashpolicy='layer2')
|
||||
self._post_and_check_failure(ndict)
|
||||
|
||||
def test_aemode_invalid_cluster_host(self):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.worker.uuid,
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
networks=['2'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_AE,
|
||||
aemode='bad_aemode',
|
||||
txhashpolicy='layer2')
|
||||
self._post_and_check_failure(ndict)
|
||||
|
||||
# Expected error: Interface ___ does not have associated cluster-host
|
||||
# interface on controller.
|
||||
def test_no_cluster_host_on_controller(self):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.worker.uuid,
|
||||
ifname='name',
|
||||
networktype=constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
networks=['2'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_ETHERNET,
|
||||
aemode='balanced',
|
||||
txhashpolicy='layer2')
|
||||
self._post_and_check_failure(ndict)
|
||||
|
||||
def test_setting_mgmt_mtu_allowed(self):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.controller.uuid,
|
||||
ifname='mgmt0',
|
||||
networktype=constants.NETWORK_TYPE_MGMT,
|
||||
networks=['1'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_ETHERNET,
|
||||
imtu=1600)
|
||||
@ -1509,8 +1391,6 @@ class TestPost(InterfaceTestCase):
|
||||
ndict = dbutils.post_get_test_interface(
|
||||
ihost_uuid=self.controller.uuid,
|
||||
ifname='cluster0',
|
||||
networktype=constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
networks=['2'],
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_ETHERNET,
|
||||
imtu=1600)
|
||||
@ -1529,7 +1409,6 @@ class TestPost(InterfaceTestCase):
|
||||
ihost_uuid=self.worker.uuid,
|
||||
datanetworks='group0-ext1',
|
||||
ifname='bond1',
|
||||
networktype=constants.NETWORK_TYPE_DATA,
|
||||
ifclass=constants.INTERFACE_CLASS_DATA,
|
||||
iftype=constants.INTERFACE_TYPE_AE,
|
||||
aemode='balanced',
|
||||
@ -1559,7 +1438,6 @@ class TestPost(InterfaceTestCase):
|
||||
ihost_uuid=self.worker.uuid,
|
||||
datanetworks='group0-ext1',
|
||||
ifname='bond0',
|
||||
networktype=constants.NETWORK_TYPE_DATA,
|
||||
ifclass=constants.INTERFACE_CLASS_DATA,
|
||||
iftype=constants.INTERFACE_TYPE_AE,
|
||||
aemode='balanced',
|
||||
@ -1579,7 +1457,6 @@ class TestPost(InterfaceTestCase):
|
||||
ihost_uuid=self.worker.uuid,
|
||||
datanetworks='group0-ext1',
|
||||
ifname='bond1',
|
||||
networktype=constants.NETWORK_TYPE_DATA,
|
||||
ifclass=constants.INTERFACE_CLASS_DATA,
|
||||
iftype=constants.INTERFACE_TYPE_VLAN,
|
||||
aemode='balanced',
|
||||
@ -1658,7 +1535,9 @@ class TestPost(InterfaceTestCase):
|
||||
def test_create_invalid_oam_data_ethernet(self):
|
||||
self._create_ethernet('shared',
|
||||
networktype=constants.NETWORK_TYPE_DATA,
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
ifclass=constants.INTERFACE_CLASS_DATA,
|
||||
datanetworks='group0-data0',
|
||||
host=self.controller,
|
||||
expect_errors=True)
|
||||
|
||||
# Expected message:
|
||||
@ -1715,13 +1594,6 @@ class TestCpePost(InterfaceTestCase):
|
||||
lower_iface=iface, datanetworks='group0-ext1',
|
||||
expect_errors=True)
|
||||
|
||||
# Expected message: An interface with \'oam\' network type is already
|
||||
# provisioned on this node
|
||||
def test_create_invalid_duplicate_networktype(self):
|
||||
self._create_ethernet('oam', constants.NETWORK_TYPE_OAM)
|
||||
self._create_ethernet('bad', constants.NETWORK_TYPE_OAM,
|
||||
expect_errors=True)
|
||||
|
||||
# Expected message: VLAN id ___ already in use on interface ___
|
||||
def test_create_vlan_id_already_in_use(self):
|
||||
port, iface = self._create_ethernet('eth1', constants.NETWORK_TYPE_NONE)
|
||||
@ -1733,13 +1605,6 @@ class TestCpePost(InterfaceTestCase):
|
||||
lower_iface=iface, datanetworks='group0-ext1',
|
||||
expect_errors=True)
|
||||
|
||||
# Expected message: VLAN interfaces cannot have an interface class of none
|
||||
def test_create_invalid_vlan_networktype_none(self):
|
||||
port, lower = self._create_ethernet('eth1', constants.NETWORK_TYPE_NONE)
|
||||
self._create_vlan('vlan2', networktype='none',
|
||||
ifclass=constants.INTERFACE_CLASS_NONE,
|
||||
vlan_id=2, lower_iface=lower, expect_errors=True)
|
||||
|
||||
# Expected error: VLAN based provider network group0-data0 cannot be
|
||||
# assigned to a VLAN interface
|
||||
def test_create_invalid_vlan_with_vlan_data_network(self):
|
||||
@ -1775,12 +1640,6 @@ class TestCpePost(InterfaceTestCase):
|
||||
mock.ANY, mock.ANY, vlans=mock.ANY, test=mock.ANY)
|
||||
mock_iinterface_destroy.assert_called_once_with(mock.ANY)
|
||||
|
||||
# Expected error: At least one provider network must be selected.
|
||||
def test_create_invalid_no_data_network(self):
|
||||
self._create_ethernet('data',
|
||||
networktype=constants.NETWORK_TYPE_DATA,
|
||||
expect_errors=True)
|
||||
|
||||
# Expected error: Data interface data0 is already attached to this
|
||||
# Data Network: group0-data0.
|
||||
def test_create_invalid_data_network_used(self):
|
||||
@ -1819,13 +1678,6 @@ class TestCpePatch(InterfaceTestCase):
|
||||
admin=constants.ADMIN_LOCKED)
|
||||
self._create_datanetworks()
|
||||
|
||||
def test_create_invalid_cluster_host_data_ethernet(self):
|
||||
self._create_ethernet('shared',
|
||||
networktype=[constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
constants.NETWORK_TYPE_DATA],
|
||||
datanetworks='group0-data0',
|
||||
expect_errors=True)
|
||||
|
||||
@testtools.skip("deprecate neutron bind interface")
|
||||
@mock.patch.object(rpcapi.ConductorAPI, 'neutron_bind_interface')
|
||||
def test_patch_neutron_bind_failed(self, mock_neutron_bind_interface):
|
||||
@ -1853,23 +1705,11 @@ class TestCpePatch(InterfaceTestCase):
|
||||
constants.NETWORK_TYPE_NONE)
|
||||
response = self.patch_dict_json(
|
||||
'%s' % self._get_path(interface['uuid']),
|
||||
networktype=constants.NETWORK_TYPE_PCI_SRIOV,
|
||||
ifclass=constants.INTERFACE_CLASS_PCI_SRIOV,
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Expected error: At most one port must be enabled.
|
||||
def test_invalid_sriov_no_port(self):
|
||||
interface = dbutils.create_test_interface(forihostid='1')
|
||||
response = self.patch_dict_json(
|
||||
'%s' % self._get_path(interface['uuid']), sriov_numvfs=1,
|
||||
networktype=constants.NETWORK_TYPE_PCI_SRIOV,
|
||||
ifclass=constants.INTERFACE_CLASS_DATA,
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Expected error: SR-IOV can't be configured on this interface
|
||||
def test_invalid_sriov_totalvfs_zero(self):
|
||||
interface = dbutils.create_test_interface(forihostid='1')
|
||||
@ -1878,7 +1718,6 @@ class TestCpePatch(InterfaceTestCase):
|
||||
pciaddr='0000:00:00.11', dev_id=0, sriov_totalvfs=0, sriov_numvfs=1)
|
||||
response = self.patch_dict_json(
|
||||
'%s' % self._get_path(interface['uuid']),
|
||||
networktype=constants.NETWORK_TYPE_PCI_SRIOV,
|
||||
ifclass=constants.INTERFACE_CLASS_PCI_SRIOV,
|
||||
sriov_numvfs=1,
|
||||
expect_errors=True)
|
||||
|
@ -7,8 +7,10 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
import mock
|
||||
from six.moves import http_client
|
||||
|
||||
from sysinv.api.controllers.v1 import interface as api_if_v1
|
||||
from sysinv.common import constants
|
||||
from sysinv.tests.api import base
|
||||
from sysinv.tests.db import utils as dbutils
|
||||
@ -17,6 +19,13 @@ from sysinv.tests.db import utils as dbutils
|
||||
class InterfaceNetworkTestCase(base.FunctionalTest):
|
||||
def setUp(self):
|
||||
super(InterfaceNetworkTestCase, self).setUp()
|
||||
|
||||
p = mock.patch.object(api_if_v1, '_get_lower_interface_macs')
|
||||
self.mock_lower_macs = p.start()
|
||||
self.mock_lower_macs.return_value = {'enp0s18': '08:00:27:8a:87:48',
|
||||
'enp0s19': '08:00:27:ea:93:8e'}
|
||||
self.addCleanup(p.stop)
|
||||
|
||||
self.system = dbutils.create_test_isystem()
|
||||
self.load = dbutils.create_test_load()
|
||||
self.controller = dbutils.create_test_ihost(
|
||||
@ -76,6 +85,12 @@ class InterfaceNetworkTestCase(base.FunctionalTest):
|
||||
name='oam',
|
||||
type=constants.NETWORK_TYPE_OAM,
|
||||
address_pool_id=self.address_pool_oam.id)
|
||||
self.oam_address = dbutils.create_test_address(
|
||||
family=2,
|
||||
address='10.10.10.3',
|
||||
prefix=24,
|
||||
name='controller-0-oam',
|
||||
address_pool_id=self.address_pool_oam.id)
|
||||
self.address_pool_pxeboot = dbutils.create_test_address_pool(
|
||||
id=4,
|
||||
network='192.168.202.0',
|
||||
@ -86,6 +101,12 @@ class InterfaceNetworkTestCase(base.FunctionalTest):
|
||||
id=4,
|
||||
type=constants.NETWORK_TYPE_PXEBOOT,
|
||||
address_pool_id=self.address_pool_pxeboot.id)
|
||||
self.pxeboot_address = dbutils.create_test_address(
|
||||
family=2,
|
||||
address='192.168.202.3',
|
||||
prefix=24,
|
||||
name='controller-0-pxeboot',
|
||||
address_pool_id=self.address_pool_pxeboot.id)
|
||||
|
||||
def _post_and_check(self, ndict, expect_errors=False):
|
||||
response = self.post_json('%s' % self._get_path(), ndict,
|
||||
@ -162,7 +183,7 @@ class InterfaceNetworkCreateTestCase(InterfaceNetworkTestCase):
|
||||
worker_interface_network = dbutils.post_get_test_interface_network(
|
||||
interface_uuid=worker_interface.uuid,
|
||||
network_uuid=self.oam_network.uuid)
|
||||
self._post_and_check(worker_interface_network, expect_errors=False)
|
||||
self._post_and_check(worker_interface_network, expect_errors=True)
|
||||
|
||||
def test_create_pxeboot_interface_network(self):
|
||||
controller_interface = dbutils.create_test_interface(
|
||||
@ -290,3 +311,68 @@ class InterfaceNetworkCreateTestCase(InterfaceNetworkTestCase):
|
||||
interface_uuid=worker_interface.uuid,
|
||||
network_uuid=self.mgmt_network.uuid)
|
||||
self._post_and_check(worker_interface_network, expect_errors=True)
|
||||
|
||||
# Expected error: The oam network type is only supported on controller nodes
|
||||
def test_invalid_oam_on_worker(self):
|
||||
worker_interface = dbutils.create_test_interface(
|
||||
ifname='enp0s3',
|
||||
forihostid=self.worker.id)
|
||||
worker_interface_network = dbutils.post_get_test_interface_network(
|
||||
interface_uuid=worker_interface.uuid,
|
||||
network_uuid=self.oam_network.uuid)
|
||||
self._post_and_check(worker_interface_network, expect_errors=True)
|
||||
|
||||
# Expected message: An interface with \'oam\' network type is already
|
||||
# provisioned on this node
|
||||
def test_create_invalid_duplicate_networktype(self):
|
||||
controller_interface1 = dbutils.create_test_interface(
|
||||
ifname='enp0s3',
|
||||
forihostid=self.controller.id)
|
||||
dbutils.create_test_interface_network(
|
||||
interface_id=controller_interface1.id,
|
||||
network_id=self.oam_network.id)
|
||||
controller_interface2 = dbutils.create_test_interface(
|
||||
ifname='enp0s8',
|
||||
forihostid=self.controller.id)
|
||||
controller_interface_network = dbutils.post_get_test_interface_network(
|
||||
interface_uuid=controller_interface2.uuid,
|
||||
network_uuid=self.oam_network.uuid)
|
||||
self._post_and_check(controller_interface_network, expect_errors=True)
|
||||
|
||||
# Expected error: Interface ___ does not have associated cluster-host
|
||||
# interface on controller.
|
||||
def test_no_cluster_host_on_controller(self):
|
||||
worker_interface = dbutils.create_test_interface(
|
||||
ifname='enp0s3',
|
||||
forihostid=self.worker.id)
|
||||
worker_interface_network = dbutils.post_get_test_interface_network(
|
||||
interface_uuid=worker_interface.uuid,
|
||||
network_uuid=self.cluster_host_network.uuid)
|
||||
self._post_and_check(worker_interface_network, expect_errors=True)
|
||||
|
||||
# Expected error: An interface with interface class data cannot
|
||||
# assign platform networks.
|
||||
def test_create_invalid_network_on_data_interface(self):
|
||||
controller_interface = dbutils.create_test_interface(
|
||||
ifname='enp0s3',
|
||||
ifclass=constants.NETWORK_TYPE_DATA,
|
||||
forihostid=self.controller.id)
|
||||
controller_interface_network = dbutils.post_get_test_interface_network(
|
||||
interface_uuid=controller_interface.uuid,
|
||||
network_uuid=self.cluster_host_network.uuid)
|
||||
self._post_and_check(controller_interface_network, expect_errors=True)
|
||||
|
||||
# Expected error: Device interface with network type ___, and interface type
|
||||
# 'aggregated ethernet' must be in mode '802.3ad'
|
||||
def test_aemode_invalid_mgmt(self):
|
||||
controller_interface = dbutils.create_test_interface(
|
||||
ifname='name',
|
||||
forihostid=self.controller.id,
|
||||
ifclass=constants.INTERFACE_CLASS_PLATFORM,
|
||||
iftype=constants.INTERFACE_TYPE_AE,
|
||||
aemode='balanced',
|
||||
txhashpolicy='layer2')
|
||||
controller_interface_network = dbutils.post_get_test_interface_network(
|
||||
interface_uuid=controller_interface.uuid,
|
||||
network_uuid=self.mgmt_network.uuid)
|
||||
self._post_and_check(controller_interface_network, expect_errors=True)
|
||||
|
@ -674,8 +674,6 @@ def post_get_test_interface(**kw):
|
||||
'imac': kw.get('imac', '11:22:33:44:55:66'),
|
||||
'imtu': kw.get('imtu', 1500),
|
||||
'ifclass': kw.get("ifclass"),
|
||||
'networktype': kw.get('networktype'),
|
||||
'networks': kw.get('networks', []),
|
||||
'aemode': kw.get('aemode', 'balanced'),
|
||||
'txhashpolicy': kw.get('txhashpolicy', 'layer2'),
|
||||
'datanetworks': datanetworks_list,
|
||||
@ -710,8 +708,7 @@ def get_test_interface(**kw):
|
||||
'imac': kw.get('imac', '11:22:33:44:55:66'),
|
||||
'imtu': kw.get('imtu', 1500),
|
||||
'ifclass': kw.get('ifclass', None),
|
||||
'networktype': kw.get('networktype'),
|
||||
'networks': kw.get('networks', []),
|
||||
'networktypelist': kw.get('networktypelist', []),
|
||||
'aemode': kw.get('aemode'),
|
||||
'txhashpolicy': kw.get('txhashpolicy', None),
|
||||
'datanetworks': datanetworks_list,
|
||||
@ -737,6 +734,7 @@ def create_test_interface(**kw):
|
||||
|
||||
interface = get_test_interface(**kw)
|
||||
datanetworks_list = interface.get('datanetworks') or []
|
||||
networks_list = interface.get('networks') or []
|
||||
|
||||
# Let DB generate ID if it isn't specified explicitly
|
||||
if 'id' not in kw:
|
||||
@ -745,10 +743,22 @@ def create_test_interface(**kw):
|
||||
if 'datanetworks' in interface:
|
||||
del interface['datanetworks']
|
||||
|
||||
if 'networks' in interface:
|
||||
del interface['networks']
|
||||
|
||||
dbapi = db_api.get_instance()
|
||||
forihostid = kw.get('forihostid')
|
||||
interface_obj = dbapi.iinterface_create(forihostid, interface)
|
||||
|
||||
# assign the network to the interface
|
||||
for network in networks_list:
|
||||
if not network:
|
||||
continue
|
||||
net = dbapi.network_get(network)
|
||||
values = {'interface_id': interface_obj.id,
|
||||
'network_id': net.id}
|
||||
dbapi.interface_network_create(values)
|
||||
|
||||
# assign the interface to the datanetwork
|
||||
for datanetwork in datanetworks_list:
|
||||
if not datanetwork:
|
||||
|
@ -64,20 +64,21 @@ class BaseTestCase(dbbase.DbTestCase):
|
||||
super(BaseTestCase, self).assertEqual(expected, observed, message)
|
||||
|
||||
def _setup_address_and_routes(self, iface):
|
||||
networktype = utils.get_primary_network_type(iface)
|
||||
if networktype in NETWORKTYPES_WITH_V4_ADDRESSES:
|
||||
if not iface['ifclass'] or iface['ifclass'] == constants.INTERFACE_CLASS_NONE:
|
||||
return None
|
||||
if iface['ifclass'] == constants.INTERFACE_CLASS_PLATFORM:
|
||||
address = {'interface_id': iface['id'],
|
||||
'family': 4,
|
||||
'prefix': 24,
|
||||
'address': '192.168.1.2'}
|
||||
self.addresses.append(dbutils.create_test_address(**address))
|
||||
elif networktype in NETWORKTYPES_WITH_V6_ADDRESSES:
|
||||
elif iface['ifclass'] == constants.INTERFACE_CLASS_DATA:
|
||||
address = {'interface_id': iface['id'],
|
||||
'family': 6,
|
||||
'prefix': 64,
|
||||
'address': '2001:1::2'}
|
||||
self.addresses.append(dbutils.create_test_address(**address))
|
||||
if networktype in NETWORKTYPES_WITH_V4_ROUTES:
|
||||
if iface['ifclass'] == constants.INTERFACE_CLASS_DATA:
|
||||
route = {'interface_id': iface['id'],
|
||||
'family': 4,
|
||||
'prefix': 24,
|
||||
@ -92,7 +93,7 @@ class BaseTestCase(dbbase.DbTestCase):
|
||||
'gateway': '192.168.1.1',
|
||||
'metric': '1'}
|
||||
self.routes.append(dbutils.create_test_route(**route))
|
||||
if networktype in NETWORKTYPES_WITH_V6_ROUTES:
|
||||
if iface['ifclass'] == constants.INTERFACE_CLASS_DATA:
|
||||
route = {'interface_id': iface['id'],
|
||||
'family': 6,
|
||||
'prefix': 64,
|
||||
|
Loading…
Reference in New Issue
Block a user