fixing pep8 problems for test verify tox job
[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         u'input': {
37             u'mapping-record': {
38                 u'recordTtl': 60,
39                 u'action': u'NoAction',
40                 u'authoritative': True,
41                 u'eid': {
42                     u'address-type':
43                         u'ietf-lisp-address-types:ipv4-prefix-afi',
44                     u'ipv4-prefix': u'10.0.0.0/32'
45                 },
46                 u'LocatorRecord': [
47                     {
48                         u'locator-id': u'ipv4:172.16.0.0',
49                         u'priority': 1,
50                         u'weight': 1,
51                         u'multicastPriority': 255,
52                         u'multicastWeight': 0,
53                         u'localLocator': True,
54                         u'rlocProbed': False,
55                         u'routed': True,
56                         u'rloc': {
57                             u'address-type':
58                                 u'ietf-lisp-address-types:ipv4-afi',
59                             u'ipv4': u'172.16.0.0'
60                         }
61                     }
62                 ]
63             }
64         }
65     }
66
67     # Template for getting mappings
68     get_mapping_template = {
69         u'input': {
70             u'eid': {
71                 u'ipv4-prefix': u'10.0.0.0'
72             }
73         }
74     }
75
76     def __init__(self, host, port, start_eid, mask, start_rloc, nmappings, v):
77         """
78         Args:
79             :param host: The host running ODL where we want to send the RPCs
80             :param port: The RESTCONF port on the ODL host
81             :param start_eid: The starting EID for adding mappings as an IPv4
82                 literal
83             :param mask: The network mask for the EID prefixes to be added
84             :param start_rloc: The starting RLOC for the locators in the
85                 mappings as an IPv4 literal
86             :param nmappings: The number of mappings to be generated
87             :param v: Version of the ODL instance (since the RPC URL changed
88                 from Lithium to Beryllium
89         """
90         self.session = requests.Session()
91         self.host = host
92         self.port = port
93         self.start_eid = netaddr.IPAddress(start_eid)
94         self.mask = mask
95         self.start_rloc = netaddr.IPAddress(start_rloc)
96         self.nmappings = nmappings
97         if v == "Li" or v == "li":
98             print "Using the Lithium RPC URL"
99             rpc_url = self.RPC_URL_LI
100         else:
101             print "Using the Beryllium and later RPC URL"
102             rpc_url = self.RPC_URL_BE
103
104         self.post_url_template = 'http://' + self.host + ':' \
105             + self.port + '/' + rpc_url
106
107     def mapping_from_tpl(self, eid, mask, rloc):
108         """Create an add-mapping RPC input dictionary from the mapping template
109         Args:
110             :param eid: Replace the default EID in the template with this one
111             :param mask: Replace the default mask in the template with this one
112             :param rloc: Replace the default RLOC in the template with this one
113         Returns:
114             :return dict: mapping - template modified with the arguments
115         """
116         mapping = copy.deepcopy(
117             self.add_mapping_template['input']['mapping-record'])
118         mapping['eid']['ipv4-prefix'] = str(netaddr.IPAddress(eid)) \
119             + '/' + mask
120         mapping['LocatorRecord'][0]['locator-id'] = 'ipv4:' \
121             + str(netaddr.IPAddress(rloc))
122         mapping['LocatorRecord'][0]['rloc']['ipv4'] \
123             = str(netaddr.IPAddress(rloc))
124         return mapping
125
126     def send_rpc(self, session, method, body):
127         """Send an HTTP POST to the RPC URL and return the status code
128         Args:
129             :param session: The HTTP session handle
130             :param method: "add" or "del"ete mapping
131             :param body: the JSON body to be sent
132         Returns:
133             :return int: status_code - HTTP status code
134         """
135         rpc_url = self.post_url_template + method
136         r = session.post(rpc_url, data=body, headers=self.putheaders,
137                          stream=False, auth=('admin', 'admin'),
138                          timeout=self.TIMEOUT)
139         return r.status_code
140
141     def add_n_mappings(self):
142         """Add self.nmappings mappings to ODL"""
143         rpc = dict(self.add_mapping_template)
144         increment = pow(2, 32 - int(self.mask))
145         for i in range(self.nmappings):
146             rpc['input']['mapping-record'] = self.mapping_from_tpl(
147                 self.start_eid + i * increment, self.mask,
148                 self.start_rloc + i)
149             rpc_json = json.dumps(rpc)
150             self.send_rpc(self.session, 'add-mapping', rpc_json)
151         self.session.close()
152
153     def get_n_mappings(self):
154         """Retrieve self.nmappings mappings from ODL
155         """
156         rpc = dict(self.get_mapping_template)
157         increment = pow(2, 32 - int(self.mask))
158         for i in range(self.nmappings):
159             eid = self.start_eid + i * increment
160             rpc['input']['eid']['ipv4-prefix'] = str(netaddr.IPAddress(eid)) \
161                 + '/' + self.mask
162             rpc_json = json.dumps(rpc)
163             self.send_rpc(self.session, 'get-mapping', rpc_json)
164         self.session.close()
165
166
167 if __name__ == "__main__":
168     parser = argparse.ArgumentParser(description='Add simple IPv4 \
169         prefix-to-IPv4 locator LISP mappings to OpenDaylight')
170
171     parser.add_argument('--mode', default='add',
172                         help='Operating mode, can be "add" or "get" \
173                             (default is "add")')
174     parser.add_argument('--host', default='127.0.0.1',
175                         help='Host where ODL controller is running (default \
176                             is 127.0.0.1)')
177     parser.add_argument('--port', default='8181',
178                         help='Port on which ODL\'s RESTCONF is listening \
179                             (default is 8181)')
180     parser.add_argument('--start-eid', default='10.0.0.0',
181                         help='Start incrementing EID from this address \
182                             (default is 10.0.0.0)')
183     parser.add_argument('--mask', default='32',
184                         help='Network mask for the IPv4 EID prefixes \
185                             (default is 32)')
186     parser.add_argument('--start-rloc', default='172.16.0.0',
187                         help='Start incrementing RLOC from this address \
188                             (default is 172.16.0.0, ignored for "get")')
189     parser.add_argument('--mappings', type=int, default=1,
190                         help='Number of mappings to add/get (default 1)')
191     parser.add_argument('--odl-version', default='Be',
192                         help='OpenDaylight version, can be "Li" or "Be" \
193                             (default is "Be")')
194
195     in_args = parser.parse_args()
196
197     mapping_rpc_blaster = MappingRPCBlaster(in_args.host, in_args.port,
198                                             in_args.start_eid, in_args.mask,
199                                             in_args.start_rloc,
200                                             in_args.mappings,
201                                             in_args.odl_version)
202
203     if in_args.mode == "add":
204         mapping_rpc_blaster.add_n_mappings()
205     elif in_args.mode == "get":
206         mapping_rpc_blaster.get_n_mappings()
207     else:
208         print "Unsupported mode:", in_args.mode