blob: b0f924b242f1075ef5d0e099951426fc30deb77c [file] [log] [blame]
Jon Hallca319892017-06-15 15:25:22 -07001#!/usr/bin/env python
2"""
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003Copyright 2017 Open Networking Foundation (ONF)
Jon Hallca319892017-06-15 15:25:22 -07004
5Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
6the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
7or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
8
9 TestON is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 2 of the License, or
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000012 (at your option) any later version.
Jon Hallca319892017-06-15 15:25:22 -070013
14 TestON is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with TestON. If not, see <http://www.gnu.org/licenses/>.
21
22
23This driver is used to interact with an ONOS cluster. It should
24handle creating the necessary components to interact with each specific ONOS nodes.
25
26Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
27the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
28or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
29
30"""
31import pexpect
32import os
33from drivers.common.clidriver import CLI
34
35# FIXME: Move this to it's own file?
36class Controller():
Jeremy Ronquillo82705492017-10-18 14:19:55 -070037
Jon Hallca319892017-06-15 15:25:22 -070038 def __str__( self ):
39 return self.name
Jeremy Ronquillo82705492017-10-18 14:19:55 -070040
Jon Hallca319892017-06-15 15:25:22 -070041 def __repr__( self ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -070042 # TODO use repr() for components?
Jon Hallca319892017-06-15 15:25:22 -070043 return "%s<IP=%s, CLI=%s, REST=%s, Bench=%s >" % ( self.name,
Jon Hall4173b242017-09-12 17:04:38 -070044 self.ipAddress,
45 self.CLI,
46 self.REST,
47 self.Bench )
Jon Hallca319892017-06-15 15:25:22 -070048
49 def __getattr__( self, name ):
50 """
51 Called when an attribute lookup has not found the attribute
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000052 in the usual places (i.e. it is not an instance attribute nor
53 is it found in the class tree for self). name is the attribute
54 name. This method should return the (computed) attribute value
Jon Hallca319892017-06-15 15:25:22 -070055 or raise an AttributeError exception.
56
57 We will look into each of the node's component handles to try to find the attreibute, looking at REST first
58 """
59 if hasattr( self.REST, name ):
Jon Hall3c0114c2020-08-11 15:07:42 -070060 main.log.debug( "%s: Using Rest driver's attribute for '%s'" % ( self.name, name ) )
61 return getattr( self.REST, name )
Jon Hallca319892017-06-15 15:25:22 -070062 if hasattr( self.CLI, name ):
Jon Hall3c0114c2020-08-11 15:07:42 -070063 main.log.debug( "%s: Using CLI driver's attribute for '%s'" % ( self.name, name ) )
64 return getattr( self.CLI, name )
Jon Hallca319892017-06-15 15:25:22 -070065 if hasattr( self.Bench, name ):
Jon Hall3c0114c2020-08-11 15:07:42 -070066 main.log.debug( "%s: Using Bench driver's attribute for '%s'" % ( self.name, name ) )
67 return getattr( self.Bench, name )
Devin Lim142b5342017-07-20 15:22:39 -070068 raise AttributeError( "Could not find the attribute %s in %r or it's component handles" % ( name, self ) )
Jon Hallca319892017-06-15 15:25:22 -070069
Jon Hall3c0114c2020-08-11 15:07:42 -070070 def __init__( self, name, ipAddress, CLI=None, REST=None, Bench=None, pos=None,
Jon Hall06fd0df2021-01-25 15:50:06 -080071 userName=None, server=None, k8s=None, dockerPrompt=None ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -070072 # TODO: validate these arguments
Jon Hallca319892017-06-15 15:25:22 -070073 self.name = str( name )
74 self.ipAddress = ipAddress
75 self.CLI = CLI
76 self.REST = REST
77 self.Bench = Bench
78 self.active = False
Devin Lim142b5342017-07-20 15:22:39 -070079 self.pos = pos
80 self.ip_address = ipAddress
81 self.user_name = userName
Jon Hall4173b242017-09-12 17:04:38 -070082 self.server = server
Jon Hall06fd0df2021-01-25 15:50:06 -080083 self.k8s = k8s
Jon Hall3c0114c2020-08-11 15:07:42 -070084 self.dockerPrompt = dockerPrompt
Jon Hallca319892017-06-15 15:25:22 -070085
86class OnosClusterDriver( CLI ):
87
88 def __init__( self ):
89 """
90 Initialize client
91 """
92 self.name = None
93 self.home = None
94 self.handle = None
Jon Hall3c0114c2020-08-11 15:07:42 -070095 self.useDocker = False
96 self.dockerPrompt = None
Jon Halle37bd1f2020-09-10 12:16:41 -070097 self.maxNodes = None
Jon Hall06fd0df2021-01-25 15:50:06 -080098 self.kubeConfig = None
Jon Hallca319892017-06-15 15:25:22 -070099 self.nodes = []
100 super( OnosClusterDriver, self ).__init__()
101
Jon Hallca319892017-06-15 15:25:22 -0700102 def connect( self, **connectargs ):
103 """
104 Creates ssh handle for ONOS "bench".
105 NOTE:
106 The ip_address would come from the topo file using the host tag, the
107 value can be an environment variable as well as a "localhost" to get
108 the ip address needed to ssh to the "bench"
109 """
110 try:
111 for key in connectargs:
112 vars( self )[ key ] = connectargs[ key ]
113 self.home = "~/onos"
114 for key in self.options:
115 if key == "home":
Jon Halle37bd1f2020-09-10 12:16:41 -0700116 self.home = self.options[ key ]
Jon Hallca319892017-06-15 15:25:22 -0700117 elif key == "karaf_username":
118 self.karafUser = self.options[ key ]
119 elif key == "karaf_password":
120 self.karafPass = self.options[ key ]
121 elif key == "cluster_name":
122 prefix = self.options[ key ]
Jon Hall3c0114c2020-08-11 15:07:42 -0700123 elif key == "useDocker":
124 self.useDocker = "True" == self.options[ key ]
125 elif key == "docker_prompt":
126 self.dockerPrompt = self.options[ key ]
Jon Hall9b0de1f2020-08-24 15:38:04 -0700127 elif key == "web_user":
128 self.webUser = self.options[ key ]
129 elif key == "web_pass":
130 self.webPass = self.options[ key ]
Jon Halle37bd1f2020-09-10 12:16:41 -0700131 elif key == "nodes":
132 # Maximum number of ONOS nodes to run, if there is any
133 self.maxNodes = self.options[ key ]
Jon Hall06fd0df2021-01-25 15:50:06 -0800134 elif key == "kubeConfig":
135 self.kubeConfig = self.options[ key ]
Jon Hallca319892017-06-15 15:25:22 -0700136
Jon Hall0e240372018-05-02 11:21:57 -0700137 self.home = self.checkOptions( self.home, "~/onos" )
138 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
139 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
Jon Hall9b0de1f2020-08-24 15:38:04 -0700140 self.webUser = self.checkOptions( self.webUser, "onos" )
141 self.webPass = self.checkOptions( self.webPass, "rocks" )
Jon Hallca319892017-06-15 15:25:22 -0700142 prefix = self.checkOptions( prefix, "ONOS" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700143 self.useDocker = self.checkOptions( self.useDocker, False )
144 self.dockerPrompt = self.checkOptions( self.dockerPrompt, "~/onos#" )
Jon Halle37bd1f2020-09-10 12:16:41 -0700145 self.maxNodes = int( self.checkOptions( self.maxNodes, 100 ) )
Jon Hall06fd0df2021-01-25 15:50:06 -0800146 self.kubeConfig = self.checkOptions( self.kubeConfig, None )
Jon Hallca319892017-06-15 15:25:22 -0700147
148 self.name = self.options[ 'name' ]
149
Jon Hallca319892017-06-15 15:25:22 -0700150
Jon Hall06fd0df2021-01-25 15:50:06 -0800151 if not self.kubeConfig:
152 # Grabs all OC environment variables based on max number of nodes
153 # TODO: Also support giving an ip range as a compononet option
154 self.onosIps = {} # Dictionary of all possible ONOS ip
155
156 try:
157 if self.maxNodes:
158 for i in range( self.maxNodes ):
159 envString = "OC" + str( i + 1 )
160 # If there is no more OC# then break the loop
161 if os.getenv( envString ):
162 self.onosIps[ envString ] = os.getenv( envString )
163 else:
164 self.maxNodes = len( self.onosIps )
165 main.log.info( self.name +
166 ": Created cluster data with " +
167 str( self.maxNodes ) +
168 " maximum number" +
169 " of nodes" )
170 break
171
172 if not self.onosIps:
173 main.log.info( "Could not read any environment variable"
174 + " please load a cell file with all" +
175 " onos IP" )
176 self.maxNodes = None
Jon Hallca319892017-06-15 15:25:22 -0700177 else:
Jon Hall06fd0df2021-01-25 15:50:06 -0800178 main.log.info( self.name + ": Found " +
179 str( self.onosIps.values() ) +
180 " ONOS IPs" )
181 except KeyError:
182 main.log.info( "Invalid environment variable" )
183 except Exception as inst:
184 main.log.error( "Uncaught exception: " + str( inst ) )
Jon Hallca319892017-06-15 15:25:22 -0700185 try:
186 if os.getenv( str( self.ip_address ) ) is not None:
187 self.ip_address = os.getenv( str( self.ip_address ) )
188 else:
189 main.log.info( self.name +
190 ": Trying to connect to " +
191 self.ip_address )
192 except KeyError:
193 main.log.info( "Invalid host name," +
194 " connecting to local host instead" )
195 self.ip_address = 'localhost'
196 except Exception as inst:
197 main.log.error( "Uncaught exception: " + str( inst ) )
198
199 self.handle = super( OnosClusterDriver, self ).connect(
200 user_name=self.user_name,
201 ip_address=self.ip_address,
202 port=self.port,
203 pwd=self.pwd,
204 home=self.home )
205
206 if self.handle:
207 self.handle.sendline( "cd " + self.home )
208 self.handle.expect( "\$" )
Jon Hall06fd0df2021-01-25 15:50:06 -0800209 if self.kubeConfig:
210 # Try to get # of onos nodes using given kubernetes configuration
211 names = self.kubectlGetPodNames( self.kubeConfig,
212 main.params[ 'kubernetes' ][ 'namespace' ],
213 main.params[ 'kubernetes' ][ 'appName' ] )
214 self.podNames = names
215 self.onosIps = {} # Dictionary of all possible ONOS ip
216 for i in range( 1, len( names ) + 1 ):
217 self.onosIps[ 'OC%i' % i ] = self.ip_address
218 self.maxNodes = len( names )
Jon Hallca319892017-06-15 15:25:22 -0700219 self.createComponents( prefix=prefix )
Jon Hall06fd0df2021-01-25 15:50:06 -0800220 if self.kubeConfig:
221 # Create Port Forwarding sessions for each controller
222 for node in self.nodes:
223 kubectl = node.k8s
224 index = self.nodes.index( node )
225 # Store each pod name in the k8s component
226 kubectl.podName = self.podNames[ index ]
227 # Setup port-forwarding and save the local port
228 guiPort = 8181
229 cliPort = 8101
230 portsList = ""
231 for port in [ guiPort, cliPort ]:
232 localPort = port + index + 1
233 portsList += "%s:%s " % ( localPort, port )
234 if port == cliPort:
235 node.CLI.karafPort = localPort
Jon Hall50a00012021-03-08 11:06:11 -0800236 elif port == guiPort:
237 node.REST.port = localPort
Jon Hall06fd0df2021-01-25 15:50:06 -0800238 main.log.info( "Setting up port forward for pod %s: [ %s ]" % ( self.podNames[ index ], portsList ) )
239 pf = kubectl.kubectlPortForward( self.podNames[ index ],
240 portsList,
241 kubectl.kubeConfig,
242 main.params[ 'kubernetes' ][ 'namespace' ] )
243 if not pf:
244 main.log.error( "Failed to create port forwarding" )
245 return main.FALSE
Jon Hallca319892017-06-15 15:25:22 -0700246 return self.handle
247 else:
248 main.log.info( "Failed to create ONOS handle" )
249 return main.FALSE
250 except pexpect.EOF:
251 main.log.error( self.name + ": EOF exception found" )
252 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700253 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700254 except Exception:
255 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700256 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700257
258 def disconnect( self ):
259 """
260 Called when Test is complete to disconnect the ONOS handle.
261 """
262 response = main.TRUE
263 try:
264 if self.handle:
265 self.handle.sendline( "" )
266 self.handle.expect( "\$" )
267 self.handle.sendline( "exit" )
268 self.handle.expect( "closed" )
269 except pexpect.EOF:
270 main.log.error( self.name + ": EOF exception found" )
271 main.log.error( self.name + ": " + self.handle.before )
272 except ValueError:
273 main.log.exception( "Exception in disconnect of " + self.name )
274 response = main.TRUE
275 except Exception:
276 main.log.exception( self.name + ": Connection failed to the host" )
277 response = main.FALSE
278 return response
279
Devin Lim142b5342017-07-20 15:22:39 -0700280 def setCliOptions( self, name, host ):
Jon Hallca319892017-06-15 15:25:22 -0700281 """
282 Parse the cluster options to create an ONOS cli component with the given name
283 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000284 main.componentDictionary[name] = main.componentDictionary[self.name].copy()
Devin Lim142b5342017-07-20 15:22:39 -0700285 clihost = main.componentDictionary[ name ][ 'COMPONENTS' ].get( "diff_clihost", "" )
286 if clihost == "True":
287 main.componentDictionary[ name ][ 'host' ] = host
Jon Hall06fd0df2021-01-25 15:50:06 -0800288 home = main.componentDictionary[name]['COMPONENTS'].get( "onos_home", None )
289 main.componentDictionary[name]['home'] = self.checkOptions( home, None )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000290 main.componentDictionary[name]['type'] = "OnosCliDriver"
291 main.componentDictionary[name]['connect_order'] = str( int( main.componentDictionary[name]['connect_order'] ) + 1 )
Jon Hallca319892017-06-15 15:25:22 -0700292
Devin Lim142b5342017-07-20 15:22:39 -0700293 def createCliComponent( self, name, host ):
Jon Hallca319892017-06-15 15:25:22 -0700294 """
295 Creates a new onos cli component.
296
297 Arguments:
298 name - The string of the name of this component. The new component
299 will be assigned to main.<name> .
300 In addition, main.<name>.name = str( name )
301 """
302 try:
303 # look to see if this component already exists
304 getattr( main, name )
305 except AttributeError:
306 # namespace is clear, creating component
Devin Lim142b5342017-07-20 15:22:39 -0700307 self.setCliOptions( name, host )
Jon Hallca319892017-06-15 15:25:22 -0700308 return main.componentInit( name )
309 except pexpect.EOF:
310 main.log.error( self.name + ": EOF exception found" )
311 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700312 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700313 except Exception:
314 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700315 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700316 else:
317 # namespace is not clear!
318 main.log.error( name + " component already exists!" )
Devin Lim44075962017-08-11 10:56:37 -0700319 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700320
321 def setRestOptions( self, name, host ):
322 """
323 Parse the cluster options to create an ONOS cli component with the given name
324 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000325 main.componentDictionary[name] = main.componentDictionary[self.name].copy()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000326 user = main.componentDictionary[name]['COMPONENTS'].get( "web_user", "onos" )
327 main.componentDictionary[name]['user'] = self.checkOptions( user, "onos" )
328 password = main.componentDictionary[name]['COMPONENTS'].get( "web_pass", "rocks" )
You Wangbef7ea12018-09-21 13:15:12 -0700329 main.componentDictionary[name]['password'] = self.checkOptions( password, "rocks" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000330 main.componentDictionary[name]['host'] = host
331 port = main.componentDictionary[name]['COMPONENTS'].get( "rest_port", "8181" )
332 main.componentDictionary[name]['port'] = self.checkOptions( port, "8181" )
333 main.componentDictionary[name]['type'] = "OnosRestDriver"
334 main.componentDictionary[name]['connect_order'] = str( int( main.componentDictionary[name]['connect_order'] ) + 1 )
Jon Hallca319892017-06-15 15:25:22 -0700335
336 def createRestComponent( self, name, ipAddress ):
337 """
338 Creates a new onos rest component.
339
340 Arguments:
341 name - The string of the name of this component. The new component
342 will be assigned to main.<name> .
343 In addition, main.<name>.name = str( name )
344 """
345 try:
346 # look to see if this component already exists
347 getattr( main, name )
348 except AttributeError:
349 # namespace is clear, creating component
350 self.setRestOptions( name, ipAddress )
351 return main.componentInit( name )
352 except pexpect.EOF:
353 main.log.error( self.name + ": EOF exception found" )
354 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700355 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700356 except Exception:
357 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700358 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700359 else:
360 # namespace is not clear!
361 main.log.error( name + " component already exists!" )
Devin Lim44075962017-08-11 10:56:37 -0700362 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700363
364 def setBenchOptions( self, name ):
365 """
366 Parse the cluster options to create an ONOS "bench" component with the given name
367 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000368 main.componentDictionary[name] = main.componentDictionary[self.name].copy()
369 main.componentDictionary[name]['type'] = "OnosDriver"
370 home = main.componentDictionary[name]['COMPONENTS'].get( "onos_home", None )
371 main.componentDictionary[name]['home'] = self.checkOptions( home, None )
372 main.componentDictionary[name]['connect_order'] = str( int( main.componentDictionary[name]['connect_order'] ) + 1 )
Jon Hallca319892017-06-15 15:25:22 -0700373
374 def createBenchComponent( self, name ):
375 """
376 Creates a new onos "bench" component.
377
378 Arguments:
379 name - The string of the name of this component. The new component
380 will be assigned to main.<name> .
381 In addition, main.<name>.name = str( name )
382 """
383 try:
384 # look to see if this component already exists
385 getattr( main, name )
386 except AttributeError:
387 # namespace is clear, creating component
388 self.setBenchOptions( name )
389 return main.componentInit( name )
390 except pexpect.EOF:
391 main.log.error( self.name + ": EOF exception found" )
392 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700393 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700394 except Exception:
395 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700396 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700397 else:
398 # namespace is not clear!
399 main.log.error( name + " component already exists!" )
Devin Lim44075962017-08-11 10:56:37 -0700400 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700401
Jon Hall4173b242017-09-12 17:04:38 -0700402 def setServerOptions( self, name, ipAddress ):
403 """
404 Parse the cluster options to create an ONOS "server" component with the given name
405
406 Arguments:
407 name - The name of the server componet
408 ipAddress - The ip address of the server
409 """
410 main.componentDictionary[name] = main.componentDictionary[self.name].copy()
411 main.componentDictionary[name]['type'] = "OnosDriver"
412 main.componentDictionary[name]['host'] = ipAddress
413 home = main.componentDictionary[name]['COMPONENTS'].get( "onos_home", None )
414 main.componentDictionary[name]['home'] = self.checkOptions( home, None )
You Wang4cc61912018-08-28 10:10:58 -0700415 # TODO: for now we use karaf user name and password also for logging to the onos nodes
Jon Hall06fd0df2021-01-25 15:50:06 -0800416 # FIXME: We shouldn't use karaf* for this, what we want is another set of variables to
417 # login to a shell on the server ONOS is running on
418 #main.componentDictionary[name]['user'] = self.karafUser
419 #main.componentDictionary[name]['password'] = self.karafPass
Jon Hall4173b242017-09-12 17:04:38 -0700420 main.componentDictionary[name]['connect_order'] = str( int( main.componentDictionary[name]['connect_order'] ) + 1 )
Jon Hall4173b242017-09-12 17:04:38 -0700421
Jon Hall4173b242017-09-12 17:04:38 -0700422 def createServerComponent( self, name, ipAddress ):
423 """
424 Creates a new onos "server" component. This will be connected to the
425 node ONOS is running on.
426
427 Arguments:
428 name - The string of the name of this component. The new component
429 will be assigned to main.<name> .
430 In addition, main.<name>.name = str( name )
431 ipAddress - The ip address of the server
432 """
433 try:
434 # look to see if this component already exists
435 getattr( main, name )
436 except AttributeError:
437 # namespace is clear, creating component
438 self.setServerOptions( name, ipAddress )
439 return main.componentInit( name )
440 except pexpect.EOF:
441 main.log.error( self.name + ": EOF exception found" )
442 main.log.error( self.name + ": " + self.handle.before )
443 main.cleanAndExit()
444 except Exception:
445 main.log.exception( self.name + ": Uncaught exception!" )
446 main.cleanAndExit()
447 else:
448 # namespace is not clear!
449 main.log.error( name + " component already exists!" )
450 main.cleanAndExit()
451
Jon Hall4173b242017-09-12 17:04:38 -0700452 def createComponents( self, prefix='', createServer=True ):
Jon Hallca319892017-06-15 15:25:22 -0700453 """
454 Creates a CLI and REST component for each nodes in the cluster
455 """
456 # TODO: This needs work to support starting two seperate clusters in one test
457 cliPrefix = prefix + "cli"
458 restPrefix = prefix + "rest"
459 benchPrefix = prefix + "bench"
Jon Hall4173b242017-09-12 17:04:38 -0700460 serverPrefix = prefix + "server"
Jon Hall06fd0df2021-01-25 15:50:06 -0800461 k8sPrefix = prefix + "k8s"
Jon Hallca319892017-06-15 15:25:22 -0700462 for i in xrange( 1, self.maxNodes + 1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000463 cliName = cliPrefix + str( i )
Jon Hallca319892017-06-15 15:25:22 -0700464 restName = restPrefix + str( i )
465 benchName = benchPrefix + str( i )
Jon Hall4173b242017-09-12 17:04:38 -0700466 serverName = serverPrefix + str( i )
Jon Hall06fd0df2021-01-25 15:50:06 -0800467 if self.kubeConfig:
468 k8sName = k8sPrefix + str( i )
Jon Hallca319892017-06-15 15:25:22 -0700469
470 # Unfortunately this means we need to have a cell set beofre running TestON,
471 # Even if it is just the entire possible cluster size
472 ip = self.onosIps[ 'OC' + str( i ) ]
473
Devin Lim142b5342017-07-20 15:22:39 -0700474 cli = self.createCliComponent( cliName, ip )
Jon Hallca319892017-06-15 15:25:22 -0700475 rest = self.createRestComponent( restName, ip )
476 bench = self.createBenchComponent( benchName )
Jon Hall4173b242017-09-12 17:04:38 -0700477 server = self.createServerComponent( serverName, ip ) if createServer else None
Jon Hall06fd0df2021-01-25 15:50:06 -0800478 k8s = self.createServerComponent( k8sName, ip ) if self.kubeConfig else None
479 if self.kubeConfig:
480 k8s.kubeConfig = self.kubeConfig
481 k8s.podName = None
Jon Hall3c0114c2020-08-11 15:07:42 -0700482 self.nodes.append( Controller( prefix + str( i ), ip, cli, rest, bench, i - 1,
Jon Hall06fd0df2021-01-25 15:50:06 -0800483 self.user_name, server=server, k8s=k8s,
Jon Hall3c0114c2020-08-11 15:07:42 -0700484 dockerPrompt=self.dockerPrompt ) )