iLO-manager first main commitgit status
This commit is contained in:
1 parent
e6f4cc04ca
commit
599d8da562
3271 files changed
+550655
No files matched your search
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Utilities to simplify communicating with iLO locally
|
||||
"""
|
||||
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,284 @@
|
||||
###
|
||||
# Copyright 2020 Hewlett Packard Enterprise, Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
###
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Base implementation for interaction with the iLO interface"""
|
||||
|
||||
# ---------Imports---------
|
||||
|
||||
import logging
|
||||
import os
|
||||
import struct
|
||||
import time
|
||||
from ctypes import byref, c_uint32, c_char_p, c_void_p, create_string_buffer
|
||||
|
||||
# ---------End of imports---------
|
||||
# ---------Debug logger---------
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# ---------End of debug logger---------
|
||||
|
||||
|
||||
class BlobReturnCodes(object):
|
||||
"""Blob store return codes.
|
||||
|
||||
SUCCESS success
|
||||
|
||||
"""
|
||||
|
||||
SUCCESS = 0
|
||||
if os.name != "nt":
|
||||
CHIFERR_NoDriver = 19
|
||||
CHIFERR_AccessDenied = 13
|
||||
else:
|
||||
CHIFERR_NoDriver = 2
|
||||
CHIFERR_AccessDenied = 5
|
||||
|
||||
|
||||
class HpIloInitialError(Exception):
|
||||
"""Raised when error during initialization of iLO Chif channel"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class HpIloNoChifDriverError(Exception):
|
||||
"""Raised when error during initialization of iLO Chif channel"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class HpIloChifAccessDeniedError(Exception):
|
||||
"""Raised when error during initialization of iLO Chif channel"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class HpIloPrepareAndCreateChannelError(Exception):
|
||||
"""Raised when error during initialization of iLO Chif channel"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class HpIloChifPacketExchangeError(Exception):
|
||||
"""Raised when errors encountered when exchanging chif packet"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class HpIloReadError(Exception):
|
||||
"""Raised when errors encountered when reading from iLO"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class HpIloWriteError(Exception):
|
||||
"""Raised when errors encountered when writing to iLO"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class HpIloSendReceiveError(Exception):
|
||||
"""Raised when errors encountered when reading form iLO after sending"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class HpIloNoDriverError(Exception):
|
||||
"""Raised when errors encountered when there is no ilo driver"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class HpIlo(object):
|
||||
"""Base class of interaction with iLO"""
|
||||
|
||||
def __init__(self, dll=None, log_dir=None):
|
||||
fhandle = c_void_p()
|
||||
self.dll = dll
|
||||
self.log_dir = log_dir
|
||||
|
||||
if LOGGER.isEnabledFor(logging.DEBUG):
|
||||
LOGGER.debug("Initializing with DLL: %s and log directory: %s", dll, log_dir)
|
||||
self.dll.enabledebugoutput.argtypes = [c_char_p]
|
||||
if log_dir is not None:
|
||||
logdir_c = create_string_buffer(log_dir.encode("UTF-8"))
|
||||
LOGGER.debug("Enabling debug output with log directory: %s", log_dir)
|
||||
self.dll.enabledebugoutput(logdir_c)
|
||||
|
||||
try:
|
||||
LOGGER.debug("Calling ChifInitialize...")
|
||||
self.dll.ChifInitialize(None)
|
||||
|
||||
self.dll.ChifCreate.argtypes = [c_void_p]
|
||||
self.dll.ChifCreate.restype = c_uint32
|
||||
|
||||
LOGGER.debug("Calling ChifCreate...")
|
||||
status = self.dll.ChifCreate(byref(fhandle))
|
||||
if status != BlobReturnCodes.SUCCESS:
|
||||
LOGGER.error("Error occurred while creating channel. Error code: %s", status)
|
||||
raise HpIloInitialError(f"Error {status} occurred while trying to create a channel.")
|
||||
|
||||
self.fhandle = fhandle
|
||||
LOGGER.debug("Channel created successfully with handle: %s", fhandle)
|
||||
|
||||
if "skip_ping" not in os.environ:
|
||||
LOGGER.debug("Attempting to ping iLO...")
|
||||
status = self.dll.ChifPing(self.fhandle)
|
||||
if status != BlobReturnCodes.SUCCESS:
|
||||
errmsg = f"Error {status} occurred while trying to open a channel to iLO"
|
||||
if status == BlobReturnCodes.CHIFERR_NoDriver:
|
||||
errmsg = "chif"
|
||||
elif status == BlobReturnCodes.CHIFERR_AccessDenied:
|
||||
errmsg = "You must be root/Administrator to use this program."
|
||||
LOGGER.error("Ping failed: %s", errmsg)
|
||||
raise HpIloInitialError(errmsg)
|
||||
|
||||
LOGGER.debug("Ping to iLO successful.")
|
||||
|
||||
# Setting receive timeout
|
||||
LOGGER.debug("Setting receive timeout to 60000ms...")
|
||||
self.dll.ChifSetRecvTimeout(self.fhandle, 60000)
|
||||
LOGGER.debug("Receive timeout set successfully.")
|
||||
except Exception as e:
|
||||
LOGGER.error("An error occurred during initialization: %s", str(e))
|
||||
raise
|
||||
|
||||
def chif_packet_exchange(self, data):
|
||||
"""Function for handling chif packet exchange
|
||||
|
||||
:param data: data to be sent for packet exchange
|
||||
:type data: str
|
||||
|
||||
"""
|
||||
LOGGER.info("Starting chif packet exchange...")
|
||||
|
||||
LOGGER.debug("Data ready to be sent...")
|
||||
# LOGGER.debug(f"Data to be sent: {data[:50]}... (first 50 bytes)")
|
||||
|
||||
datarecv = self.dll.get_max_buffer_size()
|
||||
buff = create_string_buffer(bytes(data))
|
||||
recbuff = create_string_buffer(datarecv)
|
||||
|
||||
try:
|
||||
error = self.dll.ChifPacketExchange(self.fhandle, byref(buff), byref(recbuff), datarecv)
|
||||
except Exception as e:
|
||||
LOGGER.error(f"Error occurred while calling ChifPacketExchange: {e}")
|
||||
raise
|
||||
|
||||
if error != BlobReturnCodes.SUCCESS:
|
||||
if error == 8:
|
||||
raise HpIloChifPacketExchangeError(
|
||||
"High security mode or Host Authentication has been enabled, Please provide valid credentials \n "
|
||||
)
|
||||
else:
|
||||
raise HpIloChifPacketExchangeError(f"Error {error} occurred while exchanging chif packet")
|
||||
|
||||
LOGGER.info("Chif packet exchange successful.")
|
||||
|
||||
# Process received packet
|
||||
pkt = bytearray()
|
||||
|
||||
if datarecv is None:
|
||||
LOGGER.warning("Received buffer is empty or None.")
|
||||
pkt = bytearray(recbuff[:])
|
||||
else:
|
||||
pkt = bytearray(recbuff[:datarecv])
|
||||
LOGGER.debug("Received data...")
|
||||
# LOGGER.debug(f"Received data: {pkt[:50]}... (first 50 bytes)")
|
||||
|
||||
return pkt
|
||||
|
||||
def send_receive_raw(self, data, retries=10):
|
||||
"""Function implementing proper send receive retry protocol
|
||||
|
||||
:param data: data to be sent for packet exchange
|
||||
:type data: str
|
||||
:param retries: number of retries for reading data from iLO
|
||||
:type retries: int
|
||||
|
||||
"""
|
||||
tries = 0
|
||||
sequence = struct.unpack("<H", bytes(data[2:4]))[0]
|
||||
|
||||
if LOGGER.isEnabledFor(logging.DEBUG):
|
||||
LOGGER.debug("Retries: %d, Initial sequence: %d", retries, sequence)
|
||||
|
||||
while tries < retries:
|
||||
try:
|
||||
if LOGGER.isEnabledFor(logging.DEBUG):
|
||||
LOGGER.debug("Attempt %d, sending data to iLO", tries + 1)
|
||||
|
||||
resp = self.chif_packet_exchange(data)
|
||||
|
||||
# Log the response data for debugging (consider limiting if large)
|
||||
if LOGGER.isEnabledFor(logging.DEBUG):
|
||||
LOGGER.debug("Received response...")
|
||||
|
||||
# Check for matching sequence
|
||||
received_sequence = struct.unpack("<H", bytes(resp[2:4]))[0]
|
||||
if sequence != received_sequence:
|
||||
if LOGGER.isEnabledFor(logging.DEBUG):
|
||||
LOGGER.debug(
|
||||
"Attempt %d: Bad sequence number. Expected: %d, Got: %d",
|
||||
tries + 1,
|
||||
sequence,
|
||||
received_sequence,
|
||||
)
|
||||
continue # Retry with a new attempt
|
||||
|
||||
# Successfully received response with correct sequence
|
||||
if LOGGER.isEnabledFor(logging.DEBUG):
|
||||
LOGGER.debug("Attempt %d: Successful response with correct sequence.", tries + 1)
|
||||
|
||||
return resp
|
||||
|
||||
except Exception as excp:
|
||||
time.sleep(1)
|
||||
|
||||
# Log exception on each retry attempt
|
||||
if LOGGER.isEnabledFor(logging.DEBUG):
|
||||
LOGGER.debug("Attempt %d: Error while reading iLO: %s", tries + 1, str(excp))
|
||||
|
||||
if tries == (retries - 1):
|
||||
self.close()
|
||||
|
||||
if LOGGER.isEnabledFor(logging.DEBUG):
|
||||
LOGGER.debug("Final attempt failed. Closing connection.")
|
||||
raise excp # Raise after final attempt
|
||||
|
||||
tries += 1
|
||||
|
||||
# If retries exhausted, log and raise custom exception
|
||||
if LOGGER.isEnabledFor(logging.DEBUG):
|
||||
LOGGER.debug("Retries exhausted. iLO not responding after %d attempts.", retries)
|
||||
|
||||
raise HpIloSendReceiveError("iLO not responding")
|
||||
|
||||
def close(self):
|
||||
"""Chif close function"""
|
||||
try:
|
||||
if self.fhandle is not None:
|
||||
LOGGER.debug("Calling ChifClose...")
|
||||
self.dll.ChifClose(self.fhandle)
|
||||
self.fhandle = None
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def __del__(self):
|
||||
"""Chif delete function"""
|
||||
self.close()
|
||||
@@ -0,0 +1,428 @@
|
||||
###
|
||||
# Copyright 2024 Hewlett Packard Enterprise, Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
###
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Base implementation for interaction with vnic interface"""
|
||||
|
||||
from redfish.rest.connections import ChifDriverMissingOrNotFound, VnicNotEnabledError
|
||||
from redfish.rest.v1 import InvalidCredentialsError
|
||||
import logging
|
||||
from ctypes import (
|
||||
POINTER,
|
||||
byref,
|
||||
c_bool,
|
||||
c_char_p,
|
||||
c_int,
|
||||
c_uint8,
|
||||
c_wchar_p,
|
||||
create_string_buffer,
|
||||
)
|
||||
|
||||
from redfish.hpilo.risblobstore2 import BlobStore2
|
||||
from redfish.hpilo.rishpilo import BlobReturnCodes
|
||||
|
||||
|
||||
# ---------End of imports---------
|
||||
# ---------Debug logger---------
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GenerateAndSaveAccountError(Exception):
|
||||
"""Raised when errors occured while generating and saving app account"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class ReactivateAppAccountTokenError(Exception):
|
||||
"""Raised when errors occurred while reactivating app account"""
|
||||
|
||||
pass
|
||||
|
||||
class InactiveAppAccountTokenError(Exception):
|
||||
"""Raised when inactive app account token"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class RemoveAccountError(Exception):
|
||||
"""Raised when errors occured while removing app account"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class AppAccountExistsError(Exception):
|
||||
"""Raised when errors occured while removing app account"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class VnicLoginError(Exception):
|
||||
"""Raised when error occurs while VNIC login"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class AppIdListError(Exception):
|
||||
"""Raised when error occurs during CompareAppIds"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class SavinginTPMError(Exception):
|
||||
"""Raised when error occurs while saving app account in TPM"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class SavinginiLOError(Exception):
|
||||
"""Raised when error occurs while saving app account in iLO"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class GenBeforeLoginError(Exception):
|
||||
"""Raised when error occurs while getting iLO Gen before login"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class InvalidCommandLineError(Exception):
|
||||
"""Raised when invalid command line arguments are passed"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class AppAccount(object):
|
||||
def __init__(self, appname=None, appid=None, salt=None, username=None, password=None, log_dir=None):
|
||||
"""Initialize the AppAccount object and configure logging."""
|
||||
self.appname = (appname or "self_register").encode("utf-8")
|
||||
self.dll = BlobStore2.gethprestchifhandle()
|
||||
self.salt = (salt or "self_register").encode("utf-8")
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.log_dir = log_dir
|
||||
|
||||
LOGGER.debug(
|
||||
f"Initialization parameters - AppName: {self.appname.decode('utf-8')}, "
|
||||
f"Salt: {self.salt.decode('utf-8')}, Username: {self.username if self.username else 'None'}"
|
||||
)
|
||||
|
||||
if log_dir and LOGGER.isEnabledFor(logging.DEBUG):
|
||||
logdir_c = create_string_buffer(log_dir.encode("utf-8"))
|
||||
self.dll.enabledebugoutput(logdir_c)
|
||||
LOGGER.info("Debug output enabled. Logs stored in: %s", log_dir)
|
||||
|
||||
if appid and len(appid) == 4:
|
||||
appid = self.ExpandAppId(appid)
|
||||
|
||||
self.appid = (appid or "self_register").encode("utf-8")
|
||||
|
||||
def ExpandAppId(self, appid):
|
||||
"""Calls the DLL function to expand a 4-character app ID."""
|
||||
self.dll.ExpandAppid.argtypes = [c_char_p, POINTER(c_char_p)]
|
||||
self.dll.ExpandAppid.restype = c_int
|
||||
|
||||
host_app_id_c = c_char_p(appid.encode("utf-8"))
|
||||
expanded_app_id_c = c_char_p(None)
|
||||
|
||||
LOGGER.debug(f"Calling ExpandAppid with AppID: {appid}")
|
||||
ret = self.dll.ExpandAppid(host_app_id_c, byref(expanded_app_id_c))
|
||||
if ret:
|
||||
LOGGER.error(f"Failed to expand App ID {appid} (Return code: {ret})")
|
||||
raise AppAccountExistsError()
|
||||
|
||||
expanded_id = expanded_app_id_c.value.decode("utf-8") if expanded_app_id_c else None
|
||||
if LOGGER.isEnabledFor(logging.DEBUG):
|
||||
LOGGER.debug(f"Successfully expanded App ID {appid} to {expanded_id}")
|
||||
return expanded_id
|
||||
|
||||
def generate_and_save_apptoken(self):
|
||||
"""Generate and save an application account, logging each step."""
|
||||
LOGGER.info("Starting generate_and_save_apptoken process.")
|
||||
|
||||
self.dll.GenerateAppToken.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p]
|
||||
self.dll.GenerateAppToken.restype = c_int
|
||||
|
||||
self.username = self.username.encode("utf-8")
|
||||
self.password = self.password.encode("utf-8")
|
||||
|
||||
LOGGER.debug("Calling GenerateAppToken for AppID: %s", self.appid.decode("utf-8"))
|
||||
|
||||
returncode = self.dll.GenerateAppToken(self.appid, self.appname, self.salt, self.username, self.password)
|
||||
|
||||
if returncode == BlobReturnCodes.SUCCESS:
|
||||
LOGGER.info("Application account successfully generated and saved.")
|
||||
return BlobReturnCodes.SUCCESS
|
||||
elif returncode == -54:
|
||||
LOGGER.error("Failed to save account in TPM.")
|
||||
raise SavinginTPMError()
|
||||
elif returncode == -53:
|
||||
LOGGER.error("Failed to save account in iLO.")
|
||||
raise SavinginiLOError()
|
||||
elif returncode == -55:
|
||||
LOGGER.warning("Application account already exists.")
|
||||
raise AppAccountExistsError()
|
||||
elif returncode == -8:
|
||||
raise InvalidCredentialsError(0)
|
||||
else:
|
||||
LOGGER.critical("Unknown return code: %d", returncode)
|
||||
raise GenerateAndSaveAccountError()
|
||||
|
||||
def reactivate_apptoken(self):
|
||||
"""Reactivate an application account, logging each step."""
|
||||
LOGGER.info("Starting reactivate_apptoken process.")
|
||||
|
||||
self.dll.ReactivateAppToken.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p]
|
||||
self.dll.ReactivateAppToken.restype = c_int
|
||||
|
||||
user_name = self.username.encode("utf-8")
|
||||
password = self.password.encode("utf-8")
|
||||
|
||||
LOGGER.debug("Calling ReactivateAppToken for AppID: %s", self.appid.decode("utf-8"))
|
||||
|
||||
return_code = self.dll.ReactivateAppToken(self.appid, self.appname, self.salt, user_name, password)
|
||||
|
||||
if return_code == BlobReturnCodes.SUCCESS:
|
||||
LOGGER.info("Application account has been reactivated successfully.")
|
||||
return BlobReturnCodes.SUCCESS
|
||||
elif return_code == -8:
|
||||
LOGGER.error("Please enter valid credentials.")
|
||||
raise InvalidCredentialsError(0)
|
||||
else:
|
||||
LOGGER.critical("Unknown return code: %d", return_code)
|
||||
raise ReactivateAppAccountTokenError()
|
||||
|
||||
def remove_apptoken(self):
|
||||
returncode = 1
|
||||
if self.username and self.password:
|
||||
LOGGER.debug(f"Using credentials to remove for AppID: {self.appid.decode('utf-8')}")
|
||||
self.dll.DeleteAppTokenUsingCreds.argtypes = [c_char_p, c_char_p, c_char_p]
|
||||
self.dll.DeleteAppTokenUsingCreds.restype = c_int
|
||||
self.username = self.username.encode("utf-8")
|
||||
self.password = self.password.encode("utf-8")
|
||||
returncode = self.dll.DeleteAppTokenUsingCreds(self.appid, self.username, self.password)
|
||||
|
||||
elif self.appname and self.salt:
|
||||
LOGGER.debug(f"Using app details to remove for AppID : {self.appid.decode('utf-8')}")
|
||||
self.dll.DeleteAppToken.argtypes = [c_char_p, c_char_p, c_char_p]
|
||||
self.dll.DeleteAppToken.restype = c_int
|
||||
returncode = self.dll.DeleteAppToken(self.appid, self.appname, self.salt)
|
||||
|
||||
LOGGER.debug(f"Delete operation returned code: {returncode}")
|
||||
|
||||
if returncode == BlobReturnCodes.SUCCESS:
|
||||
return BlobReturnCodes.SUCCESS
|
||||
elif returncode == -8:
|
||||
raise InvalidCredentialsError(0)
|
||||
else:
|
||||
raise RemoveAccountError("Error occurred while removing app account.")
|
||||
|
||||
def apptoken_exists(self):
|
||||
"""Check if an application account exists in TPM."""
|
||||
LOGGER.info("Checking if application account exists.")
|
||||
|
||||
self.dll.AppIdExistsinTPM.argtypes = [c_char_p, POINTER(c_bool)]
|
||||
self.dll.AppIdExistsinTPM.restype = c_int
|
||||
|
||||
vexists = c_bool(False)
|
||||
LOGGER.debug(f"Checking existence for AppID: {self.appid.decode('utf-8')}")
|
||||
returncode = self.dll.AppIdExistsinTPM(self.appid, byref(vexists))
|
||||
LOGGER.debug(f"AppIdExistsinTPM returned: {returncode}")
|
||||
|
||||
if returncode == BlobReturnCodes.SUCCESS:
|
||||
LOGGER.info("app account existence check completed. Exists: %s", vexists.value)
|
||||
return vexists.value
|
||||
else:
|
||||
LOGGER.error("Failed to check account existence")
|
||||
LOGGER.debug(f"Failed with return code: {returncode}")
|
||||
raise AppAccountExistsError()
|
||||
|
||||
def vlogin(self):
|
||||
LOGGER.info("Starting VNIC login process.")
|
||||
|
||||
self.dll.GetSessionID.argtypes = [c_char_p, c_char_p, c_char_p, POINTER(c_char_p), POINTER(c_char_p)]
|
||||
self.dll.GetSessionID.restype = c_int
|
||||
session_id = c_char_p()
|
||||
session_location = c_char_p()
|
||||
errorcode = 0
|
||||
|
||||
LOGGER.debug(f"Attempting login for AppID: {self.appid.decode('utf-8')}")
|
||||
try:
|
||||
errorcode = self.dll.GetSessionID(
|
||||
self.appid, self.appname, self.salt, byref(session_id), byref(session_location)
|
||||
)
|
||||
LOGGER.debug(f"GetSessionID returned code: {errorcode}")
|
||||
if errorcode == 2:
|
||||
raise InactiveAppAccountTokenError()
|
||||
elif errorcode != BlobReturnCodes.SUCCESS:
|
||||
raise Exception
|
||||
session_id = session_id.value.decode()
|
||||
session_location = session_location.value.decode()
|
||||
session_location = "/" + session_location.split("/", 3)[-1]
|
||||
LOGGER.debug("Successfully decoded session information")
|
||||
LOGGER.info(
|
||||
"VNIC login successful. Session Location: %s, Session ID: ****%s", session_location, session_id[-4:]
|
||||
)
|
||||
|
||||
return session_id, session_location
|
||||
except InactiveAppAccountTokenError:
|
||||
LOGGER.error("Login failed due to an inactive or expired App Account token.")
|
||||
raise InactiveAppAccountTokenError()
|
||||
except Exception as excp:
|
||||
LOGGER.error("VNIC login failed: %s", str(excp))
|
||||
raise VnicLoginError()
|
||||
|
||||
def vnic_exists(self):
|
||||
"""Check if the VNIC is ready for use."""
|
||||
LOGGER.info("Checking if VNIC is ready for use.")
|
||||
|
||||
self.dll.ReadyToUse.restype = c_int
|
||||
LOGGER.debug("Calling ReadyToUse")
|
||||
status = self.dll.ReadyToUse()
|
||||
LOGGER.debug(f"ReadyToUse returned status: {status}")
|
||||
|
||||
if status == BlobReturnCodes.SUCCESS:
|
||||
LOGGER.info("VNIC is ready for use.")
|
||||
return True
|
||||
else:
|
||||
LOGGER.warning("VNIC is not ready for use.")
|
||||
return False
|
||||
|
||||
def version_beforelogin(self):
|
||||
"""Detect the iLO version before login."""
|
||||
LOGGER.info("Detecting iLO version before login.")
|
||||
|
||||
self.dll.DetectILO.argtypes = [c_char_p, POINTER(c_int), POINTER(c_int)]
|
||||
self.dll.DetectILO.restype = c_int
|
||||
|
||||
ilo_type = c_int(0)
|
||||
security_state = c_int(0)
|
||||
|
||||
if not self.appid:
|
||||
self.appid = "self_register".encode("utf-8")
|
||||
|
||||
returncode = self.dll.DetectILO(self.appid, byref(ilo_type), byref(security_state))
|
||||
LOGGER.debug(f"DetectILO returned: type={ilo_type.value}, security={security_state.value}, code={returncode}")
|
||||
|
||||
if returncode == BlobReturnCodes.SUCCESS:
|
||||
LOGGER.info(
|
||||
"iLO version successfully detected: %d, Security State: %d", ilo_type.value, security_state.value
|
||||
)
|
||||
return ilo_type.value, security_state.value
|
||||
elif returncode == -1 and ilo_type.value == 100:
|
||||
LOGGER.info(
|
||||
"Detectilo returned ilotype: %d, Security State: %d, " "returncode: %d",
|
||||
ilo_type.value,
|
||||
security_state.value,
|
||||
returncode,
|
||||
)
|
||||
raise ChifDriverMissingOrNotFound()
|
||||
elif returncode == -50 and ilo_type.value == 101:
|
||||
LOGGER.info(
|
||||
"Detectilo returned ilotype: %d, Security State: %d, " "returncode: %d",
|
||||
ilo_type.value,
|
||||
security_state.value,
|
||||
returncode,
|
||||
)
|
||||
raise VnicNotEnabledError()
|
||||
elif returncode == -2:
|
||||
LOGGER.info("Invalid parameters were passed in the command line. Detectilo iLO returncode: -2")
|
||||
raise InvalidCommandLineError()
|
||||
else:
|
||||
LOGGER.info(
|
||||
"Detectilo returned ilotype: %d, Security State: %d, " "returncode: %d",
|
||||
ilo_type.value,
|
||||
security_state.value,
|
||||
returncode,
|
||||
)
|
||||
LOGGER.error("Failed to detect iLO version.")
|
||||
raise GenBeforeLoginError()
|
||||
|
||||
def GetIPAddress(self):
|
||||
"""Retrieve the IP address of the iLO interface."""
|
||||
LOGGER.info("Retrieving IP address.")
|
||||
|
||||
LOGGER.debug("Calling GetIPAddress")
|
||||
self.dll.GetIPAddress.restype = c_wchar_p
|
||||
ip_addr = self.dll.GetIPAddress()
|
||||
LOGGER.debug(f"GetIPAddress returned: {ip_addr if ip_addr else 'None'}")
|
||||
|
||||
LOGGER.info("IP address retrieved: %s", ip_addr)
|
||||
return ip_addr
|
||||
|
||||
def CompareAppIds(self):
|
||||
"""Compare application IDs and return a structured dictionary."""
|
||||
LOGGER.info("Starting CompareAppIds process.")
|
||||
|
||||
self.dll.CompareAppIds.argtypes = [
|
||||
c_char_p,
|
||||
c_char_p,
|
||||
c_char_p,
|
||||
POINTER(POINTER(c_char_p)),
|
||||
POINTER(POINTER(c_char_p)),
|
||||
POINTER(c_int),
|
||||
POINTER(POINTER(c_uint8)),
|
||||
POINTER(POINTER(c_uint8)),
|
||||
]
|
||||
self.dll.CompareAppIds.restype = c_int
|
||||
|
||||
app_ids_ptr = POINTER(c_char_p)()
|
||||
app_names_ptr = POINTER(c_char_p)()
|
||||
app_id_count = c_int()
|
||||
in_tpm_ptr = POINTER(c_uint8)()
|
||||
in_ilo_ptr = POINTER(c_uint8)()
|
||||
|
||||
LOGGER.debug(
|
||||
"Calling CompareAppIds with AppID: %s, AppName: %s",
|
||||
self.appid.decode("utf-8"),
|
||||
self.appname.decode("utf-8"),
|
||||
)
|
||||
|
||||
returncode = self.dll.CompareAppIds(
|
||||
self.appid,
|
||||
self.appname,
|
||||
self.salt,
|
||||
byref(app_ids_ptr),
|
||||
byref(app_names_ptr),
|
||||
byref(app_id_count),
|
||||
byref(in_tpm_ptr),
|
||||
byref(in_ilo_ptr),
|
||||
)
|
||||
if returncode != BlobReturnCodes.SUCCESS:
|
||||
LOGGER.error("Error occurred in CompareAppIds. Return Code: %d", returncode)
|
||||
raise AppIdListError("Error occurred while retrieving App Id information.\n")
|
||||
|
||||
LOGGER.info("CompareAppIds executed successfully. Number of App IDs: %d", app_id_count.value)
|
||||
app_ids = [app_ids_ptr[i].decode("utf-8") for i in range(app_id_count.value)]
|
||||
app_names = [app_names_ptr[i].decode("utf-8") for i in range(app_id_count.value)]
|
||||
in_tpm_list = [bool(in_tpm_ptr[i]) for i in range(app_id_count.value)]
|
||||
in_ilo_list = [bool(in_ilo_ptr[i]) for i in range(app_id_count.value)]
|
||||
|
||||
appid_dict = list()
|
||||
for i in range(app_id_count.value):
|
||||
appid_dict.append(
|
||||
{
|
||||
"ApplicationID": app_ids[i],
|
||||
"ApplicationName": app_names[i],
|
||||
"ExistsInTPM": in_tpm_list[i],
|
||||
"ExistsIniLO": in_ilo_list[i],
|
||||
}
|
||||
)
|
||||
|
||||
LOGGER.info("CompareAppIds completed successfully. Processed %d AppIDs.", len(appid_dict))
|
||||
|
||||
return appid_dict
|
||||
Reference in new issue
Block a user