Merge "Add root_path configuration option"

This commit is contained in:
Zuul 2025-04-28 10:50:41 +00:00 committed by Gerrit Code Review
commit ab8ce8fd34
5 changed files with 42 additions and 9 deletions

View File

@ -53,13 +53,18 @@ class PrometheusMetric(object):
class PrometheusAPIClient(object):
def __init__(self, host, session=None):
def __init__(self, host, session=None, root_path=""):
self._host = host
if not self._host.endswith('/'):
self._host += '/'
if session is None:
self._session = requests.Session()
else:
self._session = session
self._session.verify = False
self._root_path = root_path
if root_path != "" and not self._root_path.endswith('/'):
self._root_path += '/'
def set_ca_cert(self, ca_cert):
self._session.verify = ca_cert
@ -73,7 +78,7 @@ class PrometheusAPIClient(object):
def _get_url(self, endpoint):
scheme = 'https' if self._session.verify else 'http'
return f"{scheme}://{self._host}/api/v1/{endpoint}" # noqa: E231
return f"{scheme}://{self._host}{self._root_path}api/v1/{endpoint}"
def _get(self, endpoint, params=None):
url = self._get_url(endpoint)

View File

@ -85,7 +85,8 @@ class PrometheusAPIClientTestBase(testtools.TestCase):
class PrometheusAPIClientTest(PrometheusAPIClientTestBase):
def test_get(self):
url = "test"
expected_url = "http://localhost:9090/api/v1/test"
root_path = "root_path"
expected_url = f"http://localhost:9090/{root_path}/api/v1/{url}"
params = {"query": "ceilometer_image_size{publisher='localhost'}"}
expected_params = params
@ -93,7 +94,8 @@ class PrometheusAPIClientTest(PrometheusAPIClientTestBase):
return_value = self.GoodResponse()
with mock.patch.object(requests.Session, 'get',
return_value=return_value) as m:
c = client.PrometheusAPIClient("localhost:9090")
c = client.PrometheusAPIClient("localhost:9090",
root_path=root_path)
c._get(url, params)
m.assert_called_with(expected_url,
@ -121,7 +123,7 @@ class PrometheusAPIClientTest(PrometheusAPIClientTestBase):
def test_post(self):
url = "test"
expected_url = "http://localhost:9090/api/v1/test"
expected_url = f"http://localhost:9090/api/v1/{url}"
params = {"query": "ceilometer_image_size{publisher='localhost'}"}
expected_params = params

View File

@ -55,7 +55,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("somehost:1234", None)
m.assert_called_with("somehost:1234", None, "")
def test_get_prometheus_client_env_override(self):
with mock.patch.dict(os.environ,
@ -65,7 +65,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_override:1234", None)
m.assert_called_with("env_override:1234", None, "")
def test_get_prometheus_client_no_config_file(self):
patched_env = {'PROMETHEUS_HOST': 'env_override',
@ -76,7 +76,19 @@ 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_override:env_port", None)
m.assert_called_with("env_override:env_port", None, "")
def test_get_prometheus_client_prefix_in_env_variable(self):
patched_env = {'PROMETHEUS_HOST': 'env_override',
'PROMETHEUS_PORT': 'env_port',
'PROMETHEUS_ROOT_PATH': 'root_path_env'}
with mock.patch.dict(os.environ, patched_env), \
mock.patch.object(metric_utils, 'get_config_file',
return_value=None), \
mock.patch.object(prometheus_client.PrometheusAPIClient,
"__init__", return_value=None) as m:
metric_utils.get_prometheus_client()
m.assert_called_with("env_override:env_port", None, "root_path_env")
def test_get_prometheus_client_missing_configuration(self):
with mock.patch.dict(os.environ, {}), \

View File

@ -49,6 +49,7 @@ def get_prometheus_client(session=None):
host = None
port = None
ca_cert = None
root_path = ""
conf_file = get_config_file()
if conf_file is not None:
conf = yaml.safe_load(conf_file)
@ -58,6 +59,8 @@ def get_prometheus_client(session=None):
port = conf['port']
if 'ca_cert' in conf:
ca_cert = conf['ca_cert']
if 'root_path' in conf:
root_path = conf['root_path']
conf_file.close()
# NOTE(jwysogla): We allow to overide the prometheus.yaml by
@ -68,10 +71,12 @@ def get_prometheus_client(session=None):
port = os.environ['PROMETHEUS_PORT']
if 'PROMETHEUS_CA_CERT' in os.environ:
ca_cert = os.environ['PROMETHEUS_CA_CERT']
if 'PROMETHEUS_ROOT_PATH' in os.environ:
root_path = os.environ['PROMETHEUS_ROOT_PATH']
if host is None or port is None:
raise ConfigurationError("Can't find prometheus host and "
"port configuration.")
client = PrometheusAPIClient(f"{host}:{port}", session) # noqa: E231
client = PrometheusAPIClient(f"{host}:{port}", session, root_path)
if ca_cert is not None:
client.set_ca_cert(ca_cert)
return client

View File

@ -0,0 +1,9 @@
---
features:
- |
Added a "root_path" configuration option with a PROMETHEUS_ROOT_PATH
environment variable override, which allows to set a root path, which gets
prepended to the URL path section for each Prometheus API call. So for
example when Prometheus is hosted on localhost:80/prometheus, setting the
root_path to "prometheus" will enable the observabilityclient to send
requests to URLs like localhost:80/prometheus/api/v1/labels.