"""Apply Keycloak token lifespan patch on production app host.""" from __future__ import annotations import base64 import sys from pathlib import Path import paramiko ROOT = Path(__file__).resolve().parents[1] SCRIPT = ROOT / "backend" / "services" / "identity-access" / "scripts" / "patch_keycloak_token_lifespans.py" APP_HOST = "192.168.10.162" APP_USER = "morteza" APP_PASS = "Moli@5404" REMOTE = "/home/morteza/torbatyar" def run(client: paramiko.SSHClient, cmd: str, timeout: int = 120) -> tuple[int, str]: print(">>>", cmd[:200]) _i, o, e = client.exec_command(cmd, timeout=timeout, get_pty=True) out = o.read().decode("utf-8", "replace") + e.read().decode("utf-8", "replace") code = o.channel.recv_exit_status() print(out[-4000:]) return code, out def main() -> int: text = SCRIPT.read_text(encoding="utf-8") b64 = base64.b64encode(text.encode()).decode() c = paramiko.SSHClient() c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect(APP_HOST, username=APP_USER, password=APP_PASS, timeout=30, allow_agent=False, look_for_keys=False) try: # Upload script into identity container path via host bind mount run( c, f"mkdir -p {REMOTE}/backend/services/identity-access/scripts && " f"echo {b64} | base64 -d > {REMOTE}/backend/services/identity-access/scripts/patch_keycloak_token_lifespans.py", ) # Dry-run via keycloak network from identity container (KEYCLOAK on docker network) code, _ = run( c, "sg docker -c \"docker compose -f /home/morteza/torbatyar/docker-compose.yml exec -T " "-e KEYCLOAK_SERVER_URL=http://keycloak:8080 " "-e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin " "identity-access-service python scripts/patch_keycloak_token_lifespans.py\"", ) # Apply code, out = run( c, "sg docker -c \"docker compose -f /home/morteza/torbatyar/docker-compose.yml exec -T " "-e KEYCLOAK_SERVER_URL=http://keycloak:8080 " "-e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin " "identity-access-service python scripts/patch_keycloak_token_lifespans.py --apply\"", ) if code != 0: # Fallback: run on host against published 8080 run( c, f"cd {REMOTE}/backend/services/identity-access && " "KEYCLOAK_SERVER_URL=http://127.0.0.1:8080 KEYCLOAK_ADMIN=admin KEYCLOAK_ADMIN_PASSWORD=admin " "python3 scripts/patch_keycloak_token_lifespans.py --apply", ) return 0 if "OK realm" in out or code == 0 else 1 finally: c.close() if __name__ == "__main__": raise SystemExit(main())