forked from GithubBackups/healthchecks
parent
20008a1d7e
commit
0e77064c44
@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
## Improvements
|
## Improvements
|
||||||
- Add a tooltip to the 'confirmation link' label (#436)
|
- Add a tooltip to the 'confirmation link' label (#436)
|
||||||
|
- Update API to allow specifying channels by names (#440)
|
||||||
|
|
||||||
## v1.17.0 - 2020-10-14
|
## v1.17.0 - 2020-10-14
|
||||||
|
|
||||||
|
@ -123,6 +123,28 @@ class UpdateCheckTestCase(BaseTestCase):
|
|||||||
self.check.refresh_from_db()
|
self.check.refresh_from_db()
|
||||||
self.assertEqual(self.check.channel_set.count(), 1)
|
self.assertEqual(self.check.channel_set.count(), 1)
|
||||||
|
|
||||||
|
def test_it_sets_channel_by_name(self):
|
||||||
|
channel = Channel.objects.create(project=self.project, name="alerts")
|
||||||
|
|
||||||
|
r = self.post(self.check.code, {"api_key": "X" * 32, "channels": "alerts"})
|
||||||
|
|
||||||
|
self.assertEqual(r.status_code, 200)
|
||||||
|
|
||||||
|
self.check.refresh_from_db()
|
||||||
|
self.assertEqual(self.check.channel_set.count(), 1)
|
||||||
|
self.assertEqual(self.check.channel_set.first().code, channel.code)
|
||||||
|
|
||||||
|
def test_it_sets_channel_by_name_formatted_as_uuid(self):
|
||||||
|
name = "102eaa82-a274-4b15-a499-c1bb6bbcd7b6"
|
||||||
|
channel = Channel.objects.create(project=self.project, name=name)
|
||||||
|
|
||||||
|
r = self.post(self.check.code, {"api_key": "X" * 32, "channels": name})
|
||||||
|
self.assertEqual(r.status_code, 200)
|
||||||
|
|
||||||
|
self.check.refresh_from_db()
|
||||||
|
self.assertEqual(self.check.channel_set.count(), 1)
|
||||||
|
self.assertEqual(self.check.channel_set.first().code, channel.code)
|
||||||
|
|
||||||
def test_it_handles_comma_separated_channel_codes(self):
|
def test_it_handles_comma_separated_channel_codes(self):
|
||||||
c1 = Channel.objects.create(project=self.project)
|
c1 = Channel.objects.create(project=self.project)
|
||||||
c2 = Channel.objects.create(project=self.project)
|
c2 = Channel.objects.create(project=self.project)
|
||||||
@ -187,10 +209,33 @@ class UpdateCheckTestCase(BaseTestCase):
|
|||||||
self.check.refresh_from_db()
|
self.check.refresh_from_db()
|
||||||
self.assertEqual(self.check.channel_set.count(), 0)
|
self.assertEqual(self.check.channel_set.count(), 0)
|
||||||
|
|
||||||
def test_it_rejects_non_uuid_channel_code(self):
|
def test_it_handles_channel_lookup_by_name_with_no_results(self):
|
||||||
r = self.post(self.check.code, {"api_key": "X" * 32, "channels": "foo"})
|
r = self.post(self.check.code, {"api_key": "X" * 32, "channels": "foo"})
|
||||||
|
|
||||||
self.assertEqual(r.status_code, 400)
|
self.assertEqual(r.status_code, 400)
|
||||||
|
self.assertEqual(r.json()["error"], "invalid channel identifier: foo")
|
||||||
|
|
||||||
|
self.check.refresh_from_db()
|
||||||
|
self.assertEqual(self.check.channel_set.count(), 0)
|
||||||
|
|
||||||
|
def test_it_handles_channel_lookup_by_name_with_multiple_results(self):
|
||||||
|
Channel.objects.create(project=self.project, name="foo")
|
||||||
|
Channel.objects.create(project=self.project, name="foo")
|
||||||
|
|
||||||
|
r = self.post(self.check.code, {"api_key": "X" * 32, "channels": "foo"})
|
||||||
|
|
||||||
|
self.assertEqual(r.status_code, 400)
|
||||||
|
self.assertEqual(r.json()["error"], "non-unique channel identifier: foo")
|
||||||
|
|
||||||
|
self.check.refresh_from_db()
|
||||||
|
self.assertEqual(self.check.channel_set.count(), 0)
|
||||||
|
|
||||||
|
def test_it_rejects_multiple_empty_channel_names(self):
|
||||||
|
Channel.objects.create(project=self.project, name="")
|
||||||
|
|
||||||
|
r = self.post(self.check.code, {"api_key": "X" * 32, "channels": ","})
|
||||||
|
self.assertEqual(r.status_code, 400)
|
||||||
|
self.assertEqual(r.json()["error"], "empty channel identifier")
|
||||||
|
|
||||||
self.check.refresh_from_db()
|
self.check.refresh_from_db()
|
||||||
self.assertEqual(self.check.channel_set.count(), 0)
|
self.assertEqual(self.check.channel_set.count(), 0)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from datetime import timedelta as td
|
from datetime import timedelta as td
|
||||||
import time
|
import time
|
||||||
import uuid
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
@ -71,20 +70,32 @@ def _lookup(project, spec):
|
|||||||
|
|
||||||
|
|
||||||
def _update(check, spec):
|
def _update(check, spec):
|
||||||
channels = set()
|
# First, validate the supplied channel codes/names
|
||||||
# First, validate the supplied channel codes
|
if "channels" not in spec:
|
||||||
if "channels" in spec and spec["channels"] not in ("*", ""):
|
# If the channels key is not present, don't update check's channels
|
||||||
q = Channel.objects.filter(project=check.project)
|
new_channels = None
|
||||||
for s in spec["channels"].split(","):
|
elif spec["channels"] == "*":
|
||||||
try:
|
# "*" means "all project's channels"
|
||||||
code = uuid.UUID(s)
|
new_channels = Channel.objects.filter(project=check.project)
|
||||||
except ValueError:
|
elif spec.get("channels") == "":
|
||||||
raise BadChannelException("invalid channel identifier: %s" % s)
|
# "" means "empty list"
|
||||||
|
new_channels = []
|
||||||
|
else:
|
||||||
|
# expect a comma-separated list of channel codes or names
|
||||||
|
new_channels = set()
|
||||||
|
available = list(Channel.objects.filter(project=check.project))
|
||||||
|
|
||||||
try:
|
for s in spec["channels"].split(","):
|
||||||
channels.add(q.get(code=code))
|
if s == "":
|
||||||
except Channel.DoesNotExist:
|
raise BadChannelException("empty channel identifier")
|
||||||
|
|
||||||
|
matches = [c for c in available if str(c.code) == s or c.name == s]
|
||||||
|
if len(matches) == 0:
|
||||||
raise BadChannelException("invalid channel identifier: %s" % s)
|
raise BadChannelException("invalid channel identifier: %s" % s)
|
||||||
|
elif len(matches) > 1:
|
||||||
|
raise BadChannelException("non-unique channel identifier: %s" % s)
|
||||||
|
|
||||||
|
new_channels.add(matches[0])
|
||||||
|
|
||||||
if "name" in spec:
|
if "name" in spec:
|
||||||
check.name = spec["name"]
|
check.name = spec["name"]
|
||||||
@ -119,12 +130,8 @@ def _update(check, spec):
|
|||||||
|
|
||||||
# This needs to be done after saving the check, because of
|
# This needs to be done after saving the check, because of
|
||||||
# the M2M relation between checks and channels:
|
# the M2M relation between checks and channels:
|
||||||
if spec.get("channels") == "*":
|
if new_channels is not None:
|
||||||
check.assign_all_channels()
|
check.channel_set.set(new_channels)
|
||||||
elif spec.get("channels") == "":
|
|
||||||
check.channel_set.clear()
|
|
||||||
elif channels:
|
|
||||||
check.channel_set.set(channels)
|
|
||||||
|
|
||||||
return check
|
return check
|
||||||
|
|
||||||
|
@ -347,10 +347,20 @@ and POST requests.</p>
|
|||||||
<p>By default, this API call assigns no integrations to the newly created
|
<p>By default, this API call assigns no integrations to the newly created
|
||||||
check.</p>
|
check.</p>
|
||||||
<p>Set this field to a special value "*" to automatically assign all existing
|
<p>Set this field to a special value "*" to automatically assign all existing
|
||||||
integrations.</p>
|
integrations. Example:</p>
|
||||||
|
<p><pre>{"channels": "*"}</pre></p>
|
||||||
<p>To assign specific integrations, use a comma-separated list of integration
|
<p>To assign specific integrations, use a comma-separated list of integration
|
||||||
identifiers. Use the <a href="#list-channels">Get a List of Existing Integrations</a>
|
UUIDs. You can look up integration UUIDs using the
|
||||||
API call to look up the available integration identifiers.</p>
|
<a href="#list-channels">Get a List of Existing Integrations</a> API call.</p>
|
||||||
|
<p>Example:</p>
|
||||||
|
<p><pre>{"channels":
|
||||||
|
"4ec5a071-2d08-4baa-898a-eb4eb3cd6941,746a083e-f542-4554-be1a-707ce16d3acc"}</pre></p>
|
||||||
|
<p>Alternatively, if you have named your integrations in SITE_NAME dashboard,
|
||||||
|
you can specify integrations by their names. For this to work, your integrations
|
||||||
|
need non-empty and unique names, and they must not contain commas. The names
|
||||||
|
must match exactly, whitespace is significant.</p>
|
||||||
|
<p>Example:</p>
|
||||||
|
<p><pre>{"channels": "Email to Alice,SMS to Alice"}</pre></p>
|
||||||
</dd>
|
</dd>
|
||||||
<dt>unique</dt>
|
<dt>unique</dt>
|
||||||
<dd>
|
<dd>
|
||||||
@ -496,13 +506,23 @@ and POST requests.</p>
|
|||||||
<dd>
|
<dd>
|
||||||
<p>string, optional.</p>
|
<p>string, optional.</p>
|
||||||
<p>Set this field to a special value "*" to automatically assign all existing
|
<p>Set this field to a special value "*" to automatically assign all existing
|
||||||
notification channels.</p>
|
integrations. Example:</p>
|
||||||
|
<p><pre>{"channels": "*"}</pre></p>
|
||||||
<p>Set this field to a special value "" (empty string) to automatically <em>unassign</em>
|
<p>Set this field to a special value "" (empty string) to automatically <em>unassign</em>
|
||||||
all notification channels.</p>
|
all existing integrations. Example:</p>
|
||||||
<p>Set this field to a comma-separated list of channel identifiers to assign
|
<p><pre>{"channels": ""}</pre></p>
|
||||||
specific notification channels.</p>
|
<p>To assign specific integrations, use a comma-separated list of integration
|
||||||
|
UUIDs. You can look up integration UUIDs using the
|
||||||
|
<a href="#list-channels">Get a List of Existing Integrations</a> API call.</p>
|
||||||
<p>Example:</p>
|
<p>Example:</p>
|
||||||
<p><pre>{"channels": "4ec5a071-2d08-4baa-898a-eb4eb3cd6941,746a083e-f542-4554-be1a-707ce16d3acc"}</pre></p>
|
<p><pre>{"channels":
|
||||||
|
"4ec5a071-2d08-4baa-898a-eb4eb3cd6941,746a083e-f542-4554-be1a-707ce16d3acc"}</pre></p>
|
||||||
|
<p>Alternatively, if you have named your integrations in SITE_NAME dashboard,
|
||||||
|
you can specify integrations by their names. For this to work, your integrations
|
||||||
|
need non-empty and unique names, and they must not contain commas. The names
|
||||||
|
must match exactly, whitespace is significant.</p>
|
||||||
|
<p>Example:</p>
|
||||||
|
<p><pre>{"channels": "Email to Alice,SMS to Alice"}</pre></p>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<h3>Response Codes</h3>
|
<h3>Response Codes</h3>
|
||||||
|
@ -360,11 +360,27 @@ channels
|
|||||||
check.
|
check.
|
||||||
|
|
||||||
Set this field to a special value "*" to automatically assign all existing
|
Set this field to a special value "*" to automatically assign all existing
|
||||||
integrations.
|
integrations. Example:
|
||||||
|
|
||||||
|
<pre>{"channels": "*"}</pre>
|
||||||
|
|
||||||
To assign specific integrations, use a comma-separated list of integration
|
To assign specific integrations, use a comma-separated list of integration
|
||||||
identifiers. Use the [Get a List of Existing Integrations](#list-channels)
|
UUIDs. You can look up integration UUIDs using the
|
||||||
API call to look up the available integration identifiers.
|
[Get a List of Existing Integrations](#list-channels) API call.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
<pre>{"channels":
|
||||||
|
"4ec5a071-2d08-4baa-898a-eb4eb3cd6941,746a083e-f542-4554-be1a-707ce16d3acc"}</pre>
|
||||||
|
|
||||||
|
Alternatively, if you have named your integrations in SITE_NAME dashboard,
|
||||||
|
you can specify integrations by their names. For this to work, your integrations
|
||||||
|
need non-empty and unique names, and they must not contain commas. The names
|
||||||
|
must match exactly, whitespace is significant.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
<pre>{"channels": "Email to Alice,SMS to Alice"}</pre>
|
||||||
|
|
||||||
unique
|
unique
|
||||||
: array of string values, optional, default value: [].
|
: array of string values, optional, default value: [].
|
||||||
@ -540,17 +556,32 @@ channels
|
|||||||
: string, optional.
|
: string, optional.
|
||||||
|
|
||||||
Set this field to a special value "*" to automatically assign all existing
|
Set this field to a special value "*" to automatically assign all existing
|
||||||
notification channels.
|
integrations. Example:
|
||||||
|
|
||||||
|
<pre>{"channels": "*"}</pre>
|
||||||
|
|
||||||
Set this field to a special value "" (empty string) to automatically *unassign*
|
Set this field to a special value "" (empty string) to automatically *unassign*
|
||||||
all notification channels.
|
all existing integrations. Example:
|
||||||
|
|
||||||
Set this field to a comma-separated list of channel identifiers to assign
|
<pre>{"channels": ""}</pre>
|
||||||
specific notification channels.
|
|
||||||
|
To assign specific integrations, use a comma-separated list of integration
|
||||||
|
UUIDs. You can look up integration UUIDs using the
|
||||||
|
[Get a List of Existing Integrations](#list-channels) API call.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
<pre>{"channels": "4ec5a071-2d08-4baa-898a-eb4eb3cd6941,746a083e-f542-4554-be1a-707ce16d3acc"}</pre>
|
<pre>{"channels":
|
||||||
|
"4ec5a071-2d08-4baa-898a-eb4eb3cd6941,746a083e-f542-4554-be1a-707ce16d3acc"}</pre>
|
||||||
|
|
||||||
|
Alternatively, if you have named your integrations in SITE_NAME dashboard,
|
||||||
|
you can specify integrations by their names. For this to work, your integrations
|
||||||
|
need non-empty and unique names, and they must not contain commas. The names
|
||||||
|
must match exactly, whitespace is significant.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
<pre>{"channels": "Email to Alice,SMS to Alice"}</pre>
|
||||||
|
|
||||||
|
|
||||||
### Response Codes
|
### Response Codes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user