CSIT-523 HC Test: routing
[csit.git] / resources / libraries / python / honeycomb / Routing.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 """This module implements keywords to manipulate routing tables using
15 Honeycomb REST API."""
16
17 from robot.api import logger
18
19 from resources.libraries.python.HTTPRequest import HTTPCodes
20 from resources.libraries.python.honeycomb.HoneycombSetup import HoneycombError
21 from resources.libraries.python.honeycomb.HoneycombUtil \
22     import HoneycombUtil as HcUtil
23 from resources.libraries.python.honeycomb.HoneycombUtil \
24     import DataRepresentation
25 from resources.libraries.python.VatExecutor import VatTerminal
26
27
28 class RoutingKeywords(object):
29     """Implementation of keywords which make it possible to:
30     - add/remove routing tables,
31     - add/remove routing table entries
32     - get operational data about routing tables,
33     """
34
35     def __init__(self):
36         pass
37
38     @staticmethod
39     def _set_routing_table_properties(node, path, data=None):
40         """Set routing table properties and check the return code.
41
42         :param node: Honeycomb node.
43         :param path: Path which is added to the base path to identify the data.
44         :param data: The new data to be set. If None, the item will be removed.
45         :type node: dict
46         :type path: str
47         :type data: dict
48         :return: Content of response.
49         :rtype: bytearray
50         :raises HoneycombError: If the status code in response is not
51         200 = OK.
52         """
53
54         if data:
55             status_code, resp = HcUtil.\
56                 put_honeycomb_data(node, "config_routing_table", data, path,
57                                    data_representation=DataRepresentation.JSON)
58         else:
59             status_code, resp = HcUtil.\
60                 delete_honeycomb_data(node, "config_routing_table", path)
61
62         if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
63             if data is None and '"error-tag":"data-missing"' in resp:
64                 logger.debug("data does not exist in path.")
65             else:
66                 raise HoneycombError(
67                     "The configuration of routing table was not successful. "
68                     "Status code: {0}.".format(status_code))
69         return resp
70
71     @staticmethod
72     def configure_routing_table(node, name, ip_version, data, vrf=1,
73                                 special=False):
74         """Configure a routing table according to the data provided.
75
76         :param node: Honeycomb node.
77         :param name: Name for the table.
78         :param ip_version: IP protocol version, ipv4 or ipv6.
79         :param data: Route configuration that should be set.
80         :param vrf: vrf-id to attach configuration to.
81         :param special: Must be True if the configuration is a special route.
82         :type node: dict
83         :type name: str
84         :type ip_version: str
85         :type data: dict
86         :type vrf: int
87         :type special: bool
88         :returns: Content of response.
89         :rtype: bytearray
90         """
91         if special:
92             ip_version = "hc2vpp-ietf-{0}-unicast-routing:{0}".format(
93                 ip_version)
94             protocol = "vpp-routing-ra:vpp-protocol-attributes"
95         else:
96             ip_version = ip_version
97             protocol = "vpp-protocol-attributes"
98
99         full_data = {
100             "routing-protocol": [
101                 {
102                     "name": name,
103                     "description": "hc2vpp-csit test route",
104                     "enabled": "true",
105                     "type": "static",
106                     protocol: {
107                         "primary-vrf": vrf
108                     },
109                     "static-routes": {
110                         ip_version: {
111                             "route": data
112                         }
113                     }
114                 }
115             ]
116         }
117
118         path = "/routing-protocol/{0}".format(name)
119         return RoutingKeywords._set_routing_table_properties(
120             node, path, full_data)
121
122     @staticmethod
123     def delete_routing_table(node, name):
124         """Delete the specified routing table from configuration data.
125
126         :param node: Honeycomb node.
127         :param name: Name of the table.
128         :type node: dict
129         :type name: str
130         :returns: Content of response.
131         :rtype: bytearray
132         """
133
134         path = "/routing-protocol/{0}".format(name)
135         return RoutingKeywords._set_routing_table_properties(node, path)
136
137     @staticmethod
138     def get_routing_table_oper(node, name, ip_version):
139         """Retrieve operational data about the specified routing table.
140
141         :param node: Honeycomb node.
142         :param name: Name of the routing table.
143         :param ip_version: IP protocol version, ipv4 or ipv6.
144         :type node: dict
145         :type name: str
146         :type ip_version: str
147         :returns: Routing table operational data.
148         :rtype: list
149         :raises HoneycombError: If the operation fails.
150         """
151
152         path = "/routing-protocol/{0}".format(name)
153         status_code, resp = HcUtil.\
154             get_honeycomb_data(node, "oper_routing_table", path)
155
156         if status_code != HTTPCodes.OK:
157             raise HoneycombError(
158                 "Not possible to get operational information about the "
159                 "classify tables. Status code: {0}.".format(status_code))
160
161         data = RoutingKeywords.clean_routing_oper_data(
162             resp['routing-protocol'][0]['static-routes']
163             ['hc2vpp-ietf-{0}-unicast-routing:{0}'.format(ip_version)]['route'])
164
165         return data
166
167     @staticmethod
168     def clean_routing_oper_data(data):
169         """Prepare received routing operational data to be verified against
170          expected data.
171
172         :param data: Routing operational data.
173         :type data: list
174         :returns: Routing operational data without entry ID numbers.
175         :rtype: list
176         """
177
178         for item in data:
179             # ID values are auto-incremented based on existing routes in VPP
180             item.pop("id", None)
181             if "next-hop-list" in item.keys():
182                 for item2 in item["next-hop-list"]["next-hop"]:
183                     item2.pop("id", None)
184
185             if "next-hop-list" in item.keys():
186                 # List items come in random order
187                 item["next-hop-list"]["next-hop"].sort()
188
189         return data
190
191     @staticmethod
192     def log_routing_configuration(node):
193         """Retrieve route configuration using VAT and print the response
194          to robot log.
195
196          :param node: VPP node.
197          :type node: dict
198          """
199
200         with VatTerminal(node) as vat:
201             vat.vat_terminal_exec_cmd("ip_fib_dump")