Merge branch 'v1.1'
authorvelandy <rajesh.velandy@riftio.com>
Fri, 10 Feb 2017 22:30:47 +0000 (22:30 +0000)
committervelandy <rajesh.velandy@riftio.com>
Fri, 10 Feb 2017 22:30:47 +0000 (22:30 +0000)
models/openmano/python/rift/openmano/openmano_client.py
models/plugins/yang/nsd.yang
models/plugins/yang/vnfd.yang
rwcm/plugins/rwconman/rift/tasklets/rwconmantasklet/riftcm_config_plugin.py
rwcm/plugins/rwconman/rift/tasklets/rwconmantasklet/rwconman_conagent.py
rwcm/plugins/rwconman/rift/tasklets/rwconmantasklet/rwconman_config.py
rwlaunchpad/plugins/rwlaunchpadtasklet/rift/tasklets/rwlaunchpad/onboard.py
rwlaunchpad/plugins/rwlaunchpadtasklet/scripts/onboard_pkg

index 09fb43d..8a89ee1 100755 (executable)
@@ -96,7 +96,7 @@ class OpenmanoHttpAPI(object):
 class OpenmanoCliAPI(object):
     """ This class implements the necessary funtionality to interact with  """
 
-    CMD_TIMEOUT = 30
+    CMD_TIMEOUT = 120
 
     def __init__(self, log, host, port, tenant):
         self._log = log
index 3d08627..0cadca3 100644 (file)
@@ -272,7 +272,11 @@ module nsd
                to leafref, whose target is in a different module.
                Once that is resovled this will switched to use
                leafref";
-          type string;
+          type leafref {
+            path "../../../constituent-vnfd" +
+                 "[member-vnf-index = current()/../member-vnf-index-ref]" +
+                 "/vnfd-id-ref";
+          }
         }
 
         leaf vnfd-connection-point-ref {
@@ -531,7 +535,9 @@ module nsd
           description
               "Identifier for the VNFD.";
           type leafref {
-            path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id";
+            path "../../../constituent-vnfd" + 
+                 "[member-vnf-index = current()/../member-vnf-index-ref]" +
+                 "/vnfd-id-ref";
           }
         }
       }
@@ -545,14 +551,14 @@ module nsd
       key vnf-source-ref;
       leaf vnf-source-ref {
         type leafref {
-          path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id";
+          path "../../constituent-vnfd/vnfd-id-ref";
         }
       }
       leaf vnf-depends-on-ref {
         description
             "Reference to VNF that sorce VNF depends.";
         type leafref {
-          path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:id";
+          path "../../constituent-vnfd/vnfd-id-ref";
         }
       }
     }
@@ -644,7 +650,11 @@ module nsd
                   to leafref, whose target is in a different module.
                   Once that is resovled this will switched to use
                   leafref";
-             type string;
+             type leafref {
+                path "../../../../constituent-vnfd" +
+                     "[member-vnf-index = current()/../member-vnf-index-ref]" +
+                     "/vnfd-id-ref";
+             }
            }
 
            leaf vnfd-connection-point-ref {
@@ -659,7 +669,11 @@ module nsd
                   to leafref, whose target is in a different module.
                   Once that is resovled this will switched to use
                   leafref";
-              type string;
+             type leafref {
+               path "/vnfd:vnfd-catalog/vnfd:vnfd" +
+                    "[vnfd:id = current()/../vnfd-id-ref]/" +
+                    "vnfd:connection-point/vnfd:name";
+             }
           }
         }
       } //rsp
@@ -709,7 +723,11 @@ module nsd
                   to leafref, whose target is in a different module.
                   Once that is resovled this will switched to use
                   leafref";
-          type string;
+          type leafref {
+              path "../../../constituent-vnfd" +
+                   "[member-vnf-index = current()/../member-vnf-index-ref]" +
+                   "/vnfd-id-ref";
+          }
         }
 
         leaf vnfd-connection-point-ref {
@@ -724,7 +742,11 @@ module nsd
                   to leafref, whose target is in a different module.
                   Once that is resovled this will switched to use
                   leafref";
-          type string;
+          type leafref {
+              path "/vnfd:vnfd-catalog/vnfd:vnfd" +
+                   "[vnfd:id = current()/../vnfd-id-ref]/" +
+                   "vnfd:connection-point/vnfd:name";
+          }
         }
 
         list match-attributes {
@@ -793,7 +815,7 @@ module nsd
 
       list vnfd-monitoring-param {
         description "A list of VNFD monitoring params";
-        key "vnfd-id-ref vnfd-monitoring-param-ref";
+        key "member-vnf-index-ref vnfd-monitoring-param-ref";
 
         leaf vnfd-id-ref {
           description
@@ -808,7 +830,11 @@ module nsd
               Once that is resolved this will switched to use
               leafref";
 
-          type yang:uuid;
+          type leafref {
+            path "../../../constituent-vnfd" +
+                 "[member-vnf-index = current()/../member-vnf-index-ref]" +
+                 "/vnfd-id-ref";
+          }
         }
 
         leaf vnfd-monitoring-param-ref {
@@ -820,10 +846,12 @@ module nsd
           }
         }
 
-        leaf-list member-vnf-index-ref {
-         description
-            "Optional reference to member-vnf within constituent-vnfds";
-         type uint64;
+        leaf member-vnf-index-ref {
+          description
+            "Mandatory reference to member-vnf within constituent-vnfds";
+          type leafref {
+            path "../../../constituent-vnfd/member-vnf-index";
+          }
         }
       }
     }
index 3fa141f..a825be1 100644 (file)
@@ -180,7 +180,7 @@ module vnfd
                 "Use the default management interface on this VDU.";
             leaf vdu-id {
               type leafref {
-                path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu/vnfd:id";
+                path "../../vdu/id";
               }
             }
           }
@@ -190,7 +190,7 @@ module vnfd
                 "Use the ip address associated with this connection point.";
             leaf cp {
               type leafref {
-                path "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:connection-point/vnfd:name";
+                path "../../connection-point/name";
               }
             }
           }
index f285afd..640e4b5 100644 (file)
@@ -190,6 +190,11 @@ class RiftCMConfigPluginBase(object):
     def vnfr(self, vnfr_id):
         raise NotImplementedError
 
+    @abc.abstractmethod
+    def get_Service_name(self):
+        """ Get the service name specific to the plugin """
+        pass
+
     @abc.abstractmethod
     @asyncio.coroutine
     def apply_config(self, agent_nsr, agent_vnfr, config, rpc_ip):
index 543e51b..5578a35 100644 (file)
@@ -141,19 +141,23 @@ class RiftCMConfigAgent(object):
                        .format(vnfr.name, method, rc))
         return rc
 
-    def is_vnfr_config_agent_managed(self, vnfr):
-        if (not vnfr.has_field('netconf') and
-            not vnfr.has_field('juju') and
-            not vnfr.has_field('script')):
-            return False
+    def get_vnfr_config_agent(self, vnfr):
+        if (not vnfr.has_field('netconf') and
+            not vnfr.has_field('juju') and
+            not vnfr.has_field('script')):
+            return False
 
         for agent in self._plugin_instances.values():
             try:
                 if agent.is_vnfr_managed(vnfr.id):
-                    return True
+                    return agent
             except Exception as e:
                 self._log.debug("Check if VNFR {} is config agent managed: {}".
                                 format(vnfr.name, e))
+
+    def is_vnfr_config_agent_managed(self, vnfr):
+        if self.get_vnfr_config_agent(vnfr):
+            return True
         return False
 
     def _on_config_agent(self, config_agent):
index 8b47e6b..7a24d70 100644 (file)
@@ -678,10 +678,6 @@ class ConfigManagerConfig(object):
             if vnfr_name:
                 inp['vnfr_name'] = vnfr_name
 
-            # TODO (pjoseph): Add config agents, we need to identify which all
-            # config agents are required from this NS and provide only those
-            inp['config-agent'] = {}
-
             # Add parameters for initial config
             inp['parameter'] = {}
             for parameter in parameters:
@@ -696,6 +692,20 @@ class ConfigManagerConfig(object):
                                        format(nsr_obj.nsr_name, parameter, e))
 
 
+            # Add config agents specific to each VNFR
+            inp['config-agent'] = {}
+            for vnfr in nsr_obj.agent_nsr.vnfrs:
+                # Get the config agent for the VNFR
+                # If vnfr name is specified, add only CA specific to that
+                if (vnfr_name is None) or \
+                   (vnfr_name == vnfr.name):
+                    agent = self._config_agent_mgr.get_vnfr_config_agent(vnfr.vnfr_msg)
+                    if agent:
+                        if agent.agent_type != riftcm_config_plugin.DEFAULT_CAP_TYPE:
+                            inp['config-agent'][vnfr.member_vnf_index] = agent.agent_data
+                            inp['config-agent'][vnfr.member_vnf_index] \
+                                ['service-name'] = agent.get_service_name(vnfr.id)
+
             # Add vnfrs specific data
             inp['vnfr'] = {}
             for vnfr in nsr_obj.vnfrs:
@@ -730,6 +740,7 @@ class ConfigManagerConfig(object):
 
                 inp['vnfr'][vnfr['member_vnf_index_ref']] = v
 
+
             self._log.debug("Input data for {}: {}".
                             format((vnfr_name if vnfr_name else nsr_obj.nsr_name),
                                    inp))
@@ -761,18 +772,24 @@ class ConfigManagerConfig(object):
         self._log.debug("Running the CMD: {}".format(cmd))
 
         process = yield from asyncio.create_subprocess_shell(cmd,
-                                                             loop=self._loop)
-        yield from process.wait()
-
-        if process.returncode:
-            msg = "NSR/VNFR {} initial config using {} failed with {}". \
+                                                             loop=self._loop,
+                                                             stdout=subprocess.PIPE,
+                                                             stderr=subprocess.PIPE)
+        stdout, stderr = yield from process.communicate()
+        rc = yield from process.wait()
+
+        if rc:
+            msg = "NSR/VNFR {} initial config using {} failed with {}: {}". \
                   format(vnfr_name if vnfr_name else nsr_obj.nsr_name,
-                         script, process.returncode)
+                         script, rc, stderr)
             self._log.error(msg)
             raise InitialConfigError(msg)
-        else:
-            # os.remove(inp_file)
-            pass
+
+        try:
+            os.remove(inp_file)
+        except Exception as e:
+            self._log.debug("Error removing input file {}: {}".
+                            format(inp_file, e))
 
     def get_script_file(self, script_name, d_name, d_id, d_type):
           # Get the full path to the script
@@ -791,7 +808,7 @@ class ConfigManagerConfig(object):
                                     script_name)
               self._log.debug("Checking for script at %s", script)
               if not os.path.exists(script):
-                  self._log.debug("Did not find script %s", script)
+                  self._log.warning("Did not find script %s", script)
                   script = os.path.join(os.environ['RIFT_INSTALL'],
                                         'usr/bin',
                                         script_name)
@@ -801,9 +818,9 @@ class ConfigManagerConfig(object):
               # to make sure it has execute permission
               perm = os.stat(script).st_mode
               if not (perm  &  stat.S_IXUSR):
-                  self._log.warn("NSR/VNFR {} initial config script {} " \
-                                "without execute permission: {}".
-                                format(d_name, script, perm))
+                  self._log.warning("NSR/VNFR {} initial config script {} " \
+                                    "without execute permission: {}".
+                                    format(d_name, script, perm))
                   os.chmod(script, perm | stat.S_IXUSR)
               return script
 
@@ -846,8 +863,8 @@ class ConfigManagerConfig(object):
                     continue
 
                 script = self.get_script_file(conf.user_defined_script,
-                                              vnfd.id,
                                               vnfd.name,
+                                              vnfd.id,
                                               'vnfd')
 
                 yield from self.process_initial_config(nsr_obj,
index f777c97..b12e192 100644 (file)
@@ -51,7 +51,7 @@ class DescriptorOnboarder(object):
             }
 
     HEADERS = {"content-type": "application/vnd.yang.data+json"}
-    TIMEOUT_SECS = 5
+    TIMEOUT_SECS = 60
     AUTH = ('admin', 'admin')
 
     def __init__(self, log, host="127.0.0.1", port=8008, use_ssl=False, ssl_cert=None, ssl_key=None):
index 741fbae..2b2eb91 100755 (executable)
@@ -108,15 +108,23 @@ class OnboardPackage:
         self._account = None
 
         self._ip = args.so_ip
+        self._api_server_ip = "localhost"
 
         self._uport = args.upload_port
+        self._onboard_port = args.onboard_port
+        self._rport = args.restconf_port
+        self._user = args.restconf_user
+        self._password = args.restconf_password
+        self._onboard_url = "curl -k --user \"{user}:{passwd}\" \"https://{ip}:{port}/composer/upload?api_server=https://{api_server_ip}&upload_server=https://{ip}\"". \
+                             format(ip=self._ip,
+                                    port=self._onboard_port,
+                                    user=self._user,
+                                    passwd=self._password,
+                                    api_server_ip=self._api_server_ip)
         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". \
@@ -236,8 +244,8 @@ class OnboardPackage:
 
 
     def _upload_package(self, pkg):
-        upload_cmd = "{url} -F \"descriptor=@{pkg}\" ". \
-                                          format(url=self._upload_url,
+        upload_cmd = "{url} -F \"package=@{pkg}\" ". \
+                                          format(url=self._onboard_url,
                                                  pkg=pkg)
         self.log.debug("Upload pkg {} cmd: {}".format(pkg, upload_cmd))
 
@@ -398,6 +406,8 @@ if __name__ == "__main__":
     parser.add_argument("-c", "--vim-account",
                         help="Cloud/VIM account to instantiate on")
 
+    parser.add_argument("-o", "--onboard-port", default=8443, type=int,
+                        help="Onboarding port number - node port number, default 8443")
     parser.add_argument("-p", "--upload-port", default=4567, type=int,
                         help="Upload port number, default 4567")
     parser.add_argument("-P", "--restconf-port", default=8008, type=int,