26J30b5

Young-Kyoo Kim·2026년 6월 29일
"""
[신규 5단계] 생성된 최종 FinOps 산출물(Excel, PNG)을 사내 MinIO AIStor로 자동 업로드하는 엔진
실행: python upload_to_minio.py
"""

import os
import boto3
from pathlib import Path
from config import OUT_DIR

def upload_artifacts_to_minio():
    # ── 🌐 환경변수로부터 사내 MinIO AIStor 접속 정보 징수 ──
    minio_endpoint   = os.getenv("MINIO_ENDPOINT")     # 예: http://minio.internal.zone:9000
    minio_access_key = os.getenv("MINIO_ACCESS_KEY")
    minio_secret_key = os.getenv("MINIO_SECRET_KEY")
    bucket_name      = os.getenv("MINIO_BUCKET_NAME", "finops-reports")

    if not all([minio_endpoint, minio_access_key, minio_secret_key]):
        print("❌ [경고] MinIO 접속 환경변수가 누락되었습니다. 오브젝트 스토리지 업로드를 건너뜁니다.")
        return

    print(f"🔗 사내 MinIO AIStor 엔드포인트 연결 중... ({minio_endpoint})")
    
    # S3 호환 API 클라이언트 초기화
    s3_client = boto3.client(
        "s3",
        endpoint_url=minio_endpoint,
        aws_access_key_id=minio_access_key,
        aws_secret_access_key=minio_secret_key,
        config=boto3.session.Config(signature_version="s3v4") # MinIO 표준 서명 버퍼 고정
    )

    # 당일 날짜 폴더 구조 생성을 위한 접두사 (예: 20260630/)
    current_date_prefix = Path(OUT_DIR).parent.name # 파이프라인 일자 매핑용 추출
    
    # 📝 1. 마스터 엑셀 파일 업로드
    excel_file = OUT_DIR / "workload_analysis_master_fixed.xlsx"
    if excel_file.exists():
        object_name = f"excel/{excel_file.name}" # 버킷 내 저장될 가상 경로
        print(f"⏳ 엑셀 파일 업로드 중 -> Bucket: [{bucket_name}] | Path: {object_name}")
        s3_client.upload_file(str(excel_file), bucket_name, object_name)
        print("✅ [성공] 마스터 엑셀 파일 MinIO 이식 완료.")
    else:
        print("⚠️ 업로드할 최종 엑셀 파일이 존재하지 않습니다.")

    # 📊 2. 생성된 3대 마스터 차트 이미지 업로드
    plot_dir = OUT_DIR / "plots"
    if plot_dir.exists():
        print(f"⏳ 차트 이미지 파일 전송 스캔 시작...")
        for img_path in plot_dir.glob("*.png"):
            object_name = f"plots/{img_path.name}"
            s3_client.upload_file(str(img_path), bucket_name, object_name)
            print(f"  ->  🎨 이미지 이식 완료: {object_name}")
            
    print("\n🎉 === [오브젝트 스토리지 싱크 완료] 모든 FinOps 자산이 안전하게 중앙화되었습니다. ===")

if __name__ == "__main__":
    upload_artifacts_to_minio()

0개의 댓글