From a9001b5e972ab28d073faedd908928dbc7553825 Mon Sep 17 00:00:00 2001 From: Emma Foley Date: Fri, 12 Dec 2025 14:42:37 -0500 Subject: [PATCH] [keystone] Add convenience function to use openstacksdk Adds a convenience function that can be used in place of get_client and returns a openstack.connection instead of keystoneclient.Client. This commit has no impact on existing functions, since the change requires explicitly using get_connection instead of get_client when interacting with ceilometer.keystoneclient Depends-On: https://review.opendev.org/c/openstack/telemetry-tempest-plugin/+/978293 Change-Id: I95969a6091bb47c48695eae3631cfc0d01ab263c Signed-off-by: Emma Foley --- ceilometer/keystone_client.py | 19 +++++ ceilometer/tests/unit/test_keystone_client.py | 85 +++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/ceilometer/keystone_client.py b/ceilometer/keystone_client.py index ebb6a33163..de01eb5a34 100644 --- a/ceilometer/keystone_client.py +++ b/ceilometer/keystone_client.py @@ -17,6 +17,7 @@ import os from keystoneauth1 import loading as ka_loading from keystoneclient.v3 import client as ks_client_v3 +from openstack import connection from oslo_config import cfg DEFAULT_GROUP = "service_credentials" @@ -38,6 +39,22 @@ def get_session(conf, requests_session=None, group=None, timeout=None): return session +def get_connection( + conf, service_type="identity", + requests_session=None, group=DEFAULT_GROUP): + """Get an openstacksdk connection to interact with openstack services.""" + sess = get_session( + conf, requests_session=requests_session, group=group) + + # https://github.com/openstack/nova/blob/master/nova/utils.py#L905 + conn = connection.Connection( + session=sess, + oslo_conf=conf, + service_types={service_type} + ) + return conn + + def get_client(conf, trust_id=None, requests_session=None, group=DEFAULT_GROUP): """Return a client for keystone v3 endpoint, optionally using a trust.""" @@ -68,6 +85,8 @@ def get_urls( def get_auth_token(client): + # NOTE: client.session.get_token() can be used for both + # keystoneclient.v3.client.Client and openstack.connection.Connection return client.session.auth.get_access(client.session).auth_token diff --git a/ceilometer/tests/unit/test_keystone_client.py b/ceilometer/tests/unit/test_keystone_client.py index 490bee50e4..c85d873ea3 100644 --- a/ceilometer/tests/unit/test_keystone_client.py +++ b/ceilometer/tests/unit/test_keystone_client.py @@ -22,6 +22,7 @@ from oslo_config import fixture as config_fixture from ceilometer import keystone_client from ceilometer import service as ceilo_service from ceilometer.tests import base +import openstack CONF = cfg.CONF @@ -175,6 +176,75 @@ class TestKeystoneClient(base.BaseTestCase): auth=mock_load_auth.return_value, session=None, timeout=100) self.assertIsInstance(session, FakeSession) + @mock.patch('ceilometer.keystone_client.get_session', autospec=True) + @mock.patch('openstack.connection.Connection', autospec=True) + def test_get_connection(self, mock_connection, mock_get_session): + actual_conn = keystone_client.get_connection(self.CONF) + + mock_get_session.assert_called_once_with( + self.CONF, + requests_session=None, + group=keystone_client.DEFAULT_GROUP) + mock_connection.assert_called_once_with( + session=mock_get_session.return_value, + oslo_conf=self.CONF, + service_types={"identity"}) + self.assertEqual(actual_conn, mock_connection.return_value) + + @mock.patch('ceilometer.keystone_client.get_session', autospec=True) + @mock.patch('openstack.connection.Connection', autospec=True) + def test_get_connection_service_type( + self, mock_connection, mock_get_session): + actual_conn = keystone_client.get_connection( + self.CONF, service_type="other_service_type") + + mock_get_session.assert_called_once_with( + self.CONF, + requests_session=None, + group=keystone_client.DEFAULT_GROUP) + mock_connection.assert_called_once_with( + session=mock_get_session.return_value, + oslo_conf=self.CONF, + service_types={"other_service_type"}) + self.assertEqual(actual_conn, mock_connection.return_value) + + @mock.patch('ceilometer.keystone_client.get_session', autospec=True) + @mock.patch('openstack.connection.Connection', autospec=True) + def test_get_connection_existing_session( + self, mock_connection, mock_get_session): + mock_session = mock.Mock() + + actual_conn = keystone_client.get_connection( + self.CONF, requests_session=mock_session) + + mock_get_session.assert_called_once_with( + self.CONF, + requests_session=mock_session, + group=keystone_client.DEFAULT_GROUP) + mock_connection.assert_called_once_with( + session=mock_get_session.return_value, + oslo_conf=self.CONF, + service_types={"identity"}) + self.assertEqual(actual_conn, mock_connection.return_value) + + @mock.patch('ceilometer.keystone_client.get_session', autospec=True) + @mock.patch('openstack.connection.Connection', autospec=True) + def test_get_connection_new_group( + self, mock_connection, mock_get_session): + + actual_conn = keystone_client.get_connection( + self.CONF, group="some_group") + + mock_get_session.assert_called_once_with( + self.CONF, + requests_session=None, + group="some_group") + mock_connection.assert_called_once_with( + session=mock_get_session.return_value, + oslo_conf=self.CONF, + service_types={"identity"}) + self.assertEqual(actual_conn, mock_connection.return_value) + @mock.patch('keystoneclient.v3.client.Client', autospec=True) @mock.patch('ceilometer.keystone_client.get_session', autospec=True) def test_get_client(self, mock_get_session, mock_ks_client): @@ -623,4 +693,19 @@ class TestKeystoneClient(base.BaseTestCase): mock_client.session.auth.get_access.assert_called_once_with( mock_client.session) + self.assertIsInstance(result, str) self.assertEqual(result, 'auth_token') + + def test_get_auth_token_from_openstacksdk_connection(self): + mock_connection = mock.Mock(spec=openstack.connection.Connection) + mock_connection.session = mock.Mock() + mock_access = mock.Mock() + mock_access.auth_token = 'my_connection_auth_token' + mock_connection.session.auth.get_access.return_value = mock_access + + result = keystone_client.get_auth_token(mock_connection) + + mock_connection.session.auth.get_access.assert_called_once_with( + mock_connection.session) + self.assertIsInstance(result, str) + self.assertEqual(result, 'my_connection_auth_token')