From cb1eac50d98aa161c4ad7f888bd3be44cec030d1 Mon Sep 17 00:00:00 2001 From: Austin Date: Thu, 14 Dec 2017 11:10:08 -0800 Subject: [PATCH 01/11] Adds PagerTree Integration --- hc/api/models.py | 3 ++ hc/api/transports.py | 18 +++++++ hc/front/urls.py | 1 + static/img/integrations/pagertree.png | Bin 0 -> 4484 bytes templates/front/channels.html | 12 +++++ templates/front/log.html | 2 + templates/front/welcome.html | 7 +++ templates/integrations/add_pagertree.html | 46 ++++++++++++++++++ .../integrations/pagertree_description.html | 5 ++ templates/integrations/pagertree_title.html | 1 + 10 files changed, 95 insertions(+) create mode 100644 static/img/integrations/pagertree.png create mode 100644 templates/integrations/add_pagertree.html create mode 100644 templates/integrations/pagertree_description.html create mode 100644 templates/integrations/pagertree_title.html diff --git a/hc/api/models.py b/hc/api/models.py index 44cc2143..51c70e54 100644 --- a/hc/api/models.py +++ b/hc/api/models.py @@ -32,6 +32,7 @@ CHANNEL_KINDS = (("email", "Email"), ("hipchat", "HipChat"), ("slack", "Slack"), ("pd", "PagerDuty"), + ("pagertree", "PagerTree"), ("po", "Pushover"), ("pushbullet", "Pushbullet"), ("opsgenie", "OpsGenie"), @@ -260,6 +261,8 @@ class Channel(models.Model): return transports.HipChat(self) elif self.kind == "pd": return transports.PagerDuty(self) + elif self.kind == "pagertree": + return transports.PagerTree(self) elif self.kind == "victorops": return transports.VictorOps(self) elif self.kind == "pushbullet": diff --git a/hc/api/transports.py b/hc/api/transports.py index faf06cc8..4b1088d0 100644 --- a/hc/api/transports.py +++ b/hc/api/transports.py @@ -230,6 +230,24 @@ class PagerDuty(HttpTransport): return self.post(self.URL, json=payload) +class PagerTree(HttpTransport): + def notify(self, check): + url = self.channel.value + headers = { + "Conent-Type": "application/json" + } + payload = { + "incident_key": str(check.code), + "event_type": "trigger" if check.status == "down" else "resolve", + "title": tmpl("pagertree_title.html", check=check) + "description": tmpl("pagertree_description.html", check=check), + "client": settings.SITE_NAME, + "client_url": settings.SITE_ROOT, + "tags": ",".join(check.tags_list()) + } + + return self.post(url, json=payload, headers=headers) + class Pushbullet(HttpTransport): def notify(self, check): diff --git a/hc/front/urls.py b/hc/front/urls.py index 4b209b57..5f5352df 100644 --- a/hc/front/urls.py +++ b/hc/front/urls.py @@ -17,6 +17,7 @@ channel_urls = [ url(r'^add_webhook/$', views.add_webhook, name="hc-add-webhook"), url(r'^add_pd/$', views.add_pd, name="hc-add-pd"), url(r'^add_pd/([\w]{12})/$', views.add_pd, name="hc-add-pd-state"), + url(r'^add_pagertree/$', views.add_pagertree, name="hc-add-pagertree"), url(r'^add_slack/$', views.add_slack, name="hc-add-slack"), url(r'^add_slack_btn/$', views.add_slack_btn, name="hc-add-slack-btn"), url(r'^add_hipchat/$', views.add_hipchat, name="hc-add-hipchat"), diff --git a/static/img/integrations/pagertree.png b/static/img/integrations/pagertree.png new file mode 100644 index 0000000000000000000000000000000000000000..380f95f1e08d8728e4f03639c6a8d050492f4f1d GIT binary patch literal 4484 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 literal 0 HcmV?d00001 diff --git a/templates/front/channels.html b/templates/front/channels.html index f6f98b71..097ea24d 100644 --- a/templates/front/channels.html +++ b/templates/front/channels.html @@ -50,6 +50,9 @@ {% endif %} service key {{ ch.pd_service_key }} + {% elif ch.kind == "pagertree" %} + URL + {{ ch.value }} {% elif ch.kind == "opsgenie" %} API key {{ ch.value }} @@ -227,6 +230,15 @@ Add Integration {% endif %} +
  • + PagerTree icon + +

    PagerTree

    +

    On-call. Simplified.

    + + Add Integration +
  • HipChat icon diff --git a/templates/front/log.html b/templates/front/log.html index 42422737..5f302e29 100644 --- a/templates/front/log.html +++ b/templates/front/log.html @@ -89,6 +89,8 @@ {% endif %} {% elif event.channel.kind == "pd" %} Sent alert to PagerDuty + {% elif event.channel.kind == "pagertree" %} + Sent alert to PagerTree {% elif event.channel.kind == "opsgenie" %} Sent alert to OpsGenie {% elif event.channel.kind == "hipchat" %} diff --git a/templates/front/welcome.html b/templates/front/welcome.html index 75b70e13..3cb0f625 100644 --- a/templates/front/welcome.html +++ b/templates/front/welcome.html @@ -319,6 +319,13 @@ {% endif %} + + + PagerTree icon + + Open and resolve incidents in PagerTree. + + HipChat icon diff --git a/templates/integrations/add_pagertree.html b/templates/integrations/add_pagertree.html new file mode 100644 index 00000000..f3d161c9 --- /dev/null +++ b/templates/integrations/add_pagertree.html @@ -0,0 +1,46 @@ +{% extends "base.html" %} +{% load compress humanize staticfiles hc_extras %} + +{% block title %}Add PagerTree - {% site_name %}{% endblock %} + + +{% block content %} +
    +
    +

    PagerTree

    + +

    If your team uses PagerTree, + you can set up {% site_name %} to create a PagerTree incident when + a check goes down, and resolve it when a check goes back up.

    + +

    Integration Settings

    + +
    + {% csrf_token %} +
    + +
    + + + {% if form.value.errors %} +
    + {{ form.value.errors|join:"" }} +
    + {% endif %} +
    +
    +
    +
    + +
    +
    +
    +
    +
    +{% endblock %} diff --git a/templates/integrations/pagertree_description.html b/templates/integrations/pagertree_description.html new file mode 100644 index 00000000..11718355 --- /dev/null +++ b/templates/integrations/pagertree_description.html @@ -0,0 +1,5 @@ +{% load humanize %} +{{ check.name_then_code }} is {{ check.status }}. +{% if check.status == "down" %} +Last ping was {{ check.last_ping|naturaltime }} +{% endif %} diff --git a/templates/integrations/pagertree_title.html b/templates/integrations/pagertree_title.html new file mode 100644 index 00000000..b537551e --- /dev/null +++ b/templates/integrations/pagertree_title.html @@ -0,0 +1 @@ +{{ check.name_then_code }} is {{ check.status }} From 17831bb974c764b94ca24987a5968acba9f90065 Mon Sep 17 00:00:00 2001 From: Austin Date: Thu, 14 Dec 2017 11:21:21 -0800 Subject: [PATCH 02/11] Adds missing comma --- hc/api/transports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hc/api/transports.py b/hc/api/transports.py index 4b1088d0..b94c1b40 100644 --- a/hc/api/transports.py +++ b/hc/api/transports.py @@ -239,7 +239,7 @@ class PagerTree(HttpTransport): payload = { "incident_key": str(check.code), "event_type": "trigger" if check.status == "down" else "resolve", - "title": tmpl("pagertree_title.html", check=check) + "title": tmpl("pagertree_title.html", check=check), "description": tmpl("pagertree_description.html", check=check), "client": settings.SITE_NAME, "client_url": settings.SITE_ROOT, From abe7076a7384184ce4ab2fc7e7eae3ca11cda117 Mon Sep 17 00:00:00 2001 From: Austin Date: Thu, 14 Dec 2017 11:25:36 -0800 Subject: [PATCH 03/11] Add the PagerTree form handler --- hc/front/views.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/hc/front/views.py b/hc/front/views.py index 22853577..d7043f50 100644 --- a/hc/front/views.py +++ b/hc/front/views.py @@ -512,6 +512,23 @@ def add_pd(request, state=None): ctx = {"page": "channels", "connect_url": connect_url} return render(request, "integrations/add_pd.html", ctx) +@login_required +def add_pagertree(request): + if request.method == "POST": + form = AddUrlForm(request.POST) + if form.is_valid(): + channel = Channel(user=request.team.user, kind="pagertree") + channel.value = form.cleaned_data["value"] + channel.save() + + channel.assign_all_checks() + return redirect("hc-channels") + else: + form = AddUrlForm() + + ctx = {"page": "channels", "form": form} + return render(request, "integrations/add_pagertree.html", ctx) + def add_slack(request): if not settings.SLACK_CLIENT_ID and not request.user.is_authenticated: From 7808f3a5d49948aa1104e5eb0863fc25f1762aa1 Mon Sep 17 00:00:00 2001 From: Austin Date: Thu, 14 Dec 2017 15:28:23 -0800 Subject: [PATCH 04/11] Modifys our template --- templates/integrations/pagertree_description.html | 4 ++-- templates/integrations/pagertree_title.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/integrations/pagertree_description.html b/templates/integrations/pagertree_description.html index 11718355..22c9e800 100644 --- a/templates/integrations/pagertree_description.html +++ b/templates/integrations/pagertree_description.html @@ -1,5 +1,5 @@ {% load humanize %} -{{ check.name_then_code }} is {{ check.status }}. +{{ check.name_then_code }} is {{ check.status|upper }}. {% if check.status == "down" %} -Last ping was {{ check.last_ping|naturaltime }} +Last ping was {{ check.last_ping|naturaltime }}. {% endif %} diff --git a/templates/integrations/pagertree_title.html b/templates/integrations/pagertree_title.html index b537551e..29274284 100644 --- a/templates/integrations/pagertree_title.html +++ b/templates/integrations/pagertree_title.html @@ -1 +1 @@ -{{ check.name_then_code }} is {{ check.status }} +{{ check.name_then_code }} is {{ check.status|upper }} From 07069d74555b3ea184be5201fb7fe77b214199fc Mon Sep 17 00:00:00 2001 From: Austin Date: Thu, 14 Dec 2017 15:32:01 -0800 Subject: [PATCH 05/11] Tweak PagerTree description --- templates/front/channels.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/front/channels.html b/templates/front/channels.html index 097ea24d..9e8b14f1 100644 --- a/templates/front/channels.html +++ b/templates/front/channels.html @@ -235,7 +235,7 @@ class="icon" alt="PagerTree icon" />

    PagerTree

    -

    On-call. Simplified.

    +

    DevOps Incident Management - On-Call Schedules, Alerts, & Notifications

    Add Integration
  • From 7eed6160c1aad28d40c322032bb7d7a809f6c5ab Mon Sep 17 00:00:00 2001 From: Austin Date: Thu, 14 Dec 2017 16:07:24 -0800 Subject: [PATCH 06/11] Adds test for pagertree --- hc/api/tests/test_notify.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hc/api/tests/test_notify.py b/hc/api/tests/test_notify.py index d65d6121..d9cc9e7e 100644 --- a/hc/api/tests/test_notify.py +++ b/hc/api/tests/test_notify.py @@ -283,6 +283,18 @@ class NotifyTestCase(BaseTestCase): self.assertEqual(payload["event_type"], "trigger") self.assertEqual(payload["service_key"], "456") + @patch("hc.api.transports.requests.request") + def test_pd(self, mock_post): + self._setup_data("pagertree", "123") + mock_post.return_value.status_code = 200 + + self.channel.notify(self.check) + assert Notification.objects.count() == 1 + + args, kwargs = mock_post.call_args + payload = kwargs["json"] + self.assertEqual(payload["event_type"], "trigger") + @patch("hc.api.transports.requests.request") def test_slack(self, mock_post): self._setup_data("slack", "123") From 201d1a0815470ae4105c4c3e1af3f2dfb3215e34 Mon Sep 17 00:00:00 2001 From: Austin Date: Thu, 14 Dec 2017 16:11:42 -0800 Subject: [PATCH 07/11] Rename the test function --- hc/api/tests/test_notify.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hc/api/tests/test_notify.py b/hc/api/tests/test_notify.py index d9cc9e7e..286e03a9 100644 --- a/hc/api/tests/test_notify.py +++ b/hc/api/tests/test_notify.py @@ -284,7 +284,7 @@ class NotifyTestCase(BaseTestCase): self.assertEqual(payload["service_key"], "456") @patch("hc.api.transports.requests.request") - def test_pd(self, mock_post): + def test_pagertree(self, mock_post): self._setup_data("pagertree", "123") mock_post.return_value.status_code = 200 From 6a17c8768bc5c5cda7f1ed26da550fb2da9d21f7 Mon Sep 17 00:00:00 2001 From: Austin Date: Thu, 14 Dec 2017 16:20:30 -0800 Subject: [PATCH 08/11] Adds a test for out integration form --- hc/front/tests/test_add_pagertree.py | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 hc/front/tests/test_add_pagertree.py diff --git a/hc/front/tests/test_add_pagertree.py b/hc/front/tests/test_add_pagertree.py new file mode 100644 index 00000000..a1f100f5 --- /dev/null +++ b/hc/front/tests/test_add_pagertree.py @@ -0,0 +1,29 @@ +from hc.api.models import Channel +from hc.test import BaseTestCase + + +class AddVictorOpsTestCase(BaseTestCase): + url = "/integrations/add_pagertree/" + + def test_instructions_work(self): + self.client.login(username="alice@example.org", password="password") + r = self.client.get(self.url) + self.assertContains(r, "to create a PagerTree incident when a check goes down, and resolve it when a check goes back up.") + + def test_it_works(self): + form = {"value": "http://example.org"} + + self.client.login(username="alice@example.org", password="password") + r = self.client.post(self.url, form) + self.assertRedirects(r, "/integrations/") + + c = Channel.objects.get() + self.assertEqual(c.kind, "pagertree") + self.assertEqual(c.value, "http://example.org") + + def test_it_rejects_bad_url(self): + form = {"value": "not an URL"} + + self.client.login(username="alice@example.org", password="password") + r = self.client.post(self.url, form) + self.assertContains(r, "Enter a valid URL") From ef90e6e3b898bc64ddf02c7f05616fec7995a0ac Mon Sep 17 00:00:00 2001 From: Austin Date: Thu, 14 Dec 2017 16:27:02 -0800 Subject: [PATCH 09/11] Rename the class --- hc/front/tests/test_add_pagertree.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hc/front/tests/test_add_pagertree.py b/hc/front/tests/test_add_pagertree.py index a1f100f5..6f06fed1 100644 --- a/hc/front/tests/test_add_pagertree.py +++ b/hc/front/tests/test_add_pagertree.py @@ -2,13 +2,13 @@ from hc.api.models import Channel from hc.test import BaseTestCase -class AddVictorOpsTestCase(BaseTestCase): +class AddPagerTreeTestCase(BaseTestCase): url = "/integrations/add_pagertree/" def test_instructions_work(self): self.client.login(username="alice@example.org", password="password") r = self.client.get(self.url) - self.assertContains(r, "to create a PagerTree incident when a check goes down, and resolve it when a check goes back up.") + self.assertContains(r, "PagerTree") def test_it_works(self): form = {"value": "http://example.org"} From 231421fada4a296cf8c0d16a633a809b09fb41da Mon Sep 17 00:00:00 2001 From: Austin Date: Fri, 15 Dec 2017 08:25:02 -0800 Subject: [PATCH 10/11] Fixes the pagertree url --- templates/front/welcome.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/front/welcome.html b/templates/front/welcome.html index 3cb0f625..cfc1d85d 100644 --- a/templates/front/welcome.html +++ b/templates/front/welcome.html @@ -323,7 +323,7 @@ PagerTree icon - Open and resolve incidents in PagerTree. + Open and resolve incidents in PagerTree. From 8ab8bcdbbe5710e31a8821d329980a21574d6074 Mon Sep 17 00:00:00 2001 From: Austin Date: Fri, 15 Dec 2017 08:55:41 -0800 Subject: [PATCH 11/11] Adds a nice tutorial for the PagerTree integration --- static/img/integrations/setup_pagertree_1.png | Bin 0 -> 4821 bytes static/img/integrations/setup_pagertree_2.png | Bin 0 -> 9975 bytes static/img/integrations/setup_pagertree_3.png | Bin 0 -> 2919 bytes templates/integrations/add_pagertree.html | 115 ++++++++++++------ 4 files changed, 81 insertions(+), 34 deletions(-) create mode 100644 static/img/integrations/setup_pagertree_1.png create mode 100644 static/img/integrations/setup_pagertree_2.png create mode 100644 static/img/integrations/setup_pagertree_3.png diff --git a/static/img/integrations/setup_pagertree_1.png b/static/img/integrations/setup_pagertree_1.png new file mode 100644 index 0000000000000000000000000000000000000000..9d727d03327ebfba890eee976bbe5f2f6d66882f GIT binary patch literal 4821 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 F{x2g?u|NO- literal 0 HcmV?d00001 diff --git a/templates/integrations/add_pagertree.html b/templates/integrations/add_pagertree.html index f3d161c9..33fe3d94 100644 --- a/templates/integrations/add_pagertree.html +++ b/templates/integrations/add_pagertree.html @@ -6,41 +6,88 @@ {% block content %}
    -
    -

    PagerTree

    - -

    If your team uses PagerTree, - you can set up {% site_name %} to create a PagerTree incident when - a check goes down, and resolve it when a check goes back up.

    - -

    Integration Settings

    - -
    - {% csrf_token %} -
    - -
    - - - {% if form.value.errors %} -
    - {{ form.value.errors|join:"" }} -
    - {% endif %} -
    +
    +

    PagerTree

    + +

    If your team uses PagerTree, + you can set up {% site_name %} to create a PagerTree incident when + a check goes down, and resolve it when a check goes back up.

    + +

    Setup Guide

    + +
    +
    + 1 +

    + Log into your PagerTree account, select the team you wish to add this integration to. Click the Integrations tab. Then click the + Integration button. +

    -
    -
    - -
    +
    + Click create integration button
    - -
    +
    + +
    +
    + 2 +

    + In the Create Integration Form, fill out the details with apprpriate values, but most importantly make sure the Integration Type is set to Healthchecks.io. Then click the Create button. +

    +
    +
    + Create Healthchecks.io integration with details +
    +
    + +
    +
    + 3 +

    + Copy the Webhook URL and paste it below. Save the integration, and you are done! +

    +
    +
    + Copy the Webhook URL +
    +
    + +

    Integration Settings

    + +
    + {% csrf_token %} +
    + +
    + + + {% if form.value.errors %} +
    + {{ form.value.errors|join:"" }} +
    + {% endif %} +
    +
    +
    +
    + +
    +
    +
    +
    {% endblock %}