summaryrefslogtreecommitdiff
path: root/tests/topotests/lib/topojson.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/topotests/lib/topojson.py')
-rw-r--r--tests/topotests/lib/topojson.py193
1 files changed, 193 insertions, 0 deletions
diff --git a/tests/topotests/lib/topojson.py b/tests/topotests/lib/topojson.py
new file mode 100644
index 0000000000..4130451d2e
--- /dev/null
+++ b/tests/topotests/lib/topojson.py
@@ -0,0 +1,193 @@
+#
+# 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 collections import OrderedDict
+from json import dumps as json_dumps
+import ipaddr
+import pytest
+
+# 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,
+ load_config_to_router,
+ create_interfaces_cfg,
+ create_static_routes,
+ create_prefix_lists,
+ create_route_maps,
+)
+
+from lib.bgp import create_router_bgp
+
+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))
+
+
+def build_config_from_json(tgen, topo, save_bkup=True):
+ """
+ Reads initial configuraiton from JSON for each router, builds
+ configuration and loads its to router.
+
+ * `tgen`: Topogen object
+ * `topo`: json file data
+ """
+
+ func_dict = OrderedDict([
+ ("links", create_interfaces_cfg),
+ ("static_routes", create_static_routes),
+ ("prefix_lists", create_prefix_lists),
+ ("route_maps", create_route_maps),
+ ("bgp", create_router_bgp)
+ ])
+
+ data = topo["routers"]
+ for func_type in func_dict.keys():
+ logger.info('Building configuration for {}'.format(func_type))
+
+ func_dict.get(func_type)(tgen, data, build=True)
+
+ for router in sorted(topo['routers'].keys()):
+ logger.info('Configuring router {}...'.format(router))
+
+ result = load_config_to_router(tgen, router, save_bkup)
+ if not result:
+ logger.info("Failed while configuring {}".format(router))
+ pytest.exit(1)
+