G-1: 메신저 Webhook Relay + _send_to_room 실제 httpx 호출 구현 G-2: POST /api/tasks/bulk SR 대량작업 엔드포인트 (최대 100건) G-3: 라이선스 만료 알림 스케줄러 (매일 09:00 KST) G-4: 체험판 upgrade_banner 필드 + license.py 배너 로직 G-5: core/auto_rca.py + incidents/problem auto-rca 엔드포인트 G-6: core/deploy_impact.py + vibe impact-analysis 엔드포인트 G-7: core/ticket_classifier.py + SR 생성 시 AI 분류 + ai-suggestion API G-8: VulnPatchRecord 모델 + vuln_scan 패치추적 4개 엔드포인트 G-9: core/jira_sync.py + gateway Jira/Confluence 연동 엔드포인트 G-10: core/push_notify.py + routers/push.py + PushSubscription 모델 G-11: approvals 다중승인 (위임/서명/기한초과/마감연장) G-12: alembic.ini + migrations/ + cicd/migrate_to_postgres.sh 하네스: guardia-orchestrator 확장기능 Phase 반영 봇명령어: /sr /status /license /bulk 슬래시 명령어 추가 설치스크립트: setup/ (Ubuntu, CentOS, RHEL, Windows) --test 옵션 포함 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
350 lines
16 KiB
Markdown
350 lines
16 KiB
Markdown
# [Specification] GUARDiA 데이터베이스 스키마 설계서
|
|
|
|
> **DBMS:** PostgreSQL 15+
|
|
> **원칙:** root 계정 금지. 전용 서비스 계정 사용. 비밀번호 컬럼 AES-256 암호화 필수.
|
|
|
|
---
|
|
|
|
## 1. 인프라 자산 영역 (CMDB)
|
|
|
|
### TB_INST_META (관공서 마스터)
|
|
```sql
|
|
CREATE TABLE TB_INST_META (
|
|
inst_id VARCHAR(20) PRIMARY KEY, -- 기관 코드 (예: MOF, MOIS)
|
|
inst_name VARCHAR(100) NOT NULL, -- 기관명 (예: 기획재정부)
|
|
pm_contact VARCHAR(50), -- 담당 PM 사번
|
|
phone VARCHAR(20), -- 대표 연락처
|
|
address VARCHAR(300), -- 주소
|
|
region VARCHAR(50), -- 지역 (예: 서울, 세종, 부산)
|
|
contract_start DATE, -- 유지보수 계약 시작일
|
|
contract_end DATE, -- 유지보수 계약 종료일
|
|
sla_hours INT DEFAULT 4, -- SLA 응답시간 (시간)
|
|
note TEXT, -- 기타 메모
|
|
is_active CHAR(1) DEFAULT 'Y', -- Y: 활성 / N: 비활성
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
### TB_INST_CONTACT (기관 담당자 연락처)
|
|
```sql
|
|
CREATE TABLE TB_INST_CONTACT (
|
|
contact_id BIGSERIAL PRIMARY KEY,
|
|
inst_id VARCHAR(20) REFERENCES TB_INST_META(inst_id) ON DELETE CASCADE,
|
|
contact_name VARCHAR(50) NOT NULL, -- 담당자 이름
|
|
dept VARCHAR(100), -- 부서명
|
|
position VARCHAR(50), -- 직책/직급
|
|
role VARCHAR(30) NOT NULL, -- MANAGER | ENGINEER | PM | SECURITY | HELPDESK
|
|
email VARCHAR(100), -- 이메일 (필수 권장)
|
|
phone VARCHAR(20), -- 직통 전화
|
|
mobile VARCHAR(20), -- 휴대폰
|
|
is_primary CHAR(1) DEFAULT 'N', -- Y: 주 담당자
|
|
is_active CHAR(1) DEFAULT 'Y',
|
|
note TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
CREATE INDEX idx_contact_inst ON TB_INST_CONTACT(inst_id, role);
|
|
```
|
|
|
|
### TB_SERVER_INFO (서버 노드 마스터 — 확장)
|
|
```sql
|
|
CREATE TABLE TB_SERVER_INFO (
|
|
server_id VARCHAR(30) PRIMARY KEY, -- 서버 고유 ID (예: MOF-WAS-01)
|
|
inst_id VARCHAR(20) REFERENCES TB_INST_META(inst_id),
|
|
system_name VARCHAR(100) NOT NULL, -- 업무 시스템명
|
|
layer VARCHAR(10) NOT NULL, -- WEB | WAS | DB | ESB | BATCH
|
|
hostname VARCHAR(100),
|
|
ip_address VARCHAR(45) NOT NULL, -- ※ API 응답 노출 금지
|
|
ssh_port INT DEFAULT 22,
|
|
ssh_method VARCHAR(20) DEFAULT 'PASSWORD', -- PASSWORD | KEY | KEY_WITH_PASS
|
|
ssh_key_path VARCHAR(255), -- SSH 키 파일 경로 (서버측 관제 PC 경로)
|
|
ftp_path VARCHAR(255), -- 배포 기본 경로
|
|
os_user VARCHAR(50), -- SSH 접속 계정 ※ API 응답 노출 금지
|
|
os_pw_enc TEXT, -- AES-256-GCM 암호화 비밀번호 ※ 절대 노출 금지
|
|
os_type VARCHAR(20) DEFAULT 'LINUX', -- LINUX | WINDOWS | AIX | HP-UX
|
|
os_version VARCHAR(50), -- OS 버전 (예: RHEL 8.6, Ubuntu 22.04)
|
|
-- WEB 서버 정보
|
|
web_server VARCHAR(50), -- Apache | Nginx | IIS | WebtoB
|
|
web_version VARCHAR(30),
|
|
web_port INT,
|
|
web_conf_path VARCHAR(255), -- WEB 설정 파일 경로
|
|
-- WAS 서버 정보
|
|
was_type VARCHAR(50), -- Tomcat | JBoss | WebLogic | JEUS | WebSphere
|
|
was_version VARCHAR(30),
|
|
was_port INT,
|
|
was_home VARCHAR(255), -- WAS_HOME 경로
|
|
was_deploy_path VARCHAR(255), -- 배포 경로
|
|
jdk_version VARCHAR(20), -- JDK 버전
|
|
heap_min VARCHAR(20), -- JVM 최소 힙 (예: 512m)
|
|
heap_max VARCHAR(20), -- JVM 최대 힙 (예: 2048m)
|
|
-- DB 서버 정보
|
|
db_type VARCHAR(30), -- PostgreSQL | Oracle | MySQL | MSSQL | Tibero | Altibase
|
|
db_version VARCHAR(30),
|
|
db_port INT,
|
|
db_name VARCHAR(100), -- DB명 / SID
|
|
db_schema VARCHAR(100), -- 스키마명
|
|
-- 유지보수 정보
|
|
cpu_cores INT, -- CPU 코어 수
|
|
memory_gb INT, -- 메모리 (GB)
|
|
disk_total_gb INT, -- 전체 디스크 (GB)
|
|
maintenance_contact VARCHAR(50), -- 서버 담당자 사번
|
|
install_date DATE, -- 설치일
|
|
eol_date DATE, -- 지원 만료일 (EOL)
|
|
backup_path VARCHAR(255), -- 백업 경로
|
|
ssl_cert_path VARCHAR(255), -- SSL 인증서 경로
|
|
ssl_expire_date DATE, -- SSL 만료일
|
|
note TEXT, -- 유지보수 기타 메모
|
|
status VARCHAR(20) DEFAULT 'ACTIVE', -- ACTIVE | MAINTENANCE | DECOMMISSIONED
|
|
last_check TIMESTAMP,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
CREATE INDEX idx_server_inst ON TB_SERVER_INFO(inst_id, layer);
|
|
CREATE INDEX idx_server_ssl ON TB_SERVER_INFO(ssl_expire_date) WHERE ssl_expire_date IS NOT NULL;
|
|
```
|
|
|
|
### TB_SYSTEM_OWNER (시스템 담당자 매핑)
|
|
```sql
|
|
CREATE TABLE TB_SYSTEM_OWNER (
|
|
system_id VARCHAR(30) PRIMARY KEY,
|
|
inst_id VARCHAR(20) REFERENCES TB_INST_META(inst_id),
|
|
owner_id VARCHAR(50) NOT NULL, -- 1순위 승인권자 사번
|
|
deputy_id VARCHAR(50), -- 2순위 대리 승인자
|
|
supervisor_id VARCHAR(50), -- 3순위 상위 관리자
|
|
sla_minutes INT DEFAULT 10, -- 승인 대기 SLA (분)
|
|
is_active CHAR(1) DEFAULT 'Y' -- Y: 근무중 / N: 부재중
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## 2. 운영 작업 영역 (Ops Task)
|
|
|
|
### TB_OPS_TASK (운영 작업 헤더)
|
|
```sql
|
|
CREATE TABLE TB_OPS_TASK (
|
|
task_id VARCHAR(30) PRIMARY KEY, -- 예: OPS-20260523-001
|
|
task_category VARCHAR(50) NOT NULL, -- DEPLOY | INFRA | DATA | MAINTENANCE
|
|
task_sub_type VARCHAR(50), -- SSL_REPLACE | LOG_ANALYSIS | RESTART
|
|
raw_request TEXT NOT NULL, -- 사용자 원문 자연어
|
|
status VARCHAR(30) DEFAULT 'RECEIVED',
|
|
requester_id VARCHAR(50) NOT NULL,
|
|
inst_id VARCHAR(20) REFERENCES TB_INST_META(inst_id),
|
|
playbook_id VARCHAR(50), -- 실행 플레이북 ID
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
-- 상태값: RECEIVED | PARSED | PENDING_APPROVAL | ESCALATED | APPROVED | IN_PROGRESS | PENDING_PM_VALIDATION | COMPLETED | FAILED_ROLLBACK
|
|
CREATE INDEX idx_task_status ON TB_OPS_TASK(status, created_at DESC);
|
|
```
|
|
|
|
### TB_DEPLOY_HISTORY (배포 상세 이력)
|
|
```sql
|
|
CREATE TABLE TB_DEPLOY_HISTORY (
|
|
deploy_id BIGSERIAL PRIMARY KEY,
|
|
task_id VARCHAR(30) REFERENCES TB_OPS_TASK(task_id),
|
|
server_id VARCHAR(30) REFERENCES TB_SERVER_INFO(server_id),
|
|
user_id VARCHAR(50) NOT NULL,
|
|
sr_no VARCHAR(30),
|
|
artifact_list JSONB, -- 배포된 파일 목록
|
|
deploy_status CHAR(1) DEFAULT 'P', -- P:대기 S:성공 F:실패
|
|
backup_path VARCHAR(255),
|
|
result_hash CHAR(64), -- SHA-256
|
|
deployed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## 3. 거버넌스 승인 영역
|
|
|
|
### TB_APPROVAL_FLOW (다단계 승인 이력)
|
|
```sql
|
|
CREATE TABLE TB_APPROVAL_FLOW (
|
|
flow_id BIGSERIAL PRIMARY KEY,
|
|
task_id VARCHAR(30) REFERENCES TB_OPS_TASK(task_id),
|
|
step_order INT NOT NULL, -- 1, 2, 3...
|
|
approver_id VARCHAR(50) NOT NULL,
|
|
approval_status CHAR(1) DEFAULT 'P', -- P:대기 A:승인 R:반려
|
|
comments VARCHAR(500),
|
|
escalation_type VARCHAR(20), -- DIRECT | DEPUTY | SUPERVISOR
|
|
approved_at TIMESTAMP
|
|
);
|
|
CREATE INDEX idx_approval_task ON TB_APPROVAL_FLOW(task_id, step_order);
|
|
```
|
|
|
|
---
|
|
|
|
## 4. 감사 영역 (Audit — 위변조 방지)
|
|
|
|
### TB_AUDIT_LOG (SHA-256 해시 체인)
|
|
```sql
|
|
CREATE TABLE TB_AUDIT_LOG (
|
|
log_id BIGSERIAL PRIMARY KEY,
|
|
task_id VARCHAR(30) REFERENCES TB_OPS_TASK(task_id),
|
|
server_ip VARCHAR(45),
|
|
exec_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
command TEXT NOT NULL,
|
|
exit_code INT,
|
|
result_hash CHAR(64), -- SHA256(현재 결과 + 이전 hash)
|
|
operator_id VARCHAR(50)
|
|
);
|
|
-- 해시 체이닝: Log[n].result_hash = SHA256(Log[n].output || Log[n-1].result_hash)
|
|
```
|
|
|
|
### TB_SR_REQUEST (SR 티켓 — 레거시 호환)
|
|
```sql
|
|
CREATE TABLE TB_SR_REQUEST (
|
|
sr_no VARCHAR(30) PRIMARY KEY, -- SR-2026-001
|
|
requester VARCHAR(100),
|
|
system_id VARCHAR(30) REFERENCES TB_SERVER_INFO(server_id),
|
|
raw_text TEXT,
|
|
task_type VARCHAR(50), -- UI_FIX | DEPLOY | LOG_ANALYSIS
|
|
status VARCHAR(20) DEFAULT 'PENDING',
|
|
assigned_ai VARCHAR(50), -- 에이전트 실행 ID
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## 5. 메신저 채팅 영역
|
|
|
|
### TB_MSG_ROOMS (대화방)
|
|
```sql
|
|
CREATE TABLE TB_MSG_ROOMS (
|
|
room_id VARCHAR(50) PRIMARY KEY,
|
|
room_name VARCHAR(100) NOT NULL,
|
|
inst_id VARCHAR(20) REFERENCES TB_INST_META(inst_id),
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
### TB_MSG_CHAT_LOG (채팅 이력)
|
|
```sql
|
|
CREATE TABLE TB_MSG_CHAT_LOG (
|
|
chat_id BIGSERIAL PRIMARY KEY,
|
|
room_id VARCHAR(50) REFERENCES TB_MSG_ROOMS(room_id),
|
|
sender_id VARCHAR(50) NOT NULL,
|
|
sender_name VARCHAR(100),
|
|
sender_type VARCHAR(20) NOT NULL, -- HUMAN | BOT | AGENT
|
|
message_text TEXT,
|
|
is_command BOOLEAN DEFAULT FALSE,
|
|
task_id VARCHAR(30),
|
|
itsm_ticket_id VARCHAR(50), -- 향후 ITSM 연동용 (null 허용)
|
|
asset_code VARCHAR(50), -- 인프라 자산 코드
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## 6. 쉘 스크립트 관리 영역
|
|
|
|
### TB_SHELL_SCRIPT (쉘 스크립트 라이브러리)
|
|
```sql
|
|
CREATE TABLE TB_SHELL_SCRIPT (
|
|
script_id BIGSERIAL PRIMARY KEY,
|
|
script_name VARCHAR(200) NOT NULL, -- 스크립트 이름
|
|
category VARCHAR(30) NOT NULL, -- SM | REGULAR | ADHOC | DEPLOY | SECURITY | MONITORING
|
|
sub_category VARCHAR(50), -- 세부 분류 (예: DISK_CHECK, LOG_ROTATE, SSL_RENEW)
|
|
target_layer VARCHAR(20), -- WEB | WAS | DB | ESB | ALL
|
|
os_type VARCHAR(20) DEFAULT 'LINUX', -- LINUX | WINDOWS | ALL
|
|
description TEXT NOT NULL, -- 스크립트 설명 (증상/목적)
|
|
script_body TEXT NOT NULL, -- 실제 쉘 스크립트 내용
|
|
parameters JSONB, -- 파라미터 명세 [{"name":"TARGET","desc":"대상 서버","required":true}]
|
|
sample_output TEXT, -- 예상 출력 샘플 (JSON)
|
|
is_dangerous BOOLEAN DEFAULT FALSE, -- 위험 명령 포함 여부 (rm, kill 등)
|
|
requires_approval BOOLEAN DEFAULT FALSE, -- 실행 전 승인 필요 여부
|
|
author VARCHAR(50), -- 작성자 사번
|
|
version VARCHAR(20) DEFAULT '1.0.0',
|
|
tags VARCHAR(200), -- 검색 태그 (콤마 구분)
|
|
inst_id VARCHAR(20) REFERENCES TB_INST_META(inst_id), -- NULL이면 공용
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
use_count INT DEFAULT 0, -- 실행 횟수 (통계용)
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
CREATE INDEX idx_script_category ON TB_SHELL_SCRIPT(category, target_layer);
|
|
CREATE INDEX idx_script_inst ON TB_SHELL_SCRIPT(inst_id);
|
|
```
|
|
|
|
#### 카테고리 정의
|
|
|
|
| category | 설명 |
|
|
|----------|------|
|
|
| `SM` | 시스템 관리 (일상 운영) |
|
|
| `REGULAR` | 정기점검 스크립트 (월간/분기/반기) |
|
|
| `ADHOC` | 수시점검 스크립트 (장애 대응, 긴급 확인) |
|
|
| `DEPLOY` | 배포 관련 스크립트 |
|
|
| `SECURITY` | 보안 감사·계정 점검 |
|
|
| `MONITORING` | 모니터링·헬스체크 |
|
|
|
|
---
|
|
|
|
## 7. 작업 타임테이블 영역
|
|
|
|
### TB_WORK_TIMETABLE (작업 이력 타임테이블)
|
|
```sql
|
|
CREATE TABLE TB_WORK_TIMETABLE (
|
|
timetable_id BIGSERIAL PRIMARY KEY,
|
|
work_type VARCHAR(30) NOT NULL, -- REGULAR_CHECK | PM | SR | ADHOC | DEPLOY | EMERGENCY
|
|
title VARCHAR(200) NOT NULL, -- 작업 제목 (예: 2025년 1분기 정기점검 - MOF)
|
|
inst_id VARCHAR(20) REFERENCES TB_INST_META(inst_id),
|
|
server_id VARCHAR(30) REFERENCES TB_SERVER_INFO(server_id),
|
|
sr_id VARCHAR(30), -- SR 연계 (있을 경우)
|
|
script_id BIGINT REFERENCES TB_SHELL_SCRIPT(script_id),
|
|
scheduled_at TIMESTAMP NOT NULL, -- 처리 예정 일시
|
|
started_at TIMESTAMP, -- 실제 시작 일시
|
|
completed_at TIMESTAMP, -- 완료 일시
|
|
content TEXT NOT NULL, -- 처리 내용 상세
|
|
command_or_shell TEXT, -- 실행한 명령어 또는 쉘 스크립트
|
|
result TEXT, -- 처리 결과
|
|
result_status VARCHAR(20) DEFAULT 'PENDING', -- PENDING | SUCCESS | FAILED | PARTIAL | CANCELLED
|
|
assignee VARCHAR(50), -- 담당자 사번
|
|
reviewer VARCHAR(50), -- 검토자 사번 (PM)
|
|
attachments JSONB, -- 첨부파일 목록 [{"filename":"...","path":"..."}]
|
|
note TEXT, -- 비고
|
|
created_by VARCHAR(50),
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
CREATE INDEX idx_timetable_inst ON TB_WORK_TIMETABLE(inst_id, scheduled_at DESC);
|
|
CREATE INDEX idx_timetable_type ON TB_WORK_TIMETABLE(work_type, result_status);
|
|
CREATE INDEX idx_timetable_sr ON TB_WORK_TIMETABLE(sr_id) WHERE sr_id IS NOT NULL;
|
|
```
|
|
|
|
#### 작업 유형 정의
|
|
|
|
| work_type | 설명 |
|
|
|-----------|------|
|
|
| `REGULAR_CHECK` | 정기점검 (월간·분기·반기·연간) |
|
|
| `PM` | 예방 정비 (Preventive Maintenance) |
|
|
| `SR` | SR 기반 작업 (요청 처리) |
|
|
| `ADHOC` | 수시점검 / 긴급 대응 |
|
|
| `DEPLOY` | 배포 작업 |
|
|
| `EMERGENCY` | 장애 대응 / 긴급 복구 |
|
|
|
|
---
|
|
|
|
## 8. 더미 데이터 (로컬 테스트용)
|
|
|
|
```sql
|
|
-- 관공서 기관
|
|
INSERT INTO TB_INST_META (inst_id, inst_name, pm_contact) VALUES
|
|
('MOF', '기획재정부', 'PM001'),
|
|
('MOIS', '행정안전부', 'PM002'),
|
|
('MSS', '중소벤처기업부', 'PM003');
|
|
|
|
-- 서버 노드
|
|
INSERT INTO TB_SERVER_INFO (server_id, inst_id, system_name, layer, ip_address, ssh_port, ftp_path, os_user) VALUES
|
|
('MOF-WAS-01', 'MOF', '예산시스템', 'WAS', '192.168.10.11', 22, '/app/mof/webapps/ROOT', 'mofadmin'),
|
|
('MOF-WAS-02', 'MOF', '예산시스템', 'WAS', '192.168.10.12', 22, '/app/mof/webapps/ROOT', 'mofadmin'),
|
|
('MOF-DB-01', 'MOF', '예산시스템', 'DB', '192.168.10.13', 5432, '/var/lib/postgresql', 'postgres');
|
|
|
|
-- 담당자 매핑
|
|
INSERT INTO TB_SYSTEM_OWNER (system_id, inst_id, owner_id, deputy_id, supervisor_id) VALUES
|
|
('MOF-WAS-01', 'MOF', 'EMP-0101', 'EMP-0102', 'EMP-0100'),
|
|
('MOF-DB-01', 'MOF', 'EMP-0201', NULL, 'EMP-0200');
|
|
```
|