Merge "Fix ns term logic"
authorYan Yang <yangyanyj@chinamobile.com>
Tue, 13 Nov 2018 04:36:24 +0000 (04:36 +0000)
committerGerrit Code Review <gerrit@onap.org>
Tue, 13 Nov 2018 04:36:24 +0000 (04:36 +0000)
12 files changed:
lcm/ns/biz/ns_instant.py
lcm/ns/biz/ns_terminate.py
lcm/ns/tests/tests_ns_terminate.py
lcm/ns_pnfs/biz/create_pnf.py
lcm/ns_pnfs/serializers/pnf_serializer.py
lcm/ns_pnfs/tests/test_create_pnf.py
lcm/ns_vnfs/biz/create_vnfs.py
lcm/ns_vnfs/biz/grant_vnf.py
lcm/ns_vnfs/biz/subscribe.py
lcm/pub/msapi/nslcm.py
lcm/pub/msapi/sdc_run_catalog.py
lcm/workflows/build_in.py

index 1f72b32..419c4d5 100644 (file)
@@ -267,7 +267,6 @@ class InstantNSService(object):
                 if pnfd["properties"]["descriptor_id"] == pnf["pnfdId"]:
                     k = pnfd["pnf_id"]
                     pnf["nsInstances"] = self.ns_inst_id
-                    # todo pnf["pnfdInfoId"]
                     pnfs[k] = {
                         "type": "CreatePnf",
                         "input": {
index 18d9925..95f5e6a 100644 (file)
@@ -24,6 +24,7 @@ from lcm.pub.utils.jobutil import JobUtil
 from lcm.pub.utils.values import ignore_case_get
 from lcm.pub.utils import restcall
 from lcm.ns.const import OWNER_TYPE
+from lcm.pub.database.models import PNFInstModel
 
 JOB_ERROR = 255
 
@@ -48,6 +49,7 @@ class TerminateNsService(threading.Thread):
             self.cancel_sfc_list()
             self.cancel_vnf_list()
             self.cancel_vl_list()
+            self.cancel_pnf_list()
 
             NSInstModel.objects.filter(id=self.ns_inst_id).update(status='null')
             JobUtil.add_job_status(self.job_id, 100, "ns terminate ends.", '')
@@ -171,3 +173,21 @@ class TerminateNsService(threading.Thread):
         if job_timeout:
             logger.error("Job(%s) timeout", vnf_job_id)
         return job_end_normal
+
+    def cancel_pnf_list(self):
+        pnfinst_list = PNFInstModel.objects.filter(nsInstances__contains=self.ns_inst_id)
+        if len(pnfinst_list) > 0:
+            cur_progress = 90
+            step_progress = 5 / len(pnfinst_list)
+            for pnfinst in pnfinst_list:
+                delete_result = "fail"
+                try:
+                    ret = call_from_ns_cancel_resource('pnf', pnfinst.pnfId)
+                    if ret[0] == 0:
+                            delete_result = "success"
+                except Exception as e:
+                    logger.error("[cancel_pnf_list] error[%s]!" % e.message)
+                    logger.error(traceback.format_exc())
+                job_msg = "Delete pnfinst:[%s] %s" % (pnfinst.pnfId, delete_result)
+                cur_progress += step_progress
+                JobUtil.add_job_status(self.job_id, cur_progress, job_msg)
index 774fd60..7de0958 100644 (file)
@@ -101,13 +101,10 @@ class TestTerminateNsViews(TestCase):
     @mock.patch.object(TerminateNsService, 'run')
     def test_terminate_non_existing_ns_inst_id(self, mock_run):
         mock_run.re.return_value = "1"
-
         ns_inst_id = '100'
-
         req_data = {
             "terminationType": "forceful",
             "gracefulTerminationTimeout": "600"}
         response = self.client.post("/api/nslcm/v1/ns/%s/terminate" % ns_inst_id, data=req_data)
         self.failUnlessEqual(status.HTTP_202_ACCEPTED, response.status_code, response.data)
-
         self.assertRaises(NSInstModel.DoesNotExist, NSInstModel.objects.get, id=ns_inst_id)
index c920713..342d637 100644 (file)
@@ -23,11 +23,11 @@ logger = logging.getLogger(__name__)
 
 class CreatePnf(object):
     def __init__(self, data):
-        self.pnfId = data.get("pnfId"),
-        self.pnfName = data.get("pnfName"),
-        self.pnfdId = data.get("pnfdId"),
-        self.pnfdInfoId = data.get("pnfdInfoId"),
-        self.pnfProfileId = data.get("pnfProfileId"),
+        self.pnfId = data.get("pnfId")
+        self.pnfName = data.get("pnfName")
+        self.pnfdId = data.get("pnfdId")
+        self.pnfdInfoId = data.get("pnfdInfoId", "")
+        self.pnfProfileId = data.get("pnfProfileId", "")
         self.cpInfo = data.get("cpInfo", "")
         self.emsId = data.get("emsId", "")
         self.nsInstances = data.get("nsInstances")
@@ -41,7 +41,7 @@ class CreatePnf(object):
         return GetPnf({"pnfId": self.pnfId}, True).do_biz()
 
     def check_pnfd_valid(self):
-        pnf_package_info = query_pnf_descriptor({"pnfId": self.pnfdInfoId})
+        pnf_package_info = query_pnf_descriptor({"pnfdId": self.pnfdId})
         if not pnf_package_info:
             raise NSLCMException("Pnfd(%s) does not exist." % self.pnfdInfoId)
 
@@ -59,7 +59,8 @@ class CreatePnf(object):
             if not pnfInstances.filter(nsInstances__contains=self.nsInstances):
                 for pnfInstance in pnfInstances:
                     new_nsInstances = pnfInstance.nsInstances + "," + self.nsInstances
-                    pnfInstance.update(nsInstances=new_nsInstances)
+                    pnfInstance.nsInstances = new_nsInstances
+                    pnfInstance.save()
         else:
             PNFInstModel(pnfId=self.pnfId,
                          pnfName=self.pnfName,
index b3d7410..1a5a981 100644 (file)
@@ -19,9 +19,9 @@ class PnfInstanceSerializer(serializers.Serializer):
     pnfId = serializers.CharField(help_text="Identifier of the PNF.", required=True, allow_null=False)
     pnfName = serializers.CharField(help_text="Name of the PNF.", required=True, allow_null=True)
     pnfdId = serializers.CharField(help_text="Identifier of the PNFD on which the PNF is based.", required=True, allow_null=True)
-    pnfdInfoId = serializers.CharField(help_text="Identifier of the PNFD information object related to this PNF.", required=True, allow_null=True)
+    pnfdInfoId = serializers.CharField(help_text="Identifier of the PNFD information object related to this PNF.", required=False, allow_null=True, allow_blank=True)
     pnfProfileId = serializers.CharField(help_text="Identifier of the related PnfProfile in the NSD on which the PNF is based.", required=True, allow_null=True)
-    cpInfo = serializers.CharField(help_text="Information on the external CP of the PNF.", required=True, allow_null=True)
+    cpInfo = serializers.CharField(help_text="Information on the external CP of the PNF.", required=False, allow_null=True, allow_blank=True)
 
 
 class PnfInstancesSerializer(serializers.ListSerializer):
index c248ecb..d691e65 100644 (file)
@@ -83,7 +83,27 @@ class TestCreatePnfViews(TestCase):
                 }
             ],
             "emsId": str(uuid.uuid4()),
-            "nsInstances": str(uuid.uuid4()) + "," + str(uuid.uuid4())
+            "nsInstances": str(uuid.uuid4())
+        }
+
+        response = self.client.post("/api/nslcm/v1/pnfs", data=data, format='json')
+        self.assertEqual(status.HTTP_201_CREATED, response.status_code)
+
+        data = {
+            "pnfId": id,
+            "pnfName": "Test PNF",
+            "pnfdId": str(uuid.uuid4()),
+            "pnfdInfoId": str(uuid.uuid4()),
+            "pnfProfileId": str(uuid.uuid4()),
+            "cpInfo": [
+                {
+                    "cpInstanceId": str(uuid.uuid4()),
+                    "cpdId": "pnf_ext_cp01",
+                    "cpProtocolData": []
+                }
+            ],
+            "emsId": str(uuid.uuid4()),
+            "nsInstances": str(uuid.uuid4())
         }
 
         response = self.client.post("/api/nslcm/v1/pnfs", data=data, format='json')
index 5dcdb7b..b1caa39 100644 (file)
@@ -167,10 +167,24 @@ class CreateVnfs(Thread):
                     "cpdId": self.get_cpd_id_of_vl(network_info['key_name']),
                     "vim": {
                         "vimid": vl_instance.vimid
-                    }
+                    },
+                    # 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"]:
@@ -189,6 +203,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,
index 6987fc0..0923eb1 100644 (file)
@@ -52,9 +52,12 @@ class GrantVnf(object):
             additional_param = ignore_case_get(self.data, "additionalparams")
             vnfm_inst_id = ignore_case_get(additional_param, "vnfmid")
             vim_id = ignore_case_get(additional_param, "vimid")
-
-            vnfinsts = NfInstModel.objects.filter(
-                nfinstid=m_vnf_inst_id, vnfm_inst_id=vnfm_inst_id)
+            if vnfm_inst_id and vnfm_inst_id != "":
+                vnfinsts = NfInstModel.objects.filter(
+                    mnfinstid=m_vnf_inst_id, vnfm_inst_id=vnfm_inst_id)
+            else:
+                vnfinsts = NfInstModel.objects.filter(
+                    mnfinstid=m_vnf_inst_id)
             if not vnfinsts:
                 raise NSLCMException("Vnfinst(%s) is not found in vnfm(%s)" % (
                     m_vnf_inst_id, vnfm_inst_id))
index 2a4a817..21d410e 100644 (file)
@@ -20,6 +20,7 @@ from lcm.pub.exceptions import NSLCMException
 from lcm.pub.msapi.extsys import get_vnfm_by_id
 from lcm.pub.utils.restcall import req_by_msb
 from lcm.pub.utils.values import ignore_case_get
+from lcm.pub.config import config as pub_config
 
 logger = logging.getLogger(__name__)
 
@@ -35,13 +36,14 @@ class SubscriptionCreation(object):
 
     def do_biz(self):
         logger.debug('Start subscribing...')
-        self.prepare_subscription_request_data()
+        self.prepare_lccn_subscription_request_data()
         self.send_subscription_request()
         self.save_subscription_response_data()
         logger.debug('Subscribing has completed.')
 
     def prepare_lccn_subscription_request_data(self):
         vnfm_info = get_vnfm_by_id(self.vnfm_id)
+        call_back = "http://%s:%s/api/gvnfmdriver/v1/vnfs/lifecyclechangesnotification" % (pub_config.MSB_SERVICE_IP, pub_config.MSB_SERVICE_PORT)
         self.subscription_request_data = {
             "filter": {
                 "notificationTypes": ["VnfLcmOperationOccurrenceNotification"],
@@ -66,24 +68,28 @@ class SubscriptionCreation(object):
                     "ROLLED_BACK"
                 ],
                 "vnfInstanceSubscriptionFilter": {
-                    "vnfdIds": [],
+                    "vnfdIds": [],
                     "vnfInstanceIds": [self.vnf_instance_id],
-                    "vnfInstanceNames": [],
-                    "vnfProductsFromProviders": {}
+                    "vnfInstanceNames": [],
+                    "vnfProductsFromProviders": {}
                 }
             },
-            "callbackUri": "api/gvnfmdriver/v1/vnfs/lifecyclechangesnotification",  # TODO: need reconfirming
+            "callbackUri": call_back,  # TODO: need reconfirming
             "authentication": {
                 "authType": ["BASIC"],
                 "paramsBasic": {
-                    "userName": vnfm_info['userName'],
-                    "password": vnfm_info['password']
+                    "userName": vnfm_info['userName'],
+                    "password": vnfm_info['password']
                 }
             }
         }
+        if vnfm_info['userName']:
+            self.subscription_request_data["authentication"]["paramsBasic"]["userName"] = vnfm_info['userName']
+        if vnfm_info['password']:
+            self.subscription_request_data["authentication"]["paramsBasic"]["password"] = vnfm_info['password']
 
     def send_subscription_request(self):
-        ret = req_by_msb('api/gvnfmdrvier/v1/%s/subscriptions' % self.vnfm_id, 'POST', self.subscription_request_data)
+        ret = req_by_msb('api/gvnfmdriver/v1/%s/subscriptions' % self.vnfm_id, 'POST', json.JSONEncoder().encode(self.subscription_request_data))
         if ret[0] != 0:
             logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
             raise NSLCMException("Failed to subscribe from vnfm(%s)." % self.vnfm_id)
@@ -125,7 +131,7 @@ class SubscriptionDeletion(object):
     def send_subscription_deletion_request(self):
         if self.subscription:
             self.subscription_id = ignore_case_get(self.subscription, 'id')
-            ret = req_by_msb('api/gvnfmdrvier/v1/%s/subscriptions/%s' % (self.vnfm_id, self.subscription_id), 'DELETE')
+            ret = req_by_msb('api/gvnfmdriver/v1/%s/subscriptions/%s' % (self.vnfm_id, self.subscription_id), 'DELETE')
             if ret[0] != 0:
                 logger.error('Status code is %s, detail is %s.', ret[2], ret[1])
                 raise NSLCMException("Failed to subscribe from vnfm(%s)." % self.vnfm_id)
index 1ea9f11..f46ebc4 100644 (file)
@@ -24,9 +24,10 @@ def call_from_ns_cancel_resource(res_type, instid, req_param=None):
     method = "DELETE"
     if res_type == 'vl':
         uri = '/api/nslcm/v1/ns/vls/%s' % instid
-
     elif res_type == 'sfc':
         uri = '/api/nslcm/v1/ns/sfcs/%s' % instid
+    elif res_type == 'pnf':
+        uri = '/api/nslcm/v1/pnfs/%s' % instid
     else:
         # vnf
         method = "POST"
@@ -34,5 +35,5 @@ def call_from_ns_cancel_resource(res_type, instid, req_param=None):
     if not req_param:
         req_param = {}
     ret = req_by_msb(uri, method, json.dumps(req_param))
-    logger.info("[NS terminate] call vnfm [%s] result:%s" % (res_type, ret))
+    logger.info("[NS terminate] call res_type [%s] result:%s" % (res_type, ret))
     return ret
index 547a542..073b833 100644 (file)
@@ -59,11 +59,11 @@ def query_vnfpackage_by_id(csar_id):
 
 def query_pnf_descriptor(filter=None):
     if filter:
-        pnfdInfoId = filter.get("pnfdInfoId")
-        ret = req_by_msb("/api/catalog/v1/pnf_descriptors/%s" % pnfdInfoId, "GET")
+        pnfdId = filter.get("pnfdId")
+        ret = req_by_msb("/api/nsd/v1/pnf_descriptors?pnfdId=%s" % pnfdId, "GET")
     else:
-        ret = req_by_msb("/api/catalog/v1/pnf_descriptors", "GET")
+        ret = req_by_msb("/api/nsd/v1/pnf_descriptors", "GET")
     if ret[0] != 0:
         logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
-        raise NSLCMException("Failed to query pnf descriptor(%s) from catalog." % pnfdInfoId)
+        raise NSLCMException("Failed to query pnf descriptor(%s) from catalog." % pnfdId)
     return json.JSONDecoder().decode(ret[1])
index 993efbe..fa26785 100644 (file)
@@ -279,7 +279,7 @@ def confirm_sfc_status(sfc_inst_id):
 def create_pnf(pnf_param_json):
     if pnf_param_json and len(pnf_param_json) > 0:
         pnfs = json.JSONDecoder().decode(pnf_param_json)
-        for pnf in pnfs:
+        for pnf in pnfs.itervalues():
             uri = "/api/nslcm/v1/pnfs"
             method = "POST"
             content = json.JSONEncoder().encode(pnf["input"]["content"])