Add root_path configuration option
This allows to specify a root path to prepend each api call. Change-Id: I033553809c72608388250d3ac66e17b5a2784e61
This commit is contained in:
@@ -53,13 +53,18 @@ class PrometheusMetric(object):
|
|||||||
|
|
||||||
|
|
||||||
class PrometheusAPIClient(object):
|
class PrometheusAPIClient(object):
|
||||||
def __init__(self, host, session=None):
|
def __init__(self, host, session=None, root_path=""):
|
||||||
self._host = host
|
self._host = host
|
||||||
|
if not self._host.endswith('/'):
|
||||||
|
self._host += '/'
|
||||||
if session is None:
|
if session is None:
|
||||||
self._session = requests.Session()
|
self._session = requests.Session()
|
||||||
else:
|
else:
|
||||||
self._session = session
|
self._session = session
|
||||||
self._session.verify = False
|
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):
|
def set_ca_cert(self, ca_cert):
|
||||||
self._session.verify = ca_cert
|
self._session.verify = ca_cert
|
||||||
@@ -73,7 +78,7 @@ class PrometheusAPIClient(object):
|
|||||||
|
|
||||||
def _get_url(self, endpoint):
|
def _get_url(self, endpoint):
|
||||||
scheme = 'https' if self._session.verify else 'http'
|
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):
|
def _get(self, endpoint, params=None):
|
||||||
url = self._get_url(endpoint)
|
url = self._get_url(endpoint)
|
||||||
|
@@ -85,7 +85,8 @@ class PrometheusAPIClientTestBase(testtools.TestCase):
|
|||||||
class PrometheusAPIClientTest(PrometheusAPIClientTestBase):
|
class PrometheusAPIClientTest(PrometheusAPIClientTestBase):
|
||||||
def test_get(self):
|
def test_get(self):
|
||||||
url = "test"
|
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'}"}
|
params = {"query": "ceilometer_image_size{publisher='localhost'}"}
|
||||||
expected_params = params
|
expected_params = params
|
||||||
@@ -93,7 +94,8 @@ class PrometheusAPIClientTest(PrometheusAPIClientTestBase):
|
|||||||
return_value = self.GoodResponse()
|
return_value = self.GoodResponse()
|
||||||
with mock.patch.object(requests.Session, 'get',
|
with mock.patch.object(requests.Session, 'get',
|
||||||
return_value=return_value) as m:
|
return_value=return_value) as m:
|
||||||
c = client.PrometheusAPIClient("localhost:9090")
|
c = client.PrometheusAPIClient("localhost:9090",
|
||||||
|
root_path=root_path)
|
||||||
c._get(url, params)
|
c._get(url, params)
|
||||||
|
|
||||||
m.assert_called_with(expected_url,
|
m.assert_called_with(expected_url,
|
||||||
@@ -121,7 +123,7 @@ class PrometheusAPIClientTest(PrometheusAPIClientTestBase):
|
|||||||
|
|
||||||
def test_post(self):
|
def test_post(self):
|
||||||
url = "test"
|
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'}"}
|
params = {"query": "ceilometer_image_size{publisher='localhost'}"}
|
||||||
expected_params = params
|
expected_params = params
|
||||||
|
@@ -55,7 +55,7 @@ class GetPrometheusClientTest(testtools.TestCase):
|
|||||||
mock.patch.object(prometheus_client.PrometheusAPIClient,
|
mock.patch.object(prometheus_client.PrometheusAPIClient,
|
||||||
"__init__", return_value=None) as m:
|
"__init__", return_value=None) as m:
|
||||||
metric_utils.get_prometheus_client()
|
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):
|
def test_get_prometheus_client_env_override(self):
|
||||||
with mock.patch.dict(os.environ,
|
with mock.patch.dict(os.environ,
|
||||||
@@ -65,7 +65,7 @@ class GetPrometheusClientTest(testtools.TestCase):
|
|||||||
mock.patch.object(prometheus_client.PrometheusAPIClient,
|
mock.patch.object(prometheus_client.PrometheusAPIClient,
|
||||||
"__init__", return_value=None) as m:
|
"__init__", return_value=None) as m:
|
||||||
metric_utils.get_prometheus_client()
|
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):
|
def test_get_prometheus_client_no_config_file(self):
|
||||||
patched_env = {'PROMETHEUS_HOST': 'env_override',
|
patched_env = {'PROMETHEUS_HOST': 'env_override',
|
||||||
@@ -76,7 +76,19 @@ class GetPrometheusClientTest(testtools.TestCase):
|
|||||||
mock.patch.object(prometheus_client.PrometheusAPIClient,
|
mock.patch.object(prometheus_client.PrometheusAPIClient,
|
||||||
"__init__", return_value=None) as m:
|
"__init__", return_value=None) as m:
|
||||||
metric_utils.get_prometheus_client()
|
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):
|
def test_get_prometheus_client_missing_configuration(self):
|
||||||
with mock.patch.dict(os.environ, {}), \
|
with mock.patch.dict(os.environ, {}), \
|
||||||
|
@@ -49,6 +49,7 @@ def get_prometheus_client(session=None):
|
|||||||
host = None
|
host = None
|
||||||
port = None
|
port = None
|
||||||
ca_cert = None
|
ca_cert = None
|
||||||
|
root_path = ""
|
||||||
conf_file = get_config_file()
|
conf_file = get_config_file()
|
||||||
if conf_file is not None:
|
if conf_file is not None:
|
||||||
conf = yaml.safe_load(conf_file)
|
conf = yaml.safe_load(conf_file)
|
||||||
@@ -58,6 +59,8 @@ def get_prometheus_client(session=None):
|
|||||||
port = conf['port']
|
port = conf['port']
|
||||||
if 'ca_cert' in conf:
|
if 'ca_cert' in conf:
|
||||||
ca_cert = conf['ca_cert']
|
ca_cert = conf['ca_cert']
|
||||||
|
if 'root_path' in conf:
|
||||||
|
root_path = conf['root_path']
|
||||||
conf_file.close()
|
conf_file.close()
|
||||||
|
|
||||||
# NOTE(jwysogla): We allow to overide the prometheus.yaml by
|
# 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']
|
port = os.environ['PROMETHEUS_PORT']
|
||||||
if 'PROMETHEUS_CA_CERT' in os.environ:
|
if 'PROMETHEUS_CA_CERT' in os.environ:
|
||||||
ca_cert = os.environ['PROMETHEUS_CA_CERT']
|
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:
|
if host is None or port is None:
|
||||||
raise ConfigurationError("Can't find prometheus host and "
|
raise ConfigurationError("Can't find prometheus host and "
|
||||||
"port configuration.")
|
"port configuration.")
|
||||||
client = PrometheusAPIClient(f"{host}:{port}", session) # noqa: E231
|
client = PrometheusAPIClient(f"{host}:{port}", session, root_path)
|
||||||
if ca_cert is not None:
|
if ca_cert is not None:
|
||||||
client.set_ca_cert(ca_cert)
|
client.set_ca_cert(ca_cert)
|
||||||
return client
|
return client
|
||||||
|
9
releasenotes/notes/add-root-path-192ac0e6ea99b84f.yaml
Normal file
9
releasenotes/notes/add-root-path-192ac0e6ea99b84f.yaml
Normal 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.
|
Reference in New Issue
Block a user