diff --git a/Makefile b/Makefile index 07b8395..9c71260 100644 --- a/Makefile +++ b/Makefile @@ -83,6 +83,7 @@ test.unit: $(TOX) $(PYTEST) ## test.integration - Run integration tests. test.integration: docker-compose -f docker-compose.ci.yaml rm --stop --force + docker-compose -f docker-compose.ci.yaml pull docker-compose -f docker-compose.ci.yaml build sut docker-compose -f docker-compose.ci.yaml up --exit-code-from sut docker-compose -f docker-compose.ci.yaml rm --stop --force diff --git a/alertaclient/api.py b/alertaclient/api.py index 3bd8ada..092dfbc 100644 --- a/alertaclient/api.py +++ b/alertaclient/api.py @@ -168,7 +168,8 @@ 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): + def create_blackout(self, environment, service=None, resource=None, event=None, group=None, tags=None, + origin=None, customer=None, start=None, duration=None, text=None): data = { 'environment': environment, 'service': service or list(), @@ -176,6 +177,7 @@ def create_blackout(self, environment, service=None, resource=None, event=None, 'event': event, 'group': group, 'tags': tags or list(), + 'origin': origin, 'customer': customer, 'startTime': start, 'duration': duration, @@ -200,6 +202,7 @@ def update_blackout(self, id, **kwargs): 'event': kwargs.get('event'), 'group': kwargs.get('group'), 'tags': kwargs.get('tags'), + 'origin': kwargs.get('origin'), 'startTime': kwargs.get('startTime'), 'endTime': kwargs.get('endTime'), 'text': kwargs.get('text'), diff --git a/alertaclient/commands/cmd_blackout.py b/alertaclient/commands/cmd_blackout.py index c083b71..c51ed06 100644 --- a/alertaclient/commands/cmd_blackout.py +++ b/alertaclient/commands/cmd_blackout.py @@ -10,13 +10,14 @@ @click.option('--event', '-e', metavar='EVENT', help='Event name') @click.option('--group', '-g', metavar='GROUP', help='Group event by type eg. OS, Performance') @click.option('--tag', '-T', 'tags', multiple=True, metavar='TAG', help='List of tags eg. London, os:linux, AWS/EC2') +@click.option('--origin', '-O', metavar='ORIGIN', help='Origin of alert in form app/host') @click.option('--customer', metavar='STRING', help='Customer (Admin only)') @click.option('--start', metavar='DATETIME', help='Start time in ISO8601 eg. 2018-02-01T12:00:00.000Z') @click.option('--duration', metavar='SECONDS', type=int, help='Blackout period in seconds') @click.option('--text', help='Reason for blackout') @click.option('--delete', '-D', help='Delete blackout using ID') @click.pass_obj -def cli(obj, environment, service, resource, event, group, tags, customer, start, duration, text, delete): +def cli(obj, environment, service, resource, event, group, tags, origin, customer, start, duration, text, delete): """Suppress alerts for specified duration based on alert attributes.""" client = obj['client'] if delete: @@ -32,6 +33,7 @@ def cli(obj, environment, service, resource, event, group, tags, customer, start event=event, group=group, tags=tags, + origin=origin, customer=customer, start=start, duration=duration, diff --git a/alertaclient/commands/cmd_blackouts.py b/alertaclient/commands/cmd_blackouts.py index 70c2af2..583dd33 100644 --- a/alertaclient/commands/cmd_blackouts.py +++ b/alertaclient/commands/cmd_blackouts.py @@ -18,9 +18,9 @@ def cli(obj, purge): timezone = obj['timezone'] headers = { 'id': 'ID', 'priority': 'P', 'environment': 'ENVIRONMENT', 'service': 'SERVICE', 'resource': 'RESOURCE', - 'event': 'EVENT', 'group': 'GROUP', 'tags': 'TAGS', 'customer': 'CUSTOMER', 'startTime': 'START', 'endTime': 'END', - 'duration': 'DURATION', 'user': 'USER', 'createTime': 'CREATED', 'text': 'COMMENT', - 'status': 'STATUS', 'remaining': 'REMAINING' + 'event': 'EVENT', 'group': 'GROUP', 'tags': 'TAGS', 'origin': 'ORIGIN', 'customer': 'CUSTOMER', + 'startTime': 'START', 'endTime': 'END', 'duration': 'DURATION', 'user': 'USER', + 'createTime': 'CREATED', 'text': 'COMMENT', 'status': 'STATUS', 'remaining': 'REMAINING' } blackouts = client.get_blackouts() click.echo(tabulate([b.tabular(timezone) for b in blackouts], headers=headers, tablefmt=obj['output'])) diff --git a/alertaclient/models/blackout.py b/alertaclient/models/blackout.py index d1b3716..8323dea 100644 --- a/alertaclient/models/blackout.py +++ b/alertaclient/models/blackout.py @@ -24,6 +24,7 @@ def __init__(self, environment, **kwargs): self.event = kwargs.get('event', None) self.group = kwargs.get('group', None) self.tags = kwargs.get('tags', None) or list() + self.origin = kwargs.get('origin', None) self.customer = kwargs.get('customer', None) self.start_time = start_time self.end_time = end_time @@ -47,6 +48,8 @@ def __init__(self, environment, **kwargs): self.priority = 6 elif self.tags: self.priority = 7 + if self.origin: + self.priority = 8 now = datetime.utcnow() if self.start_time <= now and self.end_time > now: @@ -71,6 +74,8 @@ def __repr__(self): more += 'group=%r, ' % self.group if self.tags: more += 'tags=%r, ' % self.tags + if self.origin: + more += 'origin=%r, ' % self.origin if self.customer: more += 'customer=%r, ' % self.customer @@ -100,6 +105,7 @@ def parse(cls, json): event=json.get('event', None), group=json.get('group', None), tags=json.get('tags', list()), + origin=json.get('origin', None), customer=json.get('customer', None), start_time=DateTime.parse(json.get('startTime')), end_time=DateTime.parse(json.get('endTime')), @@ -119,6 +125,7 @@ def tabular(self, timezone=None): 'event': self.event, 'group': self.group, 'tags': ','.join(self.tags), + 'origin': self.origin, 'customer': self.customer, 'startTime': DateTime.localtime(self.start_time, timezone), 'endTime': DateTime.localtime(self.end_time, timezone), diff --git a/docker-compose.ci.yaml b/docker-compose.ci.yaml index 077fd0f..f0ddd12 100644 --- a/docker-compose.ci.yaml +++ b/docker-compose.ci.yaml @@ -2,7 +2,7 @@ version: '3.7' services: api: - image: docker.pkg.github.com/alerta/alerta/alerta-api:latest + image: ghcr.io/alerta/alerta-api:latest ports: - "8080:8080" depends_on: diff --git a/tests/integration/test_blackouts.py b/tests/integration/test_blackouts.py index 5414b94..e6d2264 100644 --- a/tests/integration/test_blackouts.py +++ b/tests/integration/test_blackouts.py @@ -10,7 +10,8 @@ def setUp(self): def test_blackout(self): blackout = self.client.create_blackout( - environment='Production', service=['Web', 'App'], resource='web01', event='node_down', group='Network', tags=['london', 'linux'] + environment='Production', service=['Web', 'App'], resource='web01', event='node_down', group='Network', + tags=['london', 'linux'], origin='foo/bar' ) blackout_id = blackout.id @@ -18,14 +19,17 @@ def test_blackout(self): self.assertEqual(blackout.service, ['Web', 'App']) self.assertIn('london', blackout.tags) self.assertIn('linux', blackout.tags) + self.assertEqual(blackout.origin, 'foo/bar') - blackout = self.client.update_blackout(blackout_id, environment='Development', group='Network', text='updated blackout') + blackout = self.client.update_blackout(blackout_id, environment='Development', group='Network', + origin='foo/quux', text='updated blackout') self.assertEqual(blackout.environment, 'Development') self.assertEqual(blackout.group, 'Network') + self.assertEqual(blackout.origin, 'foo/quux') self.assertEqual(blackout.text, 'updated blackout') blackout = self.client.create_blackout( - environment='Production', service=['Core'], group='Network' + environment='Production', service=['Core'], group='Network', origin='foo/baz' ) blackouts = self.client.get_blackouts() diff --git a/tests/unit/test_blackouts.py b/tests/unit/test_blackouts.py index 2a841b3..4962ef8 100644 --- a/tests/unit/test_blackouts.py +++ b/tests/unit/test_blackouts.py @@ -13,31 +13,33 @@ def setUp(self): self.blackout = """ { "blackout": { - "createTime": "2018-08-26T20:45:04.622Z", + "createTime": "2021-04-14T20:36:06.453Z", "customer": null, "duration": 3600, - "endTime": "2018-08-26T21:45:04.622Z", + "endTime": "2021-04-14T21:36:06.453Z", "environment": "Production", - "event": null, - "group": null, - "href": "http://localhost:8080/blackout/e18a4be8-60d7-4ce2-9b3d-f18d814f7b85", - "id": "e18a4be8-60d7-4ce2-9b3d-f18d814f7b85", - "priority": 3, - "remaining": 3599, - "resource": null, + "event": "node_down", + "group": "Network", + "href": "http://local.alerta.io:8080/blackout/5ed223a3-27dc-4c4c-97d1-504f107d8a1a", + "id": "5ed223a3-27dc-4c4c-97d1-504f107d8a1a", + "origin": "foo/xyz", + "priority": 8, + "remaining": 3600, + "resource": "web01", "service": [ - "Network" + "Web", + "App" ], - "startTime": "2018-08-26T20:45:04.622Z", + "startTime": "2021-04-14T20:36:06.453Z", "status": "active", "tags": [ - "london", - "linux" + "london", + "linux" ], "text": "Network outage in Bracknell", - "user": "admin@alerta.io" + "user": "admin@alerta.dev" }, - "id": "e18a4be8-60d7-4ce2-9b3d-f18d814f7b85", + "id": "5ed223a3-27dc-4c4c-97d1-504f107d8a1a", "status": "ok" } """ @@ -45,10 +47,13 @@ def setUp(self): @requests_mock.mock() def test_blackout(self, m): m.post('http://localhost:8080/blackout', text=self.blackout) - alert = self.client.create_blackout(environment='Production', service=[ - 'Web', 'App'], resource='web01', event='node_down', group='Network', tags=['london', 'linux']) + alert = self.client.create_blackout(environment='Production', service=['Web', 'App'], resource='web01', + event='node_down', group='Network', tags=['london', 'linux'], + origin='foo/xyz', text='Network outage in Bracknell') self.assertEqual(alert.environment, 'Production') - self.assertEqual(alert.service, ['Network']) + self.assertEqual(alert.service, ['Web', 'App']) + self.assertEqual(alert.group, 'Network') self.assertIn('london', alert.tags) + self.assertEqual(alert.origin, 'foo/xyz') self.assertEqual(alert.text, 'Network outage in Bracknell') - self.assertEqual(alert.user, 'admin@alerta.io') + self.assertEqual(alert.user, 'admin@alerta.dev')