From ccf4ace2b52376a5f64b7b831214802194b41c82 Mon Sep 17 00:00:00 2001 From: Jaromir Wysoglad Date: Wed, 16 Apr 2025 17:36:57 -0400 Subject: [PATCH] Enable providing keystone session for Prometheus This enables us to create a PrometheusAPIClient, which uses a keystone session when communicating with Prometheus, which causes the requests to include an X-Auth-Token header with the user's keystone token. This will enable observabilityclient to authenticate when communicating with Aetos in the future. Change-Id: I3693a6906efccdbb193ddd1e927ed83975592442 --- observabilityclient/prometheus_client.py | 10 +++++++--- .../tests/unit/test_prometheus_client.py | 3 ++- observabilityclient/tests/unit/test_utils.py | 13 +++++++------ observabilityclient/utils/metric_utils.py | 4 ++-- observabilityclient/v1/client.py | 2 +- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/observabilityclient/prometheus_client.py b/observabilityclient/prometheus_client.py index 68483f8..b76b288 100644 --- a/observabilityclient/prometheus_client.py +++ b/observabilityclient/prometheus_client.py @@ -53,9 +53,12 @@ class PrometheusMetric(object): class PrometheusAPIClient(object): - def __init__(self, host): + def __init__(self, host, session=None): self._host = host - self._session = requests.Session() + if session is None: + self._session = requests.Session() + else: + self._session = session self._session.verify = False def set_ca_cert(self, ca_cert): @@ -75,7 +78,8 @@ class PrometheusAPIClient(object): def _get(self, endpoint, params=None): url = self._get_url(endpoint) resp = self._session.get(url, params=params, - headers={'Accept': 'application/json'}) + headers={'Accept': 'application/json', + 'Accept-Encoding': 'identity'}) if resp.status_code != requests.codes.ok: raise PrometheusAPIClientError(resp) decoded = resp.json() diff --git a/observabilityclient/tests/unit/test_prometheus_client.py b/observabilityclient/tests/unit/test_prometheus_client.py index ecba20d..61ff8a3 100644 --- a/observabilityclient/tests/unit/test_prometheus_client.py +++ b/observabilityclient/tests/unit/test_prometheus_client.py @@ -98,7 +98,8 @@ class PrometheusAPIClientTest(PrometheusAPIClientTestBase): m.assert_called_with(expected_url, params=expected_params, - headers={'Accept': 'application/json'}) + headers={'Accept': 'application/json', + 'Accept-Encoding': 'identity'}) def test_get_error(self): url = "test" diff --git a/observabilityclient/tests/unit/test_utils.py b/observabilityclient/tests/unit/test_utils.py index d9d734d..9764e90 100644 --- a/observabilityclient/tests/unit/test_utils.py +++ b/observabilityclient/tests/unit/test_utils.py @@ -55,19 +55,20 @@ class GetPrometheusClientTest(testtools.TestCase): mock.patch.object(prometheus_client.PrometheusAPIClient, "__init__", return_value=None) as m: metric_utils.get_prometheus_client() - m.assert_called_with("somehost:1234") + m.assert_called_with("somehost:1234", None) - def test_get_prometheus_client_env_overide(self): - with mock.patch.dict(os.environ, {'PROMETHEUS_HOST': 'env_overide'}), \ + def test_get_prometheus_client_env_override(self): + with mock.patch.dict(os.environ, + {'PROMETHEUS_HOST': 'env_override'}), \ mock.patch.object(metric_utils, 'get_config_file', return_value=self.config_file), \ mock.patch.object(prometheus_client.PrometheusAPIClient, "__init__", return_value=None) as m: metric_utils.get_prometheus_client() - m.assert_called_with("env_overide:1234") + m.assert_called_with("env_override:1234", None) def test_get_prometheus_client_no_config_file(self): - patched_env = {'PROMETHEUS_HOST': 'env_overide', + patched_env = {'PROMETHEUS_HOST': 'env_override', 'PROMETHEUS_PORT': 'env_port'} with mock.patch.dict(os.environ, patched_env), \ mock.patch.object(metric_utils, 'get_config_file', @@ -75,7 +76,7 @@ class GetPrometheusClientTest(testtools.TestCase): mock.patch.object(prometheus_client.PrometheusAPIClient, "__init__", return_value=None) as m: metric_utils.get_prometheus_client() - m.assert_called_with("env_overide:env_port") + m.assert_called_with("env_override:env_port", None) def test_get_prometheus_client_missing_configuration(self): with mock.patch.dict(os.environ, {}), \ diff --git a/observabilityclient/utils/metric_utils.py b/observabilityclient/utils/metric_utils.py index b3eb5e9..925f049 100644 --- a/observabilityclient/utils/metric_utils.py +++ b/observabilityclient/utils/metric_utils.py @@ -45,7 +45,7 @@ def get_config_file(): return None -def get_prometheus_client(): +def get_prometheus_client(session=None): host = None port = None ca_cert = None @@ -71,7 +71,7 @@ def get_prometheus_client(): if host is None or port is None: raise ConfigurationError("Can't find prometheus host and " "port configuration.") - client = PrometheusAPIClient(f"{host}:{port}") # noqa: E231 + client = PrometheusAPIClient(f"{host}:{port}", session) # noqa: E231 if ca_cert is not None: client.set_ca_cert(ca_cert) return client diff --git a/observabilityclient/v1/client.py b/observabilityclient/v1/client.py index d0ed250..2023745 100644 --- a/observabilityclient/v1/client.py +++ b/observabilityclient/v1/client.py @@ -38,6 +38,6 @@ class Client(object): self.session = session - self.prometheus_client = get_prometheus_client() + self.prometheus_client = get_prometheus_client(session) self.query = python_api.QueryManager(self) self.rbac = rbac.Rbac(self, self.session, disable_rbac)