From 0d5d025acf5a3a24b6dad964490ba5dde174b618 Mon Sep 17 00:00:00 2001 From: Adit Sarfaty Date: Tue, 21 Aug 2018 09:23:03 +0300 Subject: [PATCH] NSX-V3| Fix port MAC learning flag handling The MAC learning flag is saved in the DB and displayed only if it was set by the user, or by the plugin (in case of ENS support). If the value was unset - it is not added to the DB, and not displayed. This patch fixes 2 issues with this logic: 1. Make sure False value is also saved in the DB 2. Make sure False value is also returned in show port command Change-Id: Ifb167c192bf5001ac7415d32be5a382782a44708 --- vmware_nsx/db/maclearning.py | 2 +- vmware_nsx/plugins/nsx_v3/plugin.py | 15 +++--- vmware_nsx/tests/unit/nsx_v3/test_plugin.py | 54 ++++++++++++++++++++- 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/vmware_nsx/db/maclearning.py b/vmware_nsx/db/maclearning.py index 922dd6fd32..25ad8f230f 100644 --- a/vmware_nsx/db/maclearning.py +++ b/vmware_nsx/db/maclearning.py @@ -43,7 +43,7 @@ class MacLearningDbMixin(object): @resource_extend.extends([port_def.COLLECTION_NAME]) def _extend_port_mac_learning_state(port_res, port_db): state = port_db.mac_learning_state - if state and state.mac_learning_enabled: + if state: port_res[mac.MAC_LEARNING] = state.mac_learning_enabled def _update_mac_learning_state(self, context, port_id, enabled): diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py index 4d458e6500..950433d4f1 100644 --- a/vmware_nsx/plugins/nsx_v3/plugin.py +++ b/vmware_nsx/plugins/nsx_v3/plugin.py @@ -2968,25 +2968,28 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, # sgids is a set() so we need to | it in. if psgids: sgids = list(set(sgids) | set(psgids)) - # Make sure mac_learning and port sec are not both enabled - if (validators.is_attr_set(port_data.get(mac_ext.MAC_LEARNING)) and - port_data.get(mac_ext.MAC_LEARNING)): - if is_psec_on: + + # Handle port mac learning + if validators.is_attr_set(port_data.get(mac_ext.MAC_LEARNING)): + # Make sure mac_learning and port sec are not both enabled + if port_data.get(mac_ext.MAC_LEARNING) and is_psec_on: msg = _('Mac learning requires that port security be ' 'disabled') LOG.error(msg) raise n_exc.InvalidInput(error_message=msg) - self._create_mac_learning_state(context, port_data) - elif mac_ext.MAC_LEARNING in port_data: if is_ens_tz_port and not port_data.get(mac_ext.MAC_LEARNING): msg = _('Cannot disable Mac learning for ENS TZ') LOG.error(msg) raise n_exc.InvalidInput(error_message=msg) + # save the mac learning value in the DB + self._create_mac_learning_state(context, port_data) + elif mac_ext.MAC_LEARNING in port_data: # This is due to the fact that the default is # ATTR_NOT_SPECIFIED port_data.pop(mac_ext.MAC_LEARNING) # For a ENZ TZ mac learning is always enabled if is_ens_tz_port and mac_ext.MAC_LEARNING not in port_data: + # Set the default and add to the DB port_data[mac_ext.MAC_LEARNING] = True self._create_mac_learning_state(context, port_data) diff --git a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py index 8c009e1de6..cc96764c70 100644 --- a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py @@ -1158,7 +1158,41 @@ class TestPortsV2(test_plugin.TestPortsV2, NsxV3PluginTestCaseMixin, self.plugin.update_port, self.ctx, port['id'], data) - def test_update_port_with_mac_learning(self): + def test_create_port_with_mac_learning_true(self): + with self.network() as network: + data = {'port': { + 'network_id': network['network']['id'], + 'tenant_id': self._tenant_id, + 'name': 'qos_port', + 'admin_state_up': True, + 'device_id': 'fake_device', + 'device_owner': 'fake_owner', + 'fixed_ips': [], + 'port_security_enabled': False, + 'mac_address': '00:00:00:00:00:01', + 'mac_learning_enabled': True} + } + port = self.plugin.create_port(self.ctx, data) + self.assertTrue(port['mac_learning_enabled']) + + def test_create_port_with_mac_learning_false(self): + with self.network() as network: + data = {'port': { + 'network_id': network['network']['id'], + 'tenant_id': self._tenant_id, + 'name': 'qos_port', + 'admin_state_up': True, + 'device_id': 'fake_device', + 'device_owner': 'fake_owner', + 'fixed_ips': [], + 'port_security_enabled': False, + 'mac_address': '00:00:00:00:00:01', + 'mac_learning_enabled': False} + } + port = self.plugin.create_port(self.ctx, data) + self.assertFalse(port['mac_learning_enabled']) + + def test_update_port_with_mac_learning_true(self): with self.network() as network: data = {'port': { 'network_id': network['network']['id'], @@ -1176,6 +1210,24 @@ class TestPortsV2(test_plugin.TestPortsV2, NsxV3PluginTestCaseMixin, update_res = self.plugin.update_port(self.ctx, port['id'], data) self.assertTrue(update_res['mac_learning_enabled']) + def test_update_port_with_mac_learning_false(self): + with self.network() as network: + data = {'port': { + 'network_id': network['network']['id'], + 'tenant_id': self._tenant_id, + 'name': 'qos_port', + 'admin_state_up': True, + 'device_id': 'fake_device', + 'device_owner': 'fake_owner', + 'fixed_ips': [], + 'port_security_enabled': False, + 'mac_address': '00:00:00:00:00:01'} + } + port = self.plugin.create_port(self.ctx, data) + data['port']['mac_learning_enabled'] = False + update_res = self.plugin.update_port(self.ctx, port['id'], data) + self.assertFalse(update_res['mac_learning_enabled']) + def test_update_port_with_mac_learning_failes(self): with self.network() as network: data = {'port': {