Prometheus client

Initial prometheus client

Change-Id: I8c02be6fe7e58c2f37ac19547fd7a795896af4bc
Reviewed-on: https://review.gerrithub.io/368732
Reviewed-by: Tatyanka Leontovich <tleontovich@mirantis.com>
Tested-by: Tatyanka Leontovich <tleontovich@mirantis.com>
diff --git a/tcp_tests/managers/clients/__init__.py b/tcp_tests/managers/clients/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tcp_tests/managers/clients/__init__.py
diff --git a/tcp_tests/managers/clients/http_client.py b/tcp_tests/managers/clients/http_client.py
new file mode 100644
index 0000000..5453141
--- /dev/null
+++ b/tcp_tests/managers/clients/http_client.py
@@ -0,0 +1,49 @@
+import logging
+import urlparse
+
+import requests
+
+from tcp_tests import logger
+
+LOG = logger.logger
+
+logger = logging.getLogger(__name__)
+
+
+class HttpClient(object):
+    def __init__(self, base_url=None, user=None, password=None):
+        self.base_url = base_url
+        self.kwargs = {}
+        if user and password:
+            self.kwargs.update({"auth": (user, password)})
+
+    def set_base_url(self, base_url):
+        self.base_url = base_url
+
+    def request(self, url, method, headers=None, body=None, **kwargs):
+        logger.debug(
+            "Sending request to: {}, body: {}, headers: {}, kwargs: {}".format(
+                url, body, headers, kwargs))
+        if headers is None:
+            headers = {'Content-Type': 'application/json'}
+
+        kwargs.update(self.kwargs)
+        r = requests.request(method, urlparse.urljoin(self.base_url, url),
+                             headers=headers, data=body, **kwargs)
+
+        if not r.ok:
+            raise requests.HTTPError(r.content)
+        logger.debug(r.content)
+        return r.headers, r.content
+
+    def post(self, url, body=None, **kwargs):
+        return self.request(url, "POST", body=body, **kwargs)
+
+    def get(self, url, **kwargs):
+        return self.request(url, "GET", **kwargs)
+
+    def put(self, url, body=None, **kwargs):
+        return self.request(url, "PUT", body=body, **kwargs)
+
+    def delete(self, url, **kwargs):
+        return self.request(url, "DELETE", **kwargs)
diff --git a/tcp_tests/managers/clients/prometheus/__init__.py b/tcp_tests/managers/clients/prometheus/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tcp_tests/managers/clients/prometheus/__init__.py
diff --git a/tcp_tests/managers/clients/prometheus/prometheus_client.py b/tcp_tests/managers/clients/prometheus/prometheus_client.py
new file mode 100644
index 0000000..bf748af
--- /dev/null
+++ b/tcp_tests/managers/clients/prometheus/prometheus_client.py
@@ -0,0 +1,31 @@
+import json
+
+from tcp_tests.managers.clients import http_client
+
+
+class PrometheusClient(object):
+    def __init__(self, host, port, proto):
+        self.url = '{0}://{1}:{2}'.format(proto, host, port)
+        self.client = http_client.HttpClient(base_url=self.url)
+
+    def get_targets(self):
+        _, resp = self.client.get("/api/v1/targets")
+        targets = json.loads(resp)
+        return targets["data"]["activeTargets"]
+
+    def get_query(self, query, timestamp=None):
+        params = {
+            "query": query
+        }
+
+        if timestamp is not None:
+            params.update({"time": timestamp})
+
+        _, resp = self.client.get("/api/v1/query", params=params)
+
+        query_result = json.loads(resp)
+        if query_result["status"] != "success":
+            raise Exception("Failed resp: {}".format(resp))
+
+        if query_result["data"]["resultType"] == "vector":
+            return query_result["data"]["result"]
diff --git a/tcp_tests/managers/sl_manager.py b/tcp_tests/managers/sl_manager.py
index c868d67..23d362e 100644
--- a/tcp_tests/managers/sl_manager.py
+++ b/tcp_tests/managers/sl_manager.py
@@ -13,6 +13,7 @@
 #    under the License.
 
 from tcp_tests.managers.execute_commands import ExecuteCommandsMixin
+from tcp_tests.managers.clients.prometheus import prometheus_client
 
 
 class SLManager(ExecuteCommandsMixin):
@@ -25,6 +26,7 @@
         self.__config = config
         self.__underlay = underlay
         self._salt = salt
+        self._p_client = None
         super(SLManager, self).__init__(
             config=config, underlay=underlay)
 
@@ -32,3 +34,26 @@
         self.execute_commands(commands,
                               label='Install SL services')
         self.__config.stack_light.sl_installed = True
+        self.__config.stack_light.sl_vip_host = self.get_sl_vip()
+
+    def get_sl_vip(self):
+        sl_vip_address_pillars = self._salt.get_pillar(
+            tgt='I@keepalived:cluster:enabled:true and not ctl*',
+            pillar='keepalived:cluster:instance:prometheus_server_vip:address')
+        sl_vip_ip = set([ip
+                            for item in sl_vip_address_pillars
+                            for node,ip in item.items() if ip])
+        assert len(sl_vip_ip) == 1, (
+            "Found more than one SL VIP in pillars:{0}, "
+            "expected one!").format(sl_vip_ip)
+        sl_vip_ip_host = sl_vip_ip.pop()
+        return sl_vip_ip_host
+
+    @property
+    def api(self):
+        if self._p_client is None:
+            self._p_client = prometheus_client.PrometheusClient(
+                host=self.__config.stack_light.sl_vip_host,
+                port=self.__config.stack_light.sl_prometheus_port,
+                proto=self.__config.stack_light.sl_prometheus_proto)
+        return self._p_client