update link to upper-constraints.txt
[vfc/nfvo/lcm.git] / lcm / ns_vnfs / biz / create_vnfs.py
index 9952fd6..afb6739 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2016 ZTE Corporation.
+# Copyright 2016-2018 ZTE Corporation.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # 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 json
 import logging
+from threading import Thread
 import traceback
 import uuid
-from threading import Thread
 
-from lcm.ns.const import OWNER_TYPE
+from lcm.ns.enum import OWNER_TYPE
+from lcm.ns_vnfs.const import NFVO_VNF_INST_TIMEOUT_SECOND
+from lcm.ns_vnfs.biz.subscribe import SubscriptionCreation
+from lcm.ns_vnfs.biz.wait_job import wait_job_finish
+from lcm.ns_vnfs.enum import VNF_STATUS
 from lcm.pub.config.config import REPORT_TO_AAI
-from lcm.pub.database.models import NfInstModel, NSInstModel, VmInstModel, VNFFGInstModel, VLInstModel, OOFDataModel
+from lcm.pub.config.config import REG_TO_MSB_REG_PARAM, OOF_BASE_URL, OOF_PASSWD, OOF_USER
+from lcm.pub.config.config import CUST_NAME, CUST_LAT, CUST_LONG
+from lcm.pub.database.models import NfInstModel, NSInstModel, VNFFGInstModel, VLInstModel, OOFDataModel
+from lcm.jobs.enum import JOB_MODEL_STATUS, JOB_ACTION, JOB_PROGRESS, JOB_ERROR_CODE, JOB_TYPE
 from lcm.pub.exceptions import NSLCMException
 from lcm.pub.msapi.aai import create_vnf_aai
 from lcm.pub.msapi.extsys import get_vnfm_by_id
-from lcm.pub.msapi.resmgr import create_vnf, create_vnf_creation_info
 from lcm.pub.msapi.sdc_run_catalog import query_vnfpackage_by_id
 from lcm.pub.msapi.vnfmdriver import send_nf_init_request
-from lcm.pub.utils.jobutil import JOB_MODEL_STATUS, JobUtil, JOB_TYPE
-from lcm.pub.utils.share_lock import do_biz_with_share_lock
+from lcm.pub.utils import restcall
+from lcm.pub.utils.jobutil import JobUtil
+# from lcm.pub.utils.share_lock import do_biz_with_share_lock
 from lcm.pub.utils.timeutil import now_time
 from lcm.pub.utils.values import ignore_case_get
-from lcm.pub.utils import restcall
-from lcm.ns_vnfs.const import VNF_STATUS, NFVO_VNF_INST_TIMEOUT_SECOND, INST_TYPE, INST_TYPE_NAME
-from lcm.ns_vnfs.biz.wait_job import wait_job_finish
-from lcm.pub.config.config import REG_TO_MSB_REG_PARAM, OOF_BASE_URL, OOF_PASSWD, OOF_USER
+
 
 logger = logging.getLogger(__name__)
 
 
 def prepare_create_params():
     nf_inst_id = str(uuid.uuid4())
-    NfInstModel(nfinstid=nf_inst_id, status=VNF_STATUS.INSTANTIATING, create_time=now_time(),
-                lastuptime=now_time()).save()
-    job_id = JobUtil.create_job(INST_TYPE_NAME.VNF, JOB_TYPE.CREATE_VNF, nf_inst_id)
-    JobUtil.add_job_status(job_id, 0, 'create vnf record in database.', 0)
+    NfInstModel(
+        nfinstid=nf_inst_id,
+        status=VNF_STATUS.INSTANTIATING,
+        create_time=now_time(),
+        lastuptime=now_time()
+    ).save()
+    job_id = JobUtil.create_job(JOB_TYPE.VNF, JOB_ACTION.CREATE, nf_inst_id)
+    JobUtil.add_job_status(job_id, JOB_PROGRESS.STARTED, 'create vnf record in database.', JOB_ERROR_CODE.NO_ERROR)
     return nf_inst_id, job_id
 
 
@@ -79,13 +88,12 @@ class CreateVnfs(Thread):
             self.send_nf_init_request_to_vnfm()
             self.send_homing_request_to_OOF()
             self.send_get_vnfm_request_to_extsys()
-            self.send_create_vnf_request_to_resmgr()
             self.wait_vnfm_job_finish()
-            self.write_vnf_creation_info()
+            self.subscribe()
             self.save_info_to_db()
-            JobUtil.add_job_status(self.job_id, 100, 'vnf instantiation success', 0)
+            JobUtil.add_job_status(self.job_id, JOB_PROGRESS.FINISHED, 'vnf instantiation success', JOB_ERROR_CODE.NO_ERROR)
         except NSLCMException as e:
-            self.vnf_inst_failed_handle(e.message)
+            self.vnf_inst_failed_handle(e.args[0])
         except Exception:
             logger.error(traceback.format_exc())
             self.vnf_inst_failed_handle('unexpected exception')
@@ -99,27 +107,26 @@ class CreateVnfs(Thread):
         self.properties = ignore_case_get(additional_param, 'properties')
         self.vnfm_inst_id = ignore_case_get(additional_param, 'vnfmInstanceId')
         para = ignore_case_get(additional_param, 'inputs')
-        self.inputs = json.loads(para) if isinstance(para, (str, unicode)) else para
+        self.inputs = json.loads(para) if isinstance(para, str) else para
         self.vim_id = ignore_case_get(additional_param, 'vimId')
         self.vnfd_id = ignore_case_get(additional_param, 'vnfdId')
 
     def check_nf_name_exist(self):
         is_exist = NfInstModel.objects.filter(nf_name=self.vnf_inst_name).exists()
         if is_exist:
-            logger.error('The name of NF instance already exists.')
-            raise NSLCMException('The name of NF instance already exists.')
+            raise NSLCMException('The name of VNF instance already exists.')
 
     def get_vnfd_id(self):
         if self.vnfd_id:
             logger.debug("need not get vnfd_id")
-            self.nsd_model = {'ns_vnfs': [], 'ns_vls': [], 'vnffgs': []}
+            self.nsd_model = {'vnfs': [], 'vls': [], 'vnffgs': []}
             self.vnf_inst_name = self.vnfd_id + str(uuid.uuid4())
             self.vnf_inst_name = self.vnf_inst_name[:30]
             return
         ns_inst_info = NSInstModel.objects.get(id=self.ns_inst_id)
         self.ns_inst_name = ns_inst_info.name
         self.nsd_model = json.loads(ns_inst_info.nsd_model)
-        for vnf_info in self.nsd_model['ns_vnfs']:
+        for vnf_info in self.nsd_model['vnfs']:
             if self.vnf_id == vnf_info['vnf_id']:
                 self.vnfd_id = vnf_info['properties']['id']
                 if 'name' not in vnf_info['properties']:
@@ -130,7 +137,6 @@ class CreateVnfs(Thread):
                 self.vnf_inst_name = self.vnf_inst_name[:30]
                 self.vnf_inst_name = self.vnf_inst_name.replace("-", "_")
                 return
-        logger.error('Can not found vnf in nsd model')
         raise NSLCMException('Can not found vnf in nsd model')
 
     def check_nf_package_valid(self):
@@ -141,7 +147,7 @@ class CreateVnfs(Thread):
 
     def get_virtual_link_info(self, vnf_id):
         virtual_link_list, ext_virtual_link = [], []
-        for vnf_info in self.nsd_model['ns_vnfs']:
+        for vnf_info in self.nsd_model['vnfs']:
             if vnf_info['vnf_id'] != vnf_id:
                 continue
             for network_info in vnf_info['networks']:
@@ -157,17 +163,33 @@ class CreateVnfs(Thread):
                     'subnetwork_name': subnet_name,
                     'vl_instance_id': vl_instance_id
                 })
+                vim_id = json.JSONDecoder().decode(vl_instance.vimid) if isinstance(vl_instance.vimid, str) \
+                    else vl_instance.vimid
                 ext_virtual_link.append({
                     "vlInstanceId": vl_instance_id,
                     "resourceId": vl_instance.relatednetworkid,
                     "resourceSubnetId": vl_instance.relatedsubnetworkid,
                     "cpdId": self.get_cpd_id_of_vl(network_info['key_name']),
                     "vim": {
-                        "vimid": vl_instance.vimid
-                    }
+                        "vimid": vim_id
+                    },
+                    # SOL 003 align
+                    "id": vl_instance_id,
+                    "vimConnectionId": vl_instance.vimid,
+                    "extCps": self.get_cpds_of_vl(network_info['key_name'])
                 })
         return virtual_link_list, ext_virtual_link
 
+    def get_cpds_of_vl(self, vl_key):
+        extCps = []
+        logger.debug("vl_keya; %s" % vl_key)
+        for cpd in self.vnfd_model["vnf_exposed"]["external_cps"]:
+            logger.debug("exposed_cpd; %s" % cpd)
+            if vl_key == cpd["key_name"]:
+                cp = {"cpdId": cpd["cpd_id"], "cpConfig": []}
+                extCps.append(cp)
+        return extCps
+
     def get_cpd_id_of_vl(self, vl_key):
         for cpd in self.vnfd_model["vnf_exposed"]["external_cps"]:
             if vl_key == cpd["key_name"]:
@@ -175,9 +197,9 @@ class CreateVnfs(Thread):
         return ""
 
     def get_network_info_of_vl(self, vl_id):
-        for vnf_info in self.nsd_model['ns_vls']:
+        for vnf_info in self.nsd_model['vls']:
             if vnf_info['vl_id'] == vl_id:
-                return vnf_info['properties']['vl_profile']['networkName'], vnf_info['properties']['vl_profile']['initiationParameters']['name']
+                return vnf_info['properties']['vl_profile']['networkName'], vnf_info['properties']['vl_profile']['networkName']  # ['initiationParameters']['name']
         return '', ''
 
     def send_nf_init_request_to_vnfm(self):
@@ -186,6 +208,7 @@ class CreateVnfs(Thread):
             'vnfInstanceName': self.vnf_inst_name,
             'vnfPackageId': ignore_case_get(self.nf_package_info, "vnfPackageId"),
             'vnfDescriptorId': self.vnfd_id,
+            'flavourId': "default",
             'extVirtualLink': ext_virtual_link,
             'additionalParam': {
                 "properties": self.properties,
@@ -213,7 +236,7 @@ class CreateVnfs(Thread):
 
     def build_homing_request(self):
         id = str(uuid.uuid4())
-        callback_uri = " {vfcBaseUrl}/api/nslcm/v1/ns/placevnf"
+        callback_uri = "http://{vfcBaseUrl}/api/nslcm/v1/ns/placevnf"
         IP = REG_TO_MSB_REG_PARAM["nodes"][0]["ip"]
         PORT = REG_TO_MSB_REG_PARAM["nodes"][0]["port"]
         vfcBaseUrl = IP + ':' + PORT
@@ -222,13 +245,33 @@ class CreateVnfs(Thread):
         modelVersionId = "no-resourceModelVersionId"
         nsInfo = NSInstModel.objects.filter(id=self.ns_inst_id)
         placementDemand = {
-            "resourceModuleName": self.vnf_inst_name,
+            "resourceModuleName": self.vnf_id,
             "serviceResourceId": self.vnfm_nf_inst_id,
             "resourceModelInfo": {
                 "modelInvariantId": modelInvariantId,
                 "modelVersionId": modelVersionId
             }
         }
+
+        if self.vim_id:
+            # vim_info = self.vim_id.split("_")
+            # identifiers = list()
+            # identifiers.append(vim_info[1])
+            # cloudOwner = vim_info[0]
+            identifiers = list()
+            if isinstance(self.vim_id, str):
+                self.vim_id = json.loads(self.vim_id)
+            identifiers.append(self.vim_id['cloud_regionid'])
+            cloudOwner = self.vim_id['cloud_owner']
+            required_candidate = [
+                {
+                    "identifierType": "vimId",
+                    "cloudOwner": cloudOwner,
+                    "identifiers": identifiers
+                }
+            ]
+            placementDemand["requiredCandidates"] = required_candidate
+
         req_body = {
             "requestInfo": {
                 "transactionId": id,
@@ -241,6 +284,16 @@ class CreateVnfs(Thread):
                 "timeout": 600
             },
             "placementInfo": {
+                "requestParameters": {
+                    "customerLatitude": CUST_LAT,
+                    "customerLongitude": CUST_LONG,
+                    "customerName": CUST_NAME
+                },
+                "subscriberInfo": {
+                    "globalSubscriberId": "",
+                    "subscriberName": "",
+                    "subscriberCommonSiteId": "",
+                },
                 "placementDemands": []
             },
             "serviceInfo": {
@@ -258,8 +311,8 @@ class CreateVnfs(Thread):
             request_id=id,
             transaction_id=id,
             request_status="init",
-            request_module_name=self.vnfm_nf_inst_id,
-            service_resource_id=self.vnf_inst_name,
+            request_module_name=self.vnf_id,
+            service_resource_id=self.vnfm_nf_inst_id,
             vim_id="",
             cloud_owner="",
             cloud_region_id="",
@@ -271,9 +324,17 @@ class CreateVnfs(Thread):
         req_body = self.build_homing_request()
         base_url = OOF_BASE_URL
         resources = "/api/oof/v1/placement"
-        resp = restcall.call_req(base_url=base_url, user=OOF_USER, passwd=OOF_PASSWD,
-                                 auth_type=restcall.rest_oneway_auth, resource=resources,
-                                 method="POST", content=req_body, additional_headers="")
+        resp = restcall.call_req(base_url, OOF_USER, OOF_PASSWD, restcall.rest_no_auth, resources, "POST",
+                                 json.dumps(req_body), "")
+        # resp = restcall.call_req(
+        #     base_url=base_url,
+        #     user=OOF_USER,
+        #     passwd=OOF_PASSWD,
+        #     auth_type=restcall.rest_no_auth,
+        #     resource=resources,
+        #     method="POST",
+        #     content=json.dumps(req_body),
+        #     additional_headers="")
         resp_body = resp[-2]
         resp_status = resp[-1]
         if resp_body:
@@ -282,74 +343,55 @@ class CreateVnfs(Thread):
             logger.warn("Missing OOF sync response")
         logger.debug(("OOF sync response code is %s") % resp_status)
         if str(resp_status) != '202' or resp[0] != 0:
-            OOFDataModel.objects.filter(request_id=req_body["requestInfo"]["requestId"],
-                                        transaction_id=req_body["requestInfo"]["transactionId"]).update(
+            OOFDataModel.objects.filter(
+                request_id=req_body["requestInfo"]["requestId"],
+                transaction_id=req_body["requestInfo"]["transactionId"]
+            ).update(
                 request_status="failed",
                 vim_id="none",
                 cloud_owner="none",
                 cloud_region_id="none",
                 vdu_info="none"
             )
-            raise Exception("Received a Bad Sync from OOF with response code %s" % resp_status)
+            logger.error("Received a Bad Sync from OOF with response code %s" % resp_status)
         logger.info("Completed Homing request to OOF")
 
     def send_get_vnfm_request_to_extsys(self):
         resp_body = get_vnfm_by_id(self.vnfm_inst_id)
         self.vnfm_inst_name = ignore_case_get(resp_body, 'name')
 
-    def send_create_vnf_request_to_resmgr(self):
-        pkg_vnfd = self.vnfd_model
-        data = {
-            'nf_inst_id': self.nf_inst_id,
-            'vnfm_nf_inst_id': self.vnfm_nf_inst_id,
-            'vnf_inst_name': self.vnf_inst_name,
-            'ns_inst_id': self.ns_inst_id,
-            'ns_inst_name': self.ns_inst_name,
-            'nf_inst_name': self.vnf_inst_name,
-            'vnfm_inst_id': self.vnfm_inst_id,
-            'vnfm_inst_name': self.vnfm_inst_name,
-            'vnfd_name': pkg_vnfd['metadata'].get('name', 'undefined'),
-            'vnfd_id': self.vnfd_id,
-            'job_id': self.job_id,
-            'nf_inst_status': VNF_STATUS.INSTANTIATING,
-            'vnf_type': pkg_vnfd['metadata'].get('vnf_type', 'undefined'),
-            'nf_package_id': ignore_case_get(self.nf_package_info, "vnfPackageId")
-        }
-        create_vnf(data)
-
     def wait_vnfm_job_finish(self):
-        ret = wait_job_finish(vnfm_id=self.vnfm_inst_id,
-                              vnfo_job_id=self.job_id,
-                              vnfm_job_id=self.vnfm_job_id,
-                              progress_range=[10, 90],
-                              timeout=NFVO_VNF_INST_TIMEOUT_SECOND)
+        ret = wait_job_finish(
+            vnfm_id=self.vnfm_inst_id,
+            vnfo_job_id=self.job_id,
+            vnfm_job_id=self.vnfm_job_id,
+            progress_range=[10, 90],
+            timeout=NFVO_VNF_INST_TIMEOUT_SECOND)
 
         if ret != JOB_MODEL_STATUS.FINISHED:
-            logger.error('VNF instantiation failed on VNFM side. ret=[%s]', ret)
-            raise NSLCMException('VNF instantiation failed on VNFM side.')
+            raise NSLCMException('VNF instantiation failed from VNFM. The job status is %s' % ret)
 
-    def write_vnf_creation_info(self):
-        logger.debug("write_vnf_creation_info start")
-        vm_inst_infos = VmInstModel.objects.filter(insttype=INST_TYPE.VNF, instid=self.nf_inst_id)
+    def subscribe(self):
         data = {
-            'nf_inst_id': self.nf_inst_id,
-            'ns_inst_id': self.ns_inst_id,
-            'vnfm_inst_id': self.vnfm_inst_id,
-            'vms': [{'vmId': vm_inst_info.resouceid, 'vmName': vm_inst_info.vmname, 'vmStatus': 'ACTIVE'} for
-                    vm_inst_info in vm_inst_infos]}
-        create_vnf_creation_info(data)
-        logger.debug("write_vnf_creation_info end")
+            'vnfInstanceId': self.vnfm_nf_inst_id,
+            'vnfmId': self.vnfm_inst_id
+        }
+        try:
+            SubscriptionCreation(data).do_biz()
+        except NSLCMException as e:
+            logger.error("subscribe failed: %s", e.args[0])
+        except Exception as e:
+            logger.error("subscribe failed: %s", e.args[0])
 
     def save_info_to_db(self):
         logger.debug("save_info_to_db start")
-        do_biz_with_share_lock("set-vnflist-in-vnffginst-%s" % self.ns_inst_id, self.save_vnf_inst_id_in_vnffg)
+        do_biz_with_share_lock("set-vnflist-in-vnffginst-%s" % self.ns_inst_id, self.save_vnf_inst_id_in_vnffg)
         NfInstModel.objects.filter(nfinstid=self.nf_inst_id).update(status=VNF_STATUS.ACTIVE, lastuptime=now_time())
         logger.debug("save_info_to_db end")
 
     def vnf_inst_failed_handle(self, error_msg):
         logger.error('VNF instantiation failed, detail message: %s' % error_msg)
-        NfInstModel.objects.filter(nfinstid=self.nf_inst_id).update(status=VNF_STATUS.FAILED,
-                                                                    lastuptime=now_time())
+        NfInstModel.objects.filter(nfinstid=self.nf_inst_id).update(status=VNF_STATUS.FAILED, lastuptime=now_time())
         JobUtil.add_job_status(self.job_id, 255, 'VNF instantiation failed, detail message: %s' % error_msg, 0)
 
     def save_vnf_inst_id_in_vnffg(self):
@@ -359,7 +401,6 @@ class CreateVnfs(Thread):
                 continue
             vnffg_inst_infos = VNFFGInstModel.objects.filter(vnffgdid=vnffg['vnffg_Id'], nsinstid=self.ns_inst_id)
             if not vnffg_inst_infos:
-                logger.error('Vnffg instance not exist.')
                 raise NSLCMException('Vnffg instance not exist.')
             vnf_list = vnffg_inst_infos[0].vnflist
             vnffg_inst_infos.update(vnf_list=vnf_list + ',' + self.nf_inst_id if vnf_list else self.nf_inst_id)
@@ -404,6 +445,6 @@ class CreateVnfs(Thread):
                          % (self.nf_inst_id, self.ns_inst_id, resp_status))
         except NSLCMException as e:
             logger.debug("Fail to create vnf[%s] to aai, ns instance=[%s], detail message: %s"
-                         % (self.nf_inst_id, self.ns_inst_id, e.message))
+                         % (self.nf_inst_id, self.ns_inst_id, e.args[0]))
         except:
             logger.error(traceback.format_exc())