6e274c6da6d6e65ea36e747ae9d1bf136bce6c69
[integration/test.git] / test / csit / libraries / DynamicMininet.py
1 """
2 New CLI for mininet which should dynamically add and delete switches from network"
3 """
4
5 import cmd
6 # import json
7 # import logging
8
9 import mininet.node
10 import mininet.topo
11 import mininet.net
12 import mininet.util
13 from mininet.node import RemoteController
14 from mininet.node import OVSKernelSwitch
15 from subprocess import call
16
17
18 class DynamicMininet(cmd.Cmd):
19     """Cli wrapper over Mininet network instance tool.
20
21     - when starting this CLI the 'mininet> ' cli appears, but no switches are active
22     - topology is very simple, just as many single switches without any hosts nor links
23
24     How to use it:
25     - one possible scenario is for measuring max connected switches
26        1) start cli
27        2) start mininet using command 'start <controller> <num>'
28        3) add another switches using 'add_switch' or 'add_switches <num>'
29        4) stop mininet usinf 'exit'
30     - another scenario is connect one single switch to multiple controllers or clustered controller
31       for feature testing
32        1) start cli
33        2) start mininet with specified controllers using command 'start_with_cluster <cntl>[,<cntl>[...]]>'
34        3) stop mininet using 'exit'
35     Note: Do not mix scanarios
36     """
37
38     prompt = 'mininet> '
39
40     def __init__(self):
41         cmd.Cmd.__init__(self)
42         self._running = False
43         self._net = None
44         self._topo = None
45         # last used switch id
46         self._lid = 0
47
48     def do_start(self, line):
49         """Starts mininet network with initial number of switches
50
51         Args:
52             :param controller_ip: controller's ip address or host name
53             :param num: initial number of switches in the topology
54         """
55         if self._running:
56             print 'Mininet topology is already active'
57             return
58         cntl, numsw = line.split()
59         self._topo = mininet.topo.Topo()
60         for _ in range(int(numsw)):
61             self._lid += 1
62             self._topo.addSwitch('s{0}'.format(self._lid))
63         controller = mininet.util.customConstructor({'remote': RemoteController}, 'remote,ip={0}'.format(cntl))
64         switch = mininet.util.customConstructor({'ovsk': OVSKernelSwitch}, 'ovsk,protocols=OpenFlow13')
65         self._net = mininet.net.Mininet(topo=self._topo, switch=switch, controller=controller)
66         self._net.start()
67         self._running = True
68
69     def help_start(self):
70         """Provide help message for start command"""
71         print 'Starts mininet'
72         print 'Usage: start <controller_ip> <num>'
73         print '\tcontroller_ip - controllers ip or host name'
74         print '\tnum           - number of switches at start'
75
76     def do_start_with_cluster(self, line):
77         """Starts mininet network with initial number of switches
78
79         Args:
80             :param controller_ips: list of controller ip addresses or host names
81                                    e.g.  1.1.1.1,2.2.2.2,3.3.3.3 (no spaces)
82         """
83         if self._running:
84             print 'Mininet topology is already active'
85             return
86         cntls = line.split(',')
87
88         self._topo = mininet.topo.SingleSwitchTopo()
89         switch = mininet.util.customConstructor({'ovsk': OVSKernelSwitch}, 'ovsk,protocols=OpenFlow13')
90         self._net = mininet.net.Mininet(switch=switch)
91
92         controllers = []
93         for i, cntl_ip in enumerate(cntls):
94             cnt = self._net.addController('c{0}'.format(i), controller=RemoteController, ip=cntl_ip, port=6633)
95             controllers.append(cnt)
96             print "contrller {0} created".format(cnt)
97
98         self._net.buildFromTopo(topo=self._topo)
99         self._net.start()
100         self._running = True
101
102     def help_start_with_cluster(self):
103         """Provide help message for start_with_cluster command"""
104         print 'Starts mininet with one switch'
105         print 'Usage: start <controller_ips>'
106         print '\tcontroller_ips - comma separated list of controllers ip or host names'
107
108     def do_start_switches_with_cluster(self, line):
109         """Starts mininet network with initial number of switches
110
111         Args:
112             :param swnr: number of switchers in topology
113             :param controller_ips: list of controller ip addresses or host names
114                                    e.g.  1.1.1.1,2.2.2.2,3.3.3.3 (no spaces)
115         """
116         if self._running:
117             print 'Mininet topology is already active'
118             return
119         num, contls = line.split()
120         cntls = contls.split(',')
121
122         self._topo = mininet.topo.LinearTopo(int(num))
123         switch = mininet.util.customConstructor({'ovsk': OVSKernelSwitch}, 'ovsk,protocols=OpenFlow13')
124         self._net = mininet.net.Mininet(switch=switch)
125
126         controllers = []
127         for i, cntl_ip in enumerate(cntls):
128             cnt = self._net.addController('c{0}'.format(i), controller=RemoteController, ip=cntl_ip, port=6633)
129             controllers.append(cnt)
130             print "contrller {0} created".format(cnt)
131
132         self._net.buildFromTopo(topo=self._topo)
133         self._net.start()
134         self._running = True
135
136     def help_start_switches_with_cluster(self):
137         """Provide help message for start_with_cluster command"""
138         print 'Starts mininet with one switch'
139         print 'Usage: start <swnr> <controller_ips>'
140         print '\tswnt - number of switches in topology'
141         print '\tcontroller_ips - comma separated list of controllers ip or host names'
142
143     def do_add_switch(self, line):
144         """Adds one switch to the network
145         Args:
146             no args (any given agrs are ignored)
147         """
148         if not self._running:
149             raise RuntimeError('Network not running, use command "start" first')
150         self._lid += 1
151         sname = 's{0}'.format(self._lid)
152         self._topo.addSwitch(sname)
153         self._net.addSwitch(sname, **self._topo.nodeInfo(sname))
154         s = self._net.get(sname)
155         c = self._net.get('c0')
156         s.start([c])
157
158     def help_add_switch(self):
159         """Provide help message for add_switch command"""
160         print 'Adds one sinle switch to the running topology'
161         print 'Usage: add_switch'
162
163     def do_add_switches(self, line):
164         """Adds switches to the network
165         Args:
166             :param  num: number of switches to be added to the running topology
167         """
168         for i in range(int(line)):
169             self.do_add_switch("")
170
171     def help_add_switches(self):
172         """Provide help message for add_switch command"""
173         print 'Adds one sinle switch to the running topology'
174         print 'Usage: add_switches <num>'
175         print '\tnum - number of switches tp be added'
176
177     def do_exit(self, line):
178         """Stops mininet"""
179         if self._running:
180             self._net.stop()
181             self._running = False
182         return True
183
184     def help_exit(self):
185         """Provide help message for exit command"""
186         print 'Exit mininet cli'
187         print 'Usage: exit'
188
189     def do_sh(self, line):
190         """Run an external shell command
191         Args:
192             :param line: text/command to be executed
193         """
194         call(line, shell=True)
195
196     def help_sh(self, line):
197         """Provide help message for sh command"""
198         print 'Executes given commandAdds one sinle switch to the running topology'
199         print 'Usage: sh <line>'
200         print '\tline - command to be executed(e.g. ps -e'
201
202     def emptyline(self):
203         pass
204
205
206 if __name__ == '__main__':
207     dynamic_mininet_cli = DynamicMininet()
208     dynamic_mininet_cli.cmdloop()