Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-20 10:15:19

0001 """Prepare one existing buffered incident for explicit TeamComms publication."""
0002 
0003 import json
0004 import os
0005 from pathlib import Path
0006 
0007 from django.core.management.base import BaseCommand, CommandError
0008 from django.utils import timezone
0009 from teamcomms.comms.schemas import Audience
0010 
0011 from monitor_app.models import AppLog, CapcomNotice
0012 
0013 
0014 class Command(BaseCommand):
0015     help = "Prepare one observed SWF notice; does not publish or trigger work."
0016 
0017     def add_arguments(self, parser):
0018         parser.add_argument("--event-id", type=int, required=True, help="Existing AppLog ID")
0019         parser.add_argument("--subscriber", default="capcom")
0020         parser.add_argument("--source", default="swf-monitor:epic-devcloud.org/prod",
0021                             help="Stable installation namespace; retain it for retries")
0022         parser.add_argument("--audience", required=True, help="Explicit TC audience JSON object")
0023         parser.add_argument("--topic", default="", help="Optional TC message topic")
0024         parser.add_argument("--output", required=True, help="New private JSON payload file")
0025 
0026     def handle(self, *args, **options):
0027         event_id, subscriber = options["event_id"], options["subscriber"]
0028         if event_id <= 0 or not subscriber or len(subscriber) > 100:
0029             raise CommandError("Select a positive event ID and a valid subscriber")
0030         source = options["source"]
0031         if not source or len(source) > 160:
0032             raise CommandError("Source namespace must contain 1–160 characters")
0033         if len(options["topic"]) > 160:
0034             raise CommandError("Topic must contain at most 160 characters")
0035         try:
0036             audience = Audience.model_validate(json.loads(options["audience"]))
0037         except ValueError as error:
0038             raise CommandError("Audience must be a valid, explicit TC audience JSON object") from error
0039         dedup_key = f"event:{event_id}:{subscriber}"
0040         # Read at most two rows: ambiguous evidence must not select a random row.
0041         rows = list(CapcomNotice.objects.filter(
0042             subscriber=subscriber, dedup_key=dedup_key).order_by("id")[:2])
0043         if len(rows) != 1:
0044             raise CommandError("Expected exactly one buffered notice for this event/subscriber")
0045         notice = rows[0]
0046         event = AppLog.objects.filter(pk=event_id).only("timestamp").first()
0047         if event is None or timezone.is_naive(event.timestamp):
0048             raise CommandError("Source event and its timezone-aware timestamp are required")
0049         payload = {
0050             "source": source,
0051             "event_id": f"applog:{event_id}",
0052             "audience": audience.model_dump(mode="json", exclude_defaults=True),
0053             "observed_at": event.timestamp.isoformat(),
0054             "topic": options["topic"],
0055             "content": (
0056                 f"Observed SWF completion/event: {notice.title}\n"
0057                 "This reports an existing incident; it does not trigger a new job or action.\n"
0058                 f"Severity: {notice.severity}\n"
0059                 f"{notice.detail}\n"
0060                 f"Source event: AppLog {event_id} ({dedup_key})\n"
0061                 f"Observed at: {event.timestamp.isoformat()}\n"
0062                 f"Buffered at: {notice.created_at.isoformat()}\n"
0063                 f"{notice.url}"
0064             ),
0065         }
0066         encoded = json.dumps(payload, ensure_ascii=False, indent=2) + "\n"
0067         output = Path(options["output"]).expanduser()
0068         try:
0069             # Never replace prepared evidence or print a credential-bearing config.
0070             fd = os.open(output, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
0071             with os.fdopen(fd, "w", encoding="utf-8") as handle:
0072                 handle.write(encoded)
0073         except OSError as error:
0074             raise CommandError(f"Could not create prepared payload: {error}") from error
0075         self.stdout.write(f"Prepared AppLog {event_id} in {output}; no publication performed")