129 lines
5.6 KiB
Rust
129 lines
5.6 KiB
Rust
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(())
|
|
} |