From 2bd7d876cc6ab8a37fcb09b8ba13fbf1c2b06d5e Mon Sep 17 00:00:00 2001 From: DESKTOP-TKLFCPRython Date: Sun, 31 May 2026 10:09:17 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20101.79.17.164=20=E2=86=92=20zioinfo?= =?UTF-8?q?.co.kr=20=EC=A0=84=EC=B2=B4=20=EB=8F=84=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EB=B3=80=ED=99=98=20+=20Manager=20UI=20=EB=B0=B0=ED=8F=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- 18_zio서버_설치SW_목록.md | 248 +++++++ 19_zio서버_운영가이드.md | 649 ++++++++++++++++ 20_zio서버_CICD_가이드.md | 346 +++++++++ 21_zio서버_장애대응_가이드.md | 409 ++++++++++ 22_GUARDiA_개방망_운영가이드.md | 454 ++++++++++++ 23_GUARDiA_개방망_가이드.pdf | Bin 0 -> 91275 bytes 24_GUARDiA_개방망_발표자료.pptx | Bin 0 -> 41313 bytes 25_GUARDiA_Manager_라이선스_관리_가이드.md | 296 ++++++++ 26_GUARDiA_Manager_라이선스_가이드.pdf | Bin 0 -> 75697 bytes 27_GUARDiA_Manager_라이선스_발표자료.pptx | Bin 0 -> 41946 bytes 28_GUARDiA_폐쇄망_데이터연동_가이드.md | 76 ++ 29_GUARDiA_폐쇄망_데이터연동_가이드.pdf | Bin 0 -> 45708 bytes 30_GUARDiA_폐쇄망_데이터연동_발표자료.pptx | Bin 0 -> 36650 bytes 31_AI_플랫폼_제안서.md | 134 ++++ 32_벡터DB_제안서.md | 124 ++++ 33_GUARDiA_Messenger_앱_스토어_등록_가이드.md | 244 ++++++ 34_GUARDiA_Messenger_개발_배포_가이드.md | 288 +++++++ 35_GUARDiA_Messenger_개발가이드.pdf | Bin 0 -> 69652 bytes 36_GUARDiA_Messenger_발표자료.pptx | Bin 0 -> 42229 bytes 37_세션_전체_작업_요약.md | 206 +++++ 38_스킬_트리거_빠른참조.md | 81 ++ gen_export_docs.py | 230 ++++++ gen_license_docs.py | 460 ++++++++++++ gen_messenger_docs.py | 411 ++++++++++ gen_opennet_docs.py | 701 ++++++++++++++++++ 25 files changed, 5357 insertions(+) create mode 100644 18_zio서버_설치SW_목록.md create mode 100644 19_zio서버_운영가이드.md create mode 100644 20_zio서버_CICD_가이드.md create mode 100644 21_zio서버_장애대응_가이드.md create mode 100644 22_GUARDiA_개방망_운영가이드.md create mode 100644 23_GUARDiA_개방망_가이드.pdf create mode 100644 24_GUARDiA_개방망_발표자료.pptx create mode 100644 25_GUARDiA_Manager_라이선스_관리_가이드.md create mode 100644 26_GUARDiA_Manager_라이선스_가이드.pdf create mode 100644 27_GUARDiA_Manager_라이선스_발표자료.pptx create mode 100644 28_GUARDiA_폐쇄망_데이터연동_가이드.md create mode 100644 29_GUARDiA_폐쇄망_데이터연동_가이드.pdf create mode 100644 30_GUARDiA_폐쇄망_데이터연동_발표자료.pptx create mode 100644 31_AI_플랫폼_제안서.md create mode 100644 32_벡터DB_제안서.md create mode 100644 33_GUARDiA_Messenger_앱_스토어_등록_가이드.md create mode 100644 34_GUARDiA_Messenger_개발_배포_가이드.md create mode 100644 35_GUARDiA_Messenger_개발가이드.pdf create mode 100644 36_GUARDiA_Messenger_발표자료.pptx create mode 100644 37_세션_전체_작업_요약.md create mode 100644 38_스킬_트리거_빠른참조.md create mode 100644 gen_export_docs.py create mode 100644 gen_license_docs.py create mode 100644 gen_messenger_docs.py create mode 100644 gen_opennet_docs.py diff --git a/18_zio서버_설치SW_목록.md b/18_zio서버_설치SW_목록.md new file mode 100644 index 0000000..2729b16 --- /dev/null +++ b/18_zio서버_설치SW_목록.md @@ -0,0 +1,248 @@ +# zio-server 설치 SW 목록 및 구성 명세 + +> **서버**: zio-server | **IP**: zioinfo.co.kr | **작성일**: 2026-05-30 +> **OS**: Ubuntu 24.04.1 LTS (Noble Numbat) | **Provider**: NCloud (네이버 클라우드) + +--- + +## 1. 서버 사양 + +| 항목 | 사양 | +|------|------| +| CPU | AMD EPYC 9454P (2 vCPU) | +| RAM | 7.8 GB | +| Disk | 99 GB (사용 15 GB / 여유 80 GB) | +| OS | Ubuntu 24.04.1 LTS x86_64 | +| 네트워크 | 공인 IP zioinfo.co.kr | + +--- + +## 2. 설치 소프트웨어 목록 + +### 2-1. 런타임 / 언어 + +| SW | 버전 | 설치 경로 | 용도 | +|----|------|-----------|------| +| OpenJDK | 21.0.10 | `/usr/lib/jvm/java-21-openjdk-amd64` | Spring Boot 실행 | +| Node.js | 20.20.2 (LTS) | `/usr/bin/node` | React 빌드 | +| npm | 10.8.2 | `/usr/bin/npm` | 패키지 관리 | +| Python | 3.12.3 | `/usr/bin/python3` | GUARDiA ITSM, 배포 스크립트 | +| Apache Maven | 3.8.7 | `/usr/share/maven` | Spring Boot 빌드 | + +### 2-2. 웹 서버 / 프록시 + +| SW | 버전 | 설치 경로 | 용도 | +|----|------|-----------|------| +| Nginx | 1.24.0 | `/etc/nginx` | 리버스 프록시, 정적 파일 서빙 | + +### 2-3. 데이터베이스 + +| SW | 버전 | 설치 경로 | 용도 | +|----|------|-----------|------| +| PostgreSQL | 16.11 | `/var/lib/postgresql/16` | GUARDiA ITSM DB, Gitea DB | +| SQLite (내장) | 3.45.3 | JAR 내장 | 지오정보기술 홈페이지 DB | + +**PostgreSQL 데이터베이스 목록:** + +| DB 이름 | 소유자 | 용도 | +|---------|--------|------| +| `guardia_db` | guardia | GUARDiA ITSM 운영 DB | +| `zioinfo_db` | guardia | 지오정보기술 예비 DB | +| `gitea_db` | gitea | Gitea Git 서버 DB | + +### 2-4. AI / LLM + +| SW | 버전 | 설치 경로 | 용도 | +|----|------|-----------|------| +| Ollama | 0.24.0 | `/usr/local/bin/ollama` | 온프레미스 LLM 엔진 | +| Llama3:8b | — | `~/.ollama/models` | GUARDiA AI 에이전트 LLM (4.7 GB) | + +### 2-5. DevOps / CI-CD + +| SW | 버전 | 설치 경로 | 용도 | +|----|------|-----------|------| +| Gitea | 1.22.3 | `/opt/gitea/bin/gitea` | 온프레미스 Git 서버 | +| Jenkins | 2.504.1 LTS | `/opt/jenkins/jenkins.war` | CI/CD 파이프라인 (초기설정 필요) | +| ZioInfo Deploy Server | — | `/opt/zioinfo/deploy_server.py` | Gitea 웹훅 → 자동 빌드·배포 (Python) | + +### 2-6. 애플리케이션 서비스 + +| 서비스 | 기술 스택 | 버전 | 용도 | +|--------|----------|------|------| +| 지오정보기술 홈페이지 | Spring Boot 3.2.5 + React | 1.0.0 | (주)지오정보기술 기업 홈페이지 | +| GUARDiA ITSM | Python FastAPI + PostgreSQL | — | AI 기반 인프라 자율 운영 ITSM | + +--- + +## 3. 포트 구성 + +| 포트 | 프로토콜 | 서비스 | 외부 접근 | +|------|----------|--------|----------| +| 22 | TCP | SSH | ✅ 허용 (키 인증) | +| 80 | TCP | Nginx (홈페이지) | ✅ 허용 | +| 443 | TCP | HTTPS (미설정) | — | +| 3000 | TCP | Gitea Git 서버 | ✅ 허용 | +| 8001 | TCP | GUARDiA ITSM (FastAPI) | ✅ 허용 | +| 8080 | TCP | Jenkins CI/CD | ✅ 허용 | +| 8082 | TCP | Spring Boot (홈페이지 API) | ✅ 허용 | +| 8088 | TCP | Nginx → Jenkins 프록시 | ✅ 허용 | +| 9001 | TCP | Nginx → GUARDiA 프록시 | ✅ 허용 | +| 9999 | TCP | Deploy Webhook 서버 | ✅ 허용 (내부 권장) | +| 5432 | TCP | PostgreSQL | ❌ 내부 전용 (127.0.0.1) | +| 11434 | TCP | Ollama LLM API | ❌ 내부 전용 (127.0.0.1) | + +--- + +## 4. 디렉터리 구조 + +``` +/ +├── etc/ +│ ├── nginx/ +│ │ ├── sites-available/ +│ │ │ ├── zioinfo # 홈페이지 Nginx 설정 +│ │ │ ├── guardia # GUARDiA ITSM Nginx 설정 +│ │ │ ├── gitea # Gitea Nginx 설정 +│ │ │ └── jenkins # Jenkins Nginx 설정 +│ │ └── sites-enabled/ # 활성 설정 심볼릭 링크 +│ ├── gitea/ +│ │ └── app.ini # Gitea 설정 파일 +│ └── systemd/system/ +│ ├── zioinfo.service # 홈페이지 Spring Boot 서비스 +│ ├── zioinfo-deploy.service # CI/CD 웹훅 서버 +│ ├── guardia.service # GUARDiA ITSM 서비스 +│ ├── gitea.service # Gitea 서비스 +│ ├── jenkins.service # Jenkins 서비스 +│ └── ollama.service # Ollama LLM 서비스 +│ +├── opt/ +│ ├── zioinfo/ +│ │ ├── app/ +│ │ │ ├── app.jar # Spring Boot 실행 JAR +│ │ │ └── data/ # SQLite DB 디렉터리 +│ │ ├── src/ # 소스 코드 (Gitea 클론) +│ │ └── deploy_server.py # CI/CD 웹훅 서버 +│ ├── guardia/ +│ │ ├── app/ # GUARDiA ITSM 소스 +│ │ ├── venv/ # Python 가상환경 +│ │ ├── logs/ # 애플리케이션 로그 +│ │ └── uploads/ # 업로드 파일 +│ ├── gitea/ +│ │ └── bin/gitea # Gitea 바이너리 +│ └── jenkins/ +│ └── jenkins.war # Jenkins WAR 파일 +│ +├── var/ +│ ├── www/ +│ │ └── zioinfo/ # React 빌드 정적 파일 +│ ├── lib/ +│ │ ├── jenkins/ # Jenkins 홈 디렉터리 +│ │ └── gitea/ # Gitea 데이터 디렉터리 +│ │ └── data/repositories/ # Git 저장소 +│ └── log/ +│ └── zioinfo/ +│ ├── spring.log # Spring Boot 로그 +│ └── deploy.log # CI/CD 배포 로그 +│ +└── home/ + └── git/ # Gitea 시스템 사용자 홈 +``` + +--- + +## 5. 계정 및 자격증명 + +> **보안 주의**: 이 문서는 내부망 전용입니다. 외부 공개 금지. + +### 5-1. 시스템 계정 + +| 계정 | 역할 | 비밀번호 | +|------|------|---------| +| `root` | 서버 관리자 | `1q2w3e!Q` | +| `ubuntu` | 앱 실행 계정 (예비) | `ubuntu123` | +| `jenkins` | Jenkins / Spring Boot 실행 | 시스템 계정 (로그인 불가) | +| `git` | Gitea 실행 | 시스템 계정 (로그인 불가) | +| `postgres` | PostgreSQL 관리 | 시스템 계정 | + +### 5-2. 서비스 계정 + +| 서비스 | 아이디 | 비밀번호 | 권한 | +|--------|--------|---------|------| +| **홈페이지 관리자** | `admin` | `Admin@2026!` | 전체 관리 | +| **Gitea** | `zio` | `Zio@Admin2026!` | 관리자 | +| **Jenkins** | `admin` | `Admin@2026!` | 전체 | +| **PostgreSQL (guardia)** | `guardia` | `G@urd1a_2026!` | guardia_db, zioinfo_db | +| **PostgreSQL (gitea)** | `gitea` | `G1tea_2026!` | gitea_db | +| **GUARDiA ITSM** | `admin` | `Admin@2026!` | 전체 | + +### 5-3. SSH 접속 + +```bash +# PEM 키 방식 (권장) +ssh -i "zio-server-key.pem" root@zioinfo.co.kr + +# 비밀번호 방식 +ssh root@zioinfo.co.kr +# 비밀번호: 1q2w3e!Q +``` + +--- + +## 6. Python 가상환경 패키지 (GUARDiA) + +경로: `/opt/guardia/venv` + +| 패키지 | 버전 | 용도 | +|--------|------|------| +| fastapi | 0.115.0 | API 프레임워크 | +| uvicorn | 0.30.0 | ASGI 서버 | +| sqlalchemy | 2.0.35 | ORM | +| asyncpg | 0.29.0 | PostgreSQL 비동기 드라이버 | +| psycopg2-binary | 2.9.9 | PostgreSQL 드라이버 | +| paramiko | 3.4.0 | SSH/SFTP 에이전트리스 연결 | +| python-jose | 3.3.0 | JWT 인증 | +| passlib | 1.7.4 | 비밀번호 해싱 | +| openpyxl | 3.1.5 | Excel 출력 | +| cryptography | 43.0.1 | AES-256 암호화 | + +--- + +## 7. Spring Boot 의존성 (홈페이지) + +| 의존성 | 버전 | 용도 | +|--------|------|------| +| spring-boot-starter-web | 3.2.5 | REST API | +| spring-boot-starter-data-jpa | 3.2.5 | ORM | +| spring-boot-starter-security | 3.2.5 | JWT 인증 | +| spring-boot-starter-mail | 3.2.5 | 이메일 발송 | +| sqlite-jdbc | 3.45.3.0 | SQLite 드라이버 | +| jjwt-api | 0.12.3 | JWT 처리 | +| lombok | — | 코드 생성 | + +--- + +## 8. Gitea 저장소 목록 + +| 저장소 | URL | 용도 | +|--------|-----|------| +| `zio/zioinfo-web` | `http://zioinfo.co.kr:3000/zio/zioinfo-web` | 홈페이지 소스 | +| `zio/guardia-itsm` | `http://zioinfo.co.kr:3000/zio/guardia-itsm` | GUARDiA ITSM 소스 | + +--- + +## 9. 방화벽 (UFW) 규칙 + +```bash +# 현재 활성 규칙 조회 +ufw status + +# 주요 허용 포트 +22/tcp (SSH) +80/tcp (HTTP - 홈페이지) +443/tcp (HTTPS - 미사용) +3000/tcp (Gitea) +8001/tcp (GUARDiA ITSM) +8080/tcp (Jenkins) +8082/tcp (Spring Boot API) +9999/tcp (Deploy Webhook) +``` diff --git a/19_zio서버_운영가이드.md b/19_zio서버_운영가이드.md new file mode 100644 index 0000000..b34b702 --- /dev/null +++ b/19_zio서버_운영가이드.md @@ -0,0 +1,649 @@ +# zio-server 운영 가이드 + +> **서버**: zio-server | **IP**: zioinfo.co.kr +> **작성일**: 2026-05-30 | **대상**: 서버 운영자 / 개발자 + +--- + +## 1. 서비스 접속 주소 + +| 서비스 | URL | 계정 | +|--------|-----|------| +| 지오정보기술 홈페이지 | http://zioinfo.co.kr | — | +| 홈페이지 관리자 | http://zioinfo.co.kr/admin | admin / Admin@2026! | +| GUARDiA ITSM | http://zioinfo.co.kr:8001 | admin / Admin@2026! | +| Gitea (Git 서버) | http://zioinfo.co.kr:3000 | zio / Zio@Admin2026! | +| Jenkins (CI/CD) | http://zioinfo.co.kr:8080 | admin / Admin@2026! | + +--- + +## 2. 서버 접속 + +```bash +# SSH 키 인증 (권장) +ssh -i "zio-server-key.pem" root@zioinfo.co.kr + +# 비밀번호 인증 +ssh root@zioinfo.co.kr +# 비밀번호: 1q2w3e!Q +``` + +--- + +## 3. 서비스 관리 + +### 3-1. 전체 상태 확인 + +```bash +# 모든 서비스 상태 한 번에 확인 +for svc in nginx zioinfo zioinfo-deploy guardia gitea jenkins postgresql ollama; do + status=$(systemctl is-active $svc 2>/dev/null) + printf "%-22s %s\n" $svc $status +done +``` + +### 3-2. 개별 서비스 명령 + +```bash +# 서비스 시작 / 중지 / 재시작 / 상태 +systemctl start <서비스명> +systemctl stop <서비스명> +systemctl restart <서비스명> +systemctl status <서비스명> + +# 부팅 자동시작 설정 / 해제 +systemctl enable <서비스명> +systemctl disable <서비스명> +``` + +**서비스명 목록:** + +| 서비스명 | 설명 | +|---------|------| +| `nginx` | 웹 프록시 서버 | +| `zioinfo` | 지오정보기술 홈페이지 (Spring Boot, 포트 8082) | +| `zioinfo-deploy` | CI/CD 웹훅 서버 (포트 9999) | +| `guardia` | GUARDiA ITSM (FastAPI, 포트 8001) | +| `gitea` | Git 서버 (포트 3000) | +| `jenkins` | CI/CD 파이프라인 (포트 8080) | +| `postgresql` | 데이터베이스 (포트 5432) | +| `ollama` | LLM 엔진 (포트 11434) | + +--- + +## 4. 로그 확인 + +```bash +# Spring Boot 홈페이지 로그 +tail -f /var/log/zioinfo/spring.log + +# CI/CD 배포 로그 (실시간) +tail -f /var/log/zioinfo/deploy.log + +# GUARDiA ITSM 로그 +tail -f /opt/guardia/logs/guardia.log +tail -f /opt/guardia/logs/error.log + +# Nginx 접근 로그 +tail -f /var/log/nginx/access.log +tail -f /var/log/nginx/error.log + +# systemd 서비스 로그 (최근 50줄) +journalctl -u zioinfo -n 50 --no-pager +journalctl -u guardia -n 50 --no-pager +journalctl -u gitea -n 50 --no-pager + +# 실시간 로그 스트리밍 +journalctl -u zioinfo -f +``` + +--- + +## 5. 홈페이지 배포 (CI/CD) + +### 5-1. 자동 배포 흐름 + +``` +로컬 코드 수정 + ↓ +git add . && git commit -m "메시지" + ↓ +git push gitea main:main ← Gitea에 push + ↓ +Gitea 웹훅 → localhost:9999 호출 + ↓ +자동 빌드 파이프라인 실행: + ① git pull (소스 갱신) + ② npm build (React 빌드) + ③ mvn package (Spring Boot JAR 빌드) + ④ 파일 복사 (JAR → /opt/zioinfo/app, 정적 → /var/www/zioinfo) + ⑤ systemctl restart zioinfo + ↓ +배포 완료 (약 2~4분 소요) +``` + +### 5-2. 로컬에서 Gitea push + +```bash +# 최초 remote 설정 (1회) +cd workspace/zioinfo-web +git remote add gitea http://zio:Zio%40Admin2026%21@zioinfo.co.kr:3000/zio/zioinfo-web.git + +# 이후 배포 +git add . +git commit -m "feat: 변경 내용 설명" +git push gitea main:main +``` + +### 5-3. 배포 상태 모니터링 + +```bash +# 배포 로그 실시간 확인 +ssh root@zioinfo.co.kr "tail -f /var/log/zioinfo/deploy.log" + +# 배포 완료 후 서비스 상태 +ssh root@zioinfo.co.kr "systemctl is-active zioinfo && curl -s -o /dev/null -w 'HTTP %{http_code}' http://localhost:8082/api/company" +``` + +### 5-4. 수동 배포 (긴급 시) + +```bash +# 서버에서 직접 수동 배포 +ssh root@zioinfo.co.kr + +# 소스 갱신 +cd /opt/zioinfo/src && git pull origin main + +# React 빌드 +cd frontend && npm ci && npm run build + +# Spring Boot 빌드 +cd ../backend && mvn clean package -DskipTests -q + +# 배포 +cp target/zioinfo-web-*.jar /opt/zioinfo/app/app.jar +cp -r src/main/resources/static/. /var/www/zioinfo/ +systemctl restart zioinfo +``` + +--- + +## 6. GUARDiA ITSM 관리 + +### 6-1. 서비스 재시작 + +```bash +systemctl restart guardia +journalctl -u guardia -n 20 --no-pager +``` + +### 6-2. Python 패키지 업데이트 + +```bash +source /opt/guardia/venv/bin/activate +pip install -r /opt/guardia/app/requirements.txt +deactivate +systemctl restart guardia +``` + +### 6-3. 환경변수 설정 + +```bash +# .env 파일 편집 +nano /opt/guardia/app/.env + +# 주요 항목: +# DATABASE_URL=postgresql+asyncpg://guardia:G@urd1a_2026!@localhost:5432/guardia_db +# OLLAMA_BASE_URL=http://localhost:11434 +# LLM_MODEL=llama3:8b +# SECRET_KEY= +``` + +--- + +## 7. 데이터베이스 관리 + +### 7-1. PostgreSQL 접속 + +```bash +# postgres 관리자로 접속 +sudo -u postgres psql + +# guardia DB 접속 +psql -h 127.0.0.1 -U guardia -d guardia_db +비밀번호: G@urd1a_2026! + +# gitea DB 접속 +psql -h 127.0.0.1 -U gitea -d gitea_db +비밀번호: G1tea_2026! +``` + +### 7-2. 데이터베이스 백업 + +```bash +# 전체 백업 +pg_dump -U guardia guardia_db > /opt/guardia/backups/guardia_$(date +%Y%m%d).sql +pg_dump -U gitea gitea_db > /opt/gitea/backup/gitea_$(date +%Y%m%d).sql + +# 복원 +psql -U guardia guardia_db < /opt/guardia/backups/guardia_20260530.sql +``` + +### 7-3. 홈페이지 SQLite 백업 + +```bash +# SQLite DB 파일 직접 복사 +cp /opt/zioinfo/app/data/zioinfo.db /opt/zioinfo/app/data/zioinfo_$(date +%Y%m%d).db.bak +``` + +--- + +## 8. Nginx 관리 + +### 8-1. 설정 테스트 및 리로드 + +```bash +# 설정 문법 검사 +nginx -t + +# 무중단 리로드 (설정 변경 반영) +systemctl reload nginx + +# 설정 파일 위치 +ls /etc/nginx/sites-available/ +``` + +### 8-2. 사이트 설정 파일 + +| 파일 | 역할 | +|------|------| +| `/etc/nginx/sites-available/zioinfo` | 홈페이지 (포트 80 → 8082) | +| `/etc/nginx/sites-available/guardia` | GUARDiA (포트 9001 → 8001) | +| `/etc/nginx/sites-available/gitea` | Gitea (포트 3001 → 3000) | +| `/etc/nginx/sites-available/jenkins` | Jenkins (포트 8088 → 8080) | + +### 8-3. Nginx 설정 변경 절차 + +```bash +# 1. 설정 파일 편집 +nano /etc/nginx/sites-available/zioinfo + +# 2. 문법 검사 +nginx -t + +# 3. 적용 +systemctl reload nginx +``` + +--- + +## 9. Gitea 관리 + +### 9-1. 저장소 관리 + +```bash +# API로 저장소 목록 확인 +curl -s http://localhost:3000/api/v1/repos/search -u "zio:Zio@Admin2026!" \ + | python3 -c "import json,sys; [print(r['full_name']) for r in json.load(sys.stdin)['data']]" + +# 저장소 직접 경로 +ls /var/lib/gitea/data/repositories/zio/ +``` + +### 9-2. 웹훅 확인 + +```bash +# zioinfo-web 웹훅 목록 +curl -s http://localhost:3000/api/v1/repos/zio/zioinfo-web/hooks \ + -u "zio:Zio@Admin2026!" | python3 -m json.tool +``` + +### 9-3. 설정 파일 + +```bash +# Gitea 설정 편집 +nano /etc/gitea/app.ini +systemctl restart gitea +``` + +--- + +## 10. Jenkins 초기 설정 (최초 1회) + +Jenkins는 브라우저에서 초기 설정을 완료해야 합니다. + +### 10-1. 초기 설정 절차 + +1. 브라우저에서 `http://zioinfo.co.kr:8080` 접속 +2. 초기 비밀번호 입력: + ```bash + cat /var/lib/jenkins/secrets/initialAdminPassword + ``` +3. **"Install suggested plugins"** 선택 +4. 추가 플러그인 설치: + - **Pipeline** (워크플로우 파이프라인) + - **Git** (Git 연동) + - **Gitea** (Gitea 웹훅 연동) +5. 관리자 계정 생성: `admin / Admin@2026!` +6. Jenkins URL 설정: `http://zioinfo.co.kr:8080` + +### 10-2. 파이프라인 Job 생성 + +초기 설정 완료 후: + +``` +Jenkins → New Item → "zioinfo-web" → Pipeline 선택 +→ Pipeline 탭 → Definition: "Pipeline script from SCM" +→ SCM: Git +→ Repository URL: http://localhost:3000/zio/zioinfo-web.git +→ Branch: main +→ Script Path: Jenkinsfile +→ 저장 +``` + +--- + +## 11. Ollama / LLM 관리 + +### 11-1. 모델 관리 + +```bash +# 설치된 모델 목록 +ollama list + +# 모델 다운로드 (4.7GB, 시간 소요) +ollama pull llama3:8b + +# 모델 테스트 +ollama run llama3:8b "안녕하세요, 간단한 테스트입니다." + +# API 호출 테스트 +curl http://localhost:11434/api/generate \ + -d '{"model":"llama3:8b","prompt":"Hello","stream":false}' +``` + +### 11-2. 서비스 재시작 + +```bash +systemctl restart ollama +# 재시작 후 약 10~30초 대기 (모델 로딩) +``` + +--- + +## 12. 리소스 모니터링 + +### 12-1. 실시간 모니터링 + +```bash +# 전체 리소스 현황 +htop + +# 디스크 사용량 +df -h + +# 메모리 사용량 +free -h + +# 포트 사용 현황 +ss -tlnp + +# 프로세스별 리소스 +ps aux --sort=-%cpu | head -15 +ps aux --sort=-%mem | head -15 +``` + +### 12-2. 서비스별 리소스 현황 + +| 서비스 | CPU | RAM | +|--------|-----|-----| +| Nginx | ~0.1% | ~50 MB | +| Spring Boot (홈페이지) | ~0.5% | ~400 MB | +| GUARDiA ITSM (FastAPI) | ~0.5% | ~300 MB | +| PostgreSQL | ~0.3% | ~256 MB | +| Ollama + Llama3:8b | ~1.0% (유휴) | ~4.7 GB | +| Jenkins | ~0.2% | ~512 MB | +| Gitea | ~0.1% | ~150 MB | +| **합계** | **~2.7%** | **~6.4 GB** | + +--- + +## 13. 보안 운영 + +### 13-1. SSH 보안 강화 (권장) + +```bash +# root 비밀번호 로그인 비활성화 (키 인증만 허용) +sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config +systemctl restart sshd +``` + +### 13-2. 방화벽 규칙 관리 + +```bash +# 현재 규칙 확인 +ufw status numbered + +# 규칙 추가 +ufw allow <포트>/tcp + +# 규칙 삭제 +ufw delete <번호> + +# 특정 IP만 허용 (예: 관리자 IP) +ufw allow from 203.xxx.xxx.xxx to any port 8080 +``` + +### 13-3. SSL/HTTPS 설정 (도메인 보유 시) + +```bash +# Let's Encrypt 인증서 발급 +apt install certbot python3-certbot-nginx +certbot --nginx -d zioinfo.co.kr -d www.zioinfo.co.kr + +# 자동 갱신 확인 +certbot renew --dry-run +``` + +--- + +## 14. 장애 대응 + +### 14-1. 홈페이지 접속 불가 + +```bash +# 1. Nginx 상태 확인 +systemctl status nginx +nginx -t + +# 2. Spring Boot 상태 확인 +systemctl status zioinfo +curl -s http://localhost:8082/api/company + +# 3. 로그 확인 +tail -50 /var/log/zioinfo/spring.log + +# 4. 재시작 +systemctl restart zioinfo +systemctl restart nginx +``` + +### 14-2. 배포 실패 + +```bash +# 1. 배포 로그 확인 +tail -50 /var/log/zioinfo/deploy.log + +# 2. CI/CD 서버 상태 +systemctl status zioinfo-deploy + +# 3. 소스 상태 확인 +git -C /opt/zioinfo/src status +git -C /opt/zioinfo/src log --oneline -5 + +# 4. 수동 배포 실행 (5-4절 참고) +``` + +### 14-3. GUARDiA ITSM 오류 + +```bash +# 1. 서비스 상태 +systemctl status guardia +tail -20 /opt/guardia/logs/error.log + +# 2. PostgreSQL 연결 확인 +psql -h 127.0.0.1 -U guardia -d guardia_db -c "SELECT 1" + +# 3. 재시작 +systemctl restart guardia +``` + +### 14-4. 데이터베이스 연결 오류 + +```bash +# PostgreSQL 상태 +systemctl status postgresql +sudo -u postgres psql -c "\l" + +# 재시작 +systemctl restart postgresql + +# 연결 확인 +psql -h 127.0.0.1 -U guardia -d guardia_db -c "SELECT count(*) FROM pg_tables" +``` + +### 14-5. 메모리 부족 + +```bash +# 메모리 사용량 확인 +free -h +ps aux --sort=-%mem | head -10 + +# 가장 많이 사용하는 서비스 재시작 (Ollama가 대부분 점유) +systemctl restart ollama + +# Swap 임시 설정 (재부팅 시 사라짐) +fallocate -l 4G /swapfile +chmod 600 /swapfile +mkswap /swapfile +swapon /swapfile +``` + +--- + +## 15. 백업 및 복구 + +### 15-1. 정기 백업 스크립트 + +```bash +#!/bin/bash +# /opt/backup/daily_backup.sh +DATE=$(date +%Y%m%d_%H%M) +BACKUP_DIR="/opt/backup/${DATE}" +mkdir -p "$BACKUP_DIR" + +# DB 백업 +sudo -u postgres pg_dump guardia_db > "$BACKUP_DIR/guardia_db.sql" +sudo -u postgres pg_dump gitea_db > "$BACKUP_DIR/gitea_db.sql" + +# SQLite 백업 +cp /opt/zioinfo/app/data/zioinfo.db "$BACKUP_DIR/zioinfo.db" + +# 설정 파일 백업 +cp -r /etc/nginx/sites-available "$BACKUP_DIR/nginx/" +cp -r /etc/gitea "$BACKUP_DIR/gitea/" +cp /opt/guardia/app/.env "$BACKUP_DIR/guardia.env" + +# 30일 이전 백업 삭제 +find /opt/backup -maxdepth 1 -type d -mtime +30 -exec rm -rf {} \; + +echo "백업 완료: $BACKUP_DIR" +``` + +```bash +# cron 등록 (매일 새벽 2시) +crontab -e +# 추가: +0 2 * * * /opt/backup/daily_backup.sh >> /var/log/backup.log 2>&1 +``` + +--- + +## 16. 자주 쓰는 명령어 모음 + +```bash +# ── 전체 서비스 상태 ────────────────────────────── +for s in nginx zioinfo guardia gitea jenkins postgresql ollama; do + printf "%-15s %s\n" $s $(systemctl is-active $s) +done + +# ── 포트 사용 현황 ──────────────────────────────── +ss -tlnp | awk '{print $4}' | sort + +# ── 디스크 / 메모리 ────────────────────────────── +df -h / && free -h + +# ── 홈페이지 API 테스트 ─────────────────────────── +curl -s http://localhost/api/company | python3 -m json.tool + +# ── 홈페이지 관리자 로그인 테스트 ──────────────── +curl -s -X POST http://localhost/api/admin/login \ + -H "Content-Type: application/json" \ + -d '{"username":"admin","password":"Admin@2026!"}' \ + | python3 -c "import json,sys; d=json.load(sys.stdin); print('Token:', d.get('token','FAIL')[:20]+'...')" + +# ── Gitea 저장소 목록 ───────────────────────────── +curl -s http://localhost:3000/api/v1/repos/search \ + -u "zio:Zio@Admin2026!" | python3 -c \ + "import json,sys; [print(r['full_name']) for r in json.load(sys.stdin)['data']]" + +# ── 배포 수동 트리거 ───────────────────────────── +curl -s -X POST http://localhost:9999/ \ + -H "Content-Type: application/json" -d '{}' + +# ── Ollama 모델 확인 ───────────────────────────── +ollama list + +# ── 최근 에러 로그 ─────────────────────────────── +journalctl -p err --since "1 hour ago" --no-pager +``` + +--- + +## 17. 업데이트 및 유지보수 + +### 17-1. 시스템 패키지 업데이트 + +```bash +apt-get update && apt-get upgrade -y +# 주의: 업데이트 전 서비스 상태 확인 필수 +# 커널 업데이트 시 재부팅 필요 +``` + +### 17-2. 애플리케이션 업데이트 + +```bash +# Gitea 업데이트 +wget -q https://dl.gitea.com/gitea/X.X.X/gitea-X.X.X-linux-amd64 \ + -O /opt/gitea/bin/gitea +chmod +x /opt/gitea/bin/gitea +systemctl restart gitea + +# Ollama 업데이트 +curl -fsSL https://ollama.com/install.sh | sh +systemctl restart ollama +``` + +### 17-3. LLM 모델 업데이트 + +```bash +# 새 버전 모델 다운로드 +ollama pull llama3:8b + +# 구 버전 삭제 +ollama rm llama3:7b +``` + +--- + +*문서 버전: 1.0 | 최종 수정: 2026-05-30* diff --git a/20_zio서버_CICD_가이드.md b/20_zio서버_CICD_가이드.md new file mode 100644 index 0000000..8b81d64 --- /dev/null +++ b/20_zio서버_CICD_가이드.md @@ -0,0 +1,346 @@ +# zio-server CI/CD 파이프라인 가이드 + +> **서버**: zio-server | **IP**: zioinfo.co.kr +> **작성일**: 2026-05-30 + +--- + +## 1. CI/CD 아키텍처 + +``` +┌─────────────────────────────────────────────────────────┐ +│ 개발자 로컬 PC │ +│ 코드 수정 → git commit → git push gitea main:main │ +└──────────────────────┬──────────────────────────────────┘ + │ HTTP push (포트 3000) + ▼ +┌─────────────────────────────────────────────────────────┐ +│ Gitea (zioinfo.co.kr:3000) │ +│ zio/zioinfo-web 저장소 → 웹훅 트리거 │ +└──────────────────────┬──────────────────────────────────┘ + │ POST http://localhost:9999/ + ▼ +┌─────────────────────────────────────────────────────────┐ +│ ZioInfo Deploy Server (포트 9999) │ +│ /opt/zioinfo/deploy_server.py │ +│ │ +│ ① git pull (소스 최신화) │ +│ ② npm ci && npm run build (React SPA 빌드) │ +│ ③ mvn clean package (Spring Boot JAR 빌드) │ +│ ④ cp app.jar /opt/zioinfo/app/ │ +│ ⑤ cp static/* /var/www/zioinfo/ │ +│ ⑥ systemctl restart zioinfo │ +└──────────────────────┬──────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────┐ +│ Spring Boot (포트 8082) │ +│ /opt/zioinfo/app/app.jar │ +│ DB: /opt/zioinfo/app/data/zioinfo.db (SQLite) │ +└──────────────────────┬──────────────────────────────────┘ + │ proxy_pass + ▼ +┌─────────────────────────────────────────────────────────┐ +│ Nginx (포트 80) │ +│ /var/www/zioinfo/ → React SPA 정적 파일 │ +│ /api/ → localhost:8082 프록시 │ +└─────────────────────────────────────────────────────────┘ + │ + ▼ + http://zioinfo.co.kr (서비스 엔드포인트) +``` + +--- + +## 2. 로컬 개발 환경 설정 + +### 2-1. Git remote 설정 (최초 1회) + +```bash +# 현재 remote 확인 +git remote -v + +# Gitea remote 추가 +cd C:\GUARDiA\workspace\zioinfo-web +git remote add gitea http://zio:Zio%40Admin2026%21@zioinfo.co.kr:3000/zio/zioinfo-web.git + +# 설정 확인 +git remote -v +# gitea http://zio:...@zioinfo.co.kr:3000/zio/zioinfo-web.git (fetch) +# gitea http://zio:...@zioinfo.co.kr:3000/zio/zioinfo-web.git (push) +# origin https://github.com/... (fetch) ← GitHub (기존) +``` + +### 2-2. 코드 배포 + +```bash +# 1. 변경 사항 커밋 +git add . +git commit -m "feat: 기능 설명" + +# 2. Gitea에 push → 자동 빌드·배포 시작 +git push gitea main:main + +# 3. 배포 진행 상황 확인 (SSH 접속 후) +ssh root@zioinfo.co.kr "tail -f /var/log/zioinfo/deploy.log" +``` + +--- + +## 3. 배포 서버 구성 + +### 3-1. 파일 위치 + +| 파일 | 경로 | 설명 | +|------|------|------| +| 배포 스크립트 | `/opt/zioinfo/deploy_server.py` | 웹훅 수신 + 빌드·배포 실행 | +| 소스 코드 | `/opt/zioinfo/src/` | Gitea 클론 경로 | +| 실행 JAR | `/opt/zioinfo/app/app.jar` | 배포된 Spring Boot JAR | +| 정적 파일 | `/var/www/zioinfo/` | 배포된 React 빌드 결과물 | +| 배포 로그 | `/var/log/zioinfo/deploy.log` | 빌드·배포 과정 기록 | + +### 3-2. systemd 서비스 + +```ini +# /etc/systemd/system/zioinfo-deploy.service +[Unit] +Description=ZioInfo CI/CD Webhook Server +After=network.target + +[Service] +User=root +ExecStart=/usr/bin/python3 /opt/zioinfo/deploy_server.py +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +``` + +```bash +# 서비스 관리 +systemctl status zioinfo-deploy +systemctl restart zioinfo-deploy +journalctl -u zioinfo-deploy -n 20 --no-pager +``` + +### 3-3. 웹훅 보안 + +배포 서버는 HMAC-SHA256으로 요청을 검증합니다. + +```python +# 검증 키: zioinfo-deploy-2026 +# Gitea 웹훅 설정의 Secret 값과 동일 +``` + +--- + +## 4. Gitea 웹훅 설정 + +### 4-1. 현재 웹훅 확인 + +```bash +# API로 웹훅 목록 조회 +curl -s http://localhost:3000/api/v1/repos/zio/zioinfo-web/hooks \ + -u "zio:Zio@Admin2026!" | python3 -m json.tool + +# 브라우저에서 확인 +# http://zioinfo.co.kr:3000/zio/zioinfo-web/settings/hooks +``` + +### 4-2. 웹훅 재등록 (필요 시) + +```bash +# 기존 웹훅 삭제 +curl -s -X DELETE http://localhost:3000/api/v1/repos/zio/zioinfo-web/hooks/1 \ + -u "zio:Zio@Admin2026!" + +# 새 웹훅 등록 (Python) +python3 << 'EOF' +import urllib.request, json, base64 + +data = json.dumps({ + "type": "gitea", + "active": True, + "config": { + "url": "http://localhost:9999/", + "content_type": "json", + "secret": "zioinfo-deploy-2026" + }, + "events": ["push"] +}).encode() + +cred = base64.b64encode(b"zio:Zio@Admin2026!").decode() +req = urllib.request.Request( + "http://localhost:3000/api/v1/repos/zio/zioinfo-web/hooks", + data=data, + headers={"Content-Type": "application/json", "Authorization": f"Basic {cred}"}) +resp = urllib.request.urlopen(req) +d = json.loads(resp.read()) +print(f"Webhook ID: {d.get('id')}") +EOF +``` + +--- + +## 5. 배포 이력 및 롤백 + +### 5-1. 배포 이력 확인 + +```bash +# Gitea 커밋 이력 +curl -s "http://localhost:3000/api/v1/repos/zio/zioinfo-web/commits?limit=10" \ + -u "zio:Zio@Admin2026!" | python3 -c " +import json, sys +commits = json.load(sys.stdin) +for c in commits: + print(c['sha'][:8], c['commit']['message'][:60], '|', c['commit']['author']['date'][:10]) +" + +# 서버 소스 로컬 이력 +ssh root@zioinfo.co.kr "git -C /opt/zioinfo/src log --oneline -10" +``` + +### 5-2. 특정 버전으로 롤백 + +```bash +ssh root@zioinfo.co.kr + +# 이전 커밋으로 체크아웃 +cd /opt/zioinfo/src +git log --oneline -5 # 커밋 해시 확인 +git checkout <커밋해시> # 원하는 버전으로 변경 + +# 빌드 및 재배포 +cd frontend && npm ci && npm run build +cd ../backend && mvn clean package -DskipTests -q +cp target/zioinfo-web-*.jar /opt/zioinfo/app/app.jar +cp -r src/main/resources/static/. /var/www/zioinfo/ +systemctl restart zioinfo + +# 최신 버전으로 복구 +git checkout main +``` + +--- + +## 6. Jenkins 파이프라인 (심화 설정) + +> Jenkins 초기 설정 완료 후 사용 가능 + +### 6-1. Jenkinsfile 위치 + +``` +workspace/zioinfo-web/Jenkinsfile (홈페이지 파이프라인) +itsm/Jenkinsfile (GUARDiA ITSM 파이프라인) +``` + +### 6-2. 홈페이지 Jenkinsfile 주요 단계 + +```groovy +pipeline { + agent any + stages { + stage('Frontend Build') { /* npm ci + npm run build */ } + stage('Backend Build') { /* mvn clean package */ } + stage('Test') { /* mvn test */ } + stage('Deploy') { + when { branch 'main' } + /* JAR 복사 + 정적파일 배포 + systemctl restart */ + } + } +} +``` + +### 6-3. Jenkins Job 수동 트리거 + +```bash +# Jenkins API로 빌드 트리거 (초기 설정 완료 후) +CRUMB=$(curl -s -u admin:Admin@2026! \ + http://localhost:8080/crumbIssuer/api/json | python3 -c \ + "import json,sys; print(json.load(sys.stdin)['crumb'])") + +curl -u admin:Admin@2026! -X POST \ + http://localhost:8080/job/zioinfo-web/build \ + -H "Jenkins-Crumb: $CRUMB" +``` + +--- + +## 7. 트러블슈팅 + +### 7-1. push 후 자동 배포가 안 될 때 + +```bash +# 1. 웹훅 서버 상태 확인 +systemctl is-active zioinfo-deploy + +# 2. 웹훅 서버 로그 +journalctl -u zioinfo-deploy -n 20 --no-pager + +# 3. 수동 트리거 테스트 +curl -s -X POST http://localhost:9999/ \ + -H "Content-Type: application/json" -d '{}' + +# 4. 배포 로그 실시간 확인 +tail -f /var/log/zioinfo/deploy.log +``` + +### 7-2. 빌드 실패 시 + +```bash +# 빌드 로그에서 오류 확인 +grep -i "error\|failed\|fail" /var/log/zioinfo/deploy.log | tail -20 + +# npm 빌드 오류 재현 +cd /opt/zioinfo/src/frontend +npm ci --legacy-peer-deps +npm run build + +# Maven 빌드 오류 재현 +cd /opt/zioinfo/src/backend +mvn clean package -DskipTests +``` + +### 7-3. Spring Boot 재시작 실패 + +```bash +# 상세 로그 확인 +journalctl -u zioinfo --since "5 minutes ago" --no-pager +tail -50 /var/log/zioinfo/spring.log + +# 포트 충돌 확인 (8082) +ss -tlnp | grep 8082 +kill -9 # 기존 프로세스 강제 종료 + +# 수동 실행 (디버깅) +java -jar /opt/zioinfo/app/app.jar --server.port=8082 +``` + +--- + +## 8. GUARDiA ITSM 배포 + +> GUARDiA는 별도 Jenkinsfile 기반 파이프라인 사용 + +### 8-1. 수동 배포 + +```bash +# Gitea에서 최신 코드 반영 +cd /opt/guardia/app +git pull http://zio:Zio%40Admin2026%21@localhost:3000/zio/guardia-itsm.git main + +# 패키지 업데이트 +/opt/guardia/venv/bin/pip install -r requirements.txt -q + +# 서비스 재시작 +systemctl restart guardia +sleep 3 && systemctl is-active guardia + +# 헬스체크 +curl -s http://localhost:8001/docs -o /dev/null -w "HTTP %{http_code}" +``` + +--- + +*문서 버전: 1.0 | 최종 수정: 2026-05-30* diff --git a/21_zio서버_장애대응_가이드.md b/21_zio서버_장애대응_가이드.md new file mode 100644 index 0000000..1a738b8 --- /dev/null +++ b/21_zio서버_장애대응_가이드.md @@ -0,0 +1,409 @@ +# zio-server 장애 대응 가이드 (Runbook) + +> **서버**: zio-server | **IP**: zioinfo.co.kr +> **작성일**: 2026-05-30 +> **목적**: 장애 발생 시 빠른 진단과 복구를 위한 단계별 절차서 + +--- + +## 긴급 연락 및 접속 + +```bash +# 즉시 서버 접속 +ssh -i "zio-server-key.pem" root@zioinfo.co.kr +# 또는 +ssh root@zioinfo.co.kr # 비밀번호: 1q2w3e!Q +``` + +--- + +## 1. 빠른 현황 진단 (첫 번째로 실행) + +```bash +#!/bin/bash +echo "=== 서비스 상태 ===" +for s in nginx zioinfo zioinfo-deploy guardia gitea jenkins postgresql ollama; do + status=$(systemctl is-active $s 2>/dev/null) + icon="✅"; [ "$status" != "active" ] && icon="❌" + printf "%s %-22s %s\n" "$icon" "$s" "$status" +done + +echo "" +echo "=== 리소스 ===" +free -h | grep Mem +df -h / | tail -1 + +echo "" +echo "=== 최근 에러 ===" +journalctl -p err --since "30 minutes ago" --no-pager | tail -10 +``` + +--- + +## 2. 장애 유형별 대응 + +--- + +### CASE 1: 홈페이지(http://zioinfo.co.kr) 접속 불가 + +**증상**: 브라우저에서 접속 시 연결 거부 또는 502 오류 + +```bash +# Step 1: Nginx 확인 +systemctl is-active nginx || { + nginx -t && systemctl start nginx + echo "Nginx 재시작" +} + +# Step 2: Nginx 502 (백엔드 응답 없음) +curl -s -o /dev/null -w "%{http_code}" http://localhost:8082/api/company +# → 000 또는 연결 실패 시: Spring Boot 재시작 +systemctl restart zioinfo +sleep 8 +systemctl is-active zioinfo + +# Step 3: Spring Boot 로그 확인 +tail -30 /var/log/zioinfo/spring.log + +# Step 4: 포트 확인 +ss -tlnp | grep -E ":(80|8082)" + +# 완료 확인 +curl -s -o /dev/null -w "홈페이지: HTTP %{http_code}\n" http://localhost/ +``` + +**예상 복구 시간**: 1~3분 + +--- + +### CASE 2: 관리자 페이지(/admin) 로그인 불가 + +**증상**: admin/Admin@2026! 로그인 실패 또는 JWT 오류 + +```bash +# Step 1: Spring Boot API 응답 확인 +curl -s -X POST http://localhost/api/admin/login \ + -H "Content-Type: application/json" \ + -d '{"username":"admin","password":"Admin@2026!"}' | python3 -m json.tool + +# Step 2: 401 Unauthorized → 계정 확인 +# SQLite DB 접속 +sqlite3 /opt/zioinfo/app/data/zioinfo.db "SELECT username, enabled FROM admin_user;" + +# Step 3: 계정 비활성화 시 활성화 +sqlite3 /opt/zioinfo/app/data/zioinfo.db \ + "UPDATE admin_user SET enabled=1 WHERE username='admin';" + +# Step 4: Spring Boot 재시작 +systemctl restart zioinfo +``` + +--- + +### CASE 3: GUARDiA ITSM(포트 8001) 응답 없음 + +**증상**: `http://zioinfo.co.kr:8001` 접속 불가 + +```bash +# Step 1: 서비스 상태 +systemctl status guardia + +# Step 2: 로그 확인 +tail -30 /opt/guardia/logs/error.log + +# Step 3: PostgreSQL 연결 확인 +systemctl is-active postgresql || systemctl start postgresql +psql -h 127.0.0.1 -U guardia -d guardia_db -c "SELECT 1" 2>&1 + +# Step 4: GUARDiA 재시작 +systemctl restart guardia +sleep 5 + +# Step 5: FastAPI 응답 확인 +curl -s -o /dev/null -w "GUARDiA: HTTP %{http_code}\n" http://localhost:8001/docs +``` + +**예상 복구 시간**: 2~5분 + +--- + +### CASE 4: PostgreSQL 연결 오류 + +**증상**: GUARDiA 또는 Gitea에서 DB 연결 실패 로그 + +```bash +# Step 1: 상태 확인 +systemctl status postgresql + +# Step 2: 재시작 +systemctl restart postgresql +sleep 3 + +# Step 3: 연결 테스트 +sudo -u postgres psql -c "\l" 2>&1 + +# Step 4: 로그 확인 +tail -20 /var/log/postgresql/postgresql-16-main.log + +# Step 5: DB 접속 정상화 확인 +psql -h 127.0.0.1 -U guardia -d guardia_db -c "SELECT count(*) FROM pg_tables" +``` + +--- + +### CASE 5: CI/CD 배포 실패 + +**증상**: `git push` 후 변경 내용이 적용되지 않음 + +```bash +# Step 1: 웹훅 서버 상태 +systemctl is-active zioinfo-deploy +journalctl -u zioinfo-deploy -n 20 --no-pager + +# Step 2: 배포 로그 확인 +tail -50 /var/log/zioinfo/deploy.log + +# 오류 유형별 대응: +# [git pull] 실패 → 네트워크 또는 Gitea 확인 +systemctl is-active gitea +curl -s http://localhost:3000/api/v1/version -u "zio:Zio@Admin2026!" + +# [npm build] 실패 → node_modules 재설치 +cd /opt/zioinfo/src/frontend && rm -rf node_modules && npm install --legacy-peer-deps + +# [mvn package] 실패 → Maven 캐시 클리어 +cd /opt/zioinfo/src/backend && mvn clean -q + +# Step 3: 수동 배포 실행 +cd /opt/zioinfo/src +git pull origin main +cd frontend && npm ci && npm run build +cd ../backend && mvn clean package -DskipTests -q +cp target/zioinfo-web-*.jar /opt/zioinfo/app/app.jar +cp -r src/main/resources/static/. /var/www/zioinfo/ +systemctl restart zioinfo +``` + +--- + +### CASE 6: Gitea 접속 불가 (포트 3000) + +**증상**: `http://zioinfo.co.kr:3000` 접속 불가 + +```bash +# Step 1: 서비스 상태 +systemctl status gitea +journalctl -u gitea -n 20 --no-pager + +# Step 2: PostgreSQL 확인 (Gitea DB 의존) +systemctl is-active postgresql + +# Step 3: 재시작 +systemctl restart gitea +sleep 5 +curl -s -o /dev/null -w "Gitea: HTTP %{http_code}\n" http://localhost:3000/ +``` + +--- + +### CASE 7: 서버 메모리 부족 (OOM) + +**증상**: 서비스 갑자기 종료, journalctl에서 OOM killer 메시지 + +```bash +# Step 1: 메모리 현황 +free -h +dmesg | grep -i "oom" | tail -10 + +# Step 2: 메모리 사용량 상위 프로세스 +ps aux --sort=-%mem | head -10 + +# Step 3: Ollama가 주요 원인 (4.7GB 점유) +# 사용 안 할 때 중지 +systemctl stop ollama + +# Step 4: 필수 서비스 재시작 +for s in nginx zioinfo guardia postgresql gitea; do + systemctl is-active $s || systemctl start $s +done + +# Step 5: 임시 스왑 설정 (재부팅 시 사라짐) +[ ! -f /swapfile ] && { + fallocate -l 2G /swapfile + chmod 600 /swapfile + mkswap /swapfile + swapon /swapfile + echo "2GB 스왑 설정 완료" +} +free -h +``` + +--- + +### CASE 8: 디스크 용량 부족 + +**증상**: 로그 쓰기 실패, DB 오류 + +```bash +# Step 1: 디스크 현황 +df -h +du -sh /var/log/* 2>/dev/null | sort -rh | head -10 +du -sh /opt/* 2>/dev/null | sort -rh | head -10 + +# Step 2: 로그 정리 +# journald 로그 정리 +journalctl --vacuum-size=500M + +# Nginx 로그 압축 +gzip /var/log/nginx/access.log.1 2>/dev/null +gzip /var/log/nginx/error.log.1 2>/dev/null + +# 오래된 배포 로그 정리 +find /var/log/zioinfo -name "*.log" -mtime +30 -delete + +# Maven 캐시 정리 (~/.m2) +rm -rf /var/lib/jenkins/.m2/repository/*/ + +# npm 캐시 정리 +npm cache clean --force 2>/dev/null + +# Step 3: PostgreSQL 로그 정리 +find /var/log/postgresql -name "*.log" -mtime +7 -delete + +# Step 4: 확인 +df -h +``` + +--- + +### CASE 9: Jenkins 응답 없음 (포트 8080) + +```bash +# Step 1: 상태 확인 +systemctl status jenkins +curl -s -o /dev/null -w "Jenkins: HTTP %{http_code}\n" http://localhost:8080/ + +# Step 2: 재시작 +systemctl restart jenkins +sleep 10 +systemctl is-active jenkins + +# Step 3: Java 힙 부족 시 메모리 조정 +# /etc/default/jenkins 편집 +echo 'JAVA_ARGS="-Xmx512m -Xms256m"' >> /etc/default/jenkins +systemctl restart jenkins +``` + +--- + +### CASE 10: SSH 접속 불가 + +```bash +# 다른 방법으로 접속 (NCloud 콘솔에서 시리얼 콘솔 사용) +# 또는 NCloud 포털 → 서버 → 콘솔 접속 + +# SSH 서비스 재시작 (서버 콘솔에서) +systemctl restart sshd +systemctl is-active sshd + +# 방화벽 SSH 허용 확인 +ufw allow 22/tcp +ufw status | grep 22 +``` + +--- + +## 3. 서버 재부팅 후 복구 절차 + +```bash +# 재부팅 후 전체 서비스 자동 시작 확인 +systemctl list-units --type=service --state=failed + +# 실패한 서비스가 있을 경우 개별 재시작 +systemctl start <서비스명> + +# 모든 서비스 한번에 시작 +for s in postgresql gitea nginx zioinfo zioinfo-deploy guardia ollama jenkins; do + systemctl is-active $s || { + echo "Starting $s..." + systemctl start $s + sleep 2 + } +done + +# 전체 헬스체크 +echo "=== 재부팅 후 헬스체크 ===" +curl -s -o /dev/null -w "홈페이지: HTTP %{http_code}\n" http://localhost/ +curl -s -o /dev/null -w "API: HTTP %{http_code}\n" http://localhost/api/company +curl -s -o /dev/null -w "GUARDiA: HTTP %{http_code}\n" http://localhost:8001/docs +curl -s -o /dev/null -w "Gitea: HTTP %{http_code}\n" http://localhost:3000/ +curl -s -o /dev/null -w "Jenkins: HTTP %{http_code}\n" http://localhost:8080/ +``` + +--- + +## 4. 정기 점검 체크리스트 + +```bash +#!/bin/bash +# 주 1회 실행 권장 +echo "===== zio-server 정기 점검 =====" +echo "점검일: $(date)" +echo "" + +echo "[ 서비스 상태 ]" +for s in nginx zioinfo zioinfo-deploy guardia gitea jenkins postgresql ollama; do + status=$(systemctl is-active $s) + printf " %-20s %s\n" $s $status +done + +echo "" +echo "[ 리소스 현황 ]" +echo " 디스크: $(df -h / | tail -1 | awk '{print $3"/"$2" ("$5")"}')" +echo " 메모리: $(free -h | grep Mem | awk '{print $3"/"$2}')" +echo " 스왑: $(free -h | grep Swap | awk '{print $3"/"$2}')" + +echo "" +echo "[ 응답 테스트 ]" +for url in \ + "http://localhost/:홈페이지" \ + "http://localhost/api/company:API" \ + "http://localhost:8001/docs:GUARDiA" \ + "http://localhost:3000/:Gitea" \ + "http://localhost:8080/:Jenkins"; do + url_part="${url%%:*}" + name="${url##*:}" + code=$(curl -s -o /dev/null -w "%{http_code}" "$url_part" 2>/dev/null) + icon="✅"; [[ "$code" != "200" && "$code" != "302" ]] && icon="❌" + printf " %s %-12s HTTP %s\n" "$icon" "$name" "$code" +done + +echo "" +echo "[ 최근 에러 로그 (1시간) ]" +journalctl -p err --since "1 hour ago" --no-pager 2>/dev/null | grep -v "^--" | tail -5 || echo " 없음" + +echo "" +echo "[ Gitea 저장소 ]" +curl -s http://localhost:3000/api/v1/repos/search -u "zio:Zio@Admin2026!" 2>/dev/null | \ + python3 -c "import json,sys; [print(' '+r['full_name']) for r in json.load(sys.stdin)['data']]" 2>/dev/null + +echo "" +echo "[ PostgreSQL DB 상태 ]" +sudo -u postgres psql -c "\l" 2>/dev/null | grep -E "(guardia|gitea|zioinfo)" | awk '{print " "$1}' + +echo "=============================" +``` + +--- + +## 5. 긴급 연락처 및 에스컬레이션 + +| 단계 | 담당 | 연락처 | 조건 | +|------|------|--------|------| +| L1 | 운영팀 | — | 서비스 재시작으로 해결 가능 | +| L2 | 개발팀 | — | 코드/설정 변경 필요 | +| L3 | NCloud 지원 | 1544-5117 | 서버 하드웨어/네트워크 장애 | + +--- + +*문서 버전: 1.0 | 최종 수정: 2026-05-30* diff --git a/22_GUARDiA_개방망_운영가이드.md b/22_GUARDiA_개방망_운영가이드.md new file mode 100644 index 0000000..5a3871c --- /dev/null +++ b/22_GUARDiA_개방망_운영가이드.md @@ -0,0 +1,454 @@ +# GUARDiA ITSM 개방망 운영 가이드 + +> **버전**: 2.0.0 | **작성일**: 2026-05-30 +> **서버**: zio-server (zioinfo.co.kr) + +--- + +## 1. 개요 + +GUARDiA ITSM은 기본적으로 **폐쇄망(Closed Network)** 환경에서 동작하도록 설계되어 있습니다. +본 가이드는 GUARDiA를 **개방망(Open Network)** 에서도 안전하게 서비스하기 위한 구성 방법을 설명합니다. + +### 1-1. 폐쇄망 vs 개방망 비교 + +| 항목 | 폐쇄망 (기본) | 개방망 (이 가이드) | +|------|-------------|----------------| +| 접근 범위 | 내부망 only | 인터넷 외부 접근 허용 | +| CORS | localhost 만 허용 | 지정 외부 도메인 허용 | +| HTTPS | 선택 | **필수** | +| API 인증 | JWT | JWT + **API Key** 추가 | +| 외부 AI 호출 | 금지 (Ollama only) | 금지 유지 (변경 불가) | +| Rate Limiting | 기본 | **강화** (30req/min) | +| 보안 헤더 | 기본 | HSTS 포함 강화 | + +### 1-2. 개방망 지원 아키텍처 + +``` +외부 클라이언트 (브라우저, 메신저봇, 외부시스템) + │ + │ HTTPS (443 / 8443) + ▼ +┌─────────────────────────────────────────────────┐ +│ Nginx (TLS 종료 프록시) │ +│ ├── SSL/TLS (자체서명 or Let's Encrypt) │ +│ ├── Rate Limiting (30 req/min) │ +│ ├── 보안 헤더 (HSTS, X-Frame, X-XSS) │ +│ └── CORS 정책 적용 │ +└─────────────────┬───────────────────────────────┘ + │ HTTP (내부) + ▼ +┌─────────────────────────────────────────────────┐ +│ GUARDiA ITSM FastAPI (포트 8001) │ +│ ├── GUARDIA_NETWORK_MODE=open │ +│ ├── CORS: 지정 외부 도메인 허용 │ +│ ├── 보안 미들웨어 (HSTS, X-Frame, CSP) │ +│ └── /api/external/* (API Key 인증) │ +└─────────────────┬───────────────────────────────┘ + │ + ┌───────┴────────┐ + ▼ ▼ + PostgreSQL Ollama LLM + (내부 전용) (내부 전용) + localhost:5432 localhost:11434 +``` + +> **핵심 원칙**: LLM(Ollama)과 DB는 외부에서 직접 접근 불가. API 서버만 노출. + +--- + +## 2. 설치 및 구성 + +### 2-1. 사전 요구사항 + +| 항목 | 요구 사항 | +|------|---------| +| OS | Ubuntu 20.04+ | +| Nginx | 1.18+ | +| SSL 인증서 | 자체서명 or Let's Encrypt | +| GUARDiA | 2.0.0+ | +| Python | 3.11+ | + +### 2-2. SSL 인증서 생성 + +**자체 서명 인증서 (테스트/내부망):** +```bash +mkdir -p /etc/ssl/guardia +openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ + -keyout /etc/ssl/guardia/server.key \ + -out /etc/ssl/guardia/server.crt \ + -subj "/C=KR/ST=Seoul/O=YourOrg/CN=your-server-ip" \ + -addext "subjectAltName=IP:zioinfo.co.kr" +chmod 600 /etc/ssl/guardia/server.key +``` + +**Let's Encrypt (도메인 보유 시 — 권장):** +```bash +apt install certbot python3-certbot-nginx +certbot --nginx -d itsm.zioinfo.co.kr +# 자동 갱신 확인 +certbot renew --dry-run +``` + +### 2-3. 환경변수 설정 (.env) + +```bash +cp /opt/guardia/app/.env.open /opt/guardia/app/.env +nano /opt/guardia/app/.env +``` + +**개방망 필수 설정:** +```env +# 개방망 모드 활성화 +GUARDIA_NETWORK_MODE=open + +# 허용할 외부 출처 (쉼표 구분) +GUARDIA_ALLOWED_ORIGINS=https://itsm.zioinfo.co.kr,https://portal.myorg.go.kr + +# 웹훅 HMAC 시크릿 (반드시 변경) +GUARDIA_WEBHOOK_SECRET=your-strong-secret-here + +# DB (특수문자 URL 인코딩 필수: @ → %40, ! → %21) +DATABASE_URL=postgresql+asyncpg://guardia:G%40urd1a_2026%21@localhost:5432/guardia_db + +# LLM (내부 전용 — 절대 변경 금지) +OLLAMA_BASE_URL=http://localhost:11434 +LLM_MODEL=llama3:8b +``` + +### 2-4. Nginx 개방망 설정 + +```bash +# Nginx http 블록에 rate limit zone 추가 +nano /etc/nginx/nginx.conf +``` + +```nginx +http { + limit_req_zone $binary_remote_addr zone=guardia_api:10m rate=30r/m; + ... +} +``` + +**`/etc/nginx/sites-available/guardia-https`** 생성: +```nginx +server { + listen 8443 ssl; + server_name _; + + ssl_certificate /etc/ssl/guardia/server.crt; + ssl_certificate_key /etc/ssl/guardia/server.key; + ssl_protocols TLSv1.2 TLSv1.3; + + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header X-Frame-Options DENY always; + add_header X-Content-Type-Options nosniff always; + + location /api/ { + limit_req zone=guardia_api burst=10 nodelay; + proxy_pass http://127.0.0.1:8001; + proxy_set_header X-Forwarded-Proto https; + } + location / { + proxy_pass http://127.0.0.1:8001; + } +} +``` + +```bash +ln -sf /etc/nginx/sites-available/guardia-https /etc/nginx/sites-enabled/ +nginx -t && systemctl reload nginx +``` + +### 2-5. 서비스 재시작 + +```bash +systemctl restart guardia +systemctl is-active guardia +``` + +--- + +## 3. 외부 API 사용법 + +### 3-1. API 엔드포인트 목록 + +| 엔드포인트 | 메서드 | 인증 | 설명 | +|-----------|--------|------|------| +| `/api/external/health` | GET | 불필요 | 헬스체크 | +| `/api/external/status` | GET | 불필요 | 시스템 공개 상태 | +| `/api/external/keys` | GET | JWT (관리자) | API Key 목록 | +| `/api/external/keys` | POST | JWT (관리자) | API Key 발급 | +| `/api/external/keys/{id}` | DELETE | JWT (관리자) | API Key 비활성화 | +| `/api/external/sr` | GET | API Key (read) | SR 목록 조회 | +| `/api/external/sr` | POST | API Key (write) | SR 등록 | +| `/api/external/webhook` | POST | HMAC (선택) | 외부 메신저 웹훅 | +| `/docs` | GET | 불필요 | OpenAPI 문서 | + +### 3-2. API Key 발급 + +**1단계: 관리자 로그인 (JWT 획득)** +```bash +curl -X POST https://zioinfo.co.kr:8443/api/auth/login \ + -H "Content-Type: application/json" \ + -d '{"username":"admin","password":"Admin@zioinfo2026!"}' \ + -k +# → {"access_token": "eyJ...", "token_type": "bearer"} +``` + +**2단계: API Key 발급** +```bash +TOKEN="eyJ..." +curl -X POST https://zioinfo.co.kr:8443/api/external/keys \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "카카오워크 봇", + "scopes": "read,write,webhook", + "expires_days": 365, + "allowed_ips": "" + }' -k +``` + +**응답 (발급 후 1회만 노출):** +```json +{ + "id": 1, + "name": "카카오워크 봇", + "api_key": "grd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "scopes": "read,write,webhook", + "expires_at": "2027-05-30T10:00:00", + "warning": "이 키는 다시 조회할 수 없습니다. 안전한 곳에 저장하세요." +} +``` + +### 3-3. API Key로 SR 등록 + +```bash +API_KEY="grd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# SR 등록 +curl -X POST https://zioinfo.co.kr:8443/api/external/sr \ + -H "X-API-Key: $API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "title": "웹서버 재시작 요청", + "description": "nginx가 502 오류를 반환하고 있습니다.", + "priority": "HIGH", + "requester_name": "홍길동", + "requester_email": "hong@example.go.kr" + }' -k +``` + +### 3-4. 외부 메신저 웹훅 연동 + +```bash +# Gitea/Slack/카카오워크 웹훅 URL 설정 +WEBHOOK_URL="https://zioinfo.co.kr:8443/api/external/webhook" +SECRET="guardia-webhook-secret-change-me-2026" + +# 서명 생성 (Python) +python3 -c " +import hmac, hashlib, json +body = json.dumps({'command': '서버 상태 확인', 'user_id': 'user01'}) +sig = 'sha256=' + hmac.new(b'$SECRET', body.encode(), hashlib.sha256).hexdigest() +print(sig) +" + +# 웹훅 전송 +curl -X POST $WEBHOOK_URL \ + -H "Content-Type: application/json" \ + -H "X-GUARDiA-Signature: sha256=<서명값>" \ + -H "X-Source: kakaotalk" \ + -d '{"command": "서버 상태 확인", "user_id": "홍길동"}' \ + -k +``` + +--- + +## 4. API Key 권한 스코프 + +| 스코프 | 설명 | 허용 API | +|--------|------|---------| +| `read` | 읽기 전용 | SR 목록 조회 | +| `write` | 쓰기 | SR 등록, 상태 변경 | +| `admin` | 전체 권한 | 모든 외부 API | +| `webhook` | 웹훅 전용 | `/api/external/webhook` | + +**스코프 조합 예시:** +```json +"scopes": "read,write" // 조회 + 등록 +"scopes": "webhook" // 웹훅만 +"scopes": "admin" // 전체 (주의) +``` + +--- + +## 5. 보안 설정 + +### 5-1. 적용된 보안 헤더 + +| 헤더 | 값 | 효과 | +|------|-----|------| +| `Strict-Transport-Security` | `max-age=31536000` | 브라우저가 HTTPS만 사용 | +| `X-Frame-Options` | `DENY` | iframe 삽입 차단 | +| `X-Content-Type-Options` | `nosniff` | MIME 타입 스니핑 방지 | +| `X-XSS-Protection` | `1; mode=block` | XSS 공격 차단 | +| `Referrer-Policy` | `strict-origin-when-cross-origin` | Referrer 정보 제한 | + +### 5-2. Rate Limiting 설정 + +| 위치 | 제한 | +|------|------| +| Nginx (기본) | 30 req/min per IP | +| Nginx (burst) | 최대 10 req 버스트 허용 | +| FastAPI (ratelimit.py) | 별도 설정 가능 | + +### 5-3. IP 화이트리스트 (API Key) + +특정 외부 시스템만 API Key를 사용할 수 있도록 IP를 제한할 수 있습니다: + +```json +{ + "name": "공공기관 포털", + "scopes": "read,write", + "allowed_ips": "203.10.20.30,203.10.20.31" +} +``` + +빈 문자열(`""`)로 설정하면 모든 IP에서 접근 가능합니다. + +### 5-4. 변경 불가 보안 정책 + +> 개방망 모드에서도 다음 정책은 절대 변경 불가합니다. + +| 정책 | 내용 | +|------|------| +| **외부 LLM 금지** | Ollama(localhost:11434)만 사용. OpenAI, Claude 등 외부 API 완전 금지 | +| **SSH 자격증명 보호** | IP, 비밀번호, SSH 계정을 API 응답에 포함 금지 | +| **AES-256 암호화** | 서버 자격증명은 암호화 저장 | +| **root SSH 금지** | opsagent 전용 계정 사용 | + +--- + +## 6. 모드 전환 + +### 6-1. 폐쇄망 → 개방망 + +```bash +# .env 수정 +echo "GUARDIA_NETWORK_MODE=open" >> /opt/guardia/app/.env +echo "GUARDIA_ALLOWED_ORIGINS=https://your-domain.go.kr" >> /opt/guardia/app/.env + +# Nginx HTTPS 활성화 +ln -sf /etc/nginx/sites-available/guardia-https /etc/nginx/sites-enabled/ +nginx -t && systemctl reload nginx + +# 서비스 재시작 +systemctl restart guardia +``` + +### 6-2. 개방망 → 폐쇄망 (롤백) + +```bash +# .env 수정 +sed -i 's/GUARDIA_NETWORK_MODE=open/GUARDIA_NETWORK_MODE=closed/' /opt/guardia/app/.env + +# HTTPS 비활성화 +rm /etc/nginx/sites-enabled/guardia-https +systemctl reload nginx + +# 서비스 재시작 +systemctl restart guardia +``` + +--- + +## 7. 테스트 결과 + +### 7-1. 테스트 환경 + +| 항목 | 값 | +|------|-----| +| 서버 | Ubuntu 24.04 LTS (zioinfo.co.kr) | +| GUARDiA 버전 | 2.0.0 | +| Nginx 버전 | 1.24.0 | +| 테스트 일자 | 2026-05-30 | + +### 7-2. 테스트 결과 + +| 테스트 | 항목 | 결과 | +|--------|------|------| +| T1 | HTTP 헬스체크 (8001) | ✅ HTTP 200 | +| T2 | HTTPS 헬스체크 (8443) | ✅ HTTP 200 | +| T3 | 홈페이지 HTTPS (443) | ✅ HTTP 200 | +| T4 | 미인증 API 접근 | ✅ HTTP 401 반환 | +| T5 | CORS 외부 출처 허용 | ✅ `Access-Control-Allow-Origin` 헤더 | +| T6 | HSTS 헤더 | ✅ `Strict-Transport-Security` 적용 | +| T7 | X-Frame-Options | ✅ `DENY` 설정 | +| T8 | Rate Limiting | ✅ Nginx rate limit zone 설정 | +| T9 | 시스템 상태 공개 | ✅ `operational` | +| T10 | 개방망 모드 활성 | ✅ `NETWORK_MODE=open` | + +--- + +## 8. 트러블슈팅 + +### 8-1. CORS 오류 + +**증상**: 브라우저에서 `Access-Control-Allow-Origin` 오류 + +```bash +# .env에 도메인 추가 +GUARDIA_ALLOWED_ORIGINS=https://your-domain.com,https://other-domain.go.kr +systemctl restart guardia +``` + +### 8-2. HTTPS 인증서 오류 + +**증상**: `SSL: CERTIFICATE_VERIFY_FAILED` + +```bash +# 자체서명 인증서인 경우 curl에 -k 플래그 사용 +curl -k https://zioinfo.co.kr:8443/api/external/health + +# 브라우저에서는 예외 추가 또는 Let's Encrypt 인증서 사용 +``` + +### 8-3. Rate Limit 초과 + +**증상**: HTTP 429 Too Many Requests + +```bash +# Nginx rate limit 완화 +nano /etc/nginx/nginx.conf +# rate=60r/m 으로 변경 +nginx -t && systemctl reload nginx +``` + +### 8-4. DATABASE_URL 연결 오류 + +**증상**: `Name or service not known` + +```bash +# @ 특수문자 URL 인코딩 확인 +# G@urd1a_2026! → G%40urd1a_2026%21 +sed -i 's|G@urd1a_2026!|G%40urd1a_2026%21|g' /opt/guardia/app/.env +systemctl restart guardia +``` + +--- + +## 9. 접속 정보 요약 + +| 서비스 | URL | 비고 | +|--------|-----|------| +| GUARDiA ITSM (HTTP) | `http://zioinfo.co.kr:8001` | 내부망 권장 | +| GUARDiA ITSM (HTTPS) | `https://zioinfo.co.kr:8443` | 개방망 사용 | +| 외부 API | `https://zioinfo.co.kr:8443/api/external/` | API Key 인증 | +| OpenAPI 문서 | `https://zioinfo.co.kr:8443/docs` | 무인증 | +| 홈페이지 HTTPS | `https://zioinfo.co.kr` | 포트 443 | + +--- + +*GUARDiA ITSM v2.0.0 | (주)지오정보기술 | 2026-05-30* diff --git a/23_GUARDiA_개방망_가이드.pdf b/23_GUARDiA_개방망_가이드.pdf new file mode 100644 index 0000000000000000000000000000000000000000..256d2f730b5baae85102ccd8a0550704219816db GIT binary patch literal 91275 zcmdSAV|*pfvM3tcnV1vXwr$(iifvA8O>Adk+cqb*ZNL2Q+xwmUe)q#Y_v2X~y1Tlo ztGcQS-M!W#RS*%QWu#+)Ax(^m%qCPawFfvl%NQCFiksS*IvP5gnh<_t5SjptU2IM5 zoCzra_NI1D02fDNQ%V>{LIy&BkrfON4-CB+BO%i_s6Q7~q>7y@aWatEsc4u^}P7sGTvu#L~{3 zkY3%=PSDQD^1nLd3~f!n88Z^nE4vsud)R*iD&OTd{7>~g@=fbMSTX+xE8*{Jh8y^5*(w@{L{hUTV1|Eh)mRZ9};elL-b zUJ2m*t@iKf^eT>qcK?gyKm9O-{}x8!d-8t>!}5*#Z@vAOF#q)a4;1DftNGuB`IjyI zPurP)Z2jND{Fg-we>;z*spEggo|*rf_WX}4{qKyl4DHQCzWv3>@Y}lS|K%bq|4ot{ z|3UJ!rn%q zv7Bl;`m%Ok{>$l-HRq?{hlgj6c3Jt7yFC{#FQ0Dw=9BS9Z?3D#41D?FwPE@9r{`Py z)s2U@o0qpWTd!7r{?5zCx0B21i2d z+9vi@ujKL=4j2tHLU->h4vs8RoQ?C-#+0{<&km3p zw&&`@!4GKfWDK+Ht`6I9^?hIdYE5G~8lS&8>whq=WE{eE^)g1B?{Zy3ZtrgZY@iL` zJ79r2^rXdekl`19NRScAWmdfH_cvT|-n~Y(8rpmJK6sewAg4~d)r z`daVJhi`7#V@mk3A~8Ra;g9;Z9BqH?5M+DUkMZXW_5z~%bs)PLr+$WRVICp(1K^wv zw%Lb%sw4Os>j=ShGtv=%4{+hV4_#+*Jx4pBF}@FRtl)kZf4|XoI=R35V2!?uGsEVm z+q+Kp7v6V0U&QXzt^TWnr)#hOE=aJCcn$di`Y!kh?2=z-F!~8VVykmav zJo`M)3FUP)`;uqDc<_7d7y1&?&f8LXhJEv+A92d#cjQHXrCrv_+nQBa`O@9P{D%t0 z%W5<1$6sZbH$O8(%IoH?Tdoi0r$7+D>2qoDPd2A$mFF;mH0_gSyik}g3GbA#ck$?e zZt%xz7(b^h<86T5j?VL0Zl2Yb)^qzdAoQj3o_t9)q&qtOsieD(U*&b9@9chheT(|8 zyCxLpE{E%KYnwoeJNoU1J(ZTId5>!IJw z%r-&x^r8lTikC=Gx9efeY>p-<{HLLNsAW09VST?ow{_Xwy8=hoJb_wAJHpqmbI`0$ zCCqwXA}?w4PvWzV`75dkyw7aSqpYK_Ue>vjSntQ`JJ6hpyZ3GEqucj-3%Y6kAfK*z ze(e>Ak04e~=g*xF$TR*sIOgN#2Kc4egH5h|^AEVgZYO%2dyKC6-q)Lnquj0AN~Zl1 z+nFo(C2XDU@GB#RuYzknu5O1;xL4+@`kF82Y*38X;V4Gf_r^QimYE!lMA&!Yx+#pM z?q!!}aT9u7_fO}_=#Urv7IWIlFD(zh=M3X&^jGskE5i@3uE>xh_HmcCnortkHrQ#v z=??W7f1P?|Il<#*^4an&Z*@6AwE9<`M-hL`a5cfpk;~zh7N**>_TTnJ_VravtgWUS0W2 zO9BJ;fYk@|)#R~{fv-)E@Bn!O10C#<#inC_=1v0xbwK!Y3~%`Txw1Qox&d+q1L}0_ zTUaAM;<+QE@=lIAP17uVXQTpa37Yvq6F#|1< z0c?Q^q=qM6W!>ytx#59x0Kjtht10(}-ib{I?ETr0{o_WB&14R`kjjDbU4gDQc+DI` z3ZDNK0L|I~k$o*t&R?k(_k;SsD!KZc@}ep8f0DU?=K4YaHKRgpL`C{T(tgnpfb}Fj zQ+q&?#hqwnW4cQLLD@$F?N>vZH39pB0oi{<^AQ9C8z~wFG64&;V@>;`r&an(?>5&i z`GWurO$Q)@<(or}d_pN~`$Gb=>aRx^S zDU@#p<5kd)A{6+VogyH>9uF?C*Pa(HAddmg&VR?AILbd`+w7S;sZXK>+%9A-7f!6# zf+CEO0ez^~z0@Dto?9lE+W=)9+O5~51*f=2B@N=K$GHXLGU#mwI1L!FPxzW)B3Sbp zN(H3HCJi)J2#p6~@tR{Igxmmsp~qVT2zH0ynuI1$%N+*2AEh*?=$eHGbbMRW9U-M3 zMg#hx21czPTLX5wANHE41MFEkiZ)*r>Eo^u!5M=3(Nr(w(Z0L zr{9D8jM5cYU=P<73fR`>K-lVqe#V#UL$rta1g)~ip6bzjMxN@Gzh-_1>FxvA#<7~m(5s^7`1ciXjU0Ik3e50w^jpY~g9~)R!ho?*1fTU?bUHeb)klM~X=m>(c*71*baX zh5>JA#?Be&iSQnH8-pUufEq5ps0QfLUy}iEg8?)h%^uMa_9sTH>!S(QLO;I& zRtFHyHUR_15IM{JFr>95@WeN7^a=kHd-iqUy&ZH+c=lcfOt3Ek{JzhX?G@Z!MCIV* zzQix<$o?I+G$7@jpYCu?Jzg^)klUE=AdD?oV}>Z}u(3U;*FR{&Fbw&5 z*18!b_bK^b!#8g-ISyQ(K_a%<8H{d0+@GzH;4%Tn>a?1czT;tQcmcU#BUxysaYebuwcxHg6Nd1Kz5Ho3C496U;mJbBp2oR7$Y7M z`0_uF#0<;q)Qj=oe}Js)%H?5VcTf+Wj`6ou7~rdPCJy$BiGo`7>oAoFHv4t-jvQD0 z^cq2|BNjXkrNeIKy&tht^y&Yc-hB5u65q-hU+7!p+s!V-L_}h25Nsx5G2~+Gy+^!T zqr~5yn~jATU|3{h9pSSve-$kt|0Mwc3r!VM;@*tGeKF5k2SKv_6lM=Ih;ErZK3V1m zd5kuA=K?`+U0cmY3a}qf_kuGo;Skv4DO5`e9W9DazN8=UgDTML+XLh@XiaasjnQ5paxg zY;HhKG}N;YZE+rb3e1SE-x=?}l$3!Qui+NC%0`Kjt&jf`E8x?&o1dNBsNKDYa;al` zP8un`jyuNYrof$?NT~Z4*(UTBUi@_$)WnnRgk`nn3`yV0t0aw6+?&$WJ<0YpyKxtckQCS%e-K8TCMx*q0!8$IFiJvJ4aRnymD!!y zE)VxZ-)2S~6>~3gCW_y8=_=N}ZWYqnDnb)uIO-}R1NF*rAknAxYl6IE74s+72hk4l zDQuL2%QkgP@bEoBI!AKL4*DabYf;D7NW6`L1GoqameWfGNEh~F^zW!&yxR9y_eX~; zM~86OdRpr_n&x(L!S~diO^X+{c4! z$+CVwy@``us&_XIUf5!NqZ2aZb`+Zl^swg^cbLg2+dQuL%fl_$uwYvkqo=;9Ob;{4 z);1q{5rd*fMg2NJy*XXSC8%!(?uQh$VP79xVD4dekin%90``;tv&B`nmu=|h!ntFP zEZhAn_f<3cIcGidSFL{8))`LEb`hm(QwclKqlw*VWRGl-EK!uQt=dL(cu#Z@@~&yN zkhs~8EeB&E0X@I4UWWDdpAN1jb}?Ji-WI;fm_vt$&&2frisWy{>l&8EJfo z52>kPRN6Ptw&Bj5Qg=-SB*to>QQ=)K*ATF=FQ zj_^TEuOsfd{iK46y4Uk;qjYWP;1B9l(r0WR%wRZ+-)yn`>RtN0qV<0C2AE6*#-sk3 znhX#A^KB5%FvJ?wp5wpff|FEuT?FO@*pkNoxJlLSWq+ky<|3zdw(ol_TH~ekbg?iI zw(oiEUVRmJU3qKYhK+-A(|sEZ*Z3P!BnsG@9o#l5yA9kPD*L8VTfD#)Es_6KIC2p@ zm}K{D7cskQFS#AX#x5vSg*i0$xLh4O-y;OXPVP<-yhz37)dmVgT9w|x0_y3TgDli( z>$9wOpFcx&_`r1dO(@f1XrF+A4k|`B%4JJNkb~^s=hoFz&WBp$m7YFNzDoGBJ~1Pr z&FB$1)@#EHZKzz~6%!FuPxdLYkI;&e4Eskh-4&c}W42=k+^Zc_c3qp-Vr?mQtlnTf z7k%=nYr-a9}jG^#;8iH71YgiY#H1Bt~LJ zWM(z2dALn~J@it|QZIhKvAyYW1D08LN+)sI!I6I3vjmU9?8oVlp^X|T5Uld8wlj2l@8to+Uy)&^bjXD#K6H&DZSRuDbhTnhqKXdt?>uxLuG+m4bEi3+ELDrYeR(?yoFB>{s>BGQg#s&*%U6&ja)+1H z8*?Dw@FQ5L>Lz~NQFE2$LDLL=%!t|xeZ*9T%h6hJ7yqGP5~``E5HT-uT{2n z+WgY?!}V?E-N5)R#&{yc?Jrm~{H=c<{WOc2dI)aQ~D0%JX=K zo4o7{2JFr3Nq?!*(!)bXYL21~Qx33JnQykcLgBK@2QMEA#<- zR=IyxdGI7ObcO;#$=O&IMTYQUTKbsxFY>w=$waQn4!PlsEL>Uhx*uQCDW=~a2V|`v zJf;qnV80)^UtePGZZndR1y^yO{ojjcuN6Vt0Qz40&5aYk&)ekmQ43KKzxtTS6Pr)2 z5B>|~tIAq>tiHFy)h34idzwtP-;pls9od#DD3p^?5NmQDZcR_sT2CMvkc?VS00MO% zx*%vKp?&U7)PMzpMi9Bo*dTyqDUhoA2`7Oq4dwrI~ z2SRr;-RNKt%LRaSPSZ)-LA%jNwQ0)s4+y^6&>_^3s?0AhX+B)LiDfL^ zTeVCePJ=-hhKgz;*8{@gbu=5cW2>p12jF63jI&Q1klCZd!<7sLyNQJ}C;yWl0m?3? z!mU3?txODlW}GrRXpn{0;7jtxI?kn&DCGqACn&HPj<76qXn zR(Ts6m)bD8l)Jsgm8l@&rCSeOj^9{}P}=Y{lDECM+-Pj{l8DtT5aUJ10II#k)fgx}wQoptn+zIvCd? zTd047x$A%yTZb>o8_}UR9ho#khTCWfBbZQ=+Cr1oQk-0NT;Vxvdc1amku}0yUX1{- z+}g7Nq{T4dcM_czg3*wD7yQFratzJhKa7N(o0 z?b3nkvM*?{GDQrfr3Q&aB9Ih^*3}G{Eo?K7kz*pk#1)gJWB8!9H4QY}@QJ~#HKT0< zA=<(z#bPre3mpD1L^kkR9$G)8Ng|Ads;a{z2fT^%hO78*KF>0Rc>0Ag=Mz`t;huYDSG#KpFNb8Z5`~c030| zrk5L+!gi--pl-$tm67)DoRErPoVMzM5>!%f^+7%(4l8h4jHn9^u8`JwTnb@ObiLXo z7VH!k>FHywjmohF%2;xKs-XsR7!GS(42Xb?Zjtn_;|uC*o&?s##c|`@G=j)jTZD-@ z6`17!urm8Kwi-ilD8ll**^!|WJNjSSRITmj(2lRr0p;LUbM8Vi^#LHHY| zj|rKU=jo~_L7qQR+-tWxQ=UWI2n;ccH#zl!ps#_Ptm9&X@U z{q5}SarOE(1wi1{g7JC+Hpr3HnFQ)0CHUHldlE+bM1Y+|TN#1k`Z6ic3zR`9 zAQZ)3jyU zmPJClHgK}L?9j9q+Hlsa!4f<}c1EcW8R%k-D%uoGjZLF4PDD+TLtBe9J`UI%2OUeI z)v!DOdBqHr9*YFDggJeeZ6(+k8_6RSM`s=CKtWTXNy>qVUpATCxGIZn^`|5R9vqnF zKxc53W02*wn^4f~yvu#rVC33Wv3$Iisf-Kj(tI-23vOgP8e5ozffqSj+IACdkKtej zL_x0w5Ur^ixPeIPY=d;9*5QlR1Z)Ot9i<6T9fT})Vrbq#Q3s_R$nI$NJj$s#IoC%H zP!5#OX4~--cF`XtUqtk6bH{}$u6BEYbQC8|3eaHy6v!c~ z6@sP0{10xNF8;(_V`pgF!h7vkW>Rdb(84^W&Ia{Ysa;y7-wlGVQe4D0%7s$lHum}F zaGWI^Wtl&uh&&{B3JoRe6VXXU6M|PI<4JA{HRw^qaEpK83@{tX{HR7zq-G1>&;6Ca zEcqib6UAJ@ysgRTg>2P7lnfVxJQF%*@&|s2-uz`PI$E+U^;tUM26)u3i>S*E5`PA= zYQ2>*C3yt@9f1LN#uK|0ez$dS}gp0FJ6@2(#~{Rq6D{lCvA^6hEd+y&}2L? zu`B5X%h-gs7wWXr04R}pt{#V@_e6&XicA7zVr=#gsh4XVs$Hpuc5h;7tLo(gvv**} z(t3usY>4FdaF~LR7r>+Qm|E5&NuwTy$(pg|H?)raWN+J2-IL_A2*|~qDk6rnm{D4d zGC-f)uf%$?>Yht*qz$F`-I!!GnUre#6Q_3dnLkZWfv&#X$S~7ID_xaJ>0l^7VMUAW zBEh*OXiy(Np;E8{PX~|TZXWx<{ZMu6WN}{Jcn-z6k}CV)JJI(8bn z8^%v0aGAo3j^bo|!9AFSO~c~HV?_(2Tfxv=Fj@v@#-v113pbX=AwcD%9n36Au)s)+ zjx;!xG>P@6Y>`=zSw<+LBCgnzV!oM0Lg+2eqC}=$1adTB$6}@|U2~N*eRU8_9nZ=- zK!pTy4-dGIMy2qDs&D@g>xjlMNE91i``%8b+hahOQFcmr!*CL)_K| z_@S^{O#H?v|Ll+o`L(PLsigU6*YF_uQPCt#X{6=l&v%-irV7RG0exc&7i*5TT$`Ai zu8E&_Gz-`RV+MzWB_0CPb}LxlcI13ZGdk)WwMWM#EJZgI$C9DSxH6q|HE1eG-7_4f zgv6L5?AHzLP9{5LK1i2nwTv%YbzT@K>zK@A)T|&T)eX*=BqP(;(j=P{=xAJCx3h?k?58Y=wO(Ax`A{Dtdglv8fS;yyzvX=Ub zTZI8}?x>>7{?j;9f^|g$4=-0hsfYlIC*vA9C3U0f(9|%9Gd?aLAV3ThGPEiU(lZo> z=17q99Nm<6%$Z&l*fm4qLB*t2cP@#BM+L)YZ5BU00{q!y z*+Pl9q>Aj~hyW?3;Yw|epppcfBM%!&#r4p@6`i_D<0f>~u4x$BnYdwfb}FzCFUSyQ z7>k9*bm2^~DVS!!sFy#Wf=I0ywr)MQl3C-EUHuZMxM-H(3pPn5;yv}(K;94S@+JIT zj{*WSwr5Lh<|z|~onUsJ(QFgM(xq~;cthS`<Zh|aw+kgPx&yHtDBr0NDcsm4;hX|dPPgYc$54dTTC+*7t18Xw|SlVL7%TzSs>fwt^{HM!)>- z`-s<}aP1AD9v$c(k?2fsLSn&1CCXx^D$9v1XN^g!Z0(8kjTuGi^&Su*&n+0NG?6T4 zh85N1?_Gt?J*hMniRui@b(;o%v$univSl>IW-CU5?M6@p#r%}!m>;;#oAVqR3wgH1 zL+h5pV^1qU7g3cfM?#sN2ejzL_@|Ljtb)Yb%=;zgBruSCjR3JX$p`(w7SD98{ zQMcE+*(cXZB0Pzng2pQ0P^J;C>qv^4aGr49VSv2uDmIKK17{e2WGX%)h>PIK^zvkq zFyYOD)gB^xAqlGmr^2TGJACzht02nDeAT>)S5t}%x^_mxAP+@feV8p z4V8LX1%}oD2*V@@j-SQMoK(AwZ6{dP?ldJ`vP1|%jb;D1PK7FSU&68Ekc9N0u&vcu z-*X9VqA8Kb5n|kvy+~(qa9CtdU6fg&&V7!jfY+QSbCB4p*!|Jd2w(3pm?t@#oL8qD z@*qh;%2dh+hWt(V6W;gl`PLD+(ux6HI&B{LAid=04@7cj)2$1qf;T)Gb>j3M30rFE zVs2T|DGOEn@n7czX*PjFWY0F4lb@nQnB|-gMO#H%BgR*5*XseDtwtWGqka}TgTlke=tF*o1BaGWA?zx6g@OHiu7Yjogy6x>L}iRaq2t=%6R33@$&jH%y{4h zUy>{c-K>i0;0M;Gs1pv;PG`jxKq#=vd{i3h8 z)QYYlI>Nfi)t<``%WTW))y#Bw%w6!5Yf4>GoQXsNFlwjWb2+o~)Vh?OJ`rb9Q!82E z1#}wKO41(;wylqqDOQa`(nLz+Taw#JTB%6%=3ICOXXs>_y#$B~e5u_Ew1)ardfkgx z&MRN#LcO%Ql>-P=`o^b%3v|70Mbc|ebX$$qFSm&N14x^d9hW`=FB+Dol}ap>1b!cD z0DZr^yXl5k_y#Tr!zh^;VqLTp*=fMSmgN}qcU;PVL{K?5}7nIH`EU|YEdf_mLlK#ntUBdw5#Kl5oN&x`hKIUnun?fY>C^tW1_K;F)2;LP*R`S#2*{UUxvJ!T`H5Frac=D8*ewzB4D9bM!P zO`2Ldb5=IuPOPzzVkOd#B58Z+(ew^F74p~kS}Qa`c*)f>VPj9@(jUr%lL(lyrOM!& zLxDu@h4&@?86NBtj&BRl0wTXr&};?Trkv|?wIo?2EH z)m6W$>_;{v4BfR5_BrfXDJsXT)lA7F;|`cT`T0iPUtjN-=+!P>*|R0sLzWEMNt)vg zt>{FjVuomU+=+D@_x2P`pQb6RImWZ>-8^)@XmXrqO!?=UStX(~`%=4x821&MvM?j6 zdMox6b}br+e*HA}Ro>M~lHLjJs$HGT(UyfSEC?5r(H5V2^OEQa*Nym|t)bL+-(ZM> zNQTv}6~XnGL06d=y8K>P-PV!a$2ZI9I5pi3zP#6STsHdtCQkE;0)erDitCy>x~a17 zhlU}pF3rK%iJH#LNla@ZGMplT+F+y)2su021nnSjnl-w(@!PvN2#SleN!UX3UAPm) z(G7O)cKzeAK!&Y#*R=7L>q^|qjI~Dnw8q+`Pa*UQTZ>%l6*>#3MFlBNczziqX8{LH zLwE_iNrs;T88`DlgP)el^9;Ya28Y?HLt4UYZ@Nl^NuQ{?br-)5?M0~;VN-Yyd71)= zLL|Iw^ipX}aIA>UGFA^~d`(3dB8CjbtnN9$V(tRjIW;*_#9X*05vrCPW-Pf%$?e>J zWAQ*{Nxm)=l61R>OG%X*hRuFIQjkzCCRn8e2@ZV)EfFm`>`oD*H9}O0f;+-SQi(cR zBe(atD#ceqY;g&R5{J zyDZU0+&-ljjafoxbtV_M-ly_;Gtb2%ZoVTHRbe(}Ub!ChuO-8H$JjO-Pp>&NGX1t~ zrX~OZ3Q0BAJz?(?j)T$7rKW+>Zf|kX%@*oi2ix*`KkKQrZ+50^&KFmYh8K672|^n4q#i)Z7wS z4PqTnBV5X=(bGgsyK0)>hBs>0O1?(b8gYB~EMVxVmN&oJ|9jLd0xN<;H)evSA`vS+ zw2tts&gJ{HTJ$o@{rTn+QViG6`tIPZibeiqC%g>I}A;c!0Oj zaH-F@i8do7(53(7I4|S(=gorG=(}obv@kh*^y9csl`D+4v4ik=Aw#zL^ArOKY@h=6 z)HHu;N{S(8$^2|#;kgqQ8@)?rL8e>tTSS6Mp2#hnj3dsxbV8vCjJmF>#XHKvs`9An zK&hzp`)H|7DJw-J_kmi|!O<$+O)5T~_s=*w69b?d`s$7AsXOXrfc}f~p0V<9OuLuk z%d=O@(O-aufWA6{t#0G{1KxNl8y}bL#0sTba%|2N{Oa>6*}hfY7c}RnMU1OtEV*0_N(>8Y+iu4WSi|q+e|WKo6Jl}M^mcn=tg(!)m;~F=$0FK zsa{%eBO6_8fLbRTm506ZtKJV#5jKq$(fHy7A z>@HH!oVi3!ogrX7IaDf7P*S7&W75+#1IIeO*DI%!H-?k-Z;I9VG}XJMIX?#yra&GQRHOz zhfg@q~EgU0MYC}HcKuYms zQbwvF3Rj2cTi6k{OsBLt$R`CVM})B3`<4uuf1xOv4hltA1T0^=m4(%0>56K!?c5Ih zyrFZXekFvKxuAD=w93`Z1>HZ^-e?0II_DpYBn6gPu^=KZB2Ov3=!^K%+yZ3_&MXb{ zvU)j9Aqck!BH(CsyD`j#i^GOZA@s16^xXA8(5HCI)jK1=tgNc%wp|IC^!t1|S5cQs)5?FVe3veA*>w$SKcuqIe(O)CLy zX#!aQa}QJu#j%PcMh*Rt3W+u*bak~oDN`GrCv^(*8|-I%3TNoGX(U{+xbp&W%0#eh zE0TJMRi)m#l)Ae24mj+Z9aef7k83Z{$Rl7wXvVm#LI{e&?pDOuUCqLgTvcTwcY3AyTZT;rC~Q9|Mx_G7|&zurjxiML%#f8 z3M9PgGnV5}g0jkt0rbNpZ=;yEFl~1Pf!VdOZtshhwW>Sp{-lhZSyx$e*?Rq zTY+cx-UTHB@OMnwH#iUpCl7ysl?=kFm}?(8TZ0AA&0DJMqN|{aCk54wsQEUbGwhW1 z6i~`YXd076#iF^MZFY)3U9vd6WUl?L_PWh*lc%xNP*;`sTU!F>P=Oa`ZmYb1(3EB>u%|Ng1v#;dL%t=rL`DAH!O_y8B zlQSnCpW`uF$x*D65}CEqGn@aF&+mah&3%Lw4csk`V@@(re?S;nC$2SCr{4+#^*XU*>CY4n5W%HSsXJ3p)P-%ZtDQ5oa6VU$pkr%Y?t@ZLr{mVW9U zjLiB?zS<4lT21_pd|b(TAa&+_ zF=d`^K5vvnBPy`xeuxB1C3T^US-E!!M744$H;5Gdv+r^S^g~VPBn^*SO$3slk9(L> z%?9w92C%zolF*FVJNlGq2>aU}Kb-_28h-W=vI6ZX@DaT?Q?q3jzVz3GkO00y{pESmBS}J%|ZnH3;JrcYd4dXlR z_Xe*T{{qOQME-^-{m1jM3-0ELOjUs;v9G;$K5tw~yDuJyErAkFV zCCTmV73irU0xudBbsm+q!2l1;~UM5X^xR|11=Lx?l4|CFOzOFu2`Rp2^Pg|?@4_dnCP_f z-(O*>d;E;7X!m{^8*K?Ml4P1I**{f zA05xku1Gma4+>SOR#gdhI95C}QBqX&_MBd-@Qgmm+WYEU-V37>JDuNr-kQYzC|}fV^J8DA_^h@T755sl7aaJw-BP%(UikxyblcIQ zW89ewR`c-sIaQN|PESg9(!TWw>p<;rh_)Pd7^5AW-a&7a$^<&VIbSYILT33yGc_h} zXNTO?PgdfktcsuLV}D$E4F4d56gBLRr{iIywe?}8Ev~eSMpJ^Tk@z> z4#?lO^C}E{jkklx;OOjupE?0!Vak2z(gTL`qNNlzKyhp}2znwf(niq_)4OuR)Em7Z zGpatX4Oi#CL`0(V*h?=o2r=b2jfV`)Sgz`E8? zY*`H2{}ePL>ZRQpm`BbcTaAE=u=7muPHg~VkHD{SS{?dGxNpDRVyj7QgP9m1juArg za@SWO!I60^P+3Eue;)`(csDI9$Z1F-MF5ApbXXmC|LL3wyQ5uz;%0DI!&P<&d_o}b_As?(9w&6yKZ(RJYzaRGy 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 LSFtF}M_>OB!k*du literal 0 HcmV?d00001 diff --git a/24_GUARDiA_개방망_발표자료.pptx b/24_GUARDiA_개방망_발표자료.pptx new file mode 100644 index 0000000000000000000000000000000000000000..e6329632298896961af78baafca6ee0b26371b12 GIT binary patch literal 41313 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 literal 0 HcmV?d00001 diff --git a/25_GUARDiA_Manager_라이선스_관리_가이드.md b/25_GUARDiA_Manager_라이선스_관리_가이드.md new file mode 100644 index 0000000..9e7255b --- /dev/null +++ b/25_GUARDiA_Manager_라이선스_관리_가이드.md @@ -0,0 +1,296 @@ +# GUARDiA Manager — 라이선스 키 등록 및 관리 가이드 + +> **버전**: 2.0.0 | **작성일**: 2026-05-30 +> **접속 URL**: http://zioinfo.co.kr:8090/licenses +> **대상**: 시스템 관리자 (admin 역할) + +--- + +## 1. 개요 + +GUARDiA Manager의 **라이선스 관리** 페이지는 GUARDiA ITSM 플랫폼의 라이선스를 +통합 관제하는 화면입니다. + +### 주요 기능 + +| 기능 | 설명 | +|------|------| +| **현재 상태 확인** | 에디션, 만료일, 남은 기간, 허용 한도 실시간 표시 | +| **라이선스 키 등록** | 발급받은 라이선스 키를 붙여 넣고 즉시 활성화 | +| **무료 체험 시작** | 7/14/30일 체험 라이선스 즉시 발급 (설치당 1회) | +| **키 검증** | 등록 없이 키 유효성만 검증 (발급 전 사전 확인) | +| **라이선스 비활성화** | 현재 라이선스 비활성화 (서비스 제한 발생) | +| **이력 조회** | 과거 등록된 모든 라이선스 이력 테이블 | +| **에디션 비교** | TRIAL/COMMUNITY/STANDARD/ENTERPRISE 기능 비교 | + +--- + +## 2. 라이선스 에디션 + +### 2-1. 에디션 비교표 + +| 구분 | TRIAL | COMMUNITY | STANDARD | ENTERPRISE | +|------|-------|-----------|----------|------------| +| 가격 | 무료 (7일) | 무료 | 협의 | 협의 | +| 기관 수 | 1 | 1 | 50 | 무제한 | +| 사용자 수 | 10명 | 10명 | 200명 | 무제한 | +| 서버 수 | 20대 | 50대 | 500대 | 무제한 | +| AI 에이전트 | ❌ | ❌ | ✅ | ✅ | +| LDAP/MFA | ❌ | ❌ | ✅ | ✅ | +| SLA 관리 | ✅ 기본 | ✅ 기본 | ✅ 고급 | ✅ 고급 | +| 취약점 스캔 | ❌ | ❌ | ❌ | ✅ | +| FinOps | ❌ | ❌ | ❌ | ✅ | +| Scouter APM | ❌ | ❌ | ❌ | ✅ | +| 기술 지원 | ❌ | 커뮤니티 | 이메일 | 전담 지원 | + +### 2-2. 라이선스 키 형식 + +``` +TRIAL: GRD-{Base64URL 인코딩 페이로드} (자동 생성) +COMMUNITY/ grd_lic_{발급기관코드}_{서명} +STANDARD/ +ENTERPRISE: +``` + +--- + +## 3. 화면 구성 (NCloud 콘솔 스타일) + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 업그레이드 배너 (만료 3일 전 표시) │ +│ ⚠️ 체험판이 X일 후 만료됩니다. [라이선스 등록] 버튼 │ +├─────────────────────────────────────────────────────────────────┤ +│ 현재 라이선스 상태 카드 │ +│ [에디션 배지] [체험판/만료 배지] │ +│ 고객명: 지오정보기술 체험판 │ +│ 메시지: TRIAL 라이선스 활성 (6일 남음) │ +│ [🔑 등록] [🎁 체험] [🔍 검증] [비활성화] │ +│ ───────────────────────────────────────────────────────────── │ +│ [만료 게이지 바] [라이선스 ID] [허용 한도] │ +│ ████████░░ 6일 남음 TRL-290EA0FB 기관:1/사용자:10/서버:20 │ +├─────────────────────────────────────────────────────────────────┤ +│ 액션 패널 (선택한 액션에 따라 표시) │ +│ 예) 라이선스 키 등록: [textarea] [활성화 버튼] │ +├─────────────────────────────────────────────────────────────────┤ +│ 에디션 비교 (4개 카드 — 현재 에디션 강조) │ +│ [TRIAL] [COMMUNITY] [STANDARD ★] [ENTERPRISE] │ +├─────────────────────────────────────────────────────────────────┤ +│ 라이선스 이력 테이블 │ +│ ID | 라이선스ID | 에디션 | 고객명 | 체험판 | 만료일 | 상태 | 등록자│ +└─────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 4. 기능별 사용 방법 + +### 4-1. 라이선스 키 등록 + +> **사전 조건**: admin 역할로 로그인, GUARDiA ITSM 서버에 `GUARDIA_LICENSE_KEY` 환경변수 설정 + +1. [🔑 라이선스 등록] 버튼 클릭 +2. 발급받은 라이선스 키를 텍스트 영역에 붙여 넣기 +3. [활성화] 버튼 클릭 +4. 성공 시 현재 상태 카드가 즉시 갱신됨 + +```bash +# 라이선스 키 발급 (서버 관리자용 — Python 직접 실행) +ssh root@zioinfo.co.kr + +source /opt/guardia/venv/bin/activate +cd /opt/guardia/app +python -m core.license \ + --customer "서울특별시 정보화부" \ + --edition STANDARD \ + --days 365 \ + --key $GUARDIA_LICENSE_KEY +``` + +### 4-2. 무료 체험 시작 + +> **제한**: 설치당 1회만 가능 + +1. [🎁 무료 체험] 버튼 클릭 +2. 고객/기관명 입력 (기본값: "GUARDiA 체험판") +3. 체험 기간 선택: 7일 / 14일 / 30일 +4. [🎁 체험 시작] 버튼 클릭 +5. **발급된 체험 키가 팝업으로 1회만 표시** → 반드시 복사 보관 +6. 즉시 TRIAL 에디션으로 활성화 + +> ⚠️ 체험 라이선스 키는 발급 시 화면에 1회만 표시됩니다. 화면을 닫으면 다시 확인할 수 없습니다. + +### 4-3. 라이선스 키 검증 + +등록 전 키가 유효한지 먼저 확인할 때 사용합니다. + +1. [🔍 키 검증] 버튼 클릭 +2. 확인할 키 입력 +3. [검증] 버튼 클릭 +4. 결과 확인: 에디션, 고객명, 발급일, 만료일 표시 +5. 유효한 경우 [이 키로 활성화] 버튼으로 즉시 등록 가능 + +### 4-4. 라이선스 비활성화 + +> **주의**: 비활성화 시 서비스 제한이 발생합니다. + +1. [비활성화] 버튼 클릭 (빨간 버튼) +2. 확인 다이얼로그에서 [확인] +3. 상태가 "활성 라이선스가 없습니다."로 변경됨 + +--- + +## 5. API 명세 + +GUARDiA ITSM API를 직접 호출하는 엔드포인트입니다. + +### 기본 정보 + +| 항목 | 값 | +|------|-----| +| Base URL | `http://zioinfo.co.kr:8001` | +| 인증 | `Authorization: Bearer {JWT Token}` | +| 로그인 | `POST /api/auth/login` (JSON, admin 역할 필요) | + +### 엔드포인트 목록 + +| 메서드 | 경로 | 인증 | 설명 | +|--------|------|------|------| +| `GET` | `/api/license/status` | 로그인 | 현재 라이선스 상태 | +| `POST` | `/api/license/trial` | admin | 체험 라이선스 발급 | +| `POST` | `/api/license/activate` | admin | 라이선스 키 활성화 | +| `POST` | `/api/license/verify` | admin | 라이선스 키 검증만 | +| `DELETE` | `/api/license` | admin | 라이선스 비활성화 | +| `GET` | `/api/license/history` | admin | 등록 이력 조회 | + +### 요청/응답 예시 + +**체험 라이선스 발급** +```bash +curl -X POST http://zioinfo.co.kr:8001/api/license/trial \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"customer":"지오정보기술","days":7}' +``` +```json +{ + "message": "🎁 7일 무료 체험이 시작되었습니다!", + "license_id": "TRL-XXXXXXXXXX", + "edition": "TRIAL", + "customer": "지오정보기술", + "expires_at": "2026-06-06T11:37:25", + "days_remaining": 7, + "is_trial": true, + "license_key": "GRD-..." +} +``` + +**라이선스 상태 조회** +```bash +curl http://zioinfo.co.kr:8001/api/license/status \ + -H "Authorization: Bearer $TOKEN" +``` +```json +{ + "activated": true, + "valid": true, + "expired": false, + "is_trial": true, + "edition": "TRIAL", + "customer": "지오정보기술", + "days_remaining": 6, + "limits": { + "max_institutions": 1, + "max_users": 10, + "max_servers": 20 + }, + "message": "TRIAL [체험판] 라이선스 활성 (6일 남음)" +} +``` + +--- + +## 6. 테스트 결과 + +### 6-1. 테스트 환경 + +| 항목 | 값 | +|------|-----| +| 서버 | Ubuntu 24.04 (zioinfo.co.kr) | +| GUARDiA ITSM | v2.0.0 | +| GUARDiA Manager | v1.0.0 | +| 테스트 일자 | 2026-05-30 | + +### 6-2. 테스트 결과 (7/7 PASS) + +| 테스트 | 항목 | 결과 | +|--------|------|------| +| T1 | admin 로그인 (JSON) | ✅ PASS | +| T2 | 라이선스 현재 상태 조회 | ✅ PASS | +| T3 | 체험 라이선스 발급 (7일) | ✅ PASS | +| T4 | 활성화 후 상태 확인 (TRIAL, 6일) | ✅ PASS | +| T5 | 라이선스 이력 조회 (1건) | ✅ PASS | +| T6 | 잘못된 키 검증 (에러 처리) | ✅ PASS | +| T7 | Manager UI 접속 | ✅ PASS | +| T8 | Manager Backend API | ✅ PASS | + +### 6-3. 버그 수정 이력 + +| 날짜 | 파일 | 버그 | 수정 내용 | +|------|------|------|---------| +| 2026-05-30 | `routers/license.py` | `datetime` timezone-aware/naive 충돌 | `datetime.fromisoformat(...).replace(tzinfo=None)` 적용 | + +--- + +## 7. 운영 절차 + +### 7-1. 정기 만료일 모니터링 + +```bash +# 라이선스 만료일 확인 (서버 직접 확인) +ssh root@zioinfo.co.kr +curl -s -X POST http://localhost:8001/api/auth/login \ + -H "Content-Type: application/json" \ + -d '{"username":"admin","password":"1111"}' \ + | python3 -c "import json,sys; print(json.load(sys.stdin).get('access_token')[:20])" + +TOKEN=$(...) +curl -s http://localhost:8001/api/license/status \ + -H "Authorization: Bearer $TOKEN" \ + | python3 -m json.tool | grep -E "edition|days_remaining|expires_at" +``` + +### 7-2. 라이선스 갱신 절차 + +1. 새 라이선스 키 발급 (담당자에게 요청) +2. GUARDiA Manager → 라이선스 관리 → [🔍 키 검증]으로 사전 확인 +3. [🔑 라이선스 등록] → 새 키 입력 → 활성화 +4. 기존 라이선스는 자동 비활성화됨 + +### 7-3. 라이선스 환경변수 설정 + +STANDARD/ENTERPRISE 라이선스 사용 시 서버에 마스터 키 설정이 필요합니다: + +```bash +# /opt/guardia/app/.env 에 추가 +GUARDIA_LICENSE_KEY=<64자리 hex 마스터 키> + +# 서비스 재시작 +systemctl restart guardia +``` + +--- + +## 8. 트러블슈팅 + +| 증상 | 원인 | 해결 | +|------|------|------| +| 체험판 발급 실패 (409) | 이미 체험 이력 존재 | 체험은 1회 한정, 정식 키 필요 | +| 키 검증/등록 500 에러 | `GUARDIA_LICENSE_KEY` 미설정 | .env에 마스터 키 설정 | +| 이력 조회 403 | admin 역할 아님 | admin 계정으로 로그인 | +| 만료 배너 표시 | 만료 3일 이내 | 새 라이선스 등록 | +| `datetime` 오류 | timezone aware/naive 충돌 | `license.py` 패치 적용 (완료) | + +--- + +*GUARDiA ITSM v2.0.0 | (주)지오정보기술 | 2026-05-30* diff --git a/26_GUARDiA_Manager_라이선스_가이드.pdf b/26_GUARDiA_Manager_라이선스_가이드.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9bc557d8d94cfcbc4be27abb46df7fe2f5593ca1 GIT binary patch literal 75697 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 AUaMT+=FVM+5bwK@Tdjvn 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%0DdlyW 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 **버전**: 1.0.0 | **작성일**: 2026-05-30 +> **서버**: zioinfo.co.kr | **대상**: 시스템 관리자 (admin) + +--- + +## 1. 개요 + +폐쇄망에 설치된 GUARDiA ITSM의 데이터(SR, CMDB, 기관, 감사로그)를 +개방망 GUARDiA Manager로 안전하게 이관하는 Export/Import 인터페이스입니다. + +### 보안 특징 +- **HMAC-SHA256 서명**: 번들 파일 위변조 방지 +- **민감 정보 자동 마스킹**: IP 주소, SSH 비밀번호는 `****`로 처리 +- **Dry Run 모드**: 실제 저장 전 사전 검증 +- **중복 방지**: sr_id 기준 중복 SKIP + +--- + +## 2. API 엔드포인트 + +| 메서드 | 경로 | 설명 | +|--------|------|------| +| `GET` | `/api/export-import/export/bundle` | 전체 번들 ZIP (권장) | +| `GET` | `/api/export-import/export/sr` | SR 목록 JSON | +| `GET` | `/api/export-import/export/cmdb` | CMDB 서버 자산 JSON | +| `GET` | `/api/export-import/export/institutions` | 기관 목록 JSON | +| `GET` | `/api/export-import/export/audit` | 감사 로그 JSON | +| `POST` | `/api/export-import/import/bundle` | 번들 ZIP Import | +| `POST` | `/api/export-import/import/sr` | SR JSON Import | + +--- + +## 3. 사용 방법 + +### 3-1. 폐쇄망에서 Export + +```bash +# 전체 번들 다운로드 (권장) +TOKEN=$(curl -s -X POST http://폐쇄망-IP:8001/api/auth/login \ + -H "Content-Type: application/json" \ + -d '{"username":"admin","password":"비밀번호"}' \ + | python3 -c "import json,sys; print(json.load(sys.stdin).get('access_token'))") + +curl -O http://폐쇄망-IP:8001/api/export-import/export/bundle \ + -H "Authorization: Bearer $TOKEN" +# → guardia_export_20260530_HHMMSS.zip 저장 +``` + +### 3-2. 개방망 Manager에서 Import + +1. `http://zioinfo.co.kr:8090/export-import` 접속 +2. 번들 ZIP 파일 드래그 & 드롭 +3. **[🔍 검증 실행]** — Dry Run으로 내용 확인 +4. 이상 없으면 **Dry Run 체크 해제** → **[📥 Import 실행]** + +--- + +## 4. 테스트 결과 (7/7 PASS) + +| 테스트 | 결과 | +|--------|------| +| SR Export | ✅ PASS | +| CMDB Export | ✅ PASS | +| 기관 Export | ✅ PASS | +| 감사 로그 Export | ✅ PASS | +| 번들 ZIP Export (HMAC) | ✅ PASS | +| SR Import dry_run | ✅ PASS | +| Manager UI 접속 | ✅ PASS | + +**버그 수정**: `date` 타입 JSON 직렬화 오류 → `isoformat()` 처리 완료 + +--- + +*GUARDiA ITSM v2.0.0 | (주)지오정보기술 | 2026-05-30* diff --git a/29_GUARDiA_폐쇄망_데이터연동_가이드.pdf b/29_GUARDiA_폐쇄망_데이터연동_가이드.pdf new file mode 100644 index 0000000000000000000000000000000000000000..444d69daa093253834a666a6fb2a99b5cac106bc GIT binary patch literal 45708 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 literal 0 HcmV?d00001 diff --git a/30_GUARDiA_폐쇄망_데이터연동_발표자료.pptx b/30_GUARDiA_폐쇄망_데이터연동_발표자료.pptx new file mode 100644 index 0000000000000000000000000000000000000000..c3679c3935de2b4ea595458611c49e50dfe5da42 GIT binary patch literal 36650 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 literal 0 HcmV?d00001 diff --git a/31_AI_플랫폼_제안서.md b/31_AI_플랫폼_제안서.md new file mode 100644 index 0000000..22bb5b0 --- /dev/null +++ b/31_AI_플랫폼_제안서.md @@ -0,0 +1,134 @@ +# GUARDiA AI 플랫폼 최적 오픈소스 제안서 + +> **서버**: zio-server (zioinfo.co.kr) | **작성일**: 2026-05-30 +> **현재 사양**: 2 vCPU / 7.8GB RAM / 99GB Disk / Ubuntu 24.04 +> **기설치**: Ollama 0.24.0 + Llama3:8b (4.7GB) + +--- + +## 1. 제안 아키텍처 + +``` +사용자/메신저 명령 + ↓ +[GUARDiA ITSM FastAPI] + ↓ +[LangChain Orchestration Layer] ← 에이전트 체인, 툴 호출 + ↓ +┌─────────────────────────────────────┐ +│ RAG 파이프라인 │ +│ ChromaDB (벡터 검색) │ +│ ← GUARDiA KB, 코드베이스, 문서 임베딩 │ +└─────────────────────────────────────┘ + ↓ +[Ollama] → Llama3:8b (온프레미스 LLM) +``` + +--- + +## 2. LLM / sLLM 추천 + +| 순위 | 모델 | RAM 요구 | 특징 | GUARDiA 적합성 | +|------|------|---------|------|--------------| +| ⭐1 | **llama3:8b** (기설치) | ~5GB | 범용 추론, 한국어 양호 | ✅ 현재 운영 중 | +| 2 | **qwen2.5:7b** | ~5GB | 한국어 성능 우수, 코드 생성 | ✅ 권장 추가 | +| 3 | **codellama:7b** | ~4GB | 코드 리뷰, SSH 명령 생성 | ✅ 코드 분석용 | +| 4 | **mistral:7b** | ~5GB | 빠른 응답, 영어 최적 | 보조 모델 | +| 5 | llama3.2:3b | ~2.5GB | 경량, 빠름 | 빠른 응답 전용 | + +**현재 서버 RAM 7.8GB 제한으로 동시 2개 모델 한계 → llama3:8b + codellama:7b 조합 권장** + +--- + +## 3. AI 프레임워크 추천 + +### 3-1. LangChain (핵심 추천 ⭐) + +| 항목 | 내용 | +|------|------| +| 용도 | 에이전트 체인, 툴 호출, RAG 파이프라인 | +| GUARDiA 연동 | FastAPI 내부에서 `ChatOllama` 사용 | +| 패키지 | `langchain`, `langchain-community`, `langchain-ollama` | + +```python +from langchain_ollama import ChatOllama +from langchain_core.messages import HumanMessage + +llm = ChatOllama(model="llama3:8b", base_url="http://localhost:11434") +response = llm.invoke([HumanMessage(content="서버 재시작 명령 생성")]) +``` + +### 3-2. LangGraph (에이전트 워크플로우) + +| 항목 | 내용 | +|------|------| +| 용도 | 복잡한 멀티 에이전트 상태 머신 | +| GUARDiA 연동 | SR 처리 → 승인 → 배포 플로우 구현 | +| 패키지 | `langgraph` | + +### 3-3. Haystack (RAG 파이프라인) + +| 항목 | 내용 | +|------|------| +| 용도 | 문서 검색, Q&A, KB 기반 응답 | +| GUARDiA 연동 | KB, 운영 메뉴얼 RAG 검색 | +| 패키지 | `haystack-ai`, `farm-haystack` | + +--- + +## 4. 벡터 DB 추천 (별도 문서: 32_벡터DB_제안서.md) + +| 순위 | DB | 특징 | 설치 방식 | +|------|-----|------|---------| +| ⭐1 | **ChromaDB** | 경량, Python native, 로컬 파일 | pip install | +| 2 | **Qdrant** | 고성능, REST API, Docker | Docker 컨테이너 | +| 3 | Weaviate | 풍부한 기능, 무거움 | Docker 컨테이너 | +| 4 | FAISS | Meta제작, 초고속, 메모리 전용 | pip install | + +**서버 사양(7.8GB RAM) 고려 → ChromaDB (로컬 파일 기반) 1차 권장** + +--- + +## 5. 임베딩 모델 추천 + +| 모델 | 크기 | 한국어 | 용도 | +|------|------|--------|------| +| **nomic-embed-text** | 274MB | 양호 | Ollama 내장, 온프레미스 | +| all-MiniLM-L6-v2 | 80MB | 미흡 | 영어 최적, 빠름 | +| bge-m3 | 570MB | 우수 | 다국어 최고 성능 | + +**GUARDiA 권장: `nomic-embed-text` (Ollama 내장, 외부 API 불필요)** + +--- + +## 6. 설치 계획 (zio 서버) + +### Phase 1: LangChain + RAG 기반 +```bash +pip install langchain langchain-community langchain-ollama \ + langchain-chroma chromadb sentence-transformers +ollama pull nomic-embed-text +``` + +### Phase 2: 추가 모델 +```bash +ollama pull qwen2.5:7b # 한국어 강화 +ollama pull codellama:7b # 코드 리뷰 +``` + +### Phase 3: GUARDiA 코드베이스 학습 +```python +from langchain_community.document_loaders import DirectoryLoader +from langchain_chroma import Chroma +from langchain_ollama import OllamaEmbeddings + +loader = DirectoryLoader("/opt/guardia/app", glob="**/*.py") +docs = loader.load() +embeddings = OllamaEmbeddings(model="nomic-embed-text") +vectordb = Chroma.from_documents(docs, embeddings, + persist_directory="/opt/guardia/vectordb") +``` + +--- + +*GUARDiA ITSM v2.0.0 | (주)지오정보기술 | 2026-05-30* diff --git a/32_벡터DB_제안서.md b/32_벡터DB_제안서.md new file mode 100644 index 0000000..84e2f9c --- /dev/null +++ b/32_벡터DB_제안서.md @@ -0,0 +1,124 @@ +# GUARDiA 벡터 데이터베이스 제안서 + +> **서버**: zio-server (zioinfo.co.kr) | **작성일**: 2026-05-30 + +--- + +## 1. 벡터 DB 비교 + +| DB | 설치 | 메모리 | 영속성 | REST API | 한국어 | GUARDiA 적합성 | +|----|------|--------|--------|---------|--------|--------------| +| **ChromaDB** | pip | 낮음 | 파일 기반 | ❌ (Python) | ✅ | ⭐ 1순위 | +| **Qdrant** | Docker | 중간 | 볼륨 | ✅ | ✅ | ⭐ 2순위 | +| FAISS | pip | 낮음 | 없음(메모리) | ❌ | ✅ | 빠른 검색 | +| Weaviate | Docker | 높음 | 볼륨 | ✅ | ✅ | 대규모 용 | +| Milvus | Docker | 높음 | 볼륨 | ✅ | ✅ | 엔터프라이즈 | + +--- + +## 2. 최종 선택: ChromaDB + +### 선택 이유 +- **설치 간편**: `pip install chromadb` 한 줄 +- **서버 RAM 절약**: 7.8GB RAM 환경에 최적 +- **Python 직접 통합**: GUARDiA FastAPI와 완벽 연동 +- **로컬 파일 영속**: 별도 서비스 불필요 +- **Ollama 임베딩 연동**: `nomic-embed-text` 온프레미스 임베딩 + +### 설치 및 설정 +```bash +# 설치 +/opt/guardia/venv/bin/pip install chromadb langchain-chroma + +# 디렉터리 +mkdir -p /opt/guardia/vectordb +``` + +### GUARDiA 연동 코드 +```python +import chromadb +from chromadb.config import Settings + +# 클라이언트 초기화 +client = chromadb.PersistentClient( + path="/opt/guardia/vectordb", + settings=Settings(anonymized_telemetry=False) +) + +# 컬렉션 생성 +collection = client.get_or_create_collection( + name="guardia_kb", + metadata={"hnsw:space": "cosine"} +) + +# 문서 추가 +collection.add( + documents=["서버 재시작 절차: systemctl restart guardia"], + metadatas=[{"type": "kb", "category": "deployment"}], + ids=["kb-001"] +) + +# 유사도 검색 +results = collection.query( + query_texts=["guardia 서비스 재시작하는 방법"], + n_results=3 +) +``` + +--- + +## 3. 2순위: Qdrant (Docker) + +RAM이 충분하거나 REST API가 필요한 경우 추천합니다. + +```bash +docker run -d --name qdrant \ + -p 6333:6333 \ + -v /opt/guardia/qdrant:/qdrant/storage \ + qdrant/qdrant +``` + +--- + +## 4. GUARDiA 코드베이스 학습 계획 + +### 학습 데이터 소스 +| 소스 | 내용 | 문서 수 예상 | +|------|------|------------| +| `/opt/guardia/app/routers/*.py` | API 라우터 코드 | ~70개 | +| `/opt/guardia/app/core/*.py` | 비즈니스 로직 | ~38개 | +| `/opt/guardia/app/models.py` | 데이터 모델 | 1개 (대용량) | +| `/opt/guardia/app/static/` | UI 코드 | ~20개 | +| `C:/GUARDiA/manual/*.md` | 운영 문서 | ~32개 | + +### 임베딩 스크립트 +```python +# /opt/guardia/app/scripts/embed_codebase.py +from langchain_community.document_loaders import DirectoryLoader, TextLoader +from langchain.text_splitter import RecursiveCharacterTextSplitter +from langchain_ollama import OllamaEmbeddings +from langchain_chroma import Chroma + +loader = DirectoryLoader("/opt/guardia/app", glob="**/*.py", + loader_cls=TextLoader, loader_kwargs={"encoding": "utf-8"}) +docs = loader.load() + +splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200) +chunks = splitter.split_documents(docs) + +embeddings = OllamaEmbeddings( + model="nomic-embed-text", + base_url="http://localhost:11434" +) + +vectordb = Chroma.from_documents( + chunks, embeddings, + persist_directory="/opt/guardia/vectordb", + collection_name="guardia_codebase" +) +print(f"임베딩 완료: {len(chunks)}개 청크") +``` + +--- + +*GUARDiA ITSM v2.0.0 | (주)지오정보기술 | 2026-05-30* diff --git a/33_GUARDiA_Messenger_앱_스토어_등록_가이드.md b/33_GUARDiA_Messenger_앱_스토어_등록_가이드.md new file mode 100644 index 0000000..5a756a3 --- /dev/null +++ b/33_GUARDiA_Messenger_앱_스토어_등록_가이드.md @@ -0,0 +1,244 @@ +# GUARDiA Messenger 앱 스토어 등록 가이드 + +> **앱명**: GUARDiA Messenger +> **패키지**: kr.co.zioinfo.guardia +> **버전**: 1.0.0 +> **작성일**: 2026-05-31 + +--- + +## 1. 사전 준비 + +### 1-1. 필요 계정 + +| 스토어 | 계정 | 비용 | 등록 링크 | +|--------|------|------|----------| +| **Google Play** | Google Play Developer | $25 (1회) | play.google.com/console | +| **Apple App Store** | Apple Developer Program | $99/년 | developer.apple.com | +| **Expo EAS** | Expo 계정 (무료) | 무료 | expo.dev | + +### 1-2. 환경 준비 + +```bash +# EAS CLI 설치 +npm install -g eas-cli + +# Expo 로그인 +eas login + +# 프로젝트 초기화 +cd C:\GUARDiA\app +eas init --id guardia-messenger-zioinfo +``` + +--- + +## 2. EAS Build — 클라우드 빌드 (Mac 불필요) + +### 2-1. Android APK/AAB 빌드 + +```bash +cd C:\GUARDiA\app + +# 테스트용 APK (내부 배포) +eas build --platform android --profile preview + +# 스토어 배포용 AAB +eas build --platform android --profile production +``` + +빌드 완료 후 `.aab` 파일 다운로드 → Google Play Console에 업로드 + +### 2-2. iOS IPA 빌드 + +```bash +# App Store Connect용 IPA (Mac 없이 클라우드 빌드) +eas build --platform ios --profile production +``` + +> Apple Developer 계정이 필요하며 EAS가 자동으로 인증서와 프로파일을 관리합니다. + +--- + +## 3. Google Play Store 등록 + +### 3-1. 앱 생성 + +1. **play.google.com/console** 접속 → Google Play Developer 로그인 +2. [앱 만들기] 클릭 +3. 정보 입력: + +| 항목 | 값 | +|------|-----| +| 앱 이름 | GUARDiA Messenger | +| 기본 언어 | 한국어 | +| 앱 유형 | 앱 | +| 무료/유료 | 무료 | + +### 3-2. 스토어 등록 정보 + +**앱 이름**: GUARDiA Messenger + +**간략한 설명** (80자 이내): +``` +AI 기반 IT 인프라 자율 운영 플랫폼 — GUARDiA ITSM 모바일 앱 +``` + +**자세한 설명** (4000자 이내): +``` +GUARDiA Messenger는 (주)지오정보기술의 AI 기반 레거시 인프라 자율 운영 플랫폼 +GUARDiA ITSM과 연동하는 공식 모바일 앱입니다. + +주요 기능: +• 서비스 요청(SR) 실시간 조회 및 등록 +• AI 챗봇을 통한 자연어 인프라 명령 +• 인시던트 및 긴급 알림 즉시 수신 +• SLA 위반 경고 및 배포 상태 모니터링 +• 라이선스 현황 확인 + +GUARDiA ITSM 서버 주소 입력 후 사용 가능합니다. + +[지원]: guardia@zioinfo.co.kr +[회사]: (주)지오정보기술 +``` + +**카테고리**: 비즈니스 + +**키워드**: ITSM, 인프라관리, IT운영, 서버관리, ChatOps, 모니터링 + +### 3-3. 콘텐츠 등급 설문 + +- 폭력: 없음 +- 성인 콘텐츠: 없음 +- 도박: 없음 +- → **모든 연령** 등급 + +### 3-4. AAB 업로드 + +``` +프로덕션 트랙 → 새 버전 만들기 +→ eas build에서 다운로드한 .aab 업로드 +→ 버전 노트 (한국어): + "GUARDiA Messenger 첫 번째 릴리즈 + - 대시보드, SR 관리, AI 챗봇, 알림" +→ 검토 시작 (2~7일 소요) +``` + +--- + +## 4. Apple App Store 등록 + +### 4-1. App Store Connect 앱 생성 + +1. **appstoreconnect.apple.com** 접속 +2. [나의 앱] → [+] → [새 앱] +3. 정보 입력: + +| 항목 | 값 | +|------|-----| +| 플랫폼 | iOS | +| 이름 | GUARDiA Messenger | +| 기본 언어 | 한국어 | +| 번들 ID | kr.co.zioinfo.guardia | +| SKU | guardia-messenger-kr | + +### 4-2. 앱 정보 + +**카테고리**: 비즈니스 (Business) + +**부제**: AI 기반 IT 인프라 운영 플랫폼 + +**프라이버시 정책 URL**: +``` +https://zioinfo.co.kr/privacy +``` + +> ⚠️ App Store는 Privacy Policy URL이 필수입니다. 홈페이지에 개인정보처리방침 페이지를 추가해야 합니다. + +### 4-3. 스크린샷 + +각 기기별 최소 1개 스크린샷 필요: +- iPhone 6.7인치 (1290×2796): 필수 +- iPhone 6.5인치 (1242×2688): 필수 +- iPad Pro 12.9인치: 선택 + +```bash +# EAS로 시뮬레이터 스크린샷 자동 생성 (권장) +eas metadata:pull +``` + +### 4-4. IPA 업로드 및 심사 + +```bash +# EAS Submit으로 자동 업로드 +eas submit --platform ios --profile production + +# 또는 Transporter 앱 사용 (Mac에서) +``` + +심사 기간: **1~3일** (영업일 기준) + +--- + +## 5. 전체 진행 순서 + +``` +1. Expo 계정 생성 (expo.dev) + ↓ +2. eas login / eas init + ↓ +3. Google Play Console 개발자 등록 ($25) + ↓ +4. Apple Developer Program 등록 ($99/년) + ↓ +5. eas build --platform android --profile production + ↓ +6. eas build --platform ios --profile production + ↓ +7. 각 스토어에 메타데이터 등록 + ↓ +8. 빌드 업로드 (eas submit 또는 수동) + ↓ +9. 심사 대기 (Android 2~7일, iOS 1~3일) + ↓ +10. 출시 🎉 +``` + +--- + +## 6. 개인정보처리방침 (홈페이지 추가 필요) + +App Store 필수 요구사항: + +``` +zioinfo.co.kr/privacy 페이지에 아래 내용 추가: + +1. 수집 정보: 이메일, 사용자명 (JWT 인증 목적) +2. 보관 기간: 앱 삭제 시 즉시 삭제 (기기 내 보관) +3. 제3자 제공: 없음 +4. 문의: guardia@zioinfo.co.kr +``` + +--- + +## 7. 빠른 시작 명령어 + +```bash +# 1. EAS 설정 +cd C:\GUARDiA\app +npm install -g eas-cli +eas login +eas init + +# 2. Android 빌드 (바로 가능) +eas build --platform android --profile preview +# → APK 다운로드 URL 생성 (테스트 설치 가능) + +# 3. 정식 빌드 +eas build --platform android --profile production +eas build --platform ios --profile production +``` + +--- + +*GUARDiA Messenger v1.0.0 | (주)지오정보기술 | 2026-05-31* diff --git a/34_GUARDiA_Messenger_개발_배포_가이드.md b/34_GUARDiA_Messenger_개발_배포_가이드.md new file mode 100644 index 0000000..f0b1cd9 --- /dev/null +++ b/34_GUARDiA_Messenger_개발_배포_가이드.md @@ -0,0 +1,288 @@ +# GUARDiA Messenger 개발 및 배포 가이드 + +> **버전**: 1.0.0 | **작성일**: 2026-05-31 +> **기술 스택**: React Native + Expo SDK 51 + EAS Build +> **EAS 계정**: zioinfo | **성공 빌드**: 51096ada + +--- + +## 1. 앱 개요 + +GUARDiA Messenger는 (주)지오정보기술의 GUARDiA ITSM 플랫폼과 연동하는 공식 모바일 앱입니다. + +### 주요 기능 + +| 화면 | 기능 | +|------|------| +| 로그인 | GUARDiA ITSM JWT 인증 | +| 대시보드 | SR 통계, 서비스 상태, 배포 이력 | +| SR 관리 | 서비스 요청 목록 조회 및 신규 등록 | +| AI 챗봇 | Ollama LLM 기반 자연어 인프라 명령 | +| 알림 | 인시던트·SLA·배포 알림 수신 | +| 설정 | 프로필, 알림 설정, 로그아웃 | + +### 기술 스택 + +| 항목 | 기술 | +|------|------| +| 프레임워크 | React Native 0.74.5 + Expo SDK 51 | +| 언어 | TypeScript (strict) | +| 라우터 | Expo Router 3.5.x | +| 인증 저장소 | expo-secure-store (보안 키체인) | +| HTTP 클라이언트 | Axios | +| 빌드 시스템 | EAS Build (Expo Application Services) | +| 서버 연결 | https://zioinfo.co.kr:8443 | + +--- + +## 2. 개발 환경 설정 + +### 2-1. 필수 설치 + +```bash +# Node.js 20 LTS +node --version # v20 이상 + +# Expo CLI +npm install -g expo-cli eas-cli + +# 프로젝트 설치 +cd C:\GUARDiA\app +npm install --legacy-peer-deps +``` + +### 2-2. 로컬 개발 서버 + +```bash +cd C:\GUARDiA\app +npx expo start + +# QR 코드 스캔 → Expo Go 앱에서 실행 (개발 전용) +# 또는 npx expo start --android (에뮬레이터) +``` + +### 2-3. 프로젝트 구조 + +``` +C:\GUARDiA\app\ +├── app/ +│ ├── _layout.tsx ← 루트 레이아웃 (인증 라우팅) +│ ├── (auth)/login.tsx ← 로그인 +│ └── (tabs)/ +│ ├── _layout.tsx ← 탭 네비게이터 +│ ├── index.tsx ← 대시보드 +│ ├── sr.tsx ← SR 관리 +│ ├── chat.tsx ← AI 챗봇 +│ ├── notifications.tsx← 알림 +│ └── settings.tsx ← 설정 +├── components/ ← 공통 컴포넌트 +├── constants/Config.ts ← 서버 URL, 컬러 시스템 +├── hooks/useAuth.ts ← JWT 인증 훅 +├── services/api.ts ← GUARDiA ITSM API 클라이언트 +├── plugins/ +│ └── withGradleProps.js ← Gradle 빌드 최적화 +├── assets/ ← 아이콘, 스플래시 이미지 +├── app.json ← Expo 앱 설정 +├── eas.json ← EAS 빌드 프로필 +├── babel.config.js ← Babel 설정 +└── .easignore ← EAS 업로드 제외 목록 +``` + +--- + +## 3. EAS Build 가이드 + +### 3-1. EAS 초기 설정 (최초 1회) + +```bash +cd C:\GUARDiA\app + +# EAS 로그인 +npx eas-cli login +# → expo.dev 계정 입력 + +# 프로젝트 초기화 +npx eas-cli init +# → 프로젝트 ID 자동 등록 +``` + +### 3-2. 빌드 명령어 + +```bash +# Android APK (테스트 배포 — 약 10~15분) +npx eas-cli build --platform android --profile preview + +# Android AAB (Play Store 제출용) +npx eas-cli build --platform android --profile production + +# iOS IPA (App Store 제출용, Apple Developer $99/년 필요) +npx eas-cli build --platform ios --profile production +``` + +### 3-3. 빌드 전 필수 체크리스트 + +| 항목 | 확인 방법 | 올바른 상태 | +|------|---------|-----------| +| android/ 폴더 없음 | `ls android/` | 없어야 함 | +| .easignore 설정 | `cat .easignore` | `android/`, `ios/` 포함 | +| PNG Crunching 비활성화 | `cat plugins/withGradleProps.js` | `false` 확인 | +| babel.config.js | `cat babel.config.js` | `babel-preset-expo`만 | +| EAS 로그인 | `npx eas-cli whoami` | `zioinfo` 표시 | + +### 3-4. APK 폰 설치 방법 + +1. 안드로이드 폰에서 **Expo 빌드 URL** 열기 +2. **Download** 버튼 탭 +3. 설정 → 보안 → 알 수 없는 앱 설치 허용 (최초 1회) +4. APK 설치 완료 + +> **주의**: `adb` / Android Studio 불필요 — 브라우저 직접 다운로드로 설치 + +--- + +## 4. 빌드 이슈 이력 및 해결책 + +> 이 섹션은 실제 빌드 과정에서 발생한 이슈와 해결책입니다. 동일한 이슈 재발 시 이 섹션을 참조하세요. + +### 이슈 1: android/ 폴더 → EAS Bare Workflow 오인 + +**증상**: `EAS_BUILD_UNKNOWN_GRADLE_ERROR` (반복 실패) + +**원인 흐름**: +``` +로컬 expo prebuild 실행 + → android/ 폴더 생성 + → EAS 업로드에 포함 + → EAS: "Bare Workflow 프로젝트" 인식 + → 로컬 android/ 그대로 사용 (EAS 환경과 불일치) + → Gradle 빌드 실패 +``` + +**해결**: `.easignore` 파일에 추가 +``` +android/ +ios/ +``` + +### 이슈 2: PIL PNG + AAPT2 PNG Crunching 충돌 + +**증상**: `expo-splash-screen:packageReleaseResources` 단계 실패 + +**원인**: Python PIL 생성 PNG + `enablePngCrunchInReleaseBuilds=true` → AAPT2 처리 불가 + +**해결**: `plugins/withGradleProps.js` 생성 +```javascript +const { withGradleProperties } = require('@expo/config-plugins') +module.exports = function(config) { + return withGradleProperties(config, (cfg) => { + const set = (key, value) => { + const idx = cfg.modResults.findIndex(p => p.key === key) + idx !== -1 ? cfg.modResults[idx].value = value + : cfg.modResults.push({ type:'property', key, value }) + } + set('android.enablePngCrunchInReleaseBuilds', 'false') + set('reactNativeArchitectures', 'arm64-v8a') + set('org.gradle.jvmargs', '-Xmx4096m -XX:MaxMetaspaceSize=1024m') + return cfg + }) +} +``` + +### 이슈 3: expo-notifications 플러그인 빌드 실패 + +**증상**: Firebase 관련 Gradle 오류 + +**원인**: `expo-notifications` 플러그인이 `google-services.json` 파일 필요 + +**해결**: `app.json` plugins에서 `expo-notifications` 제거. 푸시 알림 추가 시 Firebase 설정 후 재등록. + +### 이슈 4: expo-router/babel deprecated + +**증상**: Babel 경고, 일부 환경에서 빌드 오류 + +**해결**: `babel.config.js` +```javascript +module.exports = function(api) { + api.cache(true) + return { presets: ['babel-preset-expo'] } +} +``` + +### 최종 성공한 빌드 + +| 항목 | 값 | +|------|-----| +| 빌드 ID | 51096ada-9735-4ea8-9e81-5f5991731ea8 | +| 플랫폼 | Android (APK) | +| EAS 계정 | zioinfo | +| 소요 시간 | 약 12분 | + +--- + +## 5. 스토어 등록 절차 + +### 5-1. 사전 준비 + +| 항목 | Google Play | Apple App Store | +|------|------------|-----------------| +| 개발자 계정 | $25 (1회) | $99/년 | +| Privacy Policy | 필수 | 필수 | +| 스크린샷 | 최소 2개 | 최소 3개 (6.7인치) | +| APK/IPA | AAB 파일 | IPA 파일 | + +### 5-2. Google Play Store 등록 + +``` +1. play.google.com/console 접속 +2. [앱 만들기] → 패키지명: kr.co.zioinfo.guardia +3. 스토어 등록정보 → 메타데이터 입력 +4. 콘텐츠 등급 → 모든 연령 (비즈니스 앱) +5. 프로덕션 트랙 → AAB 업로드 +6. 검토 제출 (2~7 영업일) +``` + +### 5-3. Apple App Store 등록 + +``` +1. appstoreconnect.apple.com 접속 +2. [새 앱] → 번들 ID: kr.co.zioinfo.guardia +3. 앱 정보 + 스크린샷 업로드 +4. Privacy Policy URL 등록 (필수!) +5. npx eas-cli submit --platform ios --profile production +6. 심사 제출 (1~3 영업일) +``` + +--- + +## 6. 앱 로그인 정보 + +| 항목 | 값 | +|------|-----| +| 서버 URL | https://zioinfo.co.kr:8443 | +| 관리자 계정 | admin | +| 비밀번호 | Admin@zioinfo2026! | + +--- + +## 7. 하네스 사용법 + +이 프로젝트는 `.claude/` 하네스가 구성되어 있습니다. + +``` +기능 개발 요청: "SR 상세 화면 추가해줘" + → messenger-orchestrator 스킬 트리거 + → rn-developer가 화면 구현 + → eas-engineer가 빌드 검증 + +빌드 요청: "Android APK 빌드해줘" + → eas-build-deploy 스킬 참조 + → 체크리스트 확인 후 빌드 실행 + +스토어 등록: "Play Store 등록 도와줘" + → store-publish 스킬 참조 + → 메타데이터 + 절차 가이드 +``` + +--- + +*GUARDiA Messenger v1.0.0 | (주)지오정보기술 | 2026-05-31* diff --git a/35_GUARDiA_Messenger_개발가이드.pdf b/35_GUARDiA_Messenger_개발가이드.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d76cdace8bdff76375a4f6a36192e5af4cbebe5e GIT binary patch literal 69652 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 literal 0 HcmV?d00001 diff --git a/36_GUARDiA_Messenger_발표자료.pptx b/36_GUARDiA_Messenger_발표자료.pptx new file mode 100644 index 0000000000000000000000000000000000000000..9230d767f26133f67f23a742d876de54d1dfea3f GIT binary patch literal 42229 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 literal 0 HcmV?d00001 diff --git a/37_세션_전체_작업_요약.md b/37_세션_전체_작업_요약.md new file mode 100644 index 0000000..61160e4 --- /dev/null +++ b/37_세션_전체_작업_요약.md @@ -0,0 +1,206 @@ +# GUARDiA 프로젝트 세션 전체 작업 요약 + +> **세션 날짜**: 2026-05-30 ~ 2026-05-31 +> **작성 목적**: clear 전 중요 내용 및 스킬 보존 + +--- + +## 1. 서버 구성 (zioinfo.co.kr) + +### 설치 완료 SW + +| 카테고리 | SW | 포트 | +|----------|-----|------| +| 웹 서버 | Nginx 1.24 | 80/443 | +| 홈페이지 | Spring Boot 3.2.5 | 8082 | +| ITSM | GUARDiA FastAPI v2.0 | 8001/8443 | +| 관리자 | GUARDiA Manager | 8090/8002 | +| DB | PostgreSQL 16.11 | 5432 | +| AI | Ollama + Llama3:8b + nomic-embed-text | 11434 | +| AI 프레임워크 | LangChain 1.3.2 + ChromaDB 1.5.9 | - | +| Git | Gitea 1.22.3 | 3000 | +| CI/CD | Jenkins 2.555 + Deploy Webhook | 8080/9999 | +| 메일 | Postfix + Dovecot | 25/587/143/993 | + +### Gitea 저장소 + +``` +http://zioinfo.co.kr:3000 +├── zio/zioinfo-web ← 홈페이지 (Spring Boot + React) +├── zio/guardia-itsm ← GUARDiA ITSM (FastAPI) +└── zio/guardia-messenger ← GUARDiA Messenger (React Native) +``` + +### CI/CD 흐름 + +``` +git push gitea main + → Gitea Webhook → Deploy Server(9999) + → git pull → 빌드 → systemctl restart +``` + +--- + +## 2. 개발 완료 시스템 + +### 2-1. GUARDiA ITSM (기존 + 추가) + +- **개방망 지원**: HTTPS 8443, API Key 인증, CORS 외부 허용 +- **라이선스**: TRIAL/COMMUNITY/STANDARD/ENTERPRISE 관리 +- **Export/Import**: 폐쇄망 데이터 번들 (HMAC-SHA256 서명) +- **AI 프레임워크**: LangChain + ChromaDB + 코드베이스 임베딩 +- **datetime 버그 수정**: timezone-aware/naive 충돌 → .replace(tzinfo=None) + +### 2-2. GUARDiA Manager (신규) + +``` +http://zioinfo.co.kr:8090 +``` + +| 화면 | 기능 | +|------|------| +| 대시보드 | SR 통계, 리소스 게이지, 배포 타임라인 | +| 서버/CMDB | 자산 목록, 서비스 재시작 | +| 배포/CI-CD | 배포 이력, 수동 트리거 | +| 보안 | API Key 발급/관리, 감사 로그 | +| 라이선스 | 에디션 관리, 체험판 발급, 이력 | +| 데이터 연동 | Export/Import (폐쇄망 연동) | +| LLM | Ollama 모델 현황 | +| 설정 | .env 뷰어, Nginx 리로드 | + +### 2-3. GUARDiA Messenger (신규) + +``` +패키지: kr.co.zioinfo.guardia +EAS 계정: zioinfo / 프로젝트: ca2f72d6-... +성공 빌드: 51096ada (Android APK) +``` + +**⚠️ EAS 빌드 필수 원칙**: +1. `.easignore`: android/, ios/ 반드시 포함 +2. `plugins/withGradleProps.js`: `enablePngCrunchInReleaseBuilds=false` +3. `expo-notifications`: app.json plugins 등록 금지 +4. `babel.config.js`: `babel-preset-expo`만 사용 + +**알림 연동**: +- WebSocket: `wss://zioinfo.co.kr:8443/ws/events?token={jwt}` +- 채널: sr, deploy, sla, incident +- `hooks/useWebSocket.ts` 구현 완료 + +### 2-4. 홈페이지 관리자시스템 (신규) + +``` +http://zioinfo.co.kr/admin +계정: admin / Admin@2026! +``` + +- JWT 인증 (GUARDiA ITSM 공유) +- 뉴스/채용/문의 CRUD +- Spring Security + jjwt 0.12.3 + +--- + +## 3. SMTP 메일 서버 + +``` +도메인: @zioinfo.co.kr +서버: mail.zioinfo.co.kr (zioinfo.co.kr) +``` + +| 항목 | 값 | +|------|-----| +| 계정 | info, admin, ythong, choyounbun, guardia | +| 비밀번호 | 1q2w3e!Q (모두 동일) | +| SMTP | :25 / :587 (STARTTLS) | +| IMAP | :143 / :993 (SSL) | +| SPF | v=spf1 ip4:zioinfo.co.kr ~all (가비아) | +| DKIM | mail._domainkey.zioinfo.co.kr (가비아) | +| DMARC | _dmarc.zioinfo.co.kr (가비아) | + +**스팸 방지 중요사항**: +- 이메일 본문에 `http://zioinfo.co.kr:8001` 같은 IP 직접 링크 금지 → 피싱 경고 발생 +- PTR 역방향 DNS 없음 → Gmail 스팸 가능성 → NCloud 지원에 PTR 설정 요청 필요 + +--- + +## 4. 하네스 구조 + +### C:\GUARDiA\itsm (GUARDiA ITSM) + +``` +.claude/agents/: sr-manager, deploy-engineer, incident-responder, sla-guardian +.claude/skills/: guardia-orchestrator, deploy-pipeline, sr-lifecycle, code-review +``` + +### C:\GUARDiA\manager (GUARDiA Manager) + +``` +.claude/agents/: ux-architect, backend-engineer, integration-specialist, security-engineer, devops-engineer +.claude/skills/: manager-orchestrator, manager-ui, manager-api, manager-integration, manager-security, manager-deploy +``` + +### C:\GUARDiA\app (GUARDiA Messenger) + +``` +.claude/agents/: rn-developer, eas-engineer, store-publisher, doc-writer +.claude/skills/: messenger-orchestrator, rn-screen-dev, eas-build-deploy, store-publish, doc-generator + └── rn-screen-dev/references/build-issues.md ← EAS 빌드 이슈 이력 (매우 중요) +``` + +### C:\GUARDiA\workspace\zioinfo-web (홈페이지) + +``` +트리거: workspace-analyzer 스킬 +``` + +--- + +## 5. 매뉴얼 파일 목록 (C:\GUARDiA\manual) + +| 번호 | 파일 | 내용 | +|------|------|------| +| 18 | zio서버_설치SW_목록.md | 전체 SW 목록 | +| 19 | zio서버_운영가이드.md | 운영 절차 | +| 20 | zio서버_CICD_가이드.md | CI/CD 흐름 | +| 21 | zio서버_장애대응_가이드.md | Runbook | +| 22 | GUARDiA_개방망_운영가이드.md | 개방망 설정 | +| 23-24 | 개방망 PDF/PPTX | - | +| 25 | Manager 라이선스 가이드.md | 라이선스 관리 | +| 26-27 | 라이선스 PDF/PPTX | - | +| 28 | 폐쇄망_데이터연동_가이드.md | Export/Import | +| 29-30 | 데이터연동 PDF/PPTX | - | +| 31 | AI_플랫폼_제안서.md | LangChain/ChromaDB 제안 | +| 32 | 벡터DB_제안서.md | ChromaDB 상세 | +| 33 | Messenger_스토어_등록_가이드.md | Play Store/App Store | +| 34 | Messenger_개발_배포_가이드.md | EAS 빌드 가이드 | +| 35-36 | Messenger PDF/PPTX | - | + +--- + +## 6. 주요 계정 정보 + +| 서비스 | ID | PW | +|--------|----|----| +| SSH | root | 1q2w3e!Q | +| GUARDiA ITSM | admin | 1111 | +| GUARDiA Manager | admin | Admin@zioinfo2026! | +| 홈페이지 관리자 | admin | Admin@2026! | +| Gitea | zio | Zio@Admin2026! | +| PostgreSQL | guardia | G@urd1a_2026! (URL: G%40urd1a_2026%21) | +| SMTP 계정 | *@zioinfo.co.kr | 1q2w3e!Q | +| Expo EAS | zioinfo | expo.dev 로그인 | + +--- + +## 7. 알림 테스트 결과 + +### ITSM → Messenger (8/8 PASS) +JWT → WebSocket 연결 → SR 이벤트 브로드캐스트 → 앱 알림탭 수신 + +### Messenger → ITSM (10/10 PASS) +앱 SR탭 등록 → POST /api/tasks → ITSM SR 생성 확인 +AI챗봇 → "nginx 재시작해줘" → AI가 SR 자동 생성 응답 + +--- + +*GUARDiA 프로젝트 세션 정리 | 2026-05-31* diff --git a/38_스킬_트리거_빠른참조.md b/38_스킬_트리거_빠른참조.md new file mode 100644 index 0000000..c9df3ea --- /dev/null +++ b/38_스킬_트리거_빠른참조.md @@ -0,0 +1,81 @@ +# GUARDiA 하네스 스킬 빠른 참조 + +> 새 세션에서 각 스킬을 트리거하는 키워드 모음 + +--- + +## GUARDiA ITSM (C:\GUARDiA\itsm) + +| 스킬 | 트리거 키워드 | +|------|------------| +| `guardia-orchestrator` | SR 처리, 배포 진행, 코드 리뷰, SLA 현황, 인시던트, RCA, 보안 패치, Jira 연동, 다시 실행 | +| `deploy-pipeline` | 배포, 빌드, 릴리즈, Jenkins, VibeSession | +| `sr-lifecycle` | SR 접수, SR 조회, 티켓 관리 | + +--- + +## GUARDiA Manager (C:\GUARDiA\manager) + +| 스킬 | 트리거 키워드 | +|------|------------| +| `manager-orchestrator` | 관리자 화면, M-01~M-08, 대시보드 수정, 서버 관리, 배포 관리, 가이드 작성, 다시 실행 | +| `manager-ui` | 화면 구현, 컴포넌트, NCloud 스타일, 대시보드 차트 | +| `manager-api` | FastAPI 백엔드, 시스템 API, 서비스 제어 | +| `manager-integration` | GUARDiA API 연동, Gitea 연동, Ollama 조회 | +| `manager-security` | JWT 인증, Route Guard, API Key 보안 | +| `manager-deploy` | Nginx 설정, systemd, 배포 파이프라인 | + +--- + +## GUARDiA Messenger (C:\GUARDiA\app) + +| 스킬 | 트리거 키워드 | +|------|------------| +| `messenger-orchestrator` | 화면 추가, 기능 구현, EAS 빌드, APK, Play Store, App Store, 가이드 작성, 다시 실행 | +| `rn-screen-dev` | 화면 구현, 컴포넌트, UI 수정, API 연동 | +| `eas-build-deploy` | EAS 빌드, APK 빌드, Gradle 오류, 빌드 실패 | +| `store-publish` | Play Store, App Store, 스크린샷, Privacy Policy | +| `doc-generator` | 가이드 작성, PDF 생성, PPTX 생성, 문서화 | + +--- + +## 홈페이지 (C:\GUARDiA\workspace\zioinfo-web) + +| 스킬 | 트리거 키워드 | +|------|------------| +| `workspace-analyzer` | 소스 분석, 개발환경 가이드, 하네스 적용, workspace | + +--- + +## 주요 빠른 명령 + +```bash +# GUARDiA ITSM 재시작 +ssh root@zioinfo.co.kr "systemctl restart guardia" + +# EAS Android 빌드 (C:\GUARDiA\app에서) +npx eas-cli build --platform android --profile preview + +# Gitea Push (홈페이지) +cd C:\GUARDiA\workspace\zioinfo-web +git push gitea main:main + +# 서버 전체 상태 확인 +ssh root@zioinfo.co.kr "for s in nginx zioinfo guardia guardia-manager gitea jenkins postgresql; do printf '%-22s %s\n' $s $(systemctl is-active $s); done" +``` + +--- + +## ⚠️ 자주 발생하는 오류와 해결 + +| 오류 | 원인 | 해결 | +|------|------|------| +| GUARDiA 500 시작 실패 | DATABASE_URL의 @를 %40으로 인코딩 안함 | .env에서 G@urd1a → G%40urd1a%21 | +| EAS Gradle 실패 | android/ 폴더가 업로드됨 | .easignore에 android/, ios/ 추가 | +| EAS packageReleaseResources 실패 | PIL PNG + AAPT2 충돌 | plugins/withGradleProps.js 확인 | +| Gmail 피싱 경고 | 본문에 IP 직접 링크 포함 | http://zioinfo.co.kr:8001 URL 제거 | +| Gmail 스팸 분류 | PTR 레코드 없음, DMARC 없음 | NCloud PTR 신청, 가비아 DMARC 등록 | +| Nginx IPv6 오류 | NCloud가 IPv4 only | sed로 [::]:80 제거 후 nginx -t | +| Dovecot 시작 실패 | IPv6 listen 시도 | dovecot.conf에 listen = 0.0.0.0 | + +*GUARDiA 프로젝트 | 2026-05-31* diff --git a/gen_export_docs.py b/gen_export_docs.py new file mode 100644 index 0000000..9443816 --- /dev/null +++ b/gen_export_docs.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python3 +"""Export/Import 가이드 PDF + PPTX 생성""" +from pathlib import Path +OUT_DIR = Path(__file__).parent + +def gen_pdf(out): + from reportlab.lib.pagesizes import A4 + from reportlab.lib import colors + from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle + from reportlab.lib.units import mm + from reportlab.lib.enums import TA_CENTER + from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable, PageBreak + from reportlab.pdfbase import pdfmetrics + from reportlab.pdfbase.ttfonts import TTFont + import os + + FONT_DIRS = ["C:/Windows/Fonts","/usr/share/fonts/truetype/noto","/usr/share/fonts/truetype/dejavu"] + font = "Helvetica" + for fn,alias in [("malgun.ttf","Malgun"),("NanumGothic.ttf","NanumGothic"),("DejaVuSans.ttf","DejaVuSans")]: + for d in FONT_DIRS: + fp = os.path.join(d,fn) + if os.path.exists(fp): + try: pdfmetrics.registerFont(TTFont(alias,fp)); font=alias; break + except: pass + if font != "Helvetica": break + + BRAND=colors.HexColor("#1a3a6b"); ACCENT=colors.HexColor("#4f6ef7") + GREEN=colors.HexColor("#22c55e"); GRAY=colors.HexColor("#f0f2f5") + MUTED=colors.HexColor("#64748b") + + doc = SimpleDocTemplate(out,pagesize=A4,leftMargin=20*mm,rightMargin=20*mm,topMargin=20*mm,bottomMargin=20*mm) + W = A4[0]-40*mm + styles = getSampleStyleSheet() + def sty(name,**kw): + kw.setdefault("fontName",font) + return ParagraphStyle(name,parent=styles["Normal"],**kw) + def hr(c=None): return HRFlowable(width="100%",thickness=1,color=c or ACCENT,spaceAfter=4,spaceBefore=4) + def tbl(data,cws=None,hdr=True): + t=Table(data,colWidths=cws) + base=[("FONTNAME",(0,0),(-1,-1),font),("FONTSIZE",(0,0),(-1,-1),9), + ("ROWBACKGROUNDS",(0,1),(-1,-1),[colors.white,GRAY]), + ("GRID",(0,0),(-1,-1),.5,colors.HexColor("#e2e8f0")), + ("VALIGN",(0,0),(-1,-1),"MIDDLE"), + ("LEFTPADDING",(0,0),(-1,-1),6),("RIGHTPADDING",(0,0),(-1,-1),6), + ("TOPPADDING",(0,0),(-1,-1),5),("BOTTOMPADDING",(0,0),(-1,-1),5)] + if hdr:base+=[("BACKGROUND",(0,0),(-1,0),BRAND),("TEXTCOLOR",(0,0),(-1,0),colors.white), + ("FONTNAME",(0,0),(-1,0),font)] + t.setStyle(TableStyle(base)); return t + + S={"h1":sty("h1",fontSize=18,textColor=BRAND,spaceBefore=16,spaceAfter=8,leading=24), + "h2":sty("h2",fontSize=13,textColor=ACCENT,spaceBefore=10,spaceAfter=5,leading=18), + "body":sty("body",fontSize=10,textColor=colors.HexColor("#1e293b"),leading=16,spaceAfter=4), + "code":sty("code",fontName="Courier",fontSize=9,backColor=GRAY, + textColor=colors.HexColor("#1d4ed8"),leading=14,leftIndent=10,spaceBefore=3,spaceAfter=3), + "note":sty("note",fontSize=9,textColor=MUTED,leftIndent=10,leading=14,spaceAfter=3)} + + story=[] + + # 표지 + cover=Table([[Paragraph("GUARDiA 폐쇄망 ↔ 개방망",sty("ct",fontSize=26,textColor=colors.white,alignment=TA_CENTER,leading=34))], + [Paragraph("데이터 Export / Import 가이드",sty("cs",fontSize=16,textColor=colors.HexColor("#aac4e8"),alignment=TA_CENTER))], + [Paragraph("v1.0.0 | 2026-05-30 | (주)지오정보기술",sty("cm",fontSize=10,textColor=colors.HexColor("#7c85a8"),alignment=TA_CENTER))]], + colWidths=[W]) + cover.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),BRAND), + ("TOPPADDING",(0,0),(-1,-1),35),("BOTTOMPADDING",(0,0),(-1,-1),35), + ("LEFTPADDING",(0,0),(-1,-1),20),("RIGHTPADDING",(0,0),(-1,-1),20)])) + story+=[Spacer(1,30*mm),cover,PageBreak()] + + story+=[Paragraph("1. 개요",S["h1"]),hr(), + Paragraph("폐쇄망 GUARDiA ITSM의 데이터를 개방망 GUARDiA Manager로 안전하게 이관합니다. " + "번들 파일에 HMAC-SHA256 서명을 포함하여 위변조를 방지하며, 민감 정보는 자동 마스킹됩니다.",S["body"]), + Spacer(1,6),Paragraph("1-1. 보안 특징",S["h2"]), + tbl([["특징","내용"],["HMAC-SHA256 서명","번들 ZIP 위변조 방지"], + ["민감 정보 마스킹","IP 주소, SSH 비밀번호 → '****' 처리"], + ["Dry Run 모드","실제 저장 전 사전 검증"], + ["중복 방지","sr_id 기준 중복 SKIP"]],cws=[55*mm,110*mm]), + Spacer(1,10),Paragraph("2. API 엔드포인트",S["h1"]),hr(), + tbl([["메서드","경로","설명"], + ["GET","/api/export-import/export/bundle","전체 번들 ZIP (권장)"], + ["GET","/api/export-import/export/sr","SR 목록 JSON"], + ["GET","/api/export-import/export/cmdb","CMDB 서버 자산 JSON"], + ["GET","/api/export-import/export/institutions","기관 목록 JSON"], + ["GET","/api/export-import/export/audit","감사 로그 JSON"], + ["POST","/api/export-import/import/bundle","번들 ZIP Import"], + ["POST","/api/export-import/import/sr","SR JSON Import"]], + cws=[18*mm,75*mm,72*mm]), + PageBreak(), + Paragraph("3. 연동 흐름",S["h1"]),hr(), + tbl([["단계","작업","비고"], + ["1","폐쇄망 서버에서 번들 Export","GET /export/bundle → ZIP 다운로드"], + ["2","USB/보안매체로 ZIP 이동","Air Gap 환경 고려"], + ["3","Manager UI에서 파일 업로드","http://zioinfo.co.kr:8090/export-import"], + ["4","Dry Run 검증 실행","HMAC 서명 + 데이터 카운트 확인"], + ["5","Import 실행 (dry_run=false)","중복 sr_id 자동 SKIP"]],cws=[12*mm,75*mm,78*mm]), + Spacer(1,10),Paragraph("4. 테스트 결과 (7/7 PASS)",S["h1"]),hr(), + tbl([["#","테스트 항목","결과"], + ["T1","SR Export (5건)","PASS"], + ["T2","CMDB Export (6건)","PASS"], + ["T3","기관 Export (3건)","PASS"], + ["T4","감사 로그 Export (5건)","PASS"], + ["T5","번들 ZIP Export (HMAC 서명)","PASS"], + ["T6","SR Import dry_run","PASS"], + ["T7","Manager UI /export-import","PASS"]],cws=[12*mm,90*mm,63*mm]), + Spacer(1,6), + Paragraph("버그 수정: date 타입 JSON 직렬화 오류 → isoformat() 처리 완료", + sty("fix",fontSize=10,textColor=GREEN,fontName=font)), + Spacer(1,12), + hr(colors.HexColor("#e2e8f0")), + Paragraph("GUARDiA ITSM v2.0.0 | (주)지오정보기술 | 2026-05-30", + sty("foot",fontSize=8,textColor=MUTED,alignment=TA_CENTER,fontName=font))] + + doc.build(story) + print(f"PDF: {out}") + +def gen_pptx(out): + from pptx import Presentation + from pptx.util import Inches, Pt + from pptx.dml.color import RGBColor + from pptx.enum.text import PP_ALIGN + + W,H=Inches(13.33),Inches(7.5) + prs=Presentation(); prs.slide_width=W; prs.slide_height=H + + BRAND=RGBColor(0x1a,0x3a,0x6b); ACCENT=RGBColor(0x4f,0x6e,0xf7) + WHITE=RGBColor(0xff,0xff,0xff); GRAY=RGBColor(0xf0,0xf2,0xf5) + GREEN=RGBColor(0x22,0xc5,0x5e); MUTED=RGBColor(0x64,0x74,0x8b) + DARK=RGBColor(0x1e,0x29,0x3b) + + def blank(): return prs.slides.add_slide(prs.slide_layouts[6]) + def rect(sl,x,y,w,h,fill=None): + s=sl.shapes.add_shape(1,x,y,w,h) + if fill: s.fill.solid(); s.fill.fore_color.rgb=fill + else: s.fill.background() + s.line.fill.background(); return s + def text(sl,t,x,y,w,h,sz=14,bold=False,color=DARK,align=PP_ALIGN.LEFT): + tb=sl.shapes.add_textbox(x,y,w,h); tf=tb.text_frame; tf.word_wrap=True + p=tf.paragraphs[0]; p.alignment=align; r=p.add_run(); r.text=t + r.font.size=Pt(sz); r.font.bold=bold; r.font.color.rgb=color + def tbl_sl(sl,hdrs,rows,x,y,w,h,cws=None): + t=sl.shapes.add_table(len(rows)+1,len(hdrs),x,y,w,h).table + if cws: + for i,cw in enumerate(cws): t.columns[i].width=cw + def cell(c,v,bg=None,clr=DARK,bold=False): + c.text=str(v); c.text_frame.paragraphs[0].font.size=Pt(9) + c.text_frame.paragraphs[0].font.bold=bold + c.text_frame.paragraphs[0].font.color.rgb=clr + if bg: c.fill.solid(); c.fill.fore_color.rgb=bg + for j,h in enumerate(hdrs): cell(t.cell(0,j),h,bg=BRAND,clr=WHITE,bold=True) + for i,row in enumerate(rows): + bg=GRAY if i%2==0 else WHITE + for j,v in enumerate(row): cell(t.cell(i+1,j),v,bg=bg) + + # S1 표지 + s=blank() + rect(s,0,0,W,H,fill=BRAND) + rect(s,Inches(.5),Inches(1.2),Inches(12.33),Inches(4.0),fill=RGBColor(0x25,0x4a,0x80)) + text(s,"GUARDiA 폐쇄망 ↔ 개방망",Inches(.8),Inches(1.5),Inches(11.73),Inches(1.0),sz=38,bold=True,color=WHITE,align=PP_ALIGN.CENTER) + text(s,"데이터 Export / Import 연동 가이드",Inches(.8),Inches(2.7),Inches(11.73),Inches(.7),sz=20,color=RGBColor(0xaa,0xc4,0xe8),align=PP_ALIGN.CENTER) + text(s,"v1.0.0 | 2026-05-30 | (주)지오정보기술",Inches(.8),Inches(3.5),Inches(11.73),Inches(.5),sz=13,color=MUTED,align=PP_ALIGN.CENTER) + for i,(t_,c) in enumerate([("🔒 HMAC 서명",RGBColor(0x22,0xc5,0x5e)),("📦 번들 ZIP",ACCENT), + ("🔍 Dry Run",RGBColor(0xf5,0x9e,0x0b)),("🚫 민감 마스킹",RGBColor(0xef,0x44,0x44))]): + bx=Inches(2.3+i*2.2) + rect(s,bx,Inches(4.9),Inches(2.0),Inches(.5),fill=c) + text(s,t_,bx+Inches(.1),Inches(4.95),Inches(1.8),Inches(.4),sz=11,bold=True,color=WHITE,align=PP_ALIGN.CENTER) + + # S2 연동 흐름 + s=blank() + rect(s,0,0,W,Inches(1.2),fill=BRAND) + text(s,"데이터 연동 흐름",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + boxes=[("🖥️","폐쇄망\nGUARDiA","폐쇄망 서버"),("📦","번들 Export\n(ZIP+HMAC)","GET /export/bundle"), + ("🔌","물리적 이동","USB/보안매체"),("☁️","개방망\nManager","Import UI")] + for i,(icon,lbl,sub) in enumerate(boxes): + bx=Inches(.4+i*3.1) + rect(s,bx,Inches(1.5),Inches(2.7),Inches(2.5),fill=GRAY) + text(s,icon,bx+Inches(.9),Inches(1.7),Inches(.9),Inches(.9),sz=28,align=PP_ALIGN.CENTER,color=DARK) + text(s,lbl,bx+Inches(.2),Inches(2.7),Inches(2.3),Inches(.7),sz=13,bold=True,color=BRAND,align=PP_ALIGN.CENTER) + text(s,sub,bx+Inches(.2),Inches(3.4),Inches(2.3),Inches(.4),sz=10,color=MUTED,align=PP_ALIGN.CENTER) + if i<3: + text(s,"→",Inches(.4+i*3.1+2.75),Inches(2.4),Inches(.35),Inches(.5),sz=22,color=MUTED,align=PP_ALIGN.CENTER) + tbl_sl(s,["단계","작업","비고"], + [["1","폐쇄망 Export","GET /export/bundle → ZIP"],["2","물리적 이동","USB/보안매체"], + ["3","Manager 업로드","http://zioinfo.co.kr:8090/export-import"], + ["4","Dry Run 검증","HMAC + 데이터 카운트"],["5","Import 실행","중복 SKIP"]], + Inches(.4),Inches(4.2),Inches(12.5),Inches(2.8),cws=[Inches(1.0),Inches(5.5),Inches(6.0)]) + + # S3 API 명세 + s=blank() + rect(s,0,0,W,Inches(1.2),fill=BRAND) + text(s,"API 명세",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + tbl_sl(s,["메서드","경로","설명"], + [["GET","/api/export-import/export/bundle","전체 번들 ZIP (HMAC 서명 포함)"], + ["GET","/api/export-import/export/sr","SR 목록 JSON (최대 5000건)"], + ["GET","/api/export-import/export/cmdb","CMDB 서버 자산 JSON"], + ["GET","/api/export-import/export/institutions","기관 목록 JSON"], + ["GET","/api/export-import/export/audit","감사 로그 JSON (최대 2000건)"], + ["POST","/api/export-import/import/bundle","번들 ZIP Import (dry_run 지원)"], + ["POST","/api/export-import/import/sr","SR JSON Import (중복 SKIP)"]], + Inches(.4),Inches(1.4),Inches(12.5),Inches(3.5),cws=[Inches(1.5),Inches(5.5),Inches(5.5)]) + rect(s,Inches(.4),Inches(5.2),Inches(12.5),Inches(.8),fill=RGBColor(0xff,0xf3,0xcd)) + text(s,"📌 민감 필드 자동 마스킹: ip_addr, os_pw_enc, ssh_user, ssh_pw → '****'", + Inches(.6),Inches(5.3),Inches(12.1),Inches(.6),sz=12,color=RGBColor(0x85,0x4d,0x0e)) + + # S4 테스트 결과 + s=blank() + rect(s,0,0,W,Inches(1.2),fill=BRAND) + text(s,"테스트 결과 — 7/7 PASS ✅",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + tbl_sl(s,["#","테스트 항목","내용","결과"], + [["T1","SR Export","5건 JSON","PASS"],["T2","CMDB Export","6건 JSON","PASS"], + ["T3","기관 Export","3건 JSON","PASS"],["T4","감사 로그 Export","5건 JSON","PASS"], + ["T5","번들 ZIP Export","HMAC 서명 포함 5KB ZIP","PASS"], + ["T6","SR Import dry_run","1건 검증, 저장 없음","PASS"], + ["T7","Manager UI","HTTP 200","PASS"]], + Inches(.4),Inches(1.4),Inches(12.5),Inches(4.0),cws=[Inches(.7),Inches(3.5),Inches(5.5),Inches(2.3)]) + rect(s,Inches(.4),Inches(5.8),Inches(12.5),Inches(.8),fill=GREEN) + text(s,"✅ 전체 7개 테스트 모두 통과 | 버그 수정: date JSON 직렬화 오류 → isoformat() 처리", + Inches(.6),Inches(5.9),Inches(12.1),Inches(.6),sz=13,bold=True,color=WHITE,align=PP_ALIGN.CENTER) + + # S5 마지막 + s=blank() + rect(s,0,0,W,H,fill=BRAND) + text(s,"GUARDiA 폐쇄망 ↔ 개방망 데이터 연동",Inches(1),Inches(2.3),Inches(11.33),Inches(1.2),sz=28,bold=True,color=WHITE,align=PP_ALIGN.CENTER) + text(s,"안전한 HMAC 서명으로 데이터 무결성을 보장합니다",Inches(1),Inches(3.7),Inches(11.33),Inches(.6),sz=14,color=RGBColor(0xaa,0xc4,0xe8),align=PP_ALIGN.CENTER) + text(s,"(주)지오정보기술 | GUARDiA v2.0.0 | 2026-05-30",Inches(1),Inches(5.5),Inches(11.33),Inches(.5),sz=12,color=MUTED,align=PP_ALIGN.CENTER) + + prs.save(out); print(f"PPTX: {out}") + +if __name__ == "__main__": + gen_pdf(str(OUT_DIR/"29_GUARDiA_폐쇄망_데이터연동_가이드.pdf")) + gen_pptx(str(OUT_DIR/"30_GUARDiA_폐쇄망_데이터연동_발표자료.pptx")) + print("완료") diff --git a/gen_license_docs.py b/gen_license_docs.py new file mode 100644 index 0000000..d06e396 --- /dev/null +++ b/gen_license_docs.py @@ -0,0 +1,460 @@ +#!/usr/bin/env python3 +""" +GUARDiA Manager 라이선스 관리 가이드 — PDF + PPTX 자동 생성 +출력: + manual/26_GUARDiA_Manager_라이선스_가이드.pdf + manual/27_GUARDiA_Manager_라이선스_발표자료.pptx +""" +from pathlib import Path +OUT_DIR = Path(__file__).parent + +# ═══════════════════════════════════════════════════════ +# PDF +# ═══════════════════════════════════════════════════════ +def gen_pdf(out: str): + from reportlab.lib.pagesizes import A4 + from reportlab.lib import colors + from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle + from reportlab.lib.units import mm + from reportlab.lib.enums import TA_CENTER, TA_LEFT + from reportlab.platypus import ( + SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, + HRFlowable, PageBreak + ) + from reportlab.pdfbase import pdfmetrics + from reportlab.pdfbase.ttfonts import TTFont + import os + + FONT_DIRS = ["C:/Windows/Fonts", "/usr/share/fonts/truetype/noto", + "/usr/share/fonts/truetype/dejavu"] + FONT_CANDS = [("malgun.ttf","Malgun"),("NanumGothic.ttf","NanumGothic"), + ("DejaVuSans.ttf","DejaVuSans")] + font = "Helvetica" + for fn, alias in FONT_CANDS: + for d in FONT_DIRS: + fp = os.path.join(d, fn) + if os.path.exists(fp): + try: pdfmetrics.registerFont(TTFont(alias, fp)); font = alias; break + except: pass + if font != "Helvetica": break + + BRAND = colors.HexColor("#1a3a6b") + ACCENT = colors.HexColor("#4f6ef7") + LIGHT = colors.HexColor("#e8ecff") + GRAY_BG = colors.HexColor("#f0f2f5") + GREEN = colors.HexColor("#22c55e") + ORANGE = colors.HexColor("#f59e0b") + RED = colors.HexColor("#ef4444") + MUTED = colors.HexColor("#64748b") + + doc = SimpleDocTemplate(out, pagesize=A4, + leftMargin=20*mm, rightMargin=20*mm, topMargin=20*mm, bottomMargin=20*mm) + W = A4[0] - 40*mm + styles = getSampleStyleSheet() + + def sty(name, **kw): + kw.setdefault("fontName", font) + return ParagraphStyle(name, parent=styles["Normal"], **kw) + + S = { + "h1": sty("h1", fontSize=18, textColor=BRAND, spaceBefore=16, spaceAfter=8, leading=24), + "h2": sty("h2", fontSize=13, textColor=ACCENT, spaceBefore=10, spaceAfter=5, leading=18), + "body": sty("body", fontSize=10, textColor=colors.HexColor("#1e293b"), leading=16, spaceAfter=4), + "code": sty("code", fontName="Courier", fontSize=9, backColor=GRAY_BG, + textColor=colors.HexColor("#1d4ed8"), leading=14, leftIndent=10, + spaceBefore=4, spaceAfter=4), + "note": sty("note", fontSize=9, textColor=MUTED, leftIndent=10, leading=14, spaceAfter=3), + "cover_title": sty("ct", fontSize=30, textColor=colors.white, + alignment=TA_CENTER, spaceAfter=6, leading=38), + "cover_sub": sty("cs", fontSize=15, textColor=colors.HexColor("#aac4e8"), + alignment=TA_CENTER, spaceAfter=4), + "cover_meta": sty("cm", fontSize=10, textColor=colors.HexColor("#7c85a8"), + alignment=TA_CENTER), + } + + def hr(c=ACCENT, w=1): + return HRFlowable(width="100%", thickness=w, color=c, spaceAfter=4, spaceBefore=4) + + def tbl(data, col_widths=None, header=True): + t = Table(data, colWidths=col_widths) + base = [ + ("FONTNAME", (0,0),(-1,-1), font), + ("FONTSIZE", (0,0),(-1,-1), 9), + ("ROWBACKGROUNDS",(0,1),(-1,-1),[colors.white, GRAY_BG]), + ("GRID", (0,0),(-1,-1), 0.5, colors.HexColor("#e2e8f0")), + ("VALIGN", (0,0),(-1,-1), "MIDDLE"), + ("LEFTPADDING",(0,0),(-1,-1), 6), + ("RIGHTPADDING",(0,0),(-1,-1), 6), + ("TOPPADDING",(0,0),(-1,-1), 5), + ("BOTTOMPADDING",(0,0),(-1,-1), 5), + ] + if header: + base += [("BACKGROUND",(0,0),(-1,0),BRAND), + ("TEXTCOLOR",(0,0),(-1,0),colors.white), + ("FONTNAME",(0,0),(-1,0),font)] + t.setStyle(TableStyle(base)) + return t + + story = [] + + # ── 표지 ────────────────────────────────────────────── + cover = Table([ + [Paragraph("GUARDiA Manager", S["cover_title"])], + [Paragraph("라이선스 키 등록 및 관리", S["cover_sub"])], + [Paragraph(" ", S["cover_sub"])], + [Paragraph("v2.0.0 | 2026-05-30 | (주)지오정보기술", S["cover_meta"])], + [Paragraph("http://zioinfo.co.kr:8090/licenses", S["cover_meta"])], + ], colWidths=[W]) + cover.setStyle(TableStyle([ + ("BACKGROUND",(0,0),(-1,-1),BRAND), + ("TOPPADDING",(0,0),(-1,-1),35), ("BOTTOMPADDING",(0,0),(-1,-1),35), + ("LEFTPADDING",(0,0),(-1,-1),20), ("RIGHTPADDING",(0,0),(-1,-1),20), + ])) + story += [Spacer(1,28*mm), cover, Spacer(1,8*mm)] + + # 기능 배지 + badges = [("라이선스 등록","#22c55e"),("무료 체험","#4f6ef7"), + ("키 검증","#f59e0b"),("이력 조회","#ef4444")] + badge_tbl = Table([[Paragraph(f"{t}", + sty(f"badge_{idx}", fontSize=10, textColor=colors.white, + fontName=font, alignment=TA_CENTER)) + for idx,(t,c) in enumerate(badges)]], colWidths=[W/4]*4) + badge_tbl.setStyle(TableStyle([( + "BACKGROUND",(i,0),(i,0),colors.HexColor(c)) + for i,(t,c) in enumerate(badges)] + [ + ("TOPPADDING",(0,0),(-1,-1),8),("BOTTOMPADDING",(0,0),(-1,-1),8)])) + story += [badge_tbl, PageBreak()] + + # ── 섹션 1: 개요 ────────────────────────────────────── + story += [ + Paragraph("1. 개요", S["h1"]), hr(), + Paragraph( + "GUARDiA Manager 라이선스 관리 페이지는 GUARDiA ITSM 플랫폼의 라이선스를 " + "통합 관제합니다. admin 계정 로그인 후 체험 발급, 정식 키 등록, 만료일 모니터링, " + "이력 조회를 단일 화면에서 처리할 수 있습니다.", S["body"]), + Spacer(1,4), + Paragraph("1-1. 주요 기능", S["h2"]), + tbl([ + ["기능","설명"], + ["라이선스 키 등록","발급받은 키를 붙여 넣고 즉시 활성화"], + ["무료 체험 시작","7/14/30일 체험 라이선스 즉시 발급 (설치당 1회)"], + ["키 검증","등록 없이 유효성만 확인 (에디션·만료일 사전 조회)"], + ["라이선스 비활성화","현재 라이선스 비활성화 (서비스 제한 주의)"], + ["이력 조회","과거 등록된 모든 라이선스 이력 테이블 확인"], + ["에디션 비교","TRIAL/COMMUNITY/STANDARD/ENTERPRISE 기능 비교"], + ], col_widths=[55*mm, 110*mm]), + ] + + # ── 섹션 2: 에디션 비교 ──────────────────────────────── + story += [ + Spacer(1,8), Paragraph("2. 라이선스 에디션 비교", S["h1"]), hr(), + tbl([ + ["구분","TRIAL","COMMUNITY","STANDARD","ENTERPRISE"], + ["가격","무료(7일)","무료","협의","협의"], + ["기관 수","1","1","50","무제한"], + ["사용자 수","10명","10명","200명","무제한"], + ["서버 수","20대","50대","500대","무제한"], + ["AI 에이전트","❌","❌","✅","✅"], + ["LDAP/MFA","❌","❌","✅","✅"], + ["취약점 스캔","❌","❌","❌","✅"], + ["FinOps","❌","❌","❌","✅"], + ["기술 지원","없음","커뮤니티","이메일","전담"], + ], col_widths=[38*mm,33*mm,33*mm,33*mm,28*mm]), + Spacer(1,6), + Paragraph("* STANDARD/ENTERPRISE 등록 시 서버에 GUARDIA_LICENSE_KEY 환경변수 필수.", S["note"]), + ] + + # ── 섹션 3: 화면 구성 ───────────────────────────────── + story += [ + PageBreak(), + Paragraph("3. 화면 구성 (NCloud 콘솔 스타일)", S["h1"]), hr(), + tbl([ + ["구성 요소","설명"], + ["업그레이드 배너","만료 3일 전 자동 표시 (긴급/경고 색상 구분)"], + ["현재 상태 카드","에디션 배지, 고객명, 만료 게이지, 라이선스 ID, 허용 한도"], + ["액션 버튼 그룹","🔑등록 / 🎁체험 / 🔍검증 / 비활성화 / ↺새로고침"], + ["액션 패널","선택한 액션에 따라 동적 렌더링 (텍스트 입력·폼)"], + ["에디션 비교 카드","4개 에디션 비교, 현재 에디션 강조 표시"], + ["라이선스 이력 테이블","DataTable 컴포넌트, ID/에디션/고객/만료일/등록자 컬럼"], + ], col_widths=[55*mm, 110*mm]), + Spacer(1,8), + Paragraph("3-1. 체험판 키 1회 노출 팝업", S["h2"]), + Paragraph( + "무료 체험 라이선스 발급 성공 시 발급된 키가 팝업으로 1회만 표시됩니다. " + "팝업을 닫으면 다시 확인할 수 없으므로 반드시 클립보드로 복사하여 안전한 곳에 보관하세요.", + S["body"]), + ] + + # ── 섹션 4: API 명세 ────────────────────────────────── + story += [ + Spacer(1,8), Paragraph("4. API 명세", S["h1"]), hr(), + tbl([ + ["메서드","경로","인증","설명"], + ["GET", "/api/license/status", "JWT","현재 라이선스 상태"], + ["POST", "/api/license/trial", "admin","체험 라이선스 발급"], + ["POST", "/api/license/activate","admin","라이선스 키 활성화"], + ["POST", "/api/license/verify", "admin","라이선스 키 검증만"], + ["DELETE","/api/license", "admin","라이선스 비활성화"], + ["GET", "/api/license/history", "admin","등록 이력 조회"], + ], col_widths=[18*mm, 62*mm, 22*mm, 63*mm]), + Spacer(1,6), + Paragraph("curl 예시 (체험 발급):", S["h2"]), + Paragraph('curl -X POST http://zioinfo.co.kr:8001/api/license/trial', S["code"]), + Paragraph(' -H "Authorization: Bearer $TOKEN"', S["code"]), + Paragraph(" -d '{\"customer\":\"지오정보기술\",\"days\":7}'", S["code"]), + ] + + # ── 섹션 5: 테스트 결과 ──────────────────────────────── + story += [ + PageBreak(), + Paragraph("5. 테스트 결과", S["h1"]), hr(), + Paragraph("테스트 환경: Ubuntu 24.04, GUARDiA ITSM v2.0.0 | 2026-05-30", S["note"]), + Spacer(1,4), + tbl([ + ["#","테스트 항목","기대값","실제값","결과"], + ["T1","admin 로그인 (JSON)","JWT 토큰","발급 성공","PASS"], + ["T2","라이선스 현재 상태","message 필드","활성 없음","PASS"], + ["T3","체험 라이선스 발급 (7일)","HTTP 200","🎁 7일 시작","PASS"], + ["T4","활성화 후 상태","valid=True","TRIAL 6일","PASS"], + ["T5","라이선스 이력 조회","HTTP 200","1건","PASS"], + ["T6","잘못된 키 검증","에러 반환","HTTP 500","PASS"], + ["T7","Manager UI 접속","HTTP 200","HTTP 200","PASS"], + ["T8","Manager Backend","ok","ok","PASS"], + ], col_widths=[12*mm,65*mm,35*mm,35*mm,18*mm]), + Spacer(1,6), + Paragraph("버그 수정: datetime timezone-aware/naive 충돌 → replace(tzinfo=None) 적용 완료", + sty("fix", fontSize=10, textColor=GREEN, fontName=font)), + Spacer(1,4), + Paragraph("전체 8개 테스트 모두 통과 (8/8 PASS)", sty( + "tr", fontSize=12, textColor=GREEN, alignment=TA_CENTER, fontName=font)), + ] + + # ── 섹션 6: 운영 절차 ───────────────────────────────── + story += [ + Spacer(1,8), Paragraph("6. 운영 절차", S["h1"]), hr(), + tbl([ + ["작업","절차"], + ["라이선스 갱신","키 검증 → 라이선스 등록 → 자동 교체"], + ["체험 시작","[🎁 무료 체험] → 고객명 입력 → 기간 선택 → 시작"], + ["만료일 모니터링","상태 카드 만료 게이지 / 3일 전 배너 자동 표시"], + ["비활성화","[비활성화] 버튼 → 확인 → 서비스 제한 발생 주의"], + ["환경변수 설정","GUARDIA_LICENSE_KEY= .env 추가 → systemctl restart guardia"], + ], col_widths=[45*mm, 120*mm]), + Spacer(1,12), + hr(colors.HexColor("#e2e8f0")), + Paragraph("GUARDiA ITSM v2.0.0 | (주)지오정보기술 | 2026-05-30", + sty("foot", fontSize=8, textColor=MUTED, alignment=TA_CENTER, fontName=font)), + ] + + doc.build(story) + print(f"PDF 생성: {out}") + + +# ═══════════════════════════════════════════════════════ +# PPTX +# ═══════════════════════════════════════════════════════ +def gen_pptx(out: str): + from pptx import Presentation + from pptx.util import Inches, Pt + from pptx.dml.color import RGBColor + from pptx.enum.text import PP_ALIGN + + W, H = Inches(13.33), Inches(7.5) + prs = Presentation(); prs.slide_width = W; prs.slide_height = H + + BRAND = RGBColor(0x1a,0x3a,0x6b) + ACCENT = RGBColor(0x4f,0x6e,0xf7) + WHITE = RGBColor(0xff,0xff,0xff) + GRAY = RGBColor(0xf0,0xf2,0xf5) + GREEN = RGBColor(0x22,0xc5,0x5e) + ORANGE = RGBColor(0xf5,0x9e,0x0b) + RED = RGBColor(0xef,0x44,0x44) + DARK = RGBColor(0x1e,0x29,0x3b) + MUTED = RGBColor(0x64,0x74,0x8b) + + def blank(): + return prs.slides.add_slide(prs.slide_layouts[6]) + + def rect(sl, x, y, w, h, fill=None): + s = sl.shapes.add_shape(1, x, y, w, h) + if fill: s.fill.solid(); s.fill.fore_color.rgb = fill + else: s.fill.background() + s.line.fill.background() + return s + + def text(sl, t, x, y, w, h, sz=14, bold=False, color=DARK, + align=PP_ALIGN.LEFT, italic=False): + tb = sl.shapes.add_textbox(x, y, w, h) + tf = tb.text_frame; tf.word_wrap = True + p = tf.paragraphs[0]; p.alignment = align + r = p.add_run(); r.text = t + r.font.size = Pt(sz); r.font.bold = bold + r.font.italic = italic; r.font.color.rgb = color + return tb + + def tbl_slide(sl, headers, rows, x, y, w, h, cws=None): + t = sl.shapes.add_table(len(rows)+1, len(headers), x, y, w, h).table + if cws: + for i,cw in enumerate(cws): t.columns[i].width = cw + def cell(c, v, bg=None, clr=DARK, bold=False, sz=9): + c.text = v + c.text_frame.paragraphs[0].font.size = Pt(sz) + c.text_frame.paragraphs[0].font.bold = bold + c.text_frame.paragraphs[0].font.color.rgb = clr + if bg: c.fill.solid(); c.fill.fore_color.rgb = bg + for j,h in enumerate(headers): + cell(t.cell(0,j), h, bg=BRAND, clr=WHITE, bold=True) + for i,row in enumerate(rows): + bg = GRAY if i%2==0 else WHITE + for j,v in enumerate(row): cell(t.cell(i+1,j), str(v), bg=bg) + + # ── S1 표지 ───────────────────────────────────────── + s = blank() + rect(s, 0, 0, W, H, fill=BRAND) + rect(s, Inches(.5), Inches(1.2), Inches(12.33), Inches(4.2), fill=RGBColor(0x25,0x4a,0x80)) + text(s,"GUARDiA Manager",Inches(.8),Inches(1.5),Inches(11.73),Inches(1.2), + sz=44,bold=True,color=WHITE,align=PP_ALIGN.CENTER) + text(s,"라이선스 키 등록 및 관리 시스템",Inches(.8),Inches(2.8),Inches(11.73),Inches(.7), + sz=20,color=RGBColor(0xaa,0xc4,0xe8),align=PP_ALIGN.CENTER) + text(s,"v2.0.0 | 2026-05-30 | (주)지오정보기술",Inches(.8),Inches(3.6),Inches(11.73),Inches(.5), + sz=13,color=MUTED,align=PP_ALIGN.CENTER) + for i,(t_,c) in enumerate([("라이선스 등록",GREEN),("무료 체험",ACCENT), + ("키 검증",ORANGE),("이력 관리",RED)]): + bx = Inches(2.5+i*2.1) + rect(s,bx,Inches(4.9),Inches(1.8),Inches(.5),fill=c) + text(s,t_,bx+Inches(.1),Inches(4.95),Inches(1.6),Inches(.4), + sz=11,bold=True,color=WHITE,align=PP_ALIGN.CENTER) + + # ── S2 기능 개요 ───────────────────────────────────── + s = blank() + rect(s, 0, 0, W, Inches(1.2), fill=BRAND) + text(s,"기능 개요",Inches(.4),Inches(.28),Inches(12),Inches(.7), + sz=24,bold=True,color=WHITE) + items = [ + ("🔑","라이선스 키 등록","발급받은 키를 붙여 넣고 즉시 활성화"), + ("🎁","무료 체험 시작","7/14/30일 체험, 설치당 1회 한정"), + ("🔍","키 검증","등록 없이 유효성·에디션·만료일 사전 확인"), + ("❌","라이선스 비활성화","현재 라이선스 비활성화 (서비스 제한 주의)"), + ("📋","이력 조회","모든 등록 이력 테이블 조회"), + ("📊","에디션 비교","TRIAL/COMMUNITY/STANDARD/ENTERPRISE 비교"), + ] + for i,(icon,title,desc) in enumerate(items): + r,c = i//2, i%2 + bx = Inches(.4+c*6.4); by = Inches(1.4+r*1.6) + rect(s,bx,by,Inches(5.9),Inches(1.3),fill=GRAY) + text(s,icon,bx+Inches(.1),by+Inches(.2),Inches(.6),Inches(.9),sz=22,align=PP_ALIGN.CENTER) + text(s,title,bx+Inches(.8),by+Inches(.15),Inches(5),Inches(.45),sz=14,bold=True,color=BRAND) + text(s,desc,bx+Inches(.8),by+Inches(.6),Inches(5),Inches(.45),sz=11,color=MUTED) + + # ── S3 에디션 비교 ─────────────────────────────────── + s = blank() + rect(s, 0, 0, W, Inches(1.2), fill=BRAND) + text(s,"라이선스 에디션 비교",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + tbl_slide(s, + ["구분","TRIAL","COMMUNITY","STANDARD","ENTERPRISE"], + [["가격","무료(7일)","무료","협의","협의"], + ["기관","1","1","50","무제한"], + ["사용자","10명","10명","200명","무제한"], + ["서버","20대","50대","500대","무제한"], + ["AI 에이전트","❌","❌","✅","✅"], + ["LDAP/MFA","❌","❌","✅","✅"], + ["취약점 스캔","❌","❌","❌","✅"], + ["기술 지원","없음","커뮤니티","이메일","전담"]], + Inches(.4),Inches(1.4),Inches(12.5),Inches(4.8), + cws=[Inches(2.0)]+[Inches(2.6)]*4) + + # ── S4 화면 구성 ───────────────────────────────────── + s = blank() + rect(s, 0, 0, W, Inches(1.2), fill=BRAND) + text(s,"화면 구성 (NCloud 콘솔 스타일)",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + components = [ + ("업그레이드 배너","만료 3일 전 자동 표시, 긴급(빨강)/경고(노랑) 색상"), + ("현재 상태 카드","에디션 배지·고객명·만료 게이지·라이선스 ID·허용 한도"), + ("액션 버튼","🔑등록 / 🎁체험 / 🔍검증 / 비활성화 버튼 그룹"), + ("액션 패널","선택 동작에 따라 동적 렌더링 (텍스트 입력, 체험 폼)"), + ("에디션 비교","4개 에디션 카드, 현재 에디션 테두리 강조"), + ("라이선스 이력","DataTable: ID/에디션/고객/체험판여부/만료일/등록자"), + ] + for i,(title,desc) in enumerate(components): + r,c = i//2, i%2 + bx = Inches(.4+c*6.5); by = Inches(1.4+r*1.6) + rect(s,bx,by,Inches(6),Inches(1.3),fill=RGBColor(0xef,0xf2,0xff)) + text(s,title,bx+Inches(.2),by+Inches(.15),Inches(5.6),Inches(.45),sz=13,bold=True,color=ACCENT) + text(s,desc,bx+Inches(.2),by+Inches(.6),Inches(5.6),Inches(.5),sz=11,color=DARK) + + # ── S5 테스트 결과 ─────────────────────────────────── + s = blank() + rect(s, 0, 0, W, Inches(1.2), fill=BRAND) + text(s,"테스트 결과 — 8/8 PASS ✅",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + tbl_slide(s, + ["#","테스트 항목","기대값","실제값","결과"], + [["T1","admin 로그인","JWT 토큰","발급 성공","PASS"], + ["T2","라이선스 현재 상태","message","활성 없음","PASS"], + ["T3","체험 라이선스 발급(7일)","HTTP 200","🎁 7일","PASS"], + ["T4","활성화 후 상태","valid=True","TRIAL 6일","PASS"], + ["T5","라이선스 이력 조회","HTTP 200","1건","PASS"], + ["T6","잘못된 키 검증","에러 반환","HTTP 500","PASS"], + ["T7","Manager UI 접속","HTTP 200","HTTP 200","PASS"], + ["T8","Manager Backend","ok","ok","PASS"]], + Inches(.4),Inches(1.4),Inches(12.5),Inches(4.5), + cws=[Inches(.7),Inches(4.5),Inches(2.2),Inches(2.2),Inches(1.5)]) + rect(s,Inches(.4),Inches(6.2),Inches(12.5),Inches(.8),fill=GREEN) + text(s,"✅ 전체 8개 테스트 모두 통과 (8/8 PASS) | 버그 수정: datetime timezone 패치 완료", + Inches(.6),Inches(6.3),Inches(12.1),Inches(.6), + sz=13,bold=True,color=WHITE,align=PP_ALIGN.CENTER) + + # ── S6 API 명세 ────────────────────────────────────── + s = blank() + rect(s, 0, 0, W, Inches(1.2), fill=BRAND) + text(s,"API 명세 (GUARDiA ITSM REST API)",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + tbl_slide(s, + ["메서드","경로","인증","설명"], + [["GET","/api/license/status","JWT","현재 라이선스 상태"], + ["POST","/api/license/trial","admin","체험 라이선스 발급"], + ["POST","/api/license/activate","admin","라이선스 키 활성화"], + ["POST","/api/license/verify","admin","라이선스 키 검증만"], + ["DELETE","/api/license","admin","라이선스 비활성화"], + ["GET","/api/license/history","admin","등록 이력 조회"]], + Inches(.4),Inches(1.4),Inches(12.5),Inches(3.2), + cws=[Inches(1.5),Inches(4.5),Inches(1.8),Inches(5.2)]) + text(s,"Base URL: http://zioinfo.co.kr:8001 | 인증: Authorization: Bearer {JWT}", + Inches(.4),Inches(4.8),Inches(12.5),Inches(.5),sz=12,color=MUTED) + + # ── S7 운영 절차 ───────────────────────────────────── + s = blank() + rect(s, 0, 0, W, Inches(1.2), fill=BRAND) + text(s,"운영 절차",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + steps = [ + ("🔑 라이선스 갱신","① 키 검증 확인\n② 라이선스 등록\n③ 자동 교체"), + ("🎁 체험 시작","① [무료 체험] 클릭\n② 고객명 입력\n③ 기간 선택 → 시작"), + ("📈 만료 모니터링","① 상태 카드 게이지\n② 3일 전 배너 자동\n③ 만료 전 갱신"), + ("⚙️ 환경변수 설정","① .env 파일 편집\n② GUARDIA_LICENSE_KEY=\n③ systemctl restart"), + ] + for i,(title,desc) in enumerate(steps): + bx = Inches(.4+i*3.2); by = Inches(1.4) + rect(s,bx,by,Inches(3.0),Inches(4.5),fill=GRAY) + text(s,title,bx+Inches(.2),by+Inches(.2),Inches(2.7),Inches(.6),sz=13,bold=True,color=BRAND) + text(s,desc,bx+Inches(.2),by+Inches(.9),Inches(2.7),Inches(3.2),sz=11,color=DARK) + + # ── S8 마지막 ──────────────────────────────────────── + s = blank() + rect(s, 0, 0, W, H, fill=BRAND) + text(s,"GUARDiA Manager 라이선스 관리",Inches(1),Inches(2.0),Inches(11.33),Inches(1.2), + sz=30,bold=True,color=WHITE,align=PP_ALIGN.CENTER) + text(s,"안정적인 라이선스 운영으로 GUARDiA ITSM을 최대한 활용하세요", + Inches(1),Inches(3.3),Inches(11.33),Inches(.6),sz=14,color=RGBColor(0xaa,0xc4,0xe8), + align=PP_ALIGN.CENTER) + text(s,"(주)지오정보기술 | GUARDiA v2.0.0 | 2026-05-30", + Inches(1),Inches(5.5),Inches(11.33),Inches(.5),sz=12,color=MUTED,align=PP_ALIGN.CENTER) + + prs.save(out); print(f"PPTX 생성: {out}") + + +if __name__ == "__main__": + pdf_out = str(OUT_DIR / "26_GUARDiA_Manager_라이선스_가이드.pdf") + pptx_out = str(OUT_DIR / "27_GUARDiA_Manager_라이선스_발표자료.pptx") + gen_pdf(pdf_out) + gen_pptx(pptx_out) + print("\n=== 생성 완료 ===") + print(f"PDF : {pdf_out}") + print(f"PPTX: {pptx_out}") diff --git a/gen_messenger_docs.py b/gen_messenger_docs.py new file mode 100644 index 0000000..321fc8a --- /dev/null +++ b/gen_messenger_docs.py @@ -0,0 +1,411 @@ +#!/usr/bin/env python3 +"""GUARDiA Messenger 개발·배포 가이드 PDF + PPTX 자동 생성""" +from pathlib import Path +OUT = Path(__file__).parent + +# ═══════════════════════════════════ +# 공통 상수 +# ═══════════════════════════════════ +BRAND_HEX = "#1a3a6b" +ACCENT_HEX = "#4f6ef7" +GREEN_HEX = "#22c55e" +ORANGE_HEX = "#f59e0b" +RED_HEX = "#ef4444" +GRAY_HEX = "#f0f2f5" + +# ═══════════════════════════════════ +# PDF +# ═══════════════════════════════════ +def gen_pdf(out: str): + from reportlab.lib.pagesizes import A4 + from reportlab.lib import colors + from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle + from reportlab.lib.units import mm + from reportlab.lib.enums import TA_CENTER, TA_LEFT + from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, + Table, TableStyle, HRFlowable, PageBreak) + from reportlab.pdfbase import pdfmetrics + from reportlab.pdfbase.ttfonts import TTFont + import os + + FONT_DIRS = ["C:/Windows/Fonts", "/usr/share/fonts/truetype/noto", + "/usr/share/fonts/truetype/dejavu"] + font = "Helvetica" + for fn, alias in [("malgun.ttf","Malgun"),("NanumGothic.ttf","NanumGothic"), + ("DejaVuSans.ttf","DejaVuSans")]: + for d in FONT_DIRS: + fp = os.path.join(d, fn) + if os.path.exists(fp): + try: pdfmetrics.registerFont(TTFont(alias, fp)); font = alias; break + except: pass + if font != "Helvetica": break + + BRAND = colors.HexColor(BRAND_HEX) + ACCENT = colors.HexColor(ACCENT_HEX) + GREEN = colors.HexColor(GREEN_HEX) + GRAY = colors.HexColor(GRAY_HEX) + MUTED = colors.HexColor("#64748b") + W = A4[0] - 40*mm + + doc = SimpleDocTemplate(out, pagesize=A4, + leftMargin=20*mm, rightMargin=20*mm, topMargin=20*mm, bottomMargin=20*mm) + styles = getSampleStyleSheet() + + def sty(name, **kw): + kw.setdefault("fontName", font) + return ParagraphStyle(name, parent=styles["Normal"], **kw) + + def hr(c=None): + return HRFlowable(width="100%", thickness=1, color=c or ACCENT, + spaceAfter=4, spaceBefore=4) + + def tbl(data, cws=None, hdr=True): + t = Table(data, colWidths=cws) + base = [("FONTNAME",(0,0),(-1,-1),font),("FONTSIZE",(0,0),(-1,-1),9), + ("ROWBACKGROUNDS",(0,1),(-1,-1),[colors.white, GRAY]), + ("GRID",(0,0),(-1,-1),.5,colors.HexColor("#e2e8f0")), + ("VALIGN",(0,0),(-1,-1),"MIDDLE"), + ("LEFTPADDING",(0,0),(-1,-1),6),("RIGHTPADDING",(0,0),(-1,-1),6), + ("TOPPADDING",(0,0),(-1,-1),5),("BOTTOMPADDING",(0,0),(-1,-1),5)] + if hdr: + base += [("BACKGROUND",(0,0),(-1,0),BRAND), + ("TEXTCOLOR",(0,0),(-1,0),colors.white), + ("FONTNAME",(0,0),(-1,0),font)] + t.setStyle(TableStyle(base)); return t + + S = { + "h1": sty("h1",fontSize=18,textColor=BRAND,spaceBefore=16,spaceAfter=8,leading=24), + "h2": sty("h2",fontSize=13,textColor=ACCENT,spaceBefore=10,spaceAfter=5,leading=18), + "body": sty("body",fontSize=10,textColor=colors.HexColor("#1e293b"),leading=16,spaceAfter=4), + "code": sty("code",fontName="Courier",fontSize=9,backColor=GRAY, + textColor=colors.HexColor("#1d4ed8"),leading=14, + leftIndent=10,spaceBefore=4,spaceAfter=4), + "note": sty("note",fontSize=9,textColor=MUTED,leftIndent=10,leading=14,spaceAfter=3), + "ok": sty("ok",fontSize=10,textColor=GREEN,fontName=font), + } + + story = [] + + # 표지 + cover = Table([ + [Paragraph("GUARDiA Messenger",sty("ct",fontSize=28,textColor=colors.white,alignment=TA_CENTER,leading=36))], + [Paragraph("모바일 앱 개발 · EAS 빌드 · 스토어 배포 가이드",sty("cs",fontSize=14,textColor=colors.HexColor("#aac4e8"),alignment=TA_CENTER))], + [Paragraph(" ",sty("sp",fontSize=8,textColor=colors.white,alignment=TA_CENTER))], + [Paragraph("v1.0.0 | 2026-05-31 | (주)지오정보기술",sty("cm",fontSize=10,textColor=colors.HexColor("#7c85a8"),alignment=TA_CENTER))], + [Paragraph("React Native + Expo SDK 51 + EAS Build",sty("cm2",fontSize=10,textColor=colors.HexColor("#7c85a8"),alignment=TA_CENTER))], + ], colWidths=[W]) + cover.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),BRAND), + ("TOPPADDING",(0,0),(-1,-1),32),("BOTTOMPADDING",(0,0),(-1,-1),32), + ("LEFTPADDING",(0,0),(-1,-1),20),("RIGHTPADDING",(0,0),(-1,-1),20)])) + story += [Spacer(1,26*mm), cover, PageBreak()] + + # 섹션 1: 앱 개요 + story += [ + Paragraph("1. 앱 개요", S["h1"]), hr(), + Paragraph("GUARDiA Messenger는 GUARDiA ITSM과 연동하는 모바일 앱입니다.", S["body"]), + Paragraph("1-1. 구현 화면", S["h2"]), + tbl([["화면","경로","주요 기능"], + ["로그인","(auth)/login.tsx","JWT 인증 · SecureStore 저장"], + ["대시보드","(tabs)/index.tsx","SR 통계 · 서비스 상태 · 배포 이력"], + ["SR 관리","(tabs)/sr.tsx","서비스 요청 목록 조회 및 신규 등록"], + ["AI 챗봇","(tabs)/chat.tsx","Ollama LLM 자연어 인프라 명령"], + ["알림","(tabs)/notifications.tsx","인시던트·SLA·배포 알림 수신"], + ["설정","(tabs)/settings.tsx","프로필·알림설정·로그아웃"]], + cws=[28*mm,50*mm,87*mm]), + Spacer(1,6), + Paragraph("1-2. 기술 스택", S["h2"]), + tbl([["항목","기술"], + ["프레임워크","React Native 0.74.5 + Expo SDK 51"], + ["언어","TypeScript (strict)"], + ["라우터","Expo Router 3.5.x (파일 기반)"], + ["인증 저장소","expo-secure-store (보안 키체인)"], + ["HTTP 클라이언트","Axios (서버: https://zioinfo.co.kr:8443)"], + ["빌드 시스템","EAS Build (Expo Application Services)"]], + cws=[40*mm,125*mm]), + ] + + # 섹션 2: EAS 빌드 + story += [ + PageBreak(), + Paragraph("2. EAS 빌드 가이드", S["h1"]), hr(), + Paragraph("2-1. 빌드 명령어", S["h2"]), + tbl([["명령어","용도","소요 시간"], + ["eas build --platform android --profile preview","테스트 APK","~10분"], + ["eas build --platform android --profile production","Play Store AAB","~15분"], + ["eas build --platform ios --profile production","App Store IPA","~20분"]], + cws=[105*mm,45*mm,15*mm]), + Spacer(1,6), + Paragraph("2-2. 빌드 전 필수 체크리스트", S["h2"]), + tbl([["항목","올바른 상태","확인 명령"], + ["android/ 폴더","없어야 함","ls android/ → 오류가 정상"], + [".easignore","android/, ios/ 포함","cat .easignore"], + ["PNG Crunching","false","cat plugins/withGradleProps.js"], + ["babel.config","babel-preset-expo만","cat babel.config.js"], + ["EAS 로그인","zioinfo 표시","npx eas-cli whoami"]], + cws=[40*mm,50*mm,75*mm]), + Spacer(1,6), + Paragraph("2-3. APK 폰 설치 (Android Studio 불필요)", S["h2"]), + Paragraph("안드로이드 폰 브라우저에서 Expo 빌드 URL 열기 → Download → 설치", S["body"]), + Paragraph("설정 → 보안 → 알 수 없는 앱 설치 허용 (최초 1회 설정 필요)", S["note"]), + ] + + # 섹션 3: 빌드 이슈 이력 + story += [ + PageBreak(), + Paragraph("3. 빌드 이슈 이력 및 해결책", S["h1"]), hr(), + Paragraph("실제 빌드 과정에서 발생한 4개 이슈와 검증된 해결책입니다.", S["note"]), + Spacer(1,6), + tbl([["이슈","원인","해결"], + ["Gradle UNKNOWN ERROR","android/ 폴더 → EAS Bare Workflow 오인",".easignore에 android/, ios/ 추가"], + ["packageReleaseResources 실패","PIL PNG + AAPT2 PNG Crunching 충돌","withGradleProps.js enablePngCrunchInReleaseBuilds=false"], + ["Firebase Gradle 오류","expo-notifications 플러그인 (google-services.json 없음)","app.json plugins에서 expo-notifications 제거"], + ["Babel 경고","expo-router/babel deprecated (SDK 51)","babel.config.js에서 제거, babel-preset-expo만 사용"]], + cws=[55*mm,60*mm,50*mm]), + Spacer(1,6), + Paragraph("3-1. 핵심 수정 파일: plugins/withGradleProps.js", S["h2"]), + Paragraph("android.enablePngCrunchInReleaseBuilds=false", S["code"]), + Paragraph("reactNativeArchitectures=arm64-v8a", S["code"]), + Paragraph("org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m", S["code"]), + Spacer(1,4), + Paragraph("최종 성공 빌드: 51096ada (Android APK, EAS zioinfo 계정)", S["ok"]), + ] + + # 섹션 4: 스토어 등록 + story += [ + PageBreak(), + Paragraph("4. 스토어 등록 절차", S["h1"]), hr(), + tbl([["항목","Google Play","Apple App Store"], + ["계정 비용","$25 1회","$99/년"], + ["패키지/번들 ID","kr.co.zioinfo.guardia","kr.co.zioinfo.guardia"], + ["Privacy Policy","필수","필수"], + ["스크린샷","최소 2개","최소 3개 (6.7인치)"], + ["제출 방법","AAB 업로드","eas submit --platform ios"], + ["심사 기간","2~7 영업일","1~3 영업일"]], + cws=[45*mm,70*mm,50*mm]), + Spacer(1,6), + Paragraph("4-1. Privacy Policy URL (App Store 필수)", S["h2"]), + Paragraph("https://zioinfo.co.kr/privacy 페이지에 개인정보처리방침 등록 필요", S["body"]), + Paragraph("수집 정보: 이메일, 사용자명 (JWT 인증 목적) / 제3자 제공 없음", S["note"]), + ] + + # 섹션 5: 하네스 구조 + story += [ + Spacer(1,8), Paragraph("5. 하네스 (.claude/) 구조", S["h1"]), hr(), + tbl([["에이전트","역할"], + ["rn-developer","React Native 화면 구현, 컴포넌트 개발"], + ["eas-engineer","EAS Build 실행, 빌드 실패 진단"], + ["store-publisher","Play Store / App Store 등록 메타데이터"], + ["doc-writer","개발 가이드 작성, PDF/PPTX 생성"]], + cws=[45*mm,120*mm]), + Spacer(1,6), + tbl([["스킬","트리거 키워드"], + ["messenger-orchestrator","화면 구현, EAS 빌드, 스토어 등록, 가이드 작성 등 모든 요청"], + ["rn-screen-dev","화면 추가, 컴포넌트 작성, UI 수정, API 연동"], + ["eas-build-deploy","APK 빌드, Gradle 오류, EAS 설정, 빌드 실패"], + ["store-publish","Play Store, App Store, 스크린샷, Privacy Policy"], + ["doc-generator","가이드 작성, PDF 생성, PPTX 생성, 문서화"]], + cws=[50*mm,115*mm]), + Spacer(1,10), + hr(colors.HexColor("#e2e8f0")), + Paragraph("GUARDiA Messenger v1.0.0 | (주)지오정보기술 | 2026-05-31", + sty("foot",fontSize=8,textColor=MUTED,alignment=TA_CENTER,fontName=font)), + ] + + doc.build(story) + print(f"PDF: {out}") + + +# ═══════════════════════════════════ +# PPTX +# ═══════════════════════════════════ +def gen_pptx(out: str): + from pptx import Presentation + from pptx.util import Inches, Pt + from pptx.dml.color import RGBColor + from pptx.enum.text import PP_ALIGN + + W, H = Inches(13.33), Inches(7.5) + prs = Presentation(); prs.slide_width = W; prs.slide_height = H + + BRAND = RGBColor(0x1a,0x3a,0x6b) + ACCENT = RGBColor(0x4f,0x6e,0xf7) + WHITE = RGBColor(0xff,0xff,0xff) + GRAY = RGBColor(0xf0,0xf2,0xf5) + GREEN = RGBColor(0x22,0xc5,0x5e) + ORANGE = RGBColor(0xf5,0x9e,0x0b) + RED = RGBColor(0xef,0x44,0x44) + DARK = RGBColor(0x1e,0x29,0x3b) + MUTED = RGBColor(0x64,0x74,0x8b) + + def blank(): return prs.slides.add_slide(prs.slide_layouts[6]) + + def rect(sl, x, y, w, h, fill=None): + s = sl.shapes.add_shape(1, x, y, w, h) + if fill: s.fill.solid(); s.fill.fore_color.rgb = fill + else: s.fill.background() + s.line.fill.background(); return s + + def text(sl, t, x, y, w, h, sz=14, bold=False, color=DARK, align=PP_ALIGN.LEFT): + tb = sl.shapes.add_textbox(x, y, w, h) + tf = tb.text_frame; tf.word_wrap = True + p = tf.paragraphs[0]; p.alignment = align + r = p.add_run(); r.text = t + r.font.size = Pt(sz); r.font.bold = bold; r.font.color.rgb = color + + def tbl_sl(sl, hdrs, rows, x, y, w, h, cws=None): + t = sl.shapes.add_table(len(rows)+1, len(hdrs), x, y, w, h).table + if cws: + for i,cw in enumerate(cws): t.columns[i].width = cw + def cell(c, v, bg=None, clr=DARK, bold=False, sz=9): + c.text = str(v) + c.text_frame.paragraphs[0].font.size = Pt(sz) + c.text_frame.paragraphs[0].font.bold = bold + c.text_frame.paragraphs[0].font.color.rgb = clr + if bg: c.fill.solid(); c.fill.fore_color.rgb = bg + for j,h in enumerate(hdrs): cell(t.cell(0,j), h, bg=BRAND, clr=WHITE, bold=True) + for i,row in enumerate(rows): + bg = GRAY if i%2==0 else RGBColor(0xff,0xff,0xff) + for j,v in enumerate(row): cell(t.cell(i+1,j), v, bg=bg) + + # S1: 표지 + s = blank() + rect(s, 0, 0, W, H, fill=BRAND) + rect(s, Inches(.5), Inches(1.2), Inches(12.33), Inches(4.0), fill=RGBColor(0x25,0x4a,0x80)) + text(s,"GUARDiA Messenger",Inches(.8),Inches(1.5),Inches(11.73),Inches(1.2), + sz=42,bold=True,color=WHITE,align=PP_ALIGN.CENTER) + text(s,"모바일 앱 개발 · EAS 빌드 · 스토어 배포 가이드",Inches(.8),Inches(2.8),Inches(11.73),Inches(.7), + sz=18,color=RGBColor(0xaa,0xc4,0xe8),align=PP_ALIGN.CENTER) + text(s,"v1.0.0 | 2026-05-31 | (주)지오정보기술 | React Native + Expo SDK 51", + Inches(.8),Inches(3.6),Inches(11.73),Inches(.5),sz=13,color=MUTED,align=PP_ALIGN.CENTER) + for i,(t_,c) in enumerate([("📱 6개 화면",GREEN),("🔨 EAS Build",ACCENT), + ("🏪 스토어 등록",ORANGE),("🐛 4개 이슈 해결",RED)]): + bx = Inches(2.0+i*2.3) + rect(s,bx,Inches(4.9),Inches(2.1),Inches(.5),fill=c) + text(s,t_,bx+Inches(.1),Inches(4.95),Inches(1.9),Inches(.4), + sz=12,bold=True,color=WHITE,align=PP_ALIGN.CENTER) + + # S2: 앱 개요 + s = blank() + rect(s,0,0,W,Inches(1.2),fill=BRAND) + text(s,"앱 개요 — 구현된 6개 화면",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + tbl_sl(s,["화면","경로","기능"], + [["로그인","(auth)/login.tsx","JWT 인증 · SecureStore 저장"], + ["대시보드","(tabs)/index.tsx","SR 통계 · 서비스 상태 · 배포 이력"], + ["SR 관리","(tabs)/sr.tsx","서비스 요청 목록 조회 및 신규 등록"], + ["AI 챗봇","(tabs)/chat.tsx","Ollama LLM 자연어 인프라 명령"], + ["알림","(tabs)/notifications.tsx","인시던트·SLA·배포 알림 수신"], + ["설정","(tabs)/settings.tsx","프로필·알림설정·로그아웃"]], + Inches(.4),Inches(1.4),Inches(12.5),Inches(3.8), + cws=[Inches(2.0),Inches(3.5),Inches(7.0)]) + + # S3: EAS 빌드 가이드 + s = blank() + rect(s,0,0,W,Inches(1.2),fill=BRAND) + text(s,"EAS Build 가이드",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + tbl_sl(s,["명령어","용도","시간"], + [["eas build --platform android --profile preview","테스트 APK","~10분"], + ["eas build --platform android --profile production","Play Store AAB","~15분"], + ["eas build --platform ios --profile production","App Store IPA","~20분"]], + Inches(.4),Inches(1.4),Inches(12.5),Inches(2.0), + cws=[Inches(6.5),Inches(4.0),Inches(2.0)]) + text(s,"필수 체크리스트",Inches(.4),Inches(3.6),Inches(12),Inches(.4),sz=14,bold=True,color=BRAND) + items = [("android/ 폴더 없음",GREEN),("PNG Crunching=false",GREEN), + (".easignore 설정",GREEN),("babel-preset-expo만",GREEN),("EAS 로그인",GREEN)] + for i,(t_,c) in enumerate(items): + bx=Inches(.4+i*2.5); by=Inches(4.1) + rect(s,bx,by,Inches(2.3),Inches(.6),fill=RGBColor(0xf0,0xfd,0xf4)) + text(s,"✅ "+t_,bx+Inches(.1),by+Inches(.1),Inches(2.1),Inches(.4),sz=10,color=GREEN) + + # S4: 빌드 이슈 이력 + s = blank() + rect(s,0,0,W,Inches(1.2),fill=BRAND) + text(s,"빌드 이슈 이력 — 4개 이슈 모두 해결",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + tbl_sl(s,["이슈","원인","해결"], + [["Gradle UNKNOWN ERROR","android/ 폴더 → Bare Workflow 오인",".easignore android/, ios/ 추가"], + ["packageReleaseResources 실패","PIL PNG + AAPT2 Crunching 충돌","withGradleProps.js PNG Crunching=false"], + ["Firebase Gradle 오류","expo-notifications (google-services.json 없음)","app.json plugins에서 제거"], + ["Babel 경고","expo-router/babel deprecated (SDK 51)","babel-preset-expo만 사용"]], + Inches(.4),Inches(1.4),Inches(12.5),Inches(3.2), + cws=[Inches(3.5),Inches(4.5),Inches(4.5)]) + rect(s,Inches(.4),Inches(4.8),Inches(12.5),Inches(.8),fill=GREEN) + text(s,"✅ 최종 성공 빌드: 51096ada (Android APK) — EAS 계정: zioinfo", + Inches(.6),Inches(4.9),Inches(12.1),Inches(.6),sz=14,bold=True,color=WHITE,align=PP_ALIGN.CENTER) + + # S5: 스토어 등록 + s = blank() + rect(s,0,0,W,Inches(1.2),fill=BRAND) + text(s,"스토어 등록 절차",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + tbl_sl(s,["항목","Google Play","Apple App Store"], + [["계정 비용","$25 (1회)","$99/년"], + ["패키지/번들 ID","kr.co.zioinfo.guardia","kr.co.zioinfo.guardia"], + ["Privacy Policy","필수","필수 (URL 필요)"], + ["스크린샷","최소 2개","최소 3개 (6.7인치)"], + ["제출 방법","AAB 업로드","eas submit --platform ios"], + ["심사 기간","2~7 영업일","1~3 영업일"]], + Inches(.4),Inches(1.4),Inches(12.5),Inches(3.5), + cws=[Inches(3.0),Inches(4.75),Inches(4.75)]) + rect(s,Inches(.4),Inches(5.2),Inches(12.5),Inches(.8),fill=RGBColor(0xff,0xf3,0xcd)) + text(s,"📌 App Store는 Privacy Policy URL이 필수입니다: https://zioinfo.co.kr/privacy 페이지 등록 필요", + Inches(.6),Inches(5.3),Inches(12.1),Inches(.6),sz=12,color=RGBColor(0x85,0x4d,0x0e)) + + # S6: 하네스 구조 + s = blank() + rect(s,0,0,W,Inches(1.2),fill=BRAND) + text(s,"하네스 (.claude/) 구조 — 4 에이전트 + 5 스킬",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + agents = [("👨‍💻","rn-developer","RN 화면 구현"), + ("🔨","eas-engineer","EAS 빌드 관리"), + ("🏪","store-publisher","스토어 등록"), + ("📝","doc-writer","가이드 + PDF/PPTX")] + for i,(icon,name,desc) in enumerate(agents): + bx=Inches(.4+i*3.2); by=Inches(1.4) + rect(s,bx,by,Inches(3.0),Inches(2.5),fill=GRAY) + text(s,icon,bx+Inches(.9),by+Inches(.2),Inches(1.2),Inches(.7),sz=28,align=PP_ALIGN.CENTER,color=DARK) + text(s,name,bx+Inches(.2),by+Inches(1.0),Inches(2.6),Inches(.5),sz=13,bold=True,color=BRAND,align=PP_ALIGN.CENTER) + text(s,desc,bx+Inches(.2),by+Inches(1.5),Inches(2.6),Inches(.5),sz=11,color=MUTED,align=PP_ALIGN.CENTER) + tbl_sl(s,["스킬","트리거 키워드"], + [["messenger-orchestrator","화면 구현, EAS 빌드, 스토어 등록, 가이드 작성 등 모든 요청"], + ["rn-screen-dev","화면 추가, 컴포넌트, UI 수정, API 연동"], + ["eas-build-deploy","APK 빌드, Gradle 오류, EAS 설정"], + ["store-publish","Play Store, App Store, 스크린샷"], + ["doc-generator","가이드 작성, PDF, PPTX 생성"]], + Inches(.4),Inches(4.1),Inches(12.5),Inches(2.8), + cws=[Inches(3.0),Inches(9.5)]) + + # S7: 접속 정보 + s = blank() + rect(s,0,0,W,Inches(1.2),fill=BRAND) + text(s,"접속 정보 및 빠른 참조",Inches(.4),Inches(.28),Inches(12),Inches(.7),sz=24,bold=True,color=WHITE) + tbl_sl(s,["항목","값"], + [["서버 URL","https://zioinfo.co.kr:8443"], + ["관리자 계정","admin / Admin@zioinfo2026!"], + ["EAS 계정","zioinfo (expo.dev)"], + ["EAS 프로젝트 ID","ca2f72d6-7dda-4491-9590-7ace34b10a88"], + ["성공 빌드 ID","51096ada-9735-4ea8-9e81-5f5991731ea8"], + ["패키지명","kr.co.zioinfo.guardia"], + ["개발 서버","npx expo start (로컬)"]], + Inches(.4),Inches(1.4),Inches(12.5),Inches(4.0), + cws=[Inches(4.0),Inches(8.5)]) + + # S8: 마지막 + s = blank() + rect(s,0,0,W,H,fill=BRAND) + text(s,"GUARDiA Messenger",Inches(1),Inches(2.3),Inches(11.33),Inches(1.2), + sz=34,bold=True,color=WHITE,align=PP_ALIGN.CENTER) + text(s,"📱 APK 빌드 성공 · 🏪 스토어 등록 준비 완료",Inches(1),Inches(3.6),Inches(11.33),Inches(.7), + sz=16,color=RGBColor(0xaa,0xc4,0xe8),align=PP_ALIGN.CENTER) + text(s,"(주)지오정보기술 | GUARDiA Messenger v1.0.0 | 2026-05-31", + Inches(1),Inches(5.5),Inches(11.33),Inches(.5),sz=13,color=MUTED,align=PP_ALIGN.CENTER) + + prs.save(out) + print(f"PPTX: {out}") + + +if __name__ == "__main__": + pdf = str(OUT / "35_GUARDiA_Messenger_개발가이드.pdf") + pptx = str(OUT / "36_GUARDiA_Messenger_발표자료.pptx") + gen_pdf(pdf) + gen_pptx(pptx) + print("\n=== 완료 ===") + print(f"MD : {OUT}/34_GUARDiA_Messenger_개발_배포_가이드.md") + print(f"PDF : {pdf}") + print(f"PPTX: {pptx}") diff --git a/gen_opennet_docs.py b/gen_opennet_docs.py new file mode 100644 index 0000000..57565fd --- /dev/null +++ b/gen_opennet_docs.py @@ -0,0 +1,701 @@ +#!/usr/bin/env python3 +""" +GUARDiA 개방망 가이드 — PDF + PPTX 자동 생성 +출력: manual/23_GUARDiA_개방망_가이드.pdf + manual/24_GUARDiA_개방망_발표자료.pptx +""" +import os, sys +from pathlib import Path + +OUT_DIR = Path(__file__).parent +FONT_PATH = None # None이면 기본 폰트 사용 + +# ══════════════════════════════════════════════════════════════ +# PDF 생성 +# ══════════════════════════════════════════════════════════════ +def gen_pdf(output_path: str): + from reportlab.lib.pagesizes import A4 + from reportlab.lib import colors + from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle + from reportlab.lib.units import mm + from reportlab.platypus import ( + SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, + HRFlowable, PageBreak + ) + from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT + + # 폰트 등록 (한글 지원) + from reportlab.pdfbase import pdfmetrics + from reportlab.pdfbase.ttfonts import TTFont + + FONT_DIRS = [ + "C:/Windows/Fonts", + "/usr/share/fonts/truetype/noto", + "/usr/share/fonts/truetype/dejavu", + "/System/Library/Fonts", + ] + FONT_CANDIDATES = [ + ("malgun.ttf", "Malgun"), + ("NanumGothic.ttf", "NanumGothic"), + ("DejaVuSans.ttf", "DejaVuSans"), + ] + + font_name = "Helvetica" + for fname, alias in FONT_CANDIDATES: + for d in FONT_DIRS: + fp = os.path.join(d, fname) + if os.path.exists(fp): + try: + pdfmetrics.registerFont(TTFont(alias, fp)) + font_name = alias + break + except Exception: + pass + if font_name != "Helvetica": + break + + # ── 색상 정의 ────────────────────────────────────────────── + BRAND_BLUE = colors.HexColor("#1a3a6b") + ACCENT_BLUE = colors.HexColor("#4f6ef7") + LIGHT_BLUE = colors.HexColor("#e8ecff") + GRAY_BG = colors.HexColor("#f0f2f5") + SUCCESS_GRN = colors.HexColor("#22c55e") + WARNING_ORG = colors.HexColor("#f59e0b") + DANGER_RED = colors.HexColor("#ef4444") + TEXT_DARK = colors.HexColor("#1e293b") + TEXT_MUTED = colors.HexColor("#64748b") + + doc = SimpleDocTemplate( + output_path, pagesize=A4, + leftMargin=20*mm, rightMargin=20*mm, + topMargin=20*mm, bottomMargin=20*mm + ) + + styles = getSampleStyleSheet() + def sty(name, **kw): + base = kw.pop("base", "Normal") + kw.setdefault("fontName", font_name) + s = ParagraphStyle(name, parent=styles[base], **kw) + return s + + S = { + "cover_title": sty("ct", fontSize=28, textColor=colors.white, + alignment=TA_CENTER, spaceAfter=6, leading=36), + "cover_sub": sty("cs", fontSize=14, textColor=LIGHT_BLUE, + alignment=TA_CENTER, spaceAfter=4), + "cover_meta": sty("cm", fontSize=10, textColor=colors.HexColor("#aab4c8"), + alignment=TA_CENTER), + "h1": sty("h1", fontSize=18, textColor=BRAND_BLUE, + spaceAfter=8, spaceBefore=16, leading=24, fontName=font_name), + "h2": sty("h2", fontSize=13, textColor=ACCENT_BLUE, + spaceAfter=5, spaceBefore=10, leading=18), + "h3": sty("h3", fontSize=11, textColor=TEXT_DARK, + spaceAfter=4, spaceBefore=8, leading=16), + "body": sty("body", fontSize=10, textColor=TEXT_DARK, leading=16, spaceAfter=4), + "code": sty("code", fontName="Courier", fontSize=9, + backColor=GRAY_BG, textColor=colors.HexColor("#1d4ed8"), + leading=14, leftIndent=10, spaceBefore=4, spaceAfter=4), + "note": sty("note", fontSize=9, textColor=TEXT_MUTED, + leftIndent=10, leading=14, spaceAfter=3), + "badge_ok": sty("bok", fontSize=9, textColor=SUCCESS_GRN, fontName=font_name), + "badge_warn": sty("bwrn", fontSize=9, textColor=WARNING_ORG, fontName=font_name), + } + + story = [] + W = A4[0] - 40*mm + + def hr(color=ACCENT_BLUE, w=1): + return HRFlowable(width="100%", thickness=w, color=color, spaceAfter=4, spaceBefore=4) + + def table(data, col_widths=None, header=True): + t = Table(data, colWidths=col_widths) + base_style = [ + ("FONTNAME", (0,0), (-1,-1), font_name), + ("FONTSIZE", (0,0), (-1,-1), 9), + ("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.white, GRAY_BG]), + ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#e2e8f0")), + ("VALIGN", (0,0), (-1,-1), "MIDDLE"), + ("LEFTPADDING", (0,0), (-1,-1), 6), + ("RIGHTPADDING", (0,0), (-1,-1), 6), + ("TOPPADDING", (0,0), (-1,-1), 5), + ("BOTTOMPADDING",(0,0), (-1,-1), 5), + ] + if header: + base_style += [ + ("BACKGROUND", (0,0), (-1,0), BRAND_BLUE), + ("TEXTCOLOR", (0,0), (-1,0), colors.white), + ("FONTSIZE", (0,0), (-1,0), 9), + ("FONTNAME", (0,0), (-1,0), font_name), + ] + t.setStyle(TableStyle(base_style)) + return t + + # ── 표지 ──────────────────────────────────────────────────── + from reportlab.platypus import KeepTogether + cover_bg = Table( + [[Paragraph("GUARDiA ITSM", S["cover_title"]),], + [Paragraph("개방망(Open Network) 구현 가이드", S["cover_sub"])], + [Paragraph(" ", S["cover_sub"])], + [Paragraph("v2.0.0 | 2026-05-30 | (주)지오정보기술", S["cover_meta"])], + [Paragraph("서버: zioinfo.co.kr | AI 기반 레거시 인프라 자율 운영 플랫폼", S["cover_meta"])], + ], + colWidths=[W] + ) + cover_bg.setStyle(TableStyle([ + ("BACKGROUND", (0,0), (-1,-1), BRAND_BLUE), + ("TOPPADDING", (0,0), (-1,-1), 30), + ("BOTTOMPADDING",(0,0),(-1,-1), 30), + ("LEFTPADDING", (0,0), (-1,-1), 20), + ("RIGHTPADDING",(0,0), (-1,-1), 20), + ("ROUNDEDCORNERS", [8]), + ])) + story += [Spacer(1, 30*mm), cover_bg, Spacer(1, 10*mm)] + + # 목차 카드 + toc_data = [ + ["순서", "섹션", "페이지"], + ["1", "개요 및 배경", "2"], + ["2", "아키텍처", "2"], + ["3", "구현 내용", "3"], + ["4", "설치 및 설정", "4"], + ["5", "API 사용법", "5"], + ["6", "보안 설정", "6"], + ["7", "테스트 결과", "7"], + ["8", "운영 절차", "7"], + ] + story += [ + Paragraph("목 차", sty("toc_h", fontSize=13, textColor=BRAND_BLUE, + alignment=TA_CENTER, spaceAfter=8)), + table(toc_data, col_widths=[15*mm, 120*mm, 20*mm]), + PageBreak(), + ] + + # ── 섹션 1: 개요 ─────────────────────────────────────────── + story += [ + Paragraph("1. 개요 및 배경", S["h1"]), hr(), + Paragraph( + "GUARDiA ITSM은 기본적으로 폐쇄망(Closed Network) 환경에서 운영됩니다. " + "그러나 외부 메신저(카카오워크, 네이버웍스, Slack)와의 연동, 공공기관 포털 연계, " + "재택/원격 관리 등의 요구사항이 증가함에 따라 개방망 지원 기능을 추가하였습니다.", + S["body"]), + Spacer(1, 4), + Paragraph("1-1. 폐쇄망 vs 개방망 비교", S["h2"]), + table([ + ["항목", "폐쇄망 (기본)", "개방망 (이 가이드)"], + ["접근 범위", "내부망 only", "인터넷 외부 접근 허용"], + ["CORS 정책", "localhost 만 허용", "지정 외부 도메인 허용"], + ["HTTPS", "선택", "필수 (TLS 1.2/1.3)"], + ["API 인증", "JWT", "JWT + API Key"], + ["외부 AI 호출", "금지 (Ollama only)", "금지 유지 (변경 불가)"], + ["Rate Limiting", "기본", "강화 (30 req/min)"], + ["보안 헤더", "기본", "HSTS 포함 강화"], + ], col_widths=[45*mm, 60*mm, 60*mm]), + Spacer(1, 4), + Paragraph( + "⚠ 핵심 원칙 유지: 개방망 모드에서도 Ollama(LLM)는 내부 전용 유지. " + "외부 AI API(OpenAI, Anthropic 등) 절대 사용 금지.", + S["note"]), + ] + + # ── 섹션 2: 아키텍처 ─────────────────────────────────────── + story += [ + Spacer(1, 8), Paragraph("2. 개방망 아키텍처", S["h1"]), hr(), + Paragraph("2-1. 시스템 구성도", S["h2"]), + Paragraph( + "외부 클라이언트는 Nginx를 통해 TLS 암호화된 채널로 GUARDiA API에 접근합니다. " + "LLM(Ollama)과 데이터베이스(PostgreSQL)는 외부 직접 접근이 불가하며, " + "API 서버를 통해서만 간접 이용 가능합니다.", + S["body"]), + table([ + ["구성 요소", "역할", "외부 접근"], + ["Nginx (443, 8443)", "TLS 종료 + Rate Limit + 보안헤더", "허용"], + ["GUARDiA FastAPI (8001)", "비즈니스 로직 + CORS + 보안 미들웨어", "Nginx 통해서만"], + ["PostgreSQL (5432)", "데이터 저장", "금지 (127.0.0.1만)"], + ["Ollama LLM (11434)", "온프레미스 AI 추론", "금지 (127.0.0.1만)"], + ], col_widths=[55*mm, 85*mm, 25*mm]), + Spacer(1, 4), + Paragraph("2-2. 포트 구성", S["h2"]), + table([ + ["포트", "프로토콜", "서비스", "외부 접근"], + ["80", "HTTP", "홈페이지 (HTTPS 리다이렉트)", "허용"], + ["443", "HTTPS", "홈페이지 SSL", "허용"], + ["8001", "HTTP", "GUARDiA API (내부 직접)", "권장하지 않음"], + ["8443", "HTTPS", "GUARDiA API (외부 접근 권장)", "허용"], + ["5432", "TCP", "PostgreSQL", "차단"], + ["11434", "HTTP", "Ollama LLM", "차단"], + ], col_widths=[15*mm, 25*mm, 90*mm, 35*mm]), + ] + + # ── 섹션 3: 구현 내용 ──────────────────────────────────────── + story += [ + PageBreak(), + Paragraph("3. 구현 내용", S["h1"]), hr(), + Paragraph("3-1. 신규 추가 파일", S["h2"]), + table([ + ["파일", "내용"], + ["core/external_security.py", "API Key 생성/검증/감사 유틸리티"], + ["routers/external_api.py", "외부 API 라우터 (헬스체크, SR, 웹훅, API Key 관리)"], + [".env.open", "개방망 운영 환경변수 템플릿"], + ["deploy/nginx_opennet.py", "Nginx HTTPS 설정 배포 스크립트"], + ], col_widths=[70*mm, 95*mm]), + Spacer(1, 4), + Paragraph("3-2. 수정된 파일", S["h2"]), + table([ + ["파일", "변경 내용"], + ["main.py", "CORS 환경변수 기반 동적 설정, 보안 헤더 미들웨어, external_api 라우터 등록"], + ["models.py", "APIKey ORM 모델 추가 (tb_api_key 테이블)"], + ], col_widths=[70*mm, 95*mm]), + Spacer(1, 4), + Paragraph("3-3. 개방망 모드 CORS 동작 방식", S["h2"]), + Paragraph( + "환경변수 GUARDIA_NETWORK_MODE에 따라 CORS 정책이 자동 전환됩니다:", + S["body"]), + Paragraph("• closed (기본): localhost만 허용", S["note"]), + Paragraph("• open: GUARDIA_ALLOWED_ORIGINS에 지정된 외부 도메인도 허용", S["note"]), + Paragraph("• 정규식 패턴 허용으로 서브도메인 일괄 허용 가능", S["note"]), + ] + + # ── 섹션 4: 설치 및 설정 ──────────────────────────────────── + story += [ + Spacer(1, 8), + Paragraph("4. 설치 및 설정", S["h1"]), hr(), + Paragraph("4-1. .env 개방망 설정", S["h2"]), + Paragraph("다음 환경변수를 /opt/guardia/app/.env 에 설정합니다:", S["body"]), + table([ + ["환경변수", "값 예시", "설명"], + ["GUARDIA_NETWORK_MODE", "open", "개방망 모드 활성화"], + ["GUARDIA_ALLOWED_ORIGINS", "https://itsm.zioinfo.co.kr", "허용 외부 출처"], + ["GUARDIA_WEBHOOK_SECRET", "<강력한 랜덤 값>", "웹훅 HMAC 서명 키"], + ["DATABASE_URL", "postgresql+asyncpg://...", "@ 포함 시 %40으로 인코딩"], + ], col_widths=[60*mm, 55*mm, 50*mm]), + Spacer(1, 4), + Paragraph("4-2. SSL 인증서", S["h2"]), + Paragraph( + "도메인이 있는 경우 Let's Encrypt 인증서 사용을 권장합니다. " + "IP만 있는 경우 자체 서명 인증서를 생성합니다.", + S["body"]), + Paragraph("도메인 보유: certbot --nginx -d itsm.zioinfo.co.kr", S["code"]), + Paragraph( + "IP 전용: openssl req -x509 -nodes -days 3650 -newkey rsa:2048 ...", + S["code"]), + ] + + # ── 섹션 5: API 사용법 ──────────────────────────────────────── + story += [ + PageBreak(), + Paragraph("5. 외부 API 사용법", S["h1"]), hr(), + Paragraph("5-1. API 엔드포인트 목록", S["h2"]), + table([ + ["엔드포인트", "메서드", "인증", "설명"], + ["/api/external/health", "GET", "없음", "헬스체크"], + ["/api/external/status", "GET", "없음", "시스템 공개 상태"], + ["/api/external/keys", "POST", "JWT (관리자)", "API Key 발급"], + ["/api/external/keys/{id}", "DELETE", "JWT (관리자)", "API Key 비활성화"], + ["/api/external/sr", "GET", "API Key (read)", "SR 목록 조회"], + ["/api/external/sr", "POST", "API Key (write)", "SR 등록"], + ["/api/external/webhook", "POST", "HMAC (선택)", "외부 메신저 웹훅"], + ["/docs", "GET", "없음", "OpenAPI 문서"], + ], col_widths=[60*mm, 20*mm, 40*mm, 45*mm]), + Spacer(1, 4), + Paragraph("5-2. API Key 권한 스코프", S["h2"]), + table([ + ["스코프", "허용 API", "사용 예시"], + ["read", "SR 목록 조회", "모니터링 시스템"], + ["write", "SR 등록, 상태 변경", "외부 티켓 시스템"], + ["admin", "모든 외부 API", "통합 관리 도구"], + ["webhook", "웹훅 수신", "카카오워크, Slack 봇"], + ], col_widths=[30*mm, 70*mm, 65*mm]), + Spacer(1, 4), + Paragraph("5-3. 외부 메신저 웹훅 연동 구조", S["h2"]), + Paragraph( + "외부 메신저(카카오워크, 네이버웍스, Slack 등)는 GUARDiA 웹훅 엔드포인트로 " + "자연어 명령을 전송합니다. GUARDiA는 Ollama LLM으로 명령을 파싱하여 처리합니다.", + S["body"]), + table([ + ["메신저", "웹훅 URL", "인증 방식"], + ["카카오워크", "POST /api/external/webhook", "X-GUARDiA-Signature (HMAC)"], + ["네이버웍스", "POST /api/external/webhook", "X-GUARDiA-Signature (HMAC)"], + ["Slack", "POST /api/external/webhook", "X-Source: slack"], + ["Teams", "POST /api/external/webhook", "X-Source: teams"], + ["사용자 정의", "POST /api/external/webhook", "선택 (HMAC 권장)"], + ], col_widths=[35*mm, 80*mm, 50*mm]), + ] + + # ── 섹션 6: 보안 ────────────────────────────────────────────── + story += [ + Spacer(1, 8), + Paragraph("6. 보안 설정", S["h1"]), hr(), + Paragraph("6-1. 적용된 보안 헤더", S["h2"]), + table([ + ["헤더", "값", "효과"], + ["Strict-Transport-Security", "max-age=31536000; includeSubDomains", + "브라우저가 HTTPS만 사용"], + ["X-Frame-Options", "DENY", "Clickjacking 방지"], + ["X-Content-Type-Options", "nosniff", "MIME 스니핑 방지"], + ["X-XSS-Protection", "1; mode=block", "XSS 차단"], + ["Referrer-Policy", "strict-origin-when-cross-origin", "Referrer 정보 제한"], + ], col_widths=[55*mm, 70*mm, 40*mm]), + Spacer(1, 4), + Paragraph("6-2. 변경 불가 보안 정책", S["h2"]), + Paragraph( + "개방망 모드에서도 다음 핵심 보안 정책은 절대 변경 불가합니다:", + S["body"]), + table([ + ["정책", "내용"], + ["외부 LLM 금지", "Ollama(localhost) 전용. OpenAI/Claude 등 외부 API 완전 금지"], + ["SSH 자격증명 보호", "IP, 비밀번호, SSH 계정을 API 응답에 절대 포함 금지"], + ["AES-256-GCM 암호화", "서버 자격증명은 암호화 저장 (os_pw_enc 컬럼)"], + ["root SSH 금지", "opsagent 전용 계정만 사용"], + ["감사 로그", "모든 외부 API 호출 TB_AUDIT_LOG에 기록"], + ], col_widths=[50*mm, 115*mm]), + ] + + # ── 섹션 7: 테스트 결과 ─────────────────────────────────────── + story += [ + PageBreak(), + Paragraph("7. 테스트 결과", S["h1"]), hr(), + Paragraph("테스트 환경: Ubuntu 24.04, GUARDiA 2.0.0, Nginx 1.24 | 2026-05-30", S["note"]), + Spacer(1, 4), + table([ + ["#", "테스트 항목", "기대값", "실제값", "결과"], + ["T1", "HTTP 헬스체크 (8001)", "200 OK", "200 OK", "PASS"], + ["T2", "HTTPS 헬스체크 (8443)", "200 OK", "200 OK", "PASS"], + ["T3", "홈페이지 HTTPS (443)", "200 OK", "200 OK", "PASS"], + ["T4", "미인증 API 접근 차단", "401", "401", "PASS"], + ["T5", "CORS 외부 출처 허용", "Allow-Origin 헤더", "헤더 포함", "PASS"], + ["T6", "HSTS 헤더 적용", "max-age=31536000", "적용됨", "PASS"], + ["T7", "X-Frame-Options", "DENY", "DENY", "PASS"], + ["T8", "Rate Limiting 설정", "zone 설정 확인", "1개 zone", "PASS"], + ["T9", "공개 시스템 상태", "operational", "operational", "PASS"], + ["T10", "개방망 모드 활성", "open", "open", "PASS"], + ], col_widths=[10*mm, 60*mm, 40*mm, 40*mm, 15*mm]), + Spacer(1, 4), + Paragraph("전체 10개 테스트 모두 통과 (10/10 PASS)", sty( + "tr", fontSize=11, textColor=SUCCESS_GRN, alignment=TA_CENTER)), + ] + + # ── 섹션 8: 운영 절차 ────────────────────────────────────────── + story += [ + Spacer(1, 8), + Paragraph("8. 운영 절차", S["h1"]), hr(), + Paragraph("8-1. 모드 전환 명령", S["h2"]), + table([ + ["작업", "명령어"], + ["폐쇄망→개방망", + "echo GUARDIA_NETWORK_MODE=open >> .env && systemctl restart guardia"], + ["개방망→폐쇄망", + "sed -i 's/open/closed/' .env && systemctl restart guardia"], + ["HTTPS 활성화", + "ln -sf sites-available/guardia-https sites-enabled/ && nginx -t && systemctl reload nginx"], + ["HTTPS 비활성화", + "rm sites-enabled/guardia-https && systemctl reload nginx"], + ], col_widths=[35*mm, 130*mm]), + Spacer(1, 4), + Paragraph("8-2. 서비스 접속 정보", S["h2"]), + table([ + ["서비스", "URL", "용도"], + ["GUARDiA ITSM HTTP", "http://zioinfo.co.kr:8001", "내부망 직접 접근"], + ["GUARDiA ITSM HTTPS", "https://zioinfo.co.kr:8443", "개방망 외부 접근 (권장)"], + ["외부 API", "https://zioinfo.co.kr:8443/api/external/", "API Key 인증"], + ["OpenAPI 문서", "https://zioinfo.co.kr:8443/docs", "API 명세서 (공개)"], + ["홈페이지 HTTPS", "https://zioinfo.co.kr", "지오정보기술 홈페이지"], + ], col_widths=[40*mm, 75*mm, 50*mm]), + Spacer(1, 8), + hr(colors.HexColor("#e2e8f0")), + Paragraph( + "GUARDiA ITSM v2.0.0 | (주)지오정보기술 | 2026-05-30", + sty("footer", fontSize=8, textColor=TEXT_MUTED, alignment=TA_CENTER)), + ] + + doc.build(story) + print(f"PDF 생성 완료: {output_path}") + + +# ══════════════════════════════════════════════════════════════ +# PPTX 생성 +# ══════════════════════════════════════════════════════════════ +def gen_pptx(output_path: str): + from pptx import Presentation + from pptx.util import Inches, Pt, Emu + from pptx.dml.color import RGBColor + from pptx.enum.text import PP_ALIGN + from pptx.util import Inches, Pt + + W, H = Inches(13.33), Inches(7.5) # 16:9 와이드 + prs = Presentation() + prs.slide_width = W + prs.slide_height = H + + # ── 색상 팔레트 ───────────────────────────────────────────── + BRAND = RGBColor(0x1a, 0x3a, 0x6b) + ACCENT = RGBColor(0x4f, 0x6e, 0xf7) + WHITE = RGBColor(0xff, 0xff, 0xff) + GRAY_LT = RGBColor(0xf0, 0xf2, 0xf5) + GREEN = RGBColor(0x22, 0xc5, 0x5e) + ORANGE = RGBColor(0xf5, 0x9e, 0x0b) + RED = RGBColor(0xef, 0x44, 0x44) + DARK = RGBColor(0x1e, 0x29, 0x3b) + MUTED = RGBColor(0x64, 0x74, 0x8b) + + def blank_slide(): + layout = prs.slide_layouts[6] # blank + return prs.slides.add_slide(layout) + + def add_rect(slide, x, y, w, h, fill=None, line=None, radius=0): + from pptx.util import Emu + shape = slide.shapes.add_shape(1, x, y, w, h) # MSO_SHAPE_TYPE.RECTANGLE + if fill: + shape.fill.solid() + shape.fill.fore_color.rgb = fill + else: + shape.fill.background() + if line: + shape.line.color.rgb = line + shape.line.width = Pt(0.75) + else: + shape.line.fill.background() + return shape + + def add_text(slide, text, x, y, w, h, size=18, bold=False, + color=DARK, align=PP_ALIGN.LEFT, italic=False): + tb = slide.shapes.add_textbox(x, y, w, h) + tf = tb.text_frame + tf.word_wrap = True + p = tf.paragraphs[0] + p.alignment = align + run = p.add_run() + run.text = text + run.font.size = Pt(size) + run.font.bold = bold + run.font.italic = italic + run.font.color.rgb = color + return tb + + def add_table_slide(slide, headers, rows, x, y, w, h, col_widths=None): + from pptx.util import Pt + cols = len(headers) + tbl = slide.shapes.add_table(len(rows)+1, cols, x, y, w, h).table + if col_widths: + for i, cw in enumerate(col_widths): + tbl.columns[i].width = cw + + def cell_style(cell, text, bg=None, txt_color=DARK, bold=False, sz=10): + cell.text = text + cell.text_frame.paragraphs[0].font.size = Pt(sz) + cell.text_frame.paragraphs[0].font.bold = bold + cell.text_frame.paragraphs[0].font.color.rgb = txt_color + if bg: + cell.fill.solid() + cell.fill.fore_color.rgb = bg + + for j, h_text in enumerate(headers): + cell_style(tbl.cell(0, j), h_text, bg=BRAND, txt_color=WHITE, bold=True, sz=10) + for i, row in enumerate(rows): + bg = GRAY_LT if i % 2 == 0 else WHITE + for j, val in enumerate(row): + cell_style(tbl.cell(i+1, j), str(val), bg=bg) + + # ── 슬라이드 1: 표지 ─────────────────────────────────────── + s = blank_slide() + add_rect(s, 0, 0, W, H, fill=BRAND) + add_rect(s, Inches(0.5), Inches(1.2), Inches(12.33), Inches(4.5), + fill=RGBColor(0x25, 0x4a, 0x80)) + + add_text(s, "GUARDiA ITSM", Inches(0.8), Inches(1.5), Inches(11.73), Inches(1.2), + size=44, bold=True, color=WHITE, align=PP_ALIGN.CENTER) + add_text(s, "개방망(Open Network) 구현 가이드", + Inches(0.8), Inches(2.7), Inches(11.73), Inches(0.8), + size=22, color=RGBColor(0xaa, 0xc4, 0xe8), align=PP_ALIGN.CENTER) + add_text(s, "v2.0.0 | 2026-05-30 | (주)지오정보기술", + Inches(0.8), Inches(3.5), Inches(11.73), Inches(0.5), + size=13, color=MUTED, align=PP_ALIGN.CENTER) + + # 배지들 + badges = [("HTTPS", GREEN), ("API Key", ACCENT), ("CORS", ORANGE), ("Rate Limit", RED)] + for i, (txt, col) in enumerate(badges): + bx = Inches(3.2 + i * 1.8) + add_rect(s, bx, Inches(5.0), Inches(1.5), Inches(0.5), fill=col) + add_text(s, txt, bx + Inches(0.1), Inches(5.05), Inches(1.3), Inches(0.4), + size=12, bold=True, color=WHITE, align=PP_ALIGN.CENTER) + + add_text(s, "AI 기반 레거시 인프라 자율 운영 플랫폼", + Inches(0.8), Inches(6.5), Inches(11.73), Inches(0.5), + size=11, color=MUTED, italic=True, align=PP_ALIGN.CENTER) + + # ── 슬라이드 2: 목차 ─────────────────────────────────────── + s = blank_slide() + add_rect(s, 0, 0, W, Inches(1.2), fill=BRAND) + add_text(s, "목차 (Agenda)", Inches(0.4), Inches(0.25), Inches(12), Inches(0.7), + size=24, bold=True, color=WHITE) + + items = [ + ("1", "개요 및 배경", "폐쇄망 vs 개방망 비교, 지원 필요성"), + ("2", "아키텍처", "개방망 시스템 구성도, 포트 구성"), + ("3", "구현 내용", "신규/수정 파일, CORS 동작 방식"), + ("4", "설치 및 설정", ".env 설정, SSL 인증서, Nginx"), + ("5", "외부 API", "엔드포인트, API Key 권한, 웹훅 연동"), + ("6", "보안 설정", "보안 헤더, 불변 보안 정책"), + ("7", "테스트 결과", "10개 항목 전체 통과 (10/10 PASS)"), + ("8", "운영 절차", "모드 전환, 접속 정보"), + ] + for i, (num, title, desc) in enumerate(items): + row = i // 2; col = i % 2 + bx = Inches(0.4 + col * 6.4); by = Inches(1.4 + row * 1.35) + add_rect(s, bx, by, Inches(5.9), Inches(1.1), fill=GRAY_LT, line=ACCENT) + add_rect(s, bx, by, Inches(0.6), Inches(1.1), fill=ACCENT) + add_text(s, num, bx + Inches(0.05), by + Inches(0.2), + Inches(0.5), Inches(0.6), size=18, bold=True, color=WHITE, align=PP_ALIGN.CENTER) + add_text(s, title, bx + Inches(0.7), by + Inches(0.1), + Inches(5.1), Inches(0.45), size=14, bold=True, color=BRAND) + add_text(s, desc, bx + Inches(0.7), by + Inches(0.55), + Inches(5.1), Inches(0.45), size=10, color=MUTED) + + # ── 슬라이드 3: 개요 ──────────────────────────────────────── + s = blank_slide() + add_rect(s, 0, 0, W, Inches(1.2), fill=BRAND) + add_text(s, "1. 개요 — 개방망 지원 필요성", Inches(0.4), Inches(0.25), + Inches(12), Inches(0.7), size=24, bold=True, color=WHITE) + + add_table_slide(s, + ["항목", "폐쇄망 (기본)", "개방망 (이 가이드)"], + [ + ["접근 범위", "내부망 only", "인터넷 외부 접근 허용"], + ["CORS 정책", "localhost 만 허용", "지정 외부 도메인 허용"], + ["HTTPS", "선택", "필수 (TLS 1.2/1.3)"], + ["API 인증", "JWT only", "JWT + API Key 추가"], + ["외부 LLM", "금지 (Ollama only)", "금지 유지 (변경 불가)"], + ["Rate Limiting", "기본", "강화 (30 req/min)"], + ], + Inches(0.4), Inches(1.4), Inches(12.5), Inches(4.0), + col_widths=[Inches(2.5), Inches(4.5), Inches(5.5)] + ) + + add_rect(s, Inches(0.4), Inches(5.8), Inches(12.5), Inches(0.7), + fill=RGBColor(0xff, 0xf1, 0xf2)) + add_text(s, "⚠ 핵심 원칙 유지: 개방망 모드에서도 Ollama(LLM)는 내부 전용. " + "외부 AI API 절대 사용 금지.", + Inches(0.6), Inches(5.9), Inches(12.2), Inches(0.5), + size=11, bold=True, color=RED) + + # ── 슬라이드 4: 아키텍처 ──────────────────────────────────── + s = blank_slide() + add_rect(s, 0, 0, W, Inches(1.2), fill=BRAND) + add_text(s, "2. 개방망 아키텍처", Inches(0.4), Inches(0.25), + Inches(12), Inches(0.7), size=24, bold=True, color=WHITE) + + # 아키텍처 다이어그램 (박스들) + boxes = [ + ("외부 클라이언트\n(브라우저/메신저봇)", Inches(0.3), Inches(1.3), Inches(2.8), Inches(1.0), ACCENT, WHITE), + ("Nginx\n(TLS + Rate Limit + 보안헤더)", Inches(4.0), Inches(1.3), Inches(2.8), Inches(1.0), BRAND, WHITE), + ("GUARDiA ITSM\n(FastAPI 8001)", Inches(7.7), Inches(1.3), Inches(2.8), Inches(1.0), ACCENT, WHITE), + ("PostgreSQL\n(내부 전용 5432)", Inches(7.7), Inches(3.2), Inches(2.8), Inches(0.9), DARK, WHITE), + ("Ollama LLM\n(내부 전용 11434)", Inches(11.0), Inches(3.2), Inches(2.0), Inches(0.9), DARK, WHITE), + ] + for txt, bx, by, bw, bh, fill, txt_col in boxes: + add_rect(s, bx, by, bw, bh, fill=fill) + add_text(s, txt, bx + Inches(0.1), by + Inches(0.1), bw - Inches(0.2), + bh - Inches(0.2), size=11, bold=True, color=txt_col, align=PP_ALIGN.CENTER) + + # 화살표 텍스트 + add_text(s, "→ HTTPS (443/8443)", Inches(3.2), Inches(1.6), Inches(0.7), Inches(0.5), + size=8, color=MUTED, align=PP_ALIGN.CENTER) + add_text(s, "→ HTTP 내부", Inches(6.9), Inches(1.6), Inches(0.7), Inches(0.5), + size=8, color=MUTED, align=PP_ALIGN.CENTER) + + # 포트 구성 테이블 + add_table_slide(s, + ["포트", "서비스", "외부 접근"], + [ + ["80/443", "홈페이지 Nginx (HTTPS)", "허용"], + ["8001", "GUARDiA FastAPI (직접)", "권장 안 함"], + ["8443", "GUARDiA Nginx (HTTPS, 권장)", "허용"], + ["5432", "PostgreSQL", "차단"], + ["11434", "Ollama LLM", "차단"], + ], + Inches(0.4), Inches(4.3), Inches(7.5), Inches(2.7), + col_widths=[Inches(1.5), Inches(3.5), Inches(2.5)] + ) + + # ── 슬라이드 5: 외부 API ──────────────────────────────────── + s = blank_slide() + add_rect(s, 0, 0, W, Inches(1.2), fill=BRAND) + add_text(s, "5. 외부 API 엔드포인트", Inches(0.4), Inches(0.25), + Inches(12), Inches(0.7), size=24, bold=True, color=WHITE) + + add_table_slide(s, + ["엔드포인트", "메서드", "인증", "설명"], + [ + ["/api/external/health", "GET", "없음", "헬스체크 (공개)"], + ["/api/external/status", "GET", "없음", "시스템 공개 상태"], + ["/api/external/keys", "POST", "JWT (관리자)", "API Key 발급"], + ["/api/external/sr", "GET", "API Key (read)", "SR 목록 조회"], + ["/api/external/sr", "POST", "API Key (write)", "SR 등록"], + ["/api/external/webhook", "POST", "HMAC (선택)", "외부 메신저 웹훅 수신"], + ], + Inches(0.4), Inches(1.4), Inches(12.5), Inches(3.2), + col_widths=[Inches(3.5), Inches(1.5), Inches(2.5), Inches(5.0)] + ) + + add_text(s, "API Key 권한 스코프:", Inches(0.4), Inches(4.9), + Inches(4), Inches(0.4), size=12, bold=True, color=BRAND) + scopes = [("read", "조회", GREEN), ("write", "등록/수정", ACCENT), + ("webhook", "웹훅", ORANGE), ("admin", "전체", RED)] + for i, (sc, desc, col) in enumerate(scopes): + bx = Inches(0.4 + i * 3.1) + add_rect(s, bx, Inches(5.4), Inches(2.8), Inches(0.8), fill=col) + add_text(s, f"{sc}\n{desc}", bx + Inches(0.1), Inches(5.45), + Inches(2.6), Inches(0.7), size=11, bold=True, color=WHITE, align=PP_ALIGN.CENTER) + + # ── 슬라이드 6: 테스트 결과 ───────────────────────────────── + s = blank_slide() + add_rect(s, 0, 0, W, Inches(1.2), fill=BRAND) + add_text(s, "7. 테스트 결과 — 10/10 PASS ✅", Inches(0.4), Inches(0.25), + Inches(12), Inches(0.7), size=24, bold=True, color=WHITE) + + add_table_slide(s, + ["#", "테스트 항목", "기대값", "실제값", "결과"], + [ + ["T1", "HTTP 헬스체크 (8001)", "200 OK", "200 OK", "PASS"], + ["T2", "HTTPS 헬스체크 (8443)", "200 OK", "200 OK", "PASS"], + ["T3", "홈페이지 HTTPS (443)", "200 OK", "200 OK", "PASS"], + ["T4", "미인증 API 접근 차단", "401", "401", "PASS"], + ["T5", "CORS 외부 출처 허용", "Allow-Origin", "헤더 포함", "PASS"], + ["T6", "HSTS 헤더 적용", "max-age=31536000", "적용됨", "PASS"], + ["T7", "X-Frame-Options DENY", "DENY", "DENY", "PASS"], + ["T8", "Rate Limiting 설정", "zone 확인", "1개 zone", "PASS"], + ["T9", "공개 시스템 상태", "operational", "operational", "PASS"], + ["T10", "개방망 모드 활성", "NETWORK_MODE=open", "open", "PASS"], + ], + Inches(0.4), Inches(1.4), Inches(12.5), Inches(4.5), + col_widths=[Inches(0.8), Inches(3.8), Inches(2.5), Inches(2.5), Inches(1.5)] + ) + + add_rect(s, Inches(0.4), Inches(6.2), Inches(12.5), Inches(0.8), fill=GREEN) + add_text(s, "✅ 전체 10개 테스트 모두 통과 (10/10 PASS) — 2026-05-30", + Inches(0.6), Inches(6.3), Inches(12.1), Inches(0.6), + size=14, bold=True, color=WHITE, align=PP_ALIGN.CENTER) + + # ── 슬라이드 7: 마지막 ────────────────────────────────────── + s = blank_slide() + add_rect(s, 0, 0, W, H, fill=BRAND) + add_text(s, "GUARDiA ITSM 개방망 지원 완료", Inches(1), Inches(2.0), + Inches(11.33), Inches(1.2), size=32, bold=True, color=WHITE, align=PP_ALIGN.CENTER) + add_text(s, "HTTP → HTTPS 전환 | API Key 인증 | CORS 외부 허용 | 보안 헤더 강화", + Inches(1), Inches(3.3), Inches(11.33), Inches(0.6), + size=14, color=RGBColor(0xaa, 0xc4, 0xe8), align=PP_ALIGN.CENTER) + add_text(s, "(주)지오정보기술 | GUARDiA v2.0.0 | 2026-05-30", + Inches(1), Inches(5.5), Inches(11.33), Inches(0.5), + size=12, color=MUTED, align=PP_ALIGN.CENTER) + + prs.save(output_path) + print(f"PPTX 생성 완료: {output_path}") + + +if __name__ == "__main__": + pdf_out = str(OUT_DIR / "23_GUARDiA_개방망_가이드.pdf") + pptx_out = str(OUT_DIR / "24_GUARDiA_개방망_발표자료.pptx") + gen_pdf(pdf_out) + gen_pptx(pptx_out) + print("\n=== 생성 완료 ===") + print(f"PDF : {pdf_out}") + print(f"PPTX: {pptx_out}")