Browse Source

Retire HipChat.

pull/226/head
Pēteris Caune 6 years ago
parent
commit
f8c0c20d34
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
17 changed files with 14 additions and 336 deletions
  1. +0
    -33
      hc/api/models.py
  2. +0
    -24
      hc/api/tests/test_channel_model.py
  3. +2
    -7
      hc/api/tests/test_notify.py
  4. +2
    -5
      hc/api/transports.py
  5. +0
    -37
      hc/front/tests/test_add_hipchat.py
  6. +0
    -2
      hc/front/urls.py
  7. +1
    -37
      hc/front/views.py
  8. +6
    -0
      static/css/channels.css
  9. BIN
      static/img/integrations/setup_hipchat_1.png
  10. BIN
      static/img/integrations/setup_hipchat_2.png
  11. BIN
      static/img/integrations/setup_hipchat_3.png
  12. BIN
      static/img/integrations/setup_hipchat_4.png
  13. +3
    -10
      templates/front/channels.html
  14. +0
    -7
      templates/front/welcome.html
  15. +0
    -96
      templates/integrations/add_hipchat.html
  16. +0
    -23
      templates/integrations/hipchat_capabilities.json
  17. +0
    -55
      templates/integrations/hipchat_message.json

+ 0
- 33
hc/api/models.py View File

@ -2,7 +2,6 @@
import hashlib import hashlib
import json import json
import time
import uuid import uuid
from datetime import datetime, timedelta as td from datetime import datetime, timedelta as td
@ -14,7 +13,6 @@ from django.utils import timezone
from hc.accounts.models import Project from hc.accounts.models import Project
from hc.api import transports from hc.api import transports
from hc.lib import emails from hc.lib import emails
import requests
import pytz import pytz
STATUSES = ( STATUSES = (
@ -470,37 +468,6 @@ class Channel(models.Model):
doc = json.loads(self.value) doc = json.loads(self.value)
return doc.get("name") return doc.get("name")
def refresh_hipchat_access_token(self):
assert self.kind == "hipchat"
if not self.value.startswith("{"):
return # Don't have OAuth credentials
doc = json.loads(self.value)
if time.time() < doc.get("expires_at", 0):
return # Current access token is still valid
url = "https://api.hipchat.com/v2/oauth/token"
auth = (doc["oauthId"], doc["oauthSecret"])
r = requests.post(url, auth=auth, data={
"grant_type": "client_credentials",
"scope": "send_notification"
})
doc.update(r.json())
doc["expires_at"] = int(time.time()) + doc["expires_in"] - 300
self.value = json.dumps(doc)
self.save()
@property
def hipchat_webhook_url(self):
assert self.kind == "hipchat"
if not self.value.startswith("{"):
return self.value
doc = json.loads(self.value)
tmpl = "https://api.hipchat.com/v2/room/%s/notification?auth_token=%s"
return tmpl % (doc["roomId"], doc.get("access_token"))
@property @property
def pd_service_key(self): def pd_service_key(self):
assert self.kind == "pd" assert self.kind == "pd"


+ 0
- 24
hc/api/tests/test_channel_model.py View File

@ -1,24 +0,0 @@
import json
from hc.api.models import Channel
from hc.test import BaseTestCase
from mock import patch
class ChannelModelTestCase(BaseTestCase):
@patch("hc.api.models.requests.post")
def test_it_refreshes_hipchat_access_token(self, mock_post):
mock_post.return_value.json.return_value = {"expires_in": 100}
value = json.dumps({
"oauthId": "foo",
"oauthSecret": "bar"
})
channel = Channel(kind="hipchat", project=self.project, value=value)
channel.refresh_hipchat_access_token()
# It should request a token using a correct tokenUrl
mock_post.assert_called()
self.assertTrue("expires_at" in channel.value)

+ 2
- 7
hc/api/tests/test_notify.py View File

@ -354,15 +354,10 @@ class NotifyTestCase(BaseTestCase):
@patch("hc.api.transports.requests.request") @patch("hc.api.transports.requests.request")
def test_hipchat(self, mock_post): def test_hipchat(self, mock_post):
self._setup_data("hipchat", "123") self._setup_data("hipchat", "123")
mock_post.return_value.status_code = 204
self.channel.notify(self.check) self.channel.notify(self.check)
n = Notification.objects.first()
self.assertEqual(n.error, "")
args, kwargs = mock_post.call_args
payload = kwargs["json"]
self.assertIn("DOWN", payload["message"])
self.assertFalse(mock_post.called)
self.assertEqual(Notification.objects.count(), 0)
@patch("hc.api.transports.requests.request") @patch("hc.api.transports.requests.request")
def test_opsgenie(self, mock_post): def test_opsgenie(self, mock_post):


+ 2
- 5
hc/api/transports.py View File

@ -202,11 +202,8 @@ class Slack(HttpTransport):
class HipChat(HttpTransport): class HipChat(HttpTransport):
def notify(self, check):
text = tmpl("hipchat_message.json", check=check)
payload = json.loads(text)
self.channel.refresh_hipchat_access_token()
return self.post(self.channel.hipchat_webhook_url, json=payload)
def is_noop(self, check):
return True
class OpsGenie(HttpTransport): class OpsGenie(HttpTransport):


+ 0
- 37
hc/front/tests/test_add_hipchat.py View File

@ -1,37 +0,0 @@
from hc.api.models import Channel
from hc.test import BaseTestCase
from mock import patch
class AddHipChatTestCase(BaseTestCase):
url = "/integrations/add_hipchat/"
def test_instructions_work(self):
self.client.login(username="[email protected]", password="password")
r = self.client.get(self.url)
self.assertContains(r, "appropriate HipChat room")
def test_it_returns_capabilities(self):
r = self.client.get("/integrations/hipchat/capabilities/")
self.assertContains(r, "installedUrl")
@patch("hc.front.views.Channel.refresh_hipchat_access_token")
@patch("hc.front.views.requests.get")
def test_it_adds_channel(self, mock_get, mock_refresh):
mock_get.return_value.json.return_value = {
"oauthId": "test-id"
}
mock_get.return_value.text = "{}"
self.client.login(username="[email protected]", password="password")
s = "https://api.hipchat.com/foo"
r = self.client.post(self.url + "?installable_url=%s" % s)
self.assertEqual(r.status_code, 302)
self.assertTrue(mock_refresh.called)
c = Channel.objects.get()
self.assertEqual(c.kind, "hipchat")
self.assertEqual(c.value, "{}")
self.assertEqual(c.project, self.project)

+ 0
- 2
hc/front/urls.py View File

@ -26,8 +26,6 @@ channel_urls = [
path('add_pagertree/', views.add_pagertree, name="hc-add-pagertree"), path('add_pagertree/', views.add_pagertree, name="hc-add-pagertree"),
path('add_slack/', views.add_slack, name="hc-add-slack"), path('add_slack/', views.add_slack, name="hc-add-slack"),
path('add_slack_btn/', views.add_slack_btn, name="hc-add-slack-btn"), path('add_slack_btn/', views.add_slack_btn, name="hc-add-slack-btn"),
path('add_hipchat/', views.add_hipchat, name="hc-add-hipchat"),
path('hipchat/capabilities/', views.hipchat_capabilities, name="hc-hipchat-capabilities"),
path('add_pushbullet/', views.add_pushbullet, name="hc-add-pushbullet"), path('add_pushbullet/', views.add_pushbullet, name="hc-add-pushbullet"),
path('add_discord/', views.add_discord, name="hc-add-discord"), path('add_discord/', views.add_discord, name="hc-add-discord"),
path('add_pushover/', views.add_pushover, name="hc-add-pushover"), path('add_pushover/', views.add_pushover, name="hc-add-pushover"),


+ 1
- 37
hc/front/views.py View File

@ -1,6 +1,6 @@
from datetime import datetime, timedelta as td from datetime import datetime, timedelta as td
import json import json
from urllib.parse import urlencode, quote
from urllib.parse import urlencode
from croniter import croniter from croniter import croniter
from django.conf import settings from django.conf import settings
@ -800,42 +800,6 @@ def add_slack_btn(request):
return redirect("hc-channels") return redirect("hc-channels")
@login_required
def add_hipchat(request):
if "installable_url" in request.GET:
url = request.GET["installable_url"]
assert url.startswith("https://api.hipchat.com")
response = requests.get(url)
if "oauthId" not in response.json():
messages.warning(request, "Something went wrong!")
return redirect("hc-channels")
channel = Channel(kind="hipchat", project=request.project)
channel.user = request.project.owner
channel.value = response.text
channel.save()
channel.refresh_hipchat_access_token()
channel.assign_all_checks()
messages.success(request, "The HipChat integration has been added!")
return redirect("hc-channels")
install_url = "https://www.hipchat.com/addons/install?" + urlencode({
"url": settings.SITE_ROOT + reverse("hc-hipchat-capabilities")
})
ctx = {
"page": "channels",
"install_url": install_url
}
return render(request, "integrations/add_hipchat.html", ctx)
def hipchat_capabilities(request):
return render(request, "integrations/hipchat_capabilities.json", {},
content_type="application/json")
@login_required @login_required
def add_pushbullet(request): def add_pushbullet(request):
if settings.PUSHBULLET_CLIENT_ID is None: if settings.PUSHBULLET_CLIENT_ID is None:


+ 6
- 0
static/css/channels.css View File

@ -2,6 +2,12 @@
margin-top: 36px; margin-top: 36px;
} }
.channel-row.kind-hipchat {
filter: grayscale(100%);
opacity: 0.5;
}
.channels-table .channel-row > td { .channels-table .channel-row > td {
padding-top: 10px; padding-top: 10px;
padding-bottom: 10px; padding-bottom: 10px;


BIN
static/img/integrations/setup_hipchat_1.png View File

Before After
Width: 428  |  Height: 373  |  Size: 26 KiB

BIN
static/img/integrations/setup_hipchat_2.png View File

Before After
Width: 507  |  Height: 292  |  Size: 20 KiB

BIN
static/img/integrations/setup_hipchat_3.png View File

Before After
Width: 500  |  Height: 292  |  Size: 32 KiB

BIN
static/img/integrations/setup_hipchat_4.png View File

Before After
Width: 983  |  Height: 408  |  Size: 33 KiB

+ 3
- 10
templates/front/channels.html View File

@ -27,7 +27,7 @@
</tr> </tr>
{% for ch in channels %} {% for ch in channels %}
{% with n=ch.latest_notification %} {% with n=ch.latest_notification %}
<tr class="channel-row">
<tr class="channel-row kind-{{ ch.kind }}">
<td class="icon-cell"> <td class="icon-cell">
<img src="{% static ch.icon_path %}" <img src="{% static ch.icon_path %}"
class="icon" class="icon"
@ -101,6 +101,8 @@
{% else %} {% else %}
<span class="label label-default">Unconfirmed</span> <span class="label label-default">Unconfirmed</span>
{% endif %} {% endif %}
{% elif ch.kind == "hipchat" %}
Retired
{% else %} {% else %}
Ready to deliver Ready to deliver
{% endif %} {% endif %}
@ -232,15 +234,6 @@
<a href="{% url 'hc-add-pagertree' %}" class="btn btn-primary">Add Integration</a> <a href="{% url 'hc-add-pagertree' %}" class="btn btn-primary">Add Integration</a>
</li> </li>
<li>
<img src="{% static 'img/integrations/hipchat.png' %}"
class="icon" alt="HipChat icon" />
<h2>HipChat</h2>
<p>Group and private chat, file sharing, and integrations.</p>
<a href="{% url 'hc-add-hipchat' %}" class="btn btn-primary">Add Integration</a>
</li>
<li> <li>
<img src="{% static 'img/integrations/victorops.png' %}" <img src="{% static 'img/integrations/victorops.png' %}"
class="icon" alt="VictorOps icon" /> class="icon" alt="VictorOps icon" />


+ 0
- 7
templates/front/welcome.html View File

@ -369,13 +369,6 @@
</div> </div>
{% endif %} {% endif %}
<div class="col-md-2 col-sm-4 col-xs-6">
<div class="integration">
<img src="{% static 'img/integrations/hipchat.png' %}" class="icon" alt="HipChat icon" />
<h3>HipChat<br><small>Chat</small></h3>
</div>
</div>
<div class="col-md-2 col-sm-4 col-xs-6"> <div class="col-md-2 col-sm-4 col-xs-6">
<div class="integration"> <div class="integration">
<img src="{% static 'img/integrations/victorops.png' %}" class="icon" alt="VictorOps icon" /> <img src="{% static 'img/integrations/victorops.png' %}" class="icon" alt="VictorOps icon" />


+ 0
- 96
templates/integrations/add_hipchat.html View File

@ -1,96 +0,0 @@
{% extends "base.html" %}
{% load humanize static hc_extras %}
{% block title %}Notification Channels - {% site_name %}{% endblock %}
{% block content %}
<div class="row">
<div class="col-sm-12">
<h1>HipChat</h1>
<div class="jumbotron">
<p>If your team uses <a href="https://www.hipchat.com/">HipChat</a>,
you can set up {% site_name %} to post status updates directly to an
appropriate HipChat room.</p>
<div class="text-center">
{% csrf_token %}
<a href="{{ install_url }}" class="btn btn-lg btn-default">
<img class="ai-icon" src="{% static 'img/integrations/hipchat.png' %}" alt="HipChat" />
Connect HipChat
</a>
</div>
</div>
<h2>Setup Guide</h2>
<div class="row ai-step">
<div class="col-sm-6">
<span class="step-no">1</span>
<p>
After
clicking on "Connect HipChat", you will be
asked to log into HipChat.
</p>
</div>
<div class="col-sm-6">
<img
class="ai-guide-screenshot"
alt="Screenshot"
src="{% static 'img/integrations/setup_hipchat_1.png' %}">
</div>
</div>
<div class="row ai-step">
<div class="col-sm-6">
<span class="step-no">2</span>
<p>
Next, HipChat will let you select the chat room
for receiving {% site_name %} notifications.
</p>
</div>
<div class="col-sm-6">
<img
class="ai-guide-screenshot"
alt="Screenshot"
src="{% static 'img/integrations/setup_hipchat_2.png' %}">
</div>
</div>
<div class="row ai-step">
<div class="col-sm-6">
<span class="step-no">3</span>
<p>
Next, HipChat will show you the permissions
requested by {% site_name %}. There's only one permission
needed: "Send Notification".
</p>
</div>
<div class="col-sm-6">
<img
class="ai-guide-screenshot"
alt="Screenshot"
src="{% static 'img/integrations/setup_hipchat_3.png' %}">
</div>
</div>
<div class="row ai-step">
<div class="col-sm-6">
<span class="step-no">4</span>
<p>
That is all! You will now be redirected back to
"Integrations" page on {% site_name %} and see
the new integration!
</p>
</div>
<div class="col-sm-6">
<img
class="ai-guide-screenshot"
alt="Screenshot"
src="{% static 'img/integrations/setup_hipchat_4.png' %}">
</div>
</div>
</div>
</div>
{% endblock %}

+ 0
- 23
templates/integrations/hipchat_capabilities.json View File

@ -1,23 +0,0 @@
{% load hc_extras static %}
{
"name": "{% site_name %}",
"description": "Get Notified When Your Cron Jobs Fail",
"key": "io.healthchecks.hipchat",
"links": {
"homepage": "{% site_root %}",
"self": "{% site_root %}{% url 'hc-hipchat-capabilities' %}"
},
"capabilities": {
"installable": {
"allowGlobal": false,
"allowRoom": true,
"installedUrl": "{% site_root %}{% url 'hc-add-hipchat'%}"
},
"hipchatApiConsumer": {
"avatar": "{% site_root %}{% static 'img/logo-512-green.png' %}",
"scopes": [
"send_notification"
]
}
}
}

+ 0
- 55
templates/integrations/hipchat_message.json View File

@ -1,55 +0,0 @@
{% load hc_extras humanize static %}
{
"message": "“{{ check.name_then_code|escapejs }}” is {{ check.status|upper }}.",
{% if check.status == "up" %}
"color": "green",
{% else %}
"color": "red",
{% endif %}
"card": {
"style": "application",
"url": "{% site_root %}{% url 'hc-log' check.code %}",
"format": "medium",
"id": "{{ check.code }}",
"title": "{{ check.name_then_code|escapejs }}",
"icon": {
{% if check.status == "up" %}
"url": "{% site_root %}{% static 'img/up.png' %}"
{% else %}
"url": "{% site_root %}{% static 'img/down.png' %}"
{% endif %}
},
"attributes": [
{% if check.kind == "simple" %}
{"label": "Period",
"value": {"label": "{{ check.timeout|hc_duration }}"}
},
{% elif check.kind == "cron" %}
{"label": "Schedule",
"value": {"label": "{{ check.schedule|escapejs }}"}
},
{% endif %}
{"label": "Last Ping",
{% if check.last_ping %}
"value": {"label": "{{ check.last_ping|naturaltime }}"}
{% else %}
"value": {"label": "Never"}
{% endif %}
},
{% if check.tags_list %}
{"label": "Tags",
"value": {"label": "{{ check.tags_list|join:", " }}"}
},
{% endif %}
{"label": "Total Pings",
"value": {"label": "{{ check.n_pings }}"}
}
],
"activity": {
"html": "“{{ check.name_then_code|escapejs }}” is {{ check.status|upper }}."
}
}
}

Loading…
Cancel
Save