blob: eebc5ad388829f78c0acc2d6f66cbef738133d43 [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
Siddesh52750622021-03-05 19:52:03 +000098 self.karafPromptPass = None
Jon Hall06fd0df2021-01-25 15:50:06 -080099 self.kubeConfig = None
Siddesh52750622021-03-05 19:52:03 +0000100 self.karafPromptUser = None
Jon Hall3a03cad2021-04-07 11:21:55 -0700101 self.nodeUser = None
102 self.nodePass = None
Jon Hallca319892017-06-15 15:25:22 -0700103 self.nodes = []
104 super( OnosClusterDriver, self ).__init__()
105
Jon Hallca319892017-06-15 15:25:22 -0700106 def connect( self, **connectargs ):
107 """
108 Creates ssh handle for ONOS "bench".
109 NOTE:
110 The ip_address would come from the topo file using the host tag, the
111 value can be an environment variable as well as a "localhost" to get
112 the ip address needed to ssh to the "bench"
113 """
114 try:
115 for key in connectargs:
116 vars( self )[ key ] = connectargs[ key ]
117 self.home = "~/onos"
118 for key in self.options:
119 if key == "home":
Jon Halle37bd1f2020-09-10 12:16:41 -0700120 self.home = self.options[ key ]
Jon Hallca319892017-06-15 15:25:22 -0700121 elif key == "karaf_username":
122 self.karafUser = self.options[ key ]
123 elif key == "karaf_password":
124 self.karafPass = self.options[ key ]
Siddesh52750622021-03-05 19:52:03 +0000125 elif key == "node_username":
126 self.nodeUser = self.options[ key ]
127 elif key == "node_password":
128 self.nodePass = self.options[ key ]
129 elif key == "karafPrompt_username":
130 self.karafPromptUser = self.options[ key ]
131 elif key == "karafPrompt_password":
132 self.karafPromptPass = self.options[ key ]
Jon Hallca319892017-06-15 15:25:22 -0700133 elif key == "cluster_name":
134 prefix = self.options[ key ]
Jon Hall3c0114c2020-08-11 15:07:42 -0700135 elif key == "useDocker":
136 self.useDocker = "True" == self.options[ key ]
137 elif key == "docker_prompt":
138 self.dockerPrompt = self.options[ key ]
Jon Hall9b0de1f2020-08-24 15:38:04 -0700139 elif key == "web_user":
140 self.webUser = self.options[ key ]
141 elif key == "web_pass":
142 self.webPass = self.options[ key ]
Jon Halle37bd1f2020-09-10 12:16:41 -0700143 elif key == "nodes":
144 # Maximum number of ONOS nodes to run, if there is any
145 self.maxNodes = self.options[ key ]
Jon Hall06fd0df2021-01-25 15:50:06 -0800146 elif key == "kubeConfig":
147 self.kubeConfig = self.options[ key ]
Jon Hallca319892017-06-15 15:25:22 -0700148
Jon Hall0e240372018-05-02 11:21:57 -0700149 self.home = self.checkOptions( self.home, "~/onos" )
150 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
151 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
Siddesh52750622021-03-05 19:52:03 +0000152 self.nodeUser = self.checkOptions( self.nodeUser, self.user_name )
153 self.nodePass = self.checkOptions( self.nodePass, self.pwd )
154 self.karafPromptUser = self.checkOptions( self.karafPromptUser, self.user_name )
155 self.karafPromptPass = self.checkOptions( self.karafPromptPass, self.pwd )
Jon Hall9b0de1f2020-08-24 15:38:04 -0700156 self.webUser = self.checkOptions( self.webUser, "onos" )
157 self.webPass = self.checkOptions( self.webPass, "rocks" )
Jon Hallca319892017-06-15 15:25:22 -0700158 prefix = self.checkOptions( prefix, "ONOS" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700159 self.useDocker = self.checkOptions( self.useDocker, False )
160 self.dockerPrompt = self.checkOptions( self.dockerPrompt, "~/onos#" )
Jon Halle37bd1f2020-09-10 12:16:41 -0700161 self.maxNodes = int( self.checkOptions( self.maxNodes, 100 ) )
Jon Hall06fd0df2021-01-25 15:50:06 -0800162 self.kubeConfig = self.checkOptions( self.kubeConfig, None )
Jon Hallca319892017-06-15 15:25:22 -0700163
164 self.name = self.options[ 'name' ]
165
Jon Hallca319892017-06-15 15:25:22 -0700166
Jon Hall06fd0df2021-01-25 15:50:06 -0800167 if not self.kubeConfig:
168 # Grabs all OC environment variables based on max number of nodes
169 # TODO: Also support giving an ip range as a compononet option
170 self.onosIps = {} # Dictionary of all possible ONOS ip
171
172 try:
173 if self.maxNodes:
174 for i in range( self.maxNodes ):
175 envString = "OC" + str( i + 1 )
176 # If there is no more OC# then break the loop
177 if os.getenv( envString ):
178 self.onosIps[ envString ] = os.getenv( envString )
179 else:
180 self.maxNodes = len( self.onosIps )
181 main.log.info( self.name +
182 ": Created cluster data with " +
183 str( self.maxNodes ) +
184 " maximum number" +
185 " of nodes" )
186 break
187
188 if not self.onosIps:
189 main.log.info( "Could not read any environment variable"
190 + " please load a cell file with all" +
191 " onos IP" )
192 self.maxNodes = None
Jon Hallca319892017-06-15 15:25:22 -0700193 else:
Jon Hall06fd0df2021-01-25 15:50:06 -0800194 main.log.info( self.name + ": Found " +
195 str( self.onosIps.values() ) +
196 " ONOS IPs" )
197 except KeyError:
198 main.log.info( "Invalid environment variable" )
199 except Exception as inst:
200 main.log.error( "Uncaught exception: " + str( inst ) )
Jon Hallca319892017-06-15 15:25:22 -0700201 try:
202 if os.getenv( str( self.ip_address ) ) is not None:
203 self.ip_address = os.getenv( str( self.ip_address ) )
204 else:
205 main.log.info( self.name +
206 ": Trying to connect to " +
207 self.ip_address )
208 except KeyError:
209 main.log.info( "Invalid host name," +
210 " connecting to local host instead" )
211 self.ip_address = 'localhost'
212 except Exception as inst:
213 main.log.error( "Uncaught exception: " + str( inst ) )
214
215 self.handle = super( OnosClusterDriver, self ).connect(
216 user_name=self.user_name,
217 ip_address=self.ip_address,
218 port=self.port,
219 pwd=self.pwd,
220 home=self.home )
221
222 if self.handle:
223 self.handle.sendline( "cd " + self.home )
224 self.handle.expect( "\$" )
Jon Hall06fd0df2021-01-25 15:50:06 -0800225 if self.kubeConfig:
226 # Try to get # of onos nodes using given kubernetes configuration
227 names = self.kubectlGetPodNames( self.kubeConfig,
228 main.params[ 'kubernetes' ][ 'namespace' ],
229 main.params[ 'kubernetes' ][ 'appName' ] )
230 self.podNames = names
231 self.onosIps = {} # Dictionary of all possible ONOS ip
232 for i in range( 1, len( names ) + 1 ):
233 self.onosIps[ 'OC%i' % i ] = self.ip_address
234 self.maxNodes = len( names )
Jon Hallca319892017-06-15 15:25:22 -0700235 self.createComponents( prefix=prefix )
Jon Hall06fd0df2021-01-25 15:50:06 -0800236 if self.kubeConfig:
237 # Create Port Forwarding sessions for each controller
238 for node in self.nodes:
239 kubectl = node.k8s
240 index = self.nodes.index( node )
241 # Store each pod name in the k8s component
242 kubectl.podName = self.podNames[ index ]
243 # Setup port-forwarding and save the local port
244 guiPort = 8181
245 cliPort = 8101
246 portsList = ""
247 for port in [ guiPort, cliPort ]:
248 localPort = port + index + 1
249 portsList += "%s:%s " % ( localPort, port )
250 if port == cliPort:
251 node.CLI.karafPort = localPort
Jon Hall50a00012021-03-08 11:06:11 -0800252 elif port == guiPort:
253 node.REST.port = localPort
Jon Hall06fd0df2021-01-25 15:50:06 -0800254 main.log.info( "Setting up port forward for pod %s: [ %s ]" % ( self.podNames[ index ], portsList ) )
255 pf = kubectl.kubectlPortForward( self.podNames[ index ],
256 portsList,
257 kubectl.kubeConfig,
258 main.params[ 'kubernetes' ][ 'namespace' ] )
259 if not pf:
260 main.log.error( "Failed to create port forwarding" )
261 return main.FALSE
Jon Hallca319892017-06-15 15:25:22 -0700262 return self.handle
263 else:
264 main.log.info( "Failed to create ONOS handle" )
265 return main.FALSE
266 except pexpect.EOF:
267 main.log.error( self.name + ": EOF exception found" )
268 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700269 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700270 except Exception:
271 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700272 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700273
274 def disconnect( self ):
275 """
276 Called when Test is complete to disconnect the ONOS handle.
277 """
278 response = main.TRUE
279 try:
280 if self.handle:
281 self.handle.sendline( "" )
282 self.handle.expect( "\$" )
283 self.handle.sendline( "exit" )
284 self.handle.expect( "closed" )
285 except pexpect.EOF:
286 main.log.error( self.name + ": EOF exception found" )
287 main.log.error( self.name + ": " + self.handle.before )
288 except ValueError:
289 main.log.exception( "Exception in disconnect of " + self.name )
290 response = main.TRUE
291 except Exception:
292 main.log.exception( self.name + ": Connection failed to the host" )
293 response = main.FALSE
294 return response
295
Devin Lim142b5342017-07-20 15:22:39 -0700296 def setCliOptions( self, name, host ):
Jon Hallca319892017-06-15 15:25:22 -0700297 """
298 Parse the cluster options to create an ONOS cli component with the given name
299 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000300 main.componentDictionary[name] = main.componentDictionary[self.name].copy()
Devin Lim142b5342017-07-20 15:22:39 -0700301 clihost = main.componentDictionary[ name ][ 'COMPONENTS' ].get( "diff_clihost", "" )
302 if clihost == "True":
303 main.componentDictionary[ name ][ 'host' ] = host
Jon Hall06fd0df2021-01-25 15:50:06 -0800304 home = main.componentDictionary[name]['COMPONENTS'].get( "onos_home", None )
305 main.componentDictionary[name]['home'] = self.checkOptions( home, None )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000306 main.componentDictionary[name]['type'] = "OnosCliDriver"
Siddesh52750622021-03-05 19:52:03 +0000307 main.componentDictionary[name]['COMPONENTS']['karafPromptUser'] = self.karafPromptUser
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000308 main.componentDictionary[name]['connect_order'] = str( int( main.componentDictionary[name]['connect_order'] ) + 1 )
Jon Hallca319892017-06-15 15:25:22 -0700309
Devin Lim142b5342017-07-20 15:22:39 -0700310 def createCliComponent( self, name, host ):
Jon Hallca319892017-06-15 15:25:22 -0700311 """
312 Creates a new onos cli component.
313
314 Arguments:
315 name - The string of the name of this component. The new component
316 will be assigned to main.<name> .
317 In addition, main.<name>.name = str( name )
318 """
319 try:
320 # look to see if this component already exists
321 getattr( main, name )
322 except AttributeError:
323 # namespace is clear, creating component
Devin Lim142b5342017-07-20 15:22:39 -0700324 self.setCliOptions( name, host )
Jon Hallca319892017-06-15 15:25:22 -0700325 return main.componentInit( name )
326 except pexpect.EOF:
327 main.log.error( self.name + ": EOF exception found" )
328 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700329 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700330 except Exception:
331 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700332 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700333 else:
334 # namespace is not clear!
335 main.log.error( name + " component already exists!" )
Devin Lim44075962017-08-11 10:56:37 -0700336 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700337
338 def setRestOptions( self, name, host ):
339 """
340 Parse the cluster options to create an ONOS cli component with the given name
341 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000342 main.componentDictionary[name] = main.componentDictionary[self.name].copy()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000343 user = main.componentDictionary[name]['COMPONENTS'].get( "web_user", "onos" )
344 main.componentDictionary[name]['user'] = self.checkOptions( user, "onos" )
345 password = main.componentDictionary[name]['COMPONENTS'].get( "web_pass", "rocks" )
You Wangbef7ea12018-09-21 13:15:12 -0700346 main.componentDictionary[name]['password'] = self.checkOptions( password, "rocks" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000347 main.componentDictionary[name]['host'] = host
348 port = main.componentDictionary[name]['COMPONENTS'].get( "rest_port", "8181" )
349 main.componentDictionary[name]['port'] = self.checkOptions( port, "8181" )
350 main.componentDictionary[name]['type'] = "OnosRestDriver"
351 main.componentDictionary[name]['connect_order'] = str( int( main.componentDictionary[name]['connect_order'] ) + 1 )
Jon Hallca319892017-06-15 15:25:22 -0700352
353 def createRestComponent( self, name, ipAddress ):
354 """
355 Creates a new onos rest component.
356
357 Arguments:
358 name - The string of the name of this component. The new component
359 will be assigned to main.<name> .
360 In addition, main.<name>.name = str( name )
361 """
362 try:
363 # look to see if this component already exists
364 getattr( main, name )
365 except AttributeError:
366 # namespace is clear, creating component
367 self.setRestOptions( name, ipAddress )
368 return main.componentInit( name )
369 except pexpect.EOF:
370 main.log.error( self.name + ": EOF exception found" )
371 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700372 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700373 except Exception:
374 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700375 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700376 else:
377 # namespace is not clear!
378 main.log.error( name + " component already exists!" )
Devin Lim44075962017-08-11 10:56:37 -0700379 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700380
381 def setBenchOptions( self, name ):
382 """
383 Parse the cluster options to create an ONOS "bench" component with the given name
384 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000385 main.componentDictionary[name] = main.componentDictionary[self.name].copy()
386 main.componentDictionary[name]['type'] = "OnosDriver"
387 home = main.componentDictionary[name]['COMPONENTS'].get( "onos_home", None )
388 main.componentDictionary[name]['home'] = self.checkOptions( home, None )
389 main.componentDictionary[name]['connect_order'] = str( int( main.componentDictionary[name]['connect_order'] ) + 1 )
Jon Hallca319892017-06-15 15:25:22 -0700390
391 def createBenchComponent( self, name ):
392 """
393 Creates a new onos "bench" component.
394
395 Arguments:
396 name - The string of the name of this component. The new component
397 will be assigned to main.<name> .
398 In addition, main.<name>.name = str( name )
399 """
400 try:
401 # look to see if this component already exists
402 getattr( main, name )
403 except AttributeError:
404 # namespace is clear, creating component
405 self.setBenchOptions( name )
406 return main.componentInit( name )
407 except pexpect.EOF:
408 main.log.error( self.name + ": EOF exception found" )
409 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700410 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700411 except Exception:
412 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700413 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700414 else:
415 # namespace is not clear!
416 main.log.error( name + " component already exists!" )
Devin Lim44075962017-08-11 10:56:37 -0700417 main.cleanAndExit()
Jon Hallca319892017-06-15 15:25:22 -0700418
Jon Hall4173b242017-09-12 17:04:38 -0700419 def setServerOptions( self, name, ipAddress ):
420 """
421 Parse the cluster options to create an ONOS "server" component with the given name
422
423 Arguments:
424 name - The name of the server componet
425 ipAddress - The ip address of the server
426 """
427 main.componentDictionary[name] = main.componentDictionary[self.name].copy()
428 main.componentDictionary[name]['type'] = "OnosDriver"
429 main.componentDictionary[name]['host'] = ipAddress
430 home = main.componentDictionary[name]['COMPONENTS'].get( "onos_home", None )
431 main.componentDictionary[name]['home'] = self.checkOptions( home, None )
You Wang4cc61912018-08-28 10:10:58 -0700432 # TODO: for now we use karaf user name and password also for logging to the onos nodes
Jon Hall06fd0df2021-01-25 15:50:06 -0800433 # FIXME: We shouldn't use karaf* for this, what we want is another set of variables to
434 # login to a shell on the server ONOS is running on
Siddesh52750622021-03-05 19:52:03 +0000435 main.componentDictionary[name]['user'] = self.nodeUser
436 main.componentDictionary[name]['password'] = self.nodePass
Jon Hall4173b242017-09-12 17:04:38 -0700437 main.componentDictionary[name]['connect_order'] = str( int( main.componentDictionary[name]['connect_order'] ) + 1 )
Jon Hall4173b242017-09-12 17:04:38 -0700438
Jon Hall4173b242017-09-12 17:04:38 -0700439 def createServerComponent( self, name, ipAddress ):
440 """
441 Creates a new onos "server" component. This will be connected to the
442 node ONOS is running on.
443
444 Arguments:
445 name - The string of the name of this component. The new component
446 will be assigned to main.<name> .
447 In addition, main.<name>.name = str( name )
448 ipAddress - The ip address of the server
449 """
450 try:
451 # look to see if this component already exists
452 getattr( main, name )
453 except AttributeError:
454 # namespace is clear, creating component
455 self.setServerOptions( name, ipAddress )
456 return main.componentInit( name )
457 except pexpect.EOF:
458 main.log.error( self.name + ": EOF exception found" )
459 main.log.error( self.name + ": " + self.handle.before )
460 main.cleanAndExit()
461 except Exception:
462 main.log.exception( self.name + ": Uncaught exception!" )
463 main.cleanAndExit()
464 else:
465 # namespace is not clear!
466 main.log.error( name + " component already exists!" )
467 main.cleanAndExit()
468
Jon Hall4173b242017-09-12 17:04:38 -0700469 def createComponents( self, prefix='', createServer=True ):
Jon Hallca319892017-06-15 15:25:22 -0700470 """
471 Creates a CLI and REST component for each nodes in the cluster
472 """
473 # TODO: This needs work to support starting two seperate clusters in one test
474 cliPrefix = prefix + "cli"
475 restPrefix = prefix + "rest"
476 benchPrefix = prefix + "bench"
Jon Hall4173b242017-09-12 17:04:38 -0700477 serverPrefix = prefix + "server"
Jon Hall06fd0df2021-01-25 15:50:06 -0800478 k8sPrefix = prefix + "k8s"
Jon Hallca319892017-06-15 15:25:22 -0700479 for i in xrange( 1, self.maxNodes + 1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000480 cliName = cliPrefix + str( i )
Jon Hallca319892017-06-15 15:25:22 -0700481 restName = restPrefix + str( i )
482 benchName = benchPrefix + str( i )
Jon Hall4173b242017-09-12 17:04:38 -0700483 serverName = serverPrefix + str( i )
Jon Hall06fd0df2021-01-25 15:50:06 -0800484 if self.kubeConfig:
485 k8sName = k8sPrefix + str( i )
Jon Hallca319892017-06-15 15:25:22 -0700486
487 # Unfortunately this means we need to have a cell set beofre running TestON,
488 # Even if it is just the entire possible cluster size
489 ip = self.onosIps[ 'OC' + str( i ) ]
490
Devin Lim142b5342017-07-20 15:22:39 -0700491 cli = self.createCliComponent( cliName, ip )
Jon Hallca319892017-06-15 15:25:22 -0700492 rest = self.createRestComponent( restName, ip )
493 bench = self.createBenchComponent( benchName )
Jon Hall4173b242017-09-12 17:04:38 -0700494 server = self.createServerComponent( serverName, ip ) if createServer else None
Jon Hall06fd0df2021-01-25 15:50:06 -0800495 k8s = self.createServerComponent( k8sName, ip ) if self.kubeConfig else None
496 if self.kubeConfig:
497 k8s.kubeConfig = self.kubeConfig
498 k8s.podName = None
Jon Hall3c0114c2020-08-11 15:07:42 -0700499 self.nodes.append( Controller( prefix + str( i ), ip, cli, rest, bench, i - 1,
Jon Hall06fd0df2021-01-25 15:50:06 -0800500 self.user_name, server=server, k8s=k8s,
Jon Hall3c0114c2020-08-11 15:07:42 -0700501 dockerPrompt=self.dockerPrompt ) )