summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2019-10-09 10:25:15 +0000
committerGerrit Code Review <review@openstack.org>2019-10-09 10:25:15 +0000
commit9d0bbdae14c1dcf6f69fa4f51f76b05a9ae4bcc2 (patch)
tree6c91f1963edcb9d14912040faeccc0febde68dae
parentbc2edc2e0cb776a8c53deea12c6d74b84fa47a99 (diff)
parentd8ae1d05920f144531fe16a70e80f9871c37675f (diff)
downloadhorizon-9d0bbdae14c1dcf6f69fa4f51f76b05a9ae4bcc2.tar.gz
Merge "Add Allowed Address Pair/Delete buttons are only visible to admin" into stable/queens
-rw-r--r--openstack_dashboard/dashboards/admin/networks/ports/tests.py73
-rw-r--r--openstack_dashboard/dashboards/project/networks/ports/extensions/allowed_address_pairs/tables.py16
-rw-r--r--openstack_dashboard/dashboards/project/networks/ports/tests.py159
3 files changed, 248 insertions, 0 deletions
diff --git a/openstack_dashboard/dashboards/admin/networks/ports/tests.py b/openstack_dashboard/dashboards/admin/networks/ports/tests.py
index 3c8d082f2..f8bd0d2d1 100644
--- a/openstack_dashboard/dashboards/admin/networks/ports/tests.py
+++ b/openstack_dashboard/dashboards/admin/networks/ports/tests.py
@@ -15,6 +15,7 @@
from django.core.urlresolvers import reverse
from django import http
+from django.test.utils import override_settings
from mox3.mox import IsA
@@ -594,3 +595,75 @@ class NetworkPortTests(test.BaseAdminViewTests):
res = self.client.post(url, form_data)
self.assertRedirectsNoFollow(res, url)
+
+ @override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
+ @test.create_stubs({api.neutron: ('port_get',
+ 'network_get',
+ 'is_extension_supported')})
+ def test_add_allowed_address_pair_button_shown(self):
+ port = self.ports.first()
+ network_id = self.networks.first().id
+ api.neutron.port_get(IsA(http.HttpRequest), port.id) \
+ .AndReturn(self.ports.first())
+ api.neutron.is_extension_supported(IsA(http.HttpRequest),
+ 'mac-learning') \
+ .MultipleTimes().AndReturn(False)
+ api.neutron.is_extension_supported(IsA(http.HttpRequest),
+ 'allowed-address-pairs') \
+ .MultipleTimes().AndReturn(True)
+ api.neutron.network_get(IsA(http.HttpRequest), network_id) \
+ .AndReturn(self.networks.first())
+ self.mox.ReplayAll()
+
+ url = reverse('horizon:project:networks:ports:addallowedaddresspairs',
+ args=[port.id])
+ classes = 'btn data-table-action btn-default ajax-modal'
+ link_name = "Add Allowed Address Pair"
+
+ expected_string = \
+ '<a id="allowed_address_pairs__action_AddAllowedAddressPair" ' \
+ 'class="%s" href="%s" title="Add Allowed Address Pair">' \
+ '<span class="fa fa-plus"></span> %s</a>' \
+ % (classes, url, link_name)
+
+ res = self.client.get(reverse('horizon:project:networks:ports:detail',
+ args=[port.id]))
+
+ self.assertTemplateUsed(res, 'horizon/common/_detail_tab_group.html')
+ self.assertIn(expected_string, res.context_data['tab_group'].render())
+
+ @override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
+ @test.create_stubs({api.neutron: ('port_get',
+ 'network_get',
+ 'is_extension_supported')})
+ def test_delete_address_pair_button_shown(self):
+ port = self.ports.first()
+ network_id = self.networks.first().id
+ api.neutron.port_get(IsA(http.HttpRequest), port.id) \
+ .AndReturn(self.ports.first())
+ api.neutron.is_extension_supported(IsA(http.HttpRequest),
+ 'mac-learning') \
+ .MultipleTimes().AndReturn(False)
+ api.neutron.is_extension_supported(IsA(http.HttpRequest),
+ 'allowed-address-pairs') \
+ .MultipleTimes().AndReturn(True)
+ api.neutron.network_get(IsA(http.HttpRequest), network_id) \
+ .AndReturn(self.networks.first())
+ self.mox.ReplayAll()
+
+ classes = 'data-table-action btn-danger btn'
+
+ expected_string = \
+ '<button data-batch-action="true" ' \
+ 'id="allowed_address_pairs__action_delete" ' \
+ 'class="%s" name="action" help_text="This action cannot be ' \
+ 'undone." type="submit" value="allowed_address_pairs__delete">' \
+ '<span class="fa fa-trash"></span>' \
+ ' Delete</button>' \
+ % (classes)
+
+ res = self.client.get(reverse(
+ 'horizon:project:networks:ports:detail', args=[port.id]))
+
+ self.assertTemplateUsed(res, 'horizon/common/_detail_tab_group.html')
+ self.assertIn(expected_string, res.context_data['tab_group'].render())
diff --git a/openstack_dashboard/dashboards/project/networks/ports/extensions/allowed_address_pairs/tables.py b/openstack_dashboard/dashboards/project/networks/ports/extensions/allowed_address_pairs/tables.py
index 1570351d3..6e7990241 100644
--- a/openstack_dashboard/dashboards/project/networks/ports/extensions/allowed_address_pairs/tables.py
+++ b/openstack_dashboard/dashboards/project/networks/ports/extensions/allowed_address_pairs/tables.py
@@ -39,6 +39,14 @@ class AddAllowedAddressPair(policy.PolicyTargetMixin, tables.LinkAction):
("network", "update_port:allowed_address_pairs"),
)
+ def get_policy_target(self, request, datum=None):
+ policy_target = super(AddAllowedAddressPair, self).\
+ get_policy_target(request, datum)
+ policy_target["network:tenant_id"] = (
+ self.table.kwargs['port'].tenant_id)
+
+ return policy_target
+
def get_link_url(self, port=None):
if port:
return reverse(self.url, args=(port.id,))
@@ -68,6 +76,14 @@ class DeleteAllowedAddressPair(tables.DeleteAction):
("network", "update_port:allowed_address_pairs"),
)
+ def get_policy_target(self, request, datum=None):
+ policy_target = super(DeleteAllowedAddressPair, self).\
+ get_policy_target(request, datum)
+ policy_target["network:tenant_id"] = (
+ self.table.kwargs['port'].tenant_id)
+
+ return policy_target
+
def delete(self, request, ip_address):
try:
port_id = self.table.kwargs['port_id']
diff --git a/openstack_dashboard/dashboards/project/networks/ports/tests.py b/openstack_dashboard/dashboards/project/networks/ports/tests.py
index 8806db3ff..ad2b0980d 100644
--- a/openstack_dashboard/dashboards/project/networks/ports/tests.py
+++ b/openstack_dashboard/dashboards/project/networks/ports/tests.py
@@ -17,9 +17,13 @@ import copy
from django.core.urlresolvers import reverse
from django import http
+from django.test.utils import override_settings
+import mock
from mox3.mox import IsA
+from openstack_auth import utils as auth_utils
+
from horizon.workflows import views
from openstack_dashboard import api
@@ -263,6 +267,84 @@ class NetworkPortTests(test.TestCase):
address_pairs = res.context['allowed_address_pairs_table'].data
self.assertItemsEqual(port.allowed_address_pairs, address_pairs)
+ @override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
+ @test.create_stubs({api.neutron: ('port_get',
+ 'network_get',
+ 'is_extension_supported')})
+ def test_add_allowed_address_pair_button_shown_to_network_owner(self):
+ port = self.ports.first()
+
+ api.neutron.port_get(IsA(http.HttpRequest), port.id) \
+ .AndReturn(port)
+ api.neutron.is_extension_supported(IsA(http.HttpRequest),
+ 'allowed-address-pairs') \
+ .MultipleTimes().AndReturn(True)
+ api.neutron.is_extension_supported(IsA(http.HttpRequest),
+ 'mac-learning') \
+ .MultipleTimes().AndReturn(False)
+ self.mox.ReplayAll()
+
+ url = reverse('horizon:project:networks:ports:addallowedaddresspairs',
+ args=[port.id])
+ classes = 'btn data-table-action btn-default ajax-modal'
+ link_name = "Add Allowed Address Pair"
+
+ expected_string = \
+ '<a id="allowed_address_pairs__action_AddAllowedAddressPair" ' \
+ 'class="%s" href="%s" title="Add Allowed Address Pair">' \
+ '<span class="fa fa-plus"></span> %s</a>' \
+ % (classes, url, link_name)
+
+ res = self.client.get(reverse('horizon:project:networks:ports:detail',
+ args=[port.id]))
+
+ self.assertTemplateUsed(res, 'horizon/common/_detail_tab_group.html')
+ self.assertIn(expected_string, res.context_data['tab_group'].render())
+
+ @override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
+ @test.create_stubs({api.neutron: ('network_get',
+ 'port_get',
+ 'is_extension_supported',
+ 'security_group_list',)})
+ def test_add_allowed_address_pair_button_disabled_to_other_tenant(self):
+ # Current user tenant_id is 1 so select port whose tenant_id is
+ # other than 1 for checking "Add Allowed Address Pair" button is not
+ # displayed on the screen.
+ user = auth_utils.get_user(self.request)
+
+ # select port such that tenant_id is different from user's tenant_id.
+ port = [p for p in self.ports.list()
+ if p.tenant_id != user.tenant_id][0]
+
+ api.neutron.port_get(IsA(http.HttpRequest), port.id) \
+ .AndReturn(port)
+ api.neutron.is_extension_supported(IsA(http.HttpRequest),
+ 'allowed-address-pairs') \
+ .MultipleTimes().AndReturn(False)
+ api.neutron.is_extension_supported(IsA(http.HttpRequest),
+ 'mac-learning') \
+ .MultipleTimes().AndReturn(False)
+ self.mox.ReplayAll()
+
+ with mock.patch('openstack_auth.utils.get_user', return_value=user):
+ url = reverse(
+ 'horizon:project:networks:ports:addallowedaddresspairs',
+ args=[port.id])
+ classes = 'btn data-table-action btn-default ajax-modal'
+ link_name = "Add Allowed Address Pair"
+
+ expected_string = \
+ '<a id="allowed_address_pairs__action_AddAllowedAddressPair" ' \
+ 'class="%s" href="%s" title="Add Allowed Address Pair">' \
+ '<span class="fa fa-plus"></span> %s</a>' \
+ % (classes, url, link_name)
+
+ res = self.client.get(reverse(
+ 'horizon:project:networks:ports:detail', args=[port.id]))
+
+ self.assertNotIn(
+ expected_string, res.context_data['tab_group'].render())
+
@test.create_stubs({api.neutron: ('port_get', 'port_update')})
def test_port_add_allowed_address_pair(self):
detail_path = 'horizon:project:networks:ports:detail'
@@ -319,6 +401,83 @@ class NetworkPortTests(test.TestCase):
self.assertFormErrors(res, 1)
self.assertContains(res, "Incorrect format for IP address")
+ @override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
+ @test.create_stubs({api.neutron: ('port_get',
+ 'network_get',
+ 'is_extension_supported')})
+ def test_delete_address_pair_button_shown_to_network_owner(self):
+ port = self.ports.first()
+
+ api.neutron.port_get(IsA(http.HttpRequest), port.id) \
+ .AndReturn(port)
+ api.neutron.is_extension_supported(IsA(http.HttpRequest),
+ 'allowed-address-pairs') \
+ .MultipleTimes().AndReturn(True)
+ api.neutron.is_extension_supported(IsA(http.HttpRequest),
+ 'mac-learning') \
+ .MultipleTimes().AndReturn(False)
+ self.mox.ReplayAll()
+
+ classes = 'data-table-action btn-danger btn'
+
+ expected_string = \
+ '<button data-batch-action="true" ' \
+ 'id="allowed_address_pairs__action_delete" ' \
+ 'class="%s" name="action" help_text="This action cannot be ' \
+ 'undone." type="submit" value="allowed_address_pairs__delete">' \
+ '<span class="fa fa-trash"></span>' \
+ ' Delete</button>' \
+ % (classes)
+
+ res = self.client.get(reverse(
+ 'horizon:project:networks:ports:detail', args=[port.id]))
+
+ self.assertTemplateUsed(res, 'horizon/common/_detail_tab_group.html')
+ self.assertIn(expected_string, res.context_data['tab_group'].render())
+
+ @override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
+ @test.create_stubs({api.neutron: ('network_get',
+ 'port_get',
+ 'is_extension_supported',
+ 'security_group_list',)})
+ def test_delete_address_pair_button_disabled_to_other_tenant(self):
+ # Current user tenant_id is 1 so select port whose tenant_id is
+ # other than 1 for checking "Delete Allowed Address Pair" button is
+ # not displayed on the screen.
+ user = auth_utils.get_user(self.request)
+
+ # select port such that tenant_id is different from user's tenant_id.
+ port = [p for p in self.ports.list()
+ if p.tenant_id != user.tenant_id][0]
+
+ api.neutron.port_get(IsA(http.HttpRequest), port.id) \
+ .AndReturn(port)
+ api.neutron.is_extension_supported(IsA(http.HttpRequest),
+ 'allowed-address-pairs') \
+ .MultipleTimes().AndReturn(False)
+ api.neutron.is_extension_supported(IsA(http.HttpRequest),
+ 'mac-learning') \
+ .MultipleTimes().AndReturn(False)
+ self.mox.ReplayAll()
+
+ with mock.patch('openstack_auth.utils.get_user', return_value=user):
+ classes = 'data-table-action btn-danger btn'
+
+ expected_string = \
+ '<button data-batch-action="true" ' \
+ 'id="allowed_address_pairs__action_delete" ' \
+ 'class="%s" name="action" help_text="This action cannot be ' \
+ 'undone." type="submit" ' \
+ 'value="allowed_address_pairs__delete">' \
+ '<span class="fa fa-trash"></span>' \
+ ' Delete</button>' % (classes)
+
+ res = self.client.get(reverse(
+ 'horizon:project:networks:ports:detail', args=[port.id]))
+
+ self.assertNotIn(
+ expected_string, res.context_data['tab_group'].render())
+
@test.create_stubs({api.neutron: ('port_get', 'port_update',
'is_extension_supported',)})
def test_port_remove_allowed_address_pair(self):