diff options
author | Ashish Pant <ashish12pant@gmail.com> | 2019-06-24 13:04:36 +0200 |
---|---|---|
committer | Ashish Pant <ashish12pant@gmail.com> | 2019-07-09 06:56:53 +0200 |
commit | 2ad3d000f0a71d960610ada0d25afa9c0e5d19c9 (patch) | |
tree | 7e26934f07222fd5dd834da4ee18d615c6d65f8a /tests | |
parent | Merge pull request #4654 from manuhalo/fix_bgp_lbp_warn (diff) | |
download | frr-2ad3d000f0a71d960610ada0d25afa9c0e5d19c9.tar.xz frr-2ad3d000f0a71d960610ada0d25afa9c0e5d19c9.zip |
tests: Intial commit for topojson
Signed-off-by: Ashish Pant <ashish12pant@gmail.com>
Adding JSON parser for creating router and assinging ip addresses to
each interface
Diffstat (limited to 'tests')
-rw-r--r-- | tests/topotests/lib/common_config.py | 37 | ||||
-rw-r--r-- | tests/topotests/lib/topojson.py | 151 |
2 files changed, 188 insertions, 0 deletions
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py new file mode 100644 index 000000000..ecd4c0e4b --- /dev/null +++ b/tests/topotests/lib/common_config.py @@ -0,0 +1,37 @@ +# +# Copyright (c) 2019 by VMware, Inc. ("VMware") +# Used Copyright (c) 2018 by Network Device Education Foundation, Inc. +# ("NetDEF") in this file. +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + + +def number_to_row(routerName): + """ + Returns the number for the router. + Calculation based on name a0 = row 0, a1 = row 1, b2 = row 2, z23 = row 23 + etc + """ + return int(routerName[1:]) + + +def number_to_column(routerName): + """ + Returns the number for the router. + Calculation based on name a0 = columnn 0, a1 = column 0, b2= column 1, + z23 = column 26 etc + """ + return ord(routerName[0]) - 97
\ No newline at end of file diff --git a/tests/topotests/lib/topojson.py b/tests/topotests/lib/topojson.py new file mode 100644 index 000000000..b76fb6106 --- /dev/null +++ b/tests/topotests/lib/topojson.py @@ -0,0 +1,151 @@ +# +# Modified work Copyright (c) 2019 by VMware, Inc. ("VMware") +# Original work Copyright (c) 2018 by Network Device Education +# Foundation, Inc. ("NetDEF") +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + + +from json import dumps as json_dumps +import ipaddr + +# Import topogen and topotest helpers +from lib.topolog import logger + +# Required to instantiate the topology builder class. +from lib.common_config import (number_to_row, number_to_column) + + +def build_topo_from_json(tgen, topo): + """ + Reads configuration from JSON file. Adds routers, creates interface + names dynamically and link routers as defined in JSON to create + topology. Assigns IPs dynamically to all interfaces of each router. + + * `tgen`: Topogen object + * `topo`: json file data + """ + + listRouters = [] + for routerN in sorted(topo['routers'].iteritems()): + logger.info('Topo: Add router {}'.format(routerN[0])) + tgen.add_router(routerN[0]) + listRouters.append(routerN[0]) + + listRouters.sort() + if 'ipv4base' in topo: + ipv4Next = ipaddr.IPv4Address(topo['link_ip_start']['ipv4']) + ipv4Step = 2 ** (32 - topo['link_ip_start']['v4mask']) + if topo['link_ip_start']['v4mask'] < 32: + ipv4Next += 1 + if 'ipv6base' in topo: + ipv6Next = ipaddr.IPv6Address(topo['link_ip_start']['ipv6']) + ipv6Step = 2 ** (128 - topo['link_ip_start']['v6mask']) + if topo['link_ip_start']['v6mask'] < 127: + ipv6Next += 1 + for router in listRouters: + topo['routers'][router]['nextIfname'] = 0 + + while listRouters != []: + curRouter = listRouters.pop(0) + # Physical Interfaces + if 'links' in topo['routers'][curRouter]: + def link_sort(x): + if x == 'lo': + return 0 + elif 'link' in x: + return int(x.split('-link')[1]) + else: + return int(x.split('r')[1]) + for destRouterLink, data in sorted(topo['routers'][curRouter]['links']. \ + iteritems(), + key=lambda x: link_sort(x[0])): + currRouter_lo_json = \ + topo['routers'][curRouter]['links'][destRouterLink] + # Loopback interfaces + if 'type' in data and data['type'] == 'loopback': + if 'ipv4' in currRouter_lo_json and \ + currRouter_lo_json['ipv4'] == 'auto': + currRouter_lo_json['ipv4'] = '{}{}.{}/{}'. \ + format(topo['lo_prefix']['ipv4'], number_to_row(curRouter), \ + number_to_column(curRouter), topo['lo_prefix']['v4mask']) + if 'ipv6' in currRouter_lo_json and \ + currRouter_lo_json['ipv6'] == 'auto': + currRouter_lo_json['ipv6'] = '{}{}:{}/{}'. \ + format(topo['lo_prefix']['ipv6'], number_to_row(curRouter), \ + number_to_column(curRouter), topo['lo_prefix']['v6mask']) + + if "-" in destRouterLink: + # Spliting and storing destRouterLink data in tempList + tempList = destRouterLink.split("-") + + # destRouter + destRouter = tempList.pop(0) + + # Current Router Link + tempList.insert(0, curRouter) + curRouterLink = "-".join(tempList) + else: + destRouter = destRouterLink + curRouterLink = curRouter + + if destRouter in listRouters: + currRouter_link_json = \ + topo['routers'][curRouter]['links'][destRouterLink] + destRouter_link_json = \ + topo['routers'][destRouter]['links'][curRouterLink] + + # Assigning name to interfaces + currRouter_link_json['interface'] = \ + '{}-{}-eth{}'.format(curRouter, destRouter, topo['routers'] \ + [curRouter]['nextIfname']) + destRouter_link_json['interface'] = \ + '{}-{}-eth{}'.format(destRouter, curRouter, topo['routers'] \ + [destRouter]['nextIfname']) + + topo['routers'][curRouter]['nextIfname'] += 1 + topo['routers'][destRouter]['nextIfname'] += 1 + + # Linking routers to each other as defined in JSON file + tgen.gears[curRouter].add_link(tgen.gears[destRouter], + topo['routers'][curRouter]['links'][destRouterLink] \ + ['interface'], topo['routers'][destRouter]['links'] \ + [curRouterLink]['interface']) + + # IPv4 + if 'ipv4' in currRouter_link_json: + if currRouter_link_json['ipv4'] == 'auto': + currRouter_link_json['ipv4'] = \ + '{}/{}'.format(ipv4Next, topo['link_ip_start'][ \ + 'v4mask']) + destRouter_link_json['ipv4'] = \ + '{}/{}'.format(ipv4Next + 1, topo['link_ip_start'][ \ + 'v4mask']) + ipv4Next += ipv4Step + # IPv6 + if 'ipv6' in currRouter_link_json: + if currRouter_link_json['ipv6'] == 'auto': + currRouter_link_json['ipv6'] = \ + '{}/{}'.format(ipv6Next, topo['link_ip_start'][ \ + 'v6mask']) + destRouter_link_json['ipv6'] = \ + '{}/{}'.format(ipv6Next + 1, topo['link_ip_start'][ \ + 'v6mask']) + ipv6Next = ipaddr.IPv6Address(int(ipv6Next) + ipv6Step) + + logger.debug("Generated link data for router: %s\n%s", curRouter, + json_dumps(topo["routers"][curRouter]["links"], + indent=4, sort_keys=True) |