Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks.git
rev: v1.4.0
rev: v2.5.0
hooks:
- id: check-added-large-files
- id: check-ast
Expand All @@ -23,16 +23,16 @@ repos:
- id: requirements-txt-fixer
- id: trailing-whitespace
- repo: https://github.com/pre-commit/mirrors-autopep8
rev: v1.5
rev: v1.5.1
hooks:
- id: autopep8
- repo: https://github.com/asottile/pyupgrade
rev: v1.26.2
rev: v2.1.1
hooks:
- id: pyupgrade
args: ['--py3-plus']
- repo: https://github.com/asottile/seed-isort-config
rev: v1.9.4
rev: v2.1.1
hooks:
- id: seed-isort-config
- repo: https://github.com/pre-commit/mirrors-isort
Expand Down
30 changes: 22 additions & 8 deletions alertaclient/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from alertaclient.models.heartbeat import Heartbeat
from alertaclient.models.history import RichHistory
from alertaclient.models.key import ApiKey
from alertaclient.models.note import Note
from alertaclient.models.permission import Permission
from alertaclient.models.user import User
from alertaclient.utils import CustomJsonEncoder, DateTime
Expand Down Expand Up @@ -97,12 +98,6 @@ def update_attributes(self, id, attributes):
}
return self.http.put('/alert/%s/attributes' % id, data)

def add_note(self, id, note):
data = {
'note': note
}
return self.http.put('/alert/%s/note' % id, data)

def delete_alert(self, id):
return self.http.delete('/alert/%s' % id)

Expand Down Expand Up @@ -149,6 +144,25 @@ def get_tags(self, query=None):
r = self.http.get('/alerts/tags', query)
return r['tags']

def alert_note(self, id, note):
data = {
'note': note
}
return self.http.put('/alert/%s/note' % id, data)

def get_alert_notes(self, id, page=1, page_size=None):
r = self.http.get('/alert/{}/notes'.format(id), page=page, page_size=page_size)
return [Note.parse(b) for b in r['notes']]

def update_alert_note(self, id, note_id, text):
data = {
'text': text,
}
self.http.put('/alert/{}/note/{}'.format(id, note_id), data)

def delete_alert_note(self, id, note_id):
return self.http.delete('/alert/{}/note/{}'.format(id, note_id))

# Blackouts
def create_blackout(self, environment, service=None, resource=None, event=None, group=None, tags=None, customer=None, start=None, duration=None, text=None):
data = {
Expand Down Expand Up @@ -313,7 +327,7 @@ def create_user(self, name, email, password, status, roles=None, attributes=None
return User.parse(r['user'])

def get_user(self):
return Permission.parse(self.http.get('/user/%s' % id)['user'])
return User.parse(self.http.get('/user/%s' % id)['user'])

def get_user_groups(self, id):
r = self.http.get('/user/{}/groups'.format(id))
Expand Down Expand Up @@ -414,7 +428,7 @@ def get_users_groups(self, query=None):
r = self.http.get('/groups', query)
return [Group.parse(g) for g in r['groups']]

def update_group(self, id, kwargs):
def update_group(self, id, **kwargs):
data = {
'name': kwargs.get('name'),
'text': kwargs.get('text')
Expand Down
35 changes: 20 additions & 15 deletions alertaclient/commands/cmd_note.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,30 @@
from alertaclient.utils import build_query


@click.command('note', short_help='Add note to alerts')
@click.option('--ids', '-i', metavar='UUID', multiple=True, help='List of alert IDs (can use short 8-char id)')
@click.command('note', short_help='Add note')
@click.option('--ids', '-i', metavar='UUID', multiple=True, help='List of note IDs')
@click.option('--alert-ids', '-i', metavar='UUID', multiple=True, help='List of alert IDs (can use short 8-char id)')
@click.option('--query', '-q', 'query', metavar='QUERY', help='severity:"warning" AND resource:web')
@click.option('--filter', '-f', 'filters', metavar='FILTER', multiple=True, help='KEY=VALUE eg. serverity=warning resource=web')
@click.option('--text', required=True, help='Note or message')
@click.option('--text', help='Note or message')
@click.option('--delete', '-D', metavar='ID', nargs=2, help='Delete note parent ID and note ID')
@click.pass_obj
def cli(obj, ids, query, filters, text):
"""Add note to alerts."""
def cli(obj, ids, alert_ids, query, filters, text, delete):
"""Add or delete note to alerts."""
client = obj['client']
if ids:
total = len(ids)
if delete:
client.delete_alert_note(*delete)
else:
if query:
query = [('q', query)]
if alert_ids:
total = len(alert_ids)
else:
query = build_query(filters)
total, _, _ = client.get_count(query)
ids = [a.id for a in client.get_alerts(query)]
if query:
query = [('q', query)]
else:
query = build_query(filters)
total, _, _ = client.get_count(query)
alert_ids = [a.id for a in client.get_alerts(query)]

with click.progressbar(ids, label='Add note to {} alerts'.format(total)) as bar:
for id in bar:
client.add_note(id, note=text)
with click.progressbar(alert_ids, label='Add note to {} alerts'.format(total)) as bar:
for id in bar:
client.alert_note(id, note=text)
25 changes: 25 additions & 0 deletions alertaclient/commands/cmd_notes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import json

import click
from tabulate import tabulate


@click.command('notes', short_help='List notes')
@click.option('--alert-id', '-i', metavar='UUID', help='alert IDs (can use short 8-char id)')
@click.pass_obj
def cli(obj, alert_id):
"""List notes."""
client = obj['client']
if alert_id:
if obj['output'] == 'json':
r = client.http.get('/alert/{}/notes'.format(alert_id))
click.echo(json.dumps(r['notes'], sort_keys=True, indent=4, ensure_ascii=False))
else:
timezone = obj['timezone']
headers = {
'id': 'NOTE ID', 'text': 'NOTE', 'user': 'USER', 'type': 'TYPE', 'attributes': 'ATTRIBUTES',
'createTime': 'CREATED', 'updateTime': 'UPDATED', 'related': 'RELATED ID', 'customer': 'CUSTOMER'
}
click.echo(tabulate([n.tabular(timezone) for n in client.get_alert_notes(alert_id)], headers=headers, tablefmt=obj['output']))
else:
raise click.UsageError('Need "--alert-id" to list notes.')
51 changes: 51 additions & 0 deletions alertaclient/models/note.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from datetime import datetime

from alertaclient.utils import DateTime


class Note:

def __init__(self, text, user, note_type, **kwargs):

self.id = kwargs.get('id', None)
self.text = text
self.user = user
self.note_type = note_type
self.attributes = kwargs.get('attributes', None) or dict()
self.create_time = kwargs['create_time'] if 'create_time' in kwargs else datetime.utcnow()
self.update_time = kwargs.get('update_time')
self.alert = kwargs.get('alert')
self.customer = kwargs.get('customer')

@classmethod
def parse(cls, json):
return Note(
id=json.get('id', None),
text=json.get('text', None),
user=json.get('user', None),
attributes=json.get('attributes', dict()),
note_type=json.get('type', None),
create_time=DateTime.parse(json['createTime']) if 'createTime' in json else None,
update_time=DateTime.parse(json['updateTime']) if 'updateTime' in json else None,
alert=json.get('related', {}).get('alert'),
customer=json.get('customer', None)
)

def __repr__(self):
return 'Note(id={!r}, text={!r}, user={!r}, type={!r}, customer={!r})'.format(
self.id, self.text, self.user, self.note_type, self.customer
)

def tabular(self, timezone=None):
note = {
'id': self.id,
'text': self.text,
'user': self.user,
# 'attributes': self.attributes,
'type': self.note_type,
'createTime': DateTime.localtime(self.create_time, timezone),
'updateTime': DateTime.localtime(self.update_time, timezone),
'related': self.alert,
'customer': self.customer
}
return note
6 changes: 3 additions & 3 deletions tests/test_notes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ class NotesTestCase(unittest.TestCase):
def setUp(self):
self.client = Client()

self.key = """
self.note = """
{
"status": "ok"
}
"""

@requests_mock.mock()
def test_add_note(self, m):
m.put('http://localhost:8080/alert/e7020428-5dad-4a41-9bfe-78e9d55cda06/note', text=self.key)
r = self.client.add_note(id='e7020428-5dad-4a41-9bfe-78e9d55cda06', note='this is a test note')
m.put('http://localhost:8080/alert/e7020428-5dad-4a41-9bfe-78e9d55cda06/note', text=self.note)
r = self.client.alert_note(id='e7020428-5dad-4a41-9bfe-78e9d55cda06', note='this is a test note')
self.assertEqual(r['status'], 'ok')