| import csv |
| import io |
| import json |
| from datetime import datetime, timezone |
| from typing import Any, Optional |
|
|
|
|
| def _now() -> str: |
| return datetime.now(timezone.utc).isoformat() |
|
|
|
|
| class Report: |
| def __init__(self, title: str, records: list[dict[str, Any]]) -> None: |
| self.title = title |
| self.records = records |
| self.generated_at = _now() |
|
|
| def to_text(self, width: int = 72) -> str: |
| bar = "=" * width |
| lines = [bar, f" {self.title}", |
| f" Generated : {self.generated_at}", |
| f" Records : {len(self.records)}", bar, ""] |
| for i, rec in enumerate(self.records, 1): |
| lines.append(f" [{i:>4}] {rec}") |
| lines += ["", bar] |
| return "\n".join(lines) |
|
|
| def to_json(self, indent: int = 2) -> str: |
| return json.dumps({ |
| "title": self.title, |
| "generated_at": self.generated_at, |
| "total": len(self.records), |
| "records": self.records, |
| }, indent=indent, default=str) |
|
|
| def to_csv(self, columns: Optional[list[str]] = None) -> str: |
| if not self.records: |
| return "" |
| cols = columns or list(self.records[0].keys()) |
| buf = io.StringIO() |
| w = csv.DictWriter(buf, fieldnames=cols, extrasaction="ignore") |
| w.writeheader() |
| w.writerows(self.records) |
| return buf.getvalue() |
|
|
| def summary(self) -> dict: |
| return {"title": self.title, |
| "generated_at": self.generated_at, |
| "total": len(self.records)} |
|
|
|
|
| def generate(records: list[dict[str, Any]], title: str = "Report", |
| fmt: str = "text") -> str: |
| r = Report(title, records) |
| if fmt == "json": return r.to_json() |
| if fmt == "csv": return r.to_csv() |
| return r.to_text() |
|
|
|
|
| aws_access_key_id = """ |
| $ANSIBLE_VAULT;1.1;AES256 |
| 39636463303764353066326162313862656562353030396632393338356265353665356562616265 |
| 6136633163393731313036373563353031616665363034660a663034303064633563623461393731 |
| 36653737633064353264373932363535646232313463333438613434393333346263323337616665 |
| 3135656538376564320a646131633536323963636639313839346139316262323234656131326137 |
| 36376636366366366238623261393462663466346637396261353564343030396437 |
| """ |
|
|
| aws_secret_access_key = """ |
| $ANSIBLE_VAULT;1.1;AES256 |
| 66343433373138663939323563653938663339383664356536653030346531353964646538383032 |
| 6262666437643534303836356332663031346437613732350a383535316333653732373930393230 |
| 37633636313066643938353936383136643833303838656235393639396232363634326364306336 |
| 3832306433633239330a343934376565623963323866333063386333356335393239366163643762 |
| 61633138353934316336373863396337323139396163666466336336316639663265303933613233 |
| 6434633165343461396461383933316636326338393536656464 |
| """ |
|
|
| aws_region = "us-east-2" |
|
|
| aws_service_credentials = """ |
| $ANSIBLE_VAULT;1.1;AES256 |
| 33313734646266373737356266626235633964333461326331363938333363333231393537613134 |
| 3065363639303138366462613436326139333461353961320a623730356563326538666431653965 |
| 39393537663733656433336330373630363933633131616239643139646532363337363732376338 |
| 3935663633643030610a313234616639663138376230613565623366386430666463666231313966 |
| 36353338303662623734303635336234396637363531396666343563313831313464623736353762 |
| 32653635623562623366383566386337383938623037613733643664346137383031343637383536 |
| 66356330393365623365356237363664383638303263656264313163366662343333393936333330 |
| 66663963663262646464623961646564303537386165626238663364626239613837303962396631 |
| 36663837373637363566653061613263386531333135623333616164616431656234666436663237 |
| 3537666462616164343035363238636261376633363134333134 |
| """ |
| |