ufes-20191-redes-mininet/proj-impl/createbigtopo.py

216 lines
6.9 KiB
Python
Executable File

#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
import json
from os import linesep as eol
virtual_servers_per_physical_server = 2
physical_servers_per_rack_tower = 2
rack_tower_per_corridor = 2
corridors = 3
spines = 3
linkspd_virtual_physical = 0.1 # 100 mbps
linkspd_physicalhost_switch = 0.1 # 100 mbps
linkspd_physical_tower = 0.1 # 100 mbps
linkspd_tower_corridor = 1 # 1 gbps
linkspd_corridor_spine = 1 # 1 gbps
linkspd_spine_spine = 10 # 10 gbps
class CounterIterator:
def __init__(self):
self._c = 0
def __iter__(self):
return self
def __next__(self):
self._c += 1
return self._c
hosts_iter = CounterIterator()
switch_iter = CounterIterator()
def create_virtual_server():
this_hosts = []
this_switches = []
this_links = []
this_hosts.append("h%d" % next(hosts_iter))
return this_hosts, this_switches, this_links
def create_physical_server():
this_hosts = []
this_switches = []
this_links = []
serv = "h%d" % next(hosts_iter)
sw = "s%d" % next(switch_iter)
for _ in range(virtual_servers_per_physical_server):
chd_hosts, chd_switches, chd_links = create_virtual_server()
this_hosts += chd_hosts
this_switches += chd_switches
this_links += chd_links
this_links.append((chd_hosts[-1], sw, linkspd_virtual_physical))
this_hosts.append(serv)
this_switches.append(sw)
this_links.append((serv, sw, linkspd_physicalhost_switch))
return this_hosts, this_switches, this_links
def create_racktower():
this_hosts = []
this_switches = []
this_links = []
sw = "s%d" % next(switch_iter)
for _ in range(physical_servers_per_rack_tower):
chd_hosts, chd_switches, chd_links = create_physical_server()
this_hosts += chd_hosts
this_switches += chd_switches
this_links += chd_links
lsw = chd_switches[-1]
this_links.append((lsw, sw, linkspd_physical_tower))
this_switches.append(sw)
return this_hosts, this_switches, this_links
def create_corridor():
this_hosts = []
this_switches = []
this_links = []
sw1 = "s%d" % next(switch_iter)
sw2 = "s%d" % next(switch_iter)
for _ in range(rack_tower_per_corridor):
chd_hosts, chd_switches, chd_links = create_racktower()
this_hosts += chd_hosts
this_switches += chd_switches
this_links += chd_links
lsw = chd_switches[-1]
this_links.append((lsw, sw1, linkspd_tower_corridor))
this_links.append((lsw, sw2, linkspd_tower_corridor))
this_switches.append(sw1)
this_switches.append(sw2)
return this_hosts, this_switches, this_links
def create_spine():
this_hosts = []
this_switches = []
this_links = []
swsps = ["s%d" % next(switch_iter) for _ in range(spines)]
for i in range(spines-1):
chd_hosts, chd_switches, chd_links = create_corridor()
this_hosts += chd_hosts
this_switches += chd_switches
this_links += chd_links
lsw1, lsw2 = chd_switches[-2:]
this_links.append((lsw1, swsps[i], linkspd_corridor_spine))
this_links.append((lsw2, swsps[i+1], linkspd_corridor_spine))
this_switches += swsps
return this_hosts, this_switches, this_links
def create_datacenter():
this_hosts = []
this_switches = []
this_links = []
last_spined_corridor = []
for _ in range(corridors):
chd_hosts, chd_switches, chd_links = create_spine()
this_hosts += chd_hosts
this_switches += chd_switches
this_links += chd_links
spined_corridor = chd_switches[-spines:]
if len(last_spined_corridor) > 0:
for i in range(spines):
this_links.append(
(last_spined_corridor[i], spined_corridor[i], linkspd_spine_spine))
last_spined_corridor = spined_corridor
return this_hosts, this_switches, this_links
def render_topology(hosts, switches, links):
indent = ' '*4
s = ''
s += f'#!/usr/bin/env python3{eol}# -*- encoding: utf-8 -*-{eol}'+eol
s += 'from mininet.net import Mininet'+eol
s += 'from mininet.node import Controller, RemoteController, OVSController'+eol
s += 'from mininet.node import CPULimitedHost, Host, Node'+eol
s += 'from mininet.node import OVSKernelSwitch, UserSwitch'+eol
s += 'from mininet.node import IVSSwitch'+eol
s += 'from mininet.cli import CLI'+eol
s += 'from mininet.log import setLogLevel, info'+eol
s += 'from mininet.link import TCLink, Intf'+eol
s += 'from subprocess import call'+eol+eol
s += 'def myNetwork():'+eol
s += f'{indent}net = Mininet({eol}'
s += f'{indent}{indent}topo=None,{eol}'
s += f'{indent}{indent}build=False,{eol}'
s += f'{indent}{indent}ipBase="10.0.0.0/8"{eol}'
s += f'{indent}){eol}'
s += eol
# controller
s += f"{indent}info('*** Adding controller\\n'){eol}"
s += f"{indent}c0=net.addController({eol}"
s += f"{indent}{indent}name='c0',{eol}"
s += f"{indent}{indent}controller=Controller,{eol}"
s += f"{indent}{indent}protocol='tcp',{eol}"
s += f"{indent}{indent}port=6633{eol}"
s += f"{indent}){eol}"
s += eol
# switch
s += f"{indent}info('*** Adding switches\\n'){eol}"
for sw in sorted(switches, key=lambda a: int(a[1:])):
s += f"{indent}{sw} = net.addSwitch('{sw}', cls=OVSKernelSwitch){eol}"
s += eol
# hosts
s += f"{indent}info('*** Adding hosts\\n'){eol}"
for hs in sorted(hosts, key=lambda a: int(a[1:])):
ipint = int(hs[1:])
iplst = [
ipint//(256**2),
(ipint//256)%256,
ipint%256
]
ip = '.'.join(list(map(str, iplst)))
s+= f"{indent}{hs} = net.addHost('{hs}', cls=Host, ip='10.{ip}', defaultRoute=None){eol}"
s += eol
# links
s += f"{indent}info('*** Adding links\\n'){eol}"
for e1, e2, bw in links:
s += f"{indent}net.addLink({e1}, {e2}, cls=TCLink, bw={bw}){eol}"
s += eol
# rest
s += f"{indent}info('*** Starting network\\n'){eol}"
s += f"{indent}net.build(){eol}"
s += eol
s += f"{indent}info('*** Starting controllers\\n'){eol}"
s += f"{indent}for controller in net.controllers:{eol}"
s += f"{indent}{indent}controller.start(){eol}"
s += eol
s += f"{indent}info('*** Starting switches\\n'){eol}"
for sw in sorted(switches, key=lambda a: int(a[1:])):
s += f"{indent}net.get('{sw}').start([c0]){eol}"
s += eol
s += f"{indent}info('*** Post configure switches and hosts\\n'){eol}"
s += f"{indent}CLI(net){eol}"
s += f"{indent}net.stop(){eol}"
# main
s += eol
s += eol
s += f'if __name__ == "__main__":{eol}'
s += f'{indent}setLogLevel("info"){eol}'
s += f'{indent}myNetwork(){eol}'
return s
datacenter = create_datacenter()
rendered = render_topology(*datacenter)
with open('bigtopo.py', 'w') as f:
f.write(rendered)
with open('bigtopo.json', 'w') as f:
f.write(json.dumps(datacenter))