Migrate Get Requests invocations(libraries)
[integration/test.git] / tools / odl-lispflowmapping-performance-tests / mapping_blaster.py
1 #!/usr/bin/python
2 """
3 Script to add LISP mappings to ODL.  Currently it only supports the
4 RPC interface.  Support for RESTCONF is planned in a future release.
5
6 Use `./mapping_blaster.py --help` to see options
7
8 Code inspired from `flow_config_blaster.py` by Jan Medved
9 """
10
11 import argparse
12 import copy
13 import json
14
15 import netaddr
16 import requests
17
18 __author__ = "Lori Jakab"
19 __copyright__ = "Copyright (c) 2014, Cisco Systems, Inc."
20 __credits__ = ["Jan Medved"]
21 __license__ = "New-style BSD"
22 __email__ = "lojakab@cisco.com"
23 __version__ = "0.0.3"
24
25
26 class MappingRPCBlaster(object):
27     putheaders = {"Content-type": "application/json"}
28     getheaders = {"Accept": "application/json"}
29
30     RPC_URL_LI = "restconf/operations/lfm-mapping-database:"
31     RPC_URL_BE = "restconf/operations/odl-mappingservice:"
32     TIMEOUT = 10
33
34     # Template for adding mappings
35     add_mapping_template = {
36         "input": {
37             "mapping-record": {
38                 "recordTtl": 60,
39                 "action": "NoAction",
40                 "authoritative": True,
41                 "eid": {
42                     "address-type": "ietf-lisp-address-types:ipv4-prefix-afi",
43                     "ipv4-prefix": "10.0.0.0/32",
44                 },
45                 "LocatorRecord": [
46                     {
47                         "locator-id": "ipv4:172.16.0.0",
48                         "priority": 1,
49                         "weight": 1,
50                         "multicastPriority": 255,
51                         "multicastWeight": 0,
52                         "localLocator": True,
53                         "rlocProbed": False,
54                         "routed": True,
55                         "rloc": {
56                             "address-type": "ietf-lisp-address-types:ipv4-afi",
57                             "ipv4": "172.16.0.0",
58                         },
59                     }
60                 ],
61             }
62         }
63     }
64
65     # Template for getting mappings
66     get_mapping_template = {"input": {"eid": {"ipv4-prefix": "10.0.0.0"}}}
67
68     def __init__(self, host, port, start_eid, mask, start_rloc, nmappings, v):
69         """
70         Args:
71             :param host: The host running ODL where we want to send the RPCs
72             :param port: The RESTCONF port on the ODL host
73             :param start_eid: The starting EID for adding mappings as an IPv4
74                 literal
75             :param mask: The network mask for the EID prefixes to be added
76             :param start_rloc: The starting RLOC for the locators in the
77                 mappings as an IPv4 literal
78             :param nmappings: The number of mappings to be generated
79             :param v: Version of the ODL instance (since the RPC URL changed
80                 from Lithium to Beryllium
81         """
82         self.session = requests.Session()
83         self.host = host
84         self.port = port
85         self.start_eid = netaddr.IPAddress(start_eid)
86         self.mask = mask
87         self.start_rloc = netaddr.IPAddress(start_rloc)
88         self.nmappings = nmappings
89         if v == "Li" or v == "li":
90             print("Using the Lithium RPC URL")
91             rpc_url = self.RPC_URL_LI
92         else:
93             print("Using the Beryllium and later RPC URL")
94             rpc_url = self.RPC_URL_BE
95
96         self.post_url_template = "http://" + self.host + ":" + self.port + "/" + rpc_url
97
98     def mapping_from_tpl(self, eid, mask, rloc):
99         """Create an add-mapping RPC input dictionary from the mapping template
100         Args:
101             :param eid: Replace the default EID in the template with this one
102             :param mask: Replace the default mask in the template with this one
103             :param rloc: Replace the default RLOC in the template with this one
104         Returns:
105             :return dict: mapping - template modified with the arguments
106         """
107         mapping = copy.deepcopy(self.add_mapping_template["input"]["mapping-record"])
108         mapping["eid"]["ipv4-prefix"] = str(netaddr.IPAddress(eid)) + "/" + mask
109         mapping["LocatorRecord"][0]["locator-id"] = "ipv4:" + str(
110             netaddr.IPAddress(rloc)
111         )
112         mapping["LocatorRecord"][0]["rloc"]["ipv4"] = str(netaddr.IPAddress(rloc))
113         return mapping
114
115     def send_rpc(self, session, method, body):
116         """Send an HTTP POST to the RPC URL and return the status code
117         Args:
118             :param session: The HTTP session handle
119             :param method: "add" or "del"ete mapping
120             :param body: the JSON body to be sent
121         Returns:
122             :return int: status_code - HTTP status code
123         """
124         rpc_url = self.post_url_template + method
125         r = session.post(
126             rpc_url,
127             data=body,
128             headers=self.putheaders,
129             stream=False,
130             auth=("admin", "admin"),
131             timeout=self.TIMEOUT,
132         )
133         return r.status_code
134
135     def add_n_mappings(self):
136         """Add self.nmappings mappings to ODL"""
137         rpc = dict(self.add_mapping_template)
138         increment = pow(2, 32 - int(self.mask))
139         for i in range(self.nmappings):
140             rpc["input"]["mapping-record"] = self.mapping_from_tpl(
141                 self.start_eid + i * increment, self.mask, self.start_rloc + i
142             )
143             rpc_json = json.dumps(rpc)
144             self.send_rpc(self.session, "add-mapping", rpc_json)
145         self.session.close()
146
147     def get_n_mappings(self):
148         """Retrieve self.nmappings mappings from ODL"""
149         rpc = dict(self.get_mapping_template)
150         increment = pow(2, 32 - int(self.mask))
151         for i in range(self.nmappings):
152             eid = self.start_eid + i * increment
153             rpc["input"]["eid"]["ipv4-prefix"] = (
154                 str(netaddr.IPAddress(eid)) + "/" + self.mask
155             )
156             rpc_json = json.dumps(rpc)
157             self.send_rpc(self.session, "get-mapping", rpc_json)
158         self.session.close()
159
160
161 if __name__ == "__main__":
162     parser = argparse.ArgumentParser(
163         description="Add simple IPv4 \
164         prefix-to-IPv4 locator LISP mappings to OpenDaylight"
165     )
166
167     parser.add_argument(
168         "--mode",
169         default="add",
170         help='Operating mode, can be "add" or "get" \
171                             (default is "add")',
172     )
173     parser.add_argument(
174         "--host",
175         default="127.0.0.1",
176         help="Host where ODL controller is running (default \
177                             is 127.0.0.1)",
178     )
179     parser.add_argument(
180         "--port",
181         default="8181",
182         help="Port on which ODL's RESTCONF is listening \
183                             (default is 8181)",
184     )
185     parser.add_argument(
186         "--start-eid",
187         default="10.0.0.0",
188         help="Start incrementing EID from this address \
189                             (default is 10.0.0.0)",
190     )
191     parser.add_argument(
192         "--mask",
193         default="32",
194         help="Network mask for the IPv4 EID prefixes \
195                             (default is 32)",
196     )
197     parser.add_argument(
198         "--start-rloc",
199         default="172.16.0.0",
200         help='Start incrementing RLOC from this address \
201                             (default is 172.16.0.0, ignored for "get")',
202     )
203     parser.add_argument(
204         "--mappings",
205         type=int,
206         default=1,
207         help="Number of mappings to add/get (default 1)",
208     )
209     parser.add_argument(
210         "--odl-version",
211         default="Be",
212         help='OpenDaylight version, can be "Li" or "Be" \
213                             (default is "Be")',
214     )
215
216     in_args = parser.parse_args()
217
218     mapping_rpc_blaster = MappingRPCBlaster(
219         in_args.host,
220         in_args.port,
221         in_args.start_eid,
222         in_args.mask,
223         in_args.start_rloc,
224         in_args.mappings,
225         in_args.odl_version,
226     )
227
228     if in_args.mode == "add":
229         mapping_rpc_blaster.add_n_mappings()
230     elif in_args.mode == "get":
231         mapping_rpc_blaster.get_n_mappings()
232     else:
233         print("Unsupported mode:", in_args.mode)