223 lines
11 KiB
HTML
223 lines
11 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}XML 파일 관리 & 배포 - Dell Server Info{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/scp.css') }}">
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<h1 class="main-title">설정 파일 관리 (SCP)</h1>
|
|
<p class="subtitle">iDRAC 서버 설정(XML)을 내보내거나 가져오고, 버전을 비교할 수 있습니다.</p>
|
|
|
|
<div class="row">
|
|
<!-- 왼쪽: 파일 업로드 및 내보내기 -->
|
|
<div class="col-md-4">
|
|
<div class="card">
|
|
<div class="card-header-custom">
|
|
<span><i class="fas fa-cloud-upload-alt me-2"></i>파일 등록</span>
|
|
</div>
|
|
<div class="card-body">
|
|
<!-- 1. PC에서 업로드 -->
|
|
<h6 class="mb-3"><i class="fas fa-laptop me-2"></i>PC에서 업로드</h6>
|
|
<form action="{{ url_for('xml.upload_xml') }}" method="POST" enctype="multipart/form-data" class="mb-4">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
|
<div class="upload-section">
|
|
<div class="mb-2">
|
|
<div class="custom-file">
|
|
<input type="file" class="custom-file-input" id="xmlFile" name="xmlFile" accept=".xml"
|
|
onchange="updateFileName(this)">
|
|
<label class="custom-file-label" for="xmlFile" id="fileLabel">파일 선택</label>
|
|
</div>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary w-100">
|
|
<i class="fas fa-upload me-1"></i>업로드
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
<hr>
|
|
|
|
<!-- 2. iDRAC에서 내보내기 -->
|
|
<h6 class="mb-3"><i class="fas fa-server me-2"></i>iDRAC에서 추출 (Export)</h6>
|
|
<button type="button" class="btn btn-outline-primary w-100" data-bs-toggle="modal"
|
|
data-bs-target="#exportModal">
|
|
<i class="fas fa-download me-1"></i>설정 추출하기
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 오른쪽: 파일 목록 및 작업 -->
|
|
<div class="col-md-8">
|
|
<div class="card">
|
|
<div class="card-header-custom">
|
|
<span><i class="fas fa-list me-2"></i>파일 목록</span>
|
|
<button class="btn btn-light btn-sm text-primary" id="compareBtn"
|
|
data-url="{{ url_for('scp.diff_scp') }}" onclick="compareSelected()">
|
|
<i class="fas fa-exchange-alt me-1"></i>선택 비교
|
|
</button>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if xml_files %}
|
|
<div class="file-list">
|
|
{% for xml_file in xml_files %}
|
|
<div class="icon-badge-item">
|
|
<div class="icon-badge-left">
|
|
<input type="checkbox" class="select-checkbox file-selector" value="{{ xml_file }}">
|
|
<div class="file-icon-small">
|
|
<i class="fas fa-file-code"></i>
|
|
</div>
|
|
<div class="file-name-section">
|
|
<span class="file-name-badge" title="{{ xml_file }}">{{ xml_file }}</span>
|
|
<span class="badge-custom">XML</span>
|
|
</div>
|
|
</div>
|
|
<div class="action-buttons">
|
|
<!-- 배포 버튼 -->
|
|
<button type="button" class="btn btn-info btn-sm text-white"
|
|
onclick="openDeployModal('{{ xml_file }}')">
|
|
<i class="fas fa-plane-departure"></i> <span>배포</span>
|
|
</button>
|
|
<!-- 편집 버튼 -->
|
|
<a href="{{ url_for('xml.edit_xml', filename=xml_file) }}" class="btn btn-success btn-sm">
|
|
<i class="fas fa-edit"></i> <span>편집</span>
|
|
</a>
|
|
<!-- 삭제 버튼 -->
|
|
<form action="{{ url_for('xml.delete_xml', filename=xml_file) }}" method="POST"
|
|
style="display:inline;">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
|
<button type="submit" class="btn btn-danger btn-sm"
|
|
onclick="return confirm('정말 삭제하시겠습니까?')">
|
|
<i class="fas fa-trash"></i> <span>삭제</span>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<div class="empty-message">
|
|
<i class="fas fa-folder-open" style="font-size: 2rem; color: #ddd;"></i>
|
|
<p class="mt-2 mb-0">파일이 없습니다.</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Export Modal -->
|
|
<div class="modal fade" id="exportModal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form action="{{ url_for('scp.export_scp') }}" method="POST">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">iDRAC 설정 내보내기</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="alert alert-info py-2" style="font-size: 0.9rem;">
|
|
<i class="fas fa-info-circle me-1"></i> 네트워크 공유 폴더(CIFS)가 필요합니다.
|
|
</div>
|
|
|
|
<h6>대상 iDRAC</h6>
|
|
<div class="mb-2"><input type="text" class="form-control" name="target_ip" placeholder="iDRAC IP"
|
|
required></div>
|
|
<div class="row mb-3">
|
|
<div class="col"><input type="text" class="form-control" name="username" placeholder="User"
|
|
required></div>
|
|
<div class="col"><input type="password" class="form-control" name="password"
|
|
placeholder="Password" required></div>
|
|
</div>
|
|
|
|
<hr>
|
|
<h6>네트워크 공유 (저장소)</h6>
|
|
<div class="mb-2"><input type="text" class="form-control" name="share_ip"
|
|
placeholder="Share Server IP" required></div>
|
|
<div class="mb-2"><input type="text" class="form-control" name="share_name"
|
|
placeholder="Share Name (e.g. public)" required></div>
|
|
<div class="mb-2"><input type="text" class="form-control" name="filename"
|
|
placeholder="Save Filename (e.g. backup.xml)" required></div>
|
|
<div class="row">
|
|
<div class="col"><input type="text" class="form-control" name="share_user"
|
|
placeholder="Share User"></div>
|
|
<div class="col"><input type="password" class="form-control" name="share_pwd"
|
|
placeholder="Share Password"></div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">취소</button>
|
|
<button type="submit" class="btn btn-primary">내보내기 시작</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Deploy (Import) Modal -->
|
|
<div class="modal fade" id="deployModal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form action="{{ url_for('scp.import_scp') }}" method="POST">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">설정 배포 (Import)</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="alert alert-warning py-2" style="font-size: 0.9rem;">
|
|
<i class="fas fa-exclamation-triangle me-1"></i> 적용 후 서버가 재부팅될 수 있습니다.
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">배포할 파일</label>
|
|
<input type="text" class="form-control" id="deployFilename" name="filename" readonly>
|
|
</div>
|
|
|
|
<h6>대상 iDRAC</h6>
|
|
<div class="mb-2"><input type="text" class="form-control" name="target_ip" placeholder="iDRAC IP"
|
|
required></div>
|
|
<div class="row mb-3">
|
|
<div class="col"><input type="text" class="form-control" name="username" placeholder="User"
|
|
required></div>
|
|
<div class="col"><input type="password" class="form-control" name="password"
|
|
placeholder="Password" required></div>
|
|
</div>
|
|
|
|
<hr>
|
|
<h6>네트워크 공유 (소스 위치)</h6>
|
|
<div class="mb-2"><input type="text" class="form-control" name="share_ip"
|
|
placeholder="Share Server IP" required></div>
|
|
<div class="mb-2"><input type="text" class="form-control" name="share_name" placeholder="Share Name"
|
|
required></div>
|
|
<div class="row mb-3">
|
|
<div class="col"><input type="text" class="form-control" name="share_user"
|
|
placeholder="Share User"></div>
|
|
<div class="col"><input type="password" class="form-control" name="share_pwd"
|
|
placeholder="Share Password"></div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">적용 모드</label>
|
|
<select class="form-select" name="import_mode">
|
|
<option value="Replace">전체 교체 (Replace)</option>
|
|
<option value="Append">변경분만 적용 (Append)</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">취소</button>
|
|
<button type="submit" class="btn btn-danger">배포 시작</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script src="{{ url_for('static', filename='js/scp.js') }}"></script>
|
|
{% endblock %} |