1#!/usr/bin/env python 2 3r""" 4Network generic functions. 5 6""" 7 8import gen_print as gp 9import gen_cmd as gc 10import gen_misc as gm 11import var_funcs as vf 12import collections 13import re 14import ipaddress 15from robot.libraries.BuiltIn import BuiltIn 16import json 17import bmc_ssh_utils as bsu 18 19 20def netmask_prefix_length(netmask): 21 r""" 22 Return the netmask prefix length. 23 24 Description of argument(s): 25 netmask Netmask value (e.g. "255.255.0.0", "255.255.255.0", 26 "255.252.0.0", etc.). 27 """ 28 29 # IP address netmask format: '0.0.0.0/255.255.252.0' 30 return ipaddress.ip_network('0.0.0.0/' + netmask).prefixlen 31 32 33def get_netmask_address(prefix_len): 34 r""" 35 Return the netmask address. 36 37 Description of argument(s): 38 prefix_len Prefix length value (e.g. "24", "23", "22", etc.). 39 """ 40 41 # IP address netmask format: '0.0.0.0/24' 42 return ipaddress.ip_network('0.0.0.0/' + prefix_len).netmask 43 44 45def parse_nping_output(output): 46 r""" 47 Parse the output from the nping command and return as a dictionary. 48 49 Example of output value: 50 51 Starting Nping 0.6.47 ( http://nmap.org/nping ) at 2019-08-07 22:05 IST 52 SENT (0.0181s) TCP Source IP:37577 > 53 Destination IP:80 S ttl=64 id=39113 iplen=40 seq=629782493 win=1480 54 SENT (0.2189s) TCP Source IP:37577 > 55 Destination IP:80 S ttl=64 id=39113 iplen=40 seq=629782493 win=1480 56 RCVD (0.4120s) TCP Destination IP:80 > 57 Source IP:37577 SA ttl=49 id=0 iplen=44 seq=1078301364 win=5840 <mss 1380> 58 Max rtt: 193.010ms | Min rtt: 193.010ms | Avg rtt: 193.010ms 59 Raw packets sent: 2 (80B) | Rcvd: 1 (46B) | Lost: 1 (50.00%) 60 Nping done: 1 IP address pinged in 0.43 seconds 61 62 Example of data returned by this function: 63 64 nping_result: 65 [max_rtt]: 193.010ms 66 [min_rtt]: 193.010ms 67 [avg_rtt]: 193.010ms 68 [raw_packets_sent]: 2 (80B) 69 [rcvd]: 1 (46B) 70 [lost]: 1 (50.00%) 71 [percent_lost]: 50.00 72 73 Description of argument(s): 74 output The output obtained by running an nping 75 command. 76 """ 77 78 lines = output.split("\n") 79 # Obtain only the lines of interest. 80 lines = list(filter(lambda x: re.match(r"(Max rtt|Raw packets)", x), 81 lines)) 82 83 key_value_list = [] 84 for line in lines: 85 key_value_list += line.split("|") 86 nping_result = vf.key_value_list_to_dict(key_value_list) 87 # Extract percent_lost value from lost field. 88 nping_result['percent_lost'] = \ 89 float(nping_result['lost'].split(" ")[-1].strip("()%")) 90 return nping_result 91 92 93openbmc_host = BuiltIn().get_variable_value("${OPENBMC_HOST}") 94 95 96def nping(host=openbmc_host, parse_results=1, **options): 97 r""" 98 Run the nping command and return the results either as a string or as a dictionary. 99 100 Do a 'man nping' for a complete description of the nping utility. 101 102 Note that any valid nping argument may be specified as a function argument. 103 104 Example robot code: 105 106 ${nping_result}= Nping delay=${delay} count=${count} icmp=${None} icmp-type=echo 107 Rprint Vars nping_result 108 109 Resulting output: 110 111 nping_result: 112 [max_rtt]: 0.534ms 113 [min_rtt]: 0.441ms 114 [avg_rtt]: 0.487ms 115 [raw_packets_sent]: 4 (112B) 116 [rcvd]: 2 (92B) 117 [lost]: 2 (50.00%) 118 [percent_lost]: 50.0 119 120 Description of argument(s): 121 host The host name or IP of the target of the 122 nping command. 123 parse_results 1 or True indicates that this function 124 should parse the nping results and return 125 a dictionary rather than the raw nping 126 output. See the parse_nping_output() 127 function for details on the dictionary 128 structure. 129 options Zero or more options accepted by the nping 130 command. Do a 'man nping' for details. 131 """ 132 133 command_string = gc.create_command_string('nping', host, options) 134 rc, output = gc.shell_cmd(command_string, print_output=0, ignore_err=0) 135 if parse_results: 136 return parse_nping_output(output) 137 138 return output 139 140 141def get_channel_config(): 142 r""" 143 Get the channel config data and return as a dictionary. 144 145 Example: 146 channel_config = get_channel_config() 147 print_vars(channel_config) 148 149 channel_config: 150 [0]: 151 [name]: IPMB 152 [is_valid]: True 153 [active_sessions]: 0 154 [channel_info]: 155 [medium_type]: ipmb 156 [protocol_type]: ipmb-1.0 157 [session_supported]: session-less 158 [is_ipmi]: True 159 [1]: 160 [name]: eth0 161 [is_valid]: True 162 [active_sessions]: 0 163 [channel_info]: 164 [medium_type]: other-lan 165 [protocol_type]: ipmb-1.0 166 [session_supported]: multi-session 167 [is_ipmi]: True 168 [2]: 169 [name]: eth1 170 [is_valid]: True 171 [active_sessions]: 0 172 [channel_info]: 173 [medium_type]: lan-802.3 174 [protocol_type]: ipmb-1.0 175 [session_supported]: multi-session 176 [is_ipmi]: True 177 (etc.) 178 """ 179 180 stdout, stderr, rc = bsu.bmc_execute_command("cat /usr/share/ipmi-providers/channel_config.json") 181 return json.loads(stdout) 182 183 184def get_active_channel_config(): 185 r""" 186 Channel configs which medium_type are 'other-lan' or 'lan-802.3' returned by 187 this function. 188 """ 189 190 return vf.filter_struct(get_channel_config(), "[('medium_type', 'other-lan|lan-802.3')]", regex=1) 191 192 193def get_channel_access_config(file_name): 194 r""" 195 Get the channel access config data and return as a dictionary. 196 197 Description of argument: 198 file_name File name for channel access settings (e.g. '/run/ipmi/channel_access_volatile.json', 199 '/var/lib/ipmi/channel_access_nv.json'.). 200 201 Example: 202 203 channel_access_config = get_channel_access_config() 204 print_vars(channel_access_config) 205 206 channel_access_config: 207 [1]: 208 [priv_limit]: priv-admin 209 [per_msg_auth_disabled]: False 210 [access_mode]: always_available 211 [alerting_disabled]: False 212 [user_auth_disabled]: False 213 [2]: 214 [priv_limit]: priv-admin 215 [per_msg_auth_disabled]: False 216 [access_mode]: always_available 217 [alerting_disabled]: False 218 [user_auth_disabled]: False 219 """ 220 stdout, stderr, rc = bsu.bmc_execute_command("cat " + file_name) 221 222 return json.loads(stdout) 223