update
This commit is contained in:
353
backend/services/dell_catalog_alternatives.py
Normal file
353
backend/services/dell_catalog_alternatives.py
Normal file
@@ -0,0 +1,353 @@
|
||||
"""
|
||||
Dell 펌웨어 카탈로그 대안 방법들
|
||||
backend/services/dell_catalog_alternatives.py
|
||||
|
||||
Dell의 공식 Catalog.xml이 차단된 경우 사용할 수 있는 대안들
|
||||
"""
|
||||
|
||||
import requests
|
||||
from typing import List, Dict, Optional
|
||||
from backend.models.firmware_version import FirmwareVersion, db
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class DellFirmwareCatalogAlternatives:
|
||||
"""Dell 펌웨어 정보를 가져오는 대안 방법들"""
|
||||
|
||||
def __init__(self):
|
||||
self.session = requests.Session()
|
||||
self.session.headers.update({
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
|
||||
})
|
||||
|
||||
# ========================================
|
||||
# 방법 1: Dell Support API (공식 API)
|
||||
# ========================================
|
||||
|
||||
def fetch_from_dell_support_api(self, model: str = "PowerEdge R750") -> List[Dict]:
|
||||
"""
|
||||
Dell Support API를 통한 펌웨어 정보 조회
|
||||
|
||||
Dell의 공식 Support API 엔드포인트:
|
||||
https://www.dell.com/support/home/api/
|
||||
|
||||
참고: API 키가 필요할 수 있음
|
||||
"""
|
||||
try:
|
||||
# Dell Support API 엔드포인트 (예시)
|
||||
# 실제 API는 Dell 개발자 포털에서 확인 필요
|
||||
url = f"https://www.dell.com/support/home/api/products/{model}/drivers"
|
||||
|
||||
response = self.session.get(url, timeout=30)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
return self._parse_support_api_response(data, model)
|
||||
else:
|
||||
print(f"Dell Support API 오류: {response.status_code}")
|
||||
return []
|
||||
|
||||
except Exception as e:
|
||||
print(f"Dell Support API 조회 실패: {str(e)}")
|
||||
return []
|
||||
|
||||
# ========================================
|
||||
# 방법 2: Dell TechDirect (파트너 전용)
|
||||
# ========================================
|
||||
|
||||
def fetch_from_techdirect(self, model: str = "PowerEdge R750") -> List[Dict]:
|
||||
"""
|
||||
Dell TechDirect API를 통한 펌웨어 정보 조회
|
||||
|
||||
TechDirect는 Dell 파트너용 플랫폼
|
||||
API 키 필요: https://techdirect.dell.com/
|
||||
"""
|
||||
# TechDirect API 구현
|
||||
# 실제 사용 시 API 키 필요
|
||||
pass
|
||||
|
||||
# ========================================
|
||||
# 방법 3: 로컬 카탈로그 파일 사용
|
||||
# ========================================
|
||||
|
||||
def load_from_local_catalog(self, catalog_path: str) -> List[Dict]:
|
||||
"""
|
||||
로컬에 저장된 Catalog.xml 파일 사용
|
||||
|
||||
사용법:
|
||||
1. Dell 공식 사이트에서 수동으로 Catalog.xml 다운로드
|
||||
2. 로컬에 저장
|
||||
3. 이 함수로 파싱
|
||||
|
||||
Args:
|
||||
catalog_path: 로컬 Catalog.xml 파일 경로
|
||||
"""
|
||||
try:
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
with open(catalog_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
root = ET.fromstring(content)
|
||||
return self._parse_catalog_xml(root)
|
||||
|
||||
except Exception as e:
|
||||
print(f"로컬 카탈로그 파일 로드 실패: {str(e)}")
|
||||
return []
|
||||
|
||||
# ========================================
|
||||
# 방법 4: iDRAC에서 직접 조회
|
||||
# ========================================
|
||||
|
||||
def fetch_from_idrac(self, idrac_ip: str, username: str, password: str) -> List[Dict]:
|
||||
"""
|
||||
iDRAC Redfish API를 통해 사용 가능한 업데이트 조회
|
||||
|
||||
iDRAC는 Dell Update Service를 통해 사용 가능한 업데이트를 확인할 수 있음
|
||||
|
||||
장점:
|
||||
- 실제 서버에 맞는 정확한 펌웨어 정보
|
||||
- 외부 카탈로그 불필요
|
||||
|
||||
단점:
|
||||
- 각 서버마다 조회 필요
|
||||
- 네트워크 연결 필요
|
||||
"""
|
||||
try:
|
||||
from backend.services.idrac_redfish_client import DellRedfishClient
|
||||
|
||||
client = DellRedfishClient(idrac_ip, username, password)
|
||||
|
||||
# UpdateService에서 사용 가능한 업데이트 조회
|
||||
url = f"https://{idrac_ip}/redfish/v1/UpdateService"
|
||||
response = client.session.get(url, timeout=30)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
# UpdateService의 Actions 확인
|
||||
# SimpleUpdate 또는 CheckForUpdate 액션 사용
|
||||
return self._parse_idrac_updates(data)
|
||||
|
||||
return []
|
||||
|
||||
except Exception as e:
|
||||
print(f"iDRAC 업데이트 조회 실패: {str(e)}")
|
||||
return []
|
||||
|
||||
# ========================================
|
||||
# 방법 5: 수동 입력 (가장 간단하고 확실)
|
||||
# ========================================
|
||||
|
||||
def create_manual_catalog(self) -> List[Dict]:
|
||||
"""
|
||||
수동으로 작성한 펌웨어 버전 정보
|
||||
|
||||
Dell 공식 사이트에서 확인한 최신 버전을 수동으로 입력
|
||||
https://www.dell.com/support/
|
||||
|
||||
장점:
|
||||
- 가장 확실하고 안정적
|
||||
- 외부 의존성 없음
|
||||
- 검증된 버전만 사용
|
||||
|
||||
단점:
|
||||
- 수동 업데이트 필요
|
||||
"""
|
||||
manual_catalog = [
|
||||
{
|
||||
'component_name': 'BIOS',
|
||||
'latest_version': '2.15.2',
|
||||
'server_model': 'PowerEdge R750',
|
||||
'vendor': 'Dell',
|
||||
'release_date': '2024-03-15',
|
||||
'download_url': 'https://www.dell.com/support/home/drivers/driversdetails?driverid=...',
|
||||
'notes': 'PowerEdge R750 BIOS - 2024년 3월 릴리즈',
|
||||
'is_critical': False
|
||||
},
|
||||
{
|
||||
'component_name': 'iDRAC',
|
||||
'latest_version': '7.00.00.00',
|
||||
'server_model': None, # 모든 모델
|
||||
'vendor': 'Dell',
|
||||
'release_date': '2024-02-20',
|
||||
'download_url': 'https://www.dell.com/support/home/drivers/driversdetails?driverid=...',
|
||||
'notes': 'iDRAC9 최신 펌웨어 (14G/15G/16G 공용)',
|
||||
'is_critical': True
|
||||
},
|
||||
{
|
||||
'component_name': 'PERC H755',
|
||||
'latest_version': '25.5.9.0001',
|
||||
'server_model': 'PowerEdge R750',
|
||||
'vendor': 'Dell',
|
||||
'release_date': '2024-01-10',
|
||||
'notes': 'PERC H755 RAID 컨트롤러',
|
||||
'is_critical': False
|
||||
},
|
||||
# 더 많은 컴포넌트 추가...
|
||||
]
|
||||
|
||||
return manual_catalog
|
||||
|
||||
# ========================================
|
||||
# 방법 6: Dell Repository Manager (DRM)
|
||||
# ========================================
|
||||
|
||||
def fetch_from_drm_export(self, drm_export_path: str) -> List[Dict]:
|
||||
"""
|
||||
Dell Repository Manager (DRM)에서 내보낸 데이터 사용
|
||||
|
||||
DRM은 Dell의 공식 펌웨어 관리 도구
|
||||
https://www.dell.com/support/kbdoc/en-us/000177083/
|
||||
|
||||
사용법:
|
||||
1. DRM 설치 및 실행
|
||||
2. 필요한 서버 모델 선택
|
||||
3. 카탈로그 내보내기
|
||||
4. 내보낸 파일을 이 함수로 파싱
|
||||
"""
|
||||
try:
|
||||
# DRM 내보내기 파일 파싱 로직
|
||||
# XML 또는 CSV 형식일 수 있음
|
||||
pass
|
||||
except Exception as e:
|
||||
print(f"DRM 내보내기 파일 로드 실패: {str(e)}")
|
||||
return []
|
||||
|
||||
# ========================================
|
||||
# 헬퍼 함수들
|
||||
# ========================================
|
||||
|
||||
def _parse_support_api_response(self, data: Dict, model: str) -> List[Dict]:
|
||||
"""Dell Support API 응답 파싱"""
|
||||
# API 응답 구조에 따라 구현
|
||||
return []
|
||||
|
||||
def _parse_catalog_xml(self, root) -> List[Dict]:
|
||||
"""Catalog.xml 파싱"""
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
firmware_list = []
|
||||
|
||||
for pkg in root.findall(".//SoftwareComponent"):
|
||||
name = pkg.findtext("Name")
|
||||
version = pkg.findtext("Version")
|
||||
release_date = pkg.findtext("ReleaseDate")
|
||||
path = pkg.findtext("path")
|
||||
|
||||
if name and version:
|
||||
firmware_list.append({
|
||||
'component_name': name,
|
||||
'latest_version': version,
|
||||
'release_date': release_date,
|
||||
'download_url': f"https://downloads.dell.com/{path}" if path else None,
|
||||
'vendor': 'Dell'
|
||||
})
|
||||
|
||||
return firmware_list
|
||||
|
||||
def _parse_idrac_updates(self, data: Dict) -> List[Dict]:
|
||||
"""iDRAC UpdateService 응답 파싱"""
|
||||
# UpdateService 데이터 파싱
|
||||
return []
|
||||
|
||||
# ========================================
|
||||
# DB에 저장
|
||||
# ========================================
|
||||
|
||||
def save_to_database(self, firmware_list: List[Dict]) -> int:
|
||||
"""
|
||||
펌웨어 목록을 데이터베이스에 저장
|
||||
|
||||
Returns:
|
||||
저장된 항목 수
|
||||
"""
|
||||
count = 0
|
||||
|
||||
for fw in firmware_list:
|
||||
# 중복 확인
|
||||
existing = FirmwareVersion.query.filter_by(
|
||||
component_name=fw.get('component_name'),
|
||||
latest_version=fw.get('latest_version'),
|
||||
server_model=fw.get('server_model')
|
||||
).first()
|
||||
|
||||
if not existing:
|
||||
version = FirmwareVersion(
|
||||
component_name=fw.get('component_name'),
|
||||
latest_version=fw.get('latest_version'),
|
||||
server_model=fw.get('server_model'),
|
||||
vendor=fw.get('vendor', 'Dell'),
|
||||
release_date=fw.get('release_date'),
|
||||
download_url=fw.get('download_url'),
|
||||
notes=fw.get('notes'),
|
||||
is_critical=fw.get('is_critical', False)
|
||||
)
|
||||
db.session.add(version)
|
||||
count += 1
|
||||
|
||||
db.session.commit()
|
||||
return count
|
||||
|
||||
|
||||
# ========================================
|
||||
# 사용 예시
|
||||
# ========================================
|
||||
|
||||
def sync_firmware_alternative(method: str = 'manual', **kwargs) -> Dict:
|
||||
"""
|
||||
대안 방법으로 펌웨어 정보 동기화
|
||||
|
||||
Args:
|
||||
method: 'manual', 'local_catalog', 'idrac', 'support_api' 중 선택
|
||||
**kwargs: 각 방법에 필요한 추가 인자
|
||||
|
||||
Returns:
|
||||
{'success': bool, 'count': int, 'message': str}
|
||||
"""
|
||||
catalog = DellFirmwareCatalogAlternatives()
|
||||
firmware_list = []
|
||||
|
||||
try:
|
||||
if method == 'manual':
|
||||
# 가장 권장: 수동으로 작성한 카탈로그
|
||||
firmware_list = catalog.create_manual_catalog()
|
||||
|
||||
elif method == 'local_catalog':
|
||||
# 로컬 Catalog.xml 파일 사용
|
||||
catalog_path = kwargs.get('catalog_path')
|
||||
if not catalog_path:
|
||||
return {'success': False, 'count': 0, 'message': 'catalog_path 필요'}
|
||||
firmware_list = catalog.load_from_local_catalog(catalog_path)
|
||||
|
||||
elif method == 'idrac':
|
||||
# iDRAC에서 직접 조회
|
||||
idrac_ip = kwargs.get('idrac_ip')
|
||||
username = kwargs.get('username')
|
||||
password = kwargs.get('password')
|
||||
if not all([idrac_ip, username, password]):
|
||||
return {'success': False, 'count': 0, 'message': 'iDRAC 정보 필요'}
|
||||
firmware_list = catalog.fetch_from_idrac(idrac_ip, username, password)
|
||||
|
||||
elif method == 'support_api':
|
||||
# Dell Support API 사용
|
||||
model = kwargs.get('model', 'PowerEdge R750')
|
||||
firmware_list = catalog.fetch_from_dell_support_api(model)
|
||||
|
||||
else:
|
||||
return {'success': False, 'count': 0, 'message': f'알 수 없는 방법: {method}'}
|
||||
|
||||
# DB에 저장
|
||||
count = catalog.save_to_database(firmware_list)
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'count': count,
|
||||
'message': f'{count}개 펌웨어 정보 동기화 완료'
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
return {
|
||||
'success': False,
|
||||
'count': 0,
|
||||
'message': f'오류: {str(e)}'
|
||||
}
|
||||
Reference in New Issue
Block a user