4 # Copyright 2016 RIFT.IO Inc
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
30 from rift
.rwlib
.util
import certs
31 import rift
.rwcal
.cloudsim
32 import rift
.rwcal
.cloudsim
.net
34 import rift
.vcs
.core
as core
38 import rift
.rwcal
.cloudsim
39 import rift
.rwcal
.cloudsim
.net
41 from rift
.vcs
.ext
import ClassProperty
44 logger
= logging
.getLogger(__name__
)
47 class NsmTasklet(rift
.vcs
.core
.Tasklet
):
49 This class represents a network services manager tasklet.
52 def __init__(self
, name
='network-services-manager', uid
=None,
54 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
55 data_storetype
=core
.DataStore
.NOSTORE
.value
,
58 Creates a NsmTasklet object.
61 name - the name of the tasklet
62 uid - a unique identifier
64 super(NsmTasklet
, self
).__init
__(name
=name
, uid
=uid
,
65 config_ready
=config_ready
,
66 recovery_action
=recovery_action
,
67 data_storetype
=data_storetype
,
70 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwnsmtasklet')
71 plugin_name
= ClassProperty('rwnsmtasklet')
74 class VnsTasklet(rift
.vcs
.core
.Tasklet
):
76 This class represents a network services manager tasklet.
79 def __init__(self
, name
='virtual-network-service', uid
=None,
81 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
82 data_storetype
=core
.DataStore
.NOSTORE
.value
,
85 Creates a VnsTasklet object.
88 name - the name of the tasklet
89 uid - a unique identifier
91 super(VnsTasklet
, self
).__init
__(name
=name
, uid
=uid
,
92 config_ready
=config_ready
,
93 recovery_action
=recovery_action
,
94 data_storetype
=data_storetype
,
97 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwvnstasklet')
98 plugin_name
= ClassProperty('rwvnstasklet')
101 class VnfmTasklet(rift
.vcs
.core
.Tasklet
):
103 This class represents a virtual network function manager tasklet.
106 def __init__(self
, name
='virtual-network-function-manager', uid
=None,
108 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
109 data_storetype
=core
.DataStore
.NOSTORE
.value
,
112 Creates a VnfmTasklet object.
115 name - the name of the tasklet
116 uid - a unique identifier
118 super(VnfmTasklet
, self
).__init
__(name
=name
, uid
=uid
,
119 config_ready
=config_ready
,
120 recovery_action
=recovery_action
,
121 data_storetype
=data_storetype
,
124 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwvnfmtasklet')
125 plugin_name
= ClassProperty('rwvnfmtasklet')
128 class ResMgrTasklet(rift
.vcs
.core
.Tasklet
):
130 This class represents a Resource Manager tasklet.
133 def __init__(self
, name
='Resource-Manager', uid
=None,
135 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
136 data_storetype
=core
.DataStore
.NOSTORE
.value
,
139 Creates a ResMgrTasklet object.
142 name - the name of the tasklet
143 uid - a unique identifier
145 super(ResMgrTasklet
, self
).__init
__(name
=name
, uid
=uid
,
146 config_ready
=config_ready
,
147 recovery_action
=recovery_action
,
148 data_storetype
=data_storetype
,
151 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwresmgrtasklet')
152 plugin_name
= ClassProperty('rwresmgrtasklet')
155 class ImageMgrTasklet(rift
.vcs
.core
.Tasklet
):
157 This class represents a Image Manager tasklet.
160 def __init__(self
, name
='Image-Manager', uid
=None,
162 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
163 data_storetype
=core
.DataStore
.NOSTORE
.value
,
166 Creates a Image Manager Tasklet object.
169 name - the name of the tasklet
170 uid - a unique identifier
172 super(ImageMgrTasklet
, self
).__init
__(
174 config_ready
=config_ready
,
175 recovery_action
=recovery_action
,
176 data_storetype
=data_storetype
,
179 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwimagemgrtasklet')
180 plugin_name
= ClassProperty('rwimagemgrtasklet')
183 class MonitorTasklet(rift
.vcs
.core
.Tasklet
):
185 This class represents a tasklet that is used to monitor NFVI metrics.
188 def __init__(self
, name
='nfvi-metrics-monitor', uid
=None,
190 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
191 data_storetype
=core
.DataStore
.NOSTORE
.value
,
194 Creates a MonitorTasklet object.
197 name - the name of the tasklet
198 uid - a unique identifier
201 super(MonitorTasklet
, self
).__init
__(name
=name
, uid
=uid
,
202 config_ready
=config_ready
,
203 recovery_action
=recovery_action
,
204 data_storetype
=data_storetype
,
207 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwmonitor')
208 plugin_name
= ClassProperty('rwmonitor')
210 class RedisServer(rift
.vcs
.NativeProcess
):
211 def __init__(self
, name
="RW.Redis.Server",
213 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
214 data_storetype
=core
.DataStore
.NOSTORE
.value
,
216 super(RedisServer
, self
).__init
__(
218 exe
="/usr/bin/redis-server",
219 config_ready
=config_ready
,
220 recovery_action
=recovery_action
,
221 data_storetype
=data_storetype
,
226 return "./usr/bin/active_redis.conf --port 9999"
229 class MonitoringParameterTasklet(rift
.vcs
.core
.Tasklet
):
231 This class represents a tasklet that is used to generate monitoring
235 def __init__(self
, name
='Monitoring-Parameter', uid
=None,
237 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
238 data_storetype
=core
.DataStore
.NOSTORE
.value
,
241 Creates a MonitoringParameterTasklet object.
244 name - the name of the tasklet
245 uid - a unique identifier
248 super(MonitoringParameterTasklet
, self
).__init
__(name
=name
, uid
=uid
,
249 config_ready
=config_ready
,
250 recovery_action
=recovery_action
,
251 data_storetype
=data_storetype
,
254 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwmonparam')
255 plugin_name
= ClassProperty('rwmonparam')
258 class AutoscalerTasklet(rift
.vcs
.core
.Tasklet
):
260 This class represents a tasklet that is used to generate monitoring
264 def __init__(self
, name
='Autoscaler', uid
=None,
266 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
267 data_storetype
=core
.DataStore
.NOSTORE
.value
,
270 Creates a MonitoringParameterTasklet object.
273 name - the name of the tasklet
274 uid - a unique identifier
277 super(AutoscalerTasklet
, self
).__init
__(name
=name
, uid
=uid
,
278 config_ready
=config_ready
,
279 recovery_action
=recovery_action
,
280 data_storetype
=data_storetype
,
283 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwautoscaler')
284 plugin_name
= ClassProperty('rwautoscaler')
286 class StagingManagerTasklet(rift
.vcs
.core
.Tasklet
):
288 A class that provide a simple staging area for all tasklets
291 def __init__(self
, name
='StagingManager', uid
=None,
293 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
294 data_storetype
=core
.DataStore
.NOSTORE
.value
,
297 Creates a StagingMangerTasklet object.
300 name - the name of the tasklet
301 uid - a unique identifier
304 super(StagingManagerTasklet
, self
).__init
__(name
=name
, uid
=uid
,
305 config_ready
=config_ready
,
306 recovery_action
=recovery_action
,
307 data_storetype
=data_storetype
,
310 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwstagingmgr')
311 plugin_name
= ClassProperty('rwstagingmgr')
313 def get_ui_ssl_args():
314 """Returns the SSL parameter string for launchpad UI processes"""
317 use_ssl
, certfile_path
, keyfile_path
= certs
.get_bootstrap_cert_and_key()
318 except certs
.BootstrapSslMissingException
:
319 logger
.error('No bootstrap certificates found. Disabling UI SSL')
322 # If we're not using SSL, no SSL arguments are necessary
326 return "--enable-https --keyfile-path=%s --certfile-path=%s" % (keyfile_path
, certfile_path
)
329 class UIServer(rift
.vcs
.NativeProcess
):
330 def __init__(self
, name
="RW.MC.UI",
332 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
333 data_storetype
=core
.DataStore
.NOSTORE
.value
,
335 super(UIServer
, self
).__init
__(
337 exe
="./usr/share/rw.ui/skyquake/scripts/launch_ui.sh",
338 config_ready
=config_ready
,
339 recovery_action
=recovery_action
,
340 data_storetype
=data_storetype
,
345 return get_ui_ssl_args()
347 class ConfigManagerTasklet(rift
.vcs
.core
.Tasklet
):
349 This class represents a Resource Manager tasklet.
352 def __init__(self
, name
='Configuration-Manager', uid
=None,
354 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
355 data_storetype
=core
.DataStore
.NOSTORE
.value
,
358 Creates a ConfigManagerTasklet object.
361 name - the name of the tasklet
362 uid - a unique identifier
364 super(ConfigManagerTasklet
, self
).__init
__(name
=name
, uid
=uid
,
365 config_ready
=config_ready
,
366 recovery_action
=recovery_action
,
367 data_storetype
=data_storetype
,
370 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwconmantasklet')
371 plugin_name
= ClassProperty('rwconmantasklet')
373 class PackageManagerTasklet(rift
.vcs
.core
.Tasklet
):
375 This class represents a Resource Manager tasklet.
378 def __init__(self
, name
='Package-Manager', uid
=None,
380 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
381 data_storetype
=core
.DataStore
.NOSTORE
.value
,
384 Creates a PackageManager object.
387 name - the name of the tasklet
388 uid - a unique identifier
390 super(PackageManagerTasklet
, self
).__init
__(name
=name
, uid
=uid
,
391 config_ready
=config_ready
,
392 recovery_action
=recovery_action
,
393 data_storetype
=data_storetype
,
396 plugin_directory
= ClassProperty('./usr/lib/rift/plugins/rwpkgmgr')
397 plugin_name
= ClassProperty('rwpkgmgr')
399 class GlanceServer(rift
.vcs
.NativeProcess
):
400 def __init__(self
, name
="glance-image-catalog",
402 recovery_action
=core
.RecoveryType
.FAILCRITICAL
.value
,
403 data_storetype
=core
.DataStore
.NOSTORE
.value
,
405 super(GlanceServer
, self
).__init
__(
407 exe
="./usr/bin/glance_start_wrapper",
408 config_ready
=config_ready
,
409 recovery_action
=recovery_action
,
410 data_storetype
=data_storetype
,
415 return "./etc/glance"
418 class Demo(rift
.vcs
.demo
.Demo
):
419 def __init__(self
, no_ui
=False, ha_mode
=None, mgmt_ip_list
=[], test_name
=None):
421 ConfigManagerTasklet(),
423 rift
.vcs
.DtsRouterTasklet(),
424 rift
.vcs
.MsgBrokerTasklet(),
425 rift
.vcs
.RestconfTasklet(),
427 rift
.vcs
.uAgentTasklet(),
428 rift
.vcs
.IdentityManagerTasklet(),
429 rift
.vcs
.ProjectManagerTasklet(),
430 rift
.vcs
.Launchpad(),
435 rift
.vcs
.DtsRouterTasklet(),
436 rift
.vcs
.MsgBrokerTasklet(),
439 datastore
= core
.DataStore
.BDB
.value
441 procs
.append(RedisServer())
442 datastore
= core
.DataStore
.REDIS
.value
445 procs
.append(UIServer())
448 VnfmTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
449 VnsTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
450 # MonitorTasklet(recovery_action=core.RecoveryType.RESTART.value, data_storetype=datastore),
451 MonitoringParameterTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
452 NsmTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
453 ResMgrTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
454 ImageMgrTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
455 AutoscalerTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
456 PackageManagerTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
457 StagingManagerTasklet(recovery_action
=core
.RecoveryType
.RESTART
.value
, data_storetype
=datastore
),
460 if not mgmt_ip_list
or len(mgmt_ip_list
) == 0:
461 mgmt_ip_list
.append("127.0.0.1")
463 colony
= rift
.vcs
.core
.Colony(name
='top', uid
=1)
465 lead_lp_vm
= rift
.vcs
.VirtualMachine(
466 name
='vm-launchpad-1',
469 restart_procs
=restart_procs
,
471 lead_lp_vm
.leader
= True
472 colony
.append(lead_lp_vm
)
475 stby_lp_vm
= rift
.vcs
.VirtualMachine(
476 name
='launchpad-vm-2',
481 # WA to Agent mode_active flag reset
482 stby_lp_vm
.add_tasklet(rift
.vcs
.uAgentTasklet(), mode_active
=False)
483 colony
.append(stby_lp_vm
)
486 stby_lp_vm_2
= rift
.vcs
.VirtualMachine(
487 name
='launchpad-vm-3',
492 stby_lp_vm_2
.add_tasklet(rift
.vcs
.uAgentTasklet(), mode_active
=False)
493 colony
.append(stby_lp_vm_2
)
495 sysinfo
= rift
.vcs
.SystemInfo(
497 zookeeper
=rift
.vcs
.manifest
.RaZookeeper(master_ip
=mgmt_ip_list
[0]),
500 multi_dtsrouter
=True,
501 mgmt_ip_list
=mgmt_ip_list
,
505 super(Demo
, self
).__init
__(
506 # Construct the system. This system consists of 1 cluster in 1
507 # colony. The master cluster houses CLI and management VMs
510 # Define the generic portmap.
513 # Define a mapping from the placeholder logical names to the real
514 # port names for each of the different modes supported by this demo.
522 # Define the connectivity between logical port names.
527 def main(argv
=sys
.argv
[1:]):
528 logging
.basicConfig(format
='%(asctime)-15s %(levelname)s %(message)s')
530 # Create a parser which includes all generic demo arguments
531 parser
= rift
.vcs
.demo
.DemoArgParser()
532 parser
.add_argument("--no-ui", action
='store_true')
533 args
= parser
.parse_args(argv
)
535 # Disable loading any kernel modules for the launchpad VM
536 # since it doesn't need it and it will fail within containers
537 os
.environ
["NO_KERNEL_MODS"] = "1"
539 cleanup_dir_name
= None
540 if os
.environ
["INSTALLDIR"] in ["/", "/home/rift", "/home/rift/.install",
541 "/usr/rift/build/fc20_debug/install/usr/rift", "/usr/rift"]:
542 cleanup_dir_name
= os
.environ
["INSTALLDIR"] + "/var/rift/"
544 if args
.test_name
and not cleanup_dir_name
:
545 cleanup_dir_name
= "find {rift_install}/var/rift -name '*{pattern}*' -type d".format( \
546 rift_install
=os
.environ
['RIFT_INSTALL'],
547 pattern
= args
.test_name
)
549 cleanup_dir_name
= subprocess
.check_output(cleanup_dir_name
, shell
=True)
550 cleanup_dir_name
= cleanup_dir_name
[:-1].decode("utf-8") + "/"
551 except Exception as e
:
552 print ("Directory not found exception occurred. Probably running for first time")
553 print ("Zookeper cleanup cmd = {}".format(cleanup_dir_name
))
555 if not cleanup_dir_name
:
556 cleanup_dir_name
= os
.environ
["INSTALLDIR"] + "/"
558 # Remove the persistent Redis data
560 for f
in os
.listdir(cleanup_dir_name
):
561 if f
.endswith(".aof") or f
.endswith(".rdb"):
562 os
.remove(os
.path
.join(cleanup_dir_name
, f
))
564 # Remove the persistant DTS recovery files
565 for f
in os
.listdir(cleanup_dir_name
):
566 if f
.endswith(".db"):
567 os
.remove(os
.path
.join(cleanup_dir_name
, f
))
569 shutil
.rmtree(os
.path
.join(cleanup_dir_name
, "zk/server-1"))
570 shutil
.rmtree(os
.path
.join(os
.environ
["INSTALLDIR"], "var/rift/tmp*"))
571 except FileNotFoundError
as e
:
573 except Exception as e
:
574 print ("Error while cleanup: {}".format(str(e
)))
576 ha_mode
= args
.ha_mode
577 mgmt_ip_list
= [] if not args
.mgmt_ip_list
else args
.mgmt_ip_list
579 #load demo info and create Demo object
580 demo
= Demo(args
.no_ui
, ha_mode
, mgmt_ip_list
, args
.test_name
)
582 system
= rift
.vcs
.demo
.prepared_system_from_demo_and_args(
584 northbound_listing
=["platform_schema_listing.txt",
585 "platform_mgmt_schema_listing.txt",
586 "cli_launchpad_schema_listing.txt"],
587 netconf_trace_override
=True)
589 # Search for externally accessible IP address with netifaces
590 gateways
= netifaces
.gateways()
591 # Check for default route facing interface and then get its ip address
592 if 'default' in gateways
:
593 interface
= gateways
['default'][netifaces
.AF_INET
][1]
594 confd_ip
= netifaces
.ifaddresses(interface
)[netifaces
.AF_INET
][0]['addr']
596 # no default gateway. Revert to 127.0.0.1
597 confd_ip
= "127.0.0.1"
598 # TODO: This need to be changed when launchpad starts running on multiple VMs
599 rift
.vcs
.logger
.configure_sink(config_file
=None, confd_ip
=confd_ip
)
601 # Start the prepared system
605 if __name__
== "__main__":
606 resource
.setrlimit(resource
.RLIMIT_CORE
, (resource
.RLIM_INFINITY
, resource
.RLIM_INFINITY
) )
607 os
.system('/usr/rift/bin/UpdateHostsFile')
610 except rift
.vcs
.demo
.ReservationError
:
611 print("ERROR: unable to retrieve a list of IP addresses from the reservation system")
613 except rift
.vcs
.demo
.MissingModeError
:
614 print("ERROR: you need to provide a mode to run the script")
617 os
.system("stty sane")