diff --git a/.gitignore b/.gitignore index 0cf91e4..55ab627 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ nosetests.xml .idea TODO *.log + +venv diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..84d825e --- /dev/null +++ b/.pylintrc @@ -0,0 +1,5 @@ +[MESSAGES CONTROL] +disable=R,C,W,import-error,broad-except + +[TYPECHECK] +ignored-classes=_socketobject diff --git a/.travis.yml b/.travis.yml index d21daa0..a280a8d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,4 +27,7 @@ install: - pip install -r requirements-dev.txt script: + - pylint integrations/*/*.py + - pylint plugins/*/*.py + - pylint webhooks/*/*.py - pytest -v webhooks/*/test* diff --git a/integrations/consul/consulalerta.py b/integrations/consul/consulalerta.py index 71d0355..af9f57e 100755 --- a/integrations/consul/consulalerta.py +++ b/integrations/consul/consulalerta.py @@ -1,12 +1,12 @@ #!/usr/bin/env python -from alertaclient.api import Client -import sys -import os -import time import json +import os + import consul +import sys import time +from alertaclient.api import Client CONSUL_HOST = os.environ.get('CONSUL_HOST', '127.0.0.1') CONSUL_PORT = int(os.environ.get('CONSUL_PORT', 8500)) @@ -19,13 +19,13 @@ print(j) try: url = client.kv.get('alerta/apiurl')[1]['Value'] -except: +except Exception: print("No URL defined, exiting") sys.exit(1) try: key = client.kv.get('alerta/apikey')[1]['Value'] -except: +except Exception: print("No key defined, exiting") sys.exit(1) @@ -72,13 +72,13 @@ SEVERITY_MAP = { def createalert( data ): try: environment = client.kv.get('alerta/env/{0}'.format(data['Node']))[1]['Value'] - except: + except Exception: try: - environment = client.kv.get('alerta/defaultenv')[1]['Value'] - except: - environment = "Production" + environment = client.kv.get('alerta/defaultenv')[1]['Value'] + except Exception: + environment = "Production" - for i in range(max_retries): + for _ in range(max_retries): try: print("Response:") response = api.send_alert( diff --git a/integrations/consul/consulheartbeat.py b/integrations/consul/consulheartbeat.py index d6c9cd1..9caa52c 100755 --- a/integrations/consul/consulheartbeat.py +++ b/integrations/consul/consulheartbeat.py @@ -17,7 +17,7 @@ origin = client.kv.get('alerta/origin')[1]['Value'] api = Client(endpoint=url, key=key) def createheartbeat(): - for i in range(max_retries): + for _ in range(max_retries): try: print(api.heartbeat(origin=origin, timeout=timeout)) except Exception as e: diff --git a/integrations/consul/setup.py b/integrations/consul/setup.py index 57467a6..cda1762 100644 --- a/integrations/consul/setup.py +++ b/integrations/consul/setup.py @@ -1,5 +1,5 @@ -from setuptools import setup, find_packages +from setuptools import setup version = '1.1.1' diff --git a/integrations/mailer/mailer.py b/integrations/mailer/mailer.py index 27fa935..e59ff54 100755 --- a/integrations/mailer/mailer.py +++ b/integrations/mailer/mailer.py @@ -9,6 +9,8 @@ import re import signal import smtplib import socket +from functools import reduce + import sys import threading import time @@ -213,7 +215,7 @@ class MailSender(threading.Thread): return True LOG.debug('Regex %s matches nothing', regex) return False - elif isinstance(value, str) or isinstance(value, unicode): + elif isinstance(value, str) or isinstance(value, unicode): # pylint: disable=undefined-variable LOG.debug('Trying to match %s to %s', value, regex) return re.search(regex, value) is not None @@ -302,14 +304,14 @@ class MailSender(threading.Thread): LOG.debug('%s : Email sent to %s' % (alert.get_id(), ','.join(contacts))) return (msg, contacts) - except (socket.error, socket.herror, socket.gaierror) as e: - LOG.error('Mail server connection error: %s', e) - return None except smtplib.SMTPException as e: LOG.error('Failed to send mail to %s on %s:%s : %s', ", ".join(contacts), OPTIONS['smtp_host'], OPTIONS['smtp_port'], e) return None + except (socket.error, socket.herror, socket.gaierror) as e: + LOG.error('Mail server connection error: %s', e) + return None except Exception as e: LOG.error('Unexpected error while sending email: {}'.format(str(e))) # nopep8 return None diff --git a/integrations/urlmon/settings.py b/integrations/urlmon/settings.py index 8fc7fb5..432b54f 100644 --- a/integrations/urlmon/settings.py +++ b/integrations/urlmon/settings.py @@ -8,7 +8,7 @@ checks = [ "resource": "www.google.com", "url": "http://www.google.com?q=foo#q=foo", "environment": "Production", - "service": ["Google", "Search"] + "service": ["Google", "Search"], "api_endpoint": "http://localhost:8080", "api_key": None, }, diff --git a/integrations/urlmon/urlmon.py b/integrations/urlmon/urlmon.py index 83bc8de..cf5b30d 100644 --- a/integrations/urlmon/urlmon.py +++ b/integrations/urlmon/urlmon.py @@ -1,20 +1,20 @@ -import platform -import sys -import time -import urllib.request, urllib.error, urllib.parse +import datetime import json -import threading +import logging +import platform import queue import re -import logging - -import datetime -import ssl import socket - -from alertaclient.api import Client - +import ssl +import threading from http.server import BaseHTTPRequestHandler as BHRH +from urllib.error import URLError # pylint: disable=no-name-in-module +from urllib.parse import urlparse # pylint: disable=no-name-in-module +from urllib.request import build_opener, ProxyHandler, HTTPBasicAuthHandler, install_opener, Request, urlopen # pylint: disable=no-name-in-module + +import sys +import time +from alertaclient.api import Client HTTP_RESPONSES = dict([(k, v[0]) for k, v in list(BHRH.responses.items())]) @@ -240,8 +240,8 @@ class WorkerThread(threading.Thread): if check_ssl: ssl_date_fmt = r'%b %d %H:%M:%S %Y %Z' context = ssl.create_default_context() - domain = '{uri.netloc}'.format(uri=urllib.parse.urlparse(check.get('url'))) - port = urllib.parse.urlparse(check.get('url')).port or 443 + domain = '{uri.netloc}'.format(uri=urlparse(check.get('url'))) + port = urlparse(check.get('url')).port or 443 conn = context.wrap_socket( socket.socket(socket.AF_INET), server_hostname=domain @@ -311,42 +311,42 @@ class WorkerThread(threading.Thread): start = time.time() if username and password: - auth_handler = urllib.request.HTTPBasicAuthHandler() + auth_handler = HTTPBasicAuthHandler() auth_handler.add_password(realm=realm, uri=uri, user=username, passwd=password) if proxy: - opener = urllib.request.build_opener(auth_handler, urllib.request.ProxyHandler(proxy)) + opener = build_opener(auth_handler, ProxyHandler(proxy)) else: - opener = urllib.request.build_opener(auth_handler) + opener = build_opener(auth_handler) else: if proxy: - opener = urllib.request.build_opener(urllib.request.ProxyHandler(proxy)) + opener = build_opener(ProxyHandler(proxy)) else: - opener = urllib.request.build_opener() - urllib.request.install_opener(opener) + opener = build_opener() + install_opener(opener) if 'User-agent' not in headers: headers['User-agent'] = 'alert-urlmon/%s' % (__version__) try: if post: - req = urllib.request.Request(url, json.dumps(post), headers=headers) + req = Request(url, json.dumps(post), headers=headers) else: - req = urllib.request.Request(url, headers=headers) - response = urllib.request.urlopen(req, None, MAX_TIMEOUT) + req = Request(url, headers=headers) + response = urlopen(req, None, MAX_TIMEOUT) except ValueError as e: - LOG.error('Request failed: %s', e) - except urllib.error.URLError as e: + LOG.error('Request failed: %s' % e) + except URLError as e: if hasattr(e, 'reason'): reason = str(e.reason) status = None elif hasattr(e, 'code'): reason = None - status = e.code + status = e.code # pylint: disable=no-member except Exception as e: - LOG.warning('Unexpected error: %s', e) + LOG.warning('Unexpected error: %s' % e) else: status = response.getcode() body = response.read() @@ -412,7 +412,7 @@ class UrlmonDaemon(object): event='big queue for http checks', value=self.queue.qsize(), severity=severity, - text='URL check queue length is %d', self.queue.qsize(), + text='URL check queue length is %d' % self.queue.qsize(), event_type='serviceAlert', ) except Exception as e: diff --git a/plugins/alertops/alerta_alertops.py b/plugins/alertops/alerta_alertops.py index b3e687b..2c2d971 100644 --- a/plugins/alertops/alerta_alertops.py +++ b/plugins/alertops/alerta_alertops.py @@ -22,22 +22,24 @@ class TriggerEvent(PluginBase): def pre_receive(self, alert, **kwargs): - return alert + @staticmethod + def _event_type(severity): + if severity in ['cleared', 'normal', 'ok']: + return "close" + else: + return "open" + def post_receive(self, alert, **kwargs): if alert.repeat: return + message = "%s: %s alert for %s - %s" %( alert.environment, alert.severity.capitalize(), ','.join(alert.service), alert.resource) - if alert.severity in ['cleared', 'normal', 'ok']: - event_type = "close" - else: - event_type = "open" - payload = { "source_id": alert.id, - "source_status": event_type, + "source_status": TriggerEvent._event_type(alert.severity), "description": message, "resource": alert.resource, "source": "alerta", @@ -54,11 +56,12 @@ class TriggerEvent(PluginBase): def status_change(self, alert, status, text, **kwargs): if status not in ['ack', 'assign']: - return + return + message = "%s: %s alert for %s - %s" %( alert.environment, alert.severity.capitalize(), ','.join(alert.service), alert.resource) payload = { "source_id": alert.id, - "source_status": event_type, + "source_status": TriggerEvent._event_type(alert.severity), "description": message, "resource": alert.resource, "source": "alerta", diff --git a/plugins/mattermost/alerta_mattermost.py b/plugins/mattermost/alerta_mattermost.py index 7df44fa..9c80a84 100644 --- a/plugins/mattermost/alerta_mattermost.py +++ b/plugins/mattermost/alerta_mattermost.py @@ -22,15 +22,12 @@ MATTERMOST_USERNAME = os.environ.get( class ServiceIntegration(PluginBase): - def __init__(self, name=None): - - super().__init__(name) - def pre_receive(self, alert): - return alert LOG.debug('Mattermost: %s', alert) + return alert def get_icon(self, status): + LOG.debug('Mattermost: %s', status) return { 'security': ':closed_lock_with_key:', 'critical': ':bangbang:', @@ -42,9 +39,9 @@ class ServiceIntegration(PluginBase): 'trace': ':signal_strength:', 'ok': ':ok:' }.get(status, ':ok:') - LOG.debug('Mattermost: %s', status) def _prepare_payload(self, alert): + LOG.debug('Mattermost: %s', alert) return "{} **{}** **{}**\n`{}` ```{}```".format( self.get_icon(alert.severity), alert.severity, @@ -52,7 +49,6 @@ class ServiceIntegration(PluginBase): alert.event, alert.text, ) - LOG.debug('Mattermost: %s', alert) def post_receive(self, alert): if alert.repeat: diff --git a/plugins/slack/alerta_slack.py b/plugins/slack/alerta_slack.py index bc47618..b21793d 100644 --- a/plugins/slack/alerta_slack.py +++ b/plugins/slack/alerta_slack.py @@ -5,6 +5,8 @@ import os import requests import traceback +LOG = logging.getLogger('alerta.plugins.slack') + try: from jinja2 import Template except Exception as e: @@ -56,6 +58,7 @@ SLACK_HEADERS = { 'Content-Type': 'application/json' } + class ServiceIntegration(PluginBase): def __init__(self, name=None): diff --git a/requirements-dev.txt b/requirements-dev.txt index 1545d2f..2e2e383 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,2 +1,3 @@ +pylint pytest alerta-server[postgres]