From 68ba1f5ee6de7f7e0c3fc4552d6bd57a560011d2 Mon Sep 17 00:00:00 2001 From: Nick Satterly Date: Sat, 28 Mar 2026 13:30:02 +0100 Subject: [PATCH] Fix bulk commands only operating on first page of alerts All bulk commands (delete, ack, close, tag, untag, shelve, unshelve, unack, update, action, note) called get_alerts() without pagination, which defaults to page 1 with 50 results. If more than 50 alerts matched, the remaining alerts were silently skipped. Add get_all_alerts() method that paginates through all results and use it in all 11 bulk commands. Fixes #227 Co-Authored-By: Claude Opus 4.6 (1M context) --- alertaclient/api.py | 11 +++++++++++ alertaclient/commands/cmd_ack.py | 2 +- alertaclient/commands/cmd_action.py | 2 +- alertaclient/commands/cmd_close.py | 2 +- alertaclient/commands/cmd_delete.py | 2 +- alertaclient/commands/cmd_note.py | 2 +- alertaclient/commands/cmd_shelve.py | 2 +- alertaclient/commands/cmd_tag.py | 2 +- alertaclient/commands/cmd_unack.py | 2 +- alertaclient/commands/cmd_unshelve.py | 2 +- alertaclient/commands/cmd_untag.py | 2 +- alertaclient/commands/cmd_update.py | 2 +- 12 files changed, 22 insertions(+), 11 deletions(-) diff --git a/alertaclient/api.py b/alertaclient/api.py index 98c3ba5..25b032d 100644 --- a/alertaclient/api.py +++ b/alertaclient/api.py @@ -110,6 +110,17 @@ def get_alerts(self, query=None, page=1, page_size=None): r = self.http.get('/alerts', query, page=page, page_size=page_size) return [Alert.parse(a) for a in r['alerts']] + def get_all_alerts(self, query=None, page_size=1000): + alerts = [] + page = 1 + while True: + r = self.http.get('/alerts', query, page=page, page_size=page_size) + alerts.extend([Alert.parse(a) for a in r['alerts']]) + if len(r['alerts']) < page_size: + break + page += 1 + return alerts + def get_history(self, query=None, page=1, page_size=None): r = self.http.get('/alerts/history', query, page=page, page_size=page_size) return [RichHistory.parse(a) for a in r['history']] diff --git a/alertaclient/commands/cmd_ack.py b/alertaclient/commands/cmd_ack.py index 1797020..56df1ef 100644 --- a/alertaclient/commands/cmd_ack.py +++ b/alertaclient/commands/cmd_ack.py @@ -20,6 +20,6 @@ def cli(obj, ids, query, filters, text): else: query = build_query(filters) total, _, _ = client.get_count(query) - ids = [a.id for a in client.get_alerts(query)] + ids = [a.id for a in client.get_all_alerts(query)] action_progressbar(client, action='ack', ids=ids, label=f'Acking {total} alerts', text=text) diff --git a/alertaclient/commands/cmd_action.py b/alertaclient/commands/cmd_action.py index be4b29b..a2277cc 100644 --- a/alertaclient/commands/cmd_action.py +++ b/alertaclient/commands/cmd_action.py @@ -21,7 +21,7 @@ def cli(obj, action, ids, query, filters, text): else: query = build_query(filters) total, _, _ = client.get_count(query) - ids = [a.id for a in client.get_alerts(query)] + ids = [a.id for a in client.get_all_alerts(query)] label = f'Action ({action}) {total} alerts' action_progressbar(client, action=action, ids=ids, label=label, text=text) diff --git a/alertaclient/commands/cmd_close.py b/alertaclient/commands/cmd_close.py index 8b7ac78..954226e 100644 --- a/alertaclient/commands/cmd_close.py +++ b/alertaclient/commands/cmd_close.py @@ -20,6 +20,6 @@ def cli(obj, ids, query, filters, text): else: query = build_query(filters) total, _, _ = client.get_count(query) - ids = [a.id for a in client.get_alerts(query)] + ids = [a.id for a in client.get_all_alerts(query)] action_progressbar(client, action='close', ids=ids, label=f'Closing {total} alerts', text=text) diff --git a/alertaclient/commands/cmd_delete.py b/alertaclient/commands/cmd_delete.py index c3ca575..e71afb3 100644 --- a/alertaclient/commands/cmd_delete.py +++ b/alertaclient/commands/cmd_delete.py @@ -21,7 +21,7 @@ def cli(obj, ids, query, filters): else: query = build_query(filters) total, _, _ = client.get_count(query) - ids = [a.id for a in client.get_alerts(query)] + ids = [a.id for a in client.get_all_alerts(query)] with click.progressbar(ids, label=f'Deleting {total} alerts') as bar: for id in bar: diff --git a/alertaclient/commands/cmd_note.py b/alertaclient/commands/cmd_note.py index f341163..b7f3b27 100644 --- a/alertaclient/commands/cmd_note.py +++ b/alertaclient/commands/cmd_note.py @@ -40,7 +40,7 @@ def cli(obj, alert_ids, query, filters, text, delete): else: query = build_query(filters) total, _, _ = client.get_count(query) - alert_ids = [a.id for a in client.get_alerts(query)] + alert_ids = [a.id for a in client.get_all_alerts(query)] with click.progressbar(alert_ids, label=f'Add note to {total} alerts') as bar: for id in bar: diff --git a/alertaclient/commands/cmd_shelve.py b/alertaclient/commands/cmd_shelve.py index 20a4e40..da42a40 100644 --- a/alertaclient/commands/cmd_shelve.py +++ b/alertaclient/commands/cmd_shelve.py @@ -21,7 +21,7 @@ def cli(obj, ids, query, filters, timeout, text): else: query = build_query(filters) total, _, _ = client.get_count(query) - ids = [a.id for a in client.get_alerts(query)] + ids = [a.id for a in client.get_all_alerts(query)] action_progressbar(client, action='shelve', ids=ids, label=f'Shelving {total} alerts', text=text, timeout=timeout) diff --git a/alertaclient/commands/cmd_tag.py b/alertaclient/commands/cmd_tag.py index f98c678..8f3aaba 100644 --- a/alertaclient/commands/cmd_tag.py +++ b/alertaclient/commands/cmd_tag.py @@ -20,7 +20,7 @@ def cli(obj, ids, query, filters, tags): else: query = build_query(filters) total, _, _ = client.get_count(query) - ids = [a.id for a in client.get_alerts(query)] + ids = [a.id for a in client.get_all_alerts(query)] with click.progressbar(ids, label=f'Tagging {total} alerts') as bar: for id in bar: diff --git a/alertaclient/commands/cmd_unack.py b/alertaclient/commands/cmd_unack.py index 64b25d5..53496d1 100644 --- a/alertaclient/commands/cmd_unack.py +++ b/alertaclient/commands/cmd_unack.py @@ -20,6 +20,6 @@ def cli(obj, ids, query, filters, text): else: query = build_query(filters) total, _, _ = client.get_count(query) - ids = [a.id for a in client.get_alerts(query)] + ids = [a.id for a in client.get_all_alerts(query)] action_progressbar(client, action='unack', ids=ids, label=f'Un-acking {total} alerts', text=text) diff --git a/alertaclient/commands/cmd_unshelve.py b/alertaclient/commands/cmd_unshelve.py index 278a8e7..e8c431c 100644 --- a/alertaclient/commands/cmd_unshelve.py +++ b/alertaclient/commands/cmd_unshelve.py @@ -20,6 +20,6 @@ def cli(obj, ids, query, filters, text): else: query = build_query(filters) total, _, _ = client.get_count(query) - ids = [a.id for a in client.get_alerts(query)] + ids = [a.id for a in client.get_all_alerts(query)] action_progressbar(client, 'unshelve', ids, label=f'Un-shelving {total} alerts', text=text) diff --git a/alertaclient/commands/cmd_untag.py b/alertaclient/commands/cmd_untag.py index d2026cd..6a62064 100644 --- a/alertaclient/commands/cmd_untag.py +++ b/alertaclient/commands/cmd_untag.py @@ -20,7 +20,7 @@ def cli(obj, ids, query, filters, tags): else: query = build_query(filters) total, _, _ = client.get_count(query) - ids = [a.id for a in client.get_alerts(query)] + ids = [a.id for a in client.get_all_alerts(query)] with click.progressbar(ids, label=f'Untagging {total} alerts') as bar: for id in bar: diff --git a/alertaclient/commands/cmd_update.py b/alertaclient/commands/cmd_update.py index 90c0155..b0e59a1 100644 --- a/alertaclient/commands/cmd_update.py +++ b/alertaclient/commands/cmd_update.py @@ -20,7 +20,7 @@ def cli(obj, ids, query, filters, attributes): else: query = build_query(filters) total, _, _ = client.get_count(query) - ids = [a.id for a in client.get_alerts(query)] + ids = [a.id for a in client.get_all_alerts(query)] with click.progressbar(ids, label=f'Updating {total} alerts') as bar: for id in bar: