blob: 6e1ae314eb9a8289d644dbe0d35262fa4a8ba96b [file] [log] [blame]
Matteo Scandolo48d3d2d2017-08-08 13:05:27 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
A R Karthick81acbff2016-06-17 14:45:16 -070017#
Chetan Gaonkercfcce782016-05-10 10:10:42 -070018# Copyright 2016-present Ciena Corporation
19#
20# Licensed under the Apache License, Version 2.0 (the "License");
21# you may not use this file except in compliance with the License.
22# You may obtain a copy of the License at
A R Karthick81acbff2016-06-17 14:45:16 -070023#
Chetan Gaonkercfcce782016-05-10 10:10:42 -070024# http://www.apache.org/licenses/LICENSE-2.0
A R Karthick81acbff2016-06-17 14:45:16 -070025#
Chetan Gaonkercfcce782016-05-10 10:10:42 -070026# Unless required by applicable law or agreed to in writing, software
27# distributed under the License is distributed on an "AS IS" BASIS,
28# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29# See the License for the specific language governing permissions and
30# limitations under the License.
31#
A.R Karthick1700e0e2016-10-06 18:16:57 -070032from CordContainer import Container, Onos, OnosStopWrapper, OnosCord, OnosCordStopWrapper, Quagga, QuaggaStopWrapper, Radius, reinitContainerClients
A R Karthick1555c7c2017-09-07 14:59:41 -070033from OltConfig import OltConfig
A R Karthickc0a008f2017-10-04 18:35:25 -070034from OnosCtrl import OnosCtrl
35from CordTestUtils import get_controller
A R Karthickefcf1ab2017-09-08 18:24:16 -070036from EapolAAA import get_radius_macs, get_radius_networks
Chetan Gaonker3533faa2016-04-25 17:50:14 -070037from nose.tools import nottest
A R Karthick81acbff2016-06-17 14:45:16 -070038from SimpleXMLRPCServer import SimpleXMLRPCServer
A R Karthick1878c4f2016-11-29 09:19:50 -080039from resource import getrlimit, RLIMIT_NOFILE
A R Karthick81acbff2016-06-17 14:45:16 -070040import daemon
41import xmlrpclib
42import os
A R Karthicke99ab5c2016-09-30 13:59:57 -070043import signal
A R Karthick81acbff2016-06-17 14:45:16 -070044import json
45import time
46import threading
Chetan Gaonker3533faa2016-04-25 17:50:14 -070047
A R Karthick81acbff2016-06-17 14:45:16 -070048##Server to handle container restart/stop requests from test container.
Chetan Gaonker3533faa2016-04-25 17:50:14 -070049##Used now to restart ONOS from vrouter test container
50
51CORD_TEST_HOST = '172.17.0.1'
52CORD_TEST_PORT = 25000
53
A R Karthick81acbff2016-06-17 14:45:16 -070054class CordTestServer(object):
55
A R Karthickbd9b8a32016-07-21 09:56:45 -070056 onos_cord = None
57
A R Karthickc0a008f2017-10-04 18:35:25 -070058 def __ovs_flow_add(self, in_port = 1, dl_vlan = 0):
59 if dl_vlan:
60 cmd = 'ovs-ofctl -O OpenFlow13 add-flow br-int in_port=%d,dl_vlan=%d,actions=CONTROLLER:65535' %(in_port, dl_vlan)
61 else:
62 cmd = 'ovs-ofctl -O OpenFlow13 add-flow br-int in_port=%d,actions=CONTROLLER:65535' %(in_port)
63 os.system(cmd)
64 return 'DONE'
65
66 def ovs_flow_add(self, kwargs):
67 return self.__ovs_flow_add(**kwargs)
68
A R Karthickde6b9dc2016-11-29 17:46:16 -080069 def __restart_onos(self, node = None, config = None, timeout = 10):
A R Karthickbd9b8a32016-07-21 09:56:45 -070070 if self.onos_cord:
A R Karthick928ad622017-01-30 12:18:32 -080071 onos_config = '{}/network-cfg.json'.format(self.onos_cord.onos_config_dir)
A R Karthickd44cea12016-07-20 12:16:41 -070072 else:
73 onos_config = '{}/network-cfg.json'.format(Onos.host_config_dir)
A R Karthick81acbff2016-06-17 14:45:16 -070074 if config is None:
75 try:
76 os.unlink(onos_config)
77 except:
78 pass
Chetan Gaonker6cf6e472016-04-26 14:41:51 -070079 print('Restarting ONOS')
A R Karthickbd9b8a32016-07-21 09:56:45 -070080 if self.onos_cord:
81 self.onos_cord.start(restart = True, network_cfg = config)
A R Karthickd44cea12016-07-20 12:16:41 -070082 else:
A R Karthickde6b9dc2016-11-29 17:46:16 -080083 Onos.restart_node(node = node, network_cfg = config, timeout = timeout)
A R Karthick81acbff2016-06-17 14:45:16 -070084 return 'DONE'
Chetan Gaonker6cf6e472016-04-26 14:41:51 -070085
A R Karthick81acbff2016-06-17 14:45:16 -070086 def restart_onos(self, kwargs):
87 return self.__restart_onos(**kwargs)
88
A.R Karthick1700e0e2016-10-06 18:16:57 -070089 def __shutdown_onos(self, node = None):
90 if node is None:
91 node = Onos.NAME
92 OnosStopWrapper(node)
93 return 'DONE'
94
95 def shutdown_onos(self, kwargs):
96 return self.__shutdown_onos(**kwargs)
97
A.R Karthick2560f042016-11-30 14:38:52 -080098 def __restart_cluster(self, config = None, timeout = 10, setup = False):
99 Onos.restart_cluster(network_cfg = config, timeout = timeout, setup = setup)
100 return 'DONE'
101
102 def restart_cluster(self, kwargs):
103 return self.__restart_cluster(**kwargs)
104
A R Karthicke2c24bd2016-10-07 14:51:38 -0700105 def __add_cluster_onos(self, count = 1, config = None):
106 Onos.add_cluster(count = count, network_cfg = config)
107 return 'DONE'
108
109 def add_cluster_onos(self, kwargs):
A R Karthickdb59cf72016-10-10 10:43:22 -0700110 return self.__add_cluster_onos(**kwargs)
A R Karthicke2c24bd2016-10-07 14:51:38 -0700111
A R Karthick81acbff2016-06-17 14:45:16 -0700112 def __restart_quagga(self, config = None, boot_delay = 30 ):
Chetan Gaonkerfd3d6502016-05-03 13:23:07 -0700113 config_file = Quagga.quagga_config_file
A R Karthick81acbff2016-06-17 14:45:16 -0700114 if config is not None:
115 quagga_config = '{}/testrib_gen.conf'.format(Quagga.host_quagga_config)
116 config_file = '{}/testrib_gen.conf'.format(Quagga.guest_quagga_config)
117 with open(quagga_config, 'w+') as fd:
118 fd.write(str(config))
119 print('Restarting QUAGGA with config file %s, delay %d' %(config_file, boot_delay))
A R Karthick07608ef2016-08-23 16:51:19 -0700120 Quagga(prefix = Container.IMAGE_PREFIX, restart = True, config_file = config_file, boot_delay = boot_delay)
A R Karthick81acbff2016-06-17 14:45:16 -0700121 return 'DONE'
Chetan Gaonker6cf6e472016-04-26 14:41:51 -0700122
A R Karthick81acbff2016-06-17 14:45:16 -0700123 def restart_quagga(self, kwargs):
124 return self.__restart_quagga(**kwargs)
Chetan Gaonker7f4bf742016-05-04 15:56:08 -0700125
A R Karthick81acbff2016-06-17 14:45:16 -0700126 def stop_quagga(self):
127 quaggaStop = QuaggaStopWrapper()
A R Karthick4a2362c2016-06-22 17:32:44 -0700128 time.sleep(5)
Chetan Gaonker6cf6e472016-04-26 14:41:51 -0700129 try:
A R Karthick81acbff2016-06-17 14:45:16 -0700130 quagga_config_gen = '{}/testrib_gen.conf'.format(Quagga.host_quagga_config)
131 os.unlink(quagga_config_gen)
132 except: pass
133 return 'DONE'
Chetan Gaonker6cf6e472016-04-26 14:41:51 -0700134
A R Karthickc3d80e22016-06-22 17:51:24 -0700135 def __run_shell_quagga(self, cmd = None):
136 ret = 0
137 if cmd is not None:
138 exec_cmd = 'docker exec {} {}'.format(Quagga.NAME, cmd)
139 ret = os.system(exec_cmd)
140 return ret
141
A R Karthicka013a272016-08-16 16:40:19 -0700142 def __run_shell(self, cmd = None):
143 ret = 0
144 if cmd is not None:
145 ret = os.system(cmd)
146 return ret
147
A R Karthickc3d80e22016-06-22 17:51:24 -0700148 def run_shell_quagga(self, kwargs):
149 return self.__run_shell_quagga(**kwargs)
150
A R Karthicka013a272016-08-16 16:40:19 -0700151 def run_shell(self, kwargs):
152 return self.__run_shell(**kwargs)
153
A R Karthick1555c7c2017-09-07 14:59:41 -0700154 def __restart_radius(self, olt_conf_file = ''):
155 olt_conf = os.path.join(Onos.setup_dir, os.path.basename(olt_conf_file))
156 olt = OltConfig(olt_conf_file = olt_conf)
157 port_map, _ = olt.olt_port_map()
A R Karthick07608ef2016-08-23 16:51:19 -0700158 Radius(prefix = Container.IMAGE_PREFIX, restart = True)
A R Karthick1555c7c2017-09-07 14:59:41 -0700159 radius_macs = get_radius_macs(len(port_map['radius_ports']))
A R Karthickefcf1ab2017-09-08 18:24:16 -0700160 radius_networks = get_radius_networks(len(port_map['switch_radius_port_list']))
A R Karthick1555c7c2017-09-07 14:59:41 -0700161 radius_intf_index = 0
A R Karthickefcf1ab2017-09-08 18:24:16 -0700162 index = 0
A R Karthick1555c7c2017-09-07 14:59:41 -0700163 for host_intf, ports in port_map['switch_radius_port_list']:
A R Karthickefcf1ab2017-09-08 18:24:16 -0700164 prefix, subnet, _ = radius_networks[index]
165 mask = subnet.split('/')[-1]
166 index += 1
A R Karthick1555c7c2017-09-07 14:59:41 -0700167 for port in ports:
168 guest_if = 'eth{}'.format(radius_intf_index + 2)
169 port_index = port_map[port]
170 local_if = 'r{}'.format(port_index)
A R Karthickefcf1ab2017-09-08 18:24:16 -0700171 guest_ip = '{}.{}/{}'.format(prefix, port_index, mask)
A R Karthick1555c7c2017-09-07 14:59:41 -0700172 mac = radius_macs[radius_intf_index]
173 radius_intf_index += 1
174 pipework_cmd = 'pipework {0} -i {1} -l {2} {3} {4} {5}'.format(host_intf, guest_if,
175 local_if, Radius.NAME,
176 guest_ip, mac)
177 print('Configuring Radius port %s on OVS bridge %s' %(guest_if, host_intf))
178 print('Running pipework command: %s' %(pipework_cmd))
179 res = os.system(pipework_cmd)
180
181 def restart_radius(self, kwargs):
182 print('Restarting RADIUS Server')
183 self.__restart_radius(**kwargs)
A R Karthick81acbff2016-06-17 14:45:16 -0700184 return 'DONE'
Chetan Gaonker3533faa2016-04-25 17:50:14 -0700185
A R Karthicke99ab5c2016-09-30 13:59:57 -0700186 def shutdown(self):
187 print('Shutting down cord test server')
188 os.kill(0, signal.SIGKILL)
189 return 'DONE'
190
A R Karthick1878c4f2016-11-29 09:19:50 -0800191def find_files_by_path(*paths):
192 wanted = []
193 for p in paths:
194 try:
195 fd = os.open(p, os.O_RDONLY)
196 wanted.append(os.fstat(fd)[1:3])
197 finally:
198 os.close(fd)
199
200 def fd_wanted(fd):
201 try:
202 return os.fstat(fd)[1:3] in wanted
203 except OSError:
204 return False
205
206 max_fd = getrlimit(RLIMIT_NOFILE)[1]
207 return [ fd for fd in xrange(max_fd) if fd_wanted(fd) ]
208
Chetan Gaonker3533faa2016-04-25 17:50:14 -0700209@nottest
A R Karthickbd82f362016-11-10 15:08:52 -0800210def cord_test_server_start(daemonize = True,
211 cord_test_host = CORD_TEST_HOST,
212 cord_test_port = CORD_TEST_PORT,
213 onos_cord = None,
214 foreground=False):
A R Karthick81acbff2016-06-17 14:45:16 -0700215 server = SimpleXMLRPCServer( (cord_test_host, cord_test_port) )
216 server.register_instance(CordTestServer())
A R Karthickbd9b8a32016-07-21 09:56:45 -0700217 CordTestServer.onos_cord = onos_cord
A R Karthick81acbff2016-06-17 14:45:16 -0700218 if daemonize is True:
A R Karthick1878c4f2016-11-29 09:19:50 -0800219 ##before daemonizing, preserve urandom needed by paramiko
220 preserve_list = find_files_by_path('/dev/urandom')
221 preserve_list.append(server)
222 d = daemon.DaemonContext(files_preserve = preserve_list,
A R Karthick81acbff2016-06-17 14:45:16 -0700223 detach_process = True)
224 with d:
225 reinitContainerClients()
226 server.serve_forever()
227 else:
A R Karthickbd82f362016-11-10 15:08:52 -0800228 if foreground:
229 try:
230 server.serve_forever()
231 except KeyboardInterrupt:
232 return server
233 else:
234 task = threading.Thread(target = server.serve_forever)
235 ##terminate when main thread exits
236 task.daemon = True
237 task.start()
Chetan Gaonker3533faa2016-04-25 17:50:14 -0700238 return server
239
240@nottest
241def cord_test_server_stop(server):
242 server.shutdown()
243 server.server_close()
244
245@nottest
A R Karthick81acbff2016-06-17 14:45:16 -0700246def get_cord_test_loc():
247 host = os.getenv('CORD_TEST_HOST', CORD_TEST_HOST)
248 port = int(os.getenv('CORD_TEST_PORT', CORD_TEST_PORT))
249 return host, port
250
A R Karthickc0a008f2017-10-04 18:35:25 -0700251def rpc_server_instance(host = None, port = None):
A R Karthick81acbff2016-06-17 14:45:16 -0700252 '''Stateless'''
A R Karthickc0a008f2017-10-04 18:35:25 -0700253 if host is None or port is None:
254 host, port = get_cord_test_loc()
A R Karthick81acbff2016-06-17 14:45:16 -0700255 rpc_server = 'http://{}:{}'.format(host, port)
256 return xmlrpclib.Server(rpc_server, allow_none = True)
257
258@nottest
259def __cord_test_onos_restart(**kwargs):
260 return rpc_server_instance().restart_onos(kwargs)
261
262@nottest
A R Karthickde6b9dc2016-11-29 17:46:16 -0800263def cord_test_onos_restart(node = None, config = None, timeout = 10):
Chetan Gaonker3533faa2016-04-25 17:50:14 -0700264 '''Send ONOS restart to server'''
A R Karthick6cc8b812016-12-09 10:24:40 -0800265 for i in range(3):
266 try:
267 data = __cord_test_onos_restart(node = node, config = config, timeout = timeout)
268 if data == 'DONE':
269 return True
270 except:
271 time.sleep(2)
272
Chetan Gaonker6cf6e472016-04-26 14:41:51 -0700273 return False
274
275@nottest
A.R Karthick1700e0e2016-10-06 18:16:57 -0700276def __cord_test_onos_shutdown(**kwargs):
277 return rpc_server_instance().shutdown_onos(kwargs)
278
279@nottest
280def cord_test_onos_shutdown(node = None):
281 data = __cord_test_onos_shutdown(node = node)
282 if data == 'DONE':
283 return True
284 return False
285
286@nottest
A.R Karthick2560f042016-11-30 14:38:52 -0800287def __cord_test_restart_cluster(**kwargs):
288 return rpc_server_instance().restart_cluster(kwargs)
289
290@nottest
291def cord_test_restart_cluster(config = None, timeout = 10, setup = False):
A R Karthick6cc8b812016-12-09 10:24:40 -0800292 for i in range(3):
293 try:
294 data = __cord_test_restart_cluster(config = config, timeout = timeout, setup = setup)
295 if data == 'DONE':
296 return True
297 except:
298 time.sleep(2)
299
A.R Karthick2560f042016-11-30 14:38:52 -0800300 return False
301
302@nottest
A R Karthicke2c24bd2016-10-07 14:51:38 -0700303def __cord_test_onos_add_cluster(**kwargs):
304 return rpc_server_instance().add_cluster_onos(kwargs)
305
306@nottest
307def cord_test_onos_add_cluster(count = 1, config = None):
308 data = __cord_test_onos_add_cluster(count = count, config = config)
309 if data == 'DONE':
310 return True
311 return False
312
313@nottest
A R Karthick81acbff2016-06-17 14:45:16 -0700314def __cord_test_quagga_restart(**kwargs):
315 return rpc_server_instance().restart_quagga(kwargs)
316
317@nottest
A R Karthick1555c7c2017-09-07 14:59:41 -0700318def __cord_test_radius_restart(**kwargs):
319 return rpc_server_instance().restart_radius(kwargs)
320
321@nottest
A R Karthick81acbff2016-06-17 14:45:16 -0700322def cord_test_quagga_restart(config = None, boot_delay = 30):
Chetan Gaonker6cf6e472016-04-26 14:41:51 -0700323 '''Send QUAGGA restart to server'''
A R Karthick81acbff2016-06-17 14:45:16 -0700324 data = __cord_test_quagga_restart(config = config, boot_delay = boot_delay)
325 if data == 'DONE':
326 return True
327 return False
328
329@nottest
A R Karthickc3d80e22016-06-22 17:51:24 -0700330def __cord_test_quagga_shell(**kwargs):
331 return rpc_server_instance().run_shell_quagga(kwargs)
332
333@nottest
334def cord_test_quagga_shell(cmd = None):
335 '''Send QUAGGA shell cmd to server'''
336 return __cord_test_quagga_shell(cmd = cmd)
337
338@nottest
A R Karthicka013a272016-08-16 16:40:19 -0700339def __cord_test_shell(**kwargs):
340 return rpc_server_instance().run_shell(kwargs)
341
342@nottest
343def cord_test_shell(cmd = None):
344 '''Send shell cmd to run remotely'''
345 return __cord_test_shell(cmd = cmd)
346
347@nottest
A R Karthick81acbff2016-06-17 14:45:16 -0700348def cord_test_quagga_stop():
349 data = rpc_server_instance().stop_quagga()
Chetan Gaonker3533faa2016-04-25 17:50:14 -0700350 if data == 'DONE':
351 return True
352 return False
Chetan Gaonker7f4bf742016-05-04 15:56:08 -0700353
354@nottest
A R Karthick1555c7c2017-09-07 14:59:41 -0700355def cord_test_radius_restart(olt_conf_file = ''):
Chetan Gaonker7f4bf742016-05-04 15:56:08 -0700356 '''Send Radius server restart to server'''
A R Karthick1555c7c2017-09-07 14:59:41 -0700357 if not olt_conf_file:
358 olt_conf_file = os.getenv('OLT_CONFIG')
359 olt_conf_file = os.path.basename(olt_conf_file)
360 data = __cord_test_radius_restart(olt_conf_file = olt_conf_file)
Chetan Gaonker7f4bf742016-05-04 15:56:08 -0700361 if data == 'DONE':
362 return True
363 return False
A R Karthicke99ab5c2016-09-30 13:59:57 -0700364
365@nottest
366def cord_test_server_shutdown(host, port):
367 '''Shutdown the cord test server'''
368 rpc_server = 'http://{}:{}'.format(host, port)
369 try:
370 xmlrpclib.Server(rpc_server, allow_none = True).shutdown()
371 except: pass
372
373 return True
A R Karthickc0a008f2017-10-04 18:35:25 -0700374
375@nottest
376def __cord_test_ovs_flow_add(**kwargs):
377 controller = get_controller()
378 OnosCtrl.config_extraneous_flows(controller = controller)
379 try:
380 return rpc_server_instance(host = controller, port = CORD_TEST_PORT).ovs_flow_add(kwargs)
381 except:
382 pass
383
384 try:
385 return rpc_server_instance().ovs_flow_add(kwargs)
386 except:
387 pass
388
389 return 'FAIL'
390
391@nottest
392def cord_test_ovs_flow_add(in_port, dl_vlan = 0):
393 data = __cord_test_ovs_flow_add(in_port = in_port, dl_vlan = dl_vlan)
394 if data == 'DONE':
395 return True
396 return False