"""Exercise the real bootstrap shell with a local fake Vault transport.""" import json import os from pathlib import Path import subprocess import tempfile import unittest import yaml ROOT = Path(__file__).resolve().parents[2] MANIFEST = ROOT / 'services/keycloak/bootstrap-jobs/metis-node-passwords-secret-ensure-job.yaml' FAKE_CURL = r'''#!/usr/bin/env python3 import json,os,pathlib,sys args=sys.argv[1:] state=pathlib.Path(os.environ['FAKE_STATE']) s=json.loads(state.read_text()) if args[-1].endswith('/login'): print(json.dumps({'auth':{'client_token':'synthetic-token'}})); sys.exit(0) node=args[-1].rsplit('/',1)[-1] out=pathlib.Path(args[args.index('-o')+1]) if '--data-binary' in args: p=json.loads(pathlib.Path(args[args.index('--data-binary')+1][1:]).read_text()) s['writes'].append(p) status='400' if s.get('conflict') else '200' out.write_text('UNSAFE BODY MUST NOT APPEAR IN LOGS') else: d=s['records'].get(node) status='200' if d else '404' out.write_text(json.dumps({'data':{'data':d,'metadata':{'version':7}}})) state.write_text(json.dumps(s)); print(status,end='') ''' class BootstrapTests(unittest.TestCase): def exercise(self, records, conflict=False): manifest = yaml.safe_load(MANIFEST.read_text()) self.assertNotIn('ttlSecondsAfterFinished', manifest['spec']) script = manifest['spec']['template']['spec']['containers'][0]['args'][0] with tempfile.TemporaryDirectory() as d: folder = Path(d) fake = folder / 'curl' fake.write_text(FAKE_CURL) fake.chmod(0o755) state = folder / 'state.json' state.write_text(json.dumps({'records': records, 'writes': [], 'conflict': conflict})) jwt = folder / 'jwt' jwt.write_text('synthetic-jwt') env = dict(os.environ, PATH=d + os.pathsep + os.environ['PATH'], FAKE_STATE=str(state), SERVICE_ACCOUNT_TOKEN_FILE=str(jwt)) result = subprocess.run(['/bin/sh', '-c', script], env=env, capture_output=True, text=True, timeout=30) self.assertNotIn('UNSAFE BODY', result.stdout + result.stderr) self.assertNotIn('synthetic-password', result.stdout + result.stderr) return result, json.loads(state.read_text()) def test_preserves_passwords_extra_fields_and_cas(self): result, state = self.exercise({'titan-jh': {'atlas_password': 'synthetic-password', 'root_password': 'synthetic-root', 'operator_note': 'keep'}}) self.assertEqual(result.returncode, 0, result.stderr) first = state['writes'][0] self.assertEqual(first['options']['cas'], 7) self.assertEqual(first['data']['atlas_password'], 'synthetic-password') self.assertEqual(first['data']['operator_note'], 'keep') self.assertEqual(state['writes'][1]['options']['cas'], 0) def test_unchanged_secret_has_no_new_version(self): result, state = self.exercise({'titan-jh': {'atlas_password': 'synthetic-password', 'root_password': 'synthetic-root', 'intranet_ip': '192.168.22.8'}}) self.assertEqual(result.returncode, 0) self.assertFalse(any(w['data']['intranet_ip'] == '192.168.22.8' for w in state['writes'])) def test_concurrent_write_fails_closed(self): result, state = self.exercise({}, conflict=True) self.assertNotEqual(result.returncode, 0) self.assertEqual(len(state['writes']), 1) if __name__ == '__main__': unittest.main()