forked from GithubBackups/healthchecks
parent
838aee6bdd
commit
22d4d55340
@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
|
||||
### Improvements
|
||||
- "Filtering Rules" dialog, an option to require HTTP POST (#297)
|
||||
- Show Healthchecks version in Django admin header (#306)
|
||||
- Added JSON endpoint for Shields.io (#304)
|
||||
|
||||
|
||||
## v1.11.0 - 2019-11-22
|
||||
|
@ -27,6 +27,10 @@ class BadgeTestCase(BaseTestCase):
|
||||
self.assertEqual(r["Access-Control-Allow-Origin"], "*")
|
||||
self.assertContains(r, "#4c1")
|
||||
|
||||
def test_it_rejects_bad_format(self):
|
||||
r = self.client.get(self.json_url + "foo")
|
||||
self.assertEqual(r.status_code, 404)
|
||||
|
||||
def test_it_handles_options(self):
|
||||
r = self.client.options(self.svg_url)
|
||||
self.assertEqual(r.status_code, 204)
|
||||
|
@ -27,27 +27,15 @@ urlpatterns = [
|
||||
path("api/v1/notifications/<uuid:code>/bounce", views.bounce, name="hc-api-bounce"),
|
||||
path("api/v1/channels/", views.channels),
|
||||
path(
|
||||
"badge/<slug:badge_key>/<slug:signature>/<quoted:tag>.svg",
|
||||
"badge/<slug:badge_key>/<slug:signature>/<quoted:tag>.<slug:fmt>",
|
||||
views.badge,
|
||||
name="hc-badge",
|
||||
),
|
||||
path(
|
||||
"badge/<slug:badge_key>/<slug:signature>.svg",
|
||||
"badge/<slug:badge_key>/<slug:signature>.<slug:fmt>",
|
||||
views.badge,
|
||||
{"tag": "*"},
|
||||
name="hc-badge-all",
|
||||
),
|
||||
path(
|
||||
"badge/<slug:badge_key>/<slug:signature>/<quoted:tag>.json",
|
||||
views.badge,
|
||||
{"format": "json"},
|
||||
name="hc-badge-json",
|
||||
),
|
||||
path(
|
||||
"badge/<slug:badge_key>/<slug:signature>.json",
|
||||
views.badge,
|
||||
{"format": "json", "tag": "*"},
|
||||
name="hc-badge-json-all",
|
||||
),
|
||||
path("api/v1/status/", views.status),
|
||||
]
|
||||
|
@ -203,10 +203,13 @@ def pause(request, code):
|
||||
|
||||
@never_cache
|
||||
@cors("GET")
|
||||
def badge(request, badge_key, signature, tag, format="svg"):
|
||||
def badge(request, badge_key, signature, tag, fmt="svg"):
|
||||
if not check_signature(badge_key, tag, signature):
|
||||
return HttpResponseNotFound()
|
||||
|
||||
if fmt not in ("svg", "json", "shields"):
|
||||
return HttpResponseNotFound()
|
||||
|
||||
q = Check.objects.filter(project__badge_key=badge_key)
|
||||
if tag != "*":
|
||||
q = q.filter(tags__contains=tag)
|
||||
@ -225,7 +228,7 @@ def badge(request, badge_key, signature, tag, format="svg"):
|
||||
if check_status == "down":
|
||||
down += 1
|
||||
status = "down"
|
||||
if format == "svg":
|
||||
if fmt == "svg":
|
||||
# For SVG badges, we can leave the loop as soon as we
|
||||
# find the first "down"
|
||||
break
|
||||
@ -234,7 +237,16 @@ def badge(request, badge_key, signature, tag, format="svg"):
|
||||
if status == "up":
|
||||
status = "late"
|
||||
|
||||
if format == "json":
|
||||
if fmt == "shields":
|
||||
color = "success"
|
||||
if status == "down":
|
||||
color = "critical"
|
||||
elif status == "late":
|
||||
color = "important"
|
||||
|
||||
return JsonResponse({"label": label, "message": status, "color": color})
|
||||
|
||||
if fmt == "json":
|
||||
return JsonResponse(
|
||||
{"status": status, "total": total, "grace": grace, "down": down}
|
||||
)
|
||||
|
@ -590,7 +590,8 @@ def badges(request, code):
|
||||
{
|
||||
"tag": tag,
|
||||
"svg": get_badge_url(project.badge_key, tag),
|
||||
"json": get_badge_url(project.badge_key, tag, format="json"),
|
||||
"json": get_badge_url(project.badge_key, tag, fmt="json"),
|
||||
"shields": get_badge_url(project.badge_key, tag, fmt="shields"),
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -103,14 +103,12 @@ def check_signature(username, tag, sig):
|
||||
return ours == sig
|
||||
|
||||
|
||||
def get_badge_url(username, tag, format="svg"):
|
||||
def get_badge_url(username, tag, fmt="svg"):
|
||||
sig = base64_hmac(str(username), tag, settings.SECRET_KEY)
|
||||
|
||||
if tag == "*":
|
||||
view = "hc-badge-json-all" if format == "json" else "hc-badge-all"
|
||||
url = reverse(view, args=[username, sig[:8]])
|
||||
url = reverse("hc-badge-all", args=[username, sig[:8], fmt])
|
||||
else:
|
||||
view = "hc-badge-json" if format == "json" else "hc-badge"
|
||||
url = reverse(view, args=[username, sig[:8], tag])
|
||||
url = reverse("hc-badge", args=[username, sig[:8], tag, fmt])
|
||||
|
||||
return settings.SITE_ROOT + url
|
||||
|
@ -37,10 +37,14 @@
|
||||
padding-top: 32px;
|
||||
}
|
||||
|
||||
#badges-json {
|
||||
#badges-json, #badges-shields {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#badges-shields label:first-child {
|
||||
margin: 20px 0 10px 0;
|
||||
}
|
||||
|
||||
.json-response code {
|
||||
display: inline-block;
|
||||
background: #eee;
|
||||
|
@ -7,13 +7,20 @@ $(function() {
|
||||
});
|
||||
|
||||
$("#show-svg").click(function() {
|
||||
$("#badges-json").hide();
|
||||
$("#badges-svg").show();
|
||||
$("#badges-json").hide();
|
||||
$("#badges-shields").hide();
|
||||
})
|
||||
|
||||
$("#show-json").click(function() {
|
||||
$("#badges-svg").hide();
|
||||
$("#badges-json").show();
|
||||
$("#badges-shields").hide();
|
||||
})
|
||||
|
||||
$("#show-shields").click(function() {
|
||||
$("#badges-svg").hide();
|
||||
$("#badges-json").hide();
|
||||
$("#badges-shields").show();
|
||||
})
|
||||
});
|
@ -24,6 +24,9 @@
|
||||
<label id="show-json" class="btn btn-default">
|
||||
<input type="radio" autocomplete="off"> JSON
|
||||
</label>
|
||||
<label id="show-shields" class="btn btn-default">
|
||||
<input type="radio" autocomplete="off"> Shields.io
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<table id="badges-svg" class="badges table">
|
||||
@ -44,7 +47,7 @@
|
||||
<td>
|
||||
<img src="{{ urldict.svg }}" alt="" />
|
||||
</td>
|
||||
<td class="svg-url">
|
||||
<td>
|
||||
<code>{{ urldict.svg }}</code>
|
||||
</td>
|
||||
</tr>
|
||||
@ -67,12 +70,40 @@
|
||||
<tr>
|
||||
<td class="json-response" data-url="{{ urldict.json }}">
|
||||
</td>
|
||||
<td class="json-url">
|
||||
<td>
|
||||
<code>{{ urldict.json }}</code>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<div id="badges-shields">
|
||||
<table class="badges table">
|
||||
{% if have_tags %}
|
||||
<tr>
|
||||
<th>Shields.io badge</th>
|
||||
<th>JSON endpoint for Shields.io <a href="https://shields.io/endpoint">(how to use)</a></th>
|
||||
</tr>
|
||||
{% endif %}
|
||||
|
||||
{% for urldict in badges %}
|
||||
{% if urldict.tag == "*" %}
|
||||
<tr>
|
||||
<th colspan="2">Overall Status</th>
|
||||
</tr>
|
||||
{% endif %}
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<img src="https://img.shields.io/endpoint?url={{ urldict.shields|urlencode:"" }}" alt="" />
|
||||
</td>
|
||||
<td>
|
||||
<code>{{ urldict.shields }}</code>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user