From 6169eb0882e5acd87e293b3adfbb8e79b7f8a17b Mon Sep 17 00:00:00 2001 From: Karthik S Date: Mon, 5 Nov 2018 00:42:47 -0500 Subject: [PATCH] Sample templates for linux_bond, ovs_bond, dpdkbond using VFs 1. Added sample templates and testcases for linux_bond, ovs_bond, dpdkbond using VFs. 2. Set the default values for certain sriov_vf attributes when its a member of ovs_bond, ovs_bridge 3. Set the default value of promisc for sriov_pf Change-Id: Icdd2a077f6a996f409bbb2d82b0958b676bc5411 (cherry picked from commit 13d42df43144922d32491ff963321120dfa7c8ab) --- etc/os-net-config/samples/sriov_pf.json | 77 +++++- etc/os-net-config/samples/sriov_pf.yaml | 92 +++++-- .../samples/sriov_pf_ovs_dpdk.json | 57 ++++- .../samples/sriov_pf_ovs_dpdk.yaml | 66 ++++- os_net_config/objects.py | 77 +++++- os_net_config/schema.yaml | 1 + os_net_config/tests/test_cli.py | 20 ++ os_net_config/tests/test_objects.py | 234 +++++++++++++++++- os_net_config/utils.py | 2 +- 9 files changed, 578 insertions(+), 48 deletions(-) diff --git a/etc/os-net-config/samples/sriov_pf.json b/etc/os-net-config/samples/sriov_pf.json index f3d0f155..fd1ac152 100644 --- a/etc/os-net-config/samples/sriov_pf.json +++ b/etc/os-net-config/samples/sriov_pf.json @@ -5,7 +5,14 @@ "name": "p2p1", "numvfs": 10, "use_dhcp": false, - "promisc": on + "promisc": true + }, + { + "type": "sriov_pf", + "name": "p2p2", + "numvfs": 10, + "use_dhcp": false, + "promisc": true }, { "type": "sriov_vf", @@ -21,7 +28,7 @@ "spoofcheck": true, "macaddr": "00:78:90:80:cc:30", "trust": true, - "state": auto, + "state": "auto", "promisc": false }, { @@ -35,11 +42,75 @@ "device": "p2p1", "promisc": true, "vlan_id": 116, - "qos": 2, + "qos": 3, "spoofcheck": false } ], "use_dhcp": true + }, + { + "type": "ovs_bridge", + "name": "br-bond", + "use_dhcp": true, + "members": [ + { + "type": "ovs_bond", + "name": "bond_vf", + "ovs_options": "bond_mode=active-backup", + "members": [ + { + "type": "sriov_vf", + "device": "p2p1", + "vfid": 2, + "vlan_id": 112, + "qos": 4, + "primary": true, + "trust": true, + "promisc": true, + "spoofcheck": false + }, + { + "type": "sriov_vf", + "device": "p2p2", + "vfid": 2, + "vlan_id": 112, + "qos": 4, + "trust": true, + "promisc": true, + "spoofcheck": false + } + ] + } + ] + }, + { + "type": "linux_bond", + "name": "bond_lnx", + "use_dhcp": true, + "bonding_options": "mode=active-backup", + "members": [ + { + "type": "sriov_vf", + "device": "p2p1", + "vfid": 3, + "vlan_id": 113, + "qos": 5, + "spoofcheck": true, + "trust": true, + "promisc": false, + "primary": true, + }, + { + "type": "sriov_vf", + "device": "p2p2", + "vfid": 3, + "vlan_id": 113, + "qos": 5, + "spoofcheck": true, + "trust": true, + "promisc": false + } + ] } ] } diff --git a/etc/os-net-config/samples/sriov_pf.yaml b/etc/os-net-config/samples/sriov_pf.yaml index 28c1c8d7..b964144e 100644 --- a/etc/os-net-config/samples/sriov_pf.yaml +++ b/etc/os-net-config/samples/sriov_pf.yaml @@ -1,5 +1,3 @@ - - network_config: # sriov_pf type shall be used to configure the PF's of NICs. # The numvfs configured for the PF's shall be set on the sriov_numvfs of the @@ -14,9 +12,15 @@ network_config: # Dont set the IP address on the PF use_dhcp: false # Allow all the traffic received. It might be needed when one of its VF - # is attached to a ovs bridge - promisc: on + # is attached to a ovs bridge. Default: true + promisc: true + - + type: sriov_pf + name: p2p2 + numvfs: 10 + use_dhcp: false + promisc: true # sriov_vf type shall be used to configure the VF's of NICs. # It requires the PF devices to be configured via sriov_pf types # "name" parameter is not required for VF's. It'll be derived from the VF id @@ -43,12 +47,12 @@ network_config: # MAC spoofing is a method of altering the MAC address # The MAC address anti-spoofing when enabled protects from malicious MAC # address spoofing. It should be disabled for 802.3ad bonds. - spoofcheck: on + spoofcheck: true # Change the MAC address of the VF. macaddr: 00:78:90:80:cc:30 # Enabling trust (true) for VF allows enabling multicast/promiscuous mode - # on the VF. The default value is off. - trust: on + # on the VF. The default value is false. + trust: true # Link state seen by the VF # - auto: a reflection of the PF link state (default) # - enable: lets the VF to communicate with other VFs on this host even @@ -60,8 +64,8 @@ network_config: # traffic received in the physical port. Note that all traffic that has # destination mac that does not match any of the VFs/PF MAC addresses is # referred to as unmatched traffic. - # The default value is off. Requires the enabling of trust mode - promisc: off + # The default value is false. Requires the enabling of trust mode + promisc: false # Attach a SR-IOV VF to a ovs bridge - type: ovs_bridge name: br-vfs @@ -77,9 +81,67 @@ network_config: vlan_id: 116 # Optional field, but requires vlan_id qos: 3 - # Set trust to 'on' when attaching to ovs_bridge - trust: on - # Set promisc to 'on' when attaching to ovs_bridge - promisc: on - # Set spoofcheck to 'off' when attaching to ovs_bridge - spoofcheck: off + # For OVS Bridge, the default value is true (recommended) + trust: true + # For OVS Bridge, the default value is true (recommended) + promisc: true + # For OVS Bridge, the default value is false (recommended) + spoofcheck: false + - type: ovs_bridge + name: br-bond + use_dhcp: true + members: + - + type: ovs_bond + name: bond_vf + ovs_options: "bond_mode=active-backup" + members: + - + type: sriov_vf + device: p2p1 + vfid: 2 + vlan_id: 112 + qos: 4 + primary: true + # For OVS Bond, the default value is true (recommended) + trust: true + # For OVS Bond, the default value is true (recommended) + promisc: true + # For OVS Bond, the default value is false (recommended) + spoofcheck: false + - + type: sriov_vf + device: p2p2 + vfid: 2 + vlan_id: 112 + qos: 4 + trust: true + promisc: true + spoofcheck: false + - type: linux_bond + name: bond_lnx + use_dhcp: true + bonding_options: "mode=active-backup" + members: + - + type: sriov_vf + device: p2p1 + vfid: 3 + vlan_id: 113 + qos: 5 + # For linux_bond, the default value is true + spoofcheck: true + # For linux_bond, the default value is true + trust: true + # For linux_bond, the default value is false + promisc: false + primary: true + - + type: sriov_vf + device: p2p2 + vfid: 3 + vlan_id: 113 + qos: 5 + spoofcheck: true + trust: true + promisc: false diff --git a/etc/os-net-config/samples/sriov_pf_ovs_dpdk.json b/etc/os-net-config/samples/sriov_pf_ovs_dpdk.json index 29c8d853..5d15bf13 100644 --- a/etc/os-net-config/samples/sriov_pf_ovs_dpdk.json +++ b/etc/os-net-config/samples/sriov_pf_ovs_dpdk.json @@ -5,7 +5,14 @@ "name": "p2p1", "numvfs": 10, "use_dhcp": false, - "promisc": on + "promisc": true + }, + { + "type": "sriov_pf", + "name": "p2p2", + "numvfs": 10, + "use_dhcp": false, + "promisc": true }, { "type": "sriov_vf", @@ -21,7 +28,7 @@ "spoofcheck": true, "macaddr": "00:78:90:80:cc:30", "trust": true, - "state": auto, + "state": "auto", "promisc": false }, { @@ -35,7 +42,7 @@ "members": [ { "device": "p5p2", - "qos": 2, + "qos": 3, "spoofcheck": false, "trust": true, "type": "sriov_vf", @@ -46,6 +53,50 @@ } ] + }, + { + "type": "ovs_user_bridge", + "name": "br-bond", + "members": [ + { + "type" : "ovs_dpdk_bond", + "name" : "dpdkbond1", + "ovs_options": "bond_mode=active-backup", + "members": [ + { + "type" : "ovs_dpdk_port", + "name" : "dpdk2", + "members": [ + { + "type": "sriov_vf", + "device": "p2p1", + "vfid": 4, + "vlan_id": 114, + "spoofcheck": false, + "trust": true, + "qos": 6 + } + ], + "primary": true + }, + { + "type" : "ovs_dpdk_port", + "name" : "dpdk3", + "members": [ + { + "type": "sriov_vf", + "device": "p2p2", + "vfid": 4, + "vlan_id": 114, + "spoofcheck": false, + "trust": true, + "qos": 6 + } + ] + } + ] + } + ] } ] } diff --git a/etc/os-net-config/samples/sriov_pf_ovs_dpdk.yaml b/etc/os-net-config/samples/sriov_pf_ovs_dpdk.yaml index b2cc1435..aac2f7c3 100644 --- a/etc/os-net-config/samples/sriov_pf_ovs_dpdk.yaml +++ b/etc/os-net-config/samples/sriov_pf_ovs_dpdk.yaml @@ -14,9 +14,14 @@ network_config: # Dont set the IP address on the PF use_dhcp: false # Allow all the traffic received. It might be needed when one of its VF - # is attached to a ovs bridge - promisc: on - + # is attached to a ovs bridge. Default: true + promisc: true + - + type: sriov_pf + name: p2p2 + numvfs: 10 + use_dhcp: false + promisc: true # sriov_vf type shall be used to configure the VF's of NICs. # It requires the PF devices to be configured via sriov_pf types # "name" parameter is not required for VF's. It'll be derived from the VF id @@ -43,12 +48,12 @@ network_config: # MAC spoofing is a method of altering the MAC address # The MAC address anti-spoofing when enabled protects from malicious MAC # address spoofing. It should be disabled for 802.3ad bonds. - spoofcheck: on + spoofcheck: true # Change the MAC address of the VF. macaddr: 00:78:90:80:cc:30 # Enabling trust (true) for VF allows enabling multicast/promiscuous mode - # on the VF. The default value is off. - trust: on + # on the VF. The default value is false. + trust: true # Link state seen by the VF # - auto: a reflection of the PF link state (default) # - enable: lets the VF to communicate with other VFs on this host even @@ -60,8 +65,8 @@ network_config: # traffic received in the physical port. Note that all traffic that has # destination mac that does not match any of the VFs/PF MAC addresses is # referred to as unmatched traffic. - # The default value is off. Requires the enabling of trust mode - promisc: off + # The default value is false. Requires the enabling of trust mode + promisc: false # Attach a SR-IOV VF to a ovs user bridge - type: ovs_user_bridge name: br-vfs @@ -80,8 +85,45 @@ network_config: vlan_id: 116 # Optional field, but requires vlan_id qos: 3 - # Set trust to 'on' when attaching to ovs_user_bridge - trust: on - # Set spoofcheck to 'off' when attaching to ovs_user_bridge - spoofcheck: off + # Set trust to true when attaching to ovs_user_bridge + trust: true + # Set spoofcheck to false when attaching to ovs_user_bridge + spoofcheck: false # Note: Do not set promisc mode. + - + type: ovs_user_bridge + name: br-bond + members: + - + type: ovs_dpdk_bond + name: dpdkbond1 + ovs_options: "bond_mode=active-backup" + members: + - + type: ovs_dpdk_port + name: dpdk2 + members: + - + type: sriov_vf + device: p2p1 + vfid: 4 + vlan_id: 114 + qos: 6 + # Default/Recommended : false + spoofcheck: false + # Default/Recommended : true + trust: true + primary: true + # Note: DO NOT SET promisc mode + - + type: ovs_dpdk_port + name: dpdk3 + members: + - + type: sriov_vf + device: p2p2 + vfid: 4 + vlan_id: 114 + qos: 6 + spoofcheck: false + trust: true diff --git a/os_net_config/objects.py b/os_net_config/objects.py index 7af6a53c..548c2104 100644 --- a/os_net_config/objects.py +++ b/os_net_config/objects.py @@ -525,6 +525,10 @@ class OvsBridge(_BaseOpts): logger.info("Trust is not set for VF %s:%d, defaulting to on" % (iface.device, iface.vfid)) iface.trust = "on" + if iface.spoofcheck is None: + logger.info("Spoofcheck is not set for VF %s:%d, defaulting to off" + % (iface.device, iface.vfid)) + iface.spoofcheck = "off" if iface.promisc is None: logger.info("Promisc is not set for VF %s:%d, defaulting to on" % (iface.device, iface.vfid)) @@ -854,6 +858,8 @@ class LinuxBond(_BaseOpts): self.members = members self.bonding_options = bonding_options for member in self.members: + if isinstance(member, SriovVF): + LinuxBond.update_vf_config(member) member.linux_bond_name = name if member.primary: if self.primary_interface_name: @@ -864,6 +870,26 @@ class LinuxBond(_BaseOpts): else: self.primary_interface_name = member.name + @staticmethod + def update_vf_config(iface): + if iface.trust is None: + logger.info("Trust is not set for VF %s:%d, defaulting to on" + % (iface.device, iface.vfid)) + iface.trust = 'on' + if iface.spoofcheck is None: + logger.info("Spoofcheck is not set for VF %s:%d, defaulting to on" + % (iface.device, iface.vfid)) + iface.spoofcheck = 'on' + if iface.promisc is None: + logger.info("Promisc is not set for VF %s:%d, defaulting to off" + % (iface.device, iface.vfid)) + iface.promisc = 'off' + utils.update_sriov_vf_map(iface.device, iface.vfid, iface.name, + vlan_id=iface.vlan_id, qos=iface.qos, + spoofcheck=iface.spoofcheck, + trust=iface.trust, state=iface.state, + macaddr=iface.macaddr, promisc=iface.promisc) + @staticmethod def from_json(json): name = _get_required_field(json, 'name', 'LinuxBond') @@ -904,6 +930,8 @@ class OvsBond(_BaseOpts): self.ovs_options = ovs_options self.ovs_extra = format_ovs_extra(self, ovs_extra) for member in self.members: + if isinstance(member, SriovVF): + OvsBond.update_vf_config(member) if member.primary: if self.primary_interface_name: msg = 'Only one primary interface allowed per bond.' @@ -917,6 +945,26 @@ class OvsBond(_BaseOpts): bond_members.sort(key=lambda x: x.name) self.primary_interface_name = bond_members[0].name + @staticmethod + def update_vf_config(iface): + if iface.trust is None: + logger.info("Trust is not set for VF %s:%d, defaulting to on" + % (iface.device, iface.vfid)) + iface.trust = "on" + if iface.spoofcheck is None: + logger.info("Spoofcheck is not set for VF %s:%d, defaulting to off" + % (iface.device, iface.vfid)) + iface.spoofcheck = "off" + if iface.promisc is None: + logger.info("Promisc is not set for VF %s:%d, defaulting to on" + % (iface.device, iface.vfid)) + iface.promisc = "on" + utils.update_sriov_vf_map(iface.device, iface.vfid, iface.name, + vlan_id=iface.vlan_id, qos=iface.qos, + spoofcheck=iface.spoofcheck, + trust=iface.trust, state=iface.state, + macaddr=iface.macaddr, promisc=iface.promisc) + @staticmethod def from_json(json): name = _get_required_field(json, 'name', 'OvsBond') @@ -1064,6 +1112,10 @@ class OvsDpdkPort(_BaseOpts): logger.info("Trust is not set for VF %s:%d, defaulting to on" % (iface.device, iface.vfid)) iface.trust = "on" + if iface.spoofcheck is None: + logger.info("Spoofcheck is not set for VF %s:%d, defaulting to off" + % (iface.device, iface.vfid)) + iface.spoofcheck = "off" if iface.promisc is not None: logger.warning("Promisc can't be changed for ovs_dpdk_port") iface.promisc = None @@ -1106,7 +1158,7 @@ class OvsDpdkPort(_BaseOpts): OvsDpdkPort.update_vf_config(iface) members.append(iface) else: - msg = 'OVS DPDK Port should have only interface member' + msg = 'Unsupported OVS DPDK Port member type' raise InvalidConfigException(msg) else: msg = 'OVS DPDK Port should have only one member' @@ -1181,10 +1233,10 @@ class SriovVF(_BaseOpts): @staticmethod def get_on_off(config): rval = None - if config: - rval = "on" - elif config is False: + if config is False or config == "off": rval = "off" + elif config is True or config == "on": + rval = "on" return rval @staticmethod @@ -1236,15 +1288,22 @@ class SriovPF(_BaseOpts): self.name = name self.promisc = promisc + @staticmethod + def get_on_off(config): + rval = None + if config is False or config == "off": + rval = "off" + elif config is True or config == "on": + rval = "on" + return rval + @staticmethod def from_json(json): name = _get_required_field(json, 'name', 'SriovPF') numvfs = _get_required_field(json, 'numvfs', 'SriovPF') - promisc = json.get('promisc', None) - if promisc is True: - promisc = "on" - elif promisc is False: - promisc = "off" + # SR-IOV PF - promisc: on (default) + promisc = json.get('promisc', True) + promisc = SriovPF.get_on_off(promisc) opts = _BaseOpts.base_opts_from_json(json) return SriovPF(name, numvfs, *opts, promisc=promisc) diff --git a/os_net_config/schema.yaml b/os_net_config/schema.yaml index 7b586153..08b28db8 100644 --- a/os_net_config/schema.yaml +++ b/os_net_config/schema.yaml @@ -988,6 +988,7 @@ definitions: oneOf: - $ref: "#/definitions/interface" - $ref: "#/definitions/vlan" + - $ref: "#/definitions/sriov_vf" bonding_options: $ref: "#/definitions/bonding_options" # common options: diff --git a/os_net_config/tests/test_cli.py b/os_net_config/tests/test_cli.py index 344495c5..4b97e03f 100644 --- a/os_net_config/tests/test_cli.py +++ b/os_net_config/tests/test_cli.py @@ -23,6 +23,7 @@ import os_net_config from os_net_config import cli from os_net_config import sriov_config from os_net_config.tests import base +from os_net_config import utils import six @@ -205,26 +206,39 @@ class TestCli(base.TestCase): def test_sriov_noop_output(self): def test_get_vf_devname(device, vfid): return device + '_' + str(vfid) + + def test_interface_mac(name): + return 'AA:BB:CC:DD:EE:FF' + self.stub_out('os_net_config.utils.get_vf_devname', test_get_vf_devname) + self.stub_out('os_net_config.utils.interface_mac', + test_interface_mac) ivs_yaml = os.path.join(SAMPLE_BASE, 'sriov_pf.yaml') ivs_json = os.path.join(SAMPLE_BASE, 'sriov_pf.json') stdout_yaml, stderr = self.run_cli('ARG0 --provider=ifcfg --noop ' '--exit-on-validation-errors ' '-c %s' % ivs_yaml) self.assertEqual('', stderr) + contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE) + sriov_config_yaml = yaml.load(contents) + os.remove(sriov_config._SRIOV_CONFIG_FILE) stdout_json, stderr = self.run_cli('ARG0 --provider=ifcfg --noop ' '--exit-on-validation-errors ' '-c %s' % ivs_json) self.assertEqual('', stderr) + contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE) + sriov_config_json = yaml.load(contents) sanity_devices = ['DEVICE=p2p1', 'DEVICE=p2p1_5', 'DEVICE=p2p1_1', 'DEVICE=br-vfs', + 'DEVICE=br-bond', 'TYPE=OVSBridge'] for dev in sanity_devices: self.assertIn(dev, stdout_yaml) self.assertEqual(stdout_yaml, stdout_json) + self.assertItemsEqual(sriov_config_yaml, sriov_config_json) def test_sriov_vf_with_dpdk_noop_output(self): def test_get_vf_devname(device, vfid): @@ -237,10 +251,15 @@ class TestCli(base.TestCase): '--exit-on-validation-errors ' '-c %s' % ivs_yaml) self.assertEqual('', stderr) + contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE) + sriov_config_yaml = yaml.load(contents) + os.remove(sriov_config._SRIOV_CONFIG_FILE) stdout_json, stderr = self.run_cli('ARG0 --provider=ifcfg --noop ' '--exit-on-validation-errors ' '-c %s' % ivs_json) self.assertEqual('', stderr) + contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE) + sriov_config_json = yaml.load(contents) sanity_devices = ['DEVICE=p2p1', 'DEVICE=p2p1_5', 'DEVICE=br-vfs', @@ -250,6 +269,7 @@ class TestCli(base.TestCase): for dev in sanity_devices: self.assertIn(dev, stdout_yaml) self.assertEqual(stdout_yaml, stdout_json) + self.assertItemsEqual(sriov_config_yaml, sriov_config_json) def test_ovs_dpdk_bond_noop_output(self): ivs_yaml = os.path.join(SAMPLE_BASE, 'ovs_dpdk_bond.yaml') diff --git a/os_net_config/tests/test_objects.py b/os_net_config/tests/test_objects.py index 81bcdba2..2869655f 100644 --- a/os_net_config/tests/test_objects.py +++ b/os_net_config/tests/test_objects.py @@ -345,8 +345,7 @@ class TestBridge(base.TestCase): "device": "em1", "vfid": 1, "vlan_id": 111, - "qos": 1, - "spoofcheck": false + "qos": 1 }] } """ @@ -373,6 +372,118 @@ class TestBridge(base.TestCase): vf_map = yaml.load(contents) if contents else [] self.assertListEqual(vf_final, vf_map) + def test_ovs_bond_with_vf_default(self): + data = """{ +"type": "ovs_bridge", +"name": "br-foo", +"use_dhcp": true, +"members": [{ + "type": "ovs_bond", + "name": "bond1", + "members": [{ + "type": "sriov_vf", + "device": "em1", + "vfid": 1, + "vlan_id": 111, + "qos": 1, + "primary": true + }, + { + "type": "sriov_vf", + "device": "em2", + "vfid": 1, + "vlan_id": 111, + "qos": 1 + } + ] +}] +} +""" + vf_final = [{'device_type': 'vf', 'name': 'em1_1', + 'device': {'name': 'em1', 'vfid': 1}, + 'vlan_id': 111, 'qos': 1, + 'spoofcheck': 'off', 'trust': 'on', + 'promisc': 'on'}, + {'device_type': 'vf', 'name': 'em2_1', + 'device': {'name': 'em2', 'vfid': 1}, + 'vlan_id': 111, 'qos': 1, + 'spoofcheck': 'off', 'trust': 'on', + 'promisc': 'on'}] + + def test_get_vf_devname(device, vfid): + return device + '_' + str(vfid) + self.stub_out('os_net_config.utils.get_vf_devname', + test_get_vf_devname) + + bridge = objects.object_from_json(json.loads(data)) + self.assertEqual("br-foo", bridge.name) + self.assertTrue(bridge.use_dhcp) + bond = bridge.members[0] + interface1 = bond.members[0] + interface2 = bond.members[1] + self.assertEqual("em1", interface1.device) + self.assertEqual("em2", interface2.device) + self.assertEqual("br-foo", bond.bridge_name) + + contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE) + vf_map = yaml.load(contents) if contents else [] + self.assertListEqual(vf_final, vf_map) + + def test_ovs_bond_with_vf_custom(self): + data = """{ +"type": "ovs_bridge", +"name": "br-foo", +"use_dhcp": true, +"members": [{ + "type": "ovs_bond", + "name": "bond1", + "members": [{ + "type": "sriov_vf", + "device": "em1", + "vfid": 1, + "vlan_id": 111, + "qos": 1, + "primary": true, + "trust": false, + "spoofcheck": true, + "promisc": false + }, + { + "type": "sriov_vf", + "device": "em2", + "vfid": 1, + "vlan_id": 111, + "qos": 1, + "trust": false, + "spoofcheck": true, + "promisc": false + } + ] +}] +} +""" + vf_final = [{'device_type': 'vf', 'name': 'em1_1', + 'device': {'name': 'em1', 'vfid': 1}, + 'vlan_id': 111, 'qos': 1, + 'spoofcheck': 'on', 'trust': 'off', + 'promisc': 'off'}, + {'device_type': 'vf', 'name': 'em2_1', + 'device': {'name': 'em2', 'vfid': 1}, + 'vlan_id': 111, 'qos': 1, + 'spoofcheck': 'on', 'trust': 'off', + 'promisc': 'off'}] + + def test_get_vf_devname(device, vfid): + return device + '_' + str(vfid) + self.stub_out('os_net_config.utils.get_vf_devname', + test_get_vf_devname) + + objects.object_from_json(json.loads(data)) + + contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE) + vf_map = yaml.load(contents) if contents else [] + self.assertListEqual(vf_final, vf_map) + def test_ovs_bridge_with_vf_param_provided(self): data = """{ "type": "ovs_bridge", @@ -427,8 +538,7 @@ class TestBridge(base.TestCase): "device": "em1", "vfid": 1, "vlan_id": 111, - "qos": 1, - "spoofcheck": false + "qos": 1 } ] }] @@ -881,6 +991,21 @@ class TestLinuxTeam(base.TestCase): class TestLinuxBond(base.TestCase): + def setUp(self): + super(TestLinuxBond, self).setUp() + rand = str(int(random.random() * 100000)) + sriov_config._SRIOV_CONFIG_FILE = '/tmp/sriov_config_' + rand + '.yaml' + + def stub_is_ovs_installed(): + return True + self.stub_out('os_net_config.utils.is_ovs_installed', + stub_is_ovs_installed) + + def tearDown(self): + super(TestLinuxBond, self).tearDown() + if os.path.isfile(sriov_config._SRIOV_CONFIG_FILE): + os.remove(sriov_config._SRIOV_CONFIG_FILE) + def test_from_json_dhcp(self): data = """{ "type": "linux_bond", @@ -936,6 +1061,105 @@ class TestLinuxBond(base.TestCase): interface2 = bridge.members[1] self.assertEqual("em2", interface2.name) + def test_linux_bond_with_vf_default(self): + data = """{ +"type": "linux_bond", +"name": "bond1", +"use_dhcp": true, +"members": [{ + "type": "sriov_vf", + "device": "em1", + "vfid": 1, + "vlan_id": 111, + "qos": 1, + "primary": true + }, + { + "type": "sriov_vf", + "device": "em2", + "vfid": 1, + "vlan_id": 111, + "qos": 1 +}] +} +""" + vf_final = [{'device_type': 'vf', 'name': 'em1_1', + 'device': {'name': 'em1', 'vfid': 1}, + 'vlan_id': 111, 'qos': 1, + 'spoofcheck': 'on', 'trust': 'on', + 'promisc': 'off'}, + {'device_type': 'vf', 'name': 'em2_1', + 'device': {'name': 'em2', 'vfid': 1}, + 'vlan_id': 111, 'qos': 1, + 'spoofcheck': 'on', 'trust': 'on', + 'promisc': 'off'}] + + def test_get_vf_devname(device, vfid): + return device + '_' + str(vfid) + self.stub_out('os_net_config.utils.get_vf_devname', + test_get_vf_devname) + + bond = objects.object_from_json(json.loads(data)) + self.assertEqual("bond1", bond.name) + self.assertTrue(bond.use_dhcp) + interface1 = bond.members[0] + interface2 = bond.members[1] + self.assertEqual("em1", interface1.device) + self.assertEqual("em2", interface2.device) + + contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE) + vf_map = yaml.load(contents) if contents else [] + self.assertListEqual(vf_final, vf_map) + + def test_linux_bond_with_vf_param_provided(self): + data = """{ +"type": "linux_bond", +"name": "bond1", +"use_dhcp": true, +"members": [{ + "type": "sriov_vf", + "device": "em1", + "vfid": 1, + "vlan_id": 111, + "qos": 1, + "trust": false, + "spoofcheck": false, + "promisc": false + }, + { + "type": "sriov_vf", + "device": "em2", + "vfid": 1, + "vlan_id": 111, + "qos": 1, + "trust": false, + "spoofcheck": false, + "promisc": false + } +] +} +""" + vf_final = [{'device_type': 'vf', 'name': 'em1_1', + 'device': {'name': 'em1', 'vfid': 1}, + 'vlan_id': 111, 'qos': 1, + 'spoofcheck': 'off', 'trust': 'off', + 'promisc': 'off'}, + {'device_type': 'vf', 'name': 'em2_1', + 'device': {'name': 'em2', 'vfid': 1}, + 'vlan_id': 111, 'qos': 1, + 'spoofcheck': 'off', 'trust': 'off', + 'promisc': 'off'}] + + def test_get_vf_devname(device, vfid): + return device + '_' + str(vfid) + self.stub_out('os_net_config.utils.get_vf_devname', + test_get_vf_devname) + + objects.object_from_json(json.loads(data)) + contents = utils.get_file_data(sriov_config._SRIOV_CONFIG_FILE) + vf_map = yaml.load(contents) if contents else [] + self.assertListEqual(vf_final, vf_map) + class TestOvsTunnel(base.TestCase): @@ -1406,7 +1630,7 @@ class TestSriovPF(base.TestCase): self.assertEqual("em4", pf.name) self.assertEqual(16, pf.numvfs) self.assertFalse(pf.use_dhcp) - self.assertEqual(None, pf.promisc) + self.assertEqual('on', pf.promisc) class TestSriovVF(base.TestCase): diff --git a/os_net_config/utils.py b/os_net_config/utils.py index 8603f30e..35b6a553 100644 --- a/os_net_config/utils.py +++ b/os_net_config/utils.py @@ -82,7 +82,7 @@ def write_config(filename, data): def write_yaml_config(filepath, data): ensure_directory_presence(filepath) with open(filepath, 'w') as f: - yaml.dump(data, f, default_flow_style=False) + yaml.safe_dump(data, f, default_flow_style=False) def ensure_directory_presence(filepath):