X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2FIPUtil.py;h=e215b301b9f3d5311bded06357a16f3aeb5e10c4;hp=f3c037fdf097f1ce791a8c9798f7b7f17eec6523;hb=a95c54b7821596402e0aa7136cd7d1de71a5b187;hpb=74a354349cf13e8874259faec5473b7bbf25d6e5 diff --git a/resources/libraries/python/IPUtil.py b/resources/libraries/python/IPUtil.py index f3c037fdf0..e215b301b9 100644 --- a/resources/libraries/python/IPUtil.py +++ b/resources/libraries/python/IPUtil.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Cisco and/or its affiliates. +# Copyright (c) 2018 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -13,6 +13,8 @@ """Common IP utilities library.""" +import re + from ipaddress import IPv4Network, ip_address from resources.libraries.python.ssh import SSH @@ -24,6 +26,30 @@ from resources.libraries.python.topology import Topology class IPUtil(object): """Common IP utilities""" + @staticmethod + def ip_to_int(ip_str): + """Convert IP address from string format (e.g. 10.0.0.1) to integer + representation (167772161). + + :param ip_str: IP address in string representation. + :type ip_str: str + :returns: Integer representation of IP address. + :rtype: int + """ + return int(ip_address(unicode(ip_str))) + + @staticmethod + def int_to_ip(ip_int): + """Convert IP address from integer representation (e.g. 167772161) to + string format (10.0.0.1). + + :param ip_int: IP address in integer representation. + :type ip_int: int + :returns: String representation of IP address. + :rtype: str + """ + return str(ip_address(ip_int)) + @staticmethod def vpp_ip_probe(node, interface, addr, if_type="key"): """Run ip probe on VPP node. @@ -75,19 +101,19 @@ class IPUtil(object): @staticmethod def setup_network_namespace(node, namespace_name, interface_name, - ip_address, prefix): + ip_addr, prefix): """Setup namespace on given node and attach interface and IP to this namespace. Applicable also on TG node. :param node: Node to set namespace on. :param namespace_name: Namespace name. :param interface_name: Interface name. - :param ip_address: IP address of namespace's interface. + :param ip_addr: IP address of namespace's interface. :param prefix: IP address prefix length. :type node: dict :type namespace_name: str :type vhost_if: str - :type ip_address: str + :type ip_addr: str :type prefix: int """ cmd = ('ip netns add {0}'.format(namespace_name)) @@ -98,7 +124,7 @@ class IPUtil(object): exec_cmd_no_error(node, cmd, sudo=True) cmd = ('ip netns exec {0} ip addr add {1}/{2} dev {3}'.format( - namespace_name, ip_address, prefix, interface_name)) + namespace_name, ip_addr, prefix, interface_name)) exec_cmd_no_error(node, cmd, sudo=True) @staticmethod @@ -114,28 +140,77 @@ class IPUtil(object): exec_cmd_no_error(node, cmd, sudo=True) @staticmethod - def set_linux_interface_ip(node, interface, ip, prefix, namespace=None): + def get_linux_interface_name(node, pci_addr): + """Get the interface name. + + :param node: Node where to execute command. + :param pci_addr: PCI address + :type node: dict + :type pci_addr: str + :returns: Interface name + :rtype: str + :raises RuntimeError: If cannot get the information about interfaces. + """ + + regex_intf_info = r"pci@" \ + r"([0-9a-f]{4}:[0-9a-f]{2}:[0-9a-f]{2}.[0-9a-f])\s*" \ + r"([a-zA-Z0-9]*)\s*network" + + cmd = "lshw -class network -businfo" + ret_code, stdout, stderr = exec_cmd(node, cmd, timeout=30, sudo=True) + if ret_code != 0: + raise RuntimeError('Could not get information about interfaces, ' + 'reason:{0}'.format(stderr)) + + for line in stdout.splitlines()[2:]: + try: + if re.search(regex_intf_info, line).group(1) == pci_addr: + return re.search(regex_intf_info, line).group(2) + except AttributeError: + continue + return None + + @staticmethod + def set_linux_interface_up(node, interface): + """Set the specified interface up. + + :param node: Node where to execute command. + :param interface: Interface in namespace. + :type node: dict + :type interface: str + :raises RuntimeError: If the interface could not be set up. + """ + + cmd = "ip link set {0} up".format(interface) + ret_code, _, stderr = exec_cmd(node, cmd, timeout=30, sudo=True) + if ret_code != 0: + raise RuntimeError('Could not set the interface up, reason:{0}'. + format(stderr)) + + @staticmethod + def set_linux_interface_ip(node, interface, ip_addr, prefix, + namespace=None): """Set IP address to interface in linux. :param node: Node where to execute command. :param interface: Interface in namespace. - :param ip: IP to be set on interface. + :param ip_addr: IP to be set on interface. :param prefix: IP prefix. :param namespace: Execute command in namespace. Optional :type node: dict :type interface: str - :type ip: str + :type ip_addr: str :type prefix: int :type namespace: str :raises RuntimeError: IP could not be set. """ if namespace is not None: cmd = 'ip netns exec {} ip addr add {}/{} dev {}'.format( - namespace, ip, prefix, interface) + namespace, ip_addr, prefix, interface) else: - cmd = 'ip addr add {}/{} dev {}'.format(ip, prefix, interface) - (rc, _, stderr) = exec_cmd(node, cmd, timeout=5, sudo=True) - if rc != 0: + cmd = 'ip addr add {}/{} dev {}'.format(ip_addr, prefix, interface) + (ret_code, _, stderr) = exec_cmd(node, cmd, timeout=5, sudo=True) + if ret_code != 0: raise RuntimeError( 'Could not set IP for interface, reason:{}'.format(stderr)) @@ -166,7 +241,7 @@ def convert_ipv4_netmask_prefix(network): Example: mask 255.255.0.0 -> prefix length 16 :param network: Network mask or network prefix length. :type network: str or int - :return: Network mask or network prefix length. + :returns: Network mask or network prefix length. :rtype: str or int """ temp_address = "0.0.0.0"