summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Bock <nicolas.bock@canonical.com>2021-09-15 09:39:31 -0600
committerNicolas Bock <nicolas.bock@canonical.com>2022-07-24 00:53:05 +0200
commit1561fcce55371c6b2d93a31b83ca533dea82f746 (patch)
treead7fde1869c196cd10c5252f9dcbdbe48e30e9ce
parent48b702adf75b7f19420df578d2bf9bf813099af5 (diff)
downloadhorizon-1561fcce55371c6b2d93a31b83ca533dea82f746.tar.gz
Get ports directly instead of via loop
In order to get a list of available ports, the current implementation of the form code in `project/instances/attach_interface` loops through the available networks in the project and requests a list of ports for each via the Neutron API. This implementation is O(N) in time with a large prefactor (the time for a Neutron API call) where N is the number of networks. Instead of calling the Neutron API for each network this change uses one call to the Neutron API to get the list of ports on all networks and filters this list via a list comprehension. While this implementation is still O(N) the prefactor is significantly smaller. Includes some unit test fixes to workaround the fact that patch 6ac31e0 is not backported beyond Y. Closes-Bug: #1943639 Change-Id: I8fd32c3aad22d8ef7f57201f5144f6b2e357ef10 Signed-off-by: Nicolas Bock <nicolas.bock@canonical.com> (cherry picked from commit 9f5d659d160d24d359992dda22fecb0db6b6f805)
-rw-r--r--openstack_dashboard/dashboards/project/instances/tests.py49
-rw-r--r--openstack_dashboard/dashboards/project/instances/utils.py20
2 files changed, 30 insertions, 39 deletions
diff --git a/openstack_dashboard/dashboards/project/instances/tests.py b/openstack_dashboard/dashboards/project/instances/tests.py
index 5eafb48b2..edb107bbc 100644
--- a/openstack_dashboard/dashboards/project/instances/tests.py
+++ b/openstack_dashboard/dashboards/project/instances/tests.py
@@ -131,13 +131,9 @@ class InstanceTableTestMixin(object):
shared=False),
mock.call(helpers.IsHttpRequest(), shared=True),
])
- self.assertEqual(len(self.networks.list()),
- self.mock_port_list_with_trunk_types.call_count)
- self.mock_port_list_with_trunk_types(
- [mock.call(helpers.IsHttpRequest(),
- network_id=net.id,
- tenant_id=self.tenant.id)
- for net in self.networks.list()])
+ self.mock_port_list_with_trunk_types.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ tenant_id=self.tenant.id)
def _mock_nova_lists(self):
self.mock_flavor_list.return_value = self.flavors.list()
@@ -2197,12 +2193,9 @@ class InstanceLaunchInstanceTests(InstanceTestBase,
mock.call(helpers.IsHttpRequest(), shared=True),
])
self.assertEqual(4, self.mock_network_list.call_count)
- self.mock_port_list_with_trunk_types.assert_has_calls(
- [mock.call(helpers.IsHttpRequest(),
- network_id=net.id, tenant_id=self.tenant.id)
- for net in self.networks.list()])
- self.assertEqual(len(self.networks.list()),
- self.mock_port_list_with_trunk_types.call_count)
+ self.mock_port_list_with_trunk_types.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ tenant_id=self.tenant.id)
self.mock_server_group_list.assert_called_once_with(
helpers.IsHttpRequest())
self.mock_tenant_quota_usages.assert_called_once_with(
@@ -2348,10 +2341,9 @@ class InstanceLaunchInstanceTests(InstanceTestBase,
mock.call(helpers.IsHttpRequest(), shared=True),
])
self.assertEqual(4, self.mock_network_list.call_count)
- self.mock_port_list_with_trunk_types.assert_has_calls(
- [mock.call(helpers.IsHttpRequest(),
- network_id=net.id, tenant_id=self.tenant.id)
- for net in self.networks.list()])
+ self.mock_port_list_with_trunk_types.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ tenant_id=self.tenant.id)
self.mock_server_group_list.assert_called_once_with(
helpers.IsHttpRequest())
self.mock_tenant_quota_usages.assert_called_once_with(
@@ -2431,10 +2423,9 @@ class InstanceLaunchInstanceTests(InstanceTestBase,
mock.call(helpers.IsHttpRequest(), shared=True),
])
self.assertEqual(4, self.mock_network_list.call_count)
- self.mock_port_list_with_trunk_types.assert_has_calls(
- [mock.call(helpers.IsHttpRequest(),
- network_id=net.id, tenant_id=self.tenant.id)
- for net in self.networks.list()])
+ self.mock_port_list_with_trunk_types.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ tenant_id=self.tenant.id)
self.mock_server_group_list.assert_called_once_with(
helpers.IsHttpRequest())
self.mock_tenant_quota_usages.assert_called_once_with(
@@ -3606,13 +3597,9 @@ class InstanceLaunchInstanceTests(InstanceTestBase,
helpers.IsHttpRequest(),
shared=True),
])
- self.assertEqual(len(self.networks.list()),
- self.mock_port_list_with_trunk_types.call_count)
- self.mock_port_list_with_trunk_types.assert_has_calls(
- [mock.call(helpers.IsHttpRequest(),
- network_id=net.id,
- tenant_id=self.tenant.id)
- for net in self.networks.list()])
+ self.mock_port_list_with_trunk_types.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ tenant_id=self.tenant.id)
self.mock_volume_list.assert_has_calls([
mock.call(helpers.IsHttpRequest(),
search_opts=VOLUME_SEARCH_OPTS),
@@ -5085,7 +5072,8 @@ class ConsoleManagerTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
self.assertRaises(exceptions.NotAvailable,
console.get_console, None, 'FAKE', None)
- @helpers.create_mocks({api.neutron: ('network_list_for_tenant',)})
+ @helpers.create_mocks({api.neutron: ('network_list_for_tenant',
+ 'port_list_with_trunk_types',)})
def test_interface_attach_get(self):
server = self.servers.first()
self.mock_network_list_for_tenant.side_effect = [
@@ -5105,7 +5093,8 @@ class ConsoleManagerTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
])
self.assertEqual(2, self.mock_network_list_for_tenant.call_count)
- @helpers.create_mocks({api.neutron: ('network_list_for_tenant',),
+ @helpers.create_mocks({api.neutron: ('network_list_for_tenant',
+ 'port_list_with_trunk_types',),
api.nova: ('interface_attach',)})
def test_interface_attach_post(self):
fixed_ip = '10.0.0.10'
diff --git a/openstack_dashboard/dashboards/project/instances/utils.py b/openstack_dashboard/dashboards/project/instances/utils.py
index 0639690db..005ce12b2 100644
--- a/openstack_dashboard/dashboards/project/instances/utils.py
+++ b/openstack_dashboard/dashboards/project/instances/utils.py
@@ -197,7 +197,7 @@ def port_field_data(request, with_network=False):
port_name = "{} ({})".format(
port.name_or_id, ",".join(
[ip['ip_address'] for ip in port['fixed_ips']]))
- if with_network and network:
+ if with_network:
port_name += " - {}".format(network.name_or_id)
return port_name
@@ -205,14 +205,16 @@ def port_field_data(request, with_network=False):
if api.base.is_service_enabled(request, 'network'):
network_list = api.neutron.network_list_for_tenant(
request, request.user.tenant_id)
- for network in network_list:
- ports.extend(
- [(port.id, add_more_info_port_name(port, network))
- for port in api.neutron.port_list_with_trunk_types(
- request, network_id=network.id,
- tenant_id=request.user.tenant_id)
- if (not port.device_owner and
- not isinstance(port, api.neutron.PortTrunkSubport))])
+ network_dict = dict((n.id, n) for n in network_list)
+ ports = [
+ (port.id,
+ add_more_info_port_name(port, network_dict[port.network_id]))
+ for port
+ in api.neutron.port_list_with_trunk_types(
+ request, tenant_id=request.user.tenant_id)
+ if (not port.device_owner and
+ not isinstance(port, api.neutron.PortTrunkSubport))
+ ]
ports.sort(key=lambda obj: obj[1])
return ports