diff options
author | Andrew Bonney <andrew.bonney@bbc.co.uk> | 2022-04-26 11:35:38 +0100 |
---|---|---|
committer | Andrew Bonney <andrew.bonney@bbc.co.uk> | 2022-05-06 06:53:49 +0000 |
commit | 60548e804219d91d8c68ab3d74dd0ae956cd33f3 (patch) | |
tree | 461ce699a050522feae5a2423ec250d0229ac5b5 /nova | |
parent | 1ac0d6984a43cddbb5a2f1a2f7bc115fd83517c9 (diff) | |
download | nova-60548e804219d91d8c68ab3d74dd0ae956cd33f3.tar.gz |
Fix segment-aware scheduling permissions error
Resolves a bug encountered when setting the Nova scheduler to
be aware of Neutron routed provider network segments, by using
'query_placement_for_routed_network_aggregates'.
Non-admin users attempting to access the 'segment_id' attribute
of a subnet caused a traceback, resulting in instance creation
failure.
This patch ensures the Neutron client is initialised with an
administrative context no matter what the requesting user's
permissions are.
Change-Id: Ic0f25e4d2395560fc2b68f3b469e266ac59abaa2
Closes-Bug: #1970383
(cherry picked from commit ee32934f34afd8e6df467361e9d71788cd36f6ee)
Diffstat (limited to 'nova')
-rw-r--r-- | nova/network/neutron.py | 4 | ||||
-rw-r--r-- | nova/tests/unit/network/test_neutron.py | 18 |
2 files changed, 18 insertions, 4 deletions
diff --git a/nova/network/neutron.py b/nova/network/neutron.py index 3ee9774d24..7d6b6a8af9 100644 --- a/nova/network/neutron.py +++ b/nova/network/neutron.py @@ -3874,7 +3874,7 @@ class API: either Segment extension isn't enabled in Neutron or if the network isn't configured for routing. """ - client = get_client(context) + client = get_client(context, admin=True) if not self.has_segment_extension(client=client): return [] @@ -3905,7 +3905,7 @@ class API: extension isn't enabled in Neutron or the provided subnet doesn't have segments (if the related network isn't configured for routing) """ - client = get_client(context) + client = get_client(context, admin=True) if not self.has_segment_extension(client=client): return None diff --git a/nova/tests/unit/network/test_neutron.py b/nova/tests/unit/network/test_neutron.py index dbcfa80c27..8d6e063899 100644 --- a/nova/tests/unit/network/test_neutron.py +++ b/nova/tests/unit/network/test_neutron.py @@ -7026,13 +7026,17 @@ class TestAPI(TestAPIBase): req_lvl_params.same_subtree, ) - def test_get_segment_ids_for_network_no_segment_ext(self): + @mock.patch.object(neutronapi, 'get_client') + def test_get_segment_ids_for_network_no_segment_ext(self, mock_client): + mocked_client = mock.create_autospec(client.Client) + mock_client.return_value = mocked_client with mock.patch.object( self.api, 'has_segment_extension', return_value=False, ): self.assertEqual( [], self.api.get_segment_ids_for_network(self.context, uuids.network_id)) + mock_client.assert_called_once_with(self.context, admin=True) @mock.patch.object(neutronapi, 'get_client') def test_get_segment_ids_for_network_passes(self, mock_client): @@ -7046,6 +7050,7 @@ class TestAPI(TestAPIBase): res = self.api.get_segment_ids_for_network( self.context, uuids.network_id) self.assertEqual([uuids.segment_id], res) + mock_client.assert_called_once_with(self.context, admin=True) mocked_client.list_subnets.assert_called_once_with( network_id=uuids.network_id, fields='segment_id') @@ -7061,6 +7066,7 @@ class TestAPI(TestAPIBase): res = self.api.get_segment_ids_for_network( self.context, uuids.network_id) self.assertEqual([], res) + mock_client.assert_called_once_with(self.context, admin=True) mocked_client.list_subnets.assert_called_once_with( network_id=uuids.network_id, fields='segment_id') @@ -7076,14 +7082,19 @@ class TestAPI(TestAPIBase): self.assertRaises(exception.InvalidRoutedNetworkConfiguration, self.api.get_segment_ids_for_network, self.context, uuids.network_id) + mock_client.assert_called_once_with(self.context, admin=True) - def test_get_segment_id_for_subnet_no_segment_ext(self): + @mock.patch.object(neutronapi, 'get_client') + def test_get_segment_id_for_subnet_no_segment_ext(self, mock_client): + mocked_client = mock.create_autospec(client.Client) + mock_client.return_value = mocked_client with mock.patch.object( self.api, 'has_segment_extension', return_value=False, ): self.assertIsNone( self.api.get_segment_id_for_subnet(self.context, uuids.subnet_id)) + mock_client.assert_called_once_with(self.context, admin=True) @mock.patch.object(neutronapi, 'get_client') def test_get_segment_id_for_subnet_passes(self, mock_client): @@ -7097,6 +7108,7 @@ class TestAPI(TestAPIBase): res = self.api.get_segment_id_for_subnet( self.context, uuids.subnet_id) self.assertEqual(uuids.segment_id, res) + mock_client.assert_called_once_with(self.context, admin=True) mocked_client.show_subnet.assert_called_once_with(uuids.subnet_id) @mock.patch.object(neutronapi, 'get_client') @@ -7111,6 +7123,7 @@ class TestAPI(TestAPIBase): self.assertIsNone( self.api.get_segment_id_for_subnet(self.context, uuids.subnet_id)) + mock_client.assert_called_once_with(self.context, admin=True) @mock.patch.object(neutronapi, 'get_client') def test_get_segment_id_for_subnet_fails(self, mock_client): @@ -7124,6 +7137,7 @@ class TestAPI(TestAPIBase): self.assertRaises(exception.InvalidRoutedNetworkConfiguration, self.api.get_segment_id_for_subnet, self.context, uuids.subnet_id) + mock_client.assert_called_once_with(self.context, admin=True) @mock.patch.object(neutronapi.LOG, 'debug') def test_get_port_pci_dev(self, mock_debug): |