RIFT-16103 : VNFD VDU name is not passed as is in the config YAML input anymore
[osm/SO.git] / rwcm / plugins / rwconman / rift / tasklets / rwconmantasklet / rwconman_config.py
index 4848e9e..4b010b6 100644 (file)
@@ -509,7 +509,7 @@ class ConfigManagerConfig(object):
 
                 # Parse NSR
                 if nsr is not None:
-                    nsr_obj.set_nsr_name(nsr['nsd_name_ref'])
+                    nsr_obj.set_nsr_name(nsr['name_ref'])
                     nsr_dir = os.path.join(self._parent.cfg_dir, nsr_obj.nsr_name)
                     self._log.info("Checking NS config directory: %s", nsr_dir)
                     if not os.path.isdir(nsr_dir):
@@ -665,8 +665,8 @@ class ConfigManagerConfig(object):
             self._log.info("NSR(%s/%s) is deleted", nsr_obj.nsr_name, id)
 
     @asyncio.coroutine
-    def process_ns_initial_config(self, nsr_obj):
-        '''Apply the initial-config-primitives specified in NSD'''
+    def process_initial_config(self, nsr_obj, conf, script, vnfr_name=None):
+        '''Apply the initial-config-primitives specified in NSD or VNFD'''
 
         def get_input_file(parameters):
             inp = {}
@@ -674,9 +674,9 @@ class ConfigManagerConfig(object):
             # Add NSR name to file
             inp['nsr_name'] = nsr_obj.nsr_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 VNFR name if available
+            if vnfr_name:
+                inp['vnfr_name'] = vnfr_name
 
             # Add parameters for initial config
             inp['parameter'] = {}
@@ -684,9 +684,27 @@ class ConfigManagerConfig(object):
                 try:
                     inp['parameter'][parameter['name']] = parameter['value']
                 except KeyError as e:
-                    self._log.info("NSR {} initial config parameter {} with no value: {}".
-                                    format(nsr_obj.nsr_name, parameter, e))
+                    if vnfr_name:
+                        self._log.info("VNFR {} initial config parameter {} with no value: {}".
+                                       format(vnfr_name, parameter, e))
+                    else:
+                        self._log.info("NSR {} initial config parameter {} with no value: {}".
+                                       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'] = {}
@@ -711,17 +729,21 @@ class ConfigManagerConfig(object):
                         )
 
                 v['vdur'] = []
-                vdu_data = [(vdu['name'], vdu['management_ip'], vdu['vm_management_ip'], vdu['id'])
-                        for vdu in vnfr['vdur']]
-
-                for data in vdu_data:
-                    data = dict(zip(['name', 'management_ip', 'vm_management_ip', 'id'] , data))
-                    v['vdur'].append(data)
+                vdu_data = []
+                for vdu in vnfr['vdur']:
+                    d = {}
+                    for k in ['name','management_ip', 'vm_management_ip', 'id', 'vdu_id_ref']:
+                        if k in vdu:
+                            d[k] = vdu[k]
+                    vdu_data.append(d)
+                v['vdur'] = vdu_data
 
                 inp['vnfr'][vnfr['member_vnf_index_ref']] = v
 
-            self._log.debug("Input data for NSR {}: {}".
-                            format(nsr_obj.nsr_name, inp))
+
+            self._log.debug("Input data for {}: {}".
+                            format((vnfr_name if vnfr_name else nsr_obj.nsr_name),
+                                   inp))
 
             # Convert to YAML string
             yaml_string = yaml.dump(inp, default_flow_style=False)
@@ -730,91 +752,125 @@ class ConfigManagerConfig(object):
             tmp_file = None
             with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
                 tmp_file.write(yaml_string.encode("UTF-8"))
-            self._log.debug("Input file created for NSR {}: {}".
-                            format(nsr_obj.nsr_name, tmp_file.name))
+            self._log.debug("Input file created for {}: {}".
+                            format((vnfr_name if vnfr_name \
+                                    else nsr_obj.nsr_name),
+                                   tmp_file.name))
 
             return tmp_file.name
 
-        def get_script_file(script_name, nsd_name, nsd_id):
-            # Get the full path to the script
-            script = ''
-            # If script name starts with /, assume it is full path
-            if script_name[0] == '/':
-                # The script has full path, use as is
-                script = script_name
-            else:
-                script = os.path.join(os.environ['RIFT_ARTIFACTS'],
-                                      'launchpad/packages/nsd',
-                                      nsd_id,
-                                      nsd_name,
-                                      'scripts',
-                                      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)
-                    script = os.path.join(os.environ['RIFT_INSTALL'],
-                                          'usr/bin',
-                                          script_name)
-
-                # Seen cases in jenkins, where the script execution fails
-                # with permission denied. Setting the permission on script
-                # to make sure it has execute permission
-                perm = os.stat(script).st_mode
-                if not (perm  &  stat.S_IXUSR):
-                    self._log.warn("NSR {} initial config script {} " \
-                                  "without execute permission: {}".
-                                  format(nsr_id, script, perm))
-                    os.chmod(script, perm | stat.S_IXUSR)
-                return script
-
-        nsr_id = nsr_obj.nsr_id
-        nsr_name = nsr_obj.nsr_name
-        self._log.debug("Apply initial config for NSR {}({})".
-                        format(nsr_name, nsr_id))
-
-        # Fetch NSR
-        nsr = yield from self.cmdts_obj.get_nsr(nsr_id)
+        parameters = []
+        try:
+            parameters = conf['parameter']
+        except Exception as e:
+            self._log.debug("Parameter conf: {}, e: {}".
+                            format(conf, e))
+
+        inp_file = get_input_file(parameters)
+
+        cmd = "{0} {1}".format(script, inp_file)
+        self._log.debug("Running the CMD: {}".format(cmd))
+
+        process = yield from asyncio.create_subprocess_shell(cmd,
+                                                             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, rc, stderr)
+            self._log.error(msg)
+            raise InitialConfigError(msg)
+
+        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
+          script = ''
+          # If script name starts with /, assume it is full path
+          if script_name[0] == '/':
+              # The script has full path, use as is
+              script = script_name
+          else:
+              script = os.path.join(os.environ['RIFT_ARTIFACTS'],
+                                    'launchpad/packages',
+                                    d_type,
+                                    d_id,
+                                    d_name,
+                                    'scripts',
+                                    script_name)
+              self._log.debug("Checking for script at %s", script)
+              if not os.path.exists(script):
+                  self._log.warning("Did not find script %s", script)
+                  script = os.path.join(os.environ['RIFT_INSTALL'],
+                                        'usr/bin',
+                                        script_name)
+
+              # Seen cases in jenkins, where the script execution fails
+              # with permission denied. Setting the permission on script
+              # to make sure it has execute permission
+              perm = os.stat(script).st_mode
+              if not (perm  &  stat.S_IXUSR):
+                  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
+
+    @asyncio.coroutine
+    def process_ns_initial_config(self, nsr_obj):
+        '''Apply the initial-config-primitives specified in NSD'''
+
+        nsr = yield from self.cmdts_obj.get_nsr(nsr_obj.nsr_id)
+        if 'initial_config_primitive' not in nsr:
+            return
+
         if nsr is not None:
-            nsd = yield from self.cmdts_obj.get_nsd(nsr_id)
+            nsd = yield from self.cmdts_obj.get_nsd(nsr_obj.nsr_id)
+            for conf in nsr['initial_config_primitive']:
+                self._log.debug("NSR {} initial config: {}".
+                                format(nsr_obj.nsr_name, conf))
+                script = self.get_script_file(conf['user_defined_script'],
+                                              nsd.name,
+                                              nsd.id,
+                                              'nsd')
 
-            try:
-                # Check if initial config is present
-                # TODO (pjoseph): Sort based on seq
-                for conf in nsr['initial_config_primitive']:
-                    self._log.debug("Parameter conf: {}".
-                                    format(conf))
+                yield from self.process_initial_config(nsr_obj, conf, script)
 
-                    parameters = []
-                    try:
-                        parameters = conf['parameter']
-                    except Exception as e:
-                        self._log.debug("Parameter conf: {}, e: {}".
-                                        format(conf, e))
-                        pass
-
-                    inp_file = get_input_file(parameters)
-
-                    script = get_script_file(conf['user_defined_script'],
-                                             nsd.name,
-                                             nsd.id)
-
-                    cmd = "{0} {1}".format(script, inp_file)
-                    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 {} initial config using {} failed with {}". \
-                              format(nsr_name, script, process.returncode)
-                        self._log.error(msg)
-                        raise InitialConfigError(msg)
-                    else:
-                        os.remove(inp_file)
+    @asyncio.coroutine
+    def process_vnf_initial_config(self, nsr_obj, vnfr):
+        '''Apply the initial-config-primitives specified in VNFD'''
 
-            except KeyError as e:
-                self._log.debug("Did not find initial config {}".
-                                format(e))
+        vnfr_name = vnfr.name
+
+        vnfd = vnfr.vnfd
+        vnf_cfg = vnfd.vnf_configuration
+
+        for conf in vnf_cfg.initial_config_primitive:
+                self._log.debug("VNFR {} initial config: {}".
+                                format(vnfr_name, conf))
+
+                if not conf.user_defined_script:
+                    self._log.debug("VNFR {} did not fine user defined script: {}".
+                                    format(vnfr_name, conf))
+                    continue
+
+                script = self.get_script_file(conf.user_defined_script,
+                                              vnfd.name,
+                                              vnfd.id,
+                                              'vnfd')
+
+                yield from self.process_initial_config(nsr_obj,
+                                                       conf.as_dict(),
+                                                       script,
+                                                       vnfr_name=vnfr_name)
 
 
 class ConfigManagerNSR(object):
@@ -1292,6 +1348,11 @@ class XPaths(object):
         return ("D,/vnfr:vnfr-catalog/vnfr:vnfr" +
                 ("[vnfr:id='{}']".format(k) if k is not None else ""))
 
+    @staticmethod
+    def vnfd(k=None):
+        return ("C,/vnfd:vnfd-catalog/vnfd:vnfd" +
+                ("[vnfd:id='{}']".format(k) if k is not None else ""))
+
     @staticmethod
     def config_agent(k=None):
         return ("D,/rw-config-agent:config-agent/rw-config-agent:account" +
@@ -1377,6 +1438,15 @@ class ConfigManagerDTS(object):
             vnfr_msg = vnfrl[0]
         return vnfr_msg
 
+    @asyncio.coroutine
+    def get_vnfd(self, vnfd_id):
+        self._log.debug("Attempting to get VNFD: %s", vnfd_id)
+        vnfdl = yield from self._read_dts(XPaths.vnfd(vnfd_id), do_trace=False)
+        vnfd_msg = None
+        if len(vnfdl) > 0:
+            vnfd_msg = vnfdl[0]
+        return vnfd_msg
+
     @asyncio.coroutine
     def get_vlr(self, id):
         self._log.debug("Attempting to get VLR subnet: %s", id)