]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/lib/topojson.py
Merge pull request #4778 from mjstapp/dplane_macs
[mirror_frr.git] / tests / topotests / lib / topojson.py
CommitLineData
2ad3d000
AP
1#
2# Modified work Copyright (c) 2019 by VMware, Inc. ("VMware")
3# Original work Copyright (c) 2018 by Network Device Education
4# Foundation, Inc. ("NetDEF")
5#
6# Permission to use, copy, modify, and/or distribute this software
7# for any purpose with or without fee is hereby granted, provided
8# that the above copyright notice and this permission notice appear
9# in all copies.
10#
11# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
12# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
14# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
15# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
16# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
17# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
18# OF THIS SOFTWARE.
19#
20
7659b8d4 21from collections import OrderedDict
2ad3d000
AP
22from json import dumps as json_dumps
23import ipaddr
7659b8d4 24import pytest
2ad3d000
AP
25
26# Import topogen and topotest helpers
27from lib.topolog import logger
28
29# Required to instantiate the topology builder class.
7659b8d4
AP
30from lib.common_config import (
31 number_to_row, number_to_column,
32 load_config_to_router,
e4663527 33 create_interfaces_cfg,
00db2a89
AP
34 create_static_routes,
35 create_prefix_lists,
e6db2bb1 36 create_route_maps,
7659b8d4 37)
2ad3d000 38
7fa2079a 39from lib.bgp import create_router_bgp
2ad3d000
AP
40
41def build_topo_from_json(tgen, topo):
42 """
43 Reads configuration from JSON file. Adds routers, creates interface
44 names dynamically and link routers as defined in JSON to create
45 topology. Assigns IPs dynamically to all interfaces of each router.
46
47 * `tgen`: Topogen object
48 * `topo`: json file data
49 """
50
51 listRouters = []
52 for routerN in sorted(topo['routers'].iteritems()):
53 logger.info('Topo: Add router {}'.format(routerN[0]))
54 tgen.add_router(routerN[0])
55 listRouters.append(routerN[0])
56
57 listRouters.sort()
58 if 'ipv4base' in topo:
59 ipv4Next = ipaddr.IPv4Address(topo['link_ip_start']['ipv4'])
60 ipv4Step = 2 ** (32 - topo['link_ip_start']['v4mask'])
61 if topo['link_ip_start']['v4mask'] < 32:
62 ipv4Next += 1
63 if 'ipv6base' in topo:
64 ipv6Next = ipaddr.IPv6Address(topo['link_ip_start']['ipv6'])
65 ipv6Step = 2 ** (128 - topo['link_ip_start']['v6mask'])
66 if topo['link_ip_start']['v6mask'] < 127:
67 ipv6Next += 1
68 for router in listRouters:
69 topo['routers'][router]['nextIfname'] = 0
70
71 while listRouters != []:
72 curRouter = listRouters.pop(0)
73 # Physical Interfaces
74 if 'links' in topo['routers'][curRouter]:
75 def link_sort(x):
76 if x == 'lo':
77 return 0
78 elif 'link' in x:
79 return int(x.split('-link')[1])
80 else:
81 return int(x.split('r')[1])
82 for destRouterLink, data in sorted(topo['routers'][curRouter]['links']. \
83 iteritems(),
84 key=lambda x: link_sort(x[0])):
85 currRouter_lo_json = \
86 topo['routers'][curRouter]['links'][destRouterLink]
87 # Loopback interfaces
88 if 'type' in data and data['type'] == 'loopback':
89 if 'ipv4' in currRouter_lo_json and \
90 currRouter_lo_json['ipv4'] == 'auto':
91 currRouter_lo_json['ipv4'] = '{}{}.{}/{}'. \
92 format(topo['lo_prefix']['ipv4'], number_to_row(curRouter), \
93 number_to_column(curRouter), topo['lo_prefix']['v4mask'])
94 if 'ipv6' in currRouter_lo_json and \
95 currRouter_lo_json['ipv6'] == 'auto':
96 currRouter_lo_json['ipv6'] = '{}{}:{}/{}'. \
97 format(topo['lo_prefix']['ipv6'], number_to_row(curRouter), \
98 number_to_column(curRouter), topo['lo_prefix']['v6mask'])
99
100 if "-" in destRouterLink:
101 # Spliting and storing destRouterLink data in tempList
102 tempList = destRouterLink.split("-")
103
104 # destRouter
105 destRouter = tempList.pop(0)
106
107 # Current Router Link
108 tempList.insert(0, curRouter)
109 curRouterLink = "-".join(tempList)
110 else:
111 destRouter = destRouterLink
112 curRouterLink = curRouter
113
114 if destRouter in listRouters:
115 currRouter_link_json = \
116 topo['routers'][curRouter]['links'][destRouterLink]
117 destRouter_link_json = \
118 topo['routers'][destRouter]['links'][curRouterLink]
119
120 # Assigning name to interfaces
121 currRouter_link_json['interface'] = \
122 '{}-{}-eth{}'.format(curRouter, destRouter, topo['routers'] \
123 [curRouter]['nextIfname'])
124 destRouter_link_json['interface'] = \
125 '{}-{}-eth{}'.format(destRouter, curRouter, topo['routers'] \
126 [destRouter]['nextIfname'])
127
128 topo['routers'][curRouter]['nextIfname'] += 1
129 topo['routers'][destRouter]['nextIfname'] += 1
130
131 # Linking routers to each other as defined in JSON file
132 tgen.gears[curRouter].add_link(tgen.gears[destRouter],
133 topo['routers'][curRouter]['links'][destRouterLink] \
134 ['interface'], topo['routers'][destRouter]['links'] \
135 [curRouterLink]['interface'])
136
137 # IPv4
138 if 'ipv4' in currRouter_link_json:
139 if currRouter_link_json['ipv4'] == 'auto':
140 currRouter_link_json['ipv4'] = \
141 '{}/{}'.format(ipv4Next, topo['link_ip_start'][ \
142 'v4mask'])
143 destRouter_link_json['ipv4'] = \
144 '{}/{}'.format(ipv4Next + 1, topo['link_ip_start'][ \
145 'v4mask'])
146 ipv4Next += ipv4Step
147 # IPv6
148 if 'ipv6' in currRouter_link_json:
149 if currRouter_link_json['ipv6'] == 'auto':
150 currRouter_link_json['ipv6'] = \
151 '{}/{}'.format(ipv6Next, topo['link_ip_start'][ \
152 'v6mask'])
153 destRouter_link_json['ipv6'] = \
154 '{}/{}'.format(ipv6Next + 1, topo['link_ip_start'][ \
155 'v6mask'])
156 ipv6Next = ipaddr.IPv6Address(int(ipv6Next) + ipv6Step)
157
158 logger.debug("Generated link data for router: %s\n%s", curRouter,
159 json_dumps(topo["routers"][curRouter]["links"],
7fa2079a
AP
160 indent=4, sort_keys=True))
161
7659b8d4
AP
162
163def build_config_from_json(tgen, topo, save_bkup=True):
164 """
165 Reads initial configuraiton from JSON for each router, builds
166 configuration and loads its to router.
167
168 * `tgen`: Topogen object
169 * `topo`: json file data
170 """
171
172 func_dict = OrderedDict([
173 ("links", create_interfaces_cfg),
e4663527 174 ("static_routes", create_static_routes),
00db2a89 175 ("prefix_lists", create_prefix_lists),
e6db2bb1 176 ("route_maps", create_route_maps),
7fa2079a 177 ("bgp", create_router_bgp)
7659b8d4
AP
178 ])
179
180 data = topo["routers"]
181 for func_type in func_dict.keys():
182 logger.info('Building configuration for {}'.format(func_type))
183
184 func_dict.get(func_type)(tgen, data, build=True)
185
186 for router in sorted(topo['routers'].keys()):
187 logger.info('Configuring router {}...'.format(router))
188
189 result = load_config_to_router(tgen, router, save_bkup)
190 if not result:
191 logger.info("Failed while configuring {}".format(router))
192 pytest.exit(1)
193