Merge "Bug 38 - SO:Add support for E1000 virtual interfaces"
authorvelandy <rajesh.velandy@riftio.com>
Wed, 14 Sep 2016 16:46:32 +0000 (18:46 +0200)
committerGerrit Code Review <root@osm.etsi.org>
Wed, 14 Sep 2016 16:46:32 +0000 (18:46 +0200)
16 files changed:
Makefile
common/python/CMakeLists.txt
common/python/rift/mano/dts/__init__.py
common/python/rift/mano/dts/subscriber/ro_account.py [new file with mode: 0644]
common/python/rift/mano/utils/juju_api.py
rwlaunchpad/plugins/rwlaunchpadtasklet/rift/package/store.py
rwlaunchpad/plugins/rwlaunchpadtasklet/rift/tasklets/rwlaunchpad/datacenters.py
rwlaunchpad/plugins/rwlaunchpadtasklet/rift/tasklets/rwlaunchpad/tasklet.py
rwlaunchpad/plugins/rwlaunchpadtasklet/scripts/CMakeLists.txt
rwlaunchpad/plugins/rwlaunchpadtasklet/scripts/onboard_pkg [new file with mode: 0644]
rwlaunchpad/plugins/rwlaunchpadtasklet/scripts/rwlaunchpad [deleted file]
rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/cloud.py
rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/openmano_nsm.py
rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/rwnsmtasklet.py
rwlaunchpad/plugins/yang/rw-launchpad.yang
rwlaunchpad/test/launchpad.py

index cf16aff..668bc8f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -33,7 +33,7 @@ RIFT_SHELL_EXE = $(TOP_ROOT_PATH)/rift-shell -b $(RIFT_BUILD) -i $(RIFT_INSTALL)
 CONFD = XML_ONLY
 
 BUILD_TYPE = Debug
-NOT_DEVELOPER_TYPE = TRUE
+NOT_DEVELOPER_TYPE = FALSE
 COVERAGE_BUILD = FALSE
 RIFT_AGENT_BUILD = $(CONFD)
 PROJECT_TOP_DIR = $(TOP_ROOT_PATH)
@@ -52,6 +52,9 @@ rw: cmake
 install:
        $(RIFT_SHELL_EXE) $(MAKE) -C $(RIFT_BUILD) install
 
+uninstall:
+       -xargs -i sh -c '[ -e {} ] && rm -fv {}' < $(RIFT_BUILD)/install_manifest.txt
+
 unittest:
        $(RIFT_SHELL_EXE) $(MAKE) -C $(RIFT_BUILD) rw.unittest
 
index 658d525..85ead68 100644 (file)
@@ -41,6 +41,7 @@ rift_python_install_tree(
     rift/mano/dts/subscriber/store.py
     rift/mano/dts/subscriber/ns_subscriber.py
     rift/mano/dts/subscriber/vnf_subscriber.py
+    rift/mano/dts/subscriber/ro_account.py
   COMPONENT ${PKG_LONG_NAME}
   PYTHON3_ONLY
   )
index e523034..a56fa04 100644 (file)
@@ -21,4 +21,5 @@ from .core import DtsHandler
 from .subscriber.core import AbstractOpdataSubscriber, AbstractConfigSubscriber
 from .subscriber.vnf_subscriber import VnfdCatalogSubscriber, VnfrCatalogSubscriber
 from .subscriber.ns_subscriber import NsrCatalogSubscriber, NsdCatalogSubscriber
-from .subscriber.store import SubscriberStore
\ No newline at end of file
+from .subscriber.store import SubscriberStore
+from .subscriber.ro_account import ROAccountConfigSubscriber
\ No newline at end of file
diff --git a/common/python/rift/mano/dts/subscriber/ro_account.py b/common/python/rift/mano/dts/subscriber/ro_account.py
new file mode 100644 (file)
index 0000000..575d649
--- /dev/null
@@ -0,0 +1,36 @@
+"""
+# 
+#   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.
+#
+
+@file ro_account.py
+@author Varun Prasad (varun.prasad@riftio.com)
+@date 09-Jul-2016
+
+"""
+
+import gi
+gi.require_version('RwDts', '1.0')
+from gi.repository import RwDts as rwdts
+
+from . import core
+
+class ROAccountConfigSubscriber(core.AbstractConfigSubscriber):
+
+    def key_name(self):
+        return "name"
+
+    def get_xpath(self):
+        return("C,/rw-launchpad:resource-orchestrator")
\ No newline at end of file
index 6eb3568..3d7b369 100644 (file)
@@ -259,7 +259,7 @@ class JujuApi(object):
                     mep =  '{}/model/{}/api'.format(self.endpoint,
                                                     m['model']['uuid'])
                     model = Env2(mep, env_uuid=m['model']['uuid'])
-                    l = model.login(self.password, user=self.user)
+                    l = model.login(self.secret, user=self.user)
                     break
 
             if model is None:
index 454546d..2436993 100644 (file)
@@ -107,7 +107,7 @@ class PackageFilesystemStore(object):
         """
         if package_id not in self._package_dirs:
             msg = "Package %s not found in %s" % (package_id, self._root_dir)
-            raise PackageStoreError(msg)
+            raise PackageNotFoundError(msg)
 
         package_files = self._get_package_files(package_id)
         package_dir = self._get_package_dir(package_id)
index 84fddb6..05731a6 100644 (file)
@@ -22,11 +22,12 @@ from gi.repository import (
     RwLaunchpadYang,
 )
 
+import rift.mano.dts as mano_dts
 import rift.openmano.openmano_client as openmano_client
 import rift.tasklets
 
 
-class DataCenterPublisher(object):
+class DataCenterPublisher(mano_dts.DtsHandler):
     """
     This class is reponsible for exposing the data centers associated with an
     openmano cloud account.
@@ -34,44 +35,33 @@ class DataCenterPublisher(object):
 
     XPATH = "D,/rw-launchpad:datacenters"
 
-    def __init__(self, tasklet):
+    def __init__(self, log, dts, loop):
         """Creates an instance of a DataCenterPublisher
 
         Arguments:
             tasklet - the tasklet that this publisher is registered for
 
         """
-        self.tasklet = tasklet
-        self.reg = None
-
-    @property
-    def dts(self):
-        """The DTS instance used by this tasklet"""
-        return self.tasklet.dts
-
-    @property
-    def log(self):
-        """The logger used by this tasklet"""
-        return self.tasklet.log
-
-    @property
-    def loop(self):
-        """The event loop used by this tasklet"""
-        return self.tasklet.loop
-
-    @property
-    def accounts(self):
-        """The known openmano cloud accounts"""
-        accounts = list()
-        for acc in self.tasklet.cloud_accounts:
-            if acc.account_type == "openmano":
-                accounts.append(acc.account_msg)
-
-        return accounts
+        super().__init__(log, dts, loop)
+
+        self._ro_sub = mano_dts.ROAccountConfigSubscriber(
+                        self.log,
+                        self.dts,
+                        self.loop,
+                        callback=self.on_ro_account_change
+                        )
+        self.ro_accounts = {}
+
+    def on_ro_account_change(self, ro_account, action):
+        if action in  [ RwDts.QueryAction.CREATE, RwDts.QueryAction.UPDATE ]:
+            self.ro_accounts[ro_account.name] = ro_account
+        elif action == RwDts.QueryAction.DELETE and ro_account.name in self.ro_accounts:
+            del self.ro_accounts[ro_account.name]
 
     @asyncio.coroutine
     def register(self):
         """Registers the publisher with DTS"""
+        yield from self._ro_sub.register()
 
         @asyncio.coroutine
         def on_prepare(xact_info, action, ks_path, msg):
@@ -82,10 +72,13 @@ class DataCenterPublisher(object):
 
                 # Iterate over the known openmano accounts and populate cloud
                 # account instances with the corresponding data center info
-                for account in self.accounts:
+                for _, account in self.ro_accounts.items():
+                    if account.account_type != "openmano":
+                        continue
+
                     try:
-                        cloud_account = RwLaunchpadYang.CloudAccount()
-                        cloud_account.name = account.name
+                        ro_account = RwLaunchpadYang.ROAccount()
+                        ro_account.name = account.name
 
                         # Create a client for this cloud account to query for
                         # the associated data centers
@@ -98,14 +91,14 @@ class DataCenterPublisher(object):
 
                         # Populate the cloud account with the data center info
                         for uuid, name in client.datacenter_list():
-                            cloud_account.datacenters.append(
+                            ro_account.datacenters.append(
                                     RwLaunchpadYang.DataCenter(
                                         uuid=uuid,
                                         name=name,
                                         )
                                     )
 
-                        datacenters.cloud_accounts.append(cloud_account)
+                        datacenters.ro_accounts.append(ro_account)
 
                     except Exception as e:
                         self.log.exception(e)
index ca09d33..9bcb2d3 100644 (file)
@@ -405,7 +405,7 @@ class LaunchpadTasklet(rift.tasklets.Tasklet):
         yield from self.vnfd_catalog_handler.register()
 
         self.log.debug("creating datacenter handler")
-        self.datacenter_handler = datacenters.DataCenterPublisher(self)
+        self.datacenter_handler = datacenters.DataCenterPublisher(self.log, self.dts, self.loop)
         yield from self.datacenter_handler.register()
 
         self.log.debug("creating cloud account handler")
index 549af43..40f9465 100644 (file)
@@ -19,7 +19,7 @@
 
 cmake_minimum_required(VERSION 2.8)
 
-install(PROGRAMS rwlaunchpad
+install(PROGRAMS onboard_pkg
         DESTINATION usr/bin
         COMPONENT ${INSTALL_COMPONENT}
         )
diff --git a/rwlaunchpad/plugins/rwlaunchpadtasklet/scripts/onboard_pkg b/rwlaunchpad/plugins/rwlaunchpadtasklet/scripts/onboard_pkg
new file mode 100644 (file)
index 0000000..b616ccf
--- /dev/null
@@ -0,0 +1,393 @@
+#!/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 argparse
+from contextlib import closing
+import logging
+import os.path
+import socket
+import subprocess
+import sys
+import uuid
+
+import json
+
+
+class OnboardPkgError(Exception):
+    pass
+
+
+class OnboardPkgInputError(OnboardPkgError):
+    pass
+
+
+class OnboardPkgMissingPkg(OnboardPkgError):
+    pass
+
+
+class OnboardPkgFileError(OnboardPkgError):
+    pass
+
+
+class OnboardPkgMissingDescId(OnboardPkgError):
+    pass
+
+
+class OnboardPkgInvalidDescId(OnboardPkgError):
+    pass
+
+
+class OnboardPkgMissingAcct(OnboardPkgError):
+    pass
+
+
+class OnboardPkgSoConnError(OnboardPkgError):
+    pass
+
+
+class OnboardPkgCmdError(OnboardPkgError):
+    pass
+
+
+class OnboardPkgUploadError(OnboardPkgError):
+    pass
+
+
+class OnboardPkgRcConnError(OnboardPkgError):
+    pass
+
+
+class OnboardPkgAcctError(OnboardPkgError):
+    pass
+
+
+class OnboardPkgNsdError(OnboardPkgError):
+    pass
+
+
+class OnboardPkgInstError(OnboardPkgError):
+    pass
+
+
+class OnboardPkgInvalidPort(OnboardPkgError):
+    pass
+
+
+class OnboardPackage:
+
+    def __init__(self,
+                 log,
+                 args):
+        self._log = log
+        self._args = args
+
+        self._pkgs = None
+
+        self._service_name = None
+        self._nsd_id = None
+        self._dc = None
+        self._account = None
+
+        self._ip = args.so_ip
+
+        self._uport = args.upload_port
+        self._upload_url = "curl -k https://{ip}:{port}/api/upload". \
+                            format(ip=self._ip,
+                                   port=self._uport)
+
+        self._rport = args.restconf_port
+        self._user = args.restconf_user
+        self._password = args.restconf_password
+        self._headers = '-H "accept: application/json"' + \
+                        ' -H "content-type: application/json"'
+        self._conf_url = "curl -k {header} --user \"{user}:{passwd}\" https://{ip}:{port}/api/config". \
+                       format(header=self._headers,
+                              user=self._user,
+                              passwd=self._password,
+                              ip=self._ip,
+                              port=self._rport)
+
+    @property
+    def log(self):
+        return self._log
+
+    def validate_args(self):
+        if args.upload_pkg is not None:
+            self._pkgs = args.upload_pkg
+            self.log.debug("Packages to upload: {}".format(self._pkgs))
+            if len(self._pkgs) == 0:
+                raise OnboardPkgMissingPkg('Need to specify atleast one package to upload')
+
+            for pkg in self._pkgs:
+                self.log.debug("Check pkg: {}".format(pkg))
+                if os.path.isfile(pkg) is False:
+                    raise OnboardPkgFileError("Unable to access file: {}".format(pkg))
+
+        if args.instantiate:
+            if args.nsd_id is None:
+                raise OnboardPkgMissingDescId("NS Descriptor ID required for instantiation")
+
+            if args.datacenter:
+                try:
+                    uuid.UUID(args.datacenter)
+                    self._dc = args.datacenter
+                except ValueError as e:
+                    raise OnboardPkgInvalidDescId("Invalid UUID for datacenter: {}".
+                                                  format(args.datacenter))
+
+            elif args.vim_account:
+                self._account = args.vim_account
+
+            else:
+                raise OnboardPkgMissingAcct("Datacenter or VIM account required for instantiation")
+
+            self._service_name = args.instantiate
+            self._nsd_id = args.nsd_id
+
+            self.log.debug("Instantiate NSD {} as {} on {}".format(self._nsd_id,
+                                                                   self._service_name,
+                                                                   self._account))
+
+        if (self._pkgs is None) and (self._nsd_id is None):
+            raise OnboardPkgInputError("Need to specify either upload-pkg or instantiate options")
+
+        # Validate the port numbers are correct
+        def valid_port(port):
+            if 1 <= port <= 65535:
+                return True
+            return False
+
+        if not valid_port(self._uport):
+            raise OnboardPkgInvalidPort("Invalid upload port: {}".format(self._uport))
+
+        if not valid_port(self._rport):
+            raise OnboardPkgInvalidPort("Invalid Restconf port: {}".format(self._rport))
+
+    def _exec_cmd(self, cmd):
+        self.log.debug("Execute command: {}".format(cmd))
+        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
+        (output, err) = proc.communicate()
+        rc = proc.returncode
+        self.log.debug("Command exec status: {}, {}, {}".format(rc, output, err))
+        if rc != 0:
+            raise OnboardPkgCmdError("Command {} failed ({}): {}".
+                                            format(cmd, rc, err))
+        return output.decode("utf-8")
+
+    def validate_connectivity(self):
+        if self._pkgs:
+            self.log.debug("Check connectivity to SO at {}:{}".
+                           format(self._ip, self._uport))
+
+            with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
+                if sock.connect_ex((self._ip, self._uport)) != 0:
+                    raise OnboardPkgSoConnError("Connection error to SO for upload at {}:{}".
+                                                format(self._ip, self._uport))
+            self.log.debug("Connection to SO upload port succeeded")
+
+        if self._nsd_id:
+            self.log.debug("Check connectivity to SO at {}:{}, with credentials {}:{}".
+                           format(self._ip, self._rport, self._user, self._password))
+
+            rest_url = self._conf_url+"/resource-orchestrator"
+            try:
+                output = self._exec_cmd(rest_url)
+                self.log.debug("Output of restconf validation: {}".
+                               format(output))
+                if len(output) != 0:
+                    js = json.loads(output)
+                    if "error" in js:
+                        raise OnboardPkgRcConnError("SO Restconf connect error: {}".
+                                                    format(js["error"]))
+
+                self.log.debug("Connection to SO restconf port succeeded")
+
+            except OnboardPkgCmdError as e:
+                self.log.error("SO restconf connect failed: {}".format(e))
+                raise OnboardPkgRcConnError("SO Restconf connect error: {}".
+                                            format(e))
+
+
+    def _upload_package(self, pkg):
+        upload_cmd = "{url} -F \"descriptor=@{pkg}\" ". \
+                                          format(url=self._upload_url,
+                                                 pkg=pkg)
+        self.log.debug("Upload pkg {} cmd: {}".format(pkg, upload_cmd))
+
+        output = self._exec_cmd(upload_cmd)
+
+        # Get the transaction id and wait for upload to complete
+        tx_id = json.loads(output)['transaction_id']
+
+        upload_status_url = "{url}/{id}/state". \
+                            format(url=self._upload_url,
+                                   id=tx_id)
+        status = ""
+        while status not in ['success', 'failure']:
+            output = self._exec_cmd(upload_status_url)
+            js = json.loads(output)
+            self.log.debug("Upload status of pkg {}: {}".format(pkg, js))
+            status = js['status']
+
+        if status != 'success':
+            raise OnboardPkgUploadError("Package {} upload failed: {}".
+                                        format(pkg, js['errors']))
+
+        self.log.info("Upload of package {} succeeded".format(pkg))
+
+    def upload_packages(self):
+        if self._pkgs is None:
+            self.log.debug("Upload packages not provided")
+            return
+
+        for pkg in self._pkgs:
+            self._upload_package(pkg)
+
+    def instantiate(self):
+        if self._nsd_id is None:
+            self.log.debug("No NSD ID provided for instantiation")
+            return
+
+        # TODO: Add check to see if datacenter is valid
+
+        # Check cloud account is valid, if provided
+        if self._account:
+            acct_url = "{url}/cloud/account/{acct}". \
+                       format(url=self._conf_url, acct=self._account)
+            output = self._exec_cmd(acct_url)
+            if (output is None) or (len(output) == 0):
+                # Account not found
+                raise OnboardPkgAcctError("VIM/Cloud account {} provided is not valid".
+                                          format(self._account))
+
+        # Check id NSD ID is valid
+        nsd_url = "{url}/nsd-catalog/nsd/{nsd_id}". \
+                  format(url=self._conf_url, nsd_id=self._nsd_id)
+        output = self._exec_cmd(nsd_url)
+        if (output is None) or (len(output) == 0):
+            # NSD not found
+            raise OnboardPkgNsdError("NSD ID {} provided is not valid".
+                                     format(self._nsd_id))
+
+        js = json.loads(output)
+        if "error" in js:
+            raise OnboardPkgNsdError("NSD ID {} error: {}".
+                                     format(self._nsd_id,
+                                            js['error']))
+
+        nsd = js['nsd:nsd']
+        self.log.debug("NSD to instantiate: {}".format(nsd))
+
+        # Generate a UUID for NS
+        ns_id = str(uuid.uuid4())
+        self.log.debug("NS instance uuid: {}".format(ns_id))
+
+        # Build the nsr post data
+        nsr = {"id": ns_id,
+               'name': self._service_name,
+               "nsd": nsd,}
+        if self._dc:
+            nsr['om-datacenter'] = self._dc
+        else:
+            nsr['cloud-account'] = self._account
+
+        data = {'nsr': [nsr]}
+
+        data_str = json.dumps(data)
+        self.log.debug("NSR post data: {}".format(data_str))
+
+        inst_url = "{url}/ns-instance-config -X POST -d '{data}'". \
+                   format(url=self._conf_url, data=data_str)
+        output = self._exec_cmd(inst_url)
+        self.log.debug("Instantiate output: {}".format(output))
+
+        js = json.loads(output)
+
+        if "last-error" in js:
+            msg = "Error instantiating NS as {} with NSD {}: ". \
+                  format(self._service_name, self._nsd_id,
+                         js["last-error"])
+            self.log.error(msg)
+            raise OnboardPkgInstError(msg)
+
+        elif "rpc-reply" in js:
+            reply = js["rpc-reply"]
+            if "rpc-error" in reply:
+                msg = "Error instantiating NS as {} with NSD {}: ". \
+                  format(self._service_name, self._nsd_id,
+                         reply["rpc-error"])
+                self.log.error(msg)
+                raise OnboardPkgInstError(msg)
+
+        self.log.info("Successfully initiated instantiation of NS as {} ({})".
+                      format(self._service_name, ns_id))
+
+    def process(self):
+        self.validate_args()
+        self.validate_connectivity()
+        self.upload_packages()
+        self.instantiate()
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description='Upload and instantiate NS')
+    parser.add_argument("-s", "--so-ip", default='localhost',
+                        help="SO Launchpad IP")
+
+    parser.add_argument("-u", "--upload-pkg", action='append',
+                        help="Descriptor packages to upload. " + \
+                        "If multiple descriptors are provided, they are uploaded in the same sequence.")
+
+    parser.add_argument("-i", "--instantiate",
+                        help="Instantiate a network service with the name")
+    parser.add_argument("-d", "--nsd-id",
+                        help="Network descriptor ID to instantiate")
+    parser.add_argument("-D", "--datacenter",
+                        help="OpenMano datacenter to instantiate on")
+    parser.add_argument("-c", "--vim-account",
+                        help="Cloud/VIM account to instantiate on")
+
+    parser.add_argument("-p", "--upload-port", default=4567, type=int,
+                        help="Upload port number, default 4567")
+    parser.add_argument("-P", "--restconf-port", default=8888, type=int,
+                        help="RESTconf port number, default 8888")
+    parser.add_argument("--restconf-user", default='admin',
+                        help="RESTconf user name, default admin")
+    parser.add_argument("--restconf-password", default='admin',
+                        help="RESTconf password, default admin")
+
+    parser.add_argument("-v", "--verbose", action='store_true',
+                        help="Show more logs")
+
+    args = parser.parse_args()
+
+    fmt = logging.Formatter(
+        '%(asctime)-23s %(levelname)-5s  (%(name)s@%(process)d:' \
+        '%(filename)s:%(lineno)d) - %(message)s')
+    stderr_handler = logging.StreamHandler(stream=sys.stderr)
+    stderr_handler.setFormatter(fmt)
+    logging.basicConfig(level=logging.INFO)
+    log = logging.getLogger('onboard-pkg')
+    log.addHandler(stderr_handler)
+    if args.verbose:
+        log.setLevel(logging.DEBUG)
+
+    log.debug("Input arguments: {}".format(args))
+
+    ob = OnboardPackage(log, args)
+    ob.process()
diff --git a/rwlaunchpad/plugins/rwlaunchpadtasklet/scripts/rwlaunchpad b/rwlaunchpad/plugins/rwlaunchpadtasklet/scripts/rwlaunchpad
deleted file mode 100755 (executable)
index 21a06b7..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/bin/bash
-
-# Script details
-SCRIPTNAME=`basename $0`
-SCRIPT=$0
-SCRIPT_ARGS=${@}
-
-# Initialize some of the variables
-if [ "$RIFT_LP_ADDR" = "" ]; then
-  RIFT_LP_ADDR="localhost"
-fi
-PKGS=()
-INSTANTIATE=0
-DESC_ID=""
-NS_NAME=""
-LOGGING=0
-RIFT_LP_PKG_UPLOAD_URL="https://${RIFT_LP_ADDR}:4567/api/upload"
-
-######################################################################
-#  Function:usage                                                    #
-#           Prints usage                                             #
-######################################################################
-function usage() {
-  cat <<EOF
-  usage $SCRIPTNAME [-h] [-r launchpad-ip][-u upload-package][-i ns-service-name [-d descriptor-id]][-l]
-       -h : show this message
-       -r : launchpad ip address  -  defaults to RIFT_LP_ADDR enviroment variable
-       -u : upload package with the package name specified
-       -i : Instantiate a network service with network service name
-       -d : Instantiate a network service with the specified descriptor
-       -l : Log to file
-EOF
-}
-
-######################################################################
-#  Function:validate_args                                            #
-#           Validates the passed arguments                           #
-######################################################################
-function validate_args () {
-  if [ "$RIFT_LP_ADDR" = "" ]; then
-    echo "RIFT LP address must be specified - set RIFT_LP_ADDR or specify -l option"
-    usage
-    exit 1
-  fi
-  if [ "${#PKGS[@]}" -eq 0 -a "${INSTANTIATE}" -eq 0 ]; then
-    echo "One of -u or -i option must be specified"
-    usage
-    exit 1
-  fi
-  if [ "${INSTANTIATE}" -eq 1 ]; then
-    if [ "${NS_NAME}" = "" -o "${DESC_ID}" = "" ]; then
-      echo "Must specify both descriptor id and ns service name when -i is specified"
-      usage
-      exit 1
-    fi
-  fi
-}
-
-######################################################################
-#  Function:upload_pacakage                                          #
-#           Uploads a package with the passed argument               #
-######################################################################
-function upload_package() {
-  if [ -z "$1" ]; then
-    echo "upload_package: package name should be passed in as an argument"
-    usage
-    exit 1
-  fi
-  PACKAGE=$1
-  curl --insecure -F "descriptor=@${PACKAGE}" ${RIFT_LP_PKG_UPLOAD_URL}
-}
-
-######################################################################
-#  Function:instantiate_ns                                           #
-#           Instantiates a netork service                            #
-######################################################################
-function instantiate_ns() {
-  echo "instantiate_ns need implementation"
-}
-
-
-while getopts ":hl:r:u:i:n:" OPTION
-do
-    case $OPTION in
-        h)
-            usage
-            exit 1
-            ;;
-        r)
-            RIFT_LP_ADDR=$OPTARG
-            RIFT_LP_PKG_UPLOAD_URL="https://${RIFT_LP_ADDR}:4567/api/upload"
-            ;;
-        u)
-            PKGS+=($OPTARG)
-            ;;
-        i)
-            INSTANTIATE=1
-            NS_NAME=$OPTARG
-            ;;
-        n)
-            DESC_ID=$OPTARG
-            ;;
-        l)
-            LOGGING=1
-            ;;
-        *)
-            usage
-            exit 1
-            ;;
-    esac
-done
-
-shift $((OPTIND-1))
-
-validate_args
-
-if [ $LOGGING -eq 1 ]; then
-    LOGDIR="/tmp"
-    LOGFILE="$LOGDIR/$SCRIPTNAME-$DATE.log"
-    echo "Logging to file $LOGFILE"
-
-    # Redirect stdout ( > ) and stderr to file
-    # and store the STDOUT and STDERR for later use
-    exec 3>&1
-    exec 4>&2
-    exec >$LOGFILE
-    exec 2>&1
-fi
-
-echo "Started at $DATE"
-
-# Iterate through the packages and upload them
-for PKG in "${PKGS[@]}"
-do
-  echo "Uploading package $PKG"
-  upload_package $PKG
-  echo ""
-done
-
-if [ "${INSTANTIATE}" -eq 1 ]; then
-  instantiate_ns $DESC_ID
-fi
-
-echo "Ended at $DATE"
index 5326ca1..5d73680 100644 (file)
@@ -124,15 +124,6 @@ class NsmPlugins(object):
         return self._plugin_classes[name]
 
 
-class ROAccountConfigSubscriber(mano_dts.AbstractConfigSubscriber):
-
-    def key_name(self):
-        return "name"
-
-    def get_xpath(self):
-        return("C,/rw-launchpad:resource-orchestrator")
-
-
 class CloudAccountConfigSubscriber:
     def __init__(self, log, dts, log_hdl):
         self._dts = dts
@@ -180,7 +171,7 @@ class ROAccountPluginSelector(object):
 
         self._nsm_plugins = NsmPlugins()
 
-        self._ro_sub = ROAccountConfigSubscriber(
+        self._ro_sub = mano_dts.ROAccountConfigSubscriber(
                 self._log,
                 self._dts,
                 self._loop,
index d3b86a6..c3b1603 100644 (file)
@@ -312,7 +312,7 @@ class OpenmanoNsr(object):
                     ip_profile = {}
                     if vld_msg.vim_network_name:
                         network["netmap-use"] = vld_msg.vim_network_name
-                    elif vlr._ip_profile.has_field("ip_profile_params"):
+                    elif vlr._ip_profile and vlr._ip_profile.has_field("ip_profile_params"):
                         ip_profile_params = vlr._ip_profile.ip_profile_params
                         if ip_profile_params.ip_version == "ipv6":
                             ip_profile['ip-version'] = "IPv6"
index bb21767..f4c0aef 100755 (executable)
@@ -25,6 +25,8 @@ import tempfile
 import time
 import uuid
 import yaml
+import requests
+import json
 
 
 from collections import deque
@@ -2900,8 +2902,10 @@ class NsrRpcDtsHandler(object):
     EXEC_NSR_CONF_O_XPATH = "O,/nsr:start-network-service"
     NETCONF_IP_ADDRESS = "127.0.0.1"
     NETCONF_PORT = 2022
+    RESTCONF_PORT = 8888
     NETCONF_USER = "admin"
     NETCONF_PW = "admin"
+    REST_BASE_V2_URL = 'https://{}:{}/v2/api/'.format("127.0.0.1",8888)
 
     def __init__(self, dts, log, loop, nsm):
         self._dts = dts
@@ -2913,6 +2917,7 @@ class NsrRpcDtsHandler(object):
         self._ns_regh = None
 
         self._manager = None
+        self._nsr_config_url = NsrRpcDtsHandler.REST_BASE_V2_URL + 'config/ns-instance-config'
 
         self._model = RwYang.Model.create_libncx()
         self._model.load_schema_ypbc(RwNsrYang.get_schema())
@@ -2958,6 +2963,12 @@ class NsrRpcDtsHandler(object):
         raise NsrInstantiationFailed("Failed to connect to Launchpad within %s seconds" %
                                       timeout_secs)
 
+    def _apply_ns_instance_config(self,payload_dict):
+        #self._log.debug("At apply NS instance config with payload %s",payload_dict)
+        req_hdr= {'accept':'application/vnd.yang.data+json','content-type':'application/vnd.yang.data+json'}
+        response=requests.post(self._nsr_config_url, headers=req_hdr, auth=('admin', 'admin'),data=payload_dict,verify=False)
+        return response
+
     @asyncio.coroutine
     def register(self):
         """ Register for NS monitoring read from dts """
@@ -2970,7 +2981,7 @@ class NsrRpcDtsHandler(object):
                     "nsr_id":str(uuid.uuid4())
                 })
             
-            if not ('name' in rpc_ip and  'nsd_ref' in rpc_ip and 'cloud_account' in rpc_ip):
+            if not ('name' in rpc_ip and  'nsd_ref' in rpc_ip and ('cloud_account' in rpc_ip or 'om_datacenter' in rpc_ip)):
                 self._log.error("Mandatory parameters name or nsd_ref or cloud account not found in start-network-service {}".format(rpc_ip))
                 
 
@@ -2979,10 +2990,11 @@ class NsrRpcDtsHandler(object):
             try:
                 # Add used value to the pool
                 self._log.debug("RPC output: {}".format(rpc_op))
+  
                 nsd_copy = self.nsm.get_nsd(rpc_ip.nsd_ref)
 
-                if not self._manager:
-                    self._manager = yield from self._connect()
+                #if not self._manager:
+                #    self._manager = yield from self._connect()
         
                 self._log.debug("Configuring ns-instance-config with name  %s nsd-ref: %s",
                         rpc_ip.name, rpc_ip.nsd_ref)
@@ -2996,17 +3008,26 @@ class NsrRpcDtsHandler(object):
                 ns_instance_config.nsd = NsrYang.YangData_Nsr_NsInstanceConfig_Nsr_Nsd()
                 ns_instance_config.nsd.from_dict(nsd_copy.msg.as_dict())
 
-                xml = ns_instance_config.to_xml_v2(self._model)
-                netconf_xml = self.wrap_netconf_config_xml(xml)
-
-                self._log.debug("Sending configure ns-instance-config xml to %s: %s",
-                        netconf_xml, NsrRpcDtsHandler.NETCONF_IP_ADDRESS)
-
-                response = yield from self._manager.edit_config(
-                           target="running",
-                           config=netconf_xml,
-                           )
-                self._log.debug("Received edit config response: %s", str(response))
+                payload_dict = ns_instance_config.to_json(self._model)
+                #xml = ns_instance_config.to_xml_v2(self._model)
+                #netconf_xml = self.wrap_netconf_config_xml(xml)
+
+                #self._log.debug("Sending configure ns-instance-config xml to %s: %s",
+                #        netconf_xml, NsrRpcDtsHandler.NETCONF_IP_ADDRESS)
+                self._log.debug("Sending configure ns-instance-config json to %s: %s",
+                        self._nsr_config_url,ns_instance_config)
+
+                #response = yield from self._manager.edit_config(
+                #           target="running",
+                #           config=netconf_xml,
+                #           )
+                response = yield from self._loop.run_in_executor(
+                    None,
+                    self._apply_ns_instance_config,
+                    payload_dict
+                    )
+                response.raise_for_status()
+                self._log.debug("Received edit config response: %s", response.json())
 
                 xact_info.respond_xpath(rwdts.XactRspCode.ACK,
                                         NsrRpcDtsHandler.EXEC_NSR_CONF_O_XPATH,
index 37a9c85..454aec1 100644 (file)
@@ -104,18 +104,18 @@ module rw-launchpad
     rwpb:msg-new DataCenters;
     config false;
 
-    list cloud-accounts {
+    list ro-accounts {
       description
           "A list of OpenMano cloud accounts that have data centers associated
           with them";
 
-      rwpb:msg-new CloudAccount;
+      rwpb:msg-new ROAccount;
       key "name";
 
       leaf name {
         description "The name of the cloud account";
         type leafref {
-          path "/rw-cloud:cloud/rw-cloud:account/rw-cloud:name";
+          path "/rw-launchpad:resource-orchestrator/rw-launchpad:name";
         }
       }
 
index 239f91b..8036792 100755 (executable)
@@ -470,20 +470,41 @@ def main(argv=sys.argv[1:]):
     # since it doesn't need it and it will fail within containers
     os.environ["NO_KERNEL_MODS"] = "1"
 
+
+    cleanup_dir_name = None
+    if os.environ["INSTALLDIR"] in ["/", "/home/rift", "/home/rift/.install"]:
+        cleanup_dir_name = os.environ["INSTALLDIR"] + "/"
+
+    if args.test_name and not cleanup_dir_name:
+        cleanup_dir_name = "find {rift_install}/var/rift -name '*{pattern}*' -type d".format( \
+            rift_install=os.environ['RIFT_INSTALL'],
+            pattern = args.test_name)
+        try:
+            cleanup_dir_name = subprocess.check_output(cleanup_dir_name, shell=True)
+            cleanup_dir_name = cleanup_dir_name[:-1].decode("utf-8") + "/"
+        except Exception as e:
+            print ("Directory not found exception occurred. Probably running for first time")
+            print ("Zookeper cleanup cmd = {}".format(cleanup_dir_name))
+    else:
+        cleanup_dir_name = os.environ["INSTALLDIR"] + "/"
+
     # Remove the persistent Redis data
-    for f in os.listdir(os.environ["INSTALLDIR"]):
-        if f.endswith(".aof") or f.endswith(".rdb"):
-           os.remove(os.path.join(os.environ["INSTALLDIR"], f))
-    
-    # Remove the persistant DTS recovery files 
-    for f in os.listdir(os.environ["INSTALLDIR"]):
-        if f.endswith(".db"):
-            os.remove(os.path.join(os.environ["INSTALLDIR"], f))
     try:
-        shutil.rmtree(os.path.join(os.environ["INSTALLDIR"], "zk/server-1"))
+        for f in os.listdir(cleanup_dir_name):
+            if f.endswith(".aof") or f.endswith(".rdb"):
+                os.remove(os.path.join(cleanup_dir_name, f))
+
+        # Remove the persistant DTS recovery files
+        for f in os.listdir(cleanup_dir_name):
+            if f.endswith(".db"):
+                os.remove(os.path.join(cleanup_dir_name, f))
+
+        shutil.rmtree(os.path.join(cleanup_dir_name, "zk/server-1"))
         shutil.rmtree(os.path.join(os.environ["INSTALLDIR"], "var/rift/tmp*"))
-    except:
+    except FileNotFoundError as e:
         pass
+    except Exception as e:
+        print ("Error while cleanup: {}".format(str(e)))
 
     ha_mode = args.ha_mode
     mgmt_ip_list = [] if not args.mgmt_ip_list else args.mgmt_ip_list