Introduce pre-initialize driver layer
[csit.git] / resources / libraries / python / honeycomb / IPv6Management.py
1 # Copyright (c) 2017 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 """Keywords used for setup and testing of Honeycomb's control-plane interface
15 using IPv6.
16 """
17
18 from resources.libraries.python.ssh import SSH
19
20
21 class IPv6Management(object):
22     """Utilities for managing IPv6 contol-plane interfaces."""
23
24     def __init__(self):
25         pass
26
27     @staticmethod
28     def get_interface_name_by_mac(node, mac):
29         """Get the name of an interface using its MAC address.
30
31         :param node: Node in topology.
32         :param mac: MAC address.
33         :type node: dict
34         :type mac: str
35         :returns: Name of the interface.
36         :rtype: str
37         :raises RuntimeError: If no interface is found.
38         """
39
40         cmd = " | ".join([
41             "fgrep -ls '{0}' /sys/class/net/*/address".format(mac),
42             "awk -F '/' '{print $5}'"
43         ])
44
45         ssh = SSH()
46         ssh.connect(node)
47         ret_code, stdout, _ = ssh.exec_command(cmd)
48
49         if ret_code == 0:
50             return stdout.strip()
51         else:
52             raise RuntimeError("No interface found using the specified MAC "
53                                "address.")
54
55     @staticmethod
56     def clear_interface_configuration(node, interface):
57         """Remove all configured IP addresses from the specified interface
58          and set it into down state.
59
60          :param node: Node in topology.
61          :param interface: Name of an interface on the node.
62          :type node: dict
63          :type interface: str
64          :raises RuntimeError: If the configuration could not be cleared.
65          """
66
67         cmd = " && ".join([
68             "sudo ip addr flush dev {interface}".format(interface=interface),
69             "sudo ip link set dev {interface} down".format(interface=interface)
70         ])
71
72         ssh = SSH()
73         ssh.connect(node)
74         ret_code, _, _ = ssh.exec_command(cmd)
75         if ret_code != 0:
76             raise RuntimeError("Could not clear interface configuration.")
77
78     @staticmethod
79     def set_management_interface_address(node, interface, address, prefix):
80         """Configure an IP address on the specified interface.
81
82         :param node: Node in topology.
83         :param interface: Name of an interface on the node.
84         :param address: IP address to configure.
85         :param prefix: IP network prefix.
86         :type node: dict
87         :type interface: str
88         :type address: str
89         :type prefix: int
90         :raises RuntimeError: If the configuration fails.
91         """
92
93         ssh = SSH()
94         ssh.connect(node)
95
96         # Enable IPv6 for only the specified interface
97         cmd = "sudo sysctl net.ipv6.conf.{0}.disable_ipv6=0".format(interface)
98
99         ret_code, _, _ = ssh.exec_command(cmd)
100         if ret_code != 0:
101             raise RuntimeError("Could not enable IPv6 on interface.")
102
103         # Configure IPv6 address on the interface
104         cmd = "sudo ip address add {address}/{prefix} dev {interface}".format(
105             interface=interface,
106             address=address,
107             prefix=prefix)
108
109         ret_code, _, _ = ssh.exec_command(cmd)
110         if ret_code != 0:
111             raise RuntimeError("Could not configure IP address on interface.")
112
113         # Set the interface up
114         cmd = "sudo ip link set {interface} up".format(interface=interface)
115
116         ret_code, _, _ = ssh.exec_command(cmd)
117         if ret_code != 0:
118             raise RuntimeError("Could not change the interface to 'up' state.")
119
120     @staticmethod
121     def configure_control_interface_tunnel(node, src_port, dst_ip, dst_port):
122         """Configure a tunnel on the specified node, tunelling any IPv4 traffic
123         from one port to the specified address.
124
125         :param node: Node in topology.
126         :param src_port: Port to tunnel traffic from.
127         :param dst_ip: IP address to tunnel traffic to.
128         :param dst_port: Port to tunnel traffic to.
129         :type node: dict
130         :type src_port: int
131         :type dst_ip: str
132         :type dst_port: int
133         :raises RuntimeError: If tunnel creation is not successful.
134         """
135
136         cmd = "nohup socat TCP4-LISTEN:{src_port},fork,su=nobody " \
137               "TCP6:[{dst_ip}]:{dst_port} $@ > " \
138               "/tmp/socat.log 2>&1 &".format(
139                   src_port=src_port,
140                   dst_ip=dst_ip,
141                   dst_port=dst_port)
142
143         ssh = SSH()
144         ssh.connect(node)
145         ret_code, _, _ = ssh.exec_command_sudo(cmd)
146         if ret_code != 0:
147             raise RuntimeError("Could not configure tunnel.")