Initial project upload
This commit is contained in:
@@ -0,0 +1,512 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<style>
|
||||
/* 모달이 Navbar 위에 오도록 z-index 조정 */
|
||||
.modal {
|
||||
z-index: 1060 !important;
|
||||
}
|
||||
|
||||
.modal-backdrop {
|
||||
z-index: 1050 !important;
|
||||
}
|
||||
|
||||
/* 모달 헤더가 항상 잘 보이도록 배경색 및 위치 조정 */
|
||||
.modal-header {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
padding: 1rem 1rem;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1070;
|
||||
}
|
||||
|
||||
/* 모달이 너무 위로 붙지 않게 여백 추가 */
|
||||
.modal-dialog {
|
||||
margin-top: 5rem;
|
||||
}
|
||||
|
||||
/* ===== 탭 가시성 개선 ===== */
|
||||
/* Pills 스타일 탭 버튼 */
|
||||
.nav-pills .nav-link {
|
||||
color: #495057 !important;
|
||||
background-color: #e9ecef !important;
|
||||
border: 1px solid #ced4da !important;
|
||||
margin-right: 0.25rem;
|
||||
font-weight: 500;
|
||||
padding: 0.5rem 1rem;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link:hover {
|
||||
background-color: #dee2e6 !important;
|
||||
border-color: #adb5bd !important;
|
||||
color: #212529 !important;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link.active {
|
||||
background-color: #0d6efd !important;
|
||||
border-color: #0d6efd !important;
|
||||
color: #ffffff !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Select 드롭다운 가시성 개선 */
|
||||
.form-select {
|
||||
border: 2px solid #ced4da !important;
|
||||
font-weight: 500;
|
||||
color: #212529 !important;
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
|
||||
.form-select:focus {
|
||||
border-color: #0d6efd !important;
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25) !important;
|
||||
}
|
||||
|
||||
.form-select option {
|
||||
color: #212529 !important;
|
||||
background-color: #ffffff !important;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
/* 탭 컨테이너 배경 */
|
||||
.nav-pills-container {
|
||||
background-color: #f8f9fa;
|
||||
padding: 0.75rem;
|
||||
border-radius: 0.375rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
</style>
|
||||
<div class="container-fluid py-4">
|
||||
|
||||
<!-- 헤더 -->
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<h2 class="fw-bold mb-1">
|
||||
<i class="bi bi-clipboard-data text-primary me-2"></i>
|
||||
BIOS Baseline 비교
|
||||
</h2>
|
||||
<p class="text-muted mb-0">납품 전 서버의 BIOS 설정을 표준 설정과 비교합니다</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 메인 작업 영역 -->
|
||||
<div class="row g-4 mb-4">
|
||||
<!-- 왼쪽: IP 입력 및 설정 -->
|
||||
<div class="col-lg-5">
|
||||
<div class="card border shadow-sm h-100">
|
||||
<div class="card-header bg-light border-0 py-2">
|
||||
<h6 class="mb-0">
|
||||
<i class="bi bi-search me-2"></i>
|
||||
비교 설정
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body p-4 d-flex flex-column">
|
||||
|
||||
<!-- Baseline 선택 -->
|
||||
<div class="mb-3">
|
||||
<label for="baseline-select" class="form-label">Baseline 선택</label>
|
||||
<select id="baseline-select" class="form-select">
|
||||
<option value="">Baseline을 선택하세요</option>
|
||||
</select>
|
||||
<button class="btn btn-sm btn-outline-primary mt-2 w-100" onclick="showBaselineManageModal()">
|
||||
<i class="bi bi-plus-circle me-1"></i> 새 Baseline 생성
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- IP 주소 입력 -->
|
||||
<div class="mb-3 flex-grow-1 d-flex flex-column">
|
||||
<label for="ip-addresses"
|
||||
class="form-label w-100 d-flex justify-content-between align-items-end mb-2">
|
||||
<span class="mb-1">
|
||||
서버 IP 주소
|
||||
<span class="badge bg-secondary ms-1" id="ip-count">0</span>
|
||||
</span>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary px-2 py-1"
|
||||
onclick="clearIPs()" title="입력 내용 지우기" style="font-size: 0.75rem;">
|
||||
<i class="bi bi-trash me-1"></i>지우기
|
||||
</button>
|
||||
</label>
|
||||
<textarea id="ip-addresses" class="form-control font-monospace flex-grow-1"
|
||||
placeholder="예: 10.10.0.1 10.10.0.2 10.10.0.3" style="resize: none;"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- 인증 정보 -->
|
||||
<div class="row g-2 mb-3">
|
||||
<div class="col-6">
|
||||
<input type="text" id="username" class="form-control" value="root" placeholder="Username">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="password" id="password" class="form-control" placeholder="Password">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 비교 시작 버튼 -->
|
||||
<button onclick="startComparison()" class="btn btn-primary w-100 py-2">
|
||||
<i class="bi bi-arrows-angle-contract me-1"></i> 비교 시작
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 오른쪽: 결과 요약 -->
|
||||
<div class="col-lg-7">
|
||||
<div class="card border shadow-sm h-100">
|
||||
<div class="card-header bg-light border-0 py-2">
|
||||
<h6 class="mb-0">
|
||||
<i class="bi bi-bar-chart me-2"></i>
|
||||
비교 결과 요약
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body p-4" id="summary-section">
|
||||
<div class="text-center text-muted py-5">
|
||||
<i class="bi bi-info-circle fs-1 mb-3"></i>
|
||||
<p class="mb-0">비교를 시작하면 결과가 여기에 표시됩니다</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 진행률 -->
|
||||
<div class="row mb-4" id="progress-section" style="display: none;">
|
||||
<div class="col">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body p-3">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<i class="bi bi-activity text-primary me-2"></i>
|
||||
<span class="fw-semibold">처리 진행률</span>
|
||||
</div>
|
||||
<div class="progress" style="height: 25px;">
|
||||
<div id="progress-bar"
|
||||
class="progress-bar progress-bar-striped progress-bar-animated bg-success"
|
||||
role="progressbar" style="width: 0%">
|
||||
<span class="fw-semibold">0%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 상세 비교 결과 -->
|
||||
<div class="row" id="results-section" style="display: none;">
|
||||
<div class="col">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-light border-0 py-2 d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0">
|
||||
<i class="bi bi-list-check me-2"></i>
|
||||
상세 비교 결과
|
||||
</h6>
|
||||
<div>
|
||||
<button class="btn btn-sm btn-outline-secondary" onclick="toggleDiffOnly()" id="diff-only-btn">
|
||||
<i class="bi bi-funnel me-1"></i> 차이점만 보기
|
||||
</button>
|
||||
<button class="btn btn-sm btn-outline-primary" onclick="downloadResults()">
|
||||
<i class="bi bi-download me-1"></i> Excel 다운로드
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-4" id="results-container">
|
||||
<!-- 서버별 결과가 여기에 표시됨 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Baseline 관리 모달 -->
|
||||
<div class="modal fade" id="baseline-manage-modal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">
|
||||
<i class="bi bi-clipboard-data me-2"></i>
|
||||
Baseline 관리
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<!-- 탭 -->
|
||||
<div class="nav-pills-container">
|
||||
<ul class="nav nav-pills mb-0" role="tablist">
|
||||
<li class="nav-item">
|
||||
<button class="nav-link active" data-bs-toggle="pill" data-bs-target="#create-tab">
|
||||
새로 생성
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="nav-link" data-bs-toggle="pill" data-bs-target="#list-tab">
|
||||
목록 관리
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="tab-content">
|
||||
<!-- 생성 탭 -->
|
||||
<div class="tab-pane fade show active" id="create-tab">
|
||||
<form id="create-baseline-form">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">서버 IP 주소 *</label>
|
||||
<input type="text" class="form-control" id="create-ip" placeholder="10.10.0.1" required>
|
||||
</div>
|
||||
<div class="row g-2 mb-3">
|
||||
<div class="col-6">
|
||||
<label class="form-label">Username</label>
|
||||
<input type="text" class="form-control" id="create-username" value="root">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label">Password *</label>
|
||||
<input type="password" class="form-control" id="create-password" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Baseline 이름 *</label>
|
||||
<input type="text" class="form-control" id="create-name"
|
||||
placeholder="R6615_GPU_Standard_2024" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">서버 타입</label>
|
||||
<input type="text" class="form-control" id="create-type" placeholder="GPU Server">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">설명</label>
|
||||
<textarea class="form-control" id="create-description" rows="2"
|
||||
placeholder="표준 GPU 서버 설정"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100">
|
||||
<i class="bi bi-download me-1"></i> Redfish로 가져와서 생성
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- 목록 탭 -->
|
||||
<div class="tab-pane fade" id="list-tab">
|
||||
<div id="baseline-list">
|
||||
<div class="text-center text-muted py-4">
|
||||
<i class="bi bi-hourglass-split"></i> 로딩 중...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Baseline 상세 편집 모달 -->
|
||||
<div class="modal fade" id="edit-baseline-modal" tabindex="-1" aria-hidden="true" data-bs-backdrop="static">
|
||||
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">
|
||||
<i class="bi bi-pencil-square me-2"></i>
|
||||
Baseline 상세 편집
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body bg-light">
|
||||
<div class="row g-3">
|
||||
<!-- 왼쪽: 메타데이터 편집 -->
|
||||
<div class="col-lg-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-header bg-white fw-bold">기본 정보</div>
|
||||
<div class="card-body">
|
||||
<form id="edit-baseline-meta-form">
|
||||
<input type="hidden" id="edit-id">
|
||||
<div class="mb-3">
|
||||
<label class="form-label small text-muted">Baseline 이름</label>
|
||||
<input type="text" class="form-control" id="edit-name" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label small text-muted">서버 모델</label>
|
||||
<input type="text" class="form-control bg-light" id="edit-model" readonly>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label small text-muted">서버 타입</label>
|
||||
<input type="text" class="form-control" id="edit-type">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label small text-muted">설명</label>
|
||||
<textarea class="form-control" id="edit-description" rows="4"></textarea>
|
||||
</div>
|
||||
<div class="text-muted small">
|
||||
<p class="mb-1"><i class="bi bi-calendar me-1"></i>생성일: <span
|
||||
id="edit-created-at">-</span></p>
|
||||
<p class="mb-1"><i class="bi bi-cpu me-1"></i>원본 IP: <span
|
||||
id="edit-source-ip">-</span></p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 오른쪽: BIOS 설정 편집 -->
|
||||
<!-- 오른쪽: 상세 설정 편집 -->
|
||||
<div class="col-lg-8">
|
||||
<div class="card h-100 border shadow-sm">
|
||||
<div class="card-body p-3">
|
||||
<!-- 탭 메뉴 -->
|
||||
<div class="nav-pills-container">
|
||||
<ul class="nav nav-pills mb-0" id="edit-tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="tab-edit-bios" data-bs-toggle="pill"
|
||||
data-bs-target="#content-edit-bios" type="button">BIOS</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="tab-edit-idrac" data-bs-toggle="pill"
|
||||
data-bs-target="#content-edit-idrac" type="button">iDRAC</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="tab-edit-raid" data-bs-toggle="pill"
|
||||
data-bs-target="#content-edit-raid" type="button">RAID</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="tab-edit-nic" data-bs-toggle="pill"
|
||||
data-bs-target="#content-edit-nic" type="button">NIC</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="tab-edit-boot" data-bs-toggle="pill"
|
||||
data-bs-target="#content-edit-boot" type="button">Boot</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="tab-edit-firmware" data-bs-toggle="pill"
|
||||
data-bs-target="#content-edit-firmware" type="button">Firmware</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="tab-content h-100">
|
||||
|
||||
<!-- BIOS 탭 -->
|
||||
<div class="tab-pane fade show active h-100" id="content-edit-bios">
|
||||
<div
|
||||
class="d-flex justify-content-between align-items-center p-2 border-bottom bg-light">
|
||||
<span class="small text-muted fw-bold ms-2">항목 수: <span
|
||||
id="edit-bios-count">0</span></span>
|
||||
<button class="btn btn-sm btn-outline-primary bg-white"
|
||||
onclick="addSettingRow('bios')">
|
||||
<i class="bi bi-plus-lg"></i> 항목 추가
|
||||
</button>
|
||||
</div>
|
||||
<div class="table-responsive" style="max-height: 450px;">
|
||||
<table class="table table-hover mb-0" id="table-edit-bios">
|
||||
<thead class="table-light sticky-top">
|
||||
<tr>
|
||||
<th style="width: 40%;">설정 항목 (Key)</th>
|
||||
<th style="width: 40%;">설정값 (Value)</th>
|
||||
<th style="width: 20%;">작업</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><!-- JS 채움 --></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- iDRAC 탭 -->
|
||||
<div class="tab-pane fade h-100" id="content-edit-idrac">
|
||||
<div
|
||||
class="d-flex justify-content-between align-items-center p-2 border-bottom bg-light">
|
||||
<span class="small text-muted fw-bold ms-2">항목 수: <span
|
||||
id="edit-idrac-count">0</span></span>
|
||||
<button class="btn btn-sm btn-outline-primary bg-white"
|
||||
onclick="addSettingRow('idrac')">
|
||||
<i class="bi bi-plus-lg"></i> 항목 추가
|
||||
</button>
|
||||
</div>
|
||||
<div class="table-responsive" style="max-height: 450px;">
|
||||
<table class="table table-hover mb-0" id="table-edit-idrac">
|
||||
<thead class="table-light sticky-top">
|
||||
<tr>
|
||||
<th style="width: 40%;">설정 항목 (Key)</th>
|
||||
<th style="width: 40%;">설정값 (Value)</th>
|
||||
<th style="width: 20%;">작업</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><!-- JS 채움 --></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RAID 탭 -->
|
||||
<div class="tab-pane fade h-100 p-3" id="content-edit-raid">
|
||||
<div class="alert alert-info py-2 small">
|
||||
<i class="bi bi-info-circle me-1"></i>
|
||||
RAID 구성은 복잡하므로 현재 JSON 직접 편집만 지원합니다. (Read-Only 권장)
|
||||
</div>
|
||||
<textarea class="form-control font-monospace small" id="json-edit-raid"
|
||||
rows="15" style="height: 400px;"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- NIC 탭 -->
|
||||
<div class="tab-pane fade h-100 p-3" id="content-edit-nic">
|
||||
<div class="alert alert-info py-2 small">
|
||||
<i class="bi bi-info-circle me-1"></i>
|
||||
NIC 설정은 JSON 형식으로 편집합니다.
|
||||
</div>
|
||||
<textarea class="form-control font-monospace small" id="json-edit-nic" rows="15"
|
||||
style="height: 400px;"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Boot 탭 -->
|
||||
<div class="tab-pane fade h-100 p-3" id="content-edit-boot">
|
||||
<div class="alert alert-info py-2 small">
|
||||
<i class="bi bi-info-circle me-1"></i>
|
||||
부팅 순서 및 설정을 JSON 형식으로 편집합니다.
|
||||
</div>
|
||||
<textarea class="form-control font-monospace small" id="json-edit-boot"
|
||||
rows="15" style="height: 400px;"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Firmware 탭 -->
|
||||
<div class="tab-pane fade h-100" id="content-edit-firmware">
|
||||
<div
|
||||
class="d-flex justify-content-between align-items-center p-2 border-bottom bg-light">
|
||||
<span class="small text-muted fw-bold ms-2">항목 수: <span
|
||||
id="edit-firmware-count">0</span></span>
|
||||
<button class="btn btn-sm btn-outline-primary bg-white"
|
||||
onclick="addSettingRow('firmware')">
|
||||
<i class="bi bi-plus-lg"></i> 항목 추가
|
||||
</button>
|
||||
</div>
|
||||
<div class="table-responsive" style="max-height: 450px;">
|
||||
<table class="table table-hover mb-0" id="table-edit-firmware">
|
||||
<thead class="table-light sticky-top">
|
||||
<tr>
|
||||
<th style="width: 40%;">컴포넌트</th>
|
||||
<th style="width: 40%;">버전</th>
|
||||
<th style="width: 20%;">작업</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><!-- JS 채움 --></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">취소</button>
|
||||
<button type="button" class="btn btn-primary" onclick="saveBaselineChanges()">
|
||||
<i class="bi bi-save me-1"></i> 변경사항 저장
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src="{{ url_for('static', filename='js/bios_baseline.js') }}?v={{ range(1, 100000) | random }}"></script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user