forked from GithubBackups/healthchecks
Set Pushover alert priorities for "down" and "up" events separately. Fixes #204
This commit is contained in:
parent
2e6d050656
commit
fb45b67892
@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
- Set Pushover alert priorities for "down" and "up" events separately
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
- Fix after-login redirects for users landing in the "Add Slack" page
|
- Fix after-login redirects for users landing in the "Add Slack" page
|
||||||
|
|
||||||
|
@ -339,11 +339,11 @@ class Channel(models.Model):
|
|||||||
return 'img/integrations/%s.png' % self.kind
|
return 'img/integrations/%s.png' % self.kind
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def po_value(self):
|
def po_priority(self):
|
||||||
assert self.kind == "po"
|
assert self.kind == "po"
|
||||||
user_key, prio = self.value.split("|")
|
parts = self.value.split("|")
|
||||||
prio = int(prio)
|
prio = int(parts[1])
|
||||||
return user_key, prio, PO_PRIORITIES[prio]
|
return PO_PRIORITIES[prio]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def url_down(self):
|
def url_down(self):
|
||||||
|
@ -405,6 +405,21 @@ class NotifyTestCase(BaseTestCase):
|
|||||||
payload = kwargs["data"]
|
payload = kwargs["data"]
|
||||||
self.assertIn("DOWN", payload["title"])
|
self.assertIn("DOWN", payload["title"])
|
||||||
|
|
||||||
|
@patch("hc.api.transports.requests.request")
|
||||||
|
def test_pushover_up_priority(self, mock_post):
|
||||||
|
self._setup_data("po", "123|0|2", status="up")
|
||||||
|
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["data"]
|
||||||
|
self.assertIn("UP", payload["title"])
|
||||||
|
self.assertEqual(payload["priority"], 2)
|
||||||
|
self.assertIn("retry", payload)
|
||||||
|
self.assertIn("expire", payload)
|
||||||
|
|
||||||
@patch("hc.api.transports.requests.request")
|
@patch("hc.api.transports.requests.request")
|
||||||
def test_victorops(self, mock_post):
|
def test_victorops(self, mock_post):
|
||||||
self._setup_data("victorops", "123")
|
self._setup_data("victorops", "123")
|
||||||
|
@ -304,7 +304,13 @@ class Pushover(HttpTransport):
|
|||||||
}
|
}
|
||||||
text = tmpl("pushover_message.html", **ctx)
|
text = tmpl("pushover_message.html", **ctx)
|
||||||
title = tmpl("pushover_title.html", **ctx)
|
title = tmpl("pushover_title.html", **ctx)
|
||||||
user_key, prio = self.channel.value.split("|")
|
|
||||||
|
pieces = self.channel.value.split("|")
|
||||||
|
user_key, prio = pieces[0], pieces[1]
|
||||||
|
# The third element, if present, is the priority for "up" events
|
||||||
|
if len(pieces) == 3 and check.status == "up":
|
||||||
|
prio = pieces[2]
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"token": settings.PUSHOVER_API_TOKEN,
|
"token": settings.PUSHOVER_API_TOKEN,
|
||||||
"user": user_key,
|
"user": user_key,
|
||||||
|
@ -39,13 +39,13 @@ class AddPushoverTestCase(BaseTestCase):
|
|||||||
session["pushover"] = "foo"
|
session["pushover"] = "foo"
|
||||||
session.save()
|
session.save()
|
||||||
|
|
||||||
params = "pushover_user_key=a&state=foo&prio=0"
|
params = "pushover_user_key=a&state=foo&prio=0&prio_up=-1"
|
||||||
r = self.client.get("/integrations/add_pushover/?%s" % params)
|
r = self.client.get("/integrations/add_pushover/?%s" % params)
|
||||||
self.assertEqual(r.status_code, 302)
|
self.assertEqual(r.status_code, 302)
|
||||||
|
|
||||||
channels = list(Channel.objects.all())
|
channels = list(Channel.objects.all())
|
||||||
assert len(channels) == 1
|
assert len(channels) == 1
|
||||||
assert channels[0].value == "a|0"
|
assert channels[0].value == "a|0|-1"
|
||||||
|
|
||||||
def test_it_validates_priority(self):
|
def test_it_validates_priority(self):
|
||||||
self.client.login(username="alice@example.org", password="password")
|
self.client.login(username="alice@example.org", password="password")
|
||||||
@ -58,6 +58,17 @@ class AddPushoverTestCase(BaseTestCase):
|
|||||||
r = self.client.get("/integrations/add_pushover/?%s" % params)
|
r = self.client.get("/integrations/add_pushover/?%s" % params)
|
||||||
self.assertEqual(r.status_code, 400)
|
self.assertEqual(r.status_code, 400)
|
||||||
|
|
||||||
|
def test_it_validates_priority_up(self):
|
||||||
|
self.client.login(username="alice@example.org", password="password")
|
||||||
|
|
||||||
|
session = self.client.session
|
||||||
|
session["pushover"] = "foo"
|
||||||
|
session.save()
|
||||||
|
|
||||||
|
params = "pushover_user_key=a&state=foo&prio_up=abc"
|
||||||
|
r = self.client.get("/integrations/add_pushover/?%s" % params)
|
||||||
|
self.assertEqual(r.status_code, 400)
|
||||||
|
|
||||||
def test_it_validates_state(self):
|
def test_it_validates_state(self):
|
||||||
self.client.login(username="alice@example.org", password="password")
|
self.client.login(username="alice@example.org", password="password")
|
||||||
|
|
||||||
|
@ -873,6 +873,7 @@ def add_pushover(request):
|
|||||||
success_url = settings.SITE_ROOT + reverse("hc-add-pushover") + "?" + urlencode({
|
success_url = settings.SITE_ROOT + reverse("hc-add-pushover") + "?" + urlencode({
|
||||||
"state": state,
|
"state": state,
|
||||||
"prio": request.POST.get("po_priority", "0"),
|
"prio": request.POST.get("po_priority", "0"),
|
||||||
|
"prio_up": request.POST.get("po_priority_up", "0")
|
||||||
})
|
})
|
||||||
subscription_url = settings.PUSHOVER_SUBSCRIPTION_URL + "?" + urlencode({
|
subscription_url = settings.PUSHOVER_SUBSCRIPTION_URL + "?" + urlencode({
|
||||||
"success": success_url,
|
"success": success_url,
|
||||||
@ -892,6 +893,10 @@ def add_pushover(request):
|
|||||||
if prio not in ("-2", "-1", "0", "1", "2"):
|
if prio not in ("-2", "-1", "0", "1", "2"):
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
|
prio_up = request.GET.get("prio_up")
|
||||||
|
if prio_up not in ("-2", "-1", "0", "1", "2"):
|
||||||
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
if request.GET.get("pushover_unsubscribed") == "1":
|
if request.GET.get("pushover_unsubscribed") == "1":
|
||||||
# Unsubscription: delete all Pushover channels for this user
|
# Unsubscription: delete all Pushover channels for this user
|
||||||
Channel.objects.filter(user=request.user, kind="po").delete()
|
Channel.objects.filter(user=request.user, kind="po").delete()
|
||||||
@ -899,7 +904,7 @@ def add_pushover(request):
|
|||||||
|
|
||||||
# Subscription
|
# Subscription
|
||||||
channel = Channel(user=request.team.user, kind="po")
|
channel = Channel(user=request.team.user, kind="po")
|
||||||
channel.value = "%s|%s" % (key, prio)
|
channel.value = "%s|%s|%s" % (key, prio, prio_up)
|
||||||
channel.save()
|
channel.save()
|
||||||
channel.assign_all_checks()
|
channel.assign_all_checks()
|
||||||
|
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
#add-pushover .radio {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#add-pushover .help {
|
#add-pushover .help {
|
||||||
display: block;
|
opacity: 0.6;
|
||||||
color: #888;
|
|
||||||
}
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 20 KiB |
@ -54,7 +54,7 @@
|
|||||||
{% elif ch.kind == "victorops" %}
|
{% elif ch.kind == "victorops" %}
|
||||||
VictorOps
|
VictorOps
|
||||||
{% elif ch.kind == "po" %}
|
{% elif ch.kind == "po" %}
|
||||||
Pushover ({{ ch.po_value|last }} priority)
|
Pushover ({{ ch.po_priority }} priority)
|
||||||
{% elif ch.kind == "slack" %}
|
{% elif ch.kind == "slack" %}
|
||||||
Slack
|
Slack
|
||||||
{% if ch.slack_team %}
|
{% if ch.slack_team %}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load humanize static hc_extras %}
|
{% load compress humanize static hc_extras %}
|
||||||
|
|
||||||
{% block title %}Add Pushover - {% site_name %}{% endblock %}
|
{% block title %}Add Pushover - {% site_name %}{% endblock %}
|
||||||
|
|
||||||
@ -56,7 +56,7 @@
|
|||||||
<p>
|
<p>
|
||||||
After logging in, go to "Integrations → Add Pushover".
|
After logging in, go to "Integrations → Add Pushover".
|
||||||
Pushover supports different notification priorities from
|
Pushover supports different notification priorities from
|
||||||
silent to "Emergency". Select your preferred priority
|
silent to "Emergency". Select your preferred priorities
|
||||||
and click "Subscribe with Pushover".
|
and click "Subscribe with Pushover".
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -106,65 +106,72 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<h2>Integration Settings</h2>
|
<h2>Integration Settings</h2>
|
||||||
|
|
||||||
<form method="post" id="add-pushover" class="form-horizontal" action="{% url 'hc-add-pushover' %}">
|
<form id="add-pushover" method="post" class="form-horizontal" action="{% url 'hc-add-pushover' %}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-sm-2 control-label">Notification priority</label>
|
<label class="col-sm-3 control-label">Priority for "down" events</label>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-8">
|
||||||
<div class="radio">
|
<select name="po_priority" class="selectpicker form-control">
|
||||||
<label>
|
<option
|
||||||
<input type="radio" name="po_priority" value="-2">
|
value="-2"
|
||||||
Lowest Priority.
|
data-content="Lowest Priority. <span class='help'>Generates no notification on your device.</span>">
|
||||||
<span class="help">
|
Lowest Priority
|
||||||
Generates no notification/alert on your device.
|
</option>
|
||||||
On iOS, the application badge number will be increased.
|
<option
|
||||||
</span>
|
value="-1"
|
||||||
</label>
|
data-content="Low Priority. <span class='help'>Sends a quiet notification.</span>">
|
||||||
</div>
|
Low Priority
|
||||||
|
</option>
|
||||||
<div class="radio">
|
<option value="0" selected="selected">
|
||||||
<label>
|
Normal Priority
|
||||||
<input type="radio" name="po_priority" value="-1">
|
</option>
|
||||||
Low Priority.
|
<option
|
||||||
<span class="help">
|
value="1"
|
||||||
Sends a quiet notification.
|
data-content="High Priority. <span class='help'>Bypasses user's quiet hours.</span>">
|
||||||
</span>
|
High Priority
|
||||||
</label>
|
</option>
|
||||||
</div>
|
<option
|
||||||
|
value="2"
|
||||||
<div class="radio">
|
data-content="Emergency Priority. <span class='help'>Repeated every {{po_retry_delay|hc_duration }} for at most {{ po_expiration|hc_duration }} until you acknowledge them.</span>">
|
||||||
<label>
|
Emergency Priority
|
||||||
<input type="radio" name="po_priority" value="0" checked>
|
</option>
|
||||||
Normal Priority.
|
</select>
|
||||||
</label>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="radio">
|
|
||||||
<label>
|
|
||||||
<input type="radio" name="po_priority" value="1">
|
|
||||||
<span class="text-warning">High Priority.</span>
|
|
||||||
<span class="help">
|
|
||||||
Bypasses user's quiet hours.
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="radio">
|
|
||||||
<label>
|
|
||||||
<input type="radio" name="po_priority" value="2">
|
|
||||||
<span class="text-danger">Emergency Priority.</span>
|
|
||||||
<span class="help">
|
|
||||||
The notification is repeated every
|
|
||||||
{{po_retry_delay|hc_duration }} for at most
|
|
||||||
{{ po_expiration|hc_duration }} until you
|
|
||||||
acknowledge them.
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-offset-2 col-sm-10">
|
<label class="col-sm-3 control-label">Priority for "up" events</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<select name="po_priority_up" class="selectpicker form-control">
|
||||||
|
<option
|
||||||
|
value="-2"
|
||||||
|
data-content="Lowest Priority. <span class='help'>Generates no notification on your device.</span>">
|
||||||
|
Lowest Priority
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="-1"
|
||||||
|
data-content="Low Priority. <span class='help'>Sends a quiet notification.</span>">
|
||||||
|
Low Priority
|
||||||
|
</option>
|
||||||
|
<option value="0" selected="selected">
|
||||||
|
Normal Priority
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="1"
|
||||||
|
data-content="High Priority. <span class='help'>Bypasses user's quiet hours.</span>">
|
||||||
|
High Priority
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="2"
|
||||||
|
data-content="Emergency Priority. <span class='help'>Repeated every {{po_retry_delay|hc_duration }} for at most {{ po_expiration|hc_duration }} until you acknowledge them.</span>">
|
||||||
|
Emergency Priority
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-offset-3 col-sm-8">
|
||||||
<button type="submit" class="btn btn-default">
|
<button type="submit" class="btn btn-default">
|
||||||
<img class="ai-icon" src="{% static 'img/integrations/po.png' %}" alt="Pushover" />
|
<img class="ai-icon" src="{% static 'img/integrations/po.png' %}" alt="Pushover" />
|
||||||
Subscribe with Pushover
|
Subscribe with Pushover
|
||||||
@ -176,3 +183,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{% compress js %}
|
||||||
|
<script src="{% static 'js/jquery-2.1.4.min.js' %}"></script>
|
||||||
|
<script src="{% static 'js/bootstrap.min.js' %}"></script>
|
||||||
|
<script src="{% static 'js/bootstrap-select.min.js' %}"></script>
|
||||||
|
{% endcompress %}
|
||||||
|
{% endblock %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user