from flask import Blueprint, render_template, request, jsonify, flash, redirect, url_for from flask_login import login_required, current_user import logging import difflib from pathlib import Path from config import Config from backend.services.redfish_client import RedfishClient from backend.routes.xml import sanitize_preserve_unicode scp_bp = Blueprint("scp", __name__) logger = logging.getLogger(__name__) @scp_bp.route("/scp/diff", methods=["GET"]) @login_required def diff_scp(): """ 두 XML 파일의 차이점을 비교하여 보여줍니다. """ file1_name = request.args.get("file1") file2_name = request.args.get("file2") if not file1_name or not file2_name: flash("비교할 두 파일을 선택해주세요.", "warning") return redirect(url_for("xml.xml_management")) try: file1_path = Path(Config.XML_FOLDER) / sanitize_preserve_unicode(file1_name) file2_path = Path(Config.XML_FOLDER) / sanitize_preserve_unicode(file2_name) if not file1_path.exists() or not file2_path.exists(): flash("파일을 찾을 수 없습니다.", "danger") return redirect(url_for("xml.xml_management")) # 파일 내용 읽기 (LF로 통일) content1 = file1_path.read_text(encoding="utf-8").replace("\r\n", "\n").splitlines() content2 = file2_path.read_text(encoding="utf-8").replace("\r\n", "\n").splitlines() # Diff 생성 diff = difflib.unified_diff( content1, content2, fromfile=file1_name, tofile=file2_name, lineterm="" ) diff_content = "\n".join(diff) return render_template("scp_diff.html", file1=file1_name, file2=file2_name, diff_content=diff_content) except Exception as e: logger.error(f"Diff error: {e}") flash(f"비교 중 오류가 발생했습니다: {str(e)}", "danger") return redirect(url_for("xml.xml_management")) @scp_bp.route("/scp/export", methods=["POST"]) @login_required def export_scp(): """ iDRAC에서 설정을 내보내기 (Export) 네트워크 공유 설정이 필요합니다. """ data = request.form target_ip = data.get("target_ip") username = data.get("username") password = data.get("password") # Share Parameters share_ip = data.get("share_ip") share_name = data.get("share_name") share_user = data.get("share_user") share_pwd = data.get("share_pwd") filename = data.get("filename") if not all([target_ip, username, password, share_ip, share_name, filename]): flash("필수 정보가 누락되었습니다.", "warning") return redirect(url_for("xml.xml_management")) share_params = { "IPAddress": share_ip, "ShareName": share_name, "FileName": filename, "ShareType": "CIFS", # 기본값 CIFS "UserName": share_user, "Password": share_pwd } try: with RedfishClient(target_ip, username, password) as client: job_id = client.export_system_configuration(share_params) if job_id: flash(f"내보내기 작업이 시작되었습니다. Job ID: {job_id}", "success") else: flash("작업을 시작했으나 Job ID를 받지 못했습니다.", "warning") except Exception as e: logger.error(f"Export failed: {e}") flash(f"내보내기 실패: {str(e)}", "danger") return redirect(url_for("xml.xml_management")) @scp_bp.route("/scp/import", methods=["POST"]) @login_required def import_scp(): """ iDRAC로 설정 가져오기 (Import/Deploy) """ data = request.form target_ip = data.get("target_ip") username = data.get("username") password = data.get("password") # Share Parameters share_ip = data.get("share_ip") share_name = data.get("share_name") share_user = data.get("share_user") share_pwd = data.get("share_pwd") filename = data.get("filename") import_mode = data.get("import_mode", "Replace") if not all([target_ip, username, password, share_ip, share_name, filename]): flash("필수 정보가 누락되었습니다.", "warning") return redirect(url_for("xml.xml_management")) share_params = { "IPAddress": share_ip, "ShareName": share_name, "FileName": filename, "ShareType": "CIFS", "UserName": share_user, "Password": share_pwd } try: with RedfishClient(target_ip, username, password) as client: job_id = client.import_system_configuration(share_params, import_mode=import_mode) if job_id: flash(f"설정 적용(Import) 작업이 시작되었습니다. Job ID: {job_id}", "success") else: flash("작업을 시작했으나 Job ID를 받지 못했습니다.", "warning") except Exception as e: logger.error(f"Import failed: {e}") flash(f"설정 적용 실패: {str(e)}", "danger") return redirect(url_for("xml.xml_management"))