summaryrefslogtreecommitdiff
path: root/nova
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2023-05-13 19:58:49 +0000
committerGerrit Code Review <review@openstack.org>2023-05-13 19:58:49 +0000
commit078fd242d1aae5cc3abc4591023ff40cd904b3f2 (patch)
tree7eceb7136f7976fa9f414c40a98fb9ff666c18a5 /nova
parent0e511c799d0a6b46cbabcc4f36d306245010d1b2 (diff)
parent0d6dd6c67f56c9d4ed36246d14f119da6bca0a5a (diff)
downloadnova-078fd242d1aae5cc3abc4591023ff40cd904b3f2.tar.gz
Merge "Enable use of service user token with admin context" into stable/zed
Diffstat (limited to 'nova')
-rw-r--r--nova/network/neutron.py8
-rw-r--r--nova/service_auth.py6
-rw-r--r--nova/tests/unit/network/test_neutron.py16
-rw-r--r--nova/tests/unit/test_service_auth.py10
-rw-r--r--nova/tests/unit/volume/test_cinder.py11
-rw-r--r--nova/volume/cinder.py8
6 files changed, 51 insertions, 8 deletions
diff --git a/nova/network/neutron.py b/nova/network/neutron.py
index 27e7d06455..affd76535f 100644
--- a/nova/network/neutron.py
+++ b/nova/network/neutron.py
@@ -222,13 +222,15 @@ def _get_auth_plugin(context, admin=False):
# support some services (metadata API) where an admin context is used
# without an auth token.
global _ADMIN_AUTH
+ user_auth = None
if admin or (context.is_admin and not context.auth_token):
if not _ADMIN_AUTH:
_ADMIN_AUTH = _load_auth_plugin(CONF)
- return _ADMIN_AUTH
+ user_auth = _ADMIN_AUTH
- if context.auth_token:
- return service_auth.get_auth_plugin(context)
+ if context.auth_token or user_auth:
+ # When user_auth = None, user_auth will be extracted from the context.
+ return service_auth.get_auth_plugin(context, user_auth=user_auth)
# We did not get a user token and we should not be using
# an admin token so log an error
diff --git a/nova/service_auth.py b/nova/service_auth.py
index f5ae0646d8..aa8fd8fa12 100644
--- a/nova/service_auth.py
+++ b/nova/service_auth.py
@@ -30,8 +30,10 @@ def reset_globals():
_SERVICE_AUTH = None
-def get_auth_plugin(context):
- user_auth = context.get_auth_plugin()
+def get_auth_plugin(context, user_auth=None):
+ # user_auth may be passed in when the RequestContext is anonymous, such as
+ # when get_admin_context() is used for API calls by nova-manage.
+ user_auth = user_auth or context.get_auth_plugin()
if CONF.service_user.send_service_user_token:
global _SERVICE_AUTH
diff --git a/nova/tests/unit/network/test_neutron.py b/nova/tests/unit/network/test_neutron.py
index eefa7b974f..fec66fb2d3 100644
--- a/nova/tests/unit/network/test_neutron.py
+++ b/nova/tests/unit/network/test_neutron.py
@@ -142,6 +142,22 @@ class TestNeutronClient(test.NoDBTestCase):
self.assertIsInstance(cl.httpclient.auth,
service_token.ServiceTokenAuthWrapper)
+ @mock.patch('nova.service_auth._SERVICE_AUTH')
+ @mock.patch('nova.network.neutron._ADMIN_AUTH')
+ @mock.patch.object(ks_loading, 'load_auth_from_conf_options')
+ def test_admin_with_service_token(
+ self, mock_load, mock_admin_auth, mock_service_auth
+ ):
+ self.flags(send_service_user_token=True, group='service_user')
+
+ admin_context = context.get_admin_context()
+
+ cl = neutronapi.get_client(admin_context)
+ self.assertIsInstance(cl.httpclient.auth,
+ service_token.ServiceTokenAuthWrapper)
+ self.assertEqual(mock_admin_auth, cl.httpclient.auth.user_auth)
+ self.assertEqual(mock_service_auth, cl.httpclient.auth.service_auth)
+
@mock.patch.object(client.Client, "list_networks",
side_effect=exceptions.Unauthorized())
def test_Unauthorized_user(self, mock_list_networks):
diff --git a/nova/tests/unit/test_service_auth.py b/nova/tests/unit/test_service_auth.py
index 5f07515188..8966af3ce3 100644
--- a/nova/tests/unit/test_service_auth.py
+++ b/nova/tests/unit/test_service_auth.py
@@ -56,3 +56,13 @@ class ServiceAuthTestCase(test.NoDBTestCase):
result = service_auth.get_auth_plugin(self.ctx)
self.assertEqual(1, mock_load.call_count)
self.assertNotIsInstance(result, service_token.ServiceTokenAuthWrapper)
+
+ @mock.patch.object(ks_loading, 'load_auth_from_conf_options',
+ new=mock.Mock())
+ def test_get_auth_plugin_user_auth(self):
+ self.flags(send_service_user_token=True, group='service_user')
+ user_auth = mock.Mock()
+
+ result = service_auth.get_auth_plugin(self.ctx, user_auth=user_auth)
+
+ self.assertEqual(user_auth, result.user_auth)
diff --git a/nova/tests/unit/volume/test_cinder.py b/nova/tests/unit/volume/test_cinder.py
index e53ebe3cb8..f9080726fb 100644
--- a/nova/tests/unit/volume/test_cinder.py
+++ b/nova/tests/unit/volume/test_cinder.py
@@ -1276,3 +1276,14 @@ class CinderClientTestCase(test.NoDBTestCase):
admin_ctx = context.get_admin_context()
params = cinder._get_cinderclient_parameters(admin_ctx)
self.assertEqual(params[0], mock_admin_auth)
+
+ @mock.patch('nova.service_auth._SERVICE_AUTH')
+ @mock.patch('nova.volume.cinder._ADMIN_AUTH')
+ def test_admin_context_without_user_token_but_with_service_token(
+ self, mock_admin_auth, mock_service_auth
+ ):
+ self.flags(send_service_user_token=True, group='service_user')
+ admin_ctx = context.get_admin_context()
+ params = cinder._get_cinderclient_parameters(admin_ctx)
+ self.assertEqual(mock_admin_auth, params[0].user_auth)
+ self.assertEqual(mock_service_auth, params[0].service_auth)
diff --git a/nova/volume/cinder.py b/nova/volume/cinder.py
index 01efcfec19..f5328148d2 100644
--- a/nova/volume/cinder.py
+++ b/nova/volume/cinder.py
@@ -91,12 +91,14 @@ def _get_auth(context):
# from them generated from 'context.get_admin_context'
# which only set is_admin=True but is without token.
# So add load_auth_plugin when this condition appear.
+ user_auth = None
if context.is_admin and not context.auth_token:
if not _ADMIN_AUTH:
_ADMIN_AUTH = _load_auth_plugin(CONF)
- return _ADMIN_AUTH
- else:
- return service_auth.get_auth_plugin(context)
+ user_auth = _ADMIN_AUTH
+
+ # When user_auth = None, user_auth will be extracted from the context.
+ return service_auth.get_auth_plugin(context, user_auth=user_auth)
# NOTE(efried): Bug #1752152