summaryrefslogtreecommitdiff
path: root/nova
diff options
context:
space:
mode:
authorAndrew Bonney <andrew.bonney@bbc.co.uk>2022-04-26 11:35:38 +0100
committerAndrew Bonney <andrew.bonney@bbc.co.uk>2022-05-06 06:53:49 +0000
commit60548e804219d91d8c68ab3d74dd0ae956cd33f3 (patch)
tree461ce699a050522feae5a2423ec250d0229ac5b5 /nova
parent1ac0d6984a43cddbb5a2f1a2f7bc115fd83517c9 (diff)
downloadnova-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.py4
-rw-r--r--nova/tests/unit/network/test_neutron.py18
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):