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