|
| 1 | +#!/usr/bin/python3 |
| 2 | + |
| 3 | +# SPDX-FileCopyrightText: 2025 Institute for Common Good Technology |
| 4 | +# |
| 5 | +# SPDX-License-Identifier: AGPL-3.0-or-later |
| 6 | + |
| 7 | +from argparse import ArgumentParser |
| 8 | +from datetime import datetime |
| 9 | +import json |
| 10 | +from sys import exit, stderr |
| 11 | +from pprint import pprint |
| 12 | + |
| 13 | +from psycopg2 import connect |
| 14 | +from psycopg2.extras import RealDictCursor |
| 15 | + |
| 16 | +parser = ArgumentParser( |
| 17 | + prog='EventDB to JSON', |
| 18 | + description='Extract data from the IntelMQ EventDB') |
| 19 | +parser.add_argument('-v', '--verbose', action='store_true') |
| 20 | +parser.add_argument('-i', '--id', help='Get events by ID') |
| 21 | +parser.add_argument('-p', '--pretty', action='store_true', help='Pretty print JSON output') |
| 22 | +parser.add_argument('--dsn', help='A complete libpg conninfo string. If not given, it will be loaded from /etc/intelmq/eventdb-serve.conf') |
| 23 | +args = parser.parse_args() |
| 24 | + |
| 25 | +if args.dsn: |
| 26 | + conninfo = args.dsn |
| 27 | +else: |
| 28 | + try: |
| 29 | + with open('/etc/intelmq/eventdb-serve.conf') as fody_config: |
| 30 | + conninfo = json.load(fody_config)['libpg conninfo'] |
| 31 | + except FileNotFoundError as exc: |
| 32 | + print(f'Could not load database configuration. {exc}', file=stderr) |
| 33 | + exit(2) |
| 34 | + |
| 35 | +if args.verbose: |
| 36 | + print(f'Using DSN {conninfo!r}.') |
| 37 | +db = connect(dsn=conninfo) |
| 38 | +cur = db.cursor(cursor_factory=RealDictCursor) |
| 39 | +cur.execute ('SELECT * FROM events WHERE id = %s', (args.id, )) |
| 40 | + |
| 41 | +for row in cur.fetchall(): |
| 42 | + del row['id'] |
| 43 | + for key in list(row.keys()): |
| 44 | + if isinstance(row[key], datetime): |
| 45 | + # data from the database has TZ information already included |
| 46 | + row[key] = row[key].isoformat() |
| 47 | + elif row[key] is None: |
| 48 | + del row[key] |
| 49 | + if args.pretty: |
| 50 | + print(json.dumps(row, indent=2)) |
| 51 | + else: |
| 52 | + print(json.dumps(row)) |
0 commit comments