"""Jenkins job config.xml에 authToken 추가 + Gitea webhook URL 수정""" import paramiko, sys, json, time sys.stdout.reconfigure(encoding='utf-8', errors='replace') c = paramiko.SSHClient(); c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=15) sftp = c.open_sftp() J = 'http://127.0.0.1:9080' A = 'admin:Admin@2026!' TOKEN = 'gitea-build-2026' def run(label, cmd, timeout=30): print(f'\n[{label}]') _, o, _ = c.exec_command(cmd, timeout=timeout) out = o.read().decode('utf-8','replace').strip() if out: print(out[:500]) return out _, o, _ = c.exec_command(f'curl -sf -u "{A}" {J}/crumbIssuer/api/json 2>/dev/null', timeout=10) try: cd = json.loads(o.read().decode('utf-8','replace').strip()) CH = f'{cd["crumbRequestField"]}: {cd["crumb"]}' except: CH = 'Jenkins-Crumb: x' REPOS = ['guardia-itsm', 'zioinfo-web', 'guardia-manager', 'guardia-messenger', 'guardia-docs'] HOOK_IDS = {'zioinfo-web':16,'guardia-itsm':17,'guardia-manager':18,'guardia-messenger':19,'guardia-docs':20} # 1. config.xml에 authToken + GiteaWebHookTrigger 추가 print('[config.xml authToken + Gitea trigger 설정]') for repo in REPOS: _, o, _ = c.exec_command(f'curl -sf -u "{A}" {J}/job/{repo}/config.xml 2>/dev/null', timeout=10) config = o.read().decode('utf-8','replace') if not config.startswith('{TOKEN}' not in modified: if '' in modified: import re modified = re.sub(r'[^<]*', f'{TOKEN}', modified) else: modified = modified.replace('{TOKEN}\n /dev/null', timeout=15) code = o.read().decode('utf-8','replace').strip() print(f' {repo}: HTTP {code}') else: print(f' {repo}: 변경 없음') # 2. Gitea webhook URL을 token 방식으로 업데이트 print('\n[Gitea webhook URL → build?token=... 방식]') for repo, hid in HOOK_IDS.items(): payload = json.dumps({ "config": { "url": f"http://127.0.0.1:9080/job/{repo}/build?token={TOKEN}", "content_type": "json" }, "active": True, "events": ["push"] }) with sftp.open(f'/tmp/hook_{repo}.json', 'w') as f: f.write(payload) _, o, _ = c.exec_command( f"curl -sf -o /dev/null -w '%{{http_code}}' -X PATCH " f"'http://127.0.0.1:9003/api/v1/repos/zio/{repo}/hooks/{hid}' " "--header 'Authorization: Basic $(echo -n zio:Zio@Admin2026! | base64)' " "--header 'Content-Type: application/json' " f"--data @/tmp/hook_{repo}.json 2>/dev/null", timeout=15) code = o.read().decode('utf-8','replace').strip() print(f' {repo} hook {hid}: HTTP {code}') # 3. Gitea webhook 직접 테스트 time.sleep(3) run('webhook 테스트 (guardia-itsm)', "curl -sf -X POST 'http://127.0.0.1:9003/api/v1/repos/zio/guardia-itsm/hooks/17/tests' " "--header 'Authorization: Basic $(echo -n zio:Zio@Admin2026! | base64)' " "2>/dev/null && echo '전송됨' || echo FAIL") time.sleep(8) run('Jenkins 빌드 확인', f'curl -sf -u "{A}" {J}/job/guardia-itsm/api/json 2>/dev/null | ' "python3 -c \"import sys,json; d=json.load(sys.stdin); " "lb=d.get('lastBuild',{}); print('lastBuild #'+str(lb.get('number','?')), " "'nextBuild:', d.get('nextBuildNumber'))\" 2>/dev/null") # 4. 최종 아키텍처 요약 print('\n[최종 CI/CD 아키텍처]') run('webhook 서버', 'systemctl is-active zioinfo-deploy && echo "port 9999 OK"') run('Jenkins', f'curl -sf -u "{A}" {J}/api/json 2>/dev/null | ' "python3 -c \"import sys,json; d=json.load(sys.stdin); " "print(d.get('mode'), len(d.get('jobs',[])), 'jobs, all:', " "all(j['color']=='blue' for j in d['jobs']))\" 2>/dev/null") sftp.close() c.close() print('\n=== 완료 ===')