Merge "Retrieve prometheus information from keystone"
This commit is contained in:
@@ -15,6 +15,8 @@
|
|||||||
import os
|
import os
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
from keystoneauth1 import adapter
|
||||||
|
from keystoneauth1 import session
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
from observabilityclient import prometheus_client
|
from observabilityclient import prometheus_client
|
||||||
@@ -99,6 +101,62 @@ class GetPrometheusClientTest(testtools.TestCase):
|
|||||||
self.assertRaises(metric_utils.ConfigurationError,
|
self.assertRaises(metric_utils.ConfigurationError,
|
||||||
metric_utils.get_prometheus_client)
|
metric_utils.get_prometheus_client)
|
||||||
|
|
||||||
|
def test_get_prometheus_client_from_keystone_http(self):
|
||||||
|
prometheus_endpoint = "http://localhost:1234/prometheus"
|
||||||
|
keystone_session = session.Session()
|
||||||
|
with mock.patch.dict(os.environ, {}), \
|
||||||
|
mock.patch.object(metric_utils, 'get_config_file',
|
||||||
|
return_value=None), \
|
||||||
|
mock.patch.object(adapter.Adapter, 'get_endpoint',
|
||||||
|
return_value=prometheus_endpoint), \
|
||||||
|
mock.patch.object(prometheus_client.PrometheusAPIClient,
|
||||||
|
"__init__", return_value=None) as init_m, \
|
||||||
|
mock.patch.object(prometheus_client.PrometheusAPIClient,
|
||||||
|
"set_ca_cert") as ca_m:
|
||||||
|
metric_utils.get_prometheus_client(keystone_session)
|
||||||
|
init_m.assert_called_with(
|
||||||
|
"localhost:1234", keystone_session, "prometheus"
|
||||||
|
)
|
||||||
|
ca_m.assert_not_called()
|
||||||
|
|
||||||
|
def test_get_prometheus_client_from_keystone_https(self):
|
||||||
|
prometheus_endpoint = "https://localhost:1234/prometheus"
|
||||||
|
keystone_session = session.Session()
|
||||||
|
with mock.patch.dict(os.environ, {}), \
|
||||||
|
mock.patch.object(metric_utils, 'get_config_file',
|
||||||
|
return_value=None), \
|
||||||
|
mock.patch.object(adapter.Adapter, 'get_endpoint',
|
||||||
|
return_value=prometheus_endpoint), \
|
||||||
|
mock.patch.object(prometheus_client.PrometheusAPIClient,
|
||||||
|
"__init__", return_value=None) as init_m, \
|
||||||
|
mock.patch.object(prometheus_client.PrometheusAPIClient,
|
||||||
|
"set_ca_cert") as ca_m:
|
||||||
|
metric_utils.get_prometheus_client(keystone_session)
|
||||||
|
init_m.assert_called_with(
|
||||||
|
"localhost:1234", keystone_session, "prometheus"
|
||||||
|
)
|
||||||
|
ca_m.assert_called_with(True)
|
||||||
|
|
||||||
|
def test_get_prometheus_client_from_keystone_custom_ca(self):
|
||||||
|
prometheus_endpoint = "https://localhost:1234/prometheus"
|
||||||
|
keystone_session = session.Session()
|
||||||
|
config_data = 'ca_cert: "ca/path"'
|
||||||
|
config_file = mock.mock_open(read_data=config_data)("name", 'r')
|
||||||
|
with mock.patch.dict(os.environ, {}), \
|
||||||
|
mock.patch.object(metric_utils, 'get_config_file',
|
||||||
|
return_value=config_file), \
|
||||||
|
mock.patch.object(adapter.Adapter, 'get_endpoint',
|
||||||
|
return_value=prometheus_endpoint), \
|
||||||
|
mock.patch.object(prometheus_client.PrometheusAPIClient,
|
||||||
|
"__init__", return_value=None) as init_m, \
|
||||||
|
mock.patch.object(prometheus_client.PrometheusAPIClient,
|
||||||
|
"set_ca_cert") as ca_m:
|
||||||
|
metric_utils.get_prometheus_client(keystone_session)
|
||||||
|
init_m.assert_called_with(
|
||||||
|
"localhost:1234", keystone_session, "prometheus"
|
||||||
|
)
|
||||||
|
ca_m.assert_called_with("ca/path")
|
||||||
|
|
||||||
|
|
||||||
class FormatLabelsTest(testtools.TestCase):
|
class FormatLabelsTest(testtools.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@@ -14,7 +14,10 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from urllib import parse
|
||||||
|
|
||||||
|
from keystoneauth1 import adapter
|
||||||
|
from keystoneauth1.exceptions import catalog as keystone_exception
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from observabilityclient.prometheus_client import PrometheusAPIClient
|
from observabilityclient.prometheus_client import PrometheusAPIClient
|
||||||
@@ -45,7 +48,7 @@ def get_config_file():
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_prometheus_client(session=None):
|
def get_prometheus_client(session=None, adapter_options={}):
|
||||||
host = None
|
host = None
|
||||||
port = None
|
port = None
|
||||||
ca_cert = None
|
ca_cert = None
|
||||||
@@ -63,6 +66,28 @@ def get_prometheus_client(session=None):
|
|||||||
root_path = conf['root_path']
|
root_path = conf['root_path']
|
||||||
conf_file.close()
|
conf_file.close()
|
||||||
|
|
||||||
|
if session is not None and (host is None or port is None):
|
||||||
|
try:
|
||||||
|
endpoint = adapter.Adapter(
|
||||||
|
session=session, **adapter_options
|
||||||
|
).get_endpoint()
|
||||||
|
parsed_url = parse.urlparse(endpoint)
|
||||||
|
host = parsed_url.hostname
|
||||||
|
port = parsed_url.port if parsed_url.port is not None else 80
|
||||||
|
root_path = parsed_url.path.strip('/')
|
||||||
|
if parsed_url.scheme == "https" and ca_cert is None:
|
||||||
|
# NOTE(jwysogla): Use the default CA certs if the scheme
|
||||||
|
# is https, but keep the original value if already set,
|
||||||
|
# so that a custom certificate can be set in the config
|
||||||
|
# file, while the endpoint is retrieved from keystone.
|
||||||
|
ca_cert = True
|
||||||
|
except keystone_exception.EndpointNotFound:
|
||||||
|
# NOTE(jwysogla): Don't do anything here. It's still possible
|
||||||
|
# to get the correct endpoint configuration from the env vars.
|
||||||
|
# If that doesn't work, the same error message is part of the
|
||||||
|
# exception raised below.
|
||||||
|
pass
|
||||||
|
|
||||||
# NOTE(jwysogla): We allow to overide the prometheus.yaml by
|
# NOTE(jwysogla): We allow to overide the prometheus.yaml by
|
||||||
# the environment variables
|
# the environment variables
|
||||||
if 'PROMETHEUS_HOST' in os.environ:
|
if 'PROMETHEUS_HOST' in os.environ:
|
||||||
@@ -75,7 +100,8 @@ def get_prometheus_client(session=None):
|
|||||||
root_path = os.environ['PROMETHEUS_ROOT_PATH']
|
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 and endpoint for service"
|
||||||
|
"prometheus not found.")
|
||||||
client = PrometheusAPIClient(f"{host}:{port}", session, root_path)
|
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)
|
||||||
|
@@ -28,7 +28,7 @@ class Client(object):
|
|||||||
session_options = session_options or {}
|
session_options = session_options or {}
|
||||||
adapter_options = adapter_options or {}
|
adapter_options = adapter_options or {}
|
||||||
|
|
||||||
adapter_options.setdefault('service_type', "metric")
|
adapter_options.setdefault('service_type', "prometheus")
|
||||||
|
|
||||||
if session is None:
|
if session is None:
|
||||||
session = keystoneauth1.session.Session(**session_options)
|
session = keystoneauth1.session.Session(**session_options)
|
||||||
@@ -38,7 +38,9 @@ class Client(object):
|
|||||||
|
|
||||||
self.session = session
|
self.session = session
|
||||||
|
|
||||||
self.prometheus_client = get_prometheus_client(session)
|
self.prometheus_client = get_prometheus_client(
|
||||||
|
session, adapter_options
|
||||||
|
)
|
||||||
self.query = python_api.QueryManager(self)
|
self.query = python_api.QueryManager(self)
|
||||||
self.rbac = rbac.PromQLRbac(
|
self.rbac = rbac.PromQLRbac(
|
||||||
self.prometheus_client,
|
self.prometheus_client,
|
||||||
|
Reference in New Issue
Block a user