179 lines
6.0 KiB
Python
179 lines
6.0 KiB
Python
import requests
|
|
from xml.etree import ElementTree as ET
|
|
from backend.models.firmware_version import FirmwareVersion, db
|
|
from datetime import datetime
|
|
|
|
|
|
def get_manual_firmware_catalog(model="PowerEdge R750"):
|
|
"""
|
|
수동으로 작성한 펌웨어 카탈로그
|
|
|
|
Dell 공식 사이트에서 확인한 최신 버전 정보
|
|
https://www.dell.com/support/
|
|
|
|
Dell Catalog.xml이 차단된 경우 이 데이터 사용
|
|
"""
|
|
# 2024년 11월 기준 최신 버전 (정기적으로 업데이트 필요)
|
|
catalog = {
|
|
"PowerEdge R750": [
|
|
{
|
|
'component_name': 'BIOS',
|
|
'latest_version': '2.15.2',
|
|
'release_date': '2024-03-15',
|
|
'notes': 'PowerEdge R750 BIOS - 보안 업데이트 포함',
|
|
'is_critical': False
|
|
},
|
|
{
|
|
'component_name': 'iDRAC',
|
|
'latest_version': '7.00.00.00',
|
|
'release_date': '2024-02-20',
|
|
'notes': 'iDRAC9 최신 펌웨어',
|
|
'is_critical': True
|
|
},
|
|
{
|
|
'component_name': 'PERC H755',
|
|
'latest_version': '25.5.9.0001',
|
|
'release_date': '2024-01-10',
|
|
'notes': 'PERC H755 RAID 컨트롤러',
|
|
'is_critical': False
|
|
},
|
|
{
|
|
'component_name': 'CPLD',
|
|
'latest_version': '1.0.6',
|
|
'release_date': '2023-12-15',
|
|
'notes': '시스템 보드 CPLD',
|
|
'is_critical': False
|
|
},
|
|
],
|
|
"PowerEdge R640": [
|
|
{
|
|
'component_name': 'BIOS',
|
|
'latest_version': '2.19.2',
|
|
'release_date': '2024-02-01',
|
|
'notes': 'PowerEdge R640 BIOS',
|
|
'is_critical': False
|
|
},
|
|
{
|
|
'component_name': 'iDRAC',
|
|
'latest_version': '7.00.00.00',
|
|
'release_date': '2024-02-20',
|
|
'notes': 'iDRAC9 최신 펌웨어',
|
|
'is_critical': True
|
|
},
|
|
]
|
|
}
|
|
|
|
return catalog.get(model, [])
|
|
|
|
|
|
def sync_dell_catalog(model="PowerEdge R750"):
|
|
"""
|
|
Dell 펌웨어 정보 동기화
|
|
|
|
1차: Dell 공식 Catalog.xml 시도
|
|
2차: 수동 카탈로그 사용 (Fallback)
|
|
"""
|
|
count = 0
|
|
|
|
# 1차 시도: Dell 공식 Catalog.xml
|
|
try:
|
|
url = "https://downloads.dell.com/catalog/Catalog.xml"
|
|
print(f"[INFO] Dell Catalog 다운로드 시도... ({url})")
|
|
|
|
response = requests.get(url, timeout=30)
|
|
response.raise_for_status()
|
|
|
|
root = ET.fromstring(response.content)
|
|
|
|
for pkg in root.findall(".//SoftwareComponent"):
|
|
# 이 컴포넌트가 지정된 모델에 해당하는지 확인
|
|
supported = [
|
|
sys.text.strip()
|
|
for sys in pkg.findall(".//SupportedSystems/Brand/Model/Display")
|
|
if sys.text
|
|
]
|
|
if model not in supported:
|
|
continue
|
|
|
|
name = pkg.findtext("Name")
|
|
version = pkg.findtext("Version")
|
|
release_date = pkg.findtext("ReleaseDate")
|
|
path = pkg.findtext("path")
|
|
vendor = "Dell"
|
|
|
|
if not name or not version:
|
|
continue
|
|
|
|
# 중복 방지
|
|
existing = FirmwareVersion.query.filter_by(
|
|
component_name=name,
|
|
latest_version=version,
|
|
server_model=model
|
|
).first()
|
|
|
|
if not existing:
|
|
db.session.add(
|
|
FirmwareVersion(
|
|
component_name=name,
|
|
latest_version=version,
|
|
release_date=release_date,
|
|
vendor=vendor,
|
|
server_model=model,
|
|
download_url=f"https://downloads.dell.com/{path}",
|
|
)
|
|
)
|
|
count += 1
|
|
|
|
db.session.commit()
|
|
print(f"✓ {model} 관련 펌웨어 {count}개 동기화 완료 (Dell Catalog)")
|
|
return count
|
|
|
|
except requests.exceptions.HTTPError as e:
|
|
if e.response.status_code == 404:
|
|
print(f"[경고] Dell Catalog.xml 접근 불가 (404). 수동 카탈로그 사용...")
|
|
else:
|
|
print(f"[경고] Dell Catalog 다운로드 실패: {e}. 수동 카탈로그 사용...")
|
|
except Exception as e:
|
|
print(f"[경고] Dell Catalog 처리 중 오류: {e}. 수동 카탈로그 사용...")
|
|
|
|
# 2차 시도: 수동 카탈로그 사용
|
|
try:
|
|
print(f"[INFO] 수동 카탈로그에서 {model} 펌웨어 정보 로드 중...")
|
|
manual_catalog = get_manual_firmware_catalog(model)
|
|
|
|
if not manual_catalog:
|
|
print(f"[경고] {model}에 대한 수동 카탈로그 데이터가 없습니다")
|
|
return 0
|
|
|
|
for fw in manual_catalog:
|
|
# 중복 방지
|
|
existing = FirmwareVersion.query.filter_by(
|
|
component_name=fw['component_name'],
|
|
latest_version=fw['latest_version'],
|
|
server_model=model
|
|
).first()
|
|
|
|
if not existing:
|
|
db.session.add(
|
|
FirmwareVersion(
|
|
component_name=fw['component_name'],
|
|
latest_version=fw['latest_version'],
|
|
release_date=fw.get('release_date'),
|
|
vendor='Dell',
|
|
server_model=model,
|
|
notes=fw.get('notes'),
|
|
is_critical=fw.get('is_critical', False)
|
|
)
|
|
)
|
|
count += 1
|
|
|
|
db.session.commit()
|
|
print(f"✓ {model} 관련 펌웨어 {count}개 동기화 완료 (수동 카탈로그)")
|
|
return count
|
|
|
|
except Exception as e:
|
|
print(f"[오류] 수동 카탈로그 처리 실패: {e}")
|
|
db.session.rollback()
|
|
return 0
|
|
|