Files
gyber/apps/rust_gyber/src/main.rs

129 lines
5.6 KiB
Rust
Raw Normal View History

2025-09-15 13:33:34 +09:00
use anyhow::{Context, Result};
use log::{error, info, warn};
use std::collections::HashMap;
// --- 애플리케이션 모듈 선언 ---
mod config_reader;
mod db; // 데이터베이스 관련 모듈 (connection, compare, sync 포함)
mod file; // 파일 처리 관련 모듈 (json_reader, decrypt 포함)
mod logger;
// --- 필요한 구조체 및 함수 임포트 ---
use config_reader::read_app_config;
use db::{
compare::{compare_data, ComparisonResult}, // 데이터 비교 함수 및 결과 구조체
connection::connect_db, // DB 연결 함수
sync::execute_sync, // DB 동기화 실행 함수
};
use file::{
decrypt::decrypt_db_config, // DB 설정 복호화 함수
json_reader::{read_and_process_json_files, ProcessedHwInfo}, // JSON 처리 함수 및 구조체
};
use logger::setup_logger; // 로거 설정 함수
// --- 애플리케이션 메인 진입점 ---
#[tokio::main]
async fn main() -> Result<()> {
// .env 파일 로드 (환경 변수 사용 위함, 예: 복호화 키)
dotenvy::dotenv().ok(); // 파일 없어도 오류 아님
// 1. 로거 초기화
setup_logger().context("로거 설정 실패")?;
info!("자원 관리 동기화 애플리케이션 시작...");
info!("환경 변수 로드 시도 완료."); // 실제 로드 여부는 dotenvy 결과 확인 필요
// 2. 애플리케이션 설정 파일 읽기
let config_path = "config/config.json"; // 설정 파일 경로
info!("설정 파일 읽기 시도: {}", config_path);
let app_config = read_app_config(config_path).context("애플리케이션 설정 읽기 실패")?;
info!("설정 로드 완료: JSON 경로='{}', DB 설정 파일='{}'", app_config.json_files_path, app_config.db_config_path);
// 3. DB 인증 정보 복호화
info!("DB 설정 파일 복호화 시도: {}", app_config.db_config_path);
let db_creds = decrypt_db_config(&app_config.db_config_path).context("DB 인증 정보 복호화 실패")?;
info!("DB 설정 복호화 완료."); // 성공 로그 (민감 정보 노출 주의)
// 4. 데이터베이스 연결 풀 생성
info!("데이터베이스 연결 시도: 호스트={}, DB={}", db_creds.host, db_creds.db);
let db_pool = connect_db(&db_creds).await.context("데이터베이스 연결 풀 생성 실패")?;
info!("데이터베이스 연결 풀 생성 완료.");
// 5. JSON 파일 읽기 및 처리
let processed_data: HashMap<String, Vec<ProcessedHwInfo>> =
match read_and_process_json_files(&app_config.json_files_path) {
Ok(data) => data,
Err(e) => {
// JSON 처리 실패 시 즉시 종료
error!("JSON 파일 처리 실패: {}", e);
return Err(e.context("JSON 파일 처리 중 치명적 오류 발생"));
}
};
// 처리할 데이터가 없는 경우 종료
if processed_data.is_empty() {
warn!("처리할 유효한 JSON 데이터 없음. 종료.");
return Ok(());
}
info!("총 {}개 호스트 데이터 처리 완료.", processed_data.len());
// 6. 데이터 비교 (JSON vs DB)
let comparison_results: HashMap<String, ComparisonResult> =
match compare_data(&db_pool, &processed_data).await {
Ok(results) => results,
Err(e) => {
// 데이터 비교 실패 시 즉시 종료
error!("데이터 비교 실패: {}", e);
return Err(e.context("데이터 비교 중 치명적 오류 발생"));
}
};
// 변경 사항 없는 경우 종료
if comparison_results.is_empty() {
info!("DB와 비교 결과, 변경 사항 없음. 종료.");
return Ok(());
}
info!("총 {}개 호스트 변경 사항 발견.", comparison_results.len());
// 7. DB 동기화 실행 (추가/할당, 할당 해제)
info!("DB 동기화 작업 시작...");
let mut success_count = 0;
let mut fail_count = 0;
let total_hosts_to_sync = comparison_results.len();
// 각 호스트별 변경 사항 DB에 적용
for (hostname, changes) in comparison_results {
info!("'{}' 호스트 DB 동기화 처리 중...", hostname);
match execute_sync(
&db_pool,
&hostname,
changes.adds, // 추가/할당 대상 전달
changes.deletes // 할당 해제 대상 전달
).await {
Ok(_) => {
// 성공 시 카운트 증가
success_count += 1;
info!("'{}' 호스트 DB 동기화 성공.", hostname);
}
Err(e) => {
// 실패 시 카운트 증가 및 에러 로그
fail_count += 1;
error!("'{}' 호스트 DB 동기화 에러: {}", hostname, e);
// 개별 호스트 실패 시 전체 프로세스를 중단할지, 아니면 계속 진행할지 결정
// 여기서는 계속 진행하고 마지막에 요약
}
}
}
// 8. 최종 결과 요약 로깅
info!("--- DB 동기화 작업 요약 ---");
info!("총 대상 호스트: {}", total_hosts_to_sync);
info!("성공 처리 호스트: {}", success_count);
info!("오류 발생 호스트: {}", fail_count);
if fail_count > 0 {
// 실패한 호스트가 있으면 에러 레벨 로그 추가
error!("일부 호스트 동기화 중 오류 발생. 상세 내용은 위 로그 확인 필요.");
}
info!("자원 관리 동기화 애플리케이션 정상 종료.");
Ok(())
}