f0ecc8f498f6588bb59d5b336770d224b7783d53
[vfc/nfvo/lcm.git] / lcm / ns_vnfs / tests / tests.py
1 # Copyright 2016-2017 ZTE Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 import json
15 import uuid
16
17 import mock
18 from django.test import TestCase, Client
19 from rest_framework import status
20
21 from lcm.pub.database.models import NfInstModel, JobModel, NSInstModel, VmInstModel, OOFDataModel, SubscriptionModel
22 from lcm.pub.exceptions import NSLCMException
23 from lcm.pub.utils import restcall
24 from lcm.pub.utils.jobutil import JOB_MODEL_STATUS
25 from lcm.pub.utils.jobutil import JobUtil, JOB_TYPE
26 from lcm.pub.utils.timeutil import now_time
27 from lcm.pub.utils.values import ignore_case_get
28 from lcm.ns_vnfs.biz.create_vnfs import CreateVnfs
29 from lcm.ns_vnfs.biz.grant_vnf import GrantVnf
30 from lcm.ns_vnfs.biz.heal_vnfs import NFHealService
31 from lcm.ns_vnfs.biz.scale_vnfs import NFManualScaleService
32 from lcm.ns_vnfs.biz.subscribe import SubscriptionDeletion
33 from lcm.ns_vnfs.biz.terminate_nfs import TerminateVnfs
34 from lcm.ns_vnfs.const import VNF_STATUS, INST_TYPE
35 from lcm.ns_vnfs.biz import create_vnfs
36 from lcm.ns_vnfs.biz.place_vnfs import PlaceVnfs
37 from lcm.pub.msapi import resmgr
38
39
40 class TestGetVnfViews(TestCase):
41     def setUp(self):
42         self.client = Client()
43         self.nf_inst_id = str(uuid.uuid4())
44         NfInstModel(nfinstid=self.nf_inst_id, nf_name='vnf1', vnfm_inst_id='1', vnf_id='vnf_id1',
45                     status=VNF_STATUS.ACTIVE, create_time=now_time(), lastuptime=now_time()).save()
46
47     def tearDown(self):
48         NfInstModel.objects.all().delete()
49
50     def test_get_vnf(self):
51         response = self.client.get("/api/nslcm/v1/ns/vnfs/%s" % self.nf_inst_id)
52         self.failUnlessEqual(status.HTTP_200_OK, response.status_code)
53         context = json.loads(response.content)
54         self.failUnlessEqual(self.nf_inst_id, context['vnfInstId'])
55
56
57 class TestCreateVnfViews(TestCase):
58     def setUp(self):
59         self.ns_inst_id = str(uuid.uuid4())
60         self.job_id = str(uuid.uuid4())
61         self.data = {
62             "nsInstanceId": self.ns_inst_id,
63             "additionalParamForNs": {
64                 "inputs": json.dumps({
65
66                 })
67             },
68             "additionalParamForVnf": [
69                 {
70                     "vnfprofileid": "VBras",
71                     "additionalparam": {
72                         "inputs": json.dumps({
73                             "vnf_param1": "11",
74                             "vnf_param2": "22"
75                         }),
76                         "vnfminstanceid": "1",
77                         "vimId": "zte_test"
78                     }
79                 }
80             ],
81             "vnfIndex": "1"
82         }
83         self.client = Client()
84         NSInstModel(id=self.ns_inst_id, name='ns', nspackage_id='1', nsd_id='nsd_id', description='description',
85                     status='instantiating', nsd_model=json.dumps(nsd_model_dict), create_time=now_time(),
86                     lastuptime=now_time()).save()
87
88     def tearDown(self):
89         NfInstModel.objects.all().delete()
90         JobModel.objects.all().delete()
91
92     @mock.patch.object(CreateVnfs, 'run')
93     def test_create_vnf(self, mock_run):
94         response = self.client.post("/api/nslcm/v1/ns/vnfs", data=self.data)
95         self.failUnlessEqual(status.HTTP_202_ACCEPTED, response.status_code)
96         context = json.loads(response.content)
97         self.assertTrue(NfInstModel.objects.filter(nfinstid=context['vnfInstId']).exists())
98
99     @mock.patch.object(restcall, 'call_req')
100     def test_create_vnf_thread(self, mock_call_req):
101         nf_inst_id, job_id = create_vnfs.prepare_create_params()
102         mock_vals = {
103             "/api/ztevnfmdriver/v1/1/vnfs":
104                 [0, json.JSONEncoder().encode({"jobId": self.job_id, "vnfInstanceId": 3}), '200'],
105             "/api/catalog/v1/vnfpackages/zte_vbras":
106                 [0, json.JSONEncoder().encode(nf_package_info), '200'],
107             "/external-system/esr-vnfm-list/esr-vnfm/1?depth=all":
108                 [0, json.JSONEncoder().encode(vnfm_info), '200'],
109             "/api/resmgr/v1/vnf":
110                 [0, json.JSONEncoder().encode({}), '200'],
111             "/api/resmgr/v1/vnfinfo":
112                 [0, json.JSONEncoder().encode({}), '200'],
113             "/network/generic-vnfs/generic-vnf/%s" % nf_inst_id:
114                 [0, json.JSONEncoder().encode({}), '201'],
115             "/cloud-infrastructure/cloud-regions/cloud-region/zte/test?depth=all":
116                 [0, json.JSONEncoder().encode(vim_info), '201'],
117             "/cloud-infrastructure/cloud-regions/cloud-region/zte/test/tenants/tenant/admin/vservers/vserver/1":
118                 [0, json.JSONEncoder().encode({}), '201'],
119             "/api/ztevnfmdriver/v1/1/jobs/" + self.job_id + "?responseId=0":
120                 [0, json.JSONEncoder().encode({"jobid": self.job_id,
121                                                "responsedescriptor": {"progress": "100",
122                                                                       "status": JOB_MODEL_STATUS.FINISHED,
123                                                                       "responseid": "3",
124                                                                       "statusdescription": "creating",
125                                                                       "errorcode": "0",
126                                                                       "responsehistorylist": [
127                                                                           {"progress": "0",
128                                                                            "status": JOB_MODEL_STATUS.PROCESSING,
129                                                                            "responseid": "2",
130                                                                            "statusdescription": "creating",
131                                                                            "errorcode": "0"}]}}), '200']}
132
133         def side_effect(*args):
134             return mock_vals[args[4]]
135         mock_call_req.side_effect = side_effect
136         data = {
137             'ns_instance_id': ignore_case_get(self.data, 'nsInstanceId'),
138             'additional_param_for_ns': ignore_case_get(self.data, 'additionalParamForNs'),
139             'additional_param_for_vnf': ignore_case_get(self.data, 'additionalParamForVnf'),
140             'vnf_index': ignore_case_get(self.data, 'vnfIndex')
141         }
142         CreateVnfs(data, nf_inst_id, job_id).run()
143         self.assertTrue(NfInstModel.objects.get(nfinstid=nf_inst_id).status, VNF_STATUS.ACTIVE)
144
145     @mock.patch.object(restcall, 'call_req')
146     @mock.patch.object(CreateVnfs, 'build_homing_request')
147     def test_send_homing_request(self, mock_build_req, mock_call_req):
148         nf_inst_id, job_id = create_vnfs.prepare_create_params()
149         OOFDataModel.objects.all().delete()
150         resp = {
151             "requestId": "1234",
152             "transactionId": "1234",
153             "requestStatus": "accepted"
154         }
155         mock_build_req.return_value = {
156             "requestInfo": {
157                 "transactionId": "1234",
158                 "requestId": "1234",
159                 "callbackUrl": "xx",
160                 "sourceId": "vfc",
161                 "requestType": "create",
162                 "numSolutions": 1,
163                 "optimizers": ["placement"],
164                 "timeout": 600
165             },
166             "placementInfo": {
167                 "placementDemands": [
168                     {
169                         "resourceModuleName": "vG",
170                         "serviceResourceId": "1234",
171                         "resourceModelInfo": {
172                             "modelInvariantId": "1234",
173                             "modelVersionId": "1234"
174                         }
175                     }
176                 ]
177             },
178             "serviceInfo": {
179                 "serviceInstanceId": "1234",
180                 "serviceName": "1234",
181                 "modelInfo": {
182                     "modelInvariantId": "5678",
183                     "modelVersionId": "7890"
184                 }
185             }
186         }
187         mock_call_req.return_value = [0, json.JSONEncoder().encode(resp), '202']
188         data = {
189             'ns_instance_id': ignore_case_get(self.data, 'nsInstanceId'),
190             'additional_param_for_ns': ignore_case_get(self.data, 'additionalParamForNs'),
191             'additional_param_for_vnf': ignore_case_get(self.data, 'additionalParamForVnf'),
192             'vnf_index': ignore_case_get(self.data, 'vnfIndex')
193         }
194         CreateVnfs(data, nf_inst_id, job_id).send_homing_request_to_OOF()
195         ret = OOFDataModel.objects.filter(request_id="1234", transaction_id="1234")
196         self.assertIsNotNone(ret)
197
198
199 class TestTerminateVnfViews(TestCase):
200     def setUp(self):
201         self.client = Client()
202         self.ns_inst_id = str(uuid.uuid4())
203         self.nf_inst_id = '1'
204         self.vnffg_id = str(uuid.uuid4())
205         self.vim_id = str(uuid.uuid4())
206         self.job_id = str(uuid.uuid4())
207         self.nf_uuid = '111'
208         self.tenant = "tenantname"
209         self.vnfd_model = {
210             "metadata": {
211                 "vnfdId": "1",
212                 "vnfdName": "PGW001",
213                 "vnfProvider": "zte",
214                 "vnfdVersion": "V00001",
215                 "vnfVersion": "V5.10.20",
216                 "productType": "CN",
217                 "vnfType": "PGW",
218                 "description": "PGW VNFD description",
219                 "isShared": True,
220                 "vnfExtendType": "driver"
221             }
222         }
223         NSInstModel.objects.all().delete()
224         NfInstModel.objects.all().delete()
225         VmInstModel.objects.all().delete()
226         NSInstModel(id=self.ns_inst_id, name="ns_name").save()
227         NfInstModel.objects.create(nfinstid=self.nf_inst_id,
228                                    nf_name='name_1',
229                                    vnf_id='1',
230                                    vnfm_inst_id='1',
231                                    ns_inst_id='111,2-2-2',
232                                    max_cpu='14',
233                                    max_ram='12296',
234                                    max_hd='101',
235                                    max_shd="20",
236                                    max_net=10,
237                                    status='active',
238                                    mnfinstid=self.nf_uuid,
239                                    package_id='pkg1',
240                                    vnfd_model=self.vnfd_model)
241         VmInstModel.objects.create(vmid="1",
242                                    vimid="zte_test",
243                                    resouceid="1",
244                                    insttype=INST_TYPE.VNF,
245                                    instid=self.nf_inst_id,
246                                    vmname="test",
247                                    hostid='1')
248
249     def tearDown(self):
250         NSInstModel.objects.all().delete()
251         NfInstModel.objects.all().delete()
252
253     @mock.patch.object(TerminateVnfs, 'run')
254     def test_terminate_vnf_url(self, mock_run):
255         req_data = {
256             "terminationType": "forceful",
257             "gracefulTerminationTimeout": "600"}
258
259         response = self.client.post("/api/nslcm/v1/ns/terminatevnf/%s" % self.nf_inst_id, data=req_data)
260         self.failUnlessEqual(status.HTTP_202_ACCEPTED, response.status_code)
261
262     @mock.patch.object(restcall, 'call_req')
263     @mock.patch.object(SubscriptionDeletion, 'send_subscription_deletion_request')
264     def test_terminate_vnf(self, mock_send_subscription_deletion_request, mock_call_req):
265         job_id = JobUtil.create_job("VNF", JOB_TYPE.TERMINATE_VNF, self.nf_inst_id)
266
267         nfinst = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
268         if nfinst:
269             self.failUnlessEqual(1, 1)
270         else:
271             self.failUnlessEqual(1, 0)
272
273         notification_types = ["VnfLcmOperationOccurrenceNotification"],
274         operation_types = [
275             "INSTANTIATE",
276             "SCALE",
277             "SCALE_TO_LEVEL",
278             "CHANGE_FLAVOUR",
279             "TERMINATE",
280             "HEAL",
281             "OPERATE",
282             "CHANGE_EXT_CONN",
283             "MODIFY_INFO"
284         ],
285         operation_states = [
286             "STARTING",
287             "PROCESSING",
288             "COMPLETED",
289             "FAILED_TEMP",
290             "FAILED",
291             "ROLLING_BACK",
292             "ROLLED_BACK"
293         ],
294         vnf_instance_subscription_filter = {
295             "vnfdIds": [],
296             "vnfInstanceIds": '1',
297             "vnfInstanceNames": [],
298             "vnfProductsFromProviders": {}
299         }
300         SubscriptionModel.objects.create(
301             subscription_id='1',
302             notification_types=json.dumps(notification_types),
303             operation_types=json.dumps(operation_types),
304             operation_states=json.dumps(operation_states),
305             vnf_instance_filter=json.dumps(vnf_instance_subscription_filter),
306             # callback_uri,
307             # links=json.dumps(...)
308         )
309
310         vnf_info = {
311             "vnf-id": "vnf-id-test111",
312             "vnf-name": "vnf-name-test111",
313             "vnf-type": "vnf-type-test111",
314             "in-maint": True,
315             "is-closed-loop-disabled": False,
316             "resource-version": "1505465356262"
317         }
318         job_info = {
319             "jobId": job_id,
320             "responsedescriptor": {
321                 "progress": "100",
322                 "status": JOB_MODEL_STATUS.FINISHED,
323                 "responseid": "3",
324                 "statusdescription": "creating",
325                 "errorcode": "0",
326                 "responsehistorylist": [
327                     {
328                         "progress": "0",
329                         "status": JOB_MODEL_STATUS.PROCESSING,
330                         "responseid": "2",
331                         "statusdescription": "creating",
332                         "errorcode": "0"
333                     }
334                 ]
335             }
336         }
337
338         mock_vals = {
339             "/external-system/esr-vnfm-list/esr-vnfm/1?depth=all":
340                 [0, json.JSONEncoder().encode(vnfm_info), '200'],
341             "/api/ztevnfmdriver/v1/1/vnfs/111/terminate":
342                 [0, json.JSONEncoder().encode({"jobId": job_id}), '200'],
343             "/api/resmgr/v1/vnf/1":
344                 [0, json.JSONEncoder().encode({"jobId": job_id}), '200'],
345             "/cloud-infrastructure/cloud-regions/cloud-region/zte/test?depth=all":
346                 [0, json.JSONEncoder().encode(vim_info), '201'],
347             "/cloud-infrastructure/cloud-regions/cloud-region/zte/test/tenants/tenant/admin/vservers/vserver/1?depth=all":
348                 [0, json.JSONEncoder().encode(vserver_info), '201'],
349             "/cloud-infrastructure/cloud-regions/cloud-region/zte/test/tenants/tenant/admin/vservers/vserver/1?resource-version=1505465356263":
350                 [0, json.JSONEncoder().encode({}), '200'],
351             "/api/ztevnfmdriver/v1/1/jobs/" + job_id + "?responseId=0":
352                 [0, json.JSONEncoder().encode(job_info), '200'],
353             "/network/generic-vnfs/generic-vnf/1?depth=all":
354             [0, json.JSONEncoder().encode(vnf_info), '200'],
355             "/network/generic-vnfs/generic-vnf/1?resource-version=1505465356262":
356             [0, json.JSONEncoder().encode({}), '200']
357         }
358
359         def side_effect(*args):
360             return mock_vals[args[4]]
361
362         mock_call_req.side_effect = side_effect
363
364         req_data = {
365             "terminationType": "forceful",
366             "gracefulTerminationTimeout": "600"
367         }
368
369         TerminateVnfs(req_data, self.nf_inst_id, job_id).run()
370         nfinst = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
371         if nfinst:
372             self.failUnlessEqual(1, 0)
373         else:
374             self.failUnlessEqual(1, 1)
375
376
377 class TestScaleVnfViews(TestCase):
378     def setUp(self):
379         self.client = Client()
380         self.ns_inst_id = str(uuid.uuid4())
381         self.nf_inst_id = str(uuid.uuid4())
382         self.vnffg_id = str(uuid.uuid4())
383         self.vim_id = str(uuid.uuid4())
384         self.job_id = str(uuid.uuid4())
385         self.nf_uuid = '111'
386         self.tenant = "tenantname"
387         NSInstModel(id=self.ns_inst_id, name="ns_name").save()
388         NfInstModel.objects.create(nfinstid=self.nf_inst_id, nf_name='name_1', vnf_id='1',
389                                    vnfm_inst_id='1', ns_inst_id='111,2-2-2',
390                                    max_cpu='14', max_ram='12296', max_hd='101', max_shd="20", max_net=10,
391                                    status='active', mnfinstid=self.nf_uuid, package_id='pkg1',
392                                    vnfd_model='{"metadata": {"vnfdId": "1","vnfdName": "PGW001",'
393                                               '"vnfProvider": "zte","vnfdVersion": "V00001","vnfVersion": "V5.10.20",'
394                                               '"productType": "CN","vnfType": "PGW",'
395                                               '"description": "PGW VNFD description",'
396                                               '"isShared":true,"vnfExtendType":"driver"}}')
397
398     def tearDown(self):
399         NSInstModel.objects.all().delete()
400         NfInstModel.objects.all().delete()
401
402     def test_scale_vnf(self):
403         vnfd_info = {
404             "vnf_flavours": [{
405                 "flavour_id": "flavour1",
406                 "description": "",
407                 "vdu_profiles": [
408                     {
409                         "vdu_id": "vdu1Id",
410                         "instances_minimum_number": 1,
411                         "instances_maximum_number": 4,
412                         "local_affinity_antiaffinity_rule": [
413                             {
414                                 "affinity_antiaffinity": "affinity",
415                                 "scope": "node",
416                             }
417                         ]
418                     }
419                 ],
420                 "scaling_aspects": [
421                     {
422                         "id": "demo_aspect",
423                         "name": "demo_aspect",
424                         "description": "demo_aspect",
425                         "associated_group": "elementGroup1",
426                         "max_scale_level": 5
427                     }
428                 ]
429             }],
430             "element_groups": [{
431                 "group_id": "elementGroup1",
432                 "description": "",
433                 "properties": {
434                     "name": "elementGroup1",
435                 },
436                 "members": ["gsu_vm", "pfu_vm"]
437             }]
438         }
439
440         req_data = {
441             "scaleVnfData": [
442                 {
443                     "type": "SCALE_OUT",
444                     "aspectId": "demo_aspect1",
445                     "numberOfSteps": 1,
446                     "additionalParam": vnfd_info
447                 },
448                 {
449                     "type": "SCALE_OUT",
450                     "aspectId": "demo_aspect2",
451                     "numberOfSteps": 1,
452                     "additionalParam": vnfd_info
453                 }
454             ]
455         }
456
457         NFManualScaleService(self.nf_inst_id, req_data).run()
458         nsIns = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
459         self.assertIsNotNone(nsIns)
460
461     @mock.patch.object(NFManualScaleService, "send_nf_scaling_request")
462     def test_scale_vnf_success(self, mock_send_nf_scaling_request):
463         vnfd_info = {
464             "vnf_flavours": [{
465                 "flavour_id": "flavour1",
466                 "description": "",
467                 "vdu_profiles": [
468                     {
469                         "vdu_id": "vdu1Id",
470                         "instances_minimum_number": 1,
471                         "instances_maximum_number": 4,
472                         "local_affinity_antiaffinity_rule": [
473                             {
474                                 "affinity_antiaffinity": "affinity",
475                                 "scope": "node",
476                             }
477                         ]
478                     }
479                 ],
480                 "scaling_aspects": [
481                     {
482                         "id": "demo_aspect",
483                         "name": "demo_aspect",
484                         "description": "demo_aspect",
485                         "associated_group": "elementGroup1",
486                         "max_scale_level": 5
487                     }
488                 ]
489             }],
490             "element_groups": [{
491                 "group_id": "elementGroup1",
492                 "description": "",
493                 "properties": {
494                     "name": "elementGroup1",
495                 },
496                 "members": ["gsu_vm", "pfu_vm"]
497             }]
498         }
499
500         req_data = {
501             "scaleVnfData": [
502                 {
503                     "type": "SCALE_OUT",
504                     "aspectId": "demo_aspect1",
505                     "numberOfSteps": 1,
506                     "additionalParam": vnfd_info
507                 },
508                 {
509                     "type": "SCALE_OUT",
510                     "aspectId": "demo_aspect2",
511                     "numberOfSteps": 1,
512                     "additionalParam": vnfd_info
513                 }
514             ]
515         }
516         scale_service = NFManualScaleService(self.nf_inst_id, req_data)
517         scale_service.run()
518         nsIns = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
519         self.assertIsNotNone(nsIns)
520
521         jobs = JobModel.objects.filter(jobid=scale_service.job_id)
522         self.assertIsNotNone(100, jobs[0].progress)
523
524
525 class TestHealVnfViews(TestCase):
526     def setUp(self):
527         self.client = Client()
528         self.ns_inst_id = str(uuid.uuid4())
529         self.nf_inst_id = str(uuid.uuid4())
530         self.nf_uuid = '111'
531
532         self.job_id = JobUtil.create_job("VNF", JOB_TYPE.HEAL_VNF, self.nf_inst_id)
533
534         NSInstModel(id=self.ns_inst_id, name="ns_name").save()
535         NfInstModel.objects.create(nfinstid=self.nf_inst_id,
536                                    nf_name='name_1',
537                                    vnf_id='1',
538                                    vnfm_inst_id='1',
539                                    ns_inst_id='111,2-2-2',
540                                    max_cpu='14',
541                                    max_ram='12296',
542                                    max_hd='101',
543                                    max_shd="20",
544                                    max_net=10,
545                                    status='active',
546                                    mnfinstid=self.nf_uuid,
547                                    package_id='pkg1',
548                                    vnfd_model=json.dumps({
549                                        "metadata": {
550                                            "vnfdId": "1",
551                                            "vnfdName": "PGW001",
552                                            "vnfProvider": "zte",
553                                            "vnfdVersion": "V00001",
554                                            "vnfVersion": "V5.10.20",
555                                            "productType": "CN",
556                                            "vnfType": "PGW",
557                                            "description": "PGW VNFD description",
558                                            "isShared": True,
559                                            "vnfExtendType": "driver"
560                                        }
561                                    }))
562
563     def tearDown(self):
564         NSInstModel.objects.all().delete()
565         NfInstModel.objects.all().delete()
566
567     @mock.patch.object(restcall, "call_req")
568     def test_heal_vnf(self, mock_call_req):
569
570         mock_vals = {
571             "/api/ztevnfmdriver/v1/1/vnfs/111/heal":
572                 [0, json.JSONEncoder().encode({"jobId": self.job_id}), '200'],
573             "/external-system/esr-vnfm-list/esr-vnfm/1":
574                 [0, json.JSONEncoder().encode(vnfm_info), '200'],
575             "/api/resmgr/v1/vnf/1":
576                 [0, json.JSONEncoder().encode({"jobId": self.job_id}), '200'],
577             "/api/ztevnfmdriver/v1/1/jobs/" + self.job_id + "?responseId=0":
578                 [0, json.JSONEncoder().encode({
579                     "jobId": self.job_id,
580                     "responsedescriptor": {
581                         "progress": "100",
582                         "status": JOB_MODEL_STATUS.FINISHED,
583                         "responseid": "3",
584                         "statusdescription": "creating",
585                         "errorcode": "0",
586                         "responsehistorylist": [{
587                             "progress": "0",
588                             "status": JOB_MODEL_STATUS.PROCESSING,
589                             "responseid": "2",
590                             "statusdescription": "creating",
591                             "errorcode": "0"
592                         }]
593                     }
594                 }), '200']}
595
596         def side_effect(*args):
597             return mock_vals[args[4]]
598
599         mock_call_req.side_effect = side_effect
600
601         req_data = {
602             "action": "vmReset",
603             "affectedvm": {
604                 "vmid": "1",
605                 "vduid": "1",
606                 "vmname": "name",
607             }
608         }
609
610         NFHealService(self.nf_inst_id, req_data).run()
611
612         self.assertEqual(NfInstModel.objects.get(nfinstid=self.nf_inst_id).status, VNF_STATUS.ACTIVE)
613
614     @mock.patch.object(NFHealService, "run")
615     def test_heal_vnf_non_existing_vnf(self, mock_biz):
616         mock_biz.side_effect = NSLCMException("VNF Not Found")
617
618         nf_inst_id = "1"
619
620         req_data = {
621             "action": "vmReset",
622             "affectedvm": {
623                 "vmid": "1",
624                 "vduid": "1",
625                 "vmname": "name",
626             }
627         }
628
629         self.assertRaises(NSLCMException, NFHealService(nf_inst_id, req_data).run)
630         self.assertEqual(len(NfInstModel.objects.filter(nfinstid=nf_inst_id)), 0)
631
632
633 class TestGetVnfmInfoViews(TestCase):
634     def setUp(self):
635         self.client = Client()
636         self.vnfm_id = str(uuid.uuid4())
637
638     def tearDown(self):
639         pass
640
641     @mock.patch.object(restcall, "call_req")
642     def test_get_vnfm_info(self, mock_call_req):
643         vnfm_info_aai = {
644             "vnfm-id": "example-vnfm-id-val-62576",
645             "vim-id": "example-vim-id-val-35114",
646             "certificate-url": "example-certificate-url-val-90242",
647             "esr-system-info-list": {
648                 "esr-system-info": [
649                     {
650                         "esr-system-info-id": "example-esr-system-info-id-val-78484",
651                         "system-name": "example-system-name-val-23790",
652                         "type": "example-type-val-52596",
653                         "vendor": "example-vendor-val-47399",
654                         "version": "example-version-val-42051",
655                         "service-url": "example-service-url-val-10731",
656                         "user-name": "example-user-name-val-65946",
657                         "password": "example-password-val-22505",
658                         "system-type": "example-system-type-val-27221",
659                         "protocal": "example-protocal-val-54632",
660                         "ssl-cacert": "example-ssl-cacert-val-45965",
661                         "ssl-insecure": True,
662                         "ip-address": "example-ip-address-val-19212",
663                         "port": "example-port-val-57641",
664                         "cloud-domain": "example-cloud-domain-val-26296",
665                         "default-tenant": "example-default-tenant-val-87724"
666                     }
667                 ]
668             }
669         }
670         r1 = [0, json.JSONEncoder().encode(vnfm_info_aai), '200']
671         mock_call_req.side_effect = [r1]
672         esr_system_info = ignore_case_get(ignore_case_get(vnfm_info_aai, "esr-system-info-list"), "esr-system-info")
673         expect_data = {
674             "vnfmId": vnfm_info_aai["vnfm-id"],
675             "name": vnfm_info_aai["vnfm-id"],
676             "type": ignore_case_get(esr_system_info[0], "type"),
677             "vimId": vnfm_info_aai["vim-id"],
678             "vendor": ignore_case_get(esr_system_info[0], "vendor"),
679             "version": ignore_case_get(esr_system_info[0], "version"),
680             "description": "vnfm",
681             "certificateUrl": vnfm_info_aai["certificate-url"],
682             "url": ignore_case_get(esr_system_info[0], "service-url"),
683             "userName": ignore_case_get(esr_system_info[0], "user-name"),
684             "password": ignore_case_get(esr_system_info[0], "password"),
685             "createTime": ""
686         }
687
688         response = self.client.get("/api/nslcm/v1/vnfms/%s" % self.vnfm_id)
689         self.failUnlessEqual(status.HTTP_200_OK, response.status_code, response.content)
690         context = json.loads(response.content)
691         self.assertEqual(expect_data, context)
692
693
694 class TestGetVimInfoViews(TestCase):
695     def setUp(self):
696         self.client = Client()
697         self.vim_id = "zte_test"
698
699     def tearDown(self):
700         pass
701
702     @mock.patch.object(restcall, "call_req")
703     def test_get_vim_info(self, mock_call_req):
704         r1 = [0, json.JSONEncoder().encode(vim_info), '200']
705         mock_call_req.side_effect = [r1]
706         esr_system_info = ignore_case_get(ignore_case_get(vim_info, "esr-system-info-list"), "esr-system-info")
707         expect_data = {
708             "vimId": self.vim_id,
709             "name": self.vim_id,
710             "url": ignore_case_get(esr_system_info[0], "service-url"),
711             "userName": ignore_case_get(esr_system_info[0], "user-name"),
712             "password": ignore_case_get(esr_system_info[0], "password"),
713             # "tenant": ignore_case_get(tenants[0], "tenant-id"),
714             "tenant": ignore_case_get(esr_system_info[0], "default-tenant"),
715             "vendor": ignore_case_get(esr_system_info[0], "vendor"),
716             "version": ignore_case_get(esr_system_info[0], "version"),
717             "description": "vim",
718             "domain": "",
719             "type": ignore_case_get(esr_system_info[0], "type"),
720             "createTime": ""
721         }
722
723         response = self.client.get("/api/nslcm/v1/vims/%s" % self.vim_id)
724         self.failUnlessEqual(status.HTTP_200_OK, response.status_code)
725         context = json.loads(response.content)
726         self.assertEqual(expect_data["url"], context["url"])
727
728
729 class TestPlaceVnfViews(TestCase):
730     def setUp(self):
731         self.vnf_inst_id = "1234"
732         self.vnf_id = "vG"
733         self.client = Client()
734         OOFDataModel.objects.all().delete()
735         OOFDataModel.objects.create(
736             request_id="1234",
737             transaction_id="1234",
738             request_status="init",
739             request_module_name=self.vnf_id,
740             service_resource_id=self.vnf_inst_id,
741             vim_id="",
742             cloud_owner="",
743             cloud_region_id="",
744             vdu_info="",
745         )
746
747     def tearDown(self):
748         OOFDataModel.objects.all().delete()
749
750     @mock.patch.object(restcall, 'call_req')
751     def test_place_vnf(self, mock_call_req):
752         vdu_info_json = [{
753             "vduName": "vG_0",
754             "flavorName": "HPA.flavor.1",
755             "flavorId": "12345",
756             "directive": []
757         }]
758         PlaceVnfs(vnf_place_request).extract()
759         db_info = OOFDataModel.objects.filter(request_id=vnf_place_request.get("requestId"), transaction_id=vnf_place_request.get("transactionId"))
760         self.assertEqual(db_info[0].request_status, "completed")
761         self.assertEqual(db_info[0].vim_id, "CloudOwner1_DLLSTX1A")
762         self.assertEqual(db_info[0].cloud_owner, "CloudOwner1")
763         self.assertEqual(db_info[0].cloud_region_id, "DLLSTX1A")
764         self.assertEqual(db_info[0].vdu_info, json.dumps(vdu_info_json))
765
766     def test_place_vnf_with_invalid_response(self):
767         resp = {
768             "requestId": "1234",
769             "transactionId": "1234",
770             "statusMessage": "xx",
771             "requestStatus": "pending",
772             "solutions": {
773                 "placementSolutions": [
774                     [
775                         {
776                             "resourceModuleName": self.vnf_id,
777                             "serviceResourceId": self.vnf_inst_id,
778                             "solution": {
779                                 "identifierType": "serviceInstanceId",
780                                 "identifiers": [
781                                     "xx"
782                                 ],
783                                 "cloudOwner": "CloudOwner1 "
784                             },
785                             "assignmentInfo": []
786                         }
787                     ]
788                 ],
789                 "licenseSolutions": [
790                     {
791                         "resourceModuleName": "string",
792                         "serviceResourceId": "string",
793                         "entitlementPoolUUID": [
794                             "string"
795                         ],
796                         "licenseKeyGroupUUID": [
797                             "string"
798                         ],
799                         "entitlementPoolInvariantUUID": [
800                             "string"
801                         ],
802                         "licenseKeyGroupInvariantUUID": [
803                             "string"
804                         ]
805                     }
806                 ]
807             }
808         }
809         PlaceVnfs(resp).extract()
810         db_info = OOFDataModel.objects.filter(request_id=resp.get("requestId"), transaction_id=resp.get("transactionId"))
811         self.assertEqual(db_info[0].request_status, "pending")
812         self.assertEqual(db_info[0].vim_id, "none")
813         self.assertEqual(db_info[0].cloud_owner, "none")
814         self.assertEqual(db_info[0].cloud_region_id, "none")
815         self.assertEqual(db_info[0].vdu_info, "none")
816
817     def test_place_vnf_with_no_assignment_info(self):
818         resp = {
819             "requestId": "1234",
820             "transactionId": "1234",
821             "statusMessage": "xx",
822             "requestStatus": "completed",
823             "solutions": {
824                 "placementSolutions": [
825                     [
826                         {
827                             "resourceModuleName": self.vnf_id,
828                             "serviceResourceId": self.vnf_inst_id,
829                             "solution": {
830                                 "identifierType": "serviceInstanceId",
831                                 "identifiers": [
832                                     "xx"
833                                 ],
834                                 "cloudOwner": "CloudOwner1 "
835                             }
836                         }
837                     ]
838                 ],
839                 "licenseSolutions": [
840                     {
841                         "resourceModuleName": "string",
842                         "serviceResourceId": "string",
843                         "entitlementPoolUUID": [
844                             "string"
845                         ],
846                         "licenseKeyGroupUUID": [
847                             "string"
848                         ],
849                         "entitlementPoolInvariantUUID": [
850                             "string"
851                         ],
852                         "licenseKeyGroupInvariantUUID": [
853                             "string"
854                         ]
855                     }
856                 ]
857             }
858         }
859         PlaceVnfs(resp).extract()
860         db_info = OOFDataModel.objects.filter(request_id=resp.get("requestId"), transaction_id=resp.get("transactionId"))
861         self.assertEqual(db_info[0].request_status, "completed")
862         self.assertEqual(db_info[0].vim_id, "none")
863         self.assertEqual(db_info[0].cloud_owner, "none")
864         self.assertEqual(db_info[0].cloud_region_id, "none")
865         self.assertEqual(db_info[0].vdu_info, "none")
866
867     def test_place_vnf_no_directives(self):
868         resp = {
869             "requestId": "1234",
870             "transactionId": "1234",
871             "statusMessage": "xx",
872             "requestStatus": "completed",
873             "solutions": {
874                 "placementSolutions": [
875                     [
876                         {
877                             "resourceModuleName": self.vnf_id,
878                             "serviceResourceId": self.vnf_inst_id,
879                             "solution": {
880                                 "identifierType": "serviceInstanceId",
881                                 "identifiers": [
882                                     "xx"
883                                 ],
884                                 "cloudOwner": "CloudOwner1 "
885                             },
886                             "assignmentInfo": [
887                                 {"key": "locationId",
888                                  "value": "DLLSTX1A"
889                                  }
890                             ]
891                         }
892                     ]
893                 ],
894                 "licenseSoutions": [
895                     {
896                         "resourceModuleName": "string",
897                         "serviceResourceId": "string",
898                         "entitlementPoolUUID": [
899                             "string"
900                         ],
901                         "licenseKeyGroupUUID": [
902                             "string"
903                         ],
904                         "entitlementPoolInvariantUUID": [
905                             "string"
906                         ],
907                         "licenseKeyGroupInvariantUUID": [
908                             "string"
909                         ]
910                     }
911                 ]
912             }
913         }
914         PlaceVnfs(resp).extract()
915         db_info = OOFDataModel.objects.filter(request_id=resp.get("requestId"), transaction_id=resp.get("transactionId"))
916         self.assertEqual(db_info[0].request_status, "completed")
917         self.assertEqual(db_info[0].vim_id, "none")
918         self.assertEqual(db_info[0].cloud_owner, "none")
919         self.assertEqual(db_info[0].cloud_region_id, "none")
920         self.assertEqual(db_info[0].vdu_info, "none")
921
922     def test_place_vnf_with_no_solution(self):
923         resp = {
924             "requestId": "1234",
925             "transactionId": "1234",
926             "statusMessage": "xx",
927             "requestStatus": "completed",
928             "solutions": {
929                 "placementSolutions": [],
930                 "licenseSoutions": []
931             }
932         }
933         PlaceVnfs(resp).extract()
934         db_info = OOFDataModel.objects.filter(request_id=resp.get("requestId"), transaction_id=resp.get("transactionId"))
935         self.assertEqual(db_info[0].request_status, "completed")
936         self.assertEqual(db_info[0].vim_id, "none")
937         self.assertEqual(db_info[0].cloud_owner, "none")
938         self.assertEqual(db_info[0].cloud_region_id, "none")
939         self.assertEqual(db_info[0].vdu_info, "none")
940
941
942 class TestGrantVnfViews(TestCase):
943     def setUp(self):
944         self.vnf_inst_id = str(uuid.uuid4())
945         self.data = {
946             "vnfInstanceId": self.vnf_inst_id,
947             "vnfLcmOpOccId": "1234",
948             "operation": "INSTANTIATE"
949         }
950         vdu_info_dict = [{"vduName": "vg", "flavorName": "flavor_1", "flavorId": "12345", "directive": []}]
951         OOFDataModel(request_id='1234', transaction_id='1234', request_status='done', request_module_name='vg',
952                      service_resource_id=self.vnf_inst_id, vim_id='cloudOwner_casa', cloud_owner='cloudOwner',
953                      cloud_region_id='casa', vdu_info=json.dumps(vdu_info_dict)).save()
954
955     def tearDown(self):
956         OOFDataModel.objects.all().delete()
957
958     @mock.patch.object(resmgr, "grant_vnf")
959     def test_exec_grant(self, mock_grant):
960         resmgr_grant_resp = {
961             "vim": {
962                 "vimId": "cloudOwner_casa",
963                 "accessInfo": {
964                     "tenant": "tenantA"
965                 }
966             }
967         }
968         mock_grant.return_value = resmgr_grant_resp
969         resp = GrantVnf(self.data).exec_grant()
970         self.assertEquals(resp['vimAssets']['computeResourceFlavours'][0]['vimConnectionId'], 'cloudOwner_casa')
971         self.assertEquals(resp['vimAssets']['computeResourceFlavours'][0]['resourceProviderId'], 'vg')
972         self.assertEquals(resp['vimAssets']['computeResourceFlavours'][0]['vimFlavourId'], '12345')
973
974
975 vnfd_model_dict = {
976     'local_storages': [],
977     'vdus': [
978         {
979             'volumn_storages': [
980
981             ],
982             'nfv_compute': {
983                 'mem_size': '',
984                 'num_cpus': u'2'
985             },
986             'local_storages': [
987
988             ],
989             'vdu_id': u'vdu_omm.001',
990             'image_file': u'opencos_sss_omm_img_release_20150723-1-disk1',
991             'dependencies': [
992
993             ],
994             'vls': [
995
996             ],
997             'cps': [
998
999             ],
1000             'properties': {
1001                 'key_vdu': '',
1002                 'support_scaling': False,
1003                 'vdu_type': '',
1004                 'name': '',
1005                 'storage_policy': '',
1006                 'location_info': {
1007                     'vimId': '',
1008                     'availability_zone': '',
1009                     'region': '',
1010                     'dc': '',
1011                     'host': '',
1012                     'tenant': ''
1013                 },
1014                 'inject_data_list': [
1015
1016                 ],
1017                 'watchdog': {
1018                     'action': '',
1019                     'enabledelay': ''
1020                 },
1021                 'local_affinity_antiaffinity_rule': {
1022
1023                 },
1024                 'template_id': u'omm.001',
1025                 'manual_scale_select_vim': False
1026             },
1027             'description': u'singleommvm'
1028         },
1029         {
1030             'volumn_storages': [
1031
1032             ],
1033             'nfv_compute': {
1034                 'mem_size': '',
1035                 'num_cpus': u'4'
1036             },
1037             'local_storages': [
1038
1039             ],
1040             'vdu_id': u'vdu_1',
1041             'image_file': u'sss',
1042             'dependencies': [
1043
1044             ],
1045             'vls': [
1046
1047             ],
1048             'cps': [
1049
1050             ],
1051             'properties': {
1052                 'key_vdu': '',
1053                 'support_scaling': False,
1054                 'vdu_type': '',
1055                 'name': '',
1056                 'storage_policy': '',
1057                 'location_info': {
1058                     'vimId': '',
1059                     'availability_zone': '',
1060                     'region': '',
1061                     'dc': '',
1062                     'host': '',
1063                     'tenant': ''
1064                 },
1065                 'inject_data_list': [
1066
1067                 ],
1068                 'watchdog': {
1069                     'action': '',
1070                     'enabledelay': ''
1071                 },
1072                 'local_affinity_antiaffinity_rule': {
1073
1074                 },
1075                 'template_id': u'1',
1076                 'manual_scale_select_vim': False
1077             },
1078             'description': u'ompvm'
1079         },
1080         {
1081             'volumn_storages': [
1082
1083             ],
1084             'nfv_compute': {
1085                 'mem_size': '',
1086                 'num_cpus': u'14'
1087             },
1088             'local_storages': [
1089
1090             ],
1091             'vdu_id': u'vdu_2',
1092             'image_file': u'sss',
1093             'dependencies': [
1094
1095             ],
1096             'vls': [
1097
1098             ],
1099             'cps': [
1100
1101             ],
1102             'properties': {
1103                 'key_vdu': '',
1104                 'support_scaling': False,
1105                 'vdu_type': '',
1106                 'name': '',
1107                 'storage_policy': '',
1108                 'location_info': {
1109                     'vimId': '',
1110                     'availability_zone': '',
1111                     'region': '',
1112                     'dc': '',
1113                     'host': '',
1114                     'tenant': ''
1115                 },
1116                 'inject_data_list': [
1117
1118                 ],
1119                 'watchdog': {
1120                     'action': '',
1121                     'enabledelay': ''
1122                 },
1123                 'local_affinity_antiaffinity_rule': {
1124
1125                 },
1126                 'template_id': u'2',
1127                 'manual_scale_select_vim': False
1128             },
1129             'description': u'ompvm'
1130         },
1131         {
1132             'volumn_storages': [
1133
1134             ],
1135             'nfv_compute': {
1136                 'mem_size': '',
1137                 'num_cpus': u'14'
1138             },
1139             'local_storages': [
1140
1141             ],
1142             'vdu_id': u'vdu_3',
1143             'image_file': u'sss',
1144             'dependencies': [
1145
1146             ],
1147             'vls': [
1148
1149             ],
1150             'cps': [
1151
1152             ],
1153             'properties': {
1154                 'key_vdu': '',
1155                 'support_scaling': False,
1156                 'vdu_type': '',
1157                 'name': '',
1158                 'storage_policy': '',
1159                 'location_info': {
1160                     'vimId': '',
1161                     'availability_zone': '',
1162                     'region': '',
1163                     'dc': '',
1164                     'host': '',
1165                     'tenant': ''
1166                 },
1167                 'inject_data_list': [
1168
1169                 ],
1170                 'watchdog': {
1171                     'action': '',
1172                     'enabledelay': ''
1173                 },
1174                 'local_affinity_antiaffinity_rule': {
1175
1176                 },
1177                 'template_id': u'3',
1178                 'manual_scale_select_vim': False
1179             },
1180             'description': u'ompvm'
1181         },
1182         {
1183             'volumn_storages': [
1184
1185             ],
1186             'nfv_compute': {
1187                 'mem_size': '',
1188                 'num_cpus': u'4'
1189             },
1190             'local_storages': [
1191
1192             ],
1193             'vdu_id': u'vdu_10',
1194             'image_file': u'sss',
1195             'dependencies': [
1196
1197             ],
1198             'vls': [
1199
1200             ],
1201             'cps': [
1202
1203             ],
1204             'properties': {
1205                 'key_vdu': '',
1206                 'support_scaling': False,
1207                 'vdu_type': '',
1208                 'name': '',
1209                 'storage_policy': '',
1210                 'location_info': {
1211                     'vimId': '',
1212                     'availability_zone': '',
1213                     'region': '',
1214                     'dc': '',
1215                     'host': '',
1216                     'tenant': ''
1217                 },
1218                 'inject_data_list': [
1219
1220                 ],
1221                 'watchdog': {
1222                     'action': '',
1223                     'enabledelay': ''
1224                 },
1225                 'local_affinity_antiaffinity_rule': {
1226
1227                 },
1228                 'template_id': u'10',
1229                 'manual_scale_select_vim': False
1230             },
1231             'description': u'ppvm'
1232         },
1233         {
1234             'volumn_storages': [
1235
1236             ],
1237             'nfv_compute': {
1238                 'mem_size': '',
1239                 'num_cpus': u'14'
1240             },
1241             'local_storages': [
1242
1243             ],
1244             'vdu_id': u'vdu_11',
1245             'image_file': u'sss',
1246             'dependencies': [
1247
1248             ],
1249             'vls': [
1250
1251             ],
1252             'cps': [
1253
1254             ],
1255             'properties': {
1256                 'key_vdu': '',
1257                 'support_scaling': False,
1258                 'vdu_type': '',
1259                 'name': '',
1260                 'storage_policy': '',
1261                 'location_info': {
1262                     'vimId': '',
1263                     'availability_zone': '',
1264                     'region': '',
1265                     'dc': '',
1266                     'host': '',
1267                     'tenant': ''
1268                 },
1269                 'inject_data_list': [
1270
1271                 ],
1272                 'watchdog': {
1273                     'action': '',
1274                     'enabledelay': ''
1275                 },
1276                 'local_affinity_antiaffinity_rule': {
1277
1278                 },
1279                 'template_id': u'11',
1280                 'manual_scale_select_vim': False
1281             },
1282             'description': u'ppvm'
1283         },
1284         {
1285             'volumn_storages': [
1286
1287             ],
1288             'nfv_compute': {
1289                 'mem_size': '',
1290                 'num_cpus': u'14'
1291             },
1292             'local_storages': [
1293
1294             ],
1295             'vdu_id': u'vdu_12',
1296             'image_file': u'sss',
1297             'dependencies': [
1298
1299             ],
1300             'vls': [
1301
1302             ],
1303             'cps': [
1304
1305             ],
1306             'properties': {
1307                 'key_vdu': '',
1308                 'support_scaling': False,
1309                 'vdu_type': '',
1310                 'name': '',
1311                 'storage_policy': '',
1312                 'location_info': {
1313                     'vimId': '',
1314                     'availability_zone': '',
1315                     'region': '',
1316                     'dc': '',
1317                     'host': '',
1318                     'tenant': ''
1319                 },
1320                 'inject_data_list': [
1321
1322                 ],
1323                 'watchdog': {
1324                     'action': '',
1325                     'enabledelay': ''
1326                 },
1327                 'local_affinity_antiaffinity_rule': {
1328
1329                 },
1330                 'template_id': u'12',
1331                 'manual_scale_select_vim': False
1332             },
1333             'description': u'ppvm'
1334         }
1335     ],
1336     'volumn_storages': [
1337
1338     ],
1339     'policies': {
1340         'scaling': {
1341             'targets': {
1342
1343             },
1344             'policy_id': u'policy_scale_sss-vnf-template',
1345             'properties': {
1346                 'policy_file': '*-vnfd.zip/*-vnf-policy.xml'
1347             },
1348             'description': ''
1349         }
1350     },
1351     'image_files': [
1352         {
1353             'description': '',
1354             'properties': {
1355                 'name': u'opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
1356                 'checksum': '',
1357                 'disk_format': u'VMDK',
1358                 'file_url': u'./zte-cn-sss-main-image/OMM/opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
1359                 'container_type': 'vm',
1360                 'version': '',
1361                 'hypervisor_type': 'kvm'
1362             },
1363             'image_file_id': u'opencos_sss_omm_img_release_20150723-1-disk1'
1364         },
1365         {
1366             'description': '',
1367             'properties': {
1368                 'name': u'sss.vmdk',
1369                 'checksum': '',
1370                 'disk_format': u'VMDK',
1371                 'file_url': u'./zte-cn-sss-main-image/NE/sss.vmdk',
1372                 'container_type': 'vm',
1373                 'version': '',
1374                 'hypervisor_type': 'kvm'
1375             },
1376             'image_file_id': u'sss'
1377         }
1378     ],
1379     'vls': [
1380
1381     ],
1382     'cps': [
1383
1384     ],
1385     'metadata': {
1386         'vendor': u'zte',
1387         'is_shared': False,
1388         'description': '',
1389         'domain_type': u'CN',
1390         'version': u'v4.14.10',
1391         'vmnumber_overquota_alarm': False,
1392         'cross_dc': False,
1393         'vnf_type': u'SSS',
1394         'vnfd_version': u'V00000001',
1395         'id': u'sss-vnf-template',
1396         'name': u'sss-vnf-template'
1397     }
1398 }
1399
1400 nsd_model_dict = {
1401     "vnffgs": [
1402
1403     ],
1404     "inputs": {
1405         "externalDataNetworkName": {
1406             "default": "",
1407             "type": "string",
1408             "description": ""
1409         }
1410     },
1411     "pnfs": [
1412
1413     ],
1414     "fps": [
1415
1416     ],
1417     "server_groups": [
1418
1419     ],
1420     "ns_flavours": [
1421
1422     ],
1423     "vnfs": [
1424         {
1425             "dependency": [
1426
1427             ],
1428             "properties": {
1429                 "plugin_info": "vbrasplugin_1.0",
1430                 "vendor": "zte",
1431                 "is_shared": "False",
1432                 "request_reclassification": "False",
1433                 "vnfd_version": "1.0.0",
1434                 "version": "1.0",
1435                 "nsh_aware": "True",
1436                 "cross_dc": "False",
1437                 "externalDataNetworkName": {
1438                     "get_input": "externalDataNetworkName"
1439                 },
1440                 "id": "zte_vbras",
1441                 "name": "vbras"
1442             },
1443             "vnf_id": "VBras",
1444             "networks": [
1445
1446             ],
1447             "description": ""
1448         }
1449     ],
1450     "ns_exposed": {
1451         "external_cps": [
1452
1453         ],
1454         "forward_cps": [
1455
1456         ]
1457     },
1458     "vls": [
1459         {
1460             "vl_id": "ext_mnet_network",
1461             "description": "",
1462             "properties": {
1463                 "network_type": "vlan",
1464                 "name": "externalMNetworkName",
1465                 "dhcp_enabled": False,
1466                 "location_info": {
1467                     "host": True,
1468                     "vimid": 2,
1469                     "region": True,
1470                     "tenant": "admin",
1471                     "dc": ""
1472                 },
1473                 "end_ip": "190.168.100.100",
1474                 "gateway_ip": "190.168.100.1",
1475                 "start_ip": "190.168.100.2",
1476                 "cidr": "190.168.100.0/24",
1477                 "mtu": 1500,
1478                 "network_name": "sub_mnet",
1479                 "ip_version": 4
1480             }
1481         }
1482     ],
1483     "cps": [
1484
1485     ],
1486     "policies": [
1487
1488     ],
1489     "metadata": {
1490         "invariant_id": "vbras_ns",
1491         "description": "vbras_ns",
1492         "version": 1,
1493         "vendor": "zte",
1494         "id": "vbras_ns",
1495         "name": "vbras_ns"
1496     }
1497 }
1498
1499 vserver_info = {
1500     "vserver-id": "example-vserver-id-val-70924",
1501     "vserver-name": "example-vserver-name-val-61674",
1502     "vserver-name2": "example-vserver-name2-val-19234",
1503     "prov-status": "example-prov-status-val-94916",
1504     "vserver-selflink": "example-vserver-selflink-val-26562",
1505     "in-maint": True,
1506     "is-closed-loop-disabled": True,
1507     "resource-version": "1505465356263",
1508     "volumes": {
1509         "volume": [
1510             {
1511                 "volume-id": "example-volume-id-val-71854",
1512                 "volume-selflink": "example-volume-selflink-val-22433"
1513             }
1514         ]
1515     },
1516     "l-interfaces": {
1517         "l-interface": [
1518             {
1519                 "interface-name": "example-interface-name-val-24351",
1520                 "interface-role": "example-interface-role-val-43242",
1521                 "v6-wan-link-ip": "example-v6-wan-link-ip-val-4196",
1522                 "selflink": "example-selflink-val-61295",
1523                 "interface-id": "example-interface-id-val-95879",
1524                 "macaddr": "example-macaddr-val-37302",
1525                 "network-name": "example-network-name-val-44254",
1526                 "management-option": "example-management-option-val-49009",
1527                 "interface-description": "example-interface-description-val-99923",
1528                 "is-port-mirrored": True,
1529                 "in-maint": True,
1530                 "prov-status": "example-prov-status-val-4698",
1531                 "is-ip-unnumbered": True,
1532                 "allowed-address-pairs": "example-allowed-address-pairs-val-5762",
1533                 "vlans": {
1534                     "vlan": [
1535                         {
1536                             "vlan-interface": "example-vlan-interface-val-58193",
1537                             "vlan-id-inner": 54452151,
1538                             "vlan-id-outer": 70239293,
1539                             "speed-value": "example-speed-value-val-18677",
1540                             "speed-units": "example-speed-units-val-46185",
1541                             "vlan-description": "example-vlan-description-val-81675",
1542                             "backdoor-connection": "example-backdoor-connection-val-44608",
1543                             "vpn-key": "example-vpn-key-val-7946",
1544                             "orchestration-status": "example-orchestration-status-val-33611",
1545                             "in-maint": True,
1546                             "prov-status": "example-prov-status-val-8288",
1547                             "is-ip-unnumbered": True,
1548                             "l3-interface-ipv4-address-list": [
1549                                 {
1550                                     "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-25520",
1551                                     "l3-interface-ipv4-prefix-length": 69931928,
1552                                     "vlan-id-inner": 86628520,
1553                                     "vlan-id-outer": 62729236,
1554                                     "is-floating": True,
1555                                     "neutron-network-id": "example-neutron-network-id-val-64021",
1556                                     "neutron-subnet-id": "example-neutron-subnet-id-val-95049"
1557                                 }
1558                             ],
1559                             "l3-interface-ipv6-address-list": [
1560                                 {
1561                                     "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-64310",
1562                                     "l3-interface-ipv6-prefix-length": 57919834,
1563                                     "vlan-id-inner": 79150122,
1564                                     "vlan-id-outer": 59789973,
1565                                     "is-floating": True,
1566                                     "neutron-network-id": "example-neutron-network-id-val-31713",
1567                                     "neutron-subnet-id": "example-neutron-subnet-id-val-89568"
1568                                 }
1569                             ]
1570                         }
1571                     ]
1572                 },
1573                 "sriov-vfs": {
1574                     "sriov-vf": [
1575                         {
1576                             "pci-id": "example-pci-id-val-16747",
1577                             "vf-vlan-filter": "example-vf-vlan-filter-val-4613",
1578                             "vf-mac-filter": "example-vf-mac-filter-val-68168",
1579                             "vf-vlan-strip": True,
1580                             "vf-vlan-anti-spoof-check": True,
1581                             "vf-mac-anti-spoof-check": True,
1582                             "vf-mirrors": "example-vf-mirrors-val-6270",
1583                             "vf-broadcast-allow": True,
1584                             "vf-unknown-multicast-allow": True,
1585                             "vf-unknown-unicast-allow": True,
1586                             "vf-insert-stag": True,
1587                             "vf-link-status": "example-vf-link-status-val-49266",
1588                             "neutron-network-id": "example-neutron-network-id-val-29493"
1589                         }
1590                     ]
1591                 },
1592                 "l-interfaces": {
1593                     "l-interface": [
1594                         {
1595                             "interface-name": "example-interface-name-val-98222",
1596                             "interface-role": "example-interface-role-val-78360",
1597                             "v6-wan-link-ip": "example-v6-wan-link-ip-val-76921",
1598                             "selflink": "example-selflink-val-27117",
1599                             "interface-id": "example-interface-id-val-11260",
1600                             "macaddr": "example-macaddr-val-60378",
1601                             "network-name": "example-network-name-val-16258",
1602                             "management-option": "example-management-option-val-35097",
1603                             "interface-description": "example-interface-description-val-10475",
1604                             "is-port-mirrored": True,
1605                             "in-maint": True,
1606                             "prov-status": "example-prov-status-val-65203",
1607                             "is-ip-unnumbered": True,
1608                             "allowed-address-pairs": "example-allowed-address-pairs-val-65028"
1609                         }
1610                     ]
1611                 },
1612                 "l3-interface-ipv4-address-list": [
1613                     {
1614                         "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-72779",
1615                         "l3-interface-ipv4-prefix-length": 55956636,
1616                         "vlan-id-inner": 98174431,
1617                         "vlan-id-outer": 20372128,
1618                         "is-floating": True,
1619                         "neutron-network-id": "example-neutron-network-id-val-39596",
1620                         "neutron-subnet-id": "example-neutron-subnet-id-val-51109"
1621                     }
1622                 ],
1623                 "l3-interface-ipv6-address-list": [
1624                     {
1625                         "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-95203",
1626                         "l3-interface-ipv6-prefix-length": 57454747,
1627                         "vlan-id-inner": 53421060,
1628                         "vlan-id-outer": 16006050,
1629                         "is-floating": True,
1630                         "neutron-network-id": "example-neutron-network-id-val-54216",
1631                         "neutron-subnet-id": "example-neutron-subnet-id-val-1841"
1632                     }
1633                 ]
1634             }
1635         ]
1636     }
1637 }
1638
1639
1640 vnfm_info = {
1641     "vnfm-id": "example-vnfm-id-val-97336",
1642     "vim-id": "zte_test",
1643     "certificate-url": "example-certificate-url-val-18046",
1644     "resource-version": "example-resource-version-val-42094",
1645     "esr-system-info-list": {
1646         "esr-system-info": [
1647             {
1648                 "esr-system-info-id": "example-esr-system-info-id-val-7713",
1649                 "system-name": "example-system-name-val-19801",
1650                 "type": "ztevnfmdriver",
1651                 "vendor": "example-vendor-val-50079",
1652                 "version": "example-version-val-93146",
1653                 "service-url": "example-service-url-val-68090",
1654                 "user-name": "example-user-name-val-14470",
1655                 "password": "example-password-val-84190",
1656                 "system-type": "example-system-type-val-42773",
1657                 "protocal": "example-protocal-val-85736",
1658                 "ssl-cacert": "example-ssl-cacert-val-33989",
1659                 "ssl-insecure": True,
1660                 "ip-address": "example-ip-address-val-99038",
1661                 "port": "example-port-val-27323",
1662                 "cloud-domain": "example-cloud-domain-val-55163",
1663                 "default-tenant": "example-default-tenant-val-99383",
1664                 "resource-version": "example-resource-version-val-15424"
1665             }
1666         ]
1667     }
1668 }
1669
1670 vim_info = {
1671     "cloud-owner": "example-cloud-owner-val-97336",
1672     "cloud-region-id": "example-cloud-region-id-val-35532",
1673     "cloud-type": "example-cloud-type-val-18046",
1674     "owner-defined-type": "example-owner-defined-type-val-9413",
1675     "cloud-region-version": "example-cloud-region-version-val-85706",
1676     "identity-url": "example-identity-url-val-71252",
1677     "cloud-zone": "example-cloud-zone-val-27112",
1678     "complex-name": "example-complex-name-val-85283",
1679     "sriov-automation": True,
1680     "cloud-extra-info": "example-cloud-extra-info-val-90854",
1681     "cloud-epa-caps": "example-cloud-epa-caps-val-2409",
1682     "resource-version": "example-resource-version-val-42094",
1683     "esr-system-info-list": {
1684         "esr-system-info": [
1685             {
1686                 "esr-system-info-id": "example-esr-system-info-id-val-7713",
1687                 "system-name": "example-system-name-val-19801",
1688                 "type": "example-type-val-24477",
1689                 "vendor": "example-vendor-val-50079",
1690                 "version": "example-version-val-93146",
1691                 "service-url": "example-service-url-val-68090",
1692                 "user-name": "example-user-name-val-14470",
1693                 "password": "example-password-val-84190",
1694                 "system-type": "example-system-type-val-42773",
1695                 "protocal": "example-protocal-val-85736",
1696                 "ssl-cacert": "example-ssl-cacert-val-33989",
1697                 "ssl-insecure": True,
1698                 "ip-address": "example-ip-address-val-99038",
1699                 "port": "example-port-val-27323",
1700                 "cloud-domain": "example-cloud-domain-val-55163",
1701                 "default-tenant": "admin",
1702                 "resource-version": "example-resource-version-val-15424"
1703             }
1704         ]
1705     }
1706 }
1707
1708 nf_package_info = {
1709     "csarId": "zte_vbras",
1710     "packageInfo": {
1711         "vnfdId": "1",
1712         "vnfPackageId": "zte_vbras",
1713         "vnfdProvider": "1",
1714         "vnfdVersion": "1",
1715         "vnfVersion": "1",
1716         "csarName": "1",
1717         "vnfdModel": vnfd_model_dict,
1718         "downloadUrl": "1"
1719     },
1720     "imageInfo": []
1721 }
1722
1723 vnf_place_request = {
1724     "requestId": "1234",
1725     "transactionId": "1234",
1726     "statusMessage": "xx",
1727     "requestStatus": "completed",
1728     "solutions": {
1729         "placementSolutions": [
1730             [
1731                 {
1732                     "resourceModuleName": "vG",
1733                     "serviceResourceId": "1234",
1734                     "solution": {
1735                         "identifierType": "serviceInstanceId",
1736                         "identifiers": [
1737                             "xx"
1738                         ],
1739                         "cloudOwner": "CloudOwner1"
1740                     },
1741                     "assignmentInfo": [
1742                         {"key": "isRehome",
1743                          "value": "false"
1744                          },
1745                         {"key": "locationId",
1746                          "value": "DLLSTX1A"
1747                          },
1748                         {"key": "locationType",
1749                          "value": "openstack-cloud"
1750                          },
1751                         {"key": "vimId",
1752                          "value": "CloudOwner1_DLLSTX1A"
1753                          },
1754                         {"key": "physicalLocationId",
1755                          "value": "DLLSTX1223"
1756                          },
1757                         {"key": "oof_directives",
1758                          "value": {
1759                              "directives": [
1760                                  {
1761                                      "id": "vG_0",
1762                                      "type": "tosca.nodes.nfv.Vdu.Compute",
1763                                      "directives": [
1764                                          {
1765                                              "type": "flavor_directives",
1766                                              "attributes": [
1767                                                  {
1768                                                      "attribute_name": "flavorName",
1769                                                      "attribute_value": "HPA.flavor.1"
1770                                                  },
1771                                                  {
1772                                                      "attribute_name": "flavorId",
1773                                                      "attribute_value": "12345"
1774                                                  },
1775                                              ]
1776                                          }
1777                                      ]
1778                                  },
1779                                  {
1780                                      "id": "",
1781                                      "type": "vnf",
1782                                      "directives": [
1783                                          {"type": " ",
1784                                           "attributes": [
1785                                               {
1786                                                   "attribute_name": " ",
1787                                                   "attribute_value": " "
1788                                               }
1789                                           ]
1790                                           }
1791                                      ]
1792                                  }
1793                              ]
1794                          }
1795                          }
1796                     ]
1797                 }
1798             ]
1799         ],
1800         "licenseSolutions": [
1801             {
1802                 "resourceModuleName": "string",
1803                 "serviceResourceId": "string",
1804                 "entitlementPoolUUID": [
1805                     "string"
1806                 ],
1807                 "licenseKeyGroupUUID": [
1808                     "string"
1809                 ],
1810                 "entitlementPoolInvariantUUID": [
1811                     "string"
1812                 ],
1813                 "licenseKeyGroupInvariantUUID": [
1814                     "string"
1815                 ]
1816             }
1817         ]
1818     }
1819 }