From bc5b573bfc694e2e90acc2764d29777f2f449c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20Hedde?= Date: Wed, 28 Apr 2021 11:52:28 +0200 Subject: [PATCH 1/3] feat: Pushing grafana annotations on incident Initial work by @acamilleri --- README.md | 1 + demo/demo/settings/base.py | 9 +++ docs/grafana-1.png | Bin 0 -> 8815 bytes docs/grafana-2.png | Bin 0 -> 37117 bytes docs/grafana-3.png | Bin 0 -> 52946 bytes docs/grafana_annoations_support.md | 30 ++++++++ response/apps.py | 2 + response/core/models/incident.py | 2 + response/grafana/client.py | 70 ++++++++++++++++++ response/grafana/signals.py | 49 ++++++++++++ .../0018_incident_grafana_annotation_id.py | 18 +++++ 11 files changed, 181 insertions(+) create mode 100644 docs/grafana-1.png create mode 100644 docs/grafana-2.png create mode 100644 docs/grafana-3.png create mode 100644 docs/grafana_annoations_support.md create mode 100644 response/grafana/client.py create mode 100644 response/grafana/signals.py create mode 100644 response/migrations/0018_incident_grafana_annotation_id.py diff --git a/README.md b/README.md index 8a47646b..07885898 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ Follow [these instructions](./docs/slack_app_create.md) to create a new Slack Ap | `INCIDENT_CHANNEL_ID` | When an incident is declared, a 'headline' post is sent to a central channel.

See the [demo app settings](./demo/demo/settings/dev.py) for an example of how to get the incident channel ID from the Slack API. | | `INCIDENT_BOT_ID` | We want to invite the Bot to all Incident Channels, so need to know its ID.

See the [demo app settings](./demo/demo/settings/dev.py) for an example of how to get the bot ID from the Slack API. | | `SLACK_CLIENT` | Response needs a shared global instance of a Slack Client to talk to the Slack API. Typically this does not require any additional configuration.
from response.slack.client import SlackClient
SLACK_CLIENT = SlackClient(SLACK_TOKEN)
| +| `GRAFANA_URL`
`GRAFANA_TOKEN`| (OPTIONAL) Send annotations to grafana
See [grafana annotations support](./docs/grafana_annoations_support.md). | ## 3. Running the server diff --git a/demo/demo/settings/base.py b/demo/demo/settings/base.py index ebeb8deb..764f5999 100644 --- a/demo/demo/settings/base.py +++ b/demo/demo/settings/base.py @@ -16,6 +16,7 @@ from django.core.exceptions import ImproperlyConfigured from response.slack.client import SlackClient +from response.grafana.client import GrafanaClient logger = logging.getLogger(__name__) @@ -197,3 +198,11 @@ def get_env_var(setting, warn_only=False): # Whether to use https://pypi.org/project/bleach/ to strip potentially dangerous # HTML input in string fields RESPONSE_SANITIZE_USER_INPUT = True + +GRAFANA_URL = get_env_var("GRAFANA_URL", warn_only=True) +GRAFANA_CLIENT = None +if GRAFANA_URL: + GRAFANA_CLIENT = GrafanaClient( + GRAFANA_URL, + get_env_var("GRAFANA_TOKEN") + ) diff --git a/docs/grafana-1.png b/docs/grafana-1.png new file mode 100644 index 0000000000000000000000000000000000000000..8589eb5ef2a2b0cdaef5663042cd56bc44089389 GIT binary patch literal 8815 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 Sfq5^0mxzEQsD$r}=l=oqL0)nI literal 0 HcmV?d00001 diff --git a/docs/grafana_annoations_support.md b/docs/grafana_annoations_support.md new file mode 100644 index 00000000..40eb235e --- /dev/null +++ b/docs/grafana_annoations_support.md @@ -0,0 +1,30 @@ +# Grafana annotation support + +

    + +

    + +## Respone configuration +To add an incident annotation on your diagrams (see exemple above), please set the following variables: + +* `GRAFANA_URL`: The URL of your grafana instance (ex: https://grafana.example.net); +* `GRAFANA_TOKEN`: A Grafana API key with Editor role. + +## Grafana configuration + +Edit your dashboard settings. + +Go to the "Annotations" section: + +![dashboard-edit](./grafana-1.png) + +Then add a new annotation with the following settings: + +* Name: Incident (for example) +* Data source: -- Grafana -- +* Color: Enabled :heavy_check_mark: (OPTIONAL) +* Filter by: Tags +* Tags: + * incident + +![annotations setup](./grafana-2.png) diff --git a/response/apps.py b/response/apps.py index 612f1325..4f42c315 100644 --- a/response/apps.py +++ b/response/apps.py @@ -18,6 +18,8 @@ def ready(self): from .core import signals as core_signals # noqa: F401 + from .grafana import signals as grafana_signals + site_settings.RESPONSE_LOGIN_REQUIRED = getattr( site_settings, "RESPONSE_LOGIN_REQUIRED", True ) diff --git a/response/core/models/incident.py b/response/core/models/incident.py index 7edbbcb2..e7c8740d 100644 --- a/response/core/models/incident.py +++ b/response/core/models/incident.py @@ -77,6 +77,8 @@ class Incident(models.Model): max_length=10, blank=True, null=True, choices=SEVERITIES ) + grafana_annotation_id = models.PositiveIntegerField(null=True, blank=True) + def __str__(self): return self.report diff --git a/response/grafana/client.py b/response/grafana/client.py new file mode 100644 index 00000000..6f39718f --- /dev/null +++ b/response/grafana/client.py @@ -0,0 +1,70 @@ +from datetime import datetime +import logging +import requests +import json + +logger = logging.getLogger(__name__) + + +class GrafanaError(Exception): + def __init__(self, message, grafana_error=None): + self.message = message + self.grafana_error = grafana_error + + +class GrafanaClient(object): + def __init__(self, url, token): + self.url = url + self.token = token + + def create_annotation(self, **kwargs): + logger.info(f"Create Annotation") + + payload = { + "time": kwargs.get("time"), + "tags": kwargs.get("tags"), + "text": kwargs.get("text") + } + + headers = { + 'Authorization': 'Bearer {}'.format(self.token), + 'Content-Type': 'application/json' + } + res = requests.post('{0}/api/{1}'.format(self.url, "annotations"), + headers=headers, + json=payload, + verify=True) + + result = res.json() + res.close() + if res.status_code == 200: + return result + raise GrafanaError(f"Failed to create annotations '{result}'") + + def update_annotation(self, annotation_id, time, time_end, text, tags): + logger.info(f"Update Annotation: '{annotation_id}'") + + payload = {} + if time: + payload["time"] = int(time.timestamp() * 1000) + if time_end: + payload["timeEnd"] = int(time_end.timestamp() * 1000) + if text: + payload["text"] = text + if tags: + payload["tags"] = tags + + headers = { + 'Authorization': 'Bearer {}'.format(self.token), + 'Content-Type': 'application/json' + } + res = requests.patch('{0}/api/{1}/{2}'.format(self.url, "annotations", annotation_id), + headers=headers, + json=payload, + verify=True) + + result = res.json() + res.close() + if res.status_code == 200: + return result + raise GrafanaError(f"Failed to update annotation: '{annotation_id}': '{result}'") diff --git a/response/grafana/signals.py b/response/grafana/signals.py new file mode 100644 index 00000000..87ab6a18 --- /dev/null +++ b/response/grafana/signals.py @@ -0,0 +1,49 @@ +import logging +from urllib.parse import urljoin + +from django.db.models.signals import post_save, pre_save +from django.dispatch import receiver +from django.conf import settings + +from response.grafana.client import GrafanaClient +from response.core.models import Incident + +logger = logging.getLogger(__name__) + +@receiver(post_save, sender=Incident) +def update_grafana_annotation_after_incident_save(sender, instance: Incident, **kwargs): + """ + Reflect changes to incidents in the grafana annotation + + Important: this is called in the synchronous /incident flow so must remain fast (<2 secs) + + """ + if settings.GRAFANA_CLIENT and instance.grafana_annotation_id: + tags = ["incident", instance.severity_text()] + text = "%s \n %s" % (instance.report, instance.summary) + + settings.GRAFANA_CLIENT.update_annotation( + instance.grafana_annotation_id, + time=instance.report_time, + time_end=instance.end_time, + text=text, + tags=tags + ) + +@receiver(pre_save, sender=Incident) +def create_grafana_annotation_before_incident_save(sender, instance: Incident, **kwargs): + """ + Create a grafana annotation ticket before saving the incident + + Important: this is called in the synchronous /incident flow so must remain fast (<2 secs) + + """ + + if settings.GRAFANA_CLIENT and not instance.grafana_annotation_id: + tags = ["incident", instance.severity_text()] + text = "%s \n %s" % (instance.report, instance.summary) + start_time = int(instance.report_time.timestamp() * 1000) + + grafana_annotation = settings.GRAFANA_CLIENT.create_annotation(time=start_time, tags=tags, text=text) + instance.grafana_annotation_id = grafana_annotation["id"] + diff --git a/response/migrations/0018_incident_grafana_annotation_id.py b/response/migrations/0018_incident_grafana_annotation_id.py new file mode 100644 index 00000000..32bf14a9 --- /dev/null +++ b/response/migrations/0018_incident_grafana_annotation_id.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.20 on 2021-04-28 09:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('response', '0017_externaluser_deleted'), + ] + + operations = [ + migrations.AddField( + model_name='incident', + name='grafana_annotation_id', + field=models.PositiveIntegerField(blank=True, null=True), + ), + ] From f934b8a7ebe8912207845821761a7ed4e009d123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20Hedde?= Date: Fri, 21 May 2021 17:02:22 +0200 Subject: [PATCH 2/3] fix: flake8 lint --- response/apps.py | 2 +- response/grafana/client.py | 4 +--- response/grafana/signals.py | 5 ++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/response/apps.py b/response/apps.py index 4f42c315..2dfed74a 100644 --- a/response/apps.py +++ b/response/apps.py @@ -18,7 +18,7 @@ def ready(self): from .core import signals as core_signals # noqa: F401 - from .grafana import signals as grafana_signals + from .grafana import signals as grafana_signals # noqa: F401 site_settings.RESPONSE_LOGIN_REQUIRED = getattr( site_settings, "RESPONSE_LOGIN_REQUIRED", True diff --git a/response/grafana/client.py b/response/grafana/client.py index 6f39718f..21ef6112 100644 --- a/response/grafana/client.py +++ b/response/grafana/client.py @@ -1,7 +1,5 @@ -from datetime import datetime import logging import requests -import json logger = logging.getLogger(__name__) @@ -18,7 +16,7 @@ def __init__(self, url, token): self.token = token def create_annotation(self, **kwargs): - logger.info(f"Create Annotation") + logger.info("Create Annotation") payload = { "time": kwargs.get("time"), diff --git a/response/grafana/signals.py b/response/grafana/signals.py index 87ab6a18..2dff135d 100644 --- a/response/grafana/signals.py +++ b/response/grafana/signals.py @@ -1,15 +1,14 @@ import logging -from urllib.parse import urljoin from django.db.models.signals import post_save, pre_save from django.dispatch import receiver from django.conf import settings -from response.grafana.client import GrafanaClient from response.core.models import Incident logger = logging.getLogger(__name__) + @receiver(post_save, sender=Incident) def update_grafana_annotation_after_incident_save(sender, instance: Incident, **kwargs): """ @@ -30,6 +29,7 @@ def update_grafana_annotation_after_incident_save(sender, instance: Incident, ** tags=tags ) + @receiver(pre_save, sender=Incident) def create_grafana_annotation_before_incident_save(sender, instance: Incident, **kwargs): """ @@ -46,4 +46,3 @@ def create_grafana_annotation_before_incident_save(sender, instance: Incident, * grafana_annotation = settings.GRAFANA_CLIENT.create_annotation(time=start_time, tags=tags, text=text) instance.grafana_annotation_id = grafana_annotation["id"] - From 161c8d4f74c879247570598613bf241d15f2e0d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20Hedde?= Date: Fri, 21 May 2021 17:47:28 +0200 Subject: [PATCH 3/3] fix: flake8 lint --- demo/demo/settings/base.py | 7 ++-- response/grafana/client.py | 35 +++++++++++-------- response/grafana/signals.py | 16 +++++---- .../0018_incident_grafana_annotation_id.py | 6 ++-- 4 files changed, 36 insertions(+), 28 deletions(-) diff --git a/demo/demo/settings/base.py b/demo/demo/settings/base.py index 764f5999..ccc8795b 100644 --- a/demo/demo/settings/base.py +++ b/demo/demo/settings/base.py @@ -15,8 +15,8 @@ from django.core.exceptions import ImproperlyConfigured -from response.slack.client import SlackClient from response.grafana.client import GrafanaClient +from response.slack.client import SlackClient logger = logging.getLogger(__name__) @@ -202,7 +202,4 @@ def get_env_var(setting, warn_only=False): GRAFANA_URL = get_env_var("GRAFANA_URL", warn_only=True) GRAFANA_CLIENT = None if GRAFANA_URL: - GRAFANA_CLIENT = GrafanaClient( - GRAFANA_URL, - get_env_var("GRAFANA_TOKEN") - ) + GRAFANA_CLIENT = GrafanaClient(GRAFANA_URL, get_env_var("GRAFANA_TOKEN")) diff --git a/response/grafana/client.py b/response/grafana/client.py index 21ef6112..d772462f 100644 --- a/response/grafana/client.py +++ b/response/grafana/client.py @@ -1,4 +1,5 @@ import logging + import requests logger = logging.getLogger(__name__) @@ -21,17 +22,19 @@ def create_annotation(self, **kwargs): payload = { "time": kwargs.get("time"), "tags": kwargs.get("tags"), - "text": kwargs.get("text") + "text": kwargs.get("text"), } headers = { - 'Authorization': 'Bearer {}'.format(self.token), - 'Content-Type': 'application/json' + "Authorization": "Bearer {}".format(self.token), + "Content-Type": "application/json", } - res = requests.post('{0}/api/{1}'.format(self.url, "annotations"), - headers=headers, - json=payload, - verify=True) + res = requests.post( + "{0}/api/{1}".format(self.url, "annotations"), + headers=headers, + json=payload, + verify=True, + ) result = res.json() res.close() @@ -53,16 +56,20 @@ def update_annotation(self, annotation_id, time, time_end, text, tags): payload["tags"] = tags headers = { - 'Authorization': 'Bearer {}'.format(self.token), - 'Content-Type': 'application/json' + "Authorization": "Bearer {}".format(self.token), + "Content-Type": "application/json", } - res = requests.patch('{0}/api/{1}/{2}'.format(self.url, "annotations", annotation_id), - headers=headers, - json=payload, - verify=True) + res = requests.patch( + "{0}/api/{1}/{2}".format(self.url, "annotations", annotation_id), + headers=headers, + json=payload, + verify=True, + ) result = res.json() res.close() if res.status_code == 200: return result - raise GrafanaError(f"Failed to update annotation: '{annotation_id}': '{result}'") + raise GrafanaError( + f"Failed to update annotation: '{annotation_id}': '{result}'" + ) diff --git a/response/grafana/signals.py b/response/grafana/signals.py index 2dff135d..25b3b6ef 100644 --- a/response/grafana/signals.py +++ b/response/grafana/signals.py @@ -1,8 +1,8 @@ import logging +from django.conf import settings from django.db.models.signals import post_save, pre_save from django.dispatch import receiver -from django.conf import settings from response.core.models import Incident @@ -19,19 +19,21 @@ def update_grafana_annotation_after_incident_save(sender, instance: Incident, ** """ if settings.GRAFANA_CLIENT and instance.grafana_annotation_id: tags = ["incident", instance.severity_text()] - text = "%s \n %s" % (instance.report, instance.summary) + text = f"{instance.report} \n {instance.summary}" settings.GRAFANA_CLIENT.update_annotation( instance.grafana_annotation_id, time=instance.report_time, time_end=instance.end_time, text=text, - tags=tags + tags=tags, ) @receiver(pre_save, sender=Incident) -def create_grafana_annotation_before_incident_save(sender, instance: Incident, **kwargs): +def create_grafana_annotation_before_incident_save( + sender, instance: Incident, **kwargs +): """ Create a grafana annotation ticket before saving the incident @@ -41,8 +43,10 @@ def create_grafana_annotation_before_incident_save(sender, instance: Incident, * if settings.GRAFANA_CLIENT and not instance.grafana_annotation_id: tags = ["incident", instance.severity_text()] - text = "%s \n %s" % (instance.report, instance.summary) + text = f"{instance.report} \n {instance.summary}" start_time = int(instance.report_time.timestamp() * 1000) - grafana_annotation = settings.GRAFANA_CLIENT.create_annotation(time=start_time, tags=tags, text=text) + grafana_annotation = settings.GRAFANA_CLIENT.create_annotation( + time=start_time, tags=tags, text=text + ) instance.grafana_annotation_id = grafana_annotation["id"] diff --git a/response/migrations/0018_incident_grafana_annotation_id.py b/response/migrations/0018_incident_grafana_annotation_id.py index 32bf14a9..2ca489fa 100644 --- a/response/migrations/0018_incident_grafana_annotation_id.py +++ b/response/migrations/0018_incident_grafana_annotation_id.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('response', '0017_externaluser_deleted'), + ("response", "0017_externaluser_deleted"), ] operations = [ migrations.AddField( - model_name='incident', - name='grafana_annotation_id', + model_name="incident", + name="grafana_annotation_id", field=models.PositiveIntegerField(blank=True, null=True), ), ]