50 lines
2.7 KiB
Python
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")
|