| #!/usr/bin/env python | 
 |  | 
 | r""" | 
 | Provide useful ipmi functions. | 
 | """ | 
 |  | 
 | import re | 
 | import gen_print as gp | 
 | import gen_misc as gm | 
 | import gen_cmd as gc | 
 | import gen_robot_keyword as grk | 
 | import gen_robot_utils as gru | 
 | import bmc_ssh_utils as bsu | 
 | import var_funcs as vf | 
 | import ipmi_client as ic | 
 | import tempfile | 
 | gru.my_import_resource("ipmi_client.robot") | 
 | from robot.libraries.BuiltIn import BuiltIn | 
 | import json | 
 |  | 
 |  | 
 | 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 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 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 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 IPMI Standard Command  chassis status") | 
 |     result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1) | 
 |  | 
 |     return result |