1*** Settings *** 2Resource ../lib/utils.robot 3Resource ../lib/connection_client.robot 4Resource ../lib/boot_utils.robot 5Library ../lib/gen_misc.py 6Library ../lib/utils.py 7Library ../lib/bmc_network_utils.py 8 9*** Variables *** 10# MAC input from user. 11${MAC_ADDRESS} ${EMPTY} 12 13 14*** Keywords *** 15 16Check And Reset MAC 17 [Documentation] Update BMC with user input MAC address. 18 [Arguments] ${mac_address}=${MAC_ADDRESS} 19 20 # Description of argument(s): 21 # mac_address The mac address (e.g. 00:01:6c:80:02:28). 22 23 Should Not Be Empty ${mac_address} 24 Open Connection And Log In 25 ${bmc_mac_addr} ${stderr} ${rc}= BMC Execute Command 26 ... cat /sys/class/net/eth0/address 27 Run Keyword If '${mac_address.lower()}' != '${bmc_mac_addr.lower()}' 28 ... Set MAC Address 29 30 31Set MAC Address 32 [Documentation] Update eth0 with input MAC address. 33 [Arguments] ${mac_address}=${MAC_ADDRESS} 34 35 # Description of argument(s): 36 # mac_address The mac address (e.g. 00:01:6c:80:02:28). 37 38 Write fw_setenv ethaddr ${mac_address} 39 OBMC Reboot (off) 40 41 # Take SSH session post BMC reboot. 42 Open Connection And Log In 43 ${bmc_mac_addr} ${stderr} ${rc}= BMC Execute Command 44 ... cat /sys/class/net/eth0/address 45 Should Be Equal ${bmc_mac_addr} ${mac_address} ignore_case=True 46 47 48Get BMC IP Info 49 [Documentation] Get system IP address and prefix length. 50 51 52 # Get system IP address and prefix length details using "ip addr" 53 # Sample Output of "ip addr": 54 # 1: eth0: <BROADCAST,MULTIAST> mtu 1500 qdisc mq state UP qlen 1000 55 # link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff 56 # inet xx.xx.xx.xx/24 brd xx.xx.xx.xx scope global eth0 57 58 ${cmd_output} ${stderr} ${rc}= BMC Execute Command 59 ... /sbin/ip addr | grep eth0 60 61 # Get line having IP address details. 62 ${lines}= Get Lines Containing String ${cmd_output} inet 63 64 # List IP address details. 65 @{ip_components}= Split To Lines ${lines} 66 67 @{ip_data}= Create List 68 69 # Get all IP addresses and prefix lengths on system. 70 FOR ${ip_component} IN @{ip_components} 71 @{if_info}= Split String ${ip_component} 72 ${ip_n_prefix}= Get From List ${if_info} 1 73 Append To List ${ip_data} ${ip_n_prefix} 74 END 75 76 [Return] ${ip_data} 77 78Get BMC Route Info 79 [Documentation] Get system route info. 80 81 82 # Sample output of "ip route": 83 # default via xx.xx.xx.x dev eth0 84 # xx.xx.xx.0/23 dev eth0 src xx.xx.xx.xx 85 # xx.xx.xx.0/24 dev eth0 src xx.xx.xx.xx 86 87 ${cmd_output} ${stderr} ${rc}= BMC Execute Command 88 ... /sbin/ip route 89 90 [Return] ${cmd_output} 91 92# TODO: openbmc/openbmc-test-automation#1331 93Get BMC MAC Address 94 [Documentation] Get system MAC address. 95 96 97 # Sample output of "ip addr | grep ether": 98 # link/ether xx.xx.xx.xx.xx.xx brd ff:ff:ff:ff:ff:ff 99 100 ${cmd_output} ${stderr} ${rc}= BMC Execute Command 101 ... /sbin/ip addr | grep ether 102 103 # Split the line and return MAC address. 104 # Split list data: 105 # link/ether | xx:xx:xx:xx:xx:xx | brd | ff:ff:ff:ff:ff:ff 106 107 @{words}= Split String ${cmd_output} 108 109 [Return] ${words[1]} 110 111 112Get BMC MAC Address List 113 [Documentation] Get system MAC address 114 115 # Sample output of "ip addr | grep ether": 116 # link/ether xx.xx.xx.xx.xx.xx brd ff:ff:ff:ff:ff:ff 117 118 ${cmd_output} ${stderr} ${rc}= BMC Execute Command 119 ... /sbin/ip addr | grep ether 120 121 # Split the line and return MAC address. 122 # Split list data: 123 # link/ether | xx:xx:xx:xx:xx:xx | brd | ff:ff:ff:ff:ff:ff 124 # link/ether | xx:xx:xx:xx:xx:xx | brd | ff:ff:ff:ff:ff:ff 125 126 ${mac_list}= Create List 127 @{lines}= Split To Lines ${cmd_output} 128 FOR ${line} IN @{lines} 129 @{words}= Split String ${line} 130 Append To List ${mac_list} ${words[1]} 131 END 132 133 [Return] ${mac_list} 134 135Get BMC Hostname 136 [Documentation] Get BMC hostname. 137 138 # Sample output of "hostname": 139 # test_hostname 140 141 ${output} ${stderr} ${rc}= BMC Execute Command hostname 142 143 [Return] ${output} 144 145Get List Of IP Address Via REST 146 [Documentation] Get list of IP address via REST. 147 [Arguments] @{ip_uri_list} 148 149 # Description of argument(s): 150 # ip_uri_list List of IP objects. 151 # Example: 152 # "data": [ 153 # "/xyz/openbmc_project/network/eth0/ipv4/e9767624", 154 # "/xyz/openbmc_project/network/eth0/ipv4/31f4ce8b" 155 # ], 156 157 ${ip_list}= Create List 158 159 FOR ${ip_uri} IN @{ip_uri_list} 160 ${ip_addr}= Read Attribute ${ip_uri} Address 161 Append To List ${ip_list} ${ip_addr} 162 END 163 164 [Return] @{ip_list} 165 166Delete IP And Object 167 [Documentation] Delete IP and object. 168 [Arguments] ${ip_addr} @{ip_uri_list} 169 170 # Description of argument(s): 171 # ip_addr IP address to be deleted. 172 # ip_uri_list List of IP object URIs. 173 174 # Find IP object having this IP address. 175 176 FOR ${ip_uri} IN @{ip_uri_list} 177 ${ip_addr1}= Read Attribute ${ip_uri} Address 178 Run Keyword If '${ip_addr}' == '${ip_addr1}' Exit For Loop 179 END 180 181 # If the given IP address is not configured, return. 182 # Otherwise, delete the IP and object. 183 184 Run Keyword And Return If '${ip_addr}' != '${ip_addr1}' 185 ... Pass Execution IP address to be deleted is not configured. 186 187 Run Keyword And Ignore Error OpenBMC Delete Request ${ip_uri} 188 189 # After any modification on network interface, BMC restarts network 190 # module, wait until it is reachable. Then wait 15 seconds for new 191 # configuration to be updated on BMC. 192 193 Wait For Host To Ping ${OPENBMC_HOST} ${NETWORK_TIMEOUT} 194 ... ${NETWORK_RETRY_TIME} 195 Sleep 15s 196 197 # Verify whether deleted IP address is removed from BMC system. 198 199 ${ip_data}= Get BMC IP Info 200 Should Not Contain Match ${ip_data} ${ip_addr}* 201 ... msg=IP address not deleted. 202 203Get First Non Pingable IP From Subnet 204 [Documentation] Find first non-pingable IP from the subnet and return it. 205 [Arguments] ${host}=${OPENBMC_HOST} 206 207 # Description of argument(s): 208 # host Any valid host name or IP address 209 # (e.g. "machine1" or "9.xx.xx.31"). 210 211 # Non-pingable IP is unused IP address in the subnet. 212 ${host_name} ${ip_addr}= Get Host Name IP 213 214 # Split IP address into network part and host part. 215 # IP address will have 4 octets xx.xx.xx.xx. 216 # Sample output after split: 217 # split_ip [xx.xx.xx, xx] 218 219 ${split_ip}= Split String From Right ${ip_addr} . 1 220 # First element in list is Network part. 221 ${network_part}= Get From List ${split_ip} 0 222 223 FOR ${octet4} IN RANGE 1 255 224 ${new_ip}= Catenate ${network_part}.${octet4} 225 ${status}= Run Keyword And Return Status Ping Host ${new_ip} 226 # If IP is non-pingable, return it. 227 Return From Keyword If '${status}' == 'False' ${new_ip} 228 END 229 230 Fail msg=No non-pingable IP could be found in subnet ${network_part}. 231 232 233Validate MAC On BMC 234 [Documentation] Validate MAC on BMC. 235 [Arguments] ${mac_addr} 236 237 # Description of argument(s): 238 # mac_addr MAC address of the BMC. 239 240 ${system_mac}= Get BMC MAC Address 241 242 ${status}= Compare MAC Address ${system_mac} ${mac_addr} 243 Should Be True ${status} 244 ... msg=MAC address ${system_mac} does not match ${mac_addr}. 245 246 247Run Build Net 248 [Documentation] Run build_net to preconfigure the ethernet interfaces. 249 250 OS Execute Command build_net help y y 251 # Run pingum to check if the "build_net" was run correctly done. 252 ${output} ${stderr} ${rc}= OS Execute Command pingum 253 Should Contain ${output} All networks ping Ok 254 255 256Configure Hostname 257 [Documentation] Configure hostname on BMC via Redfish. 258 [Arguments] ${hostname} 259 260 # Description of argument(s): 261 # hostname A hostname value which is to be configured on BMC. 262 263 ${data}= Create Dictionary HostName=${hostname} 264 Redfish.patch ${REDFISH_NW_PROTOCOL_URI} body=&{data} 265 ... valid_status_codes=[${HTTP_OK}, ${HTTP_NO_CONTENT}] 266 267 268Verify IP On BMC 269 [Documentation] Verify IP on BMC. 270 [Arguments] ${ip} 271 272 # Description of argument(s): 273 # ip IP address to be verified (e.g. "10.7.7.7"). 274 275 # Get IP address details on BMC using IP command. 276 @{ip_data}= Get BMC IP Info 277 Should Contain Match ${ip_data} ${ip}/* 278 ... msg=IP address does not exist. 279 280 281Verify Gateway On BMC 282 [Documentation] Verify gateway on BMC. 283 [Arguments] ${gateway_ip}=0.0.0.0 284 285 # Description of argument(s): 286 # gateway_ip Gateway IP address. 287 288 ${route_info}= Get BMC Route Info 289 290 # If gateway IP is empty or 0.0.0.0 it will not have route entry. 291 292 Run Keyword If '${gateway_ip}' == '0.0.0.0' 293 ... Pass Execution Gateway IP is "0.0.0.0". 294 ... ELSE 295 ... Should Contain ${route_info} ${gateway_ip} 296 ... msg=Gateway IP address not matching. 297 298 299Get BMC DNS Info 300 [Documentation] Get system DNS info. 301 302 303 # Sample output of "resolv.conf": 304 # ### Generated manually via dbus settings ### 305 # nameserver 8.8.8.8 306 307 ${cmd_output} ${stderr} ${rc}= BMC Execute Command 308 ... cat /etc/resolv.conf 309 310 [Return] ${cmd_output} 311 312 313CLI Get Nameservers 314 [Documentation] Get the nameserver IPs from /etc/resolv.conf and return as a list. 315 316 # Example of /etc/resolv.conf data: 317 # nameserver x.x.x.x 318 # nameserver y.y.y.y 319 320 ${stdout} ${stderr} ${rc}= BMC Execute Command egrep nameserver /etc/resolv.conf | cut -f2- -d ' ' 321 ${nameservers}= Split String ${stdout} 322 323 [Return] ${nameservers} 324 325 326Get Network Configuration 327 [Documentation] Get network configuration. 328 # Sample output: 329 #{ 330 # "@odata.context": "/redfish/v1/$metadata#EthernetInterface.EthernetInterface", 331 # "@odata.id": "/redfish/v1/Managers/bmc/EthernetInterfaces/eth0", 332 # "@odata.type": "#EthernetInterface.v1_2_0.EthernetInterface", 333 # "Description": "Management Network Interface", 334 # "IPv4Addresses": [ 335 # { 336 # "Address": "169.254.xx.xx", 337 # "AddressOrigin": "IPv4LinkLocal", 338 # "Gateway": "0.0.0.0", 339 # "SubnetMask": "255.255.0.0" 340 # }, 341 # { 342 # "Address": "xx.xx.xx.xx", 343 # "AddressOrigin": "Static", 344 # "Gateway": "xx.xx.xx.1", 345 # "SubnetMask": "xx.xx.xx.xx" 346 # } 347 # ], 348 # "Id": "eth0", 349 # "MACAddress": "xx:xx:xx:xx:xx:xx", 350 # "Name": "Manager Ethernet Interface", 351 # "SpeedMbps": 0, 352 # "VLAN": { 353 # "VLANEnable": false, 354 # "VLANId": 0 355 # } 356 ${active_channel_config}= Get Active Channel Config 357 ${resp}= Redfish.Get ${REDFISH_NW_ETH_IFACE}/${active_channel_config['${CHANNEL_NUMBER}']['name']} 358 @{network_configurations}= Get From Dictionary ${resp.dict} IPv4StaticAddresses 359 [Return] @{network_configurations} 360 361 362Add IP Address 363 [Documentation] Add IP Address To BMC. 364 [Arguments] ${ip} ${subnet_mask} ${gateway} 365 ... ${valid_status_codes}=${HTTP_OK} 366 367 # Description of argument(s): 368 # ip IP address to be added (e.g. "10.7.7.7"). 369 # subnet_mask Subnet mask for the IP to be added 370 # (e.g. "255.255.0.0"). 371 # gateway Gateway for the IP to be added (e.g. "10.7.7.1"). 372 # valid_status_codes Expected return code from patch operation 373 # (e.g. "200"). See prolog of rest_request 374 # method in redfish_plus.py for details. 375 376 ${empty_dict}= Create Dictionary 377 ${ip_data}= Create Dictionary Address=${ip} 378 ... SubnetMask=${subnet_mask} Gateway=${gateway} 379 380 ${patch_list}= Create List 381 ${network_configurations}= Get Network Configuration 382 ${num_entries}= Get Length ${network_configurations} 383 384 FOR ${INDEX} IN RANGE 0 ${num_entries} 385 Append To List ${patch_list} ${empty_dict} 386 END 387 388 # We need not check for existence of IP on BMC while adding. 389 Append To List ${patch_list} ${ip_data} 390 ${data}= Create Dictionary IPv4StaticAddresses=${patch_list} 391 392 Redfish.patch ${REDFISH_NW_ETH0_URI} body=&{data} 393 ... valid_status_codes=[${valid_status_codes}] 394 395 Return From Keyword If '${valid_status_codes}' != '${HTTP_OK}' 396 397 # Note: Network restart takes around 15-18s after patch request processing. 398 Sleep ${NETWORK_TIMEOUT}s 399 Wait For Host To Ping ${OPENBMC_HOST} ${NETWORK_TIMEOUT} 400 401 Verify IP On BMC ${ip} 402 Validate Network Config On BMC 403 404 405Delete IP Address 406 [Documentation] Delete IP Address Of BMC. 407 [Arguments] ${ip} ${valid_status_codes}=${HTTP_OK} 408 409 # Description of argument(s): 410 # ip IP address to be deleted (e.g. "10.7.7.7"). 411 # valid_status_codes Expected return code from patch operation 412 # (e.g. "200"). See prolog of rest_request 413 # method in redfish_plus.py for details. 414 415 ${empty_dict}= Create Dictionary 416 ${patch_list}= Create List 417 418 @{network_configurations}= Get Network Configuration 419 FOR ${network_configuration} IN @{network_configurations} 420 Run Keyword If '${network_configuration['Address']}' == '${ip}' 421 ... Append To List ${patch_list} ${null} 422 ... ELSE Append To List ${patch_list} ${empty_dict} 423 END 424 425 ${ip_found}= Run Keyword And Return Status List Should Contain Value 426 ... ${patch_list} ${null} msg=${ip} does not exist on BMC 427 Pass Execution If ${ip_found} == ${False} ${ip} does not exist on BMC 428 429 # Run patch command only if given IP is found on BMC 430 ${data}= Create Dictionary IPv4StaticAddresses=${patch_list} 431 432 Redfish.patch ${REDFISH_NW_ETH0_URI} body=&{data} 433 ... valid_status_codes=[${valid_status_codes}] 434 435 # Note: Network restart takes around 15-18s after patch request processing 436 Sleep ${NETWORK_TIMEOUT}s 437 Wait For Host To Ping ${OPENBMC_HOST} ${NETWORK_TIMEOUT} 438 439 ${delete_status}= Run Keyword And Return Status Verify IP On BMC ${ip} 440 Run Keyword If '${valid_status_codes}' == '${HTTP_OK}' 441 ... Should Be True '${delete_status}' == '${False}' 442 ... ELSE Should Be True '${delete_status}' == '${True}' 443 444 Validate Network Config On BMC 445 446 447Validate Network Config On BMC 448 [Documentation] Check that network info obtained via redfish matches info 449 ... obtained via CLI. 450 451 @{network_configurations}= Get Network Configuration 452 ${ip_data}= Get BMC IP Info 453 FOR ${network_configuration} IN @{network_configurations} 454 Should Contain Match ${ip_data} ${network_configuration['Address']}/* 455 ... msg=IP address does not exist. 456 END 457 458 459Create VLAN 460 [Documentation] Create a VLAN. 461 [Arguments] ${id} ${interface}=eth0 ${expected_result}=valid 462 463 # Description of argument(s): 464 # id The VLAN ID (e.g. '53'). 465 # interface The physical interface for the VLAN(e.g. 'eth0'). 466 # expected_result Expected status of VLAN configuration. 467 468 @{data_vlan_id}= Create List ${interface} ${id} 469 ${data}= Create Dictionary data=@{data_vlan_id} 470 ${resp}= OpenBMC Post Request ${vlan_resource} data=${data} 471 ${resp.status_code}= Convert To String ${resp.status_code} 472 ${status}= Run Keyword And Return Status 473 ... Valid Value resp.status_code ["${HTTP_OK}"] 474 475 Run Keyword If '${expected_result}' == 'error' 476 ... Should Be Equal ${status} ${False} 477 ... msg=Configuration of an invalid VLAN ID Failed. 478 ... ELSE 479 ... Should Be Equal ${status} ${True} 480 ... msg=Configuration of a valid VLAN ID Failed. 481 482 Sleep ${NETWORK_TIMEOUT}s 483 484 485Configure Network Settings On VLAN 486 [Documentation] Configure network settings. 487 [Arguments] ${id} ${ip_addr} ${prefix_len} ${gateway_ip}=${gateway} 488 ... ${expected_result}=valid ${interface}=eth0 489 490 # Description of argument(s): 491 # id The VLAN ID (e.g. '53'). 492 # ip_addr IP address of VLAN Interface. 493 # prefix_len Prefix length of VLAN Interface. 494 # gateway_ip Gateway IP address of VLAN Interface. 495 # expected_result Expected status of network setting configuration. 496 # interface Physical Interface on which the VLAN is defined. 497 498 @{ip_parm_list}= Create List ${network_resource} 499 ... ${ip_addr} ${prefix_len} ${gateway_ip} 500 501 ${data}= Create Dictionary data=@{ip_parm_list} 502 503 Run Keyword And Ignore Error OpenBMC Post Request 504 ... ${NETWORK_MANAGER}${interface}_${id}/action/IP data=${data} 505 506 # After any modification on network interface, BMC restarts network 507 # module, wait until it is reachable. Then wait 15 seconds for new 508 # configuration to be updated on BMC. 509 510 Wait For Host To Ping ${OPENBMC_HOST} ${NETWORK_TIMEOUT} 511 ... ${NETWORK_RETRY_TIME} 512 Sleep ${NETWORK_TIMEOUT}s 513 514 # Verify whether new IP address is populated on BMC system. 515 # It should not allow to configure invalid settings. 516 ${status}= Run Keyword And Return Status 517 ... Verify IP On BMC ${ip_addr} 518 519 Run Keyword If '${expected_result}' == 'error' 520 ... Should Be Equal ${status} ${False} 521 ... msg=Configuration of invalid IP Failed. 522 ... ELSE 523 ... Should Be Equal ${status} ${True} 524 ... msg=Configuration of valid IP Failed. 525 526 527Get BMC Default Gateway 528 [Documentation] Get system default gateway. 529 530 ${route_info}= Get BMC Route Info 531 532 ${lines}= Get Lines Containing String ${route_info} default via 533 @{gateway_list}= Split To Lines ${lines} 534 535 # Extract first default gateway and return. 536 @{default_gw}= Split String ${gateway_list[0]} 537 538 [Return] ${default_gw[2]} 539