blob: 13df531f5410937f1dc565dfa32daa7b5aab3c1d [file] [log] [blame]
peustermcbcd4c22015-12-28 11:33:42 +01001"""
2Distributed Cloud Emulator (dcemulator)
3(c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
4"""
5import logging
6
7from mininet.net import Mininet
peusterme6092692016-01-11 16:32:58 +01008from mininet.node import Controller, OVSKernelSwitch, Switch, Docker, Host
peustermcbcd4c22015-12-28 11:33:42 +01009from mininet.cli import CLI
10from mininet.log import setLogLevel, info
11from mininet.link import TCLink, Link
12
13from node import Datacenter
14
15
16class DCNetwork(object):
peusterme4e89d32016-01-07 09:14:54 +010017 """
18 Wraps the original Mininet class and provides
19 methods to add data centers, switches, etc.
20
21 This class is used by topology definition scripts.
22 """
peustermcbcd4c22015-12-28 11:33:42 +010023
24 def __init__(self):
25 self.dcs = {}
26 self.switches = {}
27 self.links = []
28
29 # create a Mininet/Dockernet network
30 setLogLevel('info') # set Mininet loglevel
31 self.mnet = Mininet(controller=Controller, switch=OVSKernelSwitch)
32 self.mnet.addController('c0')
33
34 def addDatacenter(self, name):
35 """
36 Create and add a logical cloud data center to the network.
37 """
38 if name in self.dcs:
39 raise Exception("Data center name already exists: %s" % name)
40 dc = Datacenter(name)
41 dc.net = self # set reference to network
42 self.dcs[name] = dc
43 dc.create() # finally create the data center in our Mininet instance
44 logging.info("added data center: %s" % name)
45 return dc
46
47 def addSwitch(self, name):
48 """
49 We can also add additional SDN switches between data centers.
50 """
51 s = self.mnet.addSwitch(name)
52 self.switches[name] = s
53 logging.info("added switch: %s" % name)
54 return s
55
peusterme6092692016-01-11 16:32:58 +010056 def addLink(self, node1, node2, **params):
peusterm5b844a12016-01-11 15:58:15 +010057 """
58 Able to handle Datacenter objects as link
59 end points.
60 """
peustermcbcd4c22015-12-28 11:33:42 +010061 assert node1 is not None
62 assert node2 is not None
peusterme6092692016-01-11 16:32:58 +010063 logging.debug("addLink: n1=%s n2=%s" % (str(node1), str(node2)))
peustermcbcd4c22015-12-28 11:33:42 +010064 # ensure type of node1
65 if isinstance( node1, basestring ):
66 if node1 in self.dcs:
67 node1 = self.dcs[node1].switch
68 elif node1 in self.switches:
69 node1 = self.switches[node1]
70 if isinstance( node1, Datacenter ):
71 node1 = node1.switch
72 # ensure type of node2
73 if isinstance( node2, basestring ):
74 if node2 in self.dcs:
75 node2 = self.dcs[node2].switch
76 elif node2 in self.switches:
77 node2 = self.switches[node2]
78 if isinstance( node2, Datacenter ):
79 node2 = node2.switch
peustermc3b977e2016-01-12 10:09:35 +010080 # try to give containers a default IP
81 if isinstance( node1, Docker ):
82 if not "params1" in params:
83 params["params1"] = {}
84 if not "ip" in params["params1"]:
85 params["params1"]["ip"] = self.getNextIp()
86 if isinstance( node2, Docker ):
87 if not "params2" in params:
88 params["params2"] = {}
89 if not "ip" in params["params2"]:
90 params["params2"]["ip"] = self.getNextIp()
91
peusterma2ad9ff2016-01-11 17:10:07 +010092 return self.mnet.addLink(node1, node2, **params) # TODO we need TCLinks with user defined performance here
93
94 def removeLink(self, link=None, node1=None, node2=None):
95 """
96 Removes a link. Can either be specified by link object,
97 or the nodes the link connects. Wraps Dockernet method.
98 """
99 logging.debug("removeLink: n1=%s n2=%s" % (str(node1), str(node2)))
100 return self.mnet.removeLink(link=link, node1=node1, node2=node2)
peustermcbcd4c22015-12-28 11:33:42 +0100101
peusterm5b844a12016-01-11 15:58:15 +0100102 def addDocker( self, name, **params ):
103 """
104 Wrapper for addDocker method provided by Dockernet.
105 """
106 return self.mnet.addDocker( name, **params)
107
108 def removeDocker( self, name, **params):
109 """
110 Wrapper for removeHost. Just to be complete.
111 """
112 return self.mnet.removeDocker(name, **params)
113
peustermc3b977e2016-01-12 10:09:35 +0100114 def getNextIp(self):
115 return self.mnet.getNextIp()
116
peustermcbcd4c22015-12-28 11:33:42 +0100117 def start(self):
118 # start
119 for dc in self.dcs.itervalues():
120 dc.start()
121 self.mnet.start()
122
123 def stop(self):
124 self.mnet.stop()
125
126 def CLI(self):
127 CLI(self.mnet)