Files
mopac-pmo/scripts/file-identity-ticket.py

50 lines
2.7 KiB
Python

import os, json, urllib.request
URL = os.environ["REDMINE_URL"]
KEY = os.environ["REDMINE_API_KEY"]
cats = {c["name"]: c["id"] for c in
json.load(urllib.request.urlopen(urllib.request.Request(
URL + "/projects/MOPAC/issue_categories.json",
headers={"X-Redmine-API-Key": KEY}), timeout=15))["issue_categories"]}
vers = {v["name"]: v["id"] for v in
json.load(urllib.request.urlopen(urllib.request.Request(
URL + "/projects/MOPAC/versions.json",
headers={"X-Redmine-API-Key": KEY}), timeout=15))["versions"]}
print("cats:", cats, "versions:", vers)
desc = """# Two-level identity model: Linux account + Cloudron accounts
## Objective (Charles, 2026-08-29)
The harness must model TWO identity levels everywhere it acts:
- **Linux account** = runtime identity (where the daemon runs: reachableceo, TSGBOD, ..., COSWFO). Drives: state dirs, quota/usage attribution (the $200/mo breakdown is per vertical), Redmine scope, briefing rollup.
- **Cloudron accounts** = acting identities (N per Linux account, e.g. a dozen+). All actions in TSYS systems happen via API under Cloudron SSO identities; their credentials live in per-cloudron-account Bitwarden machine accounts (#497).
## Scope
- harness.toml gains an identity section: linux account name + cloudron account map (label -> credential refs via keyproxy mpk_ placeholders, per system: redmine, discourse, gitea, linkwarden, ...).
- Attribution stamped on every outbound action: loop JSONL + REPORT headers record linux account + cloudron identity used.
- deploy/accounts.tsv (from #494) gains a cloudron-accounts column; installer templates the identity section.
- Usage accounting (from #490) rolls up per linux account AND per cloudron identity.
- keyproxy ref lookup stays instance-local; cloudron label selects the BW machine account context (#497).
## Acceptance criteria
- A turn executed under a fake 2-account config attributes actions correctly at both levels.
- REPORT/JSONL show both identities; README documents the model.
## References
SPEC-20260829-charles-brief.md (cloudron accounts section); #497 scale amendment.
"""
body = json.dumps({"issue": {
"project_id": "MOPAC",
"subject": "Two-level identity model: Linux account (runtime) + Cloudron accounts (acting)",
"tracker_id": 2, "priority_id": 4,
"category_id": cats["Infrastructure"],
"fixed_version_id": vers["Production"],
"estimated_hours": 5,
"description": desc}}).encode()
req = urllib.request.Request(URL + "/issues.json", data=body,
headers={"X-Redmine-API-Key": KEY, "Content-Type": "application/json"}, method="POST")
r = json.load(urllib.request.urlopen(req, timeout=15))
print("ticket", r["issue"]["id"], "created")