Skip to content

Commit

Permalink
Reviewed requirements.
Browse files Browse the repository at this point in the history
  • Loading branch information
Adrien Delle Cave committed Jan 13, 2020
1 parent 8f60e02 commit 2dc44f4
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 35 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
python-dwho (0.3.26) unstable; urgency=medium

* Reviewed requirements.

-- Adrien DELLE CAVE (Decryptus) <adc@doowan.net> Mon, 13 Jan 2020 09:46:24 +0100

python-dwho (0.3.25) unstable; urgency=medium

* Added option async for notifiers.

-- Adrien DELLE CAVE (Decryptus) <adc@doowan.net> Mon, 13 Jan 2020 09:45:40 +0100

python-dwho (0.3.24) unstable; urgency=medium

* Reviewed option max_workers parsing.
Expand Down
2 changes: 1 addition & 1 deletion RELEASE
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.3.24
0.3.26
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.3.24
0.3.26
96 changes: 67 additions & 29 deletions dwho/classes/notifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@

from dotenv.main import dotenv_values

from sonicprobe import helpers
from sonicprobe.libs import urisup
from sonicprobe.libs.workerpool import WorkerPool

import requests
import six
import yaml

from dwho.adapters.redis import DWhoAdapterRedis
from dwho.config import get_softname, get_softver
from dwho.classes.abstract import DWhoAbstractHelper


Expand Down Expand Up @@ -62,6 +64,8 @@ class DWhoPushNotifications(object): # pylint: disable=useless-object-inheritanc
def __init__(self, server_id = None, config_path = None):
self.notifications = {}
self.server_id = server_id or getfqdn()
self.workerpool = None
self._lock = threading.Lock()

if config_path:
self.load(config_path)
Expand All @@ -83,13 +87,13 @@ def load(self, config_path):
f = None
with open(xpath, 'r') as f:
name = os.path.splitext(os.path.basename(xpath))[0]
cfg = yaml.load(f)
cfg = helpers.load_yaml(f)

self.notifications[name] = {'cfg': cfg,
'tpl': None,
'notifiers': []}

if 'template' in cfg['general']:
if cfg['general'].get('template') and os.path.isfile(cfg['general']['template']):
with open(cfg['general']['template'], 'r') as t:
self.notifications[name]['tpl'] = t.read()

Expand All @@ -107,7 +111,7 @@ def reset(self):
self.notifications = {}
return self

def __call__(self, xvars = None):
def _run(self, xvars = None):
if not xvars:
xvars = {}

Expand All @@ -116,11 +120,17 @@ def __call__(self, xvars = None):
nvars['_GMTIME_'] = datetime.utcnow()
nvars['_HOSTNAME_'] = getfqdn()
nvars['_SERVER_ID_'] = self.server_id
nvars['_SOFTNAME_'] = get_softname()
nvars['_SOFTVER_'] = get_softver()
nvars['_TIME_'] = datetime.now()
nvars['_TIMESTAMP_'] = time.time()
nvars['_UUID_'] = "%s" % uuid.uuid4()
nvars['_VARS_'] = copy.deepcopy(xvars)

if not self.workerpool:
self.workerpool = WorkerPool(max_workers = 1,
name = 'notifiers')

for name, notification in six.iteritems(self.notifications):
if not notification['cfg']['general'].get('enabled', True):
continue
Expand All @@ -138,7 +148,29 @@ def __call__(self, xvars = None):
uri = urisup.uri_help_split(cfg['general']['uri'])

for notifier in notification['notifiers']:
notifier(name, cfg, uri, nvars, tpl)
if cfg['general'].get('async'):
self.workerpool.run_args(notifier,
_name_ = "notifier:%s" % name,
name = name,
cfg = cfg,
uri = uri,
nvars = nvars,
tpl = tpl)
else:
notifier(name, cfg, uri, nvars, tpl)

while True:
if self.workerpool.killable():
self.workerpool.killall(0)
self.workerpool = None
time.sleep(0.5)

def __call__(self, xvars = None):
with self._lock:
try:
self._run(xvars)
except Exception as e:
LOG.exception(e)


class DWhoNotifierBase(DWhoAbstractHelper): # pylint: disable=useless-object-inheritance
Expand All @@ -153,7 +185,7 @@ class DWhoNotifierHttp(DWhoNotifierBase):
SCHEME = ('http', 'https')

def __call__(self, name, cfg, uri, nvars, tpl = None):
(method, headers, payload) = ('post', {}, {})
(method, auth, headers, payload) = ('post', None, {}, {})

if not isinstance(tpl, dict):
tpl = {}
Expand All @@ -167,6 +199,9 @@ def __call__(self, name, cfg, uri, nvars, tpl = None):
else:
raise ValueError("invalid HTTP method: %r" % tpl['method'])

if isinstance(tpl.get('auth'), dict):
auth = tpl['auth']

if 'headers' in tpl:
headers = tpl['headers']

Expand All @@ -175,6 +210,7 @@ def __call__(self, name, cfg, uri, nvars, tpl = None):

try:
r = getattr(requests, method)(cfg['general']['uri'],
auth = auth,
headers = headers,
data = payload,
timeout = timeout,
Expand All @@ -191,6 +227,28 @@ def __call__(self, name, cfg, uri, nvars, tpl = None):
return None


class DWhoNotifierRedis(DWhoNotifierBase):
SCHEME = ('redis',)

def __call__(self, name, cfg, uri, nvars, tpl):
config = {'general':
{'redis':
{'notifier': cfg['general'].get('options') or {}}}}
config['general']['redis']['notifier']['url'] = cfg['general']['uri']

if not tpl or not isinstance(tpl, dict):
LOG.error("missing redis template for %r", name)
return

try:
adapter_redis = DWhoAdapterRedis(config, prefix = 'notifier')
adapter_redis.set_key(tpl['key'], json.dumps(tpl['value']))
except Exception as e:
LOG.error("unable to push notification %r: %r", name, e)
else:
LOG.info("notification pushed: %r", name)


class DWhoNotifierSubprocess(DWhoNotifierBase):
SCHEME = ('subproc',)

Expand All @@ -202,6 +260,8 @@ def _set_default_env(env, xvars):
'DWHO_NOTIFIER_TIME': "%s" % xvars['_TIME_'],
'DWHO_NOTIFIER_TIMESTAMP': "%s" % xvars['_TIMESTAMP_'],
'DWHO_NOTIFIER_SERVER_ID': "%s" % xvars['_SERVER_ID_'],
'DWHO_NOTIFIER_SOFTNAME': "%s" % xvars['_SOFTNAME_'],
'DWHO_NOTIFIER_SOFTVER': "%s" % xvars['_SOFTVER_'],
'DWHO_NOTIFIER_UUID': "%s" % xvars['_UUID_']})

return env
Expand Down Expand Up @@ -411,31 +471,9 @@ def __call__(self, name, cfg, uri, nvars, tpl = None):
pass


class DWhoNotifierRedis(DWhoNotifierBase):
SCHEME = ('redis',)

def __call__(self, name, cfg, uri, nvars, tpl):
config = {'general':
{'redis':
{'notifier': cfg['general'].get('options') or {}}}}
config['general']['redis']['notifier']['url'] = cfg['general']['uri']

if not tpl or not isinstance(tpl, dict):
LOG.error("missing redis template for %r", name)
return

try:
adapter_redis = DWhoAdapterRedis(config, prefix = 'notifier')
adapter_redis.set_key(tpl['key'], json.dumps(tpl['value']))
except Exception as e:
LOG.error("unable to push notification %r: %r", name, e)
else:
LOG.info("notification pushed: %r", name)


if __name__ != "__main__":
def _start():
NOTIFIERS.register(DWhoNotifierHttp())
NOTIFIERS.register(DWhoNotifierSubprocess())
NOTIFIERS.register(DWhoNotifierRedis())
NOTIFIERS.register(DWhoNotifierSubprocess())
_start()
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
escapejson
httpdis>=0.6.10
httpdis>=0.6.11
Mako
PyYAML>=3.10
pyinotify
python-dotenv
redis>=2.4.0
requests>=2.0
six>=1.13.0
sonicprobe>=0.3.23
sonicprobe>=0.3.24
4 changes: 2 additions & 2 deletions setup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ description: dwho
author: Adrien Delle Cave
author_email: pypi@doowan.net
copyright: '2020 Adrien Delle Cave'
release: '0.3.24'
version: '0.3.24'
release: '0.3.26'
version: '0.3.26'
license: License GPL-3
url: https://github.com/decryptus/dwho
python_requires:
Expand Down

0 comments on commit 2dc44f4

Please sign in to comment.