This commit is contained in:
unknown
2026-03-21 07:26:38 +09:00
parent 166d94fca4
commit 40150cd66d
406 changed files with 34179 additions and 55658 deletions
+129
View File
@@ -0,0 +1,129 @@
"""
iDRAC 클라이언트 - racadm 명령 실행 및 결과 캐싱
"""
from typing import Optional, Dict, Tuple
import subprocess
import os
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [INFO] root: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
class IDRACClient:
"""
racadm 명령 실행 및 결과 캐싱을 담당하는 클라이언트
"""
def __init__(self, ip: str, user: str = None, password: str = None):
"""
Args:
ip: iDRAC IP 주소
user: iDRAC 사용자명 (기본값: 환경변수 IDRAC_USER 또는 'root')
password: iDRAC 비밀번호 (기본값: 환경변수 IDRAC_PASS 또는 'calvin')
"""
self.ip = ip
self.user = user or os.getenv("IDRAC_USER", "root")
self.password = password or os.getenv("IDRAC_PASS", "calvin")
self._cache: Dict[str, str] = {} # 중복 호출 방지 캐시
def run_command(self, command: str) -> Tuple[int, str]:
"""
racadm 명령 실행
Args:
command: 실행할 racadm 명령 (예: "getsysinfo", "get bios.BiosBootSettings")
Returns:
(return_code, output) 튜플
"""
cmd = f"racadm -r {self.ip} -u {self.user} -p {self.password} {command}"
try:
result = subprocess.run(
cmd,
shell=True,
capture_output=True,
text=True,
check=False,
timeout=30 # 30초 타임아웃
)
return result.returncode, result.stdout
except subprocess.TimeoutExpired:
logging.error(f"[{self.ip}] 명령 타임아웃: {command}")
return 1, ""
except Exception as e:
logging.error(f"[{self.ip}] 명령 실행 오류: {e}")
return 1, f"Error: {e}"
def get_sysinfo(self) -> str:
"""
getsysinfo 명령 실행 (캐싱)
Returns:
getsysinfo 출력 결과
"""
if "sysinfo" not in self._cache:
_, output = self.run_command("getsysinfo")
self._cache["sysinfo"] = output
return self._cache["sysinfo"]
def get_hwinventory(self) -> str:
"""
hwinventory 명령 실행 (캐싱)
Returns:
hwinventory 출력 결과
"""
if "hwinventory" not in self._cache:
_, output = self.run_command("hwinventory")
self._cache["hwinventory"] = output
return self._cache["hwinventory"]
def get_swinventory(self) -> str:
"""
swinventory 명령 실행 (캐싱)
Returns:
swinventory 출력 결과
"""
if "swinventory" not in self._cache:
_, output = self.run_command("swinventory")
self._cache["swinventory"] = output
return self._cache["swinventory"]
def get_infiniband_pages(self) -> str:
"""
InfiniBand 설정 페이지 목록 조회 (InfiniBand.VndrConfigPage)
Returns:
racadm get InfiniBand.VndrConfigPage 출력
"""
if "infiniband_pages" not in self._cache:
_, output = self.run_command("get InfiniBand.VndrConfigPage")
self._cache["infiniband_pages"] = output
return self._cache["infiniband_pages"]
def get_infiniband_page_detail(self, page_number: str) -> str:
"""
특정 InfiniBand 설정 페이지 상세 조회
Args:
page_number: 페이지 번호 (예: "1")
Returns:
racadm get InfiniBand.VndrConfigPage.{page_number} 출력
"""
cache_key = f"infiniband_page_{page_number}"
if cache_key not in self._cache:
_, output = self.run_command(f"get InfiniBand.VndrConfigPage.{page_number}")
self._cache[cache_key] = output
return self._cache[cache_key]
def clear_cache(self):
"""캐시 초기화"""
self._cache.clear()