RIFT OSM R1 Initial Submission
Signed-off-by: Jeremy Mordkoff <jeremy.mordkoff@riftio.com>
diff --git a/rwcm/test/CMakeLists.txt b/rwcm/test/CMakeLists.txt
new file mode 100644
index 0000000..ead05af
--- /dev/null
+++ b/rwcm/test/CMakeLists.txt
@@ -0,0 +1,39 @@
+#
+# Copyright 2016 RIFT.IO Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Author(s): Manish Patel
+# Creation Date: 10/28/2015
+#
+
+cmake_minimum_required(VERSION 2.8)
+
+set(CONMAN_INSTALL "demos/conman")
+
+install(
+ FILES
+ start_cm_system.py
+ README.start_cm
+ DESTINATION ${CONMAN_INSTALL}
+ COMPONENT ${PKG_LONG_NAME})
+
+# set(NS_NAME ping_pong_nsd)
+# install(
+# FILES
+# ${NS_NAME}/configuration_input_params.yml
+# ${NS_NAME}/ping_vnfd_1_scriptconf_template.cfg
+# ${NS_NAME}/pong_vnfd_11_scriptconf_template.cfg
+# DESTINATION ${CONMAN_INSTALL}/${NS_NAME}
+# COMPONENT ${PKG_LONG_NAME})
+
diff --git a/rwcm/test/README.start_cm b/rwcm/test/README.start_cm
new file mode 100644
index 0000000..7a8098b
--- /dev/null
+++ b/rwcm/test/README.start_cm
@@ -0,0 +1,4 @@
+# Following example command line to launch the system in collapse mode.
+# Please tailor for expanded mode or any other requirements
+
+./start_cm_system.py -m ethsim -c --skip-prepare-vm
diff --git a/rwcm/test/cwims_juju_nsd/configuration_input_params.yml b/rwcm/test/cwims_juju_nsd/configuration_input_params.yml
new file mode 100644
index 0000000..bbbe5bc
--- /dev/null
+++ b/rwcm/test/cwims_juju_nsd/configuration_input_params.yml
@@ -0,0 +1,20 @@
+
+# This is input parameters file for Network Service configuration.
+# This file is formatted as below:
+
+# configuration_delay : 120 # Number of seconds to wait before applying configuration after NS is up
+# number_of_vnfs_to_be_configured : 1 # Total number of VNFs in this NS to be configured by Service Orchestrator
+# 1 : # Configuration Priority, order in which each VNF will be configured
+# name : vnfd_name # Name of the VNF
+# member_vnf_index : 11 # member index of the VNF that makes it unique (in case of multiple instances of same VNF)
+# configuration_type : scriptconf # Type of configuration (Currently supported values : scriptconf, netconf)
+#
+# Repeat VNF block for as many VNFs
+
+configuration_delay : 30
+number_of_vnfs_to_be_configured : 1
+1 :
+ name : cwims_vnfd
+ member_vnf_index : 1
+ configuration_type : jujuconf
+
diff --git a/rwcm/test/cwims_juju_nsd/cwaio_vnfd_1_juju_template.cfg b/rwcm/test/cwims_juju_nsd/cwaio_vnfd_1_juju_template.cfg
new file mode 100644
index 0000000..d32efe3
--- /dev/null
+++ b/rwcm/test/cwims_juju_nsd/cwaio_vnfd_1_juju_template.cfg
@@ -0,0 +1,23 @@
+ims-a:
+ deploy:
+ store: local
+ directory: /usr/rift/charms/cw-aio-proxy/trusty/
+ series: trusty
+ to: "lxc:0"
+
+ # Data under config passed as such during deployment
+ config:
+ proxied_ip: <rw_mgmt_ip>
+ home_domain: "ims.riftio.local"
+ base_number: "1234567000"
+ number_count: 1000
+
+ units:
+ - unit:
+ # Wait for each command to complete
+ wait: true
+ # Bail on failure
+ bail: true
+ actions:
+ - create-user: { number: "1234567001", password: "secret"}
+ - create-user: { number: "1234567002", password: "secret"}
diff --git a/rwcm/test/ping_pong_nsd/configuration_input_params.yml b/rwcm/test/ping_pong_nsd/configuration_input_params.yml
new file mode 100644
index 0000000..47c4fc3
--- /dev/null
+++ b/rwcm/test/ping_pong_nsd/configuration_input_params.yml
@@ -0,0 +1,23 @@
+
+# This is input parameters file for Network Service configuration.
+# This file is formatted as below:
+
+# configuration_delay : 120 # Number of seconds to wait before applying configuration after NS is up
+# number_of_vnfs_to_be_configured : 1 # Total number of VNFs in this NS to be configured by Service Orchestrator
+# 1 : # Configuration Priority, order in which each VNF will be configured
+# name : vnfd_name # Name of the VNF
+# member_vnf_index : 11 # member index of the VNF that makes it unique (in case of multiple instances of same VNF)
+# configuration_type : scriptconf # Type of configuration (Currently supported values : scriptconf, netconf)
+#
+# Repeat VNF block for as many VNFs
+
+configuration_delay : 30
+number_of_vnfs_to_be_configured : 2
+1 :
+ name : pong_vnfd
+ member_vnf_index : 2
+ configuration_type : scriptconf
+2 :
+ name : ping_vnfd
+ member_vnf_index : 1
+ configuration_type : scriptconf
diff --git a/rwcm/test/ping_pong_nsd/ping_vnfd_1_scriptconf_template.cfg b/rwcm/test/ping_pong_nsd/ping_vnfd_1_scriptconf_template.cfg
new file mode 100755
index 0000000..e6e9889
--- /dev/null
+++ b/rwcm/test/ping_pong_nsd/ping_vnfd_1_scriptconf_template.cfg
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+# Rest API config
+ping_mgmt_ip='<rw_mgmt_ip>'
+ping_mgmt_port=18888
+
+# VNF specific configuration
+pong_server_ip='<rw_connection_point_name pong_vnfd/cp0>'
+ping_rate=5
+server_port=5555
+
+# Make rest API calls to configure VNF
+curl -D /dev/stdout \
+ -H "Accept: application/vnd.yang.data+xml" \
+ -H "Content-Type: application/vnd.yang.data+json" \
+ -X POST \
+ -d "{\"ip\":\"$pong_server_ip\", \"port\":$server_port}" \
+ http://${ping_mgmt_ip}:${ping_mgmt_port}/api/v1/ping/server
+rc=$?
+if [ $rc -ne 0 ]
+then
+ echo "Failed to set server info for ping!"
+ exit $rc
+fi
+
+curl -D /dev/stdout \
+ -H "Accept: application/vnd.yang.data+xml" \
+ -H "Content-Type: application/vnd.yang.data+json" \
+ -X POST \
+ -d "{\"rate\":$ping_rate}" \
+ http://${ping_mgmt_ip}:${ping_mgmt_port}/api/v1/ping/rate
+rc=$?
+if [ $rc -ne 0 ]
+then
+ echo "Failed to set ping rate!"
+ exit $rc
+fi
+
+output=$(curl -D /dev/stdout \
+ -H "Accept: application/vnd.yang.data+xml" \
+ -H "Content-Type: application/vnd.yang.data+json" \
+ -X POST \
+ -d "{\"enable\":true}" \
+ http://${ping_mgmt_ip}:${ping_mgmt_port}/api/v1/ping/adminstatus/state)
+if [[ $output == *"Internal Server Error"* ]]
+then
+ echo $output
+ exit 3
+else
+ echo $output
+fi
+
+
+exit 0
diff --git a/rwcm/test/ping_pong_nsd/pong_vnfd_11_scriptconf_template.cfg b/rwcm/test/ping_pong_nsd/pong_vnfd_11_scriptconf_template.cfg
new file mode 100755
index 0000000..28b01df
--- /dev/null
+++ b/rwcm/test/ping_pong_nsd/pong_vnfd_11_scriptconf_template.cfg
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+# Rest API configuration
+pong_mgmt_ip='<rw_mgmt_ip>'
+pong_mgmt_port=18889
+
+# Test
+# username=<rw_username>
+# password=<rw_password>
+
+# VNF specific configuration
+pong_server_ip='<rw_connection_point_name pong_vnfd/cp0>'
+server_port=5555
+
+# Make Rest API calls to configure VNF
+curl -D /dev/stdout \
+ -H "Accept: application/vnd.yang.data+xml" \
+ -H "Content-Type: application/vnd.yang.data+json" \
+ -X POST \
+ -d "{\"ip\":\"$pong_server_ip\", \"port\":$server_port}" \
+ http://${pong_mgmt_ip}:${pong_mgmt_port}/api/v1/pong/server
+rc=$?
+if [ $rc -ne 0 ]
+then
+ echo "Failed to set server(own) info for pong!"
+ exit $rc
+fi
+
+curl -D /dev/stdout \
+ -H "Accept: application/vnd.yang.data+xml" \
+ -H "Content-Type: application/vnd.yang.data+json" \
+ -X POST \
+ -d "{\"enable\":true}" \
+ http://${pong_mgmt_ip}:${pong_mgmt_port}/api/v1/pong/adminstatus/state
+rc=$?
+if [ $rc -ne 0 ]
+then
+ echo "Failed to enable pong service!"
+ exit $rc
+fi
+
+exit 0
diff --git a/rwcm/test/rwso_test.py b/rwcm/test/rwso_test.py
new file mode 100755
index 0000000..e0c5011
--- /dev/null
+++ b/rwcm/test/rwso_test.py
@@ -0,0 +1,349 @@
+#!/usr/bin/env python3
+
+#
+# Copyright 2016 RIFT.IO Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+import asyncio
+import logging
+import os
+import sys
+import types
+import unittest
+import uuid
+
+import xmlrunner
+
+import gi.repository.CF as cf
+import gi.repository.RwDts as rwdts
+import gi.repository.RwMain as rwmain
+import gi.repository.RwManifestYang as rwmanifest
+import gi.repository.RwConmanYang as conmanY
+import gi.repository.RwLaunchpadYang as launchpadyang
+
+import rift.tasklets
+
+if sys.version_info < (3, 4, 4):
+ asyncio.ensure_future = asyncio.async
+
+
+class RWSOTestCase(unittest.TestCase):
+ """
+ DTS GI interface unittests
+
+ Note: Each tests uses a list of asyncio.Events for staging through the
+ test. These are required here because we are bring up each coroutine
+ ("tasklet") at the same time and are not implementing any re-try
+ mechanisms. For instance, this is used in numerous tests to make sure that
+ a publisher is up and ready before the subscriber sends queries. Such
+ event lists should not be used in production software.
+ """
+ rwmain = None
+ tinfo = None
+ schema = None
+ id_cnt = 0
+
+ @classmethod
+ def setUpClass(cls):
+ msgbroker_dir = os.environ.get('MESSAGE_BROKER_DIR')
+ router_dir = os.environ.get('ROUTER_DIR')
+ cm_dir = os.environ.get('SO_DIR')
+
+ manifest = rwmanifest.Manifest()
+ manifest.init_phase.settings.rwdtsrouter.single_dtsrouter.enable = True
+
+ cls.rwmain = rwmain.Gi.new(manifest)
+ cls.tinfo = cls.rwmain.get_tasklet_info()
+
+ # Run router in mainq. Eliminates some ill-diagnosed bootstrap races.
+ os.environ['RWDTS_ROUTER_MAINQ']='1'
+ cls.rwmain.add_tasklet(msgbroker_dir, 'rwmsgbroker-c')
+ cls.rwmain.add_tasklet(router_dir, 'rwdtsrouter-c')
+ cls.rwmain.add_tasklet(cm_dir, 'rwconmantasklet')
+
+ cls.log = rift.tasklets.logger_from_tasklet_info(cls.tinfo)
+ cls.log.setLevel(logging.DEBUG)
+
+ stderr_handler = logging.StreamHandler(stream=sys.stderr)
+ fmt = logging.Formatter(
+ '%(asctime)-23s %(levelname)-5s (%(name)s@%(process)d:%(filename)s:%(lineno)d) - %(message)s')
+ stderr_handler.setFormatter(fmt)
+ cls.log.addHandler(stderr_handler)
+ cls.schema = conmanY.get_schema()
+
+ def setUp(self):
+ def scheduler_tick(self, *args):
+ self.call_soon(self.stop)
+ self.run_forever()
+
+ self.loop = asyncio.new_event_loop()
+ self.loop.scheduler_tick = types.MethodType(scheduler_tick, self.loop)
+ self.loop.set_debug(True)
+ os.environ["PYTHONASYNCIODEBUG"] = "1"
+ asyncio_logger = logging.getLogger("asyncio")
+ asyncio_logger.setLevel(logging.DEBUG)
+
+ self.asyncio_timer = None
+ self.stop_timer = None
+ self.id_cnt += 1
+
+ @asyncio.coroutine
+ def wait_tasklets(self):
+ yield from asyncio.sleep(1, loop=self.loop)
+
+ def run_until(self, test_done, timeout=30):
+ """
+ Attach the current asyncio event loop to rwsched and then run the
+ scheduler until the test_done function returns True or timeout seconds
+ pass.
+
+ @param test_done - function which should return True once the test is
+ complete and the scheduler no longer needs to run.
+ @param timeout - maximum number of seconds to run the test.
+ """
+ def shutdown(*args):
+ if args:
+ self.log.debug('Shutting down loop due to timeout')
+
+ if self.asyncio_timer is not None:
+ self.tinfo.rwsched_tasklet.CFRunLoopTimerRelease(self.asyncio_timer)
+ self.asyncio_timer = None
+
+ if self.stop_timer is not None:
+ self.tinfo.rwsched_tasklet.CFRunLoopTimerRelease(self.stop_timer)
+ self.stop_timer = None
+
+ self.tinfo.rwsched_instance.CFRunLoopStop()
+
+ def tick(*args):
+ self.loop.call_later(0.1, self.loop.stop)
+ self.loop.run_forever()
+ if test_done():
+ shutdown()
+
+ self.asyncio_timer = self.tinfo.rwsched_tasklet.CFRunLoopTimer(
+ cf.CFAbsoluteTimeGetCurrent(),
+ 0.1,
+ tick,
+ None)
+
+ self.stop_timer = self.tinfo.rwsched_tasklet.CFRunLoopTimer(
+ cf.CFAbsoluteTimeGetCurrent() + timeout,
+ 0,
+ shutdown,
+ None)
+
+ self.tinfo.rwsched_tasklet.CFRunLoopAddTimer(
+ self.tinfo.rwsched_tasklet.CFRunLoopGetCurrent(),
+ self.stop_timer,
+ self.tinfo.rwsched_instance.CFRunLoopGetMainMode())
+
+ self.tinfo.rwsched_tasklet.CFRunLoopAddTimer(
+ self.tinfo.rwsched_tasklet.CFRunLoopGetCurrent(),
+ self.asyncio_timer,
+ self.tinfo.rwsched_instance.CFRunLoopGetMainMode())
+
+ self.tinfo.rwsched_instance.CFRunLoopRun()
+
+ self.assertTrue(test_done())
+
+ def new_tinfo(self, name):
+ """
+ Create a new tasklet info instance with a unique instance_id per test.
+ It is up to each test to use unique names if more that one tasklet info
+ instance is needed.
+
+ @param name - name of the "tasklet"
+ @return - new tasklet info instance
+ """
+ ret = self.rwmain.new_tasklet_info(name, RWSOTestCase.id_cnt)
+
+ log = rift.tasklets.logger_from_tasklet_info(ret)
+ log.setLevel(logging.DEBUG)
+
+ stderr_handler = logging.StreamHandler(stream=sys.stderr)
+ fmt = logging.Formatter(
+ '%(asctime)-23s %(levelname)-5s (%(name)s@%(process)d:%(filename)s:%(lineno)d) - %(message)s')
+ stderr_handler.setFormatter(fmt)
+ log.addHandler(stderr_handler)
+
+ return ret
+
+ def get_cloud_account_msg(self):
+ cloud_account = launchpadyang.CloudAccount()
+ cloud_account.name = "cloudy"
+ cloud_account.account_type = "mock"
+ cloud_account.mock.username = "rainy"
+ return cloud_account
+
+ def get_compute_pool_msg(self, name, pool_type):
+ pool_config = rmgryang.ResourcePools()
+ pool = pool_config.pools.add()
+ pool.name = name
+ pool.resource_type = "compute"
+ if pool_type == "static":
+ # Need to query CAL for resource
+ pass
+ else:
+ pool.max_size = 10
+ return pool_config
+
+ def get_network_pool_msg(self, name, pool_type):
+ pool_config = rmgryang.ResourcePools()
+ pool = pool_config.pools.add()
+ pool.name = name
+ pool.resource_type = "network"
+ if pool_type == "static":
+ # Need to query CAL for resource
+ pass
+ else:
+ pool.max_size = 4
+ return pool_config
+
+
+ def get_network_reserve_msg(self, xpath):
+ event_id = str(uuid.uuid4())
+ msg = rmgryang.VirtualLinkEventData()
+ msg.event_id = event_id
+ msg.request_info.name = "mynet"
+ msg.request_info.subnet = "1.1.1.0/24"
+ return msg, xpath.format(event_id)
+
+ def get_compute_reserve_msg(self,xpath):
+ event_id = str(uuid.uuid4())
+ msg = rmgryang.VDUEventData()
+ msg.event_id = event_id
+ msg.request_info.name = "mynet"
+ msg.request_info.image_id = "This is a image_id"
+ msg.request_info.vm_flavor.vcpu_count = 4
+ msg.request_info.vm_flavor.memory_mb = 8192*2
+ msg.request_info.vm_flavor.storage_gb = 40
+ c1 = msg.request_info.connection_points.add()
+ c1.name = "myport1"
+ c1.virtual_link_id = "This is a network_id"
+ return msg, xpath.format(event_id)
+
+ def test_create_resource_pools(self):
+ self.log.debug("STARTING - test_create_resource_pools")
+ tinfo = self.new_tinfo('poolconfig')
+ dts = rift.tasklets.DTS(tinfo, self.schema, self.loop)
+ pool_xpath = "C,/rw-resource-mgr:resource-mgr-config/rw-resource-mgr:resource-pools"
+ pool_records_xpath = "D,/rw-resource-mgr:resource-pool-records"
+ account_xpath = "C,/rw-launchpad:cloud-account"
+ compute_xpath = "D,/rw-resource-mgr:resource-mgmt/vdu-event/vdu-event-data[event-id='{}']"
+ network_xpath = "D,/rw-resource-mgr:resource-mgmt/vlink-event/vlink-event-data[event-id='{}']"
+
+ @asyncio.coroutine
+ def configure_cloud_account():
+ msg = self.get_cloud_account_msg()
+ self.log.info("Configuring cloud-account: %s",msg)
+ yield from dts.query_create(account_xpath,
+ rwdts.XactFlag.ADVISE,
+ msg)
+ yield from asyncio.sleep(3, loop=self.loop)
+
+ @asyncio.coroutine
+ def configure_compute_resource_pools():
+ msg = self.get_compute_pool_msg("virtual-compute", "dynamic")
+ self.log.info("Configuring compute-resource-pool: %s",msg)
+ yield from dts.query_create(pool_xpath,
+ rwdts.XactFlag.ADVISE,
+ msg)
+ yield from asyncio.sleep(3, loop=self.loop)
+
+
+ @asyncio.coroutine
+ def configure_network_resource_pools():
+ msg = self.get_network_pool_msg("virtual-network", "dynamic")
+ self.log.info("Configuring network-resource-pool: %s",msg)
+ yield from dts.query_create(pool_xpath,
+ rwdts.XactFlag.ADVISE,
+ msg)
+ yield from asyncio.sleep(3, loop=self.loop)
+
+
+ @asyncio.coroutine
+ def verify_resource_pools():
+ self.log.debug("Verifying test_create_resource_pools results")
+ res_iter = yield from dts.query_read(pool_records_xpath,)
+ for result in res_iter:
+ response = yield from result
+ records = response.result.records
+ #self.assertEqual(len(records), 2)
+ #names = [i.name for i in records]
+ #self.assertTrue('virtual-compute' in names)
+ #self.assertTrue('virtual-network' in names)
+ for record in records:
+ self.log.debug("Received Pool Record, Name: %s, Resource Type: %s, Pool Status: %s, Pool Size: %d, Busy Resources: %d",
+ record.name,
+ record.resource_type,
+ record.pool_status,
+ record.max_size,
+ record.busy_resources)
+ @asyncio.coroutine
+ def reserve_network_resources():
+ msg,xpath = self.get_network_reserve_msg(network_xpath)
+ self.log.debug("Sending create event to network-event xpath %s with msg: %s" % (xpath, msg))
+ yield from dts.query_create(xpath, rwdts.XactFlag.TRACE, msg)
+ yield from asyncio.sleep(3, loop=self.loop)
+ yield from dts.query_delete(xpath, rwdts.XactFlag.TRACE)
+
+ @asyncio.coroutine
+ def reserve_compute_resources():
+ msg,xpath = self.get_compute_reserve_msg(compute_xpath)
+ self.log.debug("Sending create event to compute-event xpath %s with msg: %s" % (xpath, msg))
+ yield from dts.query_create(xpath, rwdts.XactFlag.TRACE, msg)
+ yield from asyncio.sleep(3, loop=self.loop)
+ yield from dts.query_delete(xpath, rwdts.XactFlag.TRACE)
+
+ @asyncio.coroutine
+ def run_test():
+ yield from self.wait_tasklets()
+ yield from configure_cloud_account()
+ yield from configure_compute_resource_pools()
+ yield from configure_network_resource_pools()
+ yield from verify_resource_pools()
+ yield from reserve_network_resources()
+ yield from reserve_compute_resources()
+
+ future = asyncio.ensure_future(run_test(), loop=self.loop)
+ self.run_until(future.done)
+ if future.exception() is not None:
+ self.log.error("Caught exception during test")
+ raise future.exception()
+
+ self.log.debug("DONE - test_create_resource_pools")
+
+
+def main():
+ plugin_dir = os.path.join(os.environ["RIFT_INSTALL"], "usr/lib/rift/plugins")
+
+ if 'MESSAGE_BROKER_DIR' not in os.environ:
+ os.environ['MESSAGE_BROKER_DIR'] = os.path.join(plugin_dir, 'rwmsgbroker-c')
+
+ if 'ROUTER_DIR' not in os.environ:
+ os.environ['ROUTER_DIR'] = os.path.join(plugin_dir, 'rwdtsrouter-c')
+
+ if 'SO_DIR' not in os.environ:
+ os.environ['SO_DIR'] = os.path.join(plugin_dir, 'rwconmantasklet')
+
+ runner = xmlrunner.XMLTestRunner(output=os.environ["RIFT_MODULE_TEST"])
+ unittest.main(testRunner=runner)
+
+if __name__ == '__main__':
+ main()
+
+# vim: sw=4
diff --git a/rwcm/test/start_cm_system.py b/rwcm/test/start_cm_system.py
new file mode 100755
index 0000000..1975a0a
--- /dev/null
+++ b/rwcm/test/start_cm_system.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+
+#
+# Copyright 2016 RIFT.IO Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+import logging
+import os
+import sys
+
+import rift.vcs
+import rift.vcs.demo
+import rift.vcs.vms
+
+from rift.vcs.ext import ClassProperty
+
+logger = logging.getLogger(__name__)
+
+
+class ConfigManagerTasklet(rift.vcs.core.Tasklet):
+ """
+ This class represents SO tasklet.
+ """
+
+ def __init__(self, name='rwcmtasklet', uid=None):
+ """
+ Creates a PingTasklet object.
+
+ Arguments:
+ name - the name of the tasklet
+ uid - a unique identifier
+ """
+ super(ConfigManagerTasklet, self).__init__(name=name, uid=uid)
+
+ plugin_directory = ClassProperty('./usr/lib/rift/plugins/rwconmantasklet')
+ plugin_name = ClassProperty('rwconmantasklet')
+
+
+# Construct the system. This system consists of 1 cluster in 1
+# colony. The master cluster houses CLI and management VMs
+sysinfo = rift.vcs.SystemInfo(
+ colonies=[
+ rift.vcs.Colony(
+ clusters=[
+ rift.vcs.Cluster(
+ name='master',
+ virtual_machines=[
+ rift.vcs.VirtualMachine(
+ name='vm-so',
+ ip='127.0.0.1',
+ tasklets=[
+ rift.vcs.uAgentTasklet(),
+ ],
+ procs=[
+ rift.vcs.CliTasklet(),
+ rift.vcs.DtsRouterTasklet(),
+ rift.vcs.MsgBrokerTasklet(),
+ rift.vcs.RestconfTasklet(),
+ ConfigManagerTasklet()
+ ],
+ ),
+ ]
+ )
+ ]
+ )
+ ]
+ )
+
+
+# Define the generic portmap.
+port_map = {}
+
+
+# Define a mapping from the placeholder logical names to the real
+# port names for each of the different modes supported by this demo.
+port_names = {
+ 'ethsim': {
+ },
+ 'pci': {
+ }
+}
+
+
+# Define the connectivity between logical port names.
+port_groups = {}
+
+def main(argv=sys.argv[1:]):
+ logging.basicConfig(format='%(asctime)-15s %(levelname)s %(message)s')
+
+ # Create a parser which includes all generic demo arguments
+ parser = rift.vcs.demo.DemoArgParser()
+
+ args = parser.parse_args(argv)
+
+ #load demo info and create Demo object
+ demo = rift.vcs.demo.Demo(sysinfo=sysinfo,
+ port_map=port_map,
+ port_names=port_names,
+ port_groups=port_groups)
+
+ # Create the prepared system from the demo
+ system = rift.vcs.demo.prepared_system_from_demo_and_args(demo, args, netconf_trace_override=True)
+
+ # Start the prepared system
+ system.start()
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except rift.vcs.demo.ReservationError:
+ print("ERROR: unable to retrieve a list of IP addresses from the reservation system")
+ sys.exit(1)
+ except rift.vcs.demo.MissingModeError:
+ print("ERROR: you need to provide a mode to run the script")
+ sys.exit(1)
+ finally:
+ os.system("stty sane")
diff --git a/rwcm/test/tg_vrouter_ts_nsd/configuration_input_params.yml b/rwcm/test/tg_vrouter_ts_nsd/configuration_input_params.yml
new file mode 100644
index 0000000..b5a126f
--- /dev/null
+++ b/rwcm/test/tg_vrouter_ts_nsd/configuration_input_params.yml
@@ -0,0 +1,23 @@
+
+# This is input parameters file for Network Service configuration.
+# This file is formatted as below:
+
+# configuration_delay : 120 # Number of seconds to wait before applying configuration after NS is up
+# number_of_vnfs_to_be_configured : 1 # Total number of VNFs in this NS to be configured by Service Orchestrator
+# 1 : # Configuration Priority, order in which each VNF will be configured
+# name : vnfd_name # Name of the VNF
+# member_vnf_index : 11 # member index of the VNF that makes it unique (in case of multiple instances of same VNF)
+# configuration_type : scriptconf # Type of configuration (Currently supported values : scriptconf, netconf)
+#
+# Repeat VNF block for as many VNFs
+
+configuration_delay : 120
+number_of_vnfs_to_be_configured : 2
+1 :
+ name : trafsink_vnfd
+ member_vnf_index : 3
+ configuration_type : netconf
+2 :
+ name : trafgen_vnfd
+ member_vnf_index : 1
+ configuration_type : netconf
diff --git a/rwcm/test/tg_vrouter_ts_nsd/trafgen_vnfd_1_netconf_template.cfg b/rwcm/test/tg_vrouter_ts_nsd/trafgen_vnfd_1_netconf_template.cfg
new file mode 100644
index 0000000..02dfc85
--- /dev/null
+++ b/rwcm/test/tg_vrouter_ts_nsd/trafgen_vnfd_1_netconf_template.cfg
@@ -0,0 +1,79 @@
+ <vnf-config xmlns="http://riftio.com/ns/riftware-1.0/mano-base">
+ <vnf>
+ <name>trafgen</name>
+ <instance>0</instance>
+ <network-context xmlns="http://riftio.com/ns/riftware-1.0/rw-vnf-base-config">
+ <name>trafgen-lb</name>
+ <interface>
+ <name>N1TenGi-1</name>
+ <bind>
+ <port>trafgen_vnfd/cp0</port>
+ </bind>
+ </interface>
+ </network-context>
+ <port xmlns="http://riftio.com/ns/riftware-1.0/rw-vnf-base-config">
+ <name>trafgen_vnfd/cp0</name>
+ <open/>
+ <application>
+ <rx>rw_trafgen</rx>
+ <tx>rw_trafgen</tx>
+ </application>
+ <receive-q-length>2</receive-q-length>
+ <port-identity>
+ <ip-address><rw_connection_point_name trafgen_vnfd/cp0></ip-address>
+ <port-mode>direct</port-mode>
+ </port-identity>
+ <trafgen xmlns="http://riftio.com/ns/riftware-1.0/rw-trafgen">
+ <transmit-params>
+ <transmit-mode>
+ <range/>
+ </transmit-mode>
+ </transmit-params>
+ <range-template>
+ <destination-mac>
+ <dynamic>
+ <gateway><rw_connection_point_name vrouter_vnfd/cp0></gateway>
+ </dynamic>
+ </destination-mac>
+ <source-ip>
+ <start><rw_connection_point_name trafgen_vnfd/cp0></start>
+ <minimum><rw_connection_point_name trafgen_vnfd/cp0></minimum>
+ <maximum><rw_connection_point_name trafgen_vnfd/cp0></maximum>
+ <increment>1</increment>
+ </source-ip>
+ <destination-ip>
+ <start><rw_connection_point_name trafsink_vnfd/cp0></start>
+ <minimum><rw_connection_point_name trafsink_vnfd/cp0></minimum>
+ <maximum><rw_connection_point_name trafsink_vnfd/cp0></maximum>
+ <increment>1</increment>
+ </destination-ip>
+ <source-port>
+ <start>10000</start>
+ <minimum>10000</minimum>
+ <maximum>10128</maximum>
+ <increment>1</increment>
+ </source-port>
+ <destination-port>
+ <start>5678</start>
+ <minimum>5678</minimum>
+ <maximum>5678</maximum>
+ <increment>1</increment>
+ </destination-port>
+ <packet-size>
+ <start>512</start>
+ <minimum>512</minimum>
+ <maximum>512</maximum>
+ <increment>1</increment>
+ </packet-size>
+ </range-template>
+ </trafgen>
+ </port>
+ </vnf>
+ </vnf-config>
+ <logging xmlns="http://riftio.com/ns/riftware-1.0/rwlog-mgmt">
+ <sink>
+ <name>syslog</name>
+ <server-address><rw_mgmt_ip></server-address>
+ <port>514</port>
+ </sink>
+ </logging>
diff --git a/rwcm/test/tg_vrouter_ts_nsd/trafsink_vnfd_3_netconf_template.cfg b/rwcm/test/tg_vrouter_ts_nsd/trafsink_vnfd_3_netconf_template.cfg
new file mode 100644
index 0000000..6402201
--- /dev/null
+++ b/rwcm/test/tg_vrouter_ts_nsd/trafsink_vnfd_3_netconf_template.cfg
@@ -0,0 +1,42 @@
+ <vnf-config xmlns="http://riftio.com/ns/riftware-1.0/mano-base">
+ <vnf>
+ <name>trafsink</name>
+ <instance>0</instance>
+ <network-context xmlns="http://riftio.com/ns/riftware-1.0/rw-vnf-base-config">
+ <name>lb-trafsink</name>
+ <interface>
+ <name>N3TenGigi-1</name>
+ <bind>
+ <port>trafsink_vnfd/cp0</port>
+ </bind>
+ </interface>
+ </network-context>
+ <port xmlns="http://riftio.com/ns/riftware-1.0/rw-vnf-base-config">
+ <name>trafsink_vnfd/cp0</name>
+ <open/>
+ <application>
+ <rx>rw_trafgen</rx>
+ <tx>rw_trafgen</tx>
+ </application>
+ <receive-q-length>2</receive-q-length>
+ <port-identity>
+ <ip-address><rw_connection_point_name trafsink_vnfd/cp0></ip-address>
+ <port-mode>direct</port-mode>
+ </port-identity>
+ <trafgen xmlns="http://riftio.com/ns/riftware-1.0/rw-trafgen">
+ <receive-param>
+ <receive-echo>
+ <on/>
+ </receive-echo>
+ </receive-param>
+ </trafgen>
+ </port>
+ </vnf>
+ </vnf-config>
+ <logging xmlns="http://riftio.com/ns/riftware-1.0/rwlog-mgmt">
+ <sink>
+ <name>syslog</name>
+ <server-address><rw_mgmt_ip></server-address>
+ <port>514</port>
+ </sink>
+ </logging>