Add editing for port security

Now it is possible to enable/disable port security in Horizon, when
the port-security extension is available.

Closes-Bug: #1634877
Change-Id: I6b17b49bca8e5d1a2aff10fe613ecd70590c097b
This commit is contained in:
Gyorgy Szombathelyi 2016-10-19 12:49:14 +02:00
parent 678aee340b
commit c886d8a2de
6 changed files with 153 additions and 8 deletions

View File

@ -80,6 +80,17 @@ class CreatePort(project_forms.CreatePort):
msg = _("Unable to retrieve MAC learning state")
exceptions.handle(self.request, msg)
try:
if api.neutron.is_extension_supported(request, 'port-security'):
self.fields['port_security_enabled'] = forms.BooleanField(
label=_("Port Security"),
help_text=_("Enable anti-spoofing rules for the port"),
initial=True,
required=False)
except Exception:
msg = _("Unable to retrieve port security state")
exceptions.handle(self.request, msg)
def handle(self, request, data):
try:
# We must specify tenant_id of the network which a subnet is
@ -108,6 +119,9 @@ class CreatePort(project_forms.CreatePort):
if data.get('mac_state'):
params['mac_learning_enabled'] = data['mac_state']
if 'port_security_enabled' in data:
params['port_security_enabled'] = data['port_security_enabled']
port = api.neutron.port_create(request, **params)
msg = _('Port %s was successfully created.') % port['id']
LOG.debug(msg)
@ -152,6 +166,10 @@ class UpdatePort(project_forms.UpdatePort):
if 'mac_state' in data:
extension_kwargs['mac_learning_enabled'] = data['mac_state']
if 'port_security_enabled' in data:
extension_kwargs['port_security_enabled'] = \
data['port_security_enabled']
port = api.neutron.port_update(request,
data['port_id'],
name=data['name'],

View File

@ -84,7 +84,13 @@ class NetworkPortTests(test.BaseAdminViewTests):
def test_port_create_get_with_mac_learning(self):
self._test_port_create_get(mac_learning=True)
def _test_port_create_get(self, mac_learning=False, binding=False):
@test.create_stubs({api.neutron: ('network_get',
'is_extension_supported',)})
def test_port_create_get_with_port_security(self):
self._test_port_create_get(port_security=True)
def _test_port_create_get(self, mac_learning=False, binding=False,
port_security=False):
network = self.networks.first()
api.neutron.network_get(IsA(http.HttpRequest),
network.id)\
@ -96,6 +102,9 @@ class NetworkPortTests(test.BaseAdminViewTests):
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'binding')\
.AndReturn(binding)
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'port-security')\
.AndReturn(port_security)
self.mox.ReplayAll()
url = reverse('horizon:admin:networks:addport',
@ -116,7 +125,14 @@ class NetworkPortTests(test.BaseAdminViewTests):
def test_port_create_post_with_mac_learning(self):
self._test_port_create_post(mac_learning=True, binding=False)
def _test_port_create_post(self, mac_learning=False, binding=False):
@test.create_stubs({api.neutron: ('network_get',
'is_extension_supported',
'port_create',)})
def test_port_create_post_with_port_security(self):
self._test_port_create_post(port_security=True)
def _test_port_create_post(self, mac_learning=False, binding=False,
port_security=False):
network = self.networks.first()
port = self.ports.first()
api.neutron.network_get(IsA(http.HttpRequest),
@ -134,12 +150,17 @@ class NetworkPortTests(test.BaseAdminViewTests):
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'binding') \
.AndReturn(binding)
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'port-security')\
.AndReturn(port_security)
extension_kwargs = {}
if binding:
extension_kwargs['binding__vnic_type'] = \
port.binding__vnic_type
if mac_learning:
extension_kwargs['mac_learning_enabled'] = True
if port_security:
extension_kwargs['port_security_enabled'] = True
api.neutron.port_create(IsA(http.HttpRequest),
tenant_id=network.tenant_id,
network_id=network.id,
@ -163,6 +184,8 @@ class NetworkPortTests(test.BaseAdminViewTests):
form_data['binding__vnic_type'] = port.binding__vnic_type
if mac_learning:
form_data['mac_state'] = True
if port_security:
form_data['port_security_enabled'] = True
url = reverse('horizon:admin:networks:addport',
args=[port.network_id])
res = self.client.post(url, form_data)
@ -189,6 +212,9 @@ class NetworkPortTests(test.BaseAdminViewTests):
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'mac-learning')\
.AndReturn(True)
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'port-security')\
.AndReturn(True)
extension_kwargs = {}
extension_kwargs['binding__vnic_type'] = \
port.binding__vnic_type
@ -237,8 +263,15 @@ class NetworkPortTests(test.BaseAdminViewTests):
def test_port_create_post_exception_with_mac_learning(self):
self._test_port_create_post_exception(mac_learning=True)
@test.create_stubs({api.neutron: ('network_get',
'port_create',
'is_extension_supported',)})
def test_port_create_post_exception_with_port_security(self):
self._test_port_create_post_exception(port_security=True)
def _test_port_create_post_exception(self, mac_learning=False,
binding=False):
binding=False,
port_security=False):
network = self.networks.first()
port = self.ports.first()
api.neutron.network_get(IsA(http.HttpRequest),
@ -256,11 +289,16 @@ class NetworkPortTests(test.BaseAdminViewTests):
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'binding') \
.AndReturn(binding)
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'port-security')\
.AndReturn(port_security)
extension_kwargs = {}
if binding:
extension_kwargs['binding__vnic_type'] = port.binding__vnic_type
if mac_learning:
extension_kwargs['mac_learning_enabled'] = True
if port_security:
extension_kwargs['port_security_enabled'] = True
api.neutron.port_create(IsA(http.HttpRequest),
tenant_id=network.tenant_id,
network_id=network.id,
@ -285,6 +323,8 @@ class NetworkPortTests(test.BaseAdminViewTests):
form_data['binding__vnic_type'] = port.binding__vnic_type
if mac_learning:
form_data['mac_learning_enabled'] = True
if port_security:
form_data['port_security_enabled'] = True
url = reverse('horizon:admin:networks:addport',
args=[port.network_id])
res = self.client.post(url, form_data)
@ -303,7 +343,13 @@ class NetworkPortTests(test.BaseAdminViewTests):
def test_port_update_get_with_mac_learning(self):
self._test_port_update_get(mac_learning=True)
def _test_port_update_get(self, mac_learning=False, binding=False):
@test.create_stubs({api.neutron: ('port_get',
'is_extension_supported',)})
def test_port_update_get_with_port_security(self):
self._test_port_update_get(port_security=True)
def _test_port_update_get(self, mac_learning=False, binding=False,
port_security=False):
port = self.ports.first()
api.neutron.port_get(IsA(http.HttpRequest),
port.id)\
@ -314,6 +360,9 @@ class NetworkPortTests(test.BaseAdminViewTests):
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'mac-learning')\
.AndReturn(mac_learning)
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'port-security')\
.AndReturn(port_security)
self.mox.ReplayAll()
url = reverse('horizon:admin:networks:editport',
@ -334,7 +383,14 @@ class NetworkPortTests(test.BaseAdminViewTests):
def test_port_update_post_with_mac_learning(self):
self._test_port_update_post(mac_learning=True)
def _test_port_update_post(self, mac_learning=False, binding=False):
@test.create_stubs({api.neutron: ('port_get',
'is_extension_supported',
'port_update')})
def test_port_update_post_with_port_security(self):
self._test_port_update_post(port_security=True)
def _test_port_update_post(self, mac_learning=False, binding=False,
port_security=False):
port = self.ports.first()
api.neutron.port_get(IsA(http.HttpRequest), port.id)\
.AndReturn(port)
@ -344,11 +400,16 @@ class NetworkPortTests(test.BaseAdminViewTests):
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'mac-learning')\
.AndReturn(mac_learning)
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'port-security')\
.AndReturn(port_security)
extension_kwargs = {}
if binding:
extension_kwargs['binding__vnic_type'] = port.binding__vnic_type
if mac_learning:
extension_kwargs['mac_learning_enabled'] = True
if port_security:
extension_kwargs['port_security_enabled'] = True
api.neutron.port_update(IsA(http.HttpRequest), port.id,
name=port.name,
admin_state_up=port.admin_state_up,
@ -371,6 +432,8 @@ class NetworkPortTests(test.BaseAdminViewTests):
form_data['binding__vnic_type'] = port.binding__vnic_type
if mac_learning:
form_data['mac_state'] = True
if port_security:
form_data['port_security_enabled'] = True
url = reverse('horizon:admin:networks:editport',
args=[port.network_id, port.id])
res = self.client.post(url, form_data)
@ -390,8 +453,15 @@ class NetworkPortTests(test.BaseAdminViewTests):
def test_port_update_post_exception_with_mac_learning(self):
self._test_port_update_post_exception(mac_learning=True, binding=False)
@test.create_stubs({api.neutron: ('port_get',
'is_extension_supported',
'port_update')})
def test_port_update_post_exception_with_port_security(self):
self._test_port_update_post_exception(port_security=True)
def _test_port_update_post_exception(self, mac_learning=False,
binding=False):
binding=False,
port_security=False):
port = self.ports.first()
api.neutron.port_get(IsA(http.HttpRequest), port.id)\
.AndReturn(port)
@ -401,11 +471,16 @@ class NetworkPortTests(test.BaseAdminViewTests):
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'mac-learning')\
.AndReturn(mac_learning)
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'port-security')\
.AndReturn(port_security)
extension_kwargs = {}
if binding:
extension_kwargs['binding__vnic_type'] = port.binding__vnic_type
if mac_learning:
extension_kwargs['mac_learning_enabled'] = True
if port_security:
extension_kwargs['port_security_enabled'] = True
api.neutron.port_update(IsA(http.HttpRequest), port.id,
name=port.name,
admin_state_up=port.admin_state_up,
@ -427,6 +502,8 @@ class NetworkPortTests(test.BaseAdminViewTests):
form_data['binding__vnic_type'] = port.binding__vnic_type
if mac_learning:
form_data['mac_state'] = True
if port_security:
form_data['port_security_enabled'] = True
url = reverse('horizon:admin:networks:editport',
args=[port.network_id, port.id])
res = self.client.post(url, form_data)

View File

@ -197,6 +197,16 @@ class UpdatePort(forms.SelfHandlingForm):
msg = _("Unable to retrieve MAC learning state")
exceptions.handle(self.request, msg)
try:
if api.neutron.is_extension_supported(request, 'port-security'):
self.fields['port_security_enabled'] = forms.BooleanField(
label=_("Port Security"),
help_text=_("Enable anti-spoofing rules for the port"),
required=False)
except Exception:
msg = _("Unable to retrieve port security state")
exceptions.handle(self.request, msg)
def handle(self, request, data):
data['admin_state'] = (data['admin_state'] == 'True')
try:
@ -207,6 +217,10 @@ class UpdatePort(forms.SelfHandlingForm):
data['binding__vnic_type']
if 'mac_state' in data:
extension_kwargs['mac_learning_enabled'] = data['mac_state']
if 'port_security_enabled' in data:
extension_kwargs['port_security_enabled'] = \
data['port_security_enabled']
port = api.neutron.port_update(request,
data['port_id'],
name=data['name'],

View File

@ -116,7 +116,14 @@ class NetworkPortTests(test.TestCase):
def test_port_update_post_with_mac_learning(self):
self._test_port_update_post(mac_learning=True)
def _test_port_update_post(self, mac_learning=False, binding=False):
@test.create_stubs({api.neutron: ('port_get',
'is_extension_supported',
'port_update')})
def test_port_update_post_with_port_security(self):
self._test_port_update_post(port_security=True)
def _test_port_update_post(self, mac_learning=False, binding=False,
port_security=False):
port = self.ports.first()
api.neutron.port_get(IsA(http.HttpRequest), port.id)\
.AndReturn(port)
@ -126,11 +133,16 @@ class NetworkPortTests(test.TestCase):
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'mac-learning')\
.AndReturn(mac_learning)
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'port-security')\
.AndReturn(port_security)
extension_kwargs = {}
if binding:
extension_kwargs['binding__vnic_type'] = port.binding__vnic_type
if mac_learning:
extension_kwargs['mac_learning_enabled'] = True
if port_security:
extension_kwargs['port_security_enabled'] = True
api.neutron.port_update(IsA(http.HttpRequest), port.id,
name=port.name,
admin_state_up=port.admin_state_up,
@ -146,6 +158,8 @@ class NetworkPortTests(test.TestCase):
form_data['binding__vnic_type'] = port.binding__vnic_type
if mac_learning:
form_data['mac_state'] = True
if port_security:
form_data['port_security_enabled'] = True
url = reverse('horizon:project:networks:editport',
args=[port.network_id, port.id])
res = self.client.post(url, form_data)
@ -165,8 +179,15 @@ class NetworkPortTests(test.TestCase):
def test_port_update_post_exception_with_mac_learning(self):
self._test_port_update_post_exception(mac_learning=True)
@test.create_stubs({api.neutron: ('port_get',
'is_extension_supported',
'port_update')})
def test_port_update_post_exception_with_port_security(self):
self._test_port_update_post_exception(port_security=True)
def _test_port_update_post_exception(self, mac_learning=False,
binding=False):
binding=False,
port_security=False):
port = self.ports.first()
api.neutron.port_get(IsA(http.HttpRequest), port.id)\
@ -177,11 +198,16 @@ class NetworkPortTests(test.TestCase):
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'mac-learning')\
.AndReturn(mac_learning)
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'port-security')\
.AndReturn(port_security)
extension_kwargs = {}
if binding:
extension_kwargs['binding__vnic_type'] = port.binding__vnic_type
if mac_learning:
extension_kwargs['mac_learning_enabled'] = True
if port_security:
extension_kwargs['port_security_enabled'] = True
api.neutron.port_update(IsA(http.HttpRequest), port.id,
name=port.name,
admin_state_up=port.admin_state_up,
@ -197,6 +223,8 @@ class NetworkPortTests(test.TestCase):
form_data['binding__vnic_type'] = port.binding__vnic_type
if mac_learning:
form_data['mac_state'] = True
if port_security:
form_data['port_security_enabled'] = True
url = reverse('horizon:project:networks:editport',
args=[port.network_id, port.id])
res = self.client.post(url, form_data)

View File

@ -195,4 +195,6 @@ class UpdateView(forms.ModalFormView):
except Exception:
# MAC Learning is not set
pass
if 'port_security_enabled' in port:
initial['port_security_enabled'] = port['port_security_enabled']
return initial

View File

@ -0,0 +1,6 @@
---
features:
- "Now it is possible to enable/disable port security in Horizon, when
the port-security extension is available. Note: Neutron allows disabling
the port security on a port only when no security groups are associated
to it"