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