Merge "Clean up interface network assignment"

This commit is contained in:
Zuul 2019-06-13 19:48:11 +00:00 committed by Gerrit Code Review
commit c7e73429e6
34 changed files with 715 additions and 1018 deletions

View File

@ -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." "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``." "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." "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." "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." "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." "imtu (Optional)", "plain", "xsd:integer", "The Maximum Transmission Unit (MTU) of the interface, in bytes."
@ -2447,7 +2446,6 @@ itemNotFound (404)
"vlan_id": null, "vlan_id": null,
"imtu": 1500, "imtu": 1500,
"aemode": null, "aemode": null,
"networks": ["1"],
"datanetworks": [], "datanetworks": [],
"ifclass": "platform" "ifclass": "platform"
"ifname": "eth1" "ifname": "eth1"
@ -2480,7 +2478,6 @@ itemNotFound (404)
], ],
"aemode": "balanced", "aemode": "balanced",
"networks": [],
"datanetworks": ["physnet-0,physnet-1"], "datanetworks": ["physnet-0,physnet-1"],
"ifclass": "data" "ifclass": "data"
"ifname": "data1" "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." "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``." "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." "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." "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." "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." "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"], "datanetworks" : ["physnet-0,physnet-1"],
"networks": [],
"txhashpolicy" : "layer2", "txhashpolicy" : "layer2",
"schedpolicy" : null, "schedpolicy" : null,
"uuid" : "740a5bec-b7a8-4645-93ed-aea0d4cfbf86", "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." "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``." "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." "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." "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." "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." "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." "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``." "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." "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." "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." "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." "imtu (Optional)", "plain", "xsd:integer", "The Maximum Transmission Unit (MTU) of the interface, in bytes."
@ -2667,7 +2660,6 @@ badMediaType (415)
"txhashpolicy": "layer2", "txhashpolicy": "layer2",
"ihost_uuid": "ff453a51-1d3b-437f-a65e-b2d163f79f85", "ihost_uuid": "ff453a51-1d3b-437f-a65e-b2d163f79f85",
"imtu": "1500", "imtu": "1500",
"networks": [],
"datanetworks": "physnet-0,physnet1", "datanetworks": "physnet-0,physnet1",
"ifclass": "data", "ifclass": "data",
"ifname": "data1", "ifname": "data1",
@ -2722,7 +2714,6 @@ badMediaType (415)
], ],
"aemode": "balanced", "aemode": "balanced",
"sriov_numvfs": 0, "sriov_numvfs": 0,
'networks": [],
"datanetworks": ["physnet-0,physnet-1"], "datanetworks": ["physnet-0,physnet-1"],
"ifclass": "data", "ifclass": "data",
"ifname": "data1", "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." "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``." "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." "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." "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." "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." "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." "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``." "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." "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." "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." "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." "imtu (Optional)", "plain", "xsd:integer", "The Maximum Transmission Unit (MTU) of the interface, in bytes."
@ -2870,7 +2859,6 @@ badMediaType (415)
], ],
"aemode": "active_standby", "aemode": "active_standby",
"networks": [],
"datanetworks": ["physnet-0,physnet-1"], "datanetworks": ["physnet-0,physnet-1"],
"ifclass": "data", "ifclass": "data",
"ifname": "data1", "ifname": "data1",

View File

@ -14,8 +14,9 @@
# Use shell instead of command module as source is an internal shell command # Use shell instead of command module as source is an internal shell command
shell: "{{ item }}" shell: "{{ item }}"
with_items: 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-add controller-0 lo virtual none lo -c platform -m 1500
- source /etc/platform/openrc; system host-if-modify controller-0 -c platform --networks cluster-host lo - 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 {{ 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 {{ mgmt_virtual }} brd {{ management_broadcast }} dev lo scope host label lo:1
- ip addr add {{ pxe_virtual }} dev lo scope host - ip addr add {{ pxe_virtual }} dev lo scope host

View File

@ -13,25 +13,17 @@ from cgtsclient.common import utils
from cgtsclient import exc from cgtsclient import exc
from cgtsclient.v1 import ihost as ihost_utils from cgtsclient.v1 import ihost as ihost_utils
from cgtsclient.v1 import iinterface as iinterface_utils from cgtsclient.v1 import iinterface as iinterface_utils
from cgtsclient.v1 import network as network_utils
def _print_iinterface_show(cc, iinterface): def _print_iinterface_show(cc, iinterface):
fields = ['ifname', 'iftype', 'ports', 'datanetworks', fields = ['ifname', 'iftype', 'ports', 'datanetworks',
'imac', 'imtu', 'ifclass', 'networks', 'imac', 'imtu', 'ifclass',
'aemode', 'schedpolicy', 'txhashpolicy', 'aemode', 'schedpolicy', 'txhashpolicy',
'uuid', 'ihost_uuid', 'uuid', 'ihost_uuid',
'vlan_id', 'uses', 'used_by', 'vlan_id', 'uses', 'used_by',
'created_at', 'updated_at', 'sriov_numvfs', 'sriov_vf_driver'] 'created_at', 'updated_at', 'sriov_numvfs', 'sriov_vf_driver']
optional_fields = ['ipv4_mode', 'ipv6_mode', 'ipv4_pool', 'ipv6_pool'] optional_fields = ['ipv4_mode', 'ipv6_mode', 'ipv4_pool', 'ipv6_pool']
rename_fields = [{'field': 'dpdksupport', 'label': 'accelerated'}] 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 fields]
data += [(f, getattr(iinterface, f, '')) for f in optional_fields data += [(f, getattr(iinterface, f, '')) for f in optional_fields
if hasattr(iinterface, f)] if hasattr(iinterface, f)]
@ -153,9 +145,6 @@ def do_host_if_delete(cc, args):
metavar='<class>', metavar='<class>',
choices=['platform', 'data', 'pci-passthrough', 'pci-sriov', 'none'], choices=['platform', 'data', 'pci-passthrough', 'pci-sriov', 'none'],
help='The class of the interface') help='The class of the interface')
@utils.arg('--networks',
metavar='<network name or id>',
help="Name or ID of network")
@utils.arg('portsorifaces', @utils.arg('portsorifaces',
metavar='<portsorifaces>', metavar='<portsorifaces>',
nargs='+', nargs='+',
@ -177,7 +166,7 @@ def do_host_if_delete(cc, args):
def do_host_if_add(cc, args): def do_host_if_add(cc, args):
"""Add an interface.""" """Add an interface."""
field_list = ['ifname', 'iftype', 'imtu', 'ifclass', 'networks', 'aemode', field_list = ['ifname', 'iftype', 'imtu', 'ifclass', 'aemode',
'txhashpolicy', 'datanetworks', 'vlan_id', 'txhashpolicy', 'datanetworks', 'vlan_id',
'ipv4_mode', 'ipv6_mode', 'ipv4_pool', 'ipv6_pool'] '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'] = \
user_specified_fields['datanetworks'].split(',') 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['ihost_uuid'] = ihost.uuid
user_specified_fields['ports'] = portnamesoruuids user_specified_fields['ports'] = portnamesoruuids
user_specified_fields['uses'] = uses user_specified_fields['uses'] = uses
@ -251,9 +236,6 @@ def do_host_if_add(cc, args):
@utils.arg('-c', '--ifclass', @utils.arg('-c', '--ifclass',
metavar='<class>', metavar='<class>',
help='The class of the interface') help='The class of the interface')
@utils.arg('--networks',
metavar='<network name or id>',
help="Name or ID of network")
@utils.arg('--ipv4-mode', @utils.arg('--ipv4-mode',
metavar='<ipv4_mode>', metavar='<ipv4_mode>',
choices=['disabled', 'static', 'pool'], choices=['disabled', 'static', 'pool'],
@ -281,7 +263,7 @@ def do_host_if_modify(cc, args):
"""Modify interface attributes.""" """Modify interface attributes."""
rwfields = ['iftype', 'ifname', 'imtu', 'aemode', 'txhashpolicy', rwfields = ['iftype', 'ifname', 'imtu', 'aemode', 'txhashpolicy',
'datanetworks', 'providernetworks', 'ports', 'ifclass', 'networks', 'datanetworks', 'providernetworks', 'ports', 'ifclass',
'ipv4_mode', 'ipv6_mode', 'ipv4_pool', 'ipv6_pool', 'ipv4_mode', 'ipv6_mode', 'ipv4_pool', 'ipv6_pool',
'sriov_numvfs', 'sriov_vf_driver'] 'sriov_numvfs', 'sriov_vf_driver']
@ -303,10 +285,6 @@ def do_host_if_modify(cc, args):
fields = interface.__dict__ fields = interface.__dict__
fields.update(user_specified_fields) 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 # Allow setting an interface back to a None type
if 'ifclass' in user_specified_fields.keys(): if 'ifclass' in user_specified_fields.keys():
if args.ifclass == 'none': if args.ifclass == 'none':

View File

@ -56,3 +56,11 @@ class InterfaceNetworkManager(base.Manager):
def remove(self, interface_network_uuid): def remove(self, interface_network_uuid):
path = '/v1/interface_networks/%s' % interface_network_uuid path = '/v1/interface_networks/%s' % interface_network_uuid
return self._delete(path) 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

View File

@ -16,6 +16,7 @@ from cgtsclient import exc
from cgtsclient.v1 import ethernetport as ethernetport_utils from cgtsclient.v1 import ethernetport as ethernetport_utils
from cgtsclient.v1 import icpu as icpu_utils from cgtsclient.v1 import icpu as icpu_utils
from cgtsclient.v1 import ihost as ihost_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 from cgtsclient.v1 import iprofile as iprofile_utils
import math import math
@ -58,11 +59,13 @@ def get_portconfig(iprofile):
return pstr return pstr
def get_interfaceconfig(iprofile): def get_interfaceconfig(cc, iprofile):
istr = '' istr = ''
for interface in iprofile.interfaces: for interface in iprofile.interfaces:
istr = istr + "%s: %s" % (interface.ifname, interface.networktype) if interface.ifclass == 'platform':
if interface.networktype == 'data': 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 istr = istr + "( %s )" % interface.datanetworks
_get_interface_ports_interfaces(iprofile, interface) _get_interface_ports_interfaces(iprofile, interface)
if interface.ports: if interface.ports:
@ -83,7 +86,7 @@ def get_ifprofile_data(cc, iprofile):
if iprofile.ports: # an 'interface' profile if iprofile.ports: # an 'interface' profile
iprofile.portconfig = get_portconfig(iprofile) iprofile.portconfig = get_portconfig(iprofile)
iprofile.interfaces = cc.iprofile.list_iinterface(iprofile.uuid) 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): def do_ifprofile_list(cc, args):
@ -91,7 +94,7 @@ def do_ifprofile_list(cc, args):
profiles = cc.iprofile.list_interface_profiles() profiles = cc.iprofile.list_interface_profiles()
for profile in profiles: for profile in profiles:
profile.portconfig = get_portconfig(profile) profile.portconfig = get_portconfig(profile)
profile.interfaceconfig = get_interfaceconfig(profile) profile.interfaceconfig = get_interfaceconfig(cc, profile)
field_labels = ['uuid', 'name', 'port config', 'interface config'] field_labels = ['uuid', 'name', 'port config', 'interface config']
fields = ['uuid', 'profilename', 'portconfig', 'interfaceconfig'] fields = ['uuid', 'profilename', 'portconfig', 'interfaceconfig']

View File

@ -213,22 +213,22 @@ class AgentManager(service.PeriodicService):
# do not bother with alarms since that adds too much noise. # do not bother with alarms since that adds too much noise.
LOG.info("Cross-numa performance degradation over port %s " LOG.info("Cross-numa performance degradation over port %s "
"on processor %d on host %s. Better performance " "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 " "residing on processor 0, or configure a platform "
"core on processor %d." % "core on processor %d." %
(info['name'], info['numa_node'], self.host, (info['name'], info['numa_node'], self.host,
info['networktype'], info['numa_node'])) info['numa_node']))
LOG.info("Affine %s interface %s with cpulist %s" % LOG.info("Affine platform interface %s with cpulist %s" %
(info['networktype'], info['name'], cpulist)) (info['name'], cpulist))
cmd = '/usr/bin/affine-interrupts.sh %s %s' % \ cmd = '/usr/bin/affine-interrupts.sh %s %s' % \
(info['name'], cpulist) (info['name'], cpulist)
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
proc.communicate() proc.communicate()
LOG.info("%s return %d" % (cmd, proc.returncode)) LOG.info("%s return %d" % (cmd, proc.returncode))
if proc.returncode == 1: if proc.returncode == 1:
LOG.error("Failed to affine %s %s interrupts with %s" % LOG.error("Failed to affine platform interface %s interrupts with %s" %
(info['networktype'], info['name'], cpulist)) (info['name'], cpulist))
def _update_ttys_dcd_status(self, context, host_id): def _update_ttys_dcd_status(self, context, host_id):
# Retrieve the serial line carrier detect flag # Retrieve the serial line carrier detect flag

View File

@ -246,11 +246,13 @@ class AddressController(rest.RestController):
def _check_interface_type(self, interface_id): def _check_interface_type(self, interface_id):
interface = pecan.request.dbapi.iinterface_get(interface_id) interface = pecan.request.dbapi.iinterface_get(interface_id)
if not interface.networktype: if (interface['ifclass'] == constants.INTERFACE_TYPE_PLATFORM and
raise exception.InterfaceNetworkTypeNotSet() interface['networktypelist'] is None):
if interface.networktype not in ALLOWED_NETWORK_TYPES: raise exception.InterfaceNetworkNotSet()
raise exception.UnsupportedInterfaceNetworkType( for nt in interface['networktypelist']:
networktype=interface.networktype) if nt not in ALLOWED_NETWORK_TYPES:
raise exception.UnsupportedInterfaceNetworkType(
networktype=nt)
return return
def _check_address_mode(self, interface_id, family): 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): def _check_address_count(self, interface_id, host_id):
interface = pecan.request.dbapi.iinterface_get(interface_id) interface = pecan.request.dbapi.iinterface_get(interface_id)
networktype = interface['networktype']
sdn_enabled = utils.get_sdn_enabled() 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 # Is permitted to add multiple addresses only
# if SDN L3 mode is not enabled. # if SDN L3 mode is not enabled.
return return
@ -309,12 +310,12 @@ class AddressController(rest.RestController):
# skip the one we came in with # skip the one we came in with
if uuid == interface_id: if uuid == interface_id:
continue continue
if iface['ifclass'] == constants.NETWORK_TYPE_DATA: if iface['ifclass'] == constants.INTERFACE_CLASS_DATA:
addresses = ( addresses = (
pecan.request.dbapi.addresses_get_by_interface(uuid)) pecan.request.dbapi.addresses_get_by_interface(uuid))
if len(addresses) != 0: if len(addresses) != 0:
raise exception.\ raise exception.AddressLimitedToOneWithSDN(
AddressLimitedToOneWithSDN(iftype=networktype) iftype=constants.INTERFACE_CLASS_DATA)
def _check_address_conflicts(self, host_id, interface_id, address): def _check_address_conflicts(self, host_id, interface_id, address):
self._check_address_count(interface_id, host_id) 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): def _check_managed_addr(self, host_id, interface_id):
# Check that static address alloc is enabled # Check that static address alloc is enabled
interface = pecan.request.dbapi.iinterface_get(interface_id) interface = pecan.request.dbapi.iinterface_get(interface_id)
networktype = interface['networktype'] if interface['networktypelist']:
if networktype not in [constants.NETWORK_TYPE_MGMT, for networktype in interface['networktypelist']:
constants.NETWORK_TYPE_OAM]: if networktype not in [constants.NETWORK_TYPE_MGMT,
return constants.NETWORK_TYPE_OAM]:
network = pecan.request.dbapi.network_get_by_type(networktype) continue
if network.dynamic: network = pecan.request.dbapi.network_get_by_type(networktype)
raise exception.StaticAddressNotConfigured() if network.dynamic:
raise exception.StaticAddressNotConfigured()
host = pecan.request.dbapi.ihost_get(host_id) host = pecan.request.dbapi.ihost_get(host_id)
if host['personality'] in [constants.STORAGE]: if host['personality'] in [constants.STORAGE]:
raise exception.ManagedIPAddress() raise exception.ManagedIPAddress()

View File

@ -3106,8 +3106,8 @@ class HostController(rest.RestController):
""" """
count = 0 count = 0
if interface.networktype not in address_api.ALLOWED_NETWORK_TYPES: if not any(nt in address_api.ALLOWED_NETWORK_TYPES for nt in interface.networktypelist):
return return
# Check IPv4 address presence # Check IPv4 address presence
addresses = pecan.request.dbapi.addresses_get_by_interface( addresses = pecan.request.dbapi.addresses_get_by_interface(
interface['id'], family=constants.IPV4_FAMILY) interface['id'], family=constants.IPV4_FAMILY)
@ -3134,9 +3134,9 @@ class HostController(rest.RestController):
raise wsme.exc.ClientSideError(msg) raise wsme.exc.ClientSideError(msg)
if min_count and (count < min_count): if min_count and (count < min_count):
msg = (_("Expecting at least %(min)s IP address(es) on " 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, {'min': min_count,
'networktype': interface.networktype, 'ifclass': interface.ifclass,
'ifname': interface.ifname, 'ifname': interface.ifname,
'count': count}) 'count': count})
raise wsme.exc.ClientSideError(msg) raise wsme.exc.ClientSideError(msg)
@ -3220,7 +3220,7 @@ class HostController(rest.RestController):
interfaces = ( interfaces = (
pecan.request.dbapi.iinterface_get_by_ihost(ihost['uuid'])) pecan.request.dbapi.iinterface_get_by_ihost(ihost['uuid']))
for interface in interfaces: for interface in interfaces:
if interface.networktype == constants.NETWORK_TYPE_OAM: if constants.NETWORK_TYPE_OAM in interface.networktypelist:
break break
else: else:
msg = _("Can not unlock a controller host without an oam " msg = _("Can not unlock a controller host without an oam "
@ -3333,7 +3333,7 @@ class HostController(rest.RestController):
address_count = 0 address_count = 0
interfaces = pecan.request.dbapi.iinterface_get_by_ihost(ihost['uuid']) interfaces = pecan.request.dbapi.iinterface_get_by_ihost(ihost['uuid'])
for iface in interfaces: for iface in interfaces:
if iface.networktype != constants.NETWORK_TYPE_DATA: if iface.ifclass != constants.INTERFACE_TYPE_DATA:
continue continue
addresses = ( addresses = (
pecan.request.dbapi.addresses_get_by_interface(iface['uuid'])) pecan.request.dbapi.addresses_get_by_interface(iface['uuid']))
@ -5900,11 +5900,10 @@ class HostController(rest.RestController):
# controller/worker/storage # controller/worker/storage
ihost_iinterfaces = pecan.request.dbapi.iinterface_get_by_ihost( ihost_iinterfaces = pecan.request.dbapi.iinterface_get_by_ihost(
ihost['uuid']) ihost['uuid'])
network = pecan.request.dbapi.network_get_by_type(
constants.NETWORK_TYPE_MGMT)
mgmt_interface_configured = False mgmt_interface_configured = False
for iif in ihost_iinterfaces: 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 mgmt_interface_configured = True
if not mgmt_interface_configured: if not mgmt_interface_configured:
@ -5917,10 +5916,9 @@ class HostController(rest.RestController):
# controller/worker/storage # controller/worker/storage
host_interfaces = pecan.request.dbapi.iinterface_get_by_ihost( host_interfaces = pecan.request.dbapi.iinterface_get_by_ihost(
ihost['uuid']) ihost['uuid'])
network = pecan.request.dbapi.network_get_by_type(
constants.NETWORK_TYPE_CLUSTER_HOST)
for iif in host_interfaces: 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 break
else: else:
msg = _("Cannot unlock host %s " msg = _("Cannot unlock host %s "
@ -5969,15 +5967,9 @@ class HostController(rest.RestController):
# updated management interfaces # updated management interfaces
idata = {} idata = {}
for iif in ihost_iinterfaces: for iif in ihost_iinterfaces:
iif_networktype = [] if constants.NETWORK_TYPE_MGMT in iif.networktypelist:
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):
for ila in interface_list_active: for ila in interface_list_active:
ila_networktype = [] if constants.NETWORK_TYPE_MGMT in ila.networktypelist:
if ila.networktype:
ila_networktype = [network.strip() for network in ila.networktype.split(",")]
if any(network in ila_networktype for network in iif_networktype):
idata['imtu'] = ila.imtu idata['imtu'] = ila.imtu
pecan.request.dbapi.iinterface_update(iif.uuid, idata) pecan.request.dbapi.iinterface_update(iif.uuid, idata)
break break

File diff suppressed because it is too large Load Diff

View File

@ -200,8 +200,10 @@ class InterfaceDataNetworkController(rest.RestController):
pecan.request.dbapi.iinterface_update(interface_obj.uuid, values) pecan.request.dbapi.iinterface_update(interface_obj.uuid, values)
return return
else: else:
# Allow ifclass data to assign another; disallow other ifclass # Allow ifclass data, pcipt and sriov to assign data networks
if interface_obj.ifclass != constants.INTERFACE_CLASS_DATA: 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' " msg = _("An interface with interface class '%s' "
"cannot assign datanetworks." % "cannot assign datanetworks." %
interface_obj.ifclass) interface_obj.ifclass)

View File

@ -19,6 +19,7 @@
# Copyright (c) 2013-2018 Wind River Systems, Inc. # Copyright (c) 2013-2018 Wind River Systems, Inc.
# #
import os
import uuid import uuid
import wsme import wsme
import pecan import pecan
@ -26,6 +27,7 @@ from pecan import rest
from wsme import types as wtypes from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan 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 base
from sysinv.api.controllers.v1 import collection from sysinv.api.controllers.v1 import collection
from sysinv.api.controllers.v1 import types from sysinv.api.controllers.v1 import types
@ -134,8 +136,10 @@ class InterfaceNetworkController(rest.RestController):
interface_uuid = interface_network_dict.pop('interface_uuid') interface_uuid = interface_network_dict.pop('interface_uuid')
network_uuid = interface_network_dict.pop('network_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) 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['interface_id'] = interface_id
interface_network_dict['network_id'] = network_id interface_network_dict['network_id'] = network_id
@ -143,16 +147,51 @@ class InterfaceNetworkController(rest.RestController):
self._check_interface_class(interface_uuid) self._check_interface_class(interface_uuid)
self._check_assigned_network_type(network_type) self._check_assigned_network_type(network_type)
self._check_duplicate_interface_network(interface_network_dict) 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_pxeboot_network(interface_id, network_type)
self._check_oam_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) result = pecan.request.dbapi.interface_network_create(interface_network_dict)
interface = pecan.request.dbapi.iinterface_get(interface_uuid) # Update address mode based on network type
if not interface.networktype: if network_type in [constants.NETWORK_TYPE_MGMT,
values = {'networktype': network_type} constants.NETWORK_TYPE_OAM,
pecan.request.dbapi.iinterface_update(interface_uuid, values) 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) return InterfaceNetwork.convert_with_links(result)
@ -218,16 +257,15 @@ class InterfaceNetworkController(rest.RestController):
% (interface_network['interface_id'], interface_network['network_id'])) % (interface_network['interface_id'], interface_network['network_id']))
raise wsme.exc.ClientSideError(msg) 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: if network_type in NONDUPLICATE_NETWORK_TYPES:
interface_networks = pecan.request.dbapi.interface_network_get_all() interfaces = pecan.request.dbapi.iinterface_get_by_ihost(host['uuid'])
for i in interface_networks: for host_interface in interfaces:
if i.interface_id == interface_id and i.network_type == network_type: if (network_type in host_interface['networktypelist'] and
msg = _("An interface with network type '%s' is " host_interface['uuid'] != interface_uuid):
"already provisioned on this node." % network_type) msg = _("An interface with '%s' network type is "
"already provisioned on this node" % network_type)
raise wsme.exc.ClientSideError(msg) raise wsme.exc.ClientSideError(msg)
else:
return
def _check_assigned_network_type(self, network_type): def _check_assigned_network_type(self, network_type):
if network_type not in NONASSIGNABLE_NETWORK_TYPES: if network_type not in NONASSIGNABLE_NETWORK_TYPES:
@ -275,6 +313,56 @@ class InterfaceNetworkController(rest.RestController):
% (i.network_type, network_type)) % (i.network_type, network_type))
raise wsme.exc.ClientSideError(msg) 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): def _get_interface_id(self, interface_uuid):
interface = pecan.request.dbapi.iinterface_get(interface_uuid) interface = pecan.request.dbapi.iinterface_get(interface_uuid)
return interface['id'] return interface['id']
@ -301,4 +389,125 @@ class InterfaceNetworkController(rest.RestController):
@cutils.synchronized(LOCK_NAME) @cutils.synchronized(LOCK_NAME)
@wsme_pecan.wsexpose(None, types.uuid, status_code=204) @wsme_pecan.wsexpose(None, types.uuid, status_code=204)
def delete(self, interface_network_uuid): 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) 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)

View File

@ -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 disk as disk_api
from sysinv.api.controllers.v1 import partition as partition_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 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 memory as memory_api
from sysinv.api.controllers.v1 import node as node_api from sysinv.api.controllers.v1 import node as node_api
from sysinv.api.controllers.v1 import storage as storage_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} 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) 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 # Generate the uses/used_by relationships
for i in newIfList: for i in newIfList:
uses_list = [] uses_list = []
@ -2614,6 +2622,14 @@ def ifprofile_apply_to_host(host, profile):
if interface_found is False: if interface_found is False:
hinterface = interface_api._create(data, from_profile=True) 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: except Exception as e:
# Delete all Host's interfaces # Delete all Host's interfaces
@ -2678,6 +2694,15 @@ def ifprofile_apply_to_host(host, profile):
data['forihostid'] = host.id data['forihostid'] = host.id
hinterface = interface_api._create(data, from_profile=True) 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, []): for r in profile.routes.get(i.uuid, []):
pecan.request.dbapi.route_create(hinterface.id, r) pecan.request.dbapi.route_create(hinterface.id, r)

View File

@ -263,9 +263,12 @@ class RouteController(rest.RestController):
def _check_interface_type(self, interface_id): def _check_interface_type(self, interface_id):
interface = pecan.request.dbapi.iinterface_get(interface_id) interface = pecan.request.dbapi.iinterface_get(interface_id)
networktype = interface['networktype'] if (interface['ifclass'] == constants.INTERFACE_TYPE_PLATFORM and
if networktype not in ALLOWED_NETWORK_TYPES: interface['networktypelist'] is None):
raise exception.RoutesNotSupportedOnInterfaces(iftype=networktype) raise exception.InterfaceNetworkNotSet()
for nt in interface['networktypelist']:
if nt not in ALLOWED_NETWORK_TYPES:
raise exception.RoutesNotSupportedOnInterfaces(type=nt)
return return
def _check_duplicate_route(self, host_id, route): def _check_duplicate_route(self, host_id, route):

View File

@ -598,11 +598,9 @@ class SystemController(rest.RestController):
host_id = controller['id'] host_id = controller['id']
interface_list = pecan.request.dbapi.iinterface_get_by_ihost(host_id) interface_list = pecan.request.dbapi.iinterface_get_by_ihost(host_id)
for interface in interface_list: for interface in interface_list:
for network_id in interface['networks']: if constants.NETWORK_TYPE_MGMT in interface['networktypelist']:
network = pecan.request.dbapi.network_get_by_id(network_id) if 'vlan_id' not in interface:
if network.type == constants.NETWORK_TYPE_MGMT: return 0
if 'vlan_id' not in interface: else:
return 0 return interface['vlan_id']
else:
return interface['vlan_id']
return None return None

View File

@ -326,6 +326,28 @@ def lookup_static_ip_address(name, networktype):
return None 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): class SystemHelper(object):
@staticmethod @staticmethod
def get_product_build(): def get_product_build():

View File

@ -650,6 +650,13 @@ INTERFACE_CLASS_DATA = 'data'
INTERFACE_CLASS_PCI_PASSTHROUGH = 'pci-passthrough' INTERFACE_CLASS_PCI_PASSTHROUGH = 'pci-passthrough'
INTERFACE_CLASS_PCI_SRIOV = 'pci-sriov' 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" SM_MULTICAST_MGMT_IP_NAME = "sm-mgmt-ip"
MTCE_MULTICAST_MGMT_IP_NAME = "mtce-mgmt-ip" MTCE_MULTICAST_MGMT_IP_NAME = "mtce-mgmt-ip"
PATCH_CONTROLLER_MULTICAST_MGMT_IP_NAME = "patch-controller-mgmt-ip" PATCH_CONTROLLER_MULTICAST_MGMT_IP_NAME = "patch-controller-mgmt-ip"

View File

@ -331,9 +331,8 @@ class InterfaceNameAlreadyExists(Conflict):
message = _("Interface with name %(name)s already exists.") message = _("Interface with name %(name)s already exists.")
class InterfaceNetworkTypeNotSet(Conflict): class InterfaceNetworkNotSet(Conflict):
message = _("The Interface must have a networktype configured to " message = _("The Interface does not have any network assigned to it.")
"support addresses. (data or infra)")
class AddressInUseByRouteGateway(Conflict): class AddressInUseByRouteGateway(Conflict):
@ -372,7 +371,7 @@ class RouteGatewayCannotBeLocal(Conflict):
class RoutesNotSupportedOnInterfaces(Conflict): class RoutesNotSupportedOnInterfaces(Conflict):
message = _("Routes may not be configured against interfaces with network " message = _("Routes may not be configured against interfaces with network "
"type '%(iftype)s'") "type '%(type)s'")
class DefaultRouteNotAllowedOnVRSInterface(Conflict): class DefaultRouteNotAllowedOnVRSInterface(Conflict):
@ -699,6 +698,11 @@ class AddressNotFoundByName(NotFound):
message = _("Address could not be found for %(name)s") 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): class AddressModeAlreadyExists(Conflict):
message = _("An AddressMode with UUID %(uuid)s already exists.") message = _("An AddressMode with UUID %(uuid)s already exists.")

View File

@ -1027,51 +1027,6 @@ def get_required_platform_reserved_memory(ihost, numa_node, low_core=False):
return required_reserved 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(): def get_sw_version():
return SW_VERSION return SW_VERSION
@ -1502,7 +1457,7 @@ def perform_distributed_cloud_config(dbapi, mgmt_iface_id):
mate_interfaces = dbapi.iinterface_get_all( mate_interfaces = dbapi.iinterface_get_all(
forihostid=mate_controller_id) forihostid=mate_controller_id)
for interface in mate_interfaces: for interface in mate_interfaces:
if interface.networktype == constants.NETWORK_TYPE_MGMT: if constants.NETWORK_TYPE_MGMT in interface.networktypelist:
mate_mgmt_iface = interface mate_mgmt_iface = interface
break break
else: else:

View File

@ -1196,7 +1196,7 @@ class ConductorManager(service.PeriodicService):
port_list = self.dbapi.port_get_all(host_id) port_list = self.dbapi.port_get_all(host_id)
ports = dict((p['interface_id'], p) for p in port_list) ports = dict((p['interface_id'], p) for p in port_list)
for interface in interface_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) return cutils.get_interface_os_ifname(interface, ifaces, ports)
def _find_local_mgmt_interface_vlan_id(self): def _find_local_mgmt_interface_vlan_id(self):
@ -1204,7 +1204,7 @@ class ConductorManager(service.PeriodicService):
host_id = self.get_my_host_id() host_id = self.get_my_host_id()
interface_list = self.dbapi.iinterface_get_all(host_id, expunge=True) interface_list = self.dbapi.iinterface_get_all(host_id, expunge=True)
for interface in interface_list: 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: if 'vlan_id' not in interface:
return 0 return 0
else: else:
@ -1820,7 +1820,7 @@ class ConductorManager(service.PeriodicService):
expunge=True) expunge=True)
for i in iinterfaces: for i in iinterfaces:
if i.networktype == constants.NETWORK_TYPE_MGMT: if constants.NETWORK_TYPE_MGMT in i.networktypelist:
break break
cloning = False cloning = False
@ -1923,7 +1923,6 @@ class ConductorManager(service.PeriodicService):
'imtu': mtu, 'imtu': mtu,
'iftype': 'ethernet', 'iftype': 'ethernet',
'ifclass': ifclass, 'ifclass': ifclass,
'networktype': networktype
} }
# autocreate untagged interface # autocreate untagged interface
@ -1940,6 +1939,7 @@ class ConductorManager(service.PeriodicService):
}) })
if networktype in [constants.NETWORK_TYPE_MGMT, if networktype in [constants.NETWORK_TYPE_MGMT,
constants.NETWORK_TYPE_PXEBOOT]: constants.NETWORK_TYPE_PXEBOOT]:
new_interface_networktype = networktype
network = self.dbapi.network_get_by_type(networktype) network = self.dbapi.network_get_by_type(networktype)
# create interface network association # create interface network association
ifnet_dict = { ifnet_dict = {
@ -1960,6 +1960,7 @@ class ConductorManager(service.PeriodicService):
if create_tagged_interface: if create_tagged_interface:
# autocreate tagged management interface # autocreate tagged management interface
network = self.dbapi.network_get_by_type(constants.NETWORK_TYPE_MGMT)
interface_dict = { interface_dict = {
'forihostid': ihost['id'], 'forihostid': ihost['id'],
'ifname': 'mgmt0', 'ifname': 'mgmt0',
@ -1967,7 +1968,6 @@ class ConductorManager(service.PeriodicService):
'imtu': constants.DEFAULT_MTU, 'imtu': constants.DEFAULT_MTU,
'iftype': 'vlan', 'iftype': 'vlan',
'ifclass': constants.INTERFACE_CLASS_PLATFORM, 'ifclass': constants.INTERFACE_CLASS_PLATFORM,
'networktype': constants.NETWORK_TYPE_MGMT,
'uses': [ifname], 'uses': [ifname],
'vlan_id': vlan_id, 'vlan_id': vlan_id,
} }
@ -1978,6 +1978,7 @@ class ConductorManager(service.PeriodicService):
new_interface = self.dbapi.iinterface_create( new_interface = self.dbapi.iinterface_create(
ihost['id'], interface_dict ihost['id'], interface_dict
) )
new_interface_networktype = constants.NETWORK_TYPE_MGMT
network = self.dbapi.network_get_by_type( network = self.dbapi.network_get_by_type(
constants.NETWORK_TYPE_MGMT constants.NETWORK_TYPE_MGMT
) )
@ -2057,7 +2058,7 @@ class ConductorManager(service.PeriodicService):
values = {'interface_id': new_interface['id']} values = {'interface_id': new_interface['id']}
try: try:
addr_name = cutils.format_address_name( 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) address = self.dbapi.address_get_by_name(addr_name)
self.dbapi.address_update(address['uuid'], values) self.dbapi.address_update(address['uuid'], values)
except exception.AddressNotFoundByName: except exception.AddressNotFoundByName:
@ -8449,7 +8450,8 @@ class ConductorManager(service.PeriodicService):
if nettype: if nettype:
iinterfaces[:] = [i for i in iinterfaces if iinterfaces[:] = [i for i in iinterfaces if
i.networktype == nettype] nettype in i.networktypelist]
return iinterfaces return iinterfaces
def mgmt_ip_set_by_ihost(self, def mgmt_ip_set_by_ihost(self,
@ -8604,13 +8606,12 @@ class ConductorManager(service.PeriodicService):
return ilvgs return ilvgs
def _add_port_to_list(self, interface_id, networktype, port_list): def _add_port_to_list(self, interface_id, port_list):
info = {} info = {}
ports = self.dbapi.port_get_all(interfaceid=interface_id) ports = self.dbapi.port_get_all(interfaceid=interface_id)
if ports: if ports:
info['name'] = ports[0]['name'] info['name'] = ports[0]['name']
info['numa_node'] = ports[0]['numa_node'] info['numa_node'] = ports[0]['numa_node']
info['networktype'] = networktype
if info not in port_list: if info not in port_list:
port_list.append(info) port_list.append(info)
return port_list return port_list
@ -8622,30 +8623,22 @@ class ConductorManager(service.PeriodicService):
info_list = [] info_list = []
interface_list = self.dbapi.iinterface_get_all(ihost_id, expunge=True) interface_list = self.dbapi.iinterface_get_all(ihost_id, expunge=True)
for interface in interface_list: for interface in interface_list:
ntype = interface['networktype'] if interface['ifclass'] == constants.INTERFACE_CLASS_PLATFORM:
if (ntype == constants.NETWORK_TYPE_CLUSTER_HOST or if interface['iftype'] == constants.INTERFACE_TYPE_VLAN or \
ntype == constants.NETWORK_TYPE_MGMT): interface['iftype'] == constants.INTERFACE_TYPE_AE:
if interface['iftype'] == 'vlan' or \
interface['iftype'] == 'ae':
for uses_if in interface['uses']: for uses_if in interface['uses']:
for i in interface_list: lower_iface = self.dbapi.iinterface_get(uses_if, ihost_id)
if i['ifname'] == str(uses_if): if lower_iface['iftype'] == constants.INTERFACE_TYPE_ETHERNET:
if i['iftype'] == 'ethernet': info_list = self._add_port_to_list(lower_iface['id'],
info_list = self._add_port_to_list(i['id'], info_list)
ntype, 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) info_list)
elif i['iftype'] == 'ae': elif interface['iftype'] == constants.INTERFACE_TYPE_ETHERNET:
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':
info_list = self._add_port_to_list(interface['id'], info_list = self._add_port_to_list(interface['id'],
ntype,
info_list) info_list)
LOG.info("platform_interfaces host_id=%s info_list=%s" % LOG.info("platform_interfaces host_id=%s info_list=%s" %

View File

@ -842,7 +842,6 @@ class Connection(object):
{ {
'uuid': uuidutils.generate_uuid(), 'uuid': uuidutils.generate_uuid(),
'ifname': 'bond1', 'ifname': 'bond1',
'networktype': constants.NETWORK_TYPE_DATA,
'aemode': 'balanced', 'aemode': 'balanced',
'schedpolicy': 'xor', 'schedpolicy': 'xor',
'txhashpolicy': 'L2', 'txhashpolicy': 'L2',
@ -934,7 +933,6 @@ class Connection(object):
{ {
'uuid': uuidutils.generate_uuid(), 'uuid': uuidutils.generate_uuid(),
'ifname': 'eth1', 'ifname': 'eth1',
'networktype': constants.NETWORK_TYPE_MGMT,
'extra': { ... }, 'extra': { ... },
} }
:returns: An EthernetInterface. :returns: An EthernetInterface.

View File

@ -2085,14 +2085,13 @@ class Connection(api.Connection):
query, models.ihost, [forihostid]) query, models.ihost, [forihostid])
return query.all() 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, '*') entity = with_polymorphic(models.Interfaces, '*')
query = model_query(entity) query = model_query(entity)
query = add_interface_filter(query, iinterface_id) query = add_interface_filter(query, iinterface_id)
if ihost is not None: if ihost is not None:
query = add_interface_filter_by_ihost(query, ihost) query = add_interface_filter_by_ihost(query, ihost)
if network is not None:
query = query.filter_by(networktype=network)
try: try:
result = query.one() result = query.one()
except NoResultFound: except NoResultFound:
@ -2106,7 +2105,7 @@ class Connection(api.Connection):
@objects.objectify(objects.interface) @objects.objectify(objects.interface)
def iinterface_get(self, iinterface_id, ihost=None, network=None): 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) @objects.objectify(objects.interface)
def iinterface_get_list(self, limit=None, marker=None, def iinterface_get_list(self, limit=None, marker=None,
@ -2155,16 +2154,6 @@ class Connection(api.Connection):
return _paginate_query(models.Interfaces, limit, marker, return _paginate_query(models.Interfaces, limit, marker,
sort_key, sort_dir, query) 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) @objects.objectify(objects.interface)
def iinterface_update(self, iinterface_id, values): def iinterface_update(self, iinterface_id, values):
with _session_for_write() as session: with _session_for_write() as session:
@ -2237,13 +2226,6 @@ class Connection(api.Connection):
if obj.id is None: if obj.id is None:
obj.id = temp_id 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: try:
session.add(obj) session.add(obj)
session.flush() session.flush()
@ -2318,8 +2300,6 @@ class Connection(api.Connection):
obj = self._interface_get(models.Interfaces, interface_id) obj = self._interface_get(models.Interfaces, interface_id)
for k, v in list(values.items()): for k, v in list(values.items()):
if k == 'networktype' and v == constants.NETWORK_TYPE_NONE:
v = None
if k == 'datanetworks' and v == 'none': if k == 'datanetworks' and v == 'none':
v = None v = None
if k == 'uses': if k == 'uses':
@ -4952,6 +4932,26 @@ class Connection(api.Connection):
limit, marker, limit, marker,
sort_key, sort_dir) 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): def address_destroy(self, address_uuid):
query = model_query(models.Addresses) query = model_query(models.Addresses)
query = add_identity_filter(query, address_uuid) query = add_identity_filter(query, address_uuid)

View File

@ -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.')

View File

@ -339,7 +339,6 @@ class Interfaces(Base):
ifname = Column(String(255)) ifname = Column(String(255))
ifclass = Column(String(255)) ifclass = Column(String(255))
networktype = Column(String(255))
ifcapabilities = Column(JSONEncodedDict) ifcapabilities = Column(JSONEncodedDict)
farend = Column(JSONEncodedDict) farend = Column(JSONEncodedDict)
sriov_numvfs = Column(Integer) sriov_numvfs = Column(Integer)

View File

@ -355,12 +355,10 @@ class NeutronHelm(openstack.OpenstackBaseHelm):
return ml2_config return ml2_config
def _is_data_network_type(self, iface): def _is_data_network_type(self, iface):
networktypelist = utils.get_network_type_list(iface) return iface.ifclass == constants.INTERFACE_CLASS_DATA
return bool(any(n in DATA_NETWORK_TYPES for n in networktypelist))
def _is_sriov_network_type(self, iface): def _is_sriov_network_type(self, iface):
networktypelist = utils.get_network_type_list(iface) return iface.ifclass == constants.INTERFACE_CLASS_PCI_SRIOV
return bool(any(n in SRIOV_NETWORK_TYPES for n in networktypelist))
def _get_interface_datanets(self, iface): def _get_interface_datanets(self, iface):
""" """

View File

@ -24,7 +24,6 @@ class Address(base.SysinvObject):
'forihostid': utils.int_or_none, 'forihostid': utils.int_or_none,
'interface_uuid': utils.uuid_or_none, 'interface_uuid': utils.uuid_or_none,
'pool_uuid': utils.uuid_or_none, 'pool_uuid': utils.uuid_or_none,
'networktype': utils.str_or_none,
'ifname': utils.str_or_none, 'ifname': utils.str_or_none,
'family': utils.int_or_none, 'family': utils.int_or_none,
'address': utils.ip_str_or_none(), 'address': utils.ip_str_or_none(),
@ -36,8 +35,7 @@ class Address(base.SysinvObject):
_foreign_fields = {'interface_uuid': 'interface:uuid', _foreign_fields = {'interface_uuid': 'interface:uuid',
'pool_uuid': 'address_pool:uuid', 'pool_uuid': 'address_pool:uuid',
'ifname': 'interface:ifname', 'ifname': 'interface:ifname',
'forihostid': 'interface:forihostid', 'forihostid': 'interface:forihostid'}
'networktype': 'interface:networktype'}
@base.remotable_classmethod @base.remotable_classmethod
def get_by_uuid(cls, context, uuid): def get_by_uuid(cls, context, uuid):

View File

@ -78,12 +78,12 @@ def get_host_uuid(field, db_server):
return host_uuid return host_uuid
def get_networks(field, db_object): def get_networktypes(field, db_object):
result = [] result = []
try: try:
if getattr(db_object, 'interface_networks', None): if getattr(db_object, 'interface_networks', None):
for entry in getattr(db_object, 'interface_networks', []): for entry in getattr(db_object, 'interface_networks', []):
id_str = str(entry.network_id) id_str = str(entry.network.type)
result.append(id_str) result.append(id_str)
except exc.DetachedInstanceError: except exc.DetachedInstanceError:
# instrument and return empty network # instrument and return empty network
@ -126,11 +126,10 @@ class Interface(base.SysinvObject):
'ifclass': utils.str_or_none, 'ifclass': utils.str_or_none,
'imac': utils.str_or_none, 'imac': utils.str_or_none,
'imtu': utils.int_or_none, 'imtu': utils.int_or_none,
'networktype': utils.str_or_none,
'aemode': utils.str_or_none, 'aemode': utils.str_or_none,
'schedpolicy': utils.str_or_none, 'schedpolicy': utils.str_or_none,
'txhashpolicy': 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, 'datanetworks': utils.list_of_strings_or_none,
'ifcapabilities': utils.dict_or_none, 'ifcapabilities': utils.dict_or_none,
@ -156,7 +155,7 @@ class Interface(base.SysinvObject):
'ipv4_pool': get_ipv4_address_pool, 'ipv4_pool': get_ipv4_address_pool,
'ipv6_pool': get_ipv6_address_pool, 'ipv6_pool': get_ipv6_address_pool,
'ihost_uuid': get_host_uuid, 'ihost_uuid': get_host_uuid,
'networks': get_networks, 'networktypelist': get_networktypes,
'datanetworks': get_datanetworks} 'datanetworks': get_datanetworks}
_optional_fields = ['aemode', 'txhashpolicy', 'schedpolicy', _optional_fields = ['aemode', 'txhashpolicy', 'schedpolicy',

View File

@ -24,7 +24,6 @@ class Route(base.SysinvObject):
'forihostid': utils.int_or_none, 'forihostid': utils.int_or_none,
'interface_uuid': utils.uuid_or_none, 'interface_uuid': utils.uuid_or_none,
'interface_id': int, 'interface_id': int,
'networktype': utils.str_or_none,
'ifname': utils.str_or_none, 'ifname': utils.str_or_none,
'family': utils.str_or_none, 'family': utils.str_or_none,
'network': utils.ip_str_or_none(), 'network': utils.ip_str_or_none(),
@ -36,8 +35,7 @@ class Route(base.SysinvObject):
_foreign_fields = {'interface_uuid': 'interface:uuid', _foreign_fields = {'interface_uuid': 'interface:uuid',
'interface_id': 'interface:id', 'interface_id': 'interface:id',
'ifname': 'interface:ifname', 'ifname': 'interface:ifname',
'forihostid': 'interface:forihostid', 'forihostid': 'interface:forihostid'}
'networktype': 'interface:networktype'}
@base.remotable_classmethod @base.remotable_classmethod
def get_by_uuid(cls, context, uuid): def get_by_uuid(cls, context, uuid):

View File

@ -99,8 +99,7 @@ def list_of_strings_or_none(val):
if not isinstance(val, list): if not isinstance(val, list):
raise ValueError(_('A list of strings is required here')) raise ValueError(_('A list of strings is required here'))
if not all([isinstance(x, six.string_types) for x in val]): if not all([isinstance(x, six.string_types) for x in val]):
raise ValueError(_('Invalid values found in list ' raise ValueError(_('Invalid values %s found in list (strings are required)') % val)
'(strings are required)'))
return val return val

View File

@ -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). layer interface (i.e., an interface that is used to terminate IP traffic).
""" """
LOG.debug("get_common_network_config %s %s network_id=%s" % 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, traffic_classifier = get_interface_traffic_classifier(context, iface,
network_id) network_id)
if traffic_classifier: 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 # setup an alias interface if there are multiple addresses assigned
# NOTE: DHCP will only operate over a non-alias interface # 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) ifname = "%s:%d" % (os_ifname, network_id)
else: else:
ifname = os_ifname ifname = os_ifname
@ -1012,8 +1012,9 @@ def generate_network_config(context, config, iface):
net_config['ifname']: format_network_config(net_config) net_config['ifname']: format_network_config(net_config)
}) })
for net_id in iface.networks: for net_type in iface.networktypelist:
net_config = get_interface_network_config(context, iface, int(net_id)) 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({ config[NETWORK_CONFIG_RESOURCE].update({
net_config['ifname']: format_network_config(net_config) net_config['ifname']: format_network_config(net_config)
}) })
@ -1060,8 +1061,7 @@ def find_interface_by_type(context, networktype):
mgmt, cluster-host, pxeboot, bmc). mgmt, cluster-host, pxeboot, bmc).
""" """
for ifname, iface in six.iteritems(context['interfaces']): for ifname, iface in six.iteritems(context['interfaces']):
for net_id in iface.networks: for net_type in iface.networktypelist:
net_type = find_networktype_by_network_id(context, int(net_id))
if networktype == net_type: if networktype == net_type:
return iface return iface

View File

@ -723,16 +723,12 @@ class PlatformPuppet(base.BasePuppet):
# Calculate the optimal NFS r/w size based on the network mtu based # Calculate the optimal NFS r/w size based on the network mtu based
# on the configured network(s) # on the configured network(s)
mtu = constants.DEFAULT_MTU 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) interfaces = self.dbapi.iinterface_get_by_ihost(host.uuid)
for interface in interfaces: for interface in interfaces:
if interface['ifclass'] == constants.INTERFACE_CLASS_PLATFORM: if interface['ifclass'] == constants.INTERFACE_CLASS_PLATFORM:
for net_id in interface['networks']: if constants.NETWORK_TYPE_MGMT in interface['networktypelist']:
if int(net_id) == network_id: mtu = interface.imtu
mtu = interface.imtu break
break
if self._get_address_by_name( if self._get_address_by_name(
constants.CONTROLLER_PLATFORM_NFS, constants.CONTROLLER_PLATFORM_NFS,

View File

@ -148,6 +148,7 @@ class InterfaceTestCase(base.FunctionalTest):
def setUp(self): def setUp(self):
super(InterfaceTestCase, self).setUp() super(InterfaceTestCase, self).setUp()
self.dbapi = db_api.get_instance() self.dbapi = db_api.get_instance()
p = mock.patch.object(api_if_v1, '_get_lower_interface_macs') p = mock.patch.object(api_if_v1, '_get_lower_interface_macs')
self.mock_lower_macs = p.start() self.mock_lower_macs = p.start()
self.mock_lower_macs.return_value = {'enp0s18': '08:00:27:8a:87:48', 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, def _create_ethernet(self, ifname=None, networktype=None, ifclass=None,
datanetworks=None, host=None, expect_errors=False): 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 interface_id = len(self.profile['interfaces']) + 1
networks = []
if not ifname: if not ifname:
ifname = (networktype or 'eth') + str(interface_id) ifname = (networktype or 'eth') + str(interface_id)
if not host: if not host:
host = self.controller host = self.controller
if all(network_type in constants.PLATFORM_NETWORK_TYPES if not ifclass and networktype in constants.PLATFORM_NETWORK_TYPES:
for network_type in networktypelist):
ifclass = constants.INTERFACE_CLASS_PLATFORM 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_id = len(self.profile['ports'])
port = dbutils.create_test_ethernet_port( port = dbutils.create_test_ethernet_port(
id=port_id, id=port_id,
@ -317,22 +302,23 @@ class InterfaceTestCase(base.FunctionalTest):
if not networktype: if not networktype:
interface = dbutils.create_test_interface(ifname=ifname, interface = dbutils.create_test_interface(ifname=ifname,
forihostid=host.id, forihostid=host.id,
ihost_uuid=host.uuid, ihost_uuid=host.uuid)
networks=networks)
interface_uuid = interface.uuid interface_uuid = interface.uuid
else: else:
interface = dbutils.post_get_test_interface( interface = dbutils.post_get_test_interface(
ifname=ifname, ifname=ifname,
ifclass=ifclass, ifclass=ifclass,
networktype=networktype,
networks=networks,
datanetworks=datanetworks, datanetworks=datanetworks,
forihostid=host.id, ihost_uuid=host.uuid) forihostid=host.id, ihost_uuid=host.uuid)
response = self._post_and_check(interface, expect_errors) response = self._post_and_check(interface, expect_errors)
if expect_errors is False: if expect_errors is False:
interface_uuid = response.json['uuid'] interface_uuid = response.json['uuid']
interface['uuid'] = interface_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['interfaces'].append(interface)
self.profile['ports'].append(port) self.profile['ports'].append(port)
@ -341,11 +327,6 @@ class InterfaceTestCase(base.FunctionalTest):
def _create_bond(self, ifname, networktype=None, ifclass=None, def _create_bond(self, ifname, networktype=None, ifclass=None,
datanetworks=None, host=None, expect_errors=False): datanetworks=None, host=None, expect_errors=False):
if not isinstance(networktype, list):
networktypelist = [networktype]
else:
networktypelist = networktype
networktype = ','.join(networktype)
if not host: if not host:
host = self.controller host = self.controller
port1, iface1 = self._create_ethernet(host=host) port1, iface1 = self._create_ethernet(host=host)
@ -353,26 +334,13 @@ class InterfaceTestCase(base.FunctionalTest):
interface_id = len(self.profile['interfaces']) interface_id = len(self.profile['interfaces'])
if not ifname: if not ifname:
ifname = (networktype or 'eth') + str(interface_id) ifname = (networktype or 'eth') + str(interface_id)
networks = [] if not ifclass and networktype in constants.PLATFORM_NETWORK_TYPES:
if all(network_type in constants.PLATFORM_NETWORK_TYPES
for network_type in networktypelist):
ifclass = constants.INTERFACE_CLASS_PLATFORM 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( interface = dbutils.post_get_test_interface(
id=interface_id, id=interface_id,
ifname=ifname, ifname=ifname,
iftype=constants.INTERFACE_TYPE_AE, iftype=constants.INTERFACE_TYPE_AE,
ifclass=ifclass, ifclass=ifclass,
networktype=networktype,
networks=networks,
uses=[iface1['ifname'], iface2['ifname']], uses=[iface1['ifname'], iface2['ifname']],
txhashpolicy='layer2', txhashpolicy='layer2',
datanetworks=datanetworks, datanetworks=datanetworks,
@ -403,42 +371,30 @@ class InterfaceTestCase(base.FunctionalTest):
def _create_vlan(self, ifname, networktype, ifclass, vlan_id, def _create_vlan(self, ifname, networktype, ifclass, vlan_id,
lower_iface=None, datanetworks=None, host=None, lower_iface=None, datanetworks=None, host=None,
expect_errors=False): expect_errors=False):
if not isinstance(networktype, list):
networktypelist = [networktype]
else:
networktypelist = networktype
networktype = ','.join(networktype)
if not host: if not host:
host = self.controller host = self.controller
if not lower_iface: if not lower_iface:
lower_port, lower_iface = self._create_ethernet(host=host) lower_port, lower_iface = self._create_ethernet(host=host)
if not ifname: if not ifname:
ifname = 'vlan' + str(vlan_id) ifname = 'vlan' + str(vlan_id)
networks = [] if not ifclass and networktype in constants.PLATFORM_NETWORK_TYPES:
if all(network_type in constants.PLATFORM_NETWORK_TYPES
for network_type in networktypelist):
ifclass = constants.INTERFACE_CLASS_PLATFORM 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( interface = dbutils.post_get_test_interface(
ifname=ifname, ifname=ifname,
iftype=constants.INTERFACE_TYPE_VLAN, iftype=constants.INTERFACE_TYPE_VLAN,
ifclass=ifclass, ifclass=ifclass,
networktype=networktype,
networks=networks,
vlan_id=vlan_id, vlan_id=vlan_id,
uses=[lower_iface['ifname']], uses=[lower_iface['ifname']],
datanetworks=datanetworks, datanetworks=datanetworks,
forihostid=host.id, ihost_uuid=host.uuid) forihostid=host.id, ihost_uuid=host.uuid)
response = self._post_and_check(interface, expect_errors)
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) self.profile['interfaces'].append(interface)
return interface return interface
@ -1131,7 +1087,6 @@ class TestPatch(InterfaceTestCase):
sriov_vf_driver='i40evf') sriov_vf_driver='i40evf')
response = self.patch_dict_json( response = self.patch_dict_json(
'%s' % self._get_path(interface['uuid']), '%s' % self._get_path(interface['uuid']),
networktype=constants.NETWORK_TYPE_PCI_SRIOV,
ifclass=constants.INTERFACE_CLASS_PCI_SRIOV, ifclass=constants.INTERFACE_CLASS_PCI_SRIOV,
sriov_numvfs=1, sriov_numvfs=1,
sriov_vf_driver=vf_driver, sriov_vf_driver=vf_driver,
@ -1174,12 +1129,6 @@ class TestPost(InterfaceTestCase):
self._create_host(constants.WORKER, admin=constants.ADMIN_LOCKED) self._create_host(constants.WORKER, admin=constants.ADMIN_LOCKED)
self._create_datanetworks() 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 # Expected error: The pci-passthrough, pci-sriov network types are only
# valid on Ethernet interfaces # valid on Ethernet interfaces
def test_invalid_iftype_for_pci_network_type(self): def test_invalid_iftype_for_pci_network_type(self):
@ -1237,8 +1186,6 @@ class TestPost(InterfaceTestCase):
ndict = dbutils.post_get_test_interface( ndict = dbutils.post_get_test_interface(
ihost_uuid=self.controller.uuid, ihost_uuid=self.controller.uuid,
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_MGMT,
networks=['1'],
ifclass=constants.INTERFACE_CLASS_PLATFORM, ifclass=constants.INTERFACE_CLASS_PLATFORM,
iftype=constants.INTERFACE_TYPE_ETHERNET, iftype=constants.INTERFACE_TYPE_ETHERNET,
ipv4_mode=constants.IPV4_POOL, ipv4_mode=constants.IPV4_POOL,
@ -1251,7 +1198,6 @@ class TestPost(InterfaceTestCase):
ndict = dbutils.post_get_test_interface( ndict = dbutils.post_get_test_interface(
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_PCI_PASSTHROUGH,
ifclass=constants.INTERFACE_CLASS_PCI_PASSTHROUGH, ifclass=constants.INTERFACE_CLASS_PCI_PASSTHROUGH,
iftype=constants.INTERFACE_TYPE_ETHERNET, iftype=constants.INTERFACE_TYPE_ETHERNET,
ipv4_mode=constants.IPV4_STATIC, ipv4_mode=constants.IPV4_STATIC,
@ -1266,8 +1212,6 @@ class TestPost(InterfaceTestCase):
ndict = dbutils.post_get_test_interface( ndict = dbutils.post_get_test_interface(
ihost_uuid=self.controller.uuid, ihost_uuid=self.controller.uuid,
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_CLUSTER_HOST,
networks=['2'],
ifclass=constants.INTERFACE_CLASS_PLATFORM, ifclass=constants.INTERFACE_CLASS_PLATFORM,
iftype=constants.INTERFACE_TYPE_ETHERNET, iftype=constants.INTERFACE_TYPE_ETHERNET,
ipv4_mode=constants.IPV4_DISABLED, ipv4_mode=constants.IPV4_DISABLED,
@ -1281,8 +1225,6 @@ class TestPost(InterfaceTestCase):
ndict = dbutils.post_get_test_interface( ndict = dbutils.post_get_test_interface(
ihost_uuid=self.controller.uuid, ihost_uuid=self.controller.uuid,
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_MGMT,
networks=['1'],
ifclass=constants.INTERFACE_CLASS_PLATFORM, ifclass=constants.INTERFACE_CLASS_PLATFORM,
iftype=constants.INTERFACE_TYPE_ETHERNET, iftype=constants.INTERFACE_TYPE_ETHERNET,
ipv4_mode=constants.IPV4_DISABLED, ipv4_mode=constants.IPV4_DISABLED,
@ -1296,7 +1238,6 @@ class TestPost(InterfaceTestCase):
ihost_uuid=self.controller.uuid, ihost_uuid=self.controller.uuid,
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_MGMT, networktype=constants.NETWORK_TYPE_MGMT,
networks=['1'],
ifclass=constants.INTERFACE_CLASS_PLATFORM, ifclass=constants.INTERFACE_CLASS_PLATFORM,
iftype=constants.INTERFACE_TYPE_ETHERNET, iftype=constants.INTERFACE_TYPE_ETHERNET,
ipv6_mode=constants.IPV6_DISABLED, ipv6_mode=constants.IPV6_DISABLED,
@ -1308,8 +1249,6 @@ class TestPost(InterfaceTestCase):
ndict = dbutils.post_get_test_interface( ndict = dbutils.post_get_test_interface(
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_MGMT,
networks=['1'],
ifclass=constants.INTERFACE_CLASS_PLATFORM, ifclass=constants.INTERFACE_CLASS_PLATFORM,
iftype=constants.INTERFACE_TYPE_ETHERNET, iftype=constants.INTERFACE_TYPE_ETHERNET,
ipv4_mode=constants.IPV4_POOL, ipv4_mode=constants.IPV4_POOL,
@ -1321,8 +1260,6 @@ class TestPost(InterfaceTestCase):
ndict = dbutils.post_get_test_interface( ndict = dbutils.post_get_test_interface(
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_MGMT,
networks=['1'],
ifclass=constants.INTERFACE_CLASS_PLATFORM, ifclass=constants.INTERFACE_CLASS_PLATFORM,
iftype=constants.INTERFACE_TYPE_ETHERNET, iftype=constants.INTERFACE_TYPE_ETHERNET,
ipv4_mode=constants.IPV4_POOL, ipv4_mode=constants.IPV4_POOL,
@ -1335,8 +1272,6 @@ class TestPost(InterfaceTestCase):
ndict = dbutils.post_get_test_interface( ndict = dbutils.post_get_test_interface(
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_MGMT,
networks=['1'],
ifclass=constants.INTERFACE_CLASS_PLATFORM, ifclass=constants.INTERFACE_CLASS_PLATFORM,
iftype=constants.INTERFACE_TYPE_ETHERNET, iftype=constants.INTERFACE_TYPE_ETHERNET,
ipv4_mode=constants.IPV4_POOL, ipv4_mode=constants.IPV4_POOL,
@ -1350,8 +1285,6 @@ class TestPost(InterfaceTestCase):
ndict = dbutils.post_get_test_interface( ndict = dbutils.post_get_test_interface(
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_MGMT,
networks=['1'],
ifclass=constants.INTERFACE_CLASS_PLATFORM, ifclass=constants.INTERFACE_CLASS_PLATFORM,
iftype=constants.INTERFACE_TYPE_ETHERNET, iftype=constants.INTERFACE_TYPE_ETHERNET,
ipv4_mode=constants.IPV4_POOL, ipv4_mode=constants.IPV4_POOL,
@ -1367,7 +1300,6 @@ class TestPost(InterfaceTestCase):
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
datanetworks='group0-data0', datanetworks='group0-data0',
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_DATA,
ifclass=constants.INTERFACE_CLASS_DATA, ifclass=constants.INTERFACE_CLASS_DATA,
iftype='AE', iftype='AE',
aemode='active_standby', aemode='active_standby',
@ -1381,7 +1313,6 @@ class TestPost(InterfaceTestCase):
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
datanetworks='group0-data0', datanetworks='group0-data0',
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_DATA,
ifclass=constants.INTERFACE_CLASS_DATA, ifclass=constants.INTERFACE_CLASS_DATA,
iftype=constants.INTERFACE_TYPE_AE, iftype=constants.INTERFACE_TYPE_AE,
aemode='active_standby', aemode='active_standby',
@ -1394,7 +1325,6 @@ class TestPost(InterfaceTestCase):
ndict = dbutils.post_get_test_interface( ndict = dbutils.post_get_test_interface(
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_DATA,
ifclass=constants.INTERFACE_CLASS_DATA, ifclass=constants.INTERFACE_CLASS_DATA,
iftype=constants.INTERFACE_TYPE_AE, iftype=constants.INTERFACE_TYPE_AE,
aemode='balanced', aemode='balanced',
@ -1408,7 +1338,6 @@ class TestPost(InterfaceTestCase):
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
datanetworks='group0-data0', datanetworks='group0-data0',
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_DATA,
ifclass=constants.INTERFACE_CLASS_DATA, ifclass=constants.INTERFACE_CLASS_DATA,
iftype=constants.INTERFACE_TYPE_AE, iftype=constants.INTERFACE_TYPE_AE,
aemode='802.3ad', aemode='802.3ad',
@ -1419,28 +1348,12 @@ class TestPost(InterfaceTestCase):
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
datanetworks='group0-data0', datanetworks='group0-data0',
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_DATA,
ifclass=constants.INTERFACE_CLASS_DATA, ifclass=constants.INTERFACE_CLASS_DATA,
iftype=constants.INTERFACE_TYPE_AE, iftype=constants.INTERFACE_TYPE_AE,
aemode='balanced', aemode='balanced',
txhashpolicy=None) txhashpolicy=None)
self._post_and_check_failure(ndict) 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 # Device interface with network type ___, and interface type
# 'aggregated ethernet' must be in mode 'active_standby' or 'balanced' or # 'aggregated ethernet' must be in mode 'active_standby' or 'balanced' or
# '802.3ad'. # '802.3ad'.
@ -1449,57 +1362,26 @@ class TestPost(InterfaceTestCase):
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
datanetworks='group0-data0', datanetworks='group0-data0',
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_DATA,
ifclass=constants.INTERFACE_CLASS_DATA, ifclass=constants.INTERFACE_CLASS_DATA,
iftype=constants.INTERFACE_TYPE_AE, iftype=constants.INTERFACE_TYPE_AE,
aemode='bad_aemode', aemode='bad_aemode',
txhashpolicy='layer2') txhashpolicy='layer2')
self._post_and_check_failure(ndict) self._post_and_check_failure(ndict)
def test_aemode_invalid_oam(self): def test_aemode_invalid_platform(self):
ndict = dbutils.post_get_test_interface( ndict = dbutils.post_get_test_interface(
ihost_uuid=self.controller.uuid, ihost_uuid=self.controller.uuid,
ifname='name', ifname='name',
networktype=constants.NETWORK_TYPE_OAM,
networks=['3'],
ifclass=constants.INTERFACE_CLASS_PLATFORM, ifclass=constants.INTERFACE_CLASS_PLATFORM,
iftype=constants.INTERFACE_TYPE_AE, iftype=constants.INTERFACE_TYPE_AE,
aemode='bad_aemode', aemode='bad_aemode',
txhashpolicy='layer2') txhashpolicy='layer2')
self._post_and_check_failure(ndict) 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): def test_setting_mgmt_mtu_allowed(self):
ndict = dbutils.post_get_test_interface( ndict = dbutils.post_get_test_interface(
ihost_uuid=self.controller.uuid, ihost_uuid=self.controller.uuid,
ifname='mgmt0', ifname='mgmt0',
networktype=constants.NETWORK_TYPE_MGMT,
networks=['1'],
ifclass=constants.INTERFACE_CLASS_PLATFORM, ifclass=constants.INTERFACE_CLASS_PLATFORM,
iftype=constants.INTERFACE_TYPE_ETHERNET, iftype=constants.INTERFACE_TYPE_ETHERNET,
imtu=1600) imtu=1600)
@ -1509,8 +1391,6 @@ class TestPost(InterfaceTestCase):
ndict = dbutils.post_get_test_interface( ndict = dbutils.post_get_test_interface(
ihost_uuid=self.controller.uuid, ihost_uuid=self.controller.uuid,
ifname='cluster0', ifname='cluster0',
networktype=constants.NETWORK_TYPE_CLUSTER_HOST,
networks=['2'],
ifclass=constants.INTERFACE_CLASS_PLATFORM, ifclass=constants.INTERFACE_CLASS_PLATFORM,
iftype=constants.INTERFACE_TYPE_ETHERNET, iftype=constants.INTERFACE_TYPE_ETHERNET,
imtu=1600) imtu=1600)
@ -1529,7 +1409,6 @@ class TestPost(InterfaceTestCase):
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
datanetworks='group0-ext1', datanetworks='group0-ext1',
ifname='bond1', ifname='bond1',
networktype=constants.NETWORK_TYPE_DATA,
ifclass=constants.INTERFACE_CLASS_DATA, ifclass=constants.INTERFACE_CLASS_DATA,
iftype=constants.INTERFACE_TYPE_AE, iftype=constants.INTERFACE_TYPE_AE,
aemode='balanced', aemode='balanced',
@ -1559,7 +1438,6 @@ class TestPost(InterfaceTestCase):
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
datanetworks='group0-ext1', datanetworks='group0-ext1',
ifname='bond0', ifname='bond0',
networktype=constants.NETWORK_TYPE_DATA,
ifclass=constants.INTERFACE_CLASS_DATA, ifclass=constants.INTERFACE_CLASS_DATA,
iftype=constants.INTERFACE_TYPE_AE, iftype=constants.INTERFACE_TYPE_AE,
aemode='balanced', aemode='balanced',
@ -1579,7 +1457,6 @@ class TestPost(InterfaceTestCase):
ihost_uuid=self.worker.uuid, ihost_uuid=self.worker.uuid,
datanetworks='group0-ext1', datanetworks='group0-ext1',
ifname='bond1', ifname='bond1',
networktype=constants.NETWORK_TYPE_DATA,
ifclass=constants.INTERFACE_CLASS_DATA, ifclass=constants.INTERFACE_CLASS_DATA,
iftype=constants.INTERFACE_TYPE_VLAN, iftype=constants.INTERFACE_TYPE_VLAN,
aemode='balanced', aemode='balanced',
@ -1658,7 +1535,9 @@ class TestPost(InterfaceTestCase):
def test_create_invalid_oam_data_ethernet(self): def test_create_invalid_oam_data_ethernet(self):
self._create_ethernet('shared', self._create_ethernet('shared',
networktype=constants.NETWORK_TYPE_DATA, networktype=constants.NETWORK_TYPE_DATA,
ifclass=constants.INTERFACE_CLASS_PLATFORM, ifclass=constants.INTERFACE_CLASS_DATA,
datanetworks='group0-data0',
host=self.controller,
expect_errors=True) expect_errors=True)
# Expected message: # Expected message:
@ -1715,13 +1594,6 @@ class TestCpePost(InterfaceTestCase):
lower_iface=iface, datanetworks='group0-ext1', lower_iface=iface, datanetworks='group0-ext1',
expect_errors=True) 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 ___ # Expected message: VLAN id ___ already in use on interface ___
def test_create_vlan_id_already_in_use(self): def test_create_vlan_id_already_in_use(self):
port, iface = self._create_ethernet('eth1', constants.NETWORK_TYPE_NONE) port, iface = self._create_ethernet('eth1', constants.NETWORK_TYPE_NONE)
@ -1733,13 +1605,6 @@ class TestCpePost(InterfaceTestCase):
lower_iface=iface, datanetworks='group0-ext1', lower_iface=iface, datanetworks='group0-ext1',
expect_errors=True) 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 # Expected error: VLAN based provider network group0-data0 cannot be
# assigned to a VLAN interface # assigned to a VLAN interface
def test_create_invalid_vlan_with_vlan_data_network(self): 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.ANY, mock.ANY, vlans=mock.ANY, test=mock.ANY)
mock_iinterface_destroy.assert_called_once_with(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 # Expected error: Data interface data0 is already attached to this
# Data Network: group0-data0. # Data Network: group0-data0.
def test_create_invalid_data_network_used(self): def test_create_invalid_data_network_used(self):
@ -1819,13 +1678,6 @@ class TestCpePatch(InterfaceTestCase):
admin=constants.ADMIN_LOCKED) admin=constants.ADMIN_LOCKED)
self._create_datanetworks() 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") @testtools.skip("deprecate neutron bind interface")
@mock.patch.object(rpcapi.ConductorAPI, 'neutron_bind_interface') @mock.patch.object(rpcapi.ConductorAPI, 'neutron_bind_interface')
def test_patch_neutron_bind_failed(self, mock_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) constants.NETWORK_TYPE_NONE)
response = self.patch_dict_json( response = self.patch_dict_json(
'%s' % self._get_path(interface['uuid']), '%s' % self._get_path(interface['uuid']),
networktype=constants.NETWORK_TYPE_PCI_SRIOV,
ifclass=constants.INTERFACE_CLASS_PCI_SRIOV, ifclass=constants.INTERFACE_CLASS_PCI_SRIOV,
expect_errors=True) expect_errors=True)
self.assertEqual(http_client.BAD_REQUEST, response.status_int) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
self.assertEqual('application/json', response.content_type) 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 # Expected error: SR-IOV can't be configured on this interface
def test_invalid_sriov_totalvfs_zero(self): def test_invalid_sriov_totalvfs_zero(self):
interface = dbutils.create_test_interface(forihostid='1') 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) pciaddr='0000:00:00.11', dev_id=0, sriov_totalvfs=0, sriov_numvfs=1)
response = self.patch_dict_json( response = self.patch_dict_json(
'%s' % self._get_path(interface['uuid']), '%s' % self._get_path(interface['uuid']),
networktype=constants.NETWORK_TYPE_PCI_SRIOV,
ifclass=constants.INTERFACE_CLASS_PCI_SRIOV, ifclass=constants.INTERFACE_CLASS_PCI_SRIOV,
sriov_numvfs=1, sriov_numvfs=1,
expect_errors=True) expect_errors=True)

View File

@ -7,8 +7,10 @@
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
import mock
from six.moves import http_client from six.moves import http_client
from sysinv.api.controllers.v1 import interface as api_if_v1
from sysinv.common import constants from sysinv.common import constants
from sysinv.tests.api import base from sysinv.tests.api import base
from sysinv.tests.db import utils as dbutils from sysinv.tests.db import utils as dbutils
@ -17,6 +19,13 @@ from sysinv.tests.db import utils as dbutils
class InterfaceNetworkTestCase(base.FunctionalTest): class InterfaceNetworkTestCase(base.FunctionalTest):
def setUp(self): def setUp(self):
super(InterfaceNetworkTestCase, self).setUp() 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.system = dbutils.create_test_isystem()
self.load = dbutils.create_test_load() self.load = dbutils.create_test_load()
self.controller = dbutils.create_test_ihost( self.controller = dbutils.create_test_ihost(
@ -76,6 +85,12 @@ class InterfaceNetworkTestCase(base.FunctionalTest):
name='oam', name='oam',
type=constants.NETWORK_TYPE_OAM, type=constants.NETWORK_TYPE_OAM,
address_pool_id=self.address_pool_oam.id) 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( self.address_pool_pxeboot = dbutils.create_test_address_pool(
id=4, id=4,
network='192.168.202.0', network='192.168.202.0',
@ -86,6 +101,12 @@ class InterfaceNetworkTestCase(base.FunctionalTest):
id=4, id=4,
type=constants.NETWORK_TYPE_PXEBOOT, type=constants.NETWORK_TYPE_PXEBOOT,
address_pool_id=self.address_pool_pxeboot.id) 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): def _post_and_check(self, ndict, expect_errors=False):
response = self.post_json('%s' % self._get_path(), ndict, 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( worker_interface_network = dbutils.post_get_test_interface_network(
interface_uuid=worker_interface.uuid, interface_uuid=worker_interface.uuid,
network_uuid=self.oam_network.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): def test_create_pxeboot_interface_network(self):
controller_interface = dbutils.create_test_interface( controller_interface = dbutils.create_test_interface(
@ -290,3 +311,68 @@ class InterfaceNetworkCreateTestCase(InterfaceNetworkTestCase):
interface_uuid=worker_interface.uuid, interface_uuid=worker_interface.uuid,
network_uuid=self.mgmt_network.uuid) network_uuid=self.mgmt_network.uuid)
self._post_and_check(worker_interface_network, expect_errors=True) 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)

View File

@ -674,8 +674,6 @@ def post_get_test_interface(**kw):
'imac': kw.get('imac', '11:22:33:44:55:66'), 'imac': kw.get('imac', '11:22:33:44:55:66'),
'imtu': kw.get('imtu', 1500), 'imtu': kw.get('imtu', 1500),
'ifclass': kw.get("ifclass"), 'ifclass': kw.get("ifclass"),
'networktype': kw.get('networktype'),
'networks': kw.get('networks', []),
'aemode': kw.get('aemode', 'balanced'), 'aemode': kw.get('aemode', 'balanced'),
'txhashpolicy': kw.get('txhashpolicy', 'layer2'), 'txhashpolicy': kw.get('txhashpolicy', 'layer2'),
'datanetworks': datanetworks_list, 'datanetworks': datanetworks_list,
@ -710,8 +708,7 @@ def get_test_interface(**kw):
'imac': kw.get('imac', '11:22:33:44:55:66'), 'imac': kw.get('imac', '11:22:33:44:55:66'),
'imtu': kw.get('imtu', 1500), 'imtu': kw.get('imtu', 1500),
'ifclass': kw.get('ifclass', None), 'ifclass': kw.get('ifclass', None),
'networktype': kw.get('networktype'), 'networktypelist': kw.get('networktypelist', []),
'networks': kw.get('networks', []),
'aemode': kw.get('aemode'), 'aemode': kw.get('aemode'),
'txhashpolicy': kw.get('txhashpolicy', None), 'txhashpolicy': kw.get('txhashpolicy', None),
'datanetworks': datanetworks_list, 'datanetworks': datanetworks_list,
@ -737,6 +734,7 @@ def create_test_interface(**kw):
interface = get_test_interface(**kw) interface = get_test_interface(**kw)
datanetworks_list = interface.get('datanetworks') or [] datanetworks_list = interface.get('datanetworks') or []
networks_list = interface.get('networks') or []
# Let DB generate ID if it isn't specified explicitly # Let DB generate ID if it isn't specified explicitly
if 'id' not in kw: if 'id' not in kw:
@ -745,10 +743,22 @@ def create_test_interface(**kw):
if 'datanetworks' in interface: if 'datanetworks' in interface:
del interface['datanetworks'] del interface['datanetworks']
if 'networks' in interface:
del interface['networks']
dbapi = db_api.get_instance() dbapi = db_api.get_instance()
forihostid = kw.get('forihostid') forihostid = kw.get('forihostid')
interface_obj = dbapi.iinterface_create(forihostid, interface) 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 # assign the interface to the datanetwork
for datanetwork in datanetworks_list: for datanetwork in datanetworks_list:
if not datanetwork: if not datanetwork:

View File

@ -64,20 +64,21 @@ class BaseTestCase(dbbase.DbTestCase):
super(BaseTestCase, self).assertEqual(expected, observed, message) super(BaseTestCase, self).assertEqual(expected, observed, message)
def _setup_address_and_routes(self, iface): def _setup_address_and_routes(self, iface):
networktype = utils.get_primary_network_type(iface) if not iface['ifclass'] or iface['ifclass'] == constants.INTERFACE_CLASS_NONE:
if networktype in NETWORKTYPES_WITH_V4_ADDRESSES: return None
if iface['ifclass'] == constants.INTERFACE_CLASS_PLATFORM:
address = {'interface_id': iface['id'], address = {'interface_id': iface['id'],
'family': 4, 'family': 4,
'prefix': 24, 'prefix': 24,
'address': '192.168.1.2'} 'address': '192.168.1.2'}
self.addresses.append(dbutils.create_test_address(**address)) 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'], address = {'interface_id': iface['id'],
'family': 6, 'family': 6,
'prefix': 64, 'prefix': 64,
'address': '2001:1::2'} 'address': '2001:1::2'}
self.addresses.append(dbutils.create_test_address(**address)) 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'], route = {'interface_id': iface['id'],
'family': 4, 'family': 4,
'prefix': 24, 'prefix': 24,
@ -92,7 +93,7 @@ class BaseTestCase(dbbase.DbTestCase):
'gateway': '192.168.1.1', 'gateway': '192.168.1.1',
'metric': '1'} 'metric': '1'}
self.routes.append(dbutils.create_test_route(**route)) 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'], route = {'interface_id': iface['id'],
'family': 6, 'family': 6,
'prefix': 64, 'prefix': 64,