feat: add nowcast point alarm unregister client with confirmation and backup
Shows environment, count and an irreversibility warning, requires typing the confirmation word (plus the environment name on prod), backs every registration up through get-by-id before deleting and aborts the whole run if the backup cannot be completed.
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Delete point alarm registrations listed in a CSV/TXT file, with confirmation and backup."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from common import ApiError, ConfigurationError, IklimClient, configure_logging
|
||||
from point_alarm import (
|
||||
PointAlarmService,
|
||||
PointUnregisterProcessor,
|
||||
read_id_list,
|
||||
timestamped_path,
|
||||
write_records,
|
||||
)
|
||||
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(
|
||||
description=(
|
||||
"Dosyadaki registrationId'leri siler (DELETE /v1/alarms/points/unregister/{id}). "
|
||||
"Girdi CSV (registrationId sütunu) veya TXT (satır başına bir ID). Başlamadan önce "
|
||||
"ortam, silinecek sayı ve 'geri alınamaz' uyarısı gösterilir; onay için SİL yazılmalıdır "
|
||||
"(prod ortamında ek olarak 'prod' yazılır). Bir hesabın son kaydı silinirse webhook da "
|
||||
"silinir. Silmeden önce her kayıt get-by-id ile yedeklenir; yedek yazılamazsa hiçbir "
|
||||
"kayıt silinmez."
|
||||
)
|
||||
)
|
||||
parser.add_argument("input_file", type=Path, help="ID listesi (.csv veya .txt)")
|
||||
parser.add_argument(
|
||||
"--backup",
|
||||
type=Path,
|
||||
default=BASE_DIR / "nowcast-point-unregister-backup.csv",
|
||||
help="Yedek dosyası (.csv/.txt, zaman soneki eklenir; varsayılan: nowcast-point-unregister-backup.csv)",
|
||||
)
|
||||
parser.add_argument("--no-backup", action="store_true", help="Silmeden önce yedek almayı kapatır")
|
||||
parser.add_argument(
|
||||
"--output",
|
||||
type=Path,
|
||||
help="Sonuç dosyası (.csv/.txt, zaman soneki eklenir); verilmezse yalnızca özet yazılır",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--debug-log",
|
||||
type=Path,
|
||||
default=BASE_DIR / "logs" / "iklim-api-debug.log",
|
||||
help="Maskelenmiş HTTP debug log dosyası",
|
||||
)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main() -> int:
|
||||
args = parse_args()
|
||||
configure_logging(args.debug_log)
|
||||
try:
|
||||
ids = read_id_list(args.input_file, "registrationId")
|
||||
client = IklimClient.from_env(BASE_DIR / ".env")
|
||||
processor = PointUnregisterProcessor(
|
||||
PointAlarmService(client),
|
||||
ids=ids,
|
||||
environment=client.settings.environment,
|
||||
base_url=client.settings.base_url,
|
||||
backup_path=None if args.no_backup else timestamped_path(args.backup),
|
||||
)
|
||||
results = processor.run()
|
||||
if not results:
|
||||
return 1
|
||||
failed = sum(1 for row in results if row["status"] == "FAILED")
|
||||
print(f"{len(results) - failed} silindi, {failed} başarısız.")
|
||||
if args.output:
|
||||
path = timestamped_path(args.output)
|
||||
write_records(path, results, [], columns=["registrationId", "status", "httpStatus", "errorBody"])
|
||||
print(f"Sonuçlar yazıldı: {path.resolve()}")
|
||||
return 1 if failed else 0
|
||||
except (ConfigurationError, ApiError, OSError) as exc:
|
||||
logging.error("İşlem durduruldu: %s", exc)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user