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
This commit is contained in:
Adit Sarfaty 2018-08-21 09:23:03 +03:00
parent 783dc4edf7
commit 0d5d025acf
3 changed files with 63 additions and 8 deletions

View File

@ -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):

View File

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

View File

@ -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': {