Clean up interface network assignment
The networktype field is no longer used in the interface table since an interface can have multiple networks associated with it. This commit is to remove the networktype field and use the network association instead. The host interface commands used to allow associating an initial network to the interface. This has been changed such that network association can only be done with the interface-network commands. The address assignment of an interface is performed when a network is assigned to an interface, not when the interface is provisioned. Data interface no longer requires at least one datanetwork associated with it. The REST API doc is also updated to reflect the changes. Story: 2004273 Task: 30947 Task: 33504 Change-Id: I952008408826f4c630246477d71687628357622c Signed-off-by: Teresa Ho <teresa.ho@windriver.com>
This commit is contained in:
parent
f567ff1b52
commit
78bcf995fb
|
@ -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():
|
||||
|
|
|
@ -651,6 +651,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