Refactor IPv4 utils
[csit.git] / resources / libraries / python / IPv4Util.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 """Implements IPv4 RobotFramework keywords"""
15
16 from robot.api import logger as log
17 from robot.api.deco import keyword
18
19 from resources.libraries.python.topology import Topology
20 from resources.libraries.python.topology import NodeType
21 from resources.libraries.python.TrafficScriptExecutor\
22     import TrafficScriptExecutor
23 from resources.libraries.python.IPv4Setup import get_node
24
25
26 class IPv4Util(object):
27     """Implements keywords for IPv4 tests."""
28
29     @staticmethod
30     @keyword('From node "${node}" interface "${port}" ARP-ping '
31              'IPv4 address "${ip_address}"')
32     def arp_ping(node, interface, ip_address):
33         log.debug('From node {} interface {} ARP-ping IPv4 address {}'.
34                   format(Topology.get_node_hostname(node),
35                          interface, ip_address))
36         get_node(node).arp_ping(ip_address, interface)
37
38     @staticmethod
39     @keyword('Node "${node}" routes to IPv4 network "${network}" with prefix '
40              'length "${prefix_length}" using interface "${interface}" via '
41              '"${gateway}"')
42     def set_route(node, network, prefix_length, interface, gateway):
43         """See IPv4Node.set_route for more information.
44
45         :param node:
46         :param network:
47         :param prefix_length:
48         :param interface:
49         :param gateway:
50         :return:
51         """
52         log.debug('Node {} routes to network {} with prefix length {} '
53                   'via {} interface {}'.format(Topology.get_node_hostname(node),
54                                                network, prefix_length,
55                                                gateway, interface))
56         get_node(node).set_route(network, int(prefix_length),
57                                  gateway, interface)
58
59     @staticmethod
60     @keyword('After ping is sent in topology "${nodes_info}" from node '
61              '"${src_node}" interface "${src_port}" "${src_ip}" with '
62              'destination IPv4 address "${dst_ip}" of node "${dst_node}" '
63              'interface "${dst_port}" a ping response arrives and TTL is '
64              'decreased by "${hops}"')
65     def send_ping(nodes_info, src_node, src_port, src_ip, dst_ip, dst_node,
66                   dst_port, hops):
67         """Send IPv4 ping and wait for response.
68
69         :param nodes_info: Dictionary containing information on all nodes
70         in topology.
71         :param src_node: Source node.
72         :param src_port: Source interface.
73         :param src_ip: Source ipv4 address.
74         :param dst_ip: Destination ipv4 address.
75         :param dst_node: Destination node.
76         :param dst_port: Destination interface.
77         :param hops: Number of hops between src_node and dst_node.
78         """
79         log.debug('After ping is sent from node "{}" interface "{}" '
80                   'with destination IPv4 address of node "{}" interface "{}" '
81                   'a ping response arrives and TTL is decreased by "${}"'.
82                   format(Topology.get_node_hostname(src_node), src_port,
83                          Topology.get_node_hostname(dst_node), dst_port, hops))
84         dst_mac = None
85         src_mac = Topology.get_interface_mac(src_node, src_port)
86         if dst_node['type'] == NodeType.TG:
87             dst_mac = Topology.get_interface_mac(src_node, src_port)
88         _, adj_int = Topology.\
89             get_adjacent_node_and_interface(nodes_info, src_node, src_port)
90         first_hop_mac = adj_int['mac_address']
91         args = '--src_if "{}" --src_mac "{}" --first_hop_mac "{}" ' \
92                '--src_ip "{}" --dst_ip "{}" --hops "{}"'\
93             .format(src_port, src_mac, first_hop_mac, src_ip, dst_ip, hops)
94         if dst_node['type'] == NodeType.TG:
95             args += ' --dst_if "{}" --dst_mac "{}"'.format(dst_port, dst_mac)
96         TrafficScriptExecutor.run_traffic_script_on_node(
97             "ipv4_ping_ttl_check.py", src_node, args)
98
99     @staticmethod
100     @keyword('Get IPv4 address prefix of node "${node}" interface "${port}" '
101              'from "${nodes_addr}"')
102     def get_ip_addr_prefix_length(node, port, nodes_addr):
103         """ Get IPv4 address prefix for specified interface.
104
105         :param node: Node dictionary.
106         :param port: Interface name.
107         :return: IPv4 prefix length
108         """
109         for net in nodes_addr.values():
110             for p in net['ports'].values():
111                 if p['node'] == node['host'] and p['if'] == port:
112                     return net['prefix']
113
114         raise Exception('Subnet not found for node {n} port {p}'.
115                         format(n=node['host'], p=port))
116
117     @staticmethod
118     @keyword('Get IPv4 subnet of node "${node}" interface "${port}" from '
119              '"${nodes_addr}"')
120     def get_ip_addr_subnet(node, port, nodes_addr):
121         """ Get IPv4 subnet of specified interface.
122
123         :param node: Node dictionary.
124         :param port: Interface name.
125         :return: IPv4 subnet of 'str' type
126         """
127         for net in nodes_addr.values():
128             for p in net['ports'].values():
129                 if p['node'] == node['host'] and p['if'] == port:
130                     return net['net_addr']
131
132         raise Exception('Subnet not found for node {n} port {p}'.
133                         format(n=node['host'], p=port))
134
135     @staticmethod
136     @keyword('Flush IPv4 addresses "${port}" "${node}"')
137     def flush_ip_addresses(port, node):
138         """See IPv4Node.flush_ip_addresses for more information.
139
140         :param port:
141         :param node:
142         :return:
143         """
144         get_node(node).flush_ip_addresses(port)