mirror of
https://github.com/healthchecks/healthchecks.git
synced 2025-04-12 16:18:06 +00:00
Add "Get a List of Existing Integrations" API call
This commit is contained in:
parent
21de50d84e
commit
a7061fe6a5
11 changed files with 147 additions and 10 deletions
|
@ -1,7 +1,7 @@
|
|||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## Unreleased
|
||||
## 1.3.0 - 2018-11-21
|
||||
|
||||
### Improvements
|
||||
- Load settings from environment variables
|
||||
|
@ -13,8 +13,9 @@ All notable changes to this project will be documented in this file.
|
|||
- Show a warning when running with DEBUG=True
|
||||
- Add "channels" attribute to the Check API resource
|
||||
- Can specify channel codes when updating a check via API
|
||||
- Added a workaround for email agents automatically opening "Unsubscribe" links
|
||||
- Add a workaround for email agents automatically opening "Unsubscribe" links
|
||||
- Add Channel.name field, users can now name integrations
|
||||
- Add "Get a List of Existing Integrations" API call
|
||||
|
||||
### Bug Fixes
|
||||
- During DST transition, handle ambiguous dates as pre-transition
|
||||
|
|
|
@ -254,6 +254,13 @@ class Channel(models.Model):
|
|||
|
||||
return self.get_kind_display()
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": str(self.code),
|
||||
"name": self.name,
|
||||
"kind": self.kind
|
||||
}
|
||||
|
||||
def assign_all_checks(self):
|
||||
checks = Check.objects.filter(user=self.user)
|
||||
self.checks.add(*checks)
|
||||
|
|
54
hc/api/tests/test_list_channels.py
Normal file
54
hc/api/tests/test_list_channels.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
import json
|
||||
|
||||
from hc.api.models import Channel
|
||||
from hc.test import BaseTestCase
|
||||
|
||||
|
||||
class ListChannelsTestCase(BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ListChannelsTestCase, self).setUp()
|
||||
|
||||
self.c1 = Channel(user=self.alice)
|
||||
self.c1.kind = "email"
|
||||
self.c1.name = "Email to Alice"
|
||||
self.c1.save()
|
||||
|
||||
def get(self):
|
||||
return self.client.get("/api/v1/channels/", HTTP_X_API_KEY="X" * 32)
|
||||
|
||||
def test_it_works(self):
|
||||
r = self.get()
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
doc = r.json()
|
||||
self.assertEqual(len(doc["channels"]), 1)
|
||||
|
||||
c = doc["channels"][0]
|
||||
self.assertEqual(c["id"], str(self.c1.code))
|
||||
self.assertEqual(c["kind"], "email")
|
||||
self.assertEqual(c["name"], "Email to Alice")
|
||||
|
||||
def test_it_shows_only_users_channels(self):
|
||||
Channel.objects.create(user=self.bob, kind="email", name="Bob")
|
||||
|
||||
r = self.get()
|
||||
data = r.json()
|
||||
self.assertEqual(len(data["channels"]), 1)
|
||||
for c in data["channels"]:
|
||||
self.assertNotEqual(c["name"], "Bob")
|
||||
|
||||
def test_it_accepts_api_key_from_request_body(self):
|
||||
payload = json.dumps({"api_key": "X" * 32})
|
||||
r = self.client.generic("GET", "/api/v1/channels/", payload,
|
||||
content_type="application/json")
|
||||
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertContains(r, "Email to Alice")
|
||||
|
||||
def test_readonly_key_works(self):
|
||||
self.profile.api_key_readonly = "R" * 32
|
||||
self.profile.save()
|
||||
|
||||
r = self.client.get("/api/v1/channels/", HTTP_X_API_KEY="R" * 32)
|
||||
self.assertEqual(r.status_code, 200)
|
|
@ -14,6 +14,9 @@ urlpatterns = [
|
|||
path('api/v1/notifications/<uuid:code>/bounce', views.bounce,
|
||||
name="hc-api-bounce"),
|
||||
|
||||
path('api/v1/channels/', views.channels),
|
||||
|
||||
|
||||
path('badge/<slug:username>/<slug:signature>/<slug:tag>.svg', views.badge,
|
||||
name="hc-badge"),
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ from django.shortcuts import get_object_or_404
|
|||
from django.utils import timezone
|
||||
from django.views.decorators.cache import never_cache
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.decorators.http import require_POST
|
||||
from django.views.decorators.http import require_GET, require_POST
|
||||
|
||||
from hc.api import schemas
|
||||
from hc.api.decorators import authorize, authorize_read, validate_json
|
||||
|
@ -150,6 +150,15 @@ def checks(request):
|
|||
return HttpResponse(status=405)
|
||||
|
||||
|
||||
@require_GET
|
||||
@validate_json()
|
||||
@authorize_read
|
||||
def channels(request):
|
||||
q = Channel.objects.filter(user=request.user)
|
||||
channels = [ch.to_dict() for ch in q]
|
||||
return JsonResponse({"channels": channels})
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@validate_json(schemas.check)
|
||||
@authorize
|
||||
|
|
|
@ -44,6 +44,8 @@ class Command(BaseCommand):
|
|||
# API examples
|
||||
_process("list_checks_request", lexers.BashLexer())
|
||||
_process("list_checks_response", lexers.JsonLexer())
|
||||
_process("list_channels_request", lexers.BashLexer())
|
||||
_process("list_channels_response", lexers.JsonLexer())
|
||||
_process("create_check_request_a", lexers.BashLexer())
|
||||
_process("create_check_request_b", lexers.BashLexer())
|
||||
_process("update_check_request_a", lexers.BashLexer())
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<h2>API Endpoints</h2>
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<td><a href="#list-checks">Get list of existing checks</a></td>
|
||||
<td><a href="#list-checks">Get a list of existing checks</a></td>
|
||||
<td>
|
||||
<code>GET {{ SITE_ROOT }}/api/v1/checks/</code>
|
||||
</td>
|
||||
|
@ -46,6 +46,12 @@
|
|||
<code>DELETE {{ SITE_ROOT }}/api/v1/checks/<code></code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="#list-channels">Get a list of existing integrations</a></td>
|
||||
<td>
|
||||
<code>GET {{ SITE_ROOT }}/api/v1/channels/</code>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Authentication</h2>
|
||||
|
@ -90,7 +96,7 @@ The response may contain a JSON document with additional data.
|
|||
<!-- ********************************************************************** /-->
|
||||
|
||||
<a class="section" name="list-checks">
|
||||
<h2 class="rule">Get List of Existing Checks</h2>
|
||||
<h2 class="rule">Get a List of Existing Checks</h2>
|
||||
</a>
|
||||
|
||||
<div class="api-path">GET {{ SITE_ROOT }}/api/v1/checks/</div>
|
||||
|
@ -205,12 +211,18 @@ To create a "cron" check, specify the "schedule" and "tz" parameters.
|
|||
<td>
|
||||
<p>string, optional</p>
|
||||
<p>By default, if a check is created through API, no notification
|
||||
channels are assigned to it. So, when the check goes up or down,
|
||||
no notifications will get sent.</p>
|
||||
channels (integrations) are assigned to it.
|
||||
So, when the check goes up or down, no notifications will get
|
||||
sent.</p>
|
||||
|
||||
<p>Set this field to a special value "*"
|
||||
to automatically assign all existing notification channels.</p>
|
||||
<p>To assign specific notification channels, use a comma-separated
|
||||
list of channel identifiers.</p>
|
||||
to automatically assign all existing integrations.</p>
|
||||
|
||||
<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>
|
||||
call to look up integration identifiers.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -426,6 +438,23 @@ is sometimes required by some network proxies and web servers.
|
|||
<h3 class="api-section">Example Response</h3>
|
||||
{% include "front/snippets/create_check_response.html" %}
|
||||
|
||||
<!-- ********************************************************************** /-->
|
||||
|
||||
<a class="section" name="list-channels">
|
||||
<h2 class="rule">Get a List of Existing Integrations</h2>
|
||||
</a>
|
||||
|
||||
<div class="api-path">GET {{ SITE_ROOT }}/api/v1/channels/</div>
|
||||
|
||||
<p>Returns a list of integrations belonging to the user.</p>
|
||||
|
||||
<h3 class="api-section">Example Request</h3>
|
||||
{% include "front/snippets/list_channels_request.html" %}
|
||||
|
||||
<h3 class="api-section">Example Response</h3>
|
||||
{% include "front/snippets/list_channels_response.html" %}
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
|
|
2
templates/front/snippets/list_channels_request.html
Normal file
2
templates/front/snippets/list_channels_request.html
Normal file
|
@ -0,0 +1,2 @@
|
|||
<div class="highlight"><pre><span></span>curl --header <span class="s2">"X-Api-Key: your-api-key"</span> {{ SITE_ROOT }}/api/v1/channels/
|
||||
</pre></div>
|
1
templates/front/snippets/list_channels_request.txt
Normal file
1
templates/front/snippets/list_channels_request.txt
Normal file
|
@ -0,0 +1 @@
|
|||
curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/channels/
|
15
templates/front/snippets/list_channels_response.html
Normal file
15
templates/front/snippets/list_channels_response.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<div class="highlight"><pre><span></span><span class="p">{</span>
|
||||
<span class="nt">"channels"</span><span class="p">:</span> <span class="p">[</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="s2">"4ec5a071-2d08-4baa-898a-eb4eb3cd6941"</span><span class="p">,</span>
|
||||
<span class="nt">"name"</span><span class="p">:</span> <span class="s2">"My Work Email"</span><span class="p">,</span>
|
||||
<span class="nt">"kind"</span><span class="p">:</span> <span class="s2">"email"</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nt">"id"</span><span class="p">:</span> <span class="s2">"746a083e-f542-4554-be1a-707ce16d3acc"</span><span class="p">,</span>
|
||||
<span class="nt">"name"</span><span class="p">:</span> <span class="s2">"My Phone"</span><span class="p">,</span>
|
||||
<span class="nt">"kind"</span><span class="p">:</span> <span class="s2">"sms"</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">]</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
14
templates/front/snippets/list_channels_response.txt
Normal file
14
templates/front/snippets/list_channels_response.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"channels": [
|
||||
{
|
||||
"id": "4ec5a071-2d08-4baa-898a-eb4eb3cd6941",
|
||||
"name": "My Work Email",
|
||||
"kind": "email"
|
||||
},
|
||||
{
|
||||
"id": "746a083e-f542-4554-be1a-707ce16d3acc",
|
||||
"name": "My Phone",
|
||||
"kind": "sms"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Add table
Reference in a new issue