a96683b1642fd973b5754694e09c634c4cf231f7
[csit.git] / resources / libraries / python / IPv6Util.py
1 # Copyright (c) 2016 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 """IPv6 utilities library."""
15
16 import re
17 from ssh import SSH
18
19
20 class IPv6Util(object):
21     """IPv6 utilities"""
22
23     def __init__(self):
24         pass
25
26     @staticmethod
27     def ipv6_ping(src_node, dst_addr, count=3, data_size=56, timeout=1):
28         """IPv6 ping.
29
30            Args:
31               src_node (Dict): Node where ping run.
32               dst_addr (str): Destination IPv6 address.
33               count (Optional[int]): Number of echo requests.
34               data_size (Optional[int]): Number of the data bytes.
35               timeout (Optional[int]): Time to wait for a response, in seconds.
36
37            Returns:
38               Number of lost packets.
39         """
40         ssh = SSH()
41         ssh.connect(src_node)
42
43         cmd = "ping6 -c {c} -s {s} -W {W} {dst}".format(c=count, s=data_size,
44                                                         W=timeout,
45                                                         dst=dst_addr)
46         (ret_code, stdout, _) = ssh.exec_command(cmd)
47
48         regex = re.compile(r'(\d+) packets transmitted, (\d+) received')
49         match = regex.search(stdout)
50         sent, received = match.groups()
51         packet_lost = int(sent) - int(received)
52
53         return packet_lost
54
55     @staticmethod
56     def ipv6_ping_port(nodes_ip, src_node, dst_node, port, cnt=3,
57                        size=56, timeout=1):
58         """Send IPv6 ping to the node port.
59
60            Args:
61               nodes_ip (Dict): Nodes IPv6 adresses.
62               src_node (Dict): Node where ping run.
63               dst_node (Dict): Destination node.
64               port (str): Port on the destination node.
65               cnt (Optional[int]): Number of echo requests.
66               size (Optional[int]): Number of the data bytes.
67               timeout (Optional[int]): Time to wait for a response, in seconds.
68
69            Returns:
70               Number of lost packets.
71         """
72         dst_ip = IPv6Util.get_node_port_ipv6_address(dst_node, port, nodes_ip)
73         return IPv6Util.ipv6_ping(src_node, dst_ip, cnt, size, timeout)
74
75     @staticmethod
76     def get_node_port_ipv6_address(node, interface, nodes_addr):
77         """Return IPv6 address of the node port.
78
79            Args:
80                node (Dict): Node in the topology.
81                interface (str): Interface name of the node.
82                nodes_addr (Dict): Nodes IPv6 adresses.
83
84            Returns:
85                IPv6 address string.
86         """
87         for net in nodes_addr.values():
88             for port in net['ports'].values():
89                 host = port.get('node')
90                 dev = port.get('if')
91                 if host == node['host'] and dev == interface:
92                     ip = port.get('addr')
93                     if ip is not None:
94                         return ip
95                     else:
96                         raise Exception(
97                             'Node {n} port {p} IPv6 address is not set'.format(
98                                 n=node['host'], p=interface))
99
100         raise Exception('Node {n} port {p} IPv6 address not found.'.format(
101             n=node['host'], p=interface))