- 37개 파일 IP → zioinfo.co.kr 치환 (소스/매뉴얼/설정/하네스) - Manager DrConsole/NetworkConsole/CsapConsole 빌드 + /var/www/manager/ 배포 - 테스트: Manager HTTP 200, ITSM 신규 API 7개 전체 200 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
133 lines
4.6 KiB
Python
133 lines
4.6 KiB
Python
#!/usr/bin/env python3
|
|
"""서버에서 직접 라이선스 API 테스트 (paramiko exec)"""
|
|
import paramiko, time, sys, json
|
|
|
|
HOST = '101.79.17.164'; USER = 'root'; PASS = '1q2w3e!Q'
|
|
client = paramiko.SSHClient()
|
|
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
client.connect(HOST, username=USER, password=PASS, timeout=15)
|
|
|
|
def ssh(label, cmd, timeout=20):
|
|
print(f'\n[{label}]')
|
|
chan = client.get_transport().open_session()
|
|
chan.set_combine_stderr(True)
|
|
chan.exec_command(cmd)
|
|
start = time.time()
|
|
while not chan.exit_status_ready():
|
|
if chan.recv_ready(): sys.stdout.buffer.write(chan.recv(4096)); sys.stdout.flush()
|
|
if time.time() - start > timeout: break
|
|
time.sleep(0.2)
|
|
while chan.recv_ready(): sys.stdout.buffer.write(chan.recv(4096))
|
|
sys.stdout.flush()
|
|
rc = chan.recv_exit_status()
|
|
print(f' exit={rc}')
|
|
return rc
|
|
|
|
# 테스트 스크립트 서버에 업로드
|
|
test_script = r"""#!/usr/bin/env python3
|
|
import urllib.request, urllib.parse, json
|
|
|
|
BASE = 'http://localhost:8001'
|
|
RESULTS = []
|
|
|
|
def api(method, path, data=None, token=None):
|
|
url = f'{BASE}{path}'
|
|
body = json.dumps(data).encode() if data else None
|
|
req = urllib.request.Request(url, data=body, method=method)
|
|
req.add_header('Content-Type', 'application/json')
|
|
if token: req.add_header('Authorization', f'Bearer {token}')
|
|
try:
|
|
resp = urllib.request.urlopen(req, timeout=10)
|
|
return json.loads(resp.read()), resp.status
|
|
except urllib.error.HTTPError as e:
|
|
return json.loads(e.read()), e.code
|
|
except Exception as ex:
|
|
return {'error': str(ex)}, 0
|
|
|
|
def test(name, fn):
|
|
try:
|
|
r = fn(); ok = True
|
|
except Exception as e:
|
|
r = str(e); ok = False
|
|
RESULTS.append((name, ok, r))
|
|
print(f'{"OK" if ok else "FAIL"} {name}: {str(r)[:80]}')
|
|
return r if ok else None
|
|
|
|
print('=== GUARDiA 라이선스 API 테스트 ===')
|
|
|
|
# T1 로그인
|
|
params = urllib.parse.urlencode({'username':'admin','password':'Admin@zioinfo2026!'})
|
|
req = urllib.request.Request(f'{BASE}/api/auth/login', data=params.encode(), method='POST')
|
|
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
|
|
resp = urllib.request.urlopen(req, timeout=10)
|
|
TOKEN = json.loads(resp.read()).get('access_token','')
|
|
print(f'TOKEN: {TOKEN[:20]}...\n')
|
|
|
|
# T2 현재 상태
|
|
test('T2 현재 라이선스 상태', lambda: api('GET', '/api/license/status', token=TOKEN)[0].get('message'))
|
|
|
|
# T3 체험 발급 (이미 있으면 Skip)
|
|
cur, _ = api('GET', '/api/license/status', token=TOKEN)
|
|
if not cur.get('activated'):
|
|
def t3():
|
|
r,s = api('POST','/api/license/trial',{'customer':'지오정보기술 체험판','days':7},token=TOKEN)
|
|
return f'HTTP {s}: {r.get("message",r.get("detail","?"))}'
|
|
test('T3 체험 라이선스 발급 (7일)', t3)
|
|
else:
|
|
RESULTS.append(('T3 체험 라이선스 발급','SKIP','이미 활성화됨'))
|
|
print('SKIP T3 체험 라이선스 발급: 이미 활성화됨')
|
|
|
|
# T4 활성화 후 상태
|
|
def t4():
|
|
r,_ = api('GET','/api/license/status',token=TOKEN)
|
|
return f"valid={r.get('valid')}, edition={r.get('edition')}, days={r.get('days_remaining')}"
|
|
test('T4 활성화 후 상태 확인', t4)
|
|
|
|
# T5 이력 조회
|
|
def t5():
|
|
r,s = api('GET','/api/license/history',token=TOKEN)
|
|
cnt = len(r) if isinstance(r,list) else '?'
|
|
return f'HTTP {s}: {cnt}건'
|
|
test('T5 라이선스 이력 조회', t5)
|
|
|
|
# T6 잘못된 키 검증
|
|
def t6():
|
|
r,s = api('POST','/api/license/verify',{'license_key':'invalid_test_key'},token=TOKEN)
|
|
return f'HTTP {s}: {r.get("detail",r.get("message","?"))[:50]}'
|
|
test('T6 잘못된 키 검증 (400/422 예상)', t6)
|
|
|
|
# T7 Manager UI
|
|
import urllib.request as ur
|
|
try:
|
|
resp2 = ur.urlopen('http://localhost:8090/', timeout=5)
|
|
ui_status = resp2.status
|
|
except Exception as ex:
|
|
ui_status = str(ex)
|
|
test('T7 Manager UI 접속', lambda: f'HTTP {ui_status}')
|
|
|
|
# T8 Manager API
|
|
try:
|
|
resp3 = ur.urlopen('http://localhost:8002/health', timeout=5)
|
|
api_status = json.loads(resp3.read()).get('status','?')
|
|
except Exception as ex:
|
|
api_status = str(ex)
|
|
test('T8 Manager Backend', lambda: api_status)
|
|
|
|
# 결과 요약
|
|
print(f'\n{"="*55}')
|
|
passed = sum(1 for _,ok,_ in RESULTS if ok is True or ok=='SKIP')
|
|
print(f'테스트 결과: {passed}/{len(RESULTS)} PASS')
|
|
for name,ok,detail in RESULTS:
|
|
icon = '✅' if ok is True else ('⏭️' if ok=='SKIP' else '❌')
|
|
print(f' {icon} {name}')
|
|
print('='*55)
|
|
"""
|
|
|
|
sftp = client.open_sftp()
|
|
with sftp.open('/tmp/test_license.py', 'w') as f:
|
|
f.write(test_script)
|
|
sftp.close()
|
|
|
|
ssh('라이선스 테스트 실행', 'python3 /tmp/test_license.py 2>&1', timeout=30)
|
|
client.close()
|