NSX-v3 disable psec per port

The current impl of NSX v3 port security does not remove
the spoofguard profile from the respective NSX port when
port security is disabled from neutron. In addition the address
pairs are removed upon port security disablement.
Unit tests are also included.

backport: liberty

Change-Id: Iad716b19a9a9439be0f372ef35f33d9c4ec39600
Closes-Bug: #1543694
This commit is contained in:
Boden R 2016-02-09 15:29:56 -07:00
parent deef820935
commit 4a95ba95f8
4 changed files with 58 additions and 6 deletions

View File

@ -88,6 +88,9 @@ class SwitchingProfile(AbstractRESTResource):
def uri_segment(self):
return 'switching-profiles'
def list(self):
return self._client.url_get('?include_system_owned=True')
def create(self, profile_type, display_name=None,
description=None, **api_args):
body = {
@ -202,6 +205,9 @@ class LogicalPort(AbstractRESTResource):
address_classifier['vlan'] = int(binding.vlan)
bindings.append(address_classifier)
body['address_bindings'] = bindings
elif address_bindings == []:
# explicitly clear out address bindings
body['address_bindings'] = []
if switch_profile_ids:
profiles = []

View File

@ -78,6 +78,7 @@ from vmware_nsx.nsxlib.v3 import security
LOG = log.getLogger(__name__)
NSX_V3_PSEC_PROFILE_NAME = 'neutron_port_spoof_guard_profile'
NSX_V3_NO_PSEC_PROFILE_NAME = 'nsx-default-spoof-guard-vif-profile'
NSX_V3_DHCP_PROFILE_NAME = 'neutron_port_dhcp_profile'
@ -149,6 +150,11 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
msg = _("Unable to initialize NSX v3 port spoofguard "
"switching profile: %s") % NSX_V3_PSEC_PROFILE_NAME
raise nsx_exc.NsxPluginException(msg)
profiles = nsx_resources.SwitchingProfile
self._no_psec_profile_id = profiles.build_switch_profile_ids(
self._switching_profiles,
self._switching_profiles.find_by_display_name(
NSX_V3_NO_PSEC_PROFILE_NAME)[0])[0]
LOG.debug("Initializing NSX v3 DHCP switching profile")
self._dhcp_profile = None
self._dhcp_profile = self._init_dhcp_switching_profile()
@ -651,7 +657,8 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
parent_name, tag = self._get_data_from_binding_profile(
context, port_data)
address_bindings = self._build_address_bindings(port_data)
address_bindings = (self._build_address_bindings(port_data)
if psec_is_on else [])
vif_uuid = port_data['id']
attachment_type = nsx_constants.ATTACHMENT_VIF
if not device_owner or device_owner == l3_db.DEVICE_OWNER_ROUTER_INTF:
@ -1000,6 +1007,9 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
address_bindings = self._build_address_bindings(updated_port)
if port_security and address_bindings:
switch_profile_ids = [self._get_port_security_profile_id()]
else:
switch_profile_ids = [self._no_psec_profile_id]
address_bindings = []
try:
self._update_port_on_backend(context, nsx_lport_id,

View File

@ -94,11 +94,6 @@ class NsxV3PluginTestCaseMixin(test_plugin.NeutronDbPluginV2TestCase,
_patch_object(nsx_plugin, 'nsx_client', new=mock_client_module)
_patch_object(nsx_plugin, 'nsx_cluster', new=mock_cluster_module)
super(NsxV3PluginTestCaseMixin, self).setUp(plugin=plugin,
ext_mgr=ext_mgr)
self.maxDiff = None
# populate pre-existing mock resources
cluster_id = uuidutils.generate_uuid()
self.mock_api.post(
@ -120,6 +115,18 @@ class NsxV3PluginTestCaseMixin(test_plugin.NeutronDbPluginV2TestCase,
]}),
headers=nsx_client.JSONRESTClient._DEFAULT_HEADERS)
self.mock_api.post(
'api/v1/switching-profiles',
data=jsonutils.dumps({
'id': uuidutils.generate_uuid(),
'display_name': nsx_plugin.NSX_V3_NO_PSEC_PROFILE_NAME
}), headers=nsx_client.JSONRESTClient._DEFAULT_HEADERS)
super(NsxV3PluginTestCaseMixin, self).setUp(plugin=plugin,
ext_mgr=ext_mgr)
self.maxDiff = None
def tearDown(self):
for patcher in self._patchers:
patcher.stop()

View File

@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
#
import copy
import mock
from oslo_serialization import jsonutils
@ -184,6 +186,15 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
self.assertEqual(resp_resources['results'],
mocked_resource.find_by_display_name('resource-1'))
def test_list_all_profiles(self):
mocked_resource = self._mocked_switching_profile()
mocked_resource.list()
test_client.assert_json_call(
'get', mocked_resource,
'https://1.2.3.4/api/v1/switching-profiles/'
'?include_system_owned=True',
data=None)
class LogicalPortTestCase(nsxlib_testcase.NsxClientTestCase):
@ -272,6 +283,24 @@ class LogicalPortTestCase(nsxlib_testcase.NsxClientTestCase):
'delete', mocked_resource,
'https://1.2.3.4/api/v1/logical-ports/%s?detach=true' % uuid)
def test_clear_port_bindings(self):
fake_port = copy.copy(test_constants_v3.FAKE_PORT)
fake_port['address_bindings'] = ['a', 'b']
mocked_resource = self._mocked_lport()
def get_fake_port(*args):
return fake_port
mocked_resource.get = get_fake_port
mocked_resource.update(
fake_port['id'], fake_port['id'], address_bindings=[])
fake_port['address_bindings'] = []
test_client.assert_json_call(
'put', mocked_resource,
'https://1.2.3.4/api/v1/logical-ports/%s' % fake_port['id'],
data=jsonutils.dumps(fake_port, sort_keys=True))
class LogicalRouterTestCase(nsxlib_testcase.NsxClientTestCase):