blob: 240a07980a6c7a09984d166373f45d820479e751 [file] [log] [blame]
Michael Walshfdc5ced2017-08-17 13:15:15 -05001#!/usr/bin/env python
2
3r"""
4Companion file to utils.robot.
5"""
6
7import gen_print as gp
8import gen_robot_keyword as grk
Michael Walshf880ac62017-11-10 11:29:37 -06009import bmc_ssh_utils as bsu
10import var_funcs as vf
Michael Walshfdc5ced2017-08-17 13:15:15 -050011from robot.libraries.BuiltIn import BuiltIn
Michael Walshf880ac62017-11-10 11:29:37 -060012from robot.libraries import DateTime
13try:
14 from robot.utils import DotDict
15except ImportError:
16 pass
17import collections
Michael Walshfdc5ced2017-08-17 13:15:15 -050018
19
Michael Walshfdc5ced2017-08-17 13:15:15 -050020def set_power_policy_method():
Michael Walshfdc5ced2017-08-17 13:15:15 -050021 r"""
22 Set the global bmc_power_policy_method to either 'Old' or 'New'.
23
24 The power policy data has moved from an 'org' location to an 'xyz'
25 location. This keyword will determine whether the new method of getting
26 the power policy is valid and will set the global bmc_power_policy_method
27 variable accordingly. If power_policy_setup is already set (by a prior
28 call to this function), this keyword will simply return.
29
30 If bmc_power_policy_method is "Old", this function will adjust the global
31 policy variables from data/variables.py: RESTORE_LAST_STATE,
32 ALWAYS_POWER_ON, ALWAYS_POWER_OFF.
33 """
34
35 # Retrieve global variables.
36 power_policy_setup = \
37 int(BuiltIn().get_variable_value("${power_policy_setup}",
38 default=0))
39 bmc_power_policy_method = \
40 BuiltIn().get_variable_value("${bmc_power_policy_method}",
41 default=0)
42 gp.dpvar(power_policy_setup)
43
44 # If this function has already been run once, we need not continue.
45 if power_policy_setup:
46 return
47
48 gp.dpvar(bmc_power_policy_method, 1)
49
50 # The user has not set bmc_power_policy_method via a -v parm so we will
51 # determine what it should be.
52 if bmc_power_policy_method == "":
53 status, ret_values = grk.run_key_u("New Get Power Policy", ignore=1)
54 if status == 'PASS':
55 bmc_power_policy_method = 'New'
56 else:
57 bmc_power_policy_method = 'Old'
58
59 gp.qpvar(bmc_power_policy_method)
60 # For old style, we will rewrite these global variable settings to old
61 # values.
62 if bmc_power_policy_method == "Old":
63 BuiltIn().set_global_variable("${RESTORE_LAST_STATE}",
64 "RESTORE_LAST_STATE")
65 BuiltIn().set_global_variable("${ALWAYS_POWER_ON}",
66 "ALWAYS_POWER_ON")
67 BuiltIn().set_global_variable("${ALWAYS_POWER_OFF}",
68 "ALWAYS_POWER_OFF")
69
70 # Set global variables to control subsequent calls to this function.
71 BuiltIn().set_global_variable("${bmc_power_policy_method}",
72 bmc_power_policy_method)
73 BuiltIn().set_global_variable("${power_policy_setup}", 1)
74
75
Michael Walshfdc5ced2017-08-17 13:15:15 -050076def translate_power_policy_value(policy):
Michael Walshfdc5ced2017-08-17 13:15:15 -050077 r"""
78 Translate the policy value and return the result.
79
80 Using old style functions, callers might call like this with a hard-
81 code value for policy:
82
George Keishingefc3ff22017-12-12 11:49:25 -060083 Set BMC Power Policy ALWAYS_POWER_OFF
Michael Walshfdc5ced2017-08-17 13:15:15 -050084
85 This function will get the value of the corresponding global variable (if
86 it exists) and return it.
87
88 This will allow the old style call to still work on systems using the new
89 method of storing the policy value.
90 """
91
92 valid_power_policy_vars = \
93 BuiltIn().get_variable_value("${valid_power_policy_vars}")
94
95 if policy not in valid_power_policy_vars:
96 return policy
97
98 status, ret_values = grk.run_key_u("Get Variable Value ${" + policy + "}",
99 quiet=1)
100 return ret_values
101
Michael Walshf880ac62017-11-10 11:29:37 -0600102
Michael Walshf880ac62017-11-10 11:29:37 -0600103def get_bmc_date_time():
Michael Walshf880ac62017-11-10 11:29:37 -0600104 r"""
105 Get date/time info from BMC and return as a dictionary.
106
107 Example of dictionary data returned by this keyword.
108 time_dict:
109 [local_time]: Fri 2017-11-03 152756 UTC
110 [local_time_seconds]: 1509740876
111 [universal_time]: Fri 2017-11-03 152756 UTC
112 [universal_time_seconds]: 1509740876
113 [rtc_time]: Fri 2016-05-20 163403
114 [rtc_time_seconds]: 1463780043
115 [time_zone]: n/a (UTC, +0000)
116 [network_time_on]: yes
117 [ntp_synchronized]: no
118 [rtc_in_local_tz]: no
119 """
120
121 out_buf, stderr, rc = bsu.bmc_execute_command('timedatectl')
122 # Example of output returned by call to timedatectl:
123 # Local time: Fri 2017-11-03 15:27:56 UTC
124 # Universal time: Fri 2017-11-03 15:27:56 UTC
125 # RTC time: Fri 2016-05-20 16:34:03
126 # Time zone: n/a (UTC, +0000)
127 # Network time on: yes
128 # NTP synchronized: no
129 # RTC in local TZ: no
130
131 # Convert the out_buf to a dictionary.
132 initial_time_dict = vf.key_value_outbuf_to_dict(out_buf)
133
134 # For each "_time" entry in the dictionary, we will create a corresponding
135 # "_time_seconds" entry. We create a new dictionary so that the entries
136 # are kept in a nice order for printing.
137 try:
138 result_time_dict = collections.OrderedDict()
139 except AttributeError:
140 result_time_dict = DotDict()
141
142 for key, value in initial_time_dict.items():
143 result_time_dict[key] = value
144 if not key.endswith("_time"):
145 continue
146 result_time_dict[key + '_seconds'] = \
147 int(DateTime.convert_date(value, result_format='epoch'))
148
149 return result_time_dict
150
Michael Walsh193743e2017-11-20 16:43:31 -0600151
152def get_bmc_df(df_parm_string=""):
Michael Walsh193743e2017-11-20 16:43:31 -0600153 r"""
154 Get df report from BMC and return as a report "object".
155
156 A df report object is a list where each entry is a dictionary whose keys
157 are the field names from the first entry in report_list.
158
159 Example df report object:
160
161 df_report:
162 df_report[0]:
163 [filesystem]: dev
164 [1k-blocks]: 247120
165 [used]: 0
166 [available]: 247120
167 [use%]: 0%
168 [mounted]: /dev
169 df_report[1]:
170 [filesystem]: dev
171 [1k-blocks]: 247120
172 [used]: 0
173 [available]: 247120
174 [use%]: 0%
175 [mounted]: /dev
176
177. Description of argument(s):
178 df_parm_string A string containing valid df command parms (e.g.
179 "-h /var").
180 """
181
182 out_buf, stderr, rc = bsu.bmc_execute_command("df " + df_parm_string)
183 return vf.outbuf_to_report(out_buf)
George Keishing6f407b92018-01-16 02:21:47 -0600184
185
186def get_sbe():
George Keishing6f407b92018-01-16 02:21:47 -0600187 r"""
188 Return CFAM value which contains such things as SBE side bit.
189 """
190
191 cmd_buf = "pdbg -d p9w -p0 getcfam 0x2808 | sed -re 's/.* = //g'"
192 out_buf, stderr, rc = bsu.bmc_execute_command(cmd_buf)
193
194 return int(out_buf, 16)
195
George Keishingbf724772018-02-21 08:57:16 -0600196
Gunnar Mills096cd562018-03-26 10:19:12 -0500197def compare_mac_address(sys_mac_addr, user_mac_addr):
George Keishingbf724772018-02-21 08:57:16 -0600198 r"""
199 Return 1 if the MAC value matched, otherwise 0.
200
201. Description of argument(s):
202 sys_mac_addr A valid system MAC string (e.g. "70:e2:84:14:2a:08")
203 user_mac_addr A user provided MAC string (e.g. "70:e2:84:14:2a:08")
204 """
205
206 index = 0
207 # Example: ['70', 'e2', '84', '14', '2a', '08']
208 mac_list = user_mac_addr.split(":")
209 for item in sys_mac_addr.split(":"):
210 if int(item, 16) == int(mac_list[index], 16):
211 index = index + 1
212 continue
213 return 0
214
215 return 1
Michael Walsh7847ece2018-04-12 11:37:45 -0500216
217
218def get_os_ethtool(interface_name):
219 r"""
220 Get OS 'ethtool' output for the given interface_name and return it as a
221 dictionary.
222
223 Settings for enP52p1s0f0:
224 Supported ports: [ TP ]
225 Supported link modes: 10baseT/Half 10baseT/Full
226 100baseT/Half 100baseT/Full
227 1000baseT/Half 1000baseT/Full
228 Supported pause frame use: No
229 Supports auto-negotiation: Yes
230 Supported FEC modes: Not reported
231 Advertised link modes: 10baseT/Half 10baseT/Full
232 100baseT/Half 100baseT/Full
233 1000baseT/Half 1000baseT/Full
234 Advertised pause frame use: Symmetric
235 Advertised auto-negotiation: Yes
236 Advertised FEC modes: Not reported
237 Speed: Unknown!
238 Duplex: Unknown! (255)
239 Port: Twisted Pair
240 PHYAD: 1
241 Transceiver: internal
242 Auto-negotiation: on
243 MDI-X: Unknown
244 Supports Wake-on: g
245 Wake-on: g
246 Current message level: 0x000000ff (255)
247 drv probe link timer ifdown ifup rx_err tx_err
248 Link detected: no
249
250 Given that data, this function will return the following dictionary.
251
252 ethtool_dict:
253 [supported_ports]: [ TP ]
254 [supported_link_modes]:
255 [supported_link_modes][0]: 10baseT/Half 10baseT/Full
256 [supported_link_modes][1]: 100baseT/Half 100baseT/Full
257 [supported_link_modes][2]: 1000baseT/Half 1000baseT/Full
258 [supported_pause_frame_use]: No
259 [supports_auto-negotiation]: Yes
260 [supported_fec_modes]: Not reported
261 [advertised_link_modes]:
262 [advertised_link_modes][0]: 10baseT/Half 10baseT/Full
263 [advertised_link_modes][1]: 100baseT/Half 100baseT/Full
264 [advertised_link_modes][2]: 1000baseT/Half 1000baseT/Full
265 [advertised_pause_frame_use]: Symmetric
266 [advertised_auto-negotiation]: Yes
267 [advertised_fec_modes]: Not reported
268 [speed]: Unknown!
269 [duplex]: Unknown! (255)
270 [port]: Twisted Pair
271 [phyad]: 1
272 [transceiver]: internal
273 [auto-negotiation]: on
274 [mdi-x]: Unknown
275 [supports_wake-on]: g
276 [wake-on]: g
277 [current_message_level]: 0x000000ff (255)
278 [drv_probe_link_timer_ifdown_ifup_rx_err_tx_err]:<blank>
279 [link_detected]: no
280 """
281
282 # Using sed and tail to massage the data a bit before running
283 # key_value_outbuf_to_dict.
284 cmd_buf = "ethtool " + interface_name +\
285 " | sed -re 's/(.* link modes:)(.*)/\\1\\n\\2/g' | tail -n +2"
286 stdout, stderr, rc = bsu.os_execute_command(cmd_buf)
287 result = vf.key_value_outbuf_to_dict(stdout, process_indent=1, strip=" \t")
288
289 return result