| #!/usr/bin/env python3 |
| |
| r""" |
| Provide useful ipmi functions. |
| """ |
| |
| import json |
| import re |
| import tempfile |
| |
| import bmc_ssh_utils as bsu |
| import gen_cmd as gc |
| import gen_misc as gm |
| import gen_print as gp |
| import gen_robot_keyword as grk |
| import gen_robot_utils as gru |
| import ipmi_client as ic |
| import var_funcs as vf |
| from robot.libraries.BuiltIn import BuiltIn |
| |
| gru.my_import_resource("ipmi_client.robot") |
| |
| |
| def get_sol_info(): |
| r""" |
| Get all SOL info and return it as a dictionary. |
| |
| Example use: |
| |
| Robot code: |
| ${sol_info}= get_sol_info |
| Rpvars sol_info |
| |
| Output: |
| sol_info: |
| sol_info[Info]: SOL parameter 'Payload Channel (7)' |
| not supported - defaulting to 0x0e |
| sol_info[Character Send Threshold]: 1 |
| sol_info[Force Authentication]: true |
| sol_info[Privilege Level]: USER |
| sol_info[Set in progress]: set-complete |
| sol_info[Retry Interval (ms)]: 100 |
| sol_info[Non-Volatile Bit Rate (kbps)]: IPMI-Over-Serial-Setting |
| sol_info[Character Accumulate Level (ms)]: 100 |
| sol_info[Enabled]: true |
| sol_info[Volatile Bit Rate (kbps)]: IPMI-Over-Serial-Setting |
| sol_info[Payload Channel]: 14 (0x0e) |
| sol_info[Payload Port]: 623 |
| sol_info[Force Encryption]: true |
| sol_info[Retry Count]: 7 |
| """ |
| |
| status, ret_values = grk.run_key_u( |
| "Run External IPMI Standard Command sol info" |
| ) |
| |
| # Create temp file path. |
| temp = tempfile.NamedTemporaryFile() |
| temp_file_path = temp.name |
| |
| # Write sol info to temp file path. |
| text_file = open(temp_file_path, "w") |
| text_file.write(ret_values) |
| text_file.close() |
| |
| # Use my_parm_file to interpret data. |
| sol_info = gm.my_parm_file(temp_file_path) |
| |
| return sol_info |
| |
| |
| def set_sol_setting(setting_name, setting_value): |
| r""" |
| Set SOL setting with given value. |
| |
| # Description of argument(s): |
| # setting_name SOL setting which needs to be set (e.g. |
| # "retry-count"). |
| # setting_value Value which needs to be set (e.g. "7"). |
| """ |
| |
| status, ret_values = grk.run_key_u( |
| "Run External IPMI Standard Command sol set " |
| + setting_name |
| + " " |
| + setting_value |
| ) |
| |
| return status |
| |
| |
| def execute_ipmi_cmd( |
| cmd_string, ipmi_cmd_type="inband", print_output=1, ignore_err=0, **options |
| ): |
| r""" |
| Run the given command string as an IPMI command and return the stdout, |
| stderr and the return code. |
| |
| Description of argument(s): |
| cmd_string The command string to be run as an IPMI |
| command. |
| ipmi_cmd_type 'inband' or 'external'. |
| print_output If this is set, this function will print |
| the stdout/stderr generated by |
| the IPMI command. |
| ignore_err Ignore error means that a failure |
| encountered by running the command |
| string will not be raised as a python |
| exception. |
| options These are passed directly to the |
| create_ipmi_ext_command_string function. |
| See that function's prolog for details. |
| """ |
| |
| if ipmi_cmd_type == "inband": |
| IPMI_INBAND_CMD = BuiltIn().get_variable_value("${IPMI_INBAND_CMD}") |
| cmd_buf = IPMI_INBAND_CMD + " " + cmd_string |
| return bsu.os_execute_command( |
| cmd_buf, print_out=print_output, ignore_err=ignore_err |
| ) |
| |
| if ipmi_cmd_type == "external": |
| cmd_buf = ic.create_ipmi_ext_command_string(cmd_string, **options) |
| rc, stdout, stderr = gc.shell_cmd( |
| cmd_buf, |
| print_output=print_output, |
| ignore_err=ignore_err, |
| return_stderr=1, |
| ) |
| return stdout, stderr, rc |
| |
| |
| def get_lan_print_dict(channel_number="", ipmi_cmd_type="external"): |
| r""" |
| Get IPMI 'lan print' output and return it as a dictionary. |
| |
| Here is an example of the IPMI lan print output: |
| |
| Set in Progress : Set Complete |
| Auth Type Support : MD5 |
| Auth Type Enable : Callback : MD5 |
| : User : MD5 |
| : Operator : MD5 |
| : Admin : MD5 |
| : OEM : MD5 |
| IP Address Source : Static Address |
| IP Address : x.x.x.x |
| Subnet Mask : x.x.x.x |
| MAC Address : xx:xx:xx:xx:xx:xx |
| Default Gateway IP : x.x.x.x |
| 802.1q VLAN ID : Disabled |
| Cipher Suite Priv Max : Not Available |
| Bad Password Threshold : Not Available |
| |
| Given that data, this function will return the following dictionary. |
| |
| lan_print_dict: |
| [Set in Progress]: Set Complete |
| [Auth Type Support]: MD5 |
| [Auth Type Enable]: |
| [Callback]: MD5 |
| [User]: MD5 |
| [Operator]: MD5 |
| [Admin]: MD5 |
| [OEM]: MD5 |
| [IP Address Source]: Static Address |
| [IP Address]: x.x.x.x |
| [Subnet Mask]: x.x.x.x |
| [MAC Address]: xx:xx:xx:xx:xx:xx |
| [Default Gateway IP]: x.x.x.x |
| [802.1q VLAN ID]: Disabled |
| [Cipher Suite Priv Max]: Not Available |
| [Bad Password Threshold]: Not Available |
| |
| Description of argument(s): |
| ipmi_cmd_type The type of ipmi command to use (e.g. |
| 'inband', 'external'). |
| """ |
| |
| channel_number = str(channel_number) |
| # Notice in the example of data above that 'Auth Type Enable' needs some |
| # special processing. We essentially want to isolate its data and remove |
| # the 'Auth Type Enable' string so that key_value_outbuf_to_dict can |
| # process it as a sub-dictionary. |
| cmd_buf = ( |
| "lan print " |
| + channel_number |
| + " | grep -E '^(Auth Type Enable)" |
| + "?[ ]+: ' | sed -re 's/^(Auth Type Enable)?[ ]+: //g'" |
| ) |
| stdout1, stderr, rc = execute_ipmi_cmd( |
| cmd_buf, ipmi_cmd_type, print_output=0 |
| ) |
| |
| # Now get the remainder of the data and exclude the lines with no field |
| # names (i.e. the 'Auth Type Enable' sub-fields). |
| cmd_buf = "lan print " + channel_number + " | grep -E -v '^[ ]+: '" |
| stdout2, stderr, rc = execute_ipmi_cmd( |
| cmd_buf, ipmi_cmd_type, print_output=0 |
| ) |
| |
| # Make auth_type_enable_dict sub-dictionary... |
| auth_type_enable_dict = vf.key_value_outbuf_to_dict( |
| stdout1, to_lower=0, underscores=0 |
| ) |
| |
| # Create the lan_print_dict... |
| lan_print_dict = vf.key_value_outbuf_to_dict( |
| stdout2, to_lower=0, underscores=0 |
| ) |
| # Re-assign 'Auth Type Enable' to contain the auth_type_enable_dict. |
| lan_print_dict["Auth Type Enable"] = auth_type_enable_dict |
| |
| return lan_print_dict |
| |
| |
| def get_ipmi_power_reading(strip_watts=1): |
| r""" |
| Get IPMI power reading data and return it as a dictionary. |
| |
| The data is obtained by issuing the IPMI "power reading" command. An |
| example is shown below: |
| |
| Instantaneous power reading: 234 Watts |
| Minimum during sampling period: 234 Watts |
| Maximum during sampling period: 234 Watts |
| Average power reading over sample period: 234 Watts |
| IPMI timestamp: Thu Jan 1 00:00:00 1970 |
| Sampling period: 00000000 Seconds. |
| Power reading state is: deactivated |
| |
| For the data shown above, the following dictionary will be returned. |
| |
| result: |
| [instantaneous_power_reading]: 238 Watts |
| [minimum_during_sampling_period]: 238 Watts |
| [maximum_during_sampling_period]: 238 Watts |
| [average_power_reading_over_sample_period]: 238 Watts |
| [ipmi_timestamp]: Thu Jan 1 00:00:00 1970 |
| [sampling_period]: 00000000 Seconds. |
| [power_reading_state_is]: deactivated |
| |
| Description of argument(s): |
| strip_watts Strip all dictionary values of the |
| trailing " Watts" substring. |
| """ |
| |
| status, ret_values = grk.run_key_u( |
| "Run IPMI Standard Command dcmi power reading" |
| ) |
| result = vf.key_value_outbuf_to_dict(ret_values) |
| |
| if strip_watts: |
| result.update((k, re.sub(" Watts$", "", v)) for k, v in result.items()) |
| |
| return result |
| |
| |
| def get_mc_info(): |
| r""" |
| Get IPMI mc info data and return it as a dictionary. |
| |
| The data is obtained by issuing the IPMI "mc info" command. An |
| example is shown below: |
| |
| Device ID : 0 |
| Device Revision : 0 |
| Firmware Revision : 2.01 |
| IPMI Version : 2.0 |
| Manufacturer ID : 42817 |
| Manufacturer Name : Unknown (0xA741) |
| Product ID : 16975 (0x424f) |
| Product Name : Unknown (0x424F) |
| Device Available : yes |
| Provides Device SDRs : yes |
| Additional Device Support : |
| Sensor Device |
| SEL Device |
| FRU Inventory Device |
| Chassis Device |
| Aux Firmware Rev Info : |
| 0x00 |
| 0x00 |
| 0x00 |
| 0x00 |
| |
| For the data shown above, the following dictionary will be returned. |
| mc_info: |
| [device_id]: 0 |
| [device_revision]: 0 |
| [firmware_revision]: 2.01 |
| [ipmi_version]: 2.0 |
| [manufacturer_id]: 42817 |
| [manufacturer_name]: Unknown (0xA741) |
| [product_id]: 16975 (0x424f) |
| [product_name]: Unknown (0x424F) |
| [device_available]: yes |
| [provides_device_sdrs]: yes |
| [additional_device_support]: |
| [additional_device_support][0]: Sensor Device |
| [additional_device_support][1]: SEL Device |
| [additional_device_support][2]: FRU Inventory Device |
| [additional_device_support][3]: Chassis Device |
| [aux_firmware_rev_info]: |
| [aux_firmware_rev_info][0]: 0x00 |
| [aux_firmware_rev_info][1]: 0x00 |
| [aux_firmware_rev_info][2]: 0x00 |
| [aux_firmware_rev_info][3]: 0x00 |
| """ |
| |
| status, ret_values = grk.run_key_u("Run IPMI Standard Command mc info") |
| result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1) |
| |
| return result |
| |
| |
| def get_sdr_info(): |
| r""" |
| Get IPMI sdr info data and return it as a dictionary. |
| |
| The data is obtained by issuing the IPMI "sdr info" command. An |
| example is shown below: |
| |
| SDR Version : 0x51 |
| Record Count : 216 |
| Free Space : unspecified |
| Most recent Addition : |
| Most recent Erase : |
| SDR overflow : no |
| SDR Repository Update Support : unspecified |
| Delete SDR supported : no |
| Partial Add SDR supported : no |
| Reserve SDR repository supported : no |
| SDR Repository Alloc info supported : no |
| |
| For the data shown above, the following dictionary will be returned. |
| mc_info: |
| |
| [sdr_version]: 0x51 |
| [record_Count]: 216 |
| [free_space]: unspecified |
| [most_recent_addition]: |
| [most_recent_erase]: |
| [sdr_overflow]: no |
| [sdr_repository_update_support]: unspecified |
| [delete_sdr_supported]: no |
| [partial_add_sdr_supported]: no |
| [reserve_sdr_repository_supported]: no |
| [sdr_repository_alloc_info_supported]: no |
| """ |
| |
| status, ret_values = grk.run_key_u("Run IPMI Standard Command sdr info") |
| result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1) |
| |
| return result |
| |
| |
| def fetch_sdr_count(sdr_data): |
| r""" |
| Get IPMI SDR list and return the SDR OEM count. |
| |
| The data is obtained by issuing the IPMI "sdr elist -vvv" command. An |
| example is shown below: |
| |
| SDR record ID : 0x00cb |
| SDR record ID : 0x00cc |
| SDR record type : 0xc0 |
| SDR record next : 0xffff |
| SDR record bytes: 11 |
| Getting 11 bytes from SDR at offset 5 |
| |
| For the data shown above, the SDR record type with 0xc0 count will be returned. |
| """ |
| |
| data = sdr_data.split("\n") |
| sdr_list = [] |
| for i, j in enumerate(data): |
| a = j.split(":") |
| if a[0].strip() == "SDR record type": |
| sdr_list.append(a[1].strip()) |
| return sdr_list.count("0xc0") |
| |
| |
| def get_aux_version(version_id): |
| r""" |
| Get IPMI Aux version info data and return it. |
| |
| Description of argument(s): |
| version_id The data is obtained by from BMC |
| /etc/os-release |
| (e.g. "xxx-v2.1-438-g0030304-r3-gfea8585"). |
| |
| In the prior example, the 3rd field is "438" is the commit version and |
| the 5th field is "r3" and value "3" is the release version. |
| |
| Aux version return from this function 4380003. |
| """ |
| |
| # Commit version. |
| count = re.findall("-(\\d{1,4})-", version_id) |
| |
| # Release version. |
| release = re.findall("-r(\\d{1,4})", version_id) |
| if release: |
| aux_version = count[0] + "{0:0>4}".format(release[0]) |
| else: |
| aux_version = count[0] + "0000" |
| |
| return aux_version |
| |
| |
| def get_fru_info(): |
| r""" |
| Get fru info and return it as a list of dictionaries. |
| |
| The data is obtained by issuing the IPMI "fru print -N 50" command. An |
| example is shown below: |
| |
| FRU Device Description : Builtin FRU Device (ID 0) |
| Device not present (Unspecified error) |
| |
| FRU Device Description : cpu0 (ID 1) |
| Board Mfg Date : Sun Dec 31 18:00:00 1995 |
| Board Mfg : <Manufacturer Name> |
| Board Product : PROCESSOR MODULE |
| Board Serial : YA1934315964 |
| Board Part Number : 02CY209 |
| |
| FRU Device Description : cpu1 (ID 2) |
| Board Mfg Date : Sun Dec 31 18:00:00 1995 |
| Board Mfg : <Manufacturer Name> |
| Board Product : PROCESSOR MODULE |
| Board Serial : YA1934315965 |
| Board Part Number : 02CY209 |
| |
| For the data shown above, the following list of dictionaries will be |
| returned. |
| |
| fru_obj: |
| fru_obj[0]: |
| [fru_device_description]: Builtin FRU Device (ID 0) |
| [state]: Device not present (Unspecified error) |
| fru_obj[1]: |
| [fru_device_description]: cpu0 (ID 1) |
| [board_mfg_date]: Sun Dec 31 18:00:00 1995 |
| [board_mfg]: <Manufacturer Name> |
| [board_product]: PROCESSOR MODULE |
| [board_serial]: YA1934315964 |
| [board_part_number]: 02CY209 |
| fru_obj[2]: |
| [fru_device_description]: cpu1 (ID 2) |
| [board_mfg_date]: Sun Dec 31 18:00:00 1995 |
| [board_mfg]: <Manufacturer Name> |
| [board_product]: PROCESSOR MODULE |
| [board_serial]: YA1934315965 |
| [board_part_number]: 02CY209 |
| """ |
| |
| status, ret_values = grk.run_key_u( |
| "Run IPMI Standard Command fru print -N 50" |
| ) |
| |
| # Manipulate the "Device not present" line to create a "state" key. |
| ret_values = re.sub( |
| "Device not present", "state : Device not present", ret_values |
| ) |
| |
| return [ |
| vf.key_value_outbuf_to_dict(x) for x in re.split("\n\n", ret_values) |
| ] |
| |
| |
| def get_component_fru_info(component="cpu", fru_objs=None): |
| r""" |
| Get fru info for the given component and return it as a list of |
| dictionaries. |
| |
| This function calls upon get_fru_info and then filters out the unwanted |
| entries. See get_fru_info's prolog for a layout of the data. |
| |
| Description of argument(s): |
| component The component (e.g. "cpu", "dimm", etc.). |
| fru_objs A fru_objs list such as the one returned |
| by get_fru_info. If this is None, then |
| this function will call get_fru_info to |
| obtain such a list. |
| Supplying this argument may improve |
| performance if this function is to be |
| called multiple times. |
| """ |
| |
| if fru_objs is None: |
| fru_objs = get_fru_info() |
| return [ |
| x |
| for x in fru_objs |
| if re.match(component + "([0-9]+)? ", x["fru_device_description"]) |
| ] |
| |
| |
| def get_user_info(userid, channel_number=1): |
| r""" |
| Get user info using channel command and return it as a dictionary. |
| |
| Description of argument(s): |
| userid The userid (e.g. "1", "2", etc.). |
| channel_number The user's channel number (e.g. "1"). |
| |
| Note: If userid is blank, this function will return a list of dictionaries. Each list entry represents |
| one userid record. |
| |
| The data is obtained by issuing the IPMI "channel getaccess" command. An |
| example is shown below for user id 1 and channel number 1. |
| |
| Maximum User IDs : 15 |
| Enabled User IDs : 1 |
| User ID : 1 |
| User Name : root |
| Fixed Name : No |
| Access Available : callback |
| Link Authentication : enabled |
| IPMI Messaging : enabled |
| Privilege Level : ADMINISTRATOR |
| Enable Status : enabled |
| |
| For the data shown above, the following dictionary will be returned. |
| |
| user_info: |
| [maximum_userids]: 15 |
| [enabled_userids: 1 |
| [userid] 1 |
| [user_name] root |
| [fixed_name] No |
| [access_available] callback |
| [link_authentication] enabled |
| [ipmi_messaging] enabled |
| [privilege_level] ADMINISTRATOR |
| [enable_status] enabled |
| """ |
| |
| status, ret_values = grk.run_key_u( |
| "Run IPMI Standard Command channel getaccess " |
| + str(channel_number) |
| + " " |
| + str(userid) |
| ) |
| |
| if userid == "": |
| return vf.key_value_outbuf_to_dicts(ret_values, process_indent=1) |
| else: |
| return vf.key_value_outbuf_to_dict(ret_values, process_indent=1) |
| |
| |
| def channel_getciphers_ipmi(): |
| r""" |
| Run 'channel getciphers ipmi' command and return the result as a list of dictionaries. |
| |
| Example robot code: |
| ${ipmi_channel_ciphers}= Channel Getciphers IPMI |
| Rprint Vars ipmi_channel_ciphers |
| |
| Example output: |
| ipmi_channel_ciphers: |
| [0]: |
| [id]: 3 |
| [iana]: N/A |
| [auth_alg]: hmac_sha1 |
| [integrity_alg]: hmac_sha1_96 |
| [confidentiality_alg]: aes_cbc_128 |
| [1]: |
| [id]: 17 |
| [iana]: N/A |
| [auth_alg]: hmac_sha256 |
| [integrity_alg]: sha256_128 |
| [confidentiality_alg]: aes_cbc_128 |
| """ |
| |
| cmd_buf = "channel getciphers ipmi | sed -re 's/ Alg/_Alg/g'" |
| stdout, stderr, rc = execute_ipmi_cmd(cmd_buf, "external", print_output=0) |
| return vf.outbuf_to_report(stdout) |
| |
| |
| def get_device_id_config(): |
| r""" |
| Get the device id config data and return as a dictionary. |
| |
| Example: |
| |
| dev_id_config = get_device_id_config() |
| print_vars(dev_id_config) |
| |
| dev_id_config: |
| [manuf_id]: 7244 |
| [addn_dev_support]: 141 |
| [prod_id]: 16976 |
| [aux]: 0 |
| [id]: 32 |
| [revision]: 129 |
| [device_revision]: 1 |
| """ |
| stdout, stderr, rc = bsu.bmc_execute_command( |
| "cat /usr/share/ipmi-providers/dev_id.json" |
| ) |
| |
| result = json.loads(stdout) |
| |
| # Create device revision field for the user. |
| # Reference IPMI specification v2.0 "Get Device ID Command" |
| # [7] 1 = device provides Device SDRs |
| # 0 = device does not provide Device SDRs |
| # [6:4] reserved. Return as 0. |
| # [3:0] Device Revision, binary encoded. |
| |
| result["device_revision"] = result["revision"] & 0x0F |
| |
| return result |
| |
| |
| def get_chassis_status(): |
| r""" |
| Get IPMI chassis status data and return it as a dictionary. |
| |
| The data is obtained by issuing the IPMI "chassis status" command. An |
| example is shown below: |
| |
| System Power : off |
| Power Overload : false |
| Power Interlock : inactive |
| Main Power Fault : false |
| Power Control Fault : false |
| Power Restore Policy : previous |
| Last Power Event : |
| Chassis Intrusion : inactive |
| Front-Panel Lockout : inactive |
| Drive Fault : false |
| Cooling/Fan Fault : false |
| Sleep Button Disable : not allowed |
| Diag Button Disable : not allowed |
| Reset Button Disable : not allowed |
| Power Button Disable : allowed |
| Sleep Button Disabled : false |
| Diag Button Disabled : false |
| Reset Button Disabled : false |
| Power Button Disabled : false |
| |
| For the data shown above, the following dictionary will be returned. |
| |
| chassis_status: |
| [system_power]: off |
| [power_overload]: false |
| [power_interlock]: inactive |
| [main_power_fault]: false |
| [power_control_fault]: false |
| [power_restore_policy]: previous |
| [last_power_event]: |
| [chassis_intrusion]: inactive |
| [front-panel_lockout]: inactive |
| [drive_fault]: false |
| [cooling/fan_fault]: false |
| [sleep_button_disable]: not allowed |
| [diag_button_disable]: not allowed |
| [reset_button_disable]: not allowed |
| [power_button_disable]: allowed |
| [sleep_button_disabled]: false |
| [diag_button_disabled]: false |
| [reset_button_disabled]: false |
| [power_button_disabled]: false |
| """ |
| |
| status, ret_values = grk.run_key_u( |
| "Run External IPMI Standard Command chassis status" |
| ) |
| result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1) |
| |
| return result |
| |
| |
| def get_channel_info(channel_number=1): |
| r""" |
| Get the channel info and return as a dictionary. |
| Example: |
| |
| channel_info: |
| [channel_0x2_info]: |
| [channel_medium_type]: 802.3 LAN |
| [channel_protocol_type]: IPMB-1.0 |
| [session_support]: multi-session |
| [active_session_count]: 0 |
| [protocol_vendor_id]: 7154 |
| [volatile(active)_settings]: |
| [alerting]: enabled |
| [per-message_auth]: enabled |
| [user_level_auth]: enabled |
| [access_mode]: always available |
| [non-volatile_settings]: |
| [alerting]: enabled |
| [per-message_auth]: enabled |
| [user_level_auth]: enabled |
| [access_mode]: always available |
| """ |
| |
| status, ret_values = grk.run_key_u( |
| "Run IPMI Standard Command channel info " + str(channel_number) |
| ) |
| key_var_list = list(filter(None, ret_values.split("\n"))) |
| # To match the dict format, add a colon after 'Volatile(active) Settings' and 'Non-Volatile Settings' |
| # respectively. |
| key_var_list[6] = "Volatile(active) Settings:" |
| key_var_list[11] = "Non-Volatile Settings:" |
| result = vf.key_value_list_to_dict(key_var_list, process_indent=1) |
| return result |
| |
| |
| def get_user_access_ipmi(channel_number=1): |
| r""" |
| Run 'user list [<channel number>]' command and return the result as a list of dictionaries. |
| |
| Example robot code: |
| ${users_access}= user list 1 |
| Rprint Vars users_access |
| |
| Example output: |
| users: |
| [0]: |
| [id]: 1 |
| [name]: root |
| [callin]: false |
| [link]: true |
| [auth]: true |
| [ipmi]: ADMINISTRATOR |
| [1]: |
| [id]: 2 |
| [name]: axzIDwnz |
| [callin]: true |
| [link]: false |
| [auth]: true |
| [ipmi]: ADMINISTRATOR |
| """ |
| |
| cmd_buf = "user list " + str(channel_number) |
| stdout, stderr, rc = execute_ipmi_cmd(cmd_buf, "external", print_output=0) |
| return vf.outbuf_to_report(stdout) |
| |
| |
| def get_channel_auth_capabilities(channel_number=1, privilege_level=4): |
| r""" |
| Get the channel authentication capabilities and return as a dictionary. |
| |
| Example: |
| |
| channel_auth_cap: |
| [channel_number]: 2 |
| [ipmi_v1.5__auth_types]: |
| [kg_status]: default (all zeroes) |
| [per_message_authentication]: enabled |
| [user_level_authentication]: enabled |
| [non-null_user_names_exist]: yes |
| [null_user_names_exist]: no |
| [anonymous_login_enabled]: no |
| [channel_supports_ipmi_v1.5]: no |
| [channel_supports_ipmi_v2.0]: yes |
| """ |
| |
| status, ret_values = grk.run_key_u( |
| "Run IPMI Standard Command channel authcap " |
| + str(channel_number) |
| + " " |
| + str(privilege_level) |
| ) |
| result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1) |
| |
| return result |
| |
| |
| def fetch_date(date): |
| r""" |
| Removes prefix 0 in a date in given date |
| |
| Example : 08/12/2021 then returns 8/12/2021 |
| """ |
| |
| date = date.lstrip("0") |
| return date |
| |
| |
| def fetch_added_sel_date(entry): |
| r""" |
| Split sel entry string with with | and join only the date with space |
| |
| Example : If entry given is, "a | 02/14/2020 | 01:16:58 | Sensor_type #0x17 | | Asserted" |
| Then the result will be "02/14/2020 01:16:58" |
| """ |
| |
| temp = entry.split(" | ") |
| date = temp[1] + " " + temp[2] |
| print(date) |
| return date |
| |
| |
| def prefix_bytes(listx): |
| r""" |
| prefixes byte strings in list |
| |
| Example: |
| ${listx} = ['01', '02', '03'] |
| ${listx}= Prefix Bytes ${listx} |
| then, |
| ${listx}= ['0x01', '0x02', '0x03'] |
| |
| """ |
| |
| listy = [] |
| for item in listx: |
| item = "0x" + item |
| listy.append(item) |
| return listy |
| |
| |
| def modify_and_fetch_threshold(old_threshold, threshold_list): |
| r""" |
| Description of argument(s): |
| |
| old_threshold List of threshold values of sensor, |
| threshold_list List of higher and lower of critical and non-critical values. |
| i,e [ "lcr", "lnc", "unc", "ucr" ] |
| |
| Gets old threshold values from sensor and threshold levels, |
| then returns the list of new threshold and the dict of threshold levels |
| |
| For example : |
| 1. If old_threshold list is [ 1, 2, 3, 4] then the newthreshold_list will be [ 101, 102, 103, 104 ]. |
| If old_threshold has 'na' the same will be appended to new list, eg: [ 101, 102, 103, 104, 'na']. |
| |
| 2. The newthreshold_list will be zipped to dictionary with threshold_list levels, |
| Example : threshold_dict = { 'lcr': 101, 'lnc': 102, 'unc': 103, 'ucr': 104 } |
| |
| """ |
| |
| # Adding the difference of 100 as less than this value, |
| # may not have greater impact as the sensor considered is a fan sensor. |
| # The set threshold may round off for certain values below 100. |
| n = 100 |
| newthreshold_list = [] |
| for th in old_threshold: |
| th = th.strip() |
| if th == "na": |
| newthreshold_list.append("na") |
| else: |
| x = int(float(th)) + n |
| newthreshold_list.append(x) |
| n = n + 100 |
| threshold_dict = dict(zip(threshold_list, newthreshold_list)) |
| return newthreshold_list, threshold_dict |