Modification on SFC test Cases
[integration/test.git] / csit / libraries / JsonGenerator.py
1 import json
2 import pyangbind.lib.pybindJSON as pbJ
3 import sys
4 import os
5 # Bindings must present in ${WORKSPACE}
6 workspace = os.environ['WORKSPACE'] + '/odl-lispflowmapping-yang-files'
7
8 """Helper Functions """
9
10
11 def Clean_JSON(string_dump):
12     """ Description: clean the pyangbind generated object
13         Return: python dictionary
14         Params:
15          string_dump: string representation of pyangbind generated dictionary
16     """
17     string_dump = string_dump.replace("odl-mappingservice:", "")
18     string_dump = string_dump.replace("laddr:", "ietf-lisp-address-types:")
19     dict_obj = clean_hops(json.loads(string_dump))
20     return dict_obj
21
22
23 def Merge(first, second):
24     """ Description: merge two python dictionaries
25         Return: python dictionary
26         Params:
27          first: python dictionary
28          second: python dictionary
29     """
30     first.update(second)
31     return first
32
33
34 def Wrap_input(dict_obj):
35     """ Description: Wrap input to python dictionary
36         Return: python dictionary
37         Params:
38          dict_obj: python dictionary
39     """
40     out_dump = {"input": dict_obj}
41     return out_dump
42
43
44 def Merge_And_Wrap_input(first, second):
45     """ Description: Merge two python dictionaries and wrap input
46         Return: python dictionary
47         Params:
48          first: python dictionary
49          second: python dictionary
50     """
51     return Wrap_input(Merge(first, second))
52
53
54 def copy_eid(objA, objB):
55     """ Description: Copy value of attributes from one eid object to other
56         Return: None
57         Params:
58          objA: eid object of pyangbind generated class
59          objB: eid object of pyangbind generated class
60     """
61     for name in dir(objB):
62         if name[:4] == '_eid':
63             value = getattr(objB, name)
64             try:
65                 setattr(objA, name, value)
66             except AttributeError:
67                 print name, "giving attribute error in", objA
68
69
70 def copy_rloc(objA, objB):
71     """ Description: Copy value of attributes from one rloc object to other
72         Returns: None
73         Params:
74          objA: rloc object of pyangbind generated class
75          objB: rloc object of pyangbind generated class
76     """
77     for name in dir(objB):
78         if name[:5] == '_rloc':
79             value = getattr(objB, name)
80             try:
81                 setattr(objA, name, value)
82             except AttributeError:
83                 print name, "giving attribute error in", objA
84
85
86 def clean_hops(obj):
87     """ Description: Clean hop-ids and lrs-bits
88         Returns: python dictionary
89         Params:
90          obj: python dictionary for pyangbind generated object
91     """
92     new_obj = {}
93     for key, value in obj.items():
94         if key == 'hop':
95             for hop in value:
96                 values = hop['hop-id'].split(' ')
97                 hop['hop-id'] = values[0] + " " + values[1]
98                 if values[2] != '':
99                     hop['lrs-bits'] = ' '.join(values[2:])[:-1]
100                 new_obj[key] = value
101         if isinstance(value, dict):
102             new_obj[key] = clean_hops(value)
103         elif isinstance(value, list):
104             if len(value) > 0 and isinstance(value[0], dict):
105                 cur_items = []
106                 for items in value:
107                     cur_items.append(clean_hops(items))
108                 new_obj[key] = cur_items
109             else:
110                 new_obj[key] = value
111         else:
112             new_obj[key] = value
113     return new_obj
114
115
116 """Generator Functions"""
117
118
119 def Get_LispAddress_Object(eid_string, vni=None, laddr_obj=None):
120     """ Description: Returns lisp address object from pyangbind generated classes.
121         Returns: lisp address object
122         Params:
123          eid_string: type of lisp address
124          vni: virtual network id
125          laddr_obj: lisp address object
126     """
127     if laddr_obj is None:
128         sys.path.insert(0, workspace)
129         from LISPFlowMappingYANGBindings.odl_mappingservice_rpc.add_mapping.input import input
130         rpc_input = input()
131         laddr_obj = rpc_input.mapping_record.eid
132
133     if vni:
134         laddr_obj.virtual_network_id = vni
135
136     eid_string = eid_string.split(':')
137     prefix, text = eid_string[0], ':'.join(eid_string[1:])
138     if prefix:
139         if prefix == 'srcdst':
140             # Example: srcdst:192.0.2.1/32|192.0.2.2/32
141             laddr_obj.address_type = 'laddr:source-dest-key-lcaf'
142             text = text.split('|')
143             laddr_obj.source_dest_key.source = text[0]
144             laddr_obj.source_dest_key.dest = text[1]
145         elif prefix == 'no':
146             # Example: no:
147             laddr_obj.address_type = 'laddr:no-address-afi'
148         elif prefix == 'ipv4':
149             if '/' in text:
150                 # Case: ipv4-prefix
151                 laddr_obj.address_type = 'laddr:ipv4-prefix-afi'
152                 laddr_obj.ipv4_prefix = text
153             else:
154                 # Case: ipv4
155                 laddr_obj.address_type = 'laddr:ipv4-afi'
156                 laddr_obj.ipv4 = text
157         elif prefix == 'ipv6':
158             if '/' in text:
159                 # Case: ipv6-prefix
160                 laddr_obj.address_type = 'laddr:ipv6-prefix-afi'
161                 laddr_obj.ipv6_prefix = text
162             else:
163                 laddr_obj.address_type = 'laddr:ipv6-afi'
164                 laddr_obj.ipv6 = text
165         elif prefix == 'mac':
166             # Example: mac:00:00:5E:00:53:00
167             laddr_obj.address_type = 'laddr:mac-afi'
168             laddr_obj.mac = text
169         elif prefix == 'dn':
170             # Example: dn:stringAsIs
171             laddr_obj.address_type = 'laddr:distinguished-name-afi'
172             laddr_obj.distinguished_name = text
173         elif prefix == 'as':
174             # Example: as:AS64500
175             laddr_obj.address_type = 'laddr:as-number-afi'
176             laddr_obj.as_number = text
177         elif prefix == 'list':
178             # Example: list:{192.0.2.1,192.0.2.2,2001:db8::1}
179             laddr_obj.address_type = 'laddr:afi-list-lcaf'
180             list_elements = text[1:len(text) - 1].split(',')  # removed start and end braces
181             laddr_obj.afi_list.address_list = list_elements
182         elif prefix == 'appdata':
183             # Example: appdata:192.0.2.1!128!17!80-81!6667-7000
184             laddr_obj.address_type = 'laddr:application-data-lcaf'
185             text = text.split('!')
186             laddr_obj.application_data.address = text[0]
187             laddr_obj.application_data.ip_tos = text[1]
188             laddr_obj.application_data.protocol = text[2]
189             local_ports = text[3].split('-')
190             laddr_obj.application_data.local_port_low = local_ports[0]
191             laddr_obj.application_data.local_port_high = local_ports[1]
192             remote_ports = text[4].split('-')
193             laddr_obj.application_data.remote_port_low = remote_ports[0]
194             laddr_obj.application_data.remote_port_high = remote_ports[1]
195         elif prefix == 'elp':
196             # TODO: BITS_TYPE_for_lps
197             # Example: elp:{192.0.2.1->192.0.2.2|lps->192.0.2.3}
198             laddr_obj.address_type = 'laddr:explicit-locator-path-lcaf'
199             text = text[1:len(text) - 1]
200             text = text.split('->')  # all the hops
201             for i in range(0, len(text)):
202                 cur_hop = text[i].split('|')
203                 address = cur_hop[0]
204                 lrs_bits = ""
205                 hop_id = "Hop " + str(i + 1) + " " + lrs_bits
206                 if len(cur_hop) > 1:
207                     lps = cur_hop[1]
208                     if "l" in lps:
209                         lrs_bits += "lookup "
210                     if "p" in lps:
211                         lrs_bits += "rloc-probe "
212                     if "s" in lps:
213                         lrs_bits += "strict "
214                 laddr_obj.explicit_locator_path.hop.add(hop_id)
215                 laddr_obj.explicit_locator_path.hop[hop_id].address = address
216         elif prefix == 'kv':
217             # Example: kv:192.0.2.1->192.0.2.2
218             laddr_obj.address_type = 'laddr:key-value-address-lcaf'
219             text = text.split('->')
220             laddr_obj.key_value_address.key = text[0]
221             laddr_obj.key_value_address.value = text[1]
222         elif prefix == 'sp':
223             # Example: sp:42(3)
224             laddr_obj.address_type = 'laddr:service-path-lcaf'
225             text = text.split('(')
226             laddr_obj.service_path.service_path_id = text[0]
227             laddr_obj.service_path.service_index = text[1][:-1]
228
229     return laddr_obj
230
231
232 def Get_LispAddress_JSON(eid_string, vni=None):
233     """ Description: Returns lisp address dictionary with eid wrapped
234         Returns: python dictionary
235         Params:
236          eid_string: type of lisp address
237          vni: virtual network id
238     """
239     pbj_dump = pbJ.dumps(Get_LispAddress_Object(eid_string, vni), filter=True, mode="ietf")
240     out_dump = '{"eid":' + pbj_dump + '}'
241     return Clean_JSON(out_dump)
242
243
244 def Get_LispAddress_Noeid_JSON(eid_string, vni=None):
245     """ Description: Returns lisp address dictionary
246         Returns: python dictionary
247         Params:
248          eid_string: type of lisp address
249          vni: virtual network id
250     """
251     out_dump = pbJ.dumps(Get_LispAddress_Object(eid_string, vni), filter=True, mode="ietf")
252     return Clean_JSON(out_dump)
253
254
255 def Get_LispAddress_JSON_And_Wrap_input(eid_string, vni=None):
256     """ Description: Returns lisp address dictionary with eid and input wrapped
257         Returns: python dictionary
258         Params:
259          eid_string: type of lisp address
260          vni: virtual network id
261     """
262     return Wrap_input(Get_LispAddress_JSON(eid_string, vni))
263
264
265 def Get_LocatorRecord_Object(rloc, weights='1/1/255/0', flags=001, loc_id="ISP1"):
266     """ Description: Returns locator record object from pyangbind generated classes
267         Returns: locator record object
268         Params:
269          rloc: eid_string for lisp address object
270          weights: priority/weight/multicastPriority/multicastWeight
271          flags: Three bit parameter in the sequence routed->rlocProbed->routed
272          loc_id: id of locator record object
273     """
274     sys.path.insert(0, workspace)
275     from LISPFlowMappingYANGBindings.odl_mappingservice_rpc.add_mapping.input import input
276     rpc_input = input()
277     lrecord_obj = rpc_input.mapping_record.LocatorRecord
278     # TODO: What should be the locator-id
279     lrecord_obj.add(loc_id)
280     lrecord_ele = weights.split('/')
281     lrecord_obj[loc_id].priority = lrecord_ele[0]
282     lrecord_obj[loc_id].weight = lrecord_ele[1]
283     lrecord_obj[loc_id].multicastPriority = lrecord_ele[2]
284     lrecord_obj[loc_id].multicastWeight = lrecord_ele[3]
285     laddr_obj = lrecord_obj[loc_id].rloc
286     laddr_obj = Get_LispAddress_Object(rloc, laddr_obj=laddr_obj)
287     lrecord_obj[loc_id].localLocator = flags % 10
288     lrecord_obj[loc_id].rlocProbed = (flags / 10) % 10
289     lrecord_obj[loc_id].routed = (flags / 100) % 10
290     return lrecord_obj
291
292
293 def Get_LocatorRecord_JSON(rloc, weights='1/1/255/0', flags=001, loc_id="ISP1"):
294     """ Description: Returns locator record dictionary
295         Returns: python dictionary
296         Params:
297          rloc: eid_string for lisp address object
298          weights: priority/weight/multicastPriority/multicastWeight
299          flags: Three bit parameter in the sequence routed->rlocProbed->routed
300          loc_id: id of locator record object
301     """
302     pbj_dump = pbJ.dumps(Get_LocatorRecord_Object(rloc, weights, flags, loc_id), filter=True, mode="default")
303     pbj_dict = json.loads(pbj_dump)
304     pbj_dict[loc_id]['rloc'] = Get_LispAddress_Noeid_JSON(rloc)
305     out_dump = '{"LocatorRecord":' + str(pbj_dict) + '}'
306     return Clean_JSON(out_dump)
307
308
309 def Get_MappingRecord_Object(eid, locators, ttl=1440, authoritative=True, action='NoAction'):
310     """ Description: Returns mapping record object from pyangbind generated classes.
311         Returns: mapping record object
312         Params:
313          eid: lisp address object
314          locators: list of locator record objects
315          ttl: recordTtl
316          authoritative: authoritative
317          action: action
318     """
319     sys.path.insert(0, workspace)
320     from LISPFlowMappingYANGBindings.odl_mappingservice_rpc.add_mapping.input import input
321     rpc_input = input()
322     mrecord_obj = rpc_input.mapping_record
323     mrecord_obj.recordTtl = ttl
324     mrecord_obj.authoritative = authoritative
325     mrecord_obj.action = action
326     copy_eid(mrecord_obj.eid, eid)
327     idx = 0
328     loc_ids = []
329     for loc in locators:
330         loc_id = loc.keys()[0]
331         loc_obj = loc[loc_id]
332         if loc_id in loc_ids:
333             print "Locator objects should have different keys"
334             break
335         # TODO: Locator-id, currently in the format of loc_id0, loc_id1
336         mrecord_obj.LocatorRecord.add(loc_id)
337         mrecord_loc_obj = mrecord_obj.LocatorRecord[loc_id]
338         mrecord_loc_obj.priority = loc_obj.priority
339         mrecord_loc_obj.weight = loc_obj.weight
340         mrecord_loc_obj.multicastPriority = loc_obj.multicastPriority
341         mrecord_loc_obj.multicastWeight = loc_obj.multicastWeight
342         copy_rloc(mrecord_loc_obj.rloc, loc_obj.rloc)
343         mrecord_loc_obj.localLocator = loc_obj.localLocator
344         mrecord_loc_obj.rlocProbed = loc_obj.rlocProbed
345         mrecord_loc_obj.routed = loc_obj.routed
346         idx += 1
347     return mrecord_obj
348
349
350 def Get_MappingRecord_JSON(eid, locators, ttl=1440, authoritative=True, action='NoAction'):
351     """ Description: Returns mapping record dictionary
352         Returns: python dictionary
353         Params:
354          eid: lisp address object
355          locators: list of locator record objects
356          ttl: recordTtl
357          authoritative: authoritative
358          action: action
359     """
360     pbj_dump = pbJ.dumps(Get_MappingRecord_Object(eid, locators, ttl, authoritative, action), filter=True, mode="ietf")
361     out_dump = '{"mapping-record":' + pbj_dump + '}'
362     return Clean_JSON(out_dump)
363
364
365 def Get_MappingAuthkey_Object(key_string="password", key_type=1):
366     """ Description: Returns mapping auth key object from pyangbind generated classes.
367         Returns: mapping auth key object
368         Params:
369          key_string: key string
370          key_type: key type
371     """
372     sys.path.insert(0, workspace)
373     from LISPFlowMappingYANGBindings.odl_mappingservice_rpc.add_key.input import input as add_key_input
374     rpc_input = add_key_input()
375     authkey_obj = rpc_input.mapping_authkey
376     authkey_obj.key_string = key_string
377     authkey_obj.key_type = key_type
378     return authkey_obj
379
380
381 def Get_MappingAuthkey_JSON(key_string="password", key_type=1):
382     """ Description: Returns mapping auth key dictionary
383         Returns: python dictionary
384         Params:
385          key_string: key string
386          key_type: key type
387     """
388     pbj_dump = pbJ.dumps(Get_MappingAuthkey_Object(key_string, key_type), filter=True, mode="default")
389     out_dump = '{"mapping-authkey":' + pbj_dump + '}'
390     return Clean_JSON(out_dump)