add SLACK_CHANNEL_MAP for environment and severity mapping ()

* making ICON_EMOJI optional

* adding SLACK_CHANNEL_MAP

* fix payload dictionary access

* update default ICON_EMOJI in readme

* require pytest>=5.4.3

Co-authored-by: Nick Satterly <nfsatterly@gmail.com>
This commit is contained in:
eli 2020-06-18 10:58:35 -04:00 committed by GitHub
parent 2d0bf01c98
commit 862c47064a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 34 deletions

View file

@ -41,11 +41,12 @@ for your Slack channel and adding the following configuration settings to `alert
SLACK_WEBHOOK_URL = 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX'
SLACK_ATTACHMENTS = True # default=False
SLACK_CHANNEL = '' # if empty then uses channel from incoming webhook configuration
SLACK_CHANNEL_ENV_MAP = { 'Production' : '#alert-prod' } # Default=None (optionnal) Allow to specify a channel on a per-environment basis. SLACK_CHANNEL is used a default value
SLACK_CHANNEL_EVENT_MAP = { 'Node offline' : '#critical-alerts' } # Default=None (optionnal) Allow to specify a channel on a per-event basis. SLACK_CHANNEL is used a default value
SLACK_CHANNEL_SEVERITY_MAP = { 'critical' : '#critical-alerts', 'informational': '#noisy-feed' } # Default=None (optionnal) Allow to specify a channel on a per-severity basis. SLACK_CHANNEL is used a default value
SLACK_SEVERITY_FILTER = ['warning'] # blocks alerts with severity in this list from being forwarded to Slack
ICON_EMOJI = '' # default :rocket:
SLACK_CHANNEL_ENV_MAP = { 'Production' : '#alert-prod' } # Default=None (optional) Allow specifying a channel on a per-environment basis. SLACK_CHANNEL is used as a default value.
SLACK_CHANNEL_EVENT_MAP = { 'Node offline' : '#critical-alerts' } # Default=None (optional) Allow specifying a channel on a per-event basis. SLACK_CHANNEL is used as a default value.
SLACK_CHANNEL_SEVERITY_MAP = { 'critical' : '#critical-alerts', 'informational': '#noisy-feed' } # Default=None (optional) Allow specifying a channel on a per-severity basis. SLACK_CHANNEL is used as a default value.
SLACK_CHANNEL_MAP = { 'Production' : { 'critical' : '#prod-alerts' } } # Default=None (optional) Allow specifying a channel on both a per-environment and per-severity basis. SLACK_CHANNEL is used as a default value.
ICON_EMOJI = '' # default None
ALERTA_USERNAME = '' # default alerta
```

View file

@ -42,6 +42,12 @@ try:
except Exception as e:
SLACK_CHANNEL_SEVERITY_MAP = app.config.get('SLACK_CHANNEL_SEVERITY_MAP', dict())
try:
SLACK_CHANNEL_MAP = json.loads(
os.environ.get('SLACK_CHANNEL_MAP'))
except Exception as e:
SLACK_CHANNEL_MAP = app.config.get('SLACK_CHANNEL_MAP', dict())
try:
SLACK_SEVERITY_FILTER = ast.literal_eval(
os.environ.get('SLACK_SEVERITY_FILTER'))
@ -98,7 +104,7 @@ class ServiceIntegration(PluginBase):
SLACK_CHANNEL = self.get_config('SLACK_CHANNEL', default='', type=str, **kwargs)
SLACK_SUMMARY_FMT = self.get_config('SLACK_SUMMARY_FMT', type=str, **kwargs) # Message summary format
SLACK_PAYLOAD = self.get_config('SLACK_PAYLOAD', type=str, **kwargs) # Full API control
ICON_EMOJI = self.get_config('ICON_EMOJI', default=':rocket:', type=str, **kwargs)
ICON_EMOJI = self.get_config('ICON_EMOJI', type=str, **kwargs)
ALERTA_USERNAME = self.get_config('ALERTA_USERNAME', default='alerta', type=str, **kwargs)
DASHBOARD_URL = self.get_config('DASHBOARD_URL', default='', type=str, **kwargs)
SLACK_TOKEN = self.get_config('SLACK_TOKEN', type=str, **kwargs)
@ -124,6 +130,11 @@ class ServiceIntegration(PluginBase):
LOG.debug("Found event mapping. Channel: %s" % channel)
else:
LOG.debug("No event mapping. Channel: %s" % channel)
channel = SLACK_CHANNEL_MAP.get(alert.environment, dict()).get(alert.severity, channel)
if SLACK_CHANNEL_MAP.get(alert.environment, dict()).get(alert.severity, channel):
LOG.debug("Found env-severity mapping. Channel: %s" % channel)
else:
LOG.debug("No env-severity mapping. Channel: %s" % channel)
templateVars = {
'alert': alert,
@ -154,33 +165,26 @@ class ServiceIntegration(PluginBase):
short_id=alert.get_id(short=True),
dashboard=DASHBOARD_URL
)
if not SLACK_ATTACHMENTS:
payload = {
"username": ALERTA_USERNAME,
"channel": channel,
"text": summary,
"icon_emoji": ICON_EMOJI
}
else:
payload = {
"username": ALERTA_USERNAME,
"channel": channel,
"icon_emoji": ICON_EMOJI,
"text": summary,
"attachments": [{
"fallback": summary,
"color": color,
"fields": [
{"title": "Status", "value": (status if status else alert.status).capitalize(),
"short": True},
{"title": "Environment",
"value": alert.environment, "short": True},
{"title": "Resource", "value": alert.resource, "short": True},
{"title": "Services", "value": ", ".join(
alert.service), "short": True}
]
}]
}
payload = {}
payload['username'] = ALERTA_USERNAME
payload['channel'] = channel
payload['text'] = summary
if ICON_EMOJI:
payload['icon_emoji'] = ICON_EMOJI
if SLACK_ATTACHMENTS:
payload['attachments'] = [{
"fallback": summary,
"color": color,
"fields": [
{"title": "Status", "value": (status if status else alert.status).capitalize(),
"short": True},
{"title": "Environment",
"value": alert.environment, "short": True},
{"title": "Resource", "value": alert.resource, "short": True},
{"title": "Services", "value": ", ".join(
alert.service), "short": True}
]
}]
return payload

View file

@ -7,7 +7,7 @@ mock
mypy
pre-commit
pylint
pytest
pytest>=5.4.3
pytest-cov
python-dotenv
requests_mock