blob: 82b10fd45d27efe7a51819d8d5f279b249f2dd25 [file] [log] [blame]
George Keishinge7e91712021-09-03 11:28:44 -05001#!/usr/bin/env python3
Prashanth Katti747ce9d2019-02-07 07:23:48 -06002
3r"""
4Network generic functions.
5
6"""
7
Patrick Williams57318182022-12-08 06:18:26 -06008import collections
9import ipaddress
10import json
11import re
12import socket
13import subprocess
14
15import bmc_ssh_utils as bsu
Michael Walsh8ce4e032019-08-22 18:03:12 -050016import gen_cmd as gc
17import gen_misc as gm
Patrick Williams57318182022-12-08 06:18:26 -060018import gen_print as gp
Michael Walsh8ce4e032019-08-22 18:03:12 -050019import var_funcs as vf
Prashanth Katti747ce9d2019-02-07 07:23:48 -060020from robot.libraries.BuiltIn import BuiltIn
21
Sushil Singhdc187d42020-09-11 01:30:24 -050022ip_regex = r"\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}"
23
Sushil Singh45d841e2020-07-30 11:52:11 -050024
Sushil Singh07297f82020-09-08 09:12:04 -050025def get_running_system_ip():
Sushil Singh45d841e2020-07-30 11:52:11 -050026 r"""
Sushil Singh07297f82020-09-08 09:12:04 -050027 Get the IP address of server from which robot code is running.
Sushil Singhbfaeb032020-09-01 02:02:36 -050028
Sushil Singh45d841e2020-07-30 11:52:11 -050029 """
30
Sushil Singh07297f82020-09-08 09:12:04 -050031 ip_list = list()
Patrick Williams57318182022-12-08 06:18:26 -060032 stdout = subprocess.check_output(["hostname", "--all-fqdns"], shell=True)
Sushil Singhca49ced2020-11-05 03:15:19 -060033 host_fqdns = stdout.decode("utf-8").strip()
34 ip_address = socket.gethostbyname(str(host_fqdns))
35 ip_list.append(ip_address)
Sushil Singh45d841e2020-07-30 11:52:11 -050036
Sushil Singh07297f82020-09-08 09:12:04 -050037 return ip_list
Sushil Singh45d841e2020-07-30 11:52:11 -050038
Prashanth Katti747ce9d2019-02-07 07:23:48 -060039
40def netmask_prefix_length(netmask):
41 r"""
42 Return the netmask prefix length.
43
44 Description of argument(s):
45 netmask Netmask value (e.g. "255.255.0.0", "255.255.255.0",
46 "255.252.0.0", etc.).
47 """
48
49 # IP address netmask format: '0.0.0.0/255.255.252.0'
Patrick Williams57318182022-12-08 06:18:26 -060050 return ipaddress.ip_network("0.0.0.0/" + netmask).prefixlen
Michael Walsh91960fd2019-08-19 14:21:20 -050051
52
Anvesh Kumar Rayankula8e25b8f2020-04-06 01:18:37 -050053def get_netmask_address(prefix_len):
54 r"""
55 Return the netmask address.
56
57 Description of argument(s):
58 prefix_len Prefix length value (e.g. "24", "23", "22", etc.).
59 """
60
61 # IP address netmask format: '0.0.0.0/24'
Patrick Williams57318182022-12-08 06:18:26 -060062 return ipaddress.ip_network("0.0.0.0/" + prefix_len).netmask
Anvesh Kumar Rayankula8e25b8f2020-04-06 01:18:37 -050063
64
Michael Walsh91960fd2019-08-19 14:21:20 -050065def parse_nping_output(output):
66 r"""
67 Parse the output from the nping command and return as a dictionary.
68
69 Example of output value:
70
71 Starting Nping 0.6.47 ( http://nmap.org/nping ) at 2019-08-07 22:05 IST
72 SENT (0.0181s) TCP Source IP:37577 >
73 Destination IP:80 S ttl=64 id=39113 iplen=40 seq=629782493 win=1480
74 SENT (0.2189s) TCP Source IP:37577 >
75 Destination IP:80 S ttl=64 id=39113 iplen=40 seq=629782493 win=1480
76 RCVD (0.4120s) TCP Destination IP:80 >
77 Source IP:37577 SA ttl=49 id=0 iplen=44 seq=1078301364 win=5840 <mss 1380>
78 Max rtt: 193.010ms | Min rtt: 193.010ms | Avg rtt: 193.010ms
79 Raw packets sent: 2 (80B) | Rcvd: 1 (46B) | Lost: 1 (50.00%)
shrsuman123a8b3e182021-12-09 05:46:22 -060080 TCP connection attempts: 5 | Successful connections: 5 | Failed: 0 (0.00%)
Michael Walsh91960fd2019-08-19 14:21:20 -050081 Nping done: 1 IP address pinged in 0.43 seconds
82
83 Example of data returned by this function:
84
85 nping_result:
86 [max_rtt]: 193.010ms
87 [min_rtt]: 193.010ms
88 [avg_rtt]: 193.010ms
89 [raw_packets_sent]: 2 (80B)
90 [rcvd]: 1 (46B)
91 [lost]: 1 (50.00%)
92 [percent_lost]: 50.00
shrsuman123a8b3e182021-12-09 05:46:22 -060093 [tcp_connection_attempts]: 5
94 [successful_connections]: 5
95 [failed]: 0 (0.00%)
96 [percent_failed]: 0.00
Michael Walsh91960fd2019-08-19 14:21:20 -050097
98 Description of argument(s):
99 output The output obtained by running an nping
100 command.
101 """
102
103 lines = output.split("\n")
104 # Obtain only the lines of interest.
Patrick Williams57318182022-12-08 06:18:26 -0600105 lines = list(
106 filter(
107 lambda x: re.match(r"(Max rtt|Raw packets|TCP connection)", x),
108 lines,
109 )
110 )
Michael Walsh91960fd2019-08-19 14:21:20 -0500111
112 key_value_list = []
113 for line in lines:
114 key_value_list += line.split("|")
115 nping_result = vf.key_value_list_to_dict(key_value_list)
shrsuman123a8b3e182021-12-09 05:46:22 -0600116 # Extract percent_lost/percent_failed value from lost/failed field.
Patrick Williams57318182022-12-08 06:18:26 -0600117 if "lost" in nping_result:
118 nping_result["percent_lost"] = float(
119 nping_result["lost"].split(" ")[-1].strip("()%")
120 )
shrsuman123a8b3e182021-12-09 05:46:22 -0600121 else:
Patrick Williams57318182022-12-08 06:18:26 -0600122 nping_result["percent_failed"] = float(
123 nping_result["failed"].split(" ")[-1].strip("()%")
124 )
Michael Walsh91960fd2019-08-19 14:21:20 -0500125 return nping_result
Michael Walsh8ce4e032019-08-22 18:03:12 -0500126
127
128openbmc_host = BuiltIn().get_variable_value("${OPENBMC_HOST}")
129
130
131def nping(host=openbmc_host, parse_results=1, **options):
132 r"""
133 Run the nping command and return the results either as a string or as a dictionary.
134
135 Do a 'man nping' for a complete description of the nping utility.
136
137 Note that any valid nping argument may be specified as a function argument.
138
139 Example robot code:
140
141 ${nping_result}= Nping delay=${delay} count=${count} icmp=${None} icmp-type=echo
142 Rprint Vars nping_result
143
144 Resulting output:
145
146 nping_result:
147 [max_rtt]: 0.534ms
148 [min_rtt]: 0.441ms
149 [avg_rtt]: 0.487ms
150 [raw_packets_sent]: 4 (112B)
151 [rcvd]: 2 (92B)
152 [lost]: 2 (50.00%)
153 [percent_lost]: 50.0
154
155 Description of argument(s):
156 host The host name or IP of the target of the
157 nping command.
158 parse_results 1 or True indicates that this function
159 should parse the nping results and return
160 a dictionary rather than the raw nping
161 output. See the parse_nping_output()
162 function for details on the dictionary
163 structure.
164 options Zero or more options accepted by the nping
165 command. Do a 'man nping' for details.
166 """
167
Patrick Williams57318182022-12-08 06:18:26 -0600168 command_string = gc.create_command_string("nping", host, options)
Michael Walsh8ce4e032019-08-22 18:03:12 -0500169 rc, output = gc.shell_cmd(command_string, print_output=0, ignore_err=0)
170 if parse_results:
171 return parse_nping_output(output)
172
173 return output
Tony Leeea741302019-11-08 11:01:58 +0800174
175
176def get_channel_config():
177 r"""
178 Get the channel config data and return as a dictionary.
179
180 Example:
181 channel_config = get_channel_config()
182 print_vars(channel_config)
183
184 channel_config:
185 [0]:
186 [name]: IPMB
187 [is_valid]: True
188 [active_sessions]: 0
189 [channel_info]:
190 [medium_type]: ipmb
191 [protocol_type]: ipmb-1.0
192 [session_supported]: session-less
193 [is_ipmi]: True
194 [1]:
195 [name]: eth0
196 [is_valid]: True
197 [active_sessions]: 0
198 [channel_info]:
199 [medium_type]: other-lan
200 [protocol_type]: ipmb-1.0
201 [session_supported]: multi-session
202 [is_ipmi]: True
203 [2]:
204 [name]: eth1
205 [is_valid]: True
206 [active_sessions]: 0
207 [channel_info]:
208 [medium_type]: lan-802.3
209 [protocol_type]: ipmb-1.0
210 [session_supported]: multi-session
211 [is_ipmi]: True
212 (etc.)
213 """
214
Patrick Williams57318182022-12-08 06:18:26 -0600215 stdout, stderr, rc = bsu.bmc_execute_command(
216 "cat /usr/share/ipmi-providers/channel_config.json"
217 )
Tony Leeea741302019-11-08 11:01:58 +0800218 return json.loads(stdout)
219
220
221def get_active_channel_config():
222 r"""
223 Channel configs which medium_type are 'other-lan' or 'lan-802.3' returned by
224 this function.
225 """
226
Patrick Williams57318182022-12-08 06:18:26 -0600227 return vf.filter_struct(
228 get_channel_config(),
229 "[('medium_type', 'other-lan|lan-802.3')]",
230 regex=1,
231 )
Tony Lee18c6f9a2020-02-18 17:00:20 +0800232
233
Tony Lee87c9cb92020-03-04 14:47:09 +0800234def get_channel_access_config(file_name):
Tony Lee18c6f9a2020-02-18 17:00:20 +0800235 r"""
236 Get the channel access config data and return as a dictionary.
237
Tony Lee87c9cb92020-03-04 14:47:09 +0800238 Description of argument:
239 file_name File name for channel access settings (e.g. '/run/ipmi/channel_access_volatile.json',
240 '/var/lib/ipmi/channel_access_nv.json'.).
241
Tony Lee18c6f9a2020-02-18 17:00:20 +0800242 Example:
243
244 channel_access_config = get_channel_access_config()
245 print_vars(channel_access_config)
246
247 channel_access_config:
248 [1]:
249 [priv_limit]: priv-admin
250 [per_msg_auth_disabled]: False
251 [access_mode]: always_available
252 [alerting_disabled]: False
253 [user_auth_disabled]: False
254 [2]:
255 [priv_limit]: priv-admin
256 [per_msg_auth_disabled]: False
257 [access_mode]: always_available
258 [alerting_disabled]: False
259 [user_auth_disabled]: False
260 """
Tony Lee87c9cb92020-03-04 14:47:09 +0800261 stdout, stderr, rc = bsu.bmc_execute_command("cat " + file_name)
Tony Lee18c6f9a2020-02-18 17:00:20 +0800262
263 return json.loads(stdout)