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