improved CLI
[osm/vim-emu.git] / emuvim / dcemulator / net.py
1 """
2 Distributed Cloud Emulator (dcemulator)
3 (c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
4 """
5 import logging
6
7 from mininet.net import Dockernet
8 from mininet.node import Controller, OVSKernelSwitch, Switch, Docker, Host
9 from mininet.cli import CLI
10 from mininet.log import setLogLevel, info
11 from mininet.link import TCLink, Link
12
13 from node import Datacenter, EmulatorCompute
14
15
16 class DCNetwork(object):
17 """
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 """
23
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 = Dockernet(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
56 def addLink(self, node1, node2, **params):
57 """
58 Able to handle Datacenter objects as link
59 end points.
60 """
61 assert node1 is not None
62 assert node2 is not None
63 logging.debug("addLink: n1=%s n2=%s" % (str(node1), str(node2)))
64 # 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
80 # 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
92 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)
101
102 def addDocker( self, name, **params ):
103 """
104 Wrapper for addDocker method provided by Dockernet.
105 """
106 return self.mnet.addDocker( name, cls=EmulatorCompute, **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
114 def getNextIp(self):
115 return self.mnet.getNextIp()
116
117 def getAllContainers(self):
118 """
119 Returns a list with all containers within all data centers.
120 """
121 all_containers = []
122 for dc in self.dcs.itervalues():
123 all_containers += dc.listCompute()
124 return all_containers
125
126 def start(self):
127 # start
128 for dc in self.dcs.itervalues():
129 dc.start()
130 self.mnet.start()
131
132 def stop(self):
133 self.mnet.stop()
134
135 def CLI(self):
136 CLI(self.mnet)