Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Commit

Permalink
Merge pull request #117 from librato/feature/service_attributes
Browse files Browse the repository at this point in the history
Add all attributes to Service model
  • Loading branch information
jderrett committed Jun 6, 2016
2 parents 1c1bf77 + 26be5aa commit 0321e34
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 13 deletions.
13 changes: 9 additions & 4 deletions librato/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
from librato.queue import Queue
from librato.metrics import Gauge, Counter
from librato.instruments import Instrument
from librato.alerts import Alert
from librato.alerts import Alert, Service
from librato.dashboards import Dashboard
from librato.annotations import Annotation
from librato.spaces import Space, Chart
Expand Down Expand Up @@ -398,15 +398,16 @@ def delete_alert(self, name):
resp = self._mexe("alerts/%s" % alert._id, method="DELETE")
return resp

def get_alert(self, name ,**query_props):
def get_alert(self, name, **query_props):
"""Get specific alert"""
resp = self._mexe("alerts", query_props={'version':2,'name':name})
resp = self._mexe("alerts", query_props={'version': 2, 'name': name})
alerts = self._parse(resp, "alerts", Alert)
if len(alerts) > 0:
return alerts[0]
return None

# List alerts (defaults to v2 only)
# TODO: support for pagination
def list_alerts(self, active_only=True, **query_props):
"""List all alerts (default to active only)"""
# Only v2 is supported
Expand All @@ -416,10 +417,14 @@ def list_alerts(self, active_only=True, **query_props):
resp = self._mexe("alerts", query_props=query_props)
alerts = self._parse(resp, "alerts", Alert)
if active_only:
return list(filter(lambda a: a.active, alerts))
return [a for a in alerts if a.active]
else:
return alerts

def list_services(self, **query_props):
resp = self._mexe("services", query_props=query_props)
return self._parse(resp, "services", Service)

#
# Spaces
#
Expand Down
27 changes: 18 additions & 9 deletions librato/alerts.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
class Alert(object):
"""Librato Alert Base class"""

def __init__(self, connection, name, _id=None, description=None, version=2, conditions=[], services=[], attributes={}, active=True, rearm_seconds=None):
def __init__(self, connection, name, _id=None, description=None, version=2,
conditions=[], services=[], attributes={}, active=True, rearm_seconds=None):
self.connection = connection
self.name = name
self.description = description
Expand All @@ -10,16 +11,16 @@ def __init__(self, connection, name, _id=None, description=None, version=2, cond
for c in conditions:
if isinstance(c, Condition):
self.conditions.append(c)
elif isinstance(c, dict): # Probably parsing JSON here
elif isinstance(c, dict):
self.conditions.append(Condition.from_dict(c))
else:
self.conditions.append(Condition(*c))
self.services = []
for s in services:
if isinstance(s, Service):
self.services.append(s)
elif isinstance(s, dict): # Probably parsing JSON here
self.services.append(Service.from_dict(s))
elif isinstance(s, dict):
self.services.append(Service.from_dict(connection, s))
elif isinstance(s, int):
self.services.append(Service(s))
else:
Expand Down Expand Up @@ -140,13 +141,21 @@ def get_payload(self):
return obj

class Service(object):
def __init__(self, _id):
def __init__(self, _id, title=None, type=None, settings=None):
self._id = _id
self.title = title
self.type = type
self.settings = settings

@classmethod
def from_dict(cls, data):
obj = cls(_id=data['id'])
def from_dict(cls, connection, data):
obj = cls(data['id'], data['title'], data['type'], data['settings'])
return obj


def get_payload(self):
return {'id': self._id}
return {
'id': self._id,
'title': self.title,
'type': self.type,
'settings': self.settings
}
29 changes: 29 additions & 0 deletions tests/mock_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ def clean(self):
self.metrics = {'gauges': OrderedDict(), 'counters': OrderedDict()}
self.instruments = OrderedDict()
self.alerts = OrderedDict()
self.services = OrderedDict()
self.dashboards = OrderedDict()
self.spaces = OrderedDict()
self.last_i_id = 0
self.last_a_id = 0
self.last_service_id = 0
self.last_db_id = 0
self.last_spc_id = 0
self.last_chrt_id = 0
Expand Down Expand Up @@ -106,6 +108,12 @@ def create_alert(self, payload):
self.alerts[self.last_a_id] = payload
return json.dumps(payload).encode('utf-8')

def create_service(self, payload):
self.last_service_id += 1
payload["id"] = self.last_service_id
self.services[self.last_service_id] = payload
return json.dumps(payload).encode('utf-8')

def get_alert(self, name, payload):
return self.list_of_alerts(name)

Expand All @@ -126,6 +134,21 @@ def list_of_alerts(self, name=None):
alert.append(c_alert)
return json.dumps(answer).encode('utf-8')

def list_of_services(self):
#{
# 'services': [
# {'id': 1, 'title': 'A Service', 'type': 'mail',
# 'settings': {'addresses': '[email protected]'}}
# ]
#}
answer = {}
answer['query'] = {}
answer['services'] = []
for _id, c_service in self.services.items():
c_service['id'] = _id
answer['services'].append(c_service)
return json.dumps(answer).encode('utf-8')

def list_of_dashboards(self):
answer = {}
answer["query"] = {}
Expand Down Expand Up @@ -458,6 +481,8 @@ def _json_body_based_on_request(self):
return server.get_instrument(r.uri)
elif self._req_is_list_of_alerts():
return server.list_of_alerts()
elif self._req_is_list_of_services():
return server.list_of_services()
elif self._req_is_get_alert():
return server.get_alert(self._extract_name_from_url_parameters(), r.body)
elif self._req_is_create_alert():
Expand Down Expand Up @@ -552,6 +577,10 @@ def _req_is_delete_alert(self):
return (self._method_is('DELETE') and
re.match('/v1/alerts/\d+', self.request.uri))

# Services
def _req_is_list_of_services(self):
return self._method_is('GET') and self._path_is('/v1/services')

# dashboards
def _req_is_create_dashboard(self):
return self._method_is('POST') and self._path_is('/v1/dashboards')
Expand Down
43 changes: 43 additions & 0 deletions tests/test_alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,49 @@ def test_immediate_condition(self):
cond._duration = 60
assert cond.immediate() == False

class TestService(unittest.TestCase):
def setUp(self):
self.conn = librato.connect('user_test', 'key_test')
self.sample_payload = {
'title': 'Email Ops',
'type': 'mail',
'settings': {'addresses': '[email protected]'}
}
server.clean()

def test_list_services(self):
services = self.conn.list_services()
self.assertEqual(len(services), 0)
# Hack this into the server until we have a :create_service
# method on the actual connection
server.create_service(self.sample_payload)
# id is 1
self.assertEqual(server.services[1], self.sample_payload)
services = self.conn.list_services()
self.assertEqual(len(services), 1)
s = services[0]
self.assertIsInstance(s, librato.alerts.Service)
self.assertEqual(s.title, self.sample_payload['title'])
self.assertEqual(s.type, self.sample_payload['type'])
self.assertEqual(s.settings, self.sample_payload['settings'])

def test_init_service(self):
s = librato.alerts.Service(123, title='the title', type='mail',
settings={'addresses': '[email protected]'})
self.assertEqual(s._id, 123)
self.assertEqual(s.title, 'the title')
self.assertEqual(s.type, 'mail')
self.assertEqual(s.settings['addresses'], '[email protected]')

def test_service_from_dict(self):
payload = {'id': 123, 'title': 'the title', 'type': 'slack',
'settings': {'room': 'a room'}}
s = librato.alerts.Service.from_dict(self.conn, payload)
self.assertEqual(s._id, 123)
self.assertEqual(s.title, payload['title'])
self.assertEqual(s.type, payload['type'])
self.assertEqual(s.settings['room'], payload['settings']['room'])


if __name__ == '__main__':
unittest.main()

0 comments on commit 0321e34

Please sign in to comment.