diff --git a/api.py b/api.py new file mode 100644 index 0000000..ccd63e4 --- /dev/null +++ b/api.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +import re + +from packaging import version + + +class EjabberdApi: + """ + class to interact with the ejabberd rest/ xmlrpc api + """ + def __init__(self, url, login=None, api: str = "rpc"): + # api variables + self._login = login + self._url = url + + if api == "rpc": + self.cmd = self._rpc + else: + import requests + + self.session = requests.Session() + self.cmd = self._rest + + @property + def _auth(self) -> (str, None): + if self._login is not None: + return f"{self._login['user']}@{self._login['server']}", self._login['password'] + return None + + @property + def verstring(self): + if self._login is not None: + ver_str = re.compile('([1-9][0-9.]*)') + status = self.cmd('status', {}) + + # matches + tmp = ver_str.findall(status)[0] + + # return parsed version string + return version.parse(tmp) + + return None + + def _rest(self, command: str, data) -> dict: + # add authentication header to the session obj + if self.session.auth is None: + self.session.auth = self._auth + + # post + r = self.session.post('/'.join([self._url, command]), json=data) + + # proceed if response is ok + if r.ok: + return r.json() + + return {} + + def _rpc(self, command: str, data): + from xmlrpc import client + + with client.ServerProxy(self._url) as server: + fn = getattr(server, command) + try: + if self._login is not None: + return fn(self._login, data) + return fn(data) + + except: + # this needs to be more specific + return {} diff --git a/influx.py b/influx.py index 59728ac..d0569d4 100644 --- a/influx.py +++ b/influx.py @@ -5,7 +5,7 @@ import time from influxdb import InfluxDBClient from config import Config -from ejabberdrpc import EjabberdMetrics +from metrics import EjabberdMetrics class Influx: diff --git a/ejabberdrpc.py b/metrics.py old mode 100755 new mode 100644 similarity index 86% rename from ejabberdrpc.py rename to metrics.py index 6a34cd0..abc57db --- a/ejabberdrpc.py +++ b/metrics.py @@ -1,9 +1,8 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- import ipaddress -import re -from packaging import version +from api import EjabberdApi # rfc6052: IPv6 Addressing of IPv4/IPv6 Translators nat64 = ipaddress.ip_network("64:ff9b::/96") @@ -14,63 +13,13 @@ class EjabberdMetrics: class to fetch metrics per xmlrpc """ def __init__(self, url, login=None, api="rpc", muc_host: str = 'conference'): - self._login = login + # init ejabberd api + self.api = EjabberdApi(url, login, api) + self._cmd = self.api.cmd + + # variables + self._verstring = self.api.verstring self.muc_host = muc_host - if api == "rpc": - self.url = url - self._cmd = self._rpc - else: - import requests - - self._url = url - self.session = requests.Session() - self._cmd = self._rest - - @property - def _auth(self): - if self._login is not None: - return f"{self._login['user']}@{self._login['server']}", self._login['password'] - return None - - @property - def _verstring(self): - if self._login is not None: - ver_str = re.compile('([1-9][0-9.-]*)') - status = self._cmd('status', {}) - - # matches - tmp = ver_str.findall(status)[0] - - # return parsed version string - return version.parse(tmp) - - return None - - def _rest(self, command: str, data) -> dict: - # add authentication header to the session obj - if self.session.auth is None: - self.session.auth = self._auth - - # post - r = self.session.post('/'.join([self._url, command]), json=data) - - # proceed if response is ok - if r.ok: - return r.json() - - return {} - - def _rpc(self, command: str, data): - from xmlrpc import client - - with client.ServerProxy(self.url) as server: - fn = getattr(server, command) - try: - if self._login is not None: - return fn(self._login, data) - return fn(data) - except: - return {} def _client(self, resource): clientmap = { diff --git a/prometheus.py b/prometheus.py old mode 100755 new mode 100644 index 4aab1b3..4441c87 --- a/prometheus.py +++ b/prometheus.py @@ -8,7 +8,7 @@ from http.server import BaseHTTPRequestHandler, HTTPServer from socketserver import ThreadingMixIn from config import Config -from ejabberdrpc import EjabberdMetrics +from metrics import EjabberdMetrics class _ThreadingSimpleServer(ThreadingMixIn, HTTPServer):