xref: /openbmc/openbmc-test-automation/lib/ipmi_utils.py (revision e17cf5fd0e4bff1169dab667fe0ce361ca76d857)
1#!/usr/bin/env python
2
3r"""
4Provide useful ipmi functions.
5"""
6
7import re
8import gen_print as gp
9import gen_misc as gm
10import gen_robot_keyword as grk
11import gen_robot_utils as gru
12import bmc_ssh_utils as bsu
13import var_funcs as vf
14import tempfile
15gru.my_import_resource("ipmi_client.robot")
16from robot.libraries.BuiltIn import BuiltIn
17
18
19def get_sol_info():
20
21    r"""
22    Get all SOL info and return it as a dictionary.
23
24    Example use:
25
26    Robot code:
27    ${sol_info}=  get_sol_info
28    Rpvars  sol_info
29
30    Output:
31    sol_info:
32      sol_info[Info]:                                SOL parameter 'Payload Channel (7)' not supported - defaulting to 0x0e
33      sol_info[Character Send Threshold]:            1
34      sol_info[Force Authentication]:                true
35      sol_info[Privilege Level]:                     USER
36      sol_info[Set in progress]:                     set-complete
37      sol_info[Retry Interval (ms)]:                 100
38      sol_info[Non-Volatile Bit Rate (kbps)]:        IPMI-Over-Serial-Setting
39      sol_info[Character Accumulate Level (ms)]:     100
40      sol_info[Enabled]:                             true
41      sol_info[Volatile Bit Rate (kbps)]:            IPMI-Over-Serial-Setting
42      sol_info[Payload Channel]:                     14 (0x0e)
43      sol_info[Payload Port]:                        623
44      sol_info[Force Encryption]:                    true
45      sol_info[Retry Count]:                         7
46    """
47
48    status, ret_values = grk.run_key_u("Run IPMI Standard Command  sol info")
49
50    # Create temp file path.
51    temp = tempfile.NamedTemporaryFile()
52    temp_file_path = temp.name
53
54    # Write sol info to temp file path.
55    text_file = open(temp_file_path, "w")
56    text_file.write(ret_values)
57    text_file.close()
58
59    # Use my_parm_file to interpret data.
60    sol_info = gm.my_parm_file(temp_file_path)
61
62    return sol_info
63
64
65def set_sol_setting(setting_name, setting_value):
66
67    r"""
68    Set SOL setting with given value.
69
70    # Description of argument(s):
71    # setting_name    SOL setting which needs to be set (e.g. "retry-count").
72    # setting_value   Value which needs to be set (e.g. "7").
73    """
74
75    status, ret_values = grk.run_key_u("Run IPMI Standard Command  sol set " +
76                                       setting_name + " " + setting_value)
77
78    return status
79
80
81def get_lan_print_dict():
82
83    r"""
84    Get IPMI 'lan print' output and return it as a dictionary.
85
86    Here is an example of the IPMI lan print output:
87
88    Set in Progress         : Set Complete
89    Auth Type Support       : MD5
90    Auth Type Enable        : Callback : MD5
91                            : User     : MD5
92                            : Operator : MD5
93                            : Admin    : MD5
94                            : OEM      : MD5
95    IP Address Source       : Static Address
96    IP Address              : x.x.x.x
97    Subnet Mask             : x.x.x.x
98    MAC Address             : xx:xx:xx:xx:xx:xx
99    Default Gateway IP      : x.x.x.x
100    802.1q VLAN ID          : Disabled
101    Cipher Suite Priv Max   : Not Available
102    Bad Password Threshold  : Not Available
103
104    Given that data, this function will return the following dictionary.
105
106    lan_print_dict:
107      [Set in Progress]:                              Set Complete
108      [Auth Type Support]:                            MD5
109      [Auth Type Enable]:
110        [Callback]:                                   MD5
111        [User]:                                       MD5
112        [Operator]:                                   MD5
113        [Admin]:                                      MD5
114        [OEM]:                                        MD5
115      [IP Address Source]:                            Static Address
116      [IP Address]:                                   x.x.x.x
117      [Subnet Mask]:                                  x.x.x.x
118      [MAC Address]:                                  xx:xx:xx:xx:xx:xx
119      [Default Gateway IP]:                           x.x.x.x
120      [802.1q VLAN ID]:                               Disabled
121      [Cipher Suite Priv Max]:                        Not Available
122      [Bad Password Threshold]:                       Not Available
123
124    """
125
126    IPMI_INBAND_CMD = BuiltIn().get_variable_value("${IPMI_INBAND_CMD}")
127
128    # Notice in the example of data above that 'Auth Type Enable' needs some
129    # special processing.  We essentially want to isolate its data and remove
130    # the 'Auth Type Enable' string so that key_value_outbuf_to_dict can
131    # process it as a sub-dictionary.
132    cmd_buf = IPMI_INBAND_CMD + " lan print | grep -E '^(Auth Type Enable)" +\
133        "?[ ]+: ' | sed -re 's/^(Auth Type Enable)?[ ]+: //g'"
134    stdout1, stderr, rc = bsu.os_execute_command(cmd_buf)
135
136    # Now get the remainder of the data and exclude the lines with no field
137    # names (i.e. the 'Auth Type Enable' sub-fields).
138    cmd_buf = IPMI_INBAND_CMD + " lan print | grep -E -v '^[ ]+: '"
139    stdout2, stderr, rc = bsu.os_execute_command(cmd_buf)
140
141    # Make auth_type_enable_dict sub-dictionary...
142    auth_type_enable_dict = vf.key_value_outbuf_to_dict(stdout1, to_lower=0,
143                                                        underscores=0)
144
145    # Create the lan_print_dict...
146    lan_print_dict = vf.key_value_outbuf_to_dict(stdout2, to_lower=0,
147                                                 underscores=0)
148    # Re-assign 'Auth Type Enable' to contain the auth_type_enable_dict.
149    lan_print_dict['Auth Type Enable'] = auth_type_enable_dict
150
151    return lan_print_dict
152
153
154def get_ipmi_power_reading(strip_watts=1):
155
156    r"""
157    Get IPMI power reading data and return it as a dictionary.
158
159    The data is obtained by issuing the IPMI "power reading" command.  An
160    example is shown below:
161
162    Instantaneous power reading:                   234 Watts
163    Minimum during sampling period:                234 Watts
164    Maximum during sampling period:                234 Watts
165    Average power reading over sample period:      234 Watts
166    IPMI timestamp:                           Thu Jan  1 00:00:00 1970
167    Sampling period:                          00000000 Seconds.
168    Power reading state is:                   deactivated
169
170    For the data shown above, the following dictionary will be returned.
171
172    result:
173      [instantaneous_power_reading]:              238 Watts
174      [minimum_during_sampling_period]:           238 Watts
175      [maximum_during_sampling_period]:           238 Watts
176      [average_power_reading_over_sample_period]: 238 Watts
177      [ipmi_timestamp]:                           Thu Jan  1 00:00:00 1970
178      [sampling_period]:                          00000000 Seconds.
179      [power_reading_state_is]:                   deactivated
180
181    Description of argument(s):
182    strip_watts  Strip all dictionary values of the trailing " Watts"
183                 substring.
184    """
185
186    status, ret_values = \
187        grk.run_key_u("Run IPMI Standard Command  dcmi power reading")
188    result = vf.key_value_outbuf_to_dict(ret_values)
189
190    if strip_watts:
191        result.update((k, re.sub(' Watts$', '', v)) for k, v in result.items())
192
193    return result
194
195
196def get_mc_info():
197
198    r"""
199    Get IPMI mc info data and return it as a dictionary.
200
201    The data is obtained by issuing the IPMI "mc info" command.  An
202    example is shown below:
203
204    Device ID                 : 0
205    Device Revision           : 0
206    Firmware Revision         : 2.01
207    IPMI Version              : 2.0
208    Manufacturer ID           : 42817
209    Manufacturer Name         : Unknown (0xA741)
210    Product ID                : 16975 (0x424f)
211    Product Name              : Unknown (0x424F)
212    Device Available          : yes
213    Provides Device SDRs      : yes
214    Additional Device Support :
215        Sensor Device
216        SEL Device
217        FRU Inventory Device
218        Chassis Device
219    Aux Firmware Rev Info     :
220        0x00
221        0x00
222        0x00
223        0x00
224
225    For the data shown above, the following dictionary will be returned.
226    mc_info:
227      [device_id]:                       0
228      [device_revision]:                 0
229      [firmware_revision]:               2.01
230      [ipmi_version]:                    2.0
231      [manufacturer_id]:                 42817
232      [manufacturer_name]:               Unknown (0xA741)
233      [product_id]:                      16975 (0x424f)
234      [product_name]:                    Unknown (0x424F)
235      [device_available]:                yes
236      [provides_device_sdrs]:            yes
237      [additional_device_support]:
238        [additional_device_support][0]:  Sensor Device
239        [additional_device_support][1]:  SEL Device
240        [additional_device_support][2]:  FRU Inventory Device
241        [additional_device_support][3]:  Chassis Device
242      [aux_firmware_rev_info]:
243        [aux_firmware_rev_info][0]:      0x00
244        [aux_firmware_rev_info][1]:      0x00
245        [aux_firmware_rev_info][2]:      0x00
246        [aux_firmware_rev_info][3]:      0x00
247    """
248
249    status, ret_values = \
250        grk.run_key_u("Run IPMI Standard Command  mc info")
251    result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1)
252
253    return result
254
255
256def get_sdr_info():
257
258    r"""
259    Get IPMI sdr info data and return it as a dictionary.
260
261    The data is obtained by issuing the IPMI "sdr info" command.  An
262    example is shown below:
263
264    SDR Version                         : 0x51
265    Record Count                        : 216
266    Free Space                          : unspecified
267    Most recent Addition                :
268    Most recent Erase                   :
269    SDR overflow                        : no
270    SDR Repository Update Support       : unspecified
271    Delete SDR supported                : no
272    Partial Add SDR supported           : no
273    Reserve SDR repository supported    : no
274    SDR Repository Alloc info supported : no
275
276    For the data shown above, the following dictionary will be returned.
277    mc_info:
278
279      [sdr_version]:                         0x51
280      [record_Count]:                        216
281      [free_space]:                          unspecified
282      [most_recent_addition]:
283      [most_recent_erase]:
284      [sdr_overflow]:                        no
285      [sdr_repository_update_support]:       unspecified
286      [delete_sdr_supported]:                no
287      [partial_add_sdr_supported]:           no
288      [reserve_sdr_repository_supported]:    no
289      [sdr_repository_alloc_info_supported]: no
290    """
291
292    status, ret_values = \
293        grk.run_key_u("Run IPMI Standard Command  sdr info")
294    result = vf.key_value_outbuf_to_dict(ret_values, process_indent=1)
295
296    return result
297