Modify code of apply_grant
[vfc/gvnfm/vnflcm.git] / lcm / lcm / nf / vnfs / tests / test_vnf_create.py
1 # Copyright 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.nf.vnfs.vnf_create.inst_vnf import InstVnf
22 from lcm.pub.database.models import NfInstModel, JobStatusModel, VmInstModel, NetworkInstModel, \
23     SubNetworkInstModel, PortInstModel
24 from lcm.pub.utils import restcall
25 from lcm.pub.utils.jobutil import JobUtil
26 from lcm.pub.utils.timeutil import now_time
27
28
29 class TestNFInstantiate(TestCase):
30     def setUp(self):
31         self.client = Client()
32         VmInstModel.objects.create(vmid="1", vimid="1", resouceid="11", insttype=0, instid="1", vmname="test_01",
33                                    operationalstate=1)
34         VmInstModel.objects.create(vmid="2", vimid="2", resouceid="22", insttype=0, instid="2",
35                                    vmname="test_02", operationalstate=1)
36         NetworkInstModel.objects.create(networkid='1', vimid='1', resouceid='1', name='pnet_network',
37                                         tenant='admin', insttype=0, instid='1')
38         SubNetworkInstModel.objects.create(subnetworkid='1', vimid='1', resouceid='1', networkid='1',
39                                            name='sub_pnet', tenant='admin', insttype=0, instid='1')
40         PortInstModel.objects.create(portid='1', networkid='1', subnetworkid='1', vimid='1', resouceid='1',
41                                      name='aaa_pnet_cp', tenant='admin', insttype=0, instid='1')
42
43     def tearDown(self):
44         pass
45         VmInstModel.objects.all().delete()
46         NetworkInstModel.objects.all().delete()
47         SubNetworkInstModel.objects.all().delete()
48         PortInstModel.objects.all().delete()
49
50     def assert_job_result(self, job_id, job_progress, job_detail):
51         jobs = JobStatusModel.objects.filter(
52             jobid=job_id,
53             progress=job_progress,
54             descp=job_detail)
55         self.assertEqual(1, len(jobs))
56
57     def test_swagger_ok(self):
58         response = self.client.get("/openoapi/vnflcm/v1/swagger.json", format='json')
59         self.assertEqual(response.status_code, status.HTTP_200_OK)
60
61     @mock.patch.object(restcall, 'call_req')
62     def test_create_vnf_identifier(self, mock_call_req):
63         r1 = [0, json.JSONEncoder().encode({'package_id':'222', 'csar_id':'2222'}), '200']  # get csar_id from nslcm by vnfd_id
64         r2 = [0, json.JSONEncoder().encode(vnfd_raw_data), '200']
65         mock_call_req.side_effect = [r1, r2]
66         data = {
67             "vnfdId": "111",
68             "vnfInstanceName": "vFW_01",
69             "vnfInstanceDescription": "vFW in Nanjing TIC Edge"}
70         response = self.client.post("/openoapi/vnflcm/v1/vnf_instances", data=data, format='json')
71         self.failUnlessEqual(status.HTTP_201_CREATED, response.status_code)
72         context = json.loads(response.content)
73         self.assertTrue(NfInstModel.objects.filter(nfinstid=context['vnfInstanceId']).exists())
74
75     @mock.patch.object(InstVnf, 'run')
76     def test_instantiate_vnf(self, mock_run):
77         mock_run.re.return_value = None
78         response = self.client.post("/openoapi/vnflcm/v1/vnf_instances/12/instantiate", data={}, format='json')
79         self.failUnlessEqual(status.HTTP_202_ACCEPTED, response.status_code)
80
81     def test_instantiate_vnf_when_inst_id_not_exist(self):
82         self.nf_inst_id = str(uuid.uuid4())
83         self.job_id = JobUtil.create_job('NF', 'CREATE', self.nf_inst_id)
84         JobUtil.add_job_status(self.job_id, 0, "INST_VNF_READY")
85         data = inst_req_data
86         InstVnf(data, nf_inst_id=self.nf_inst_id, job_id=self.job_id).run()
87         self.assert_job_result(self.job_id, 255, "VNF nf_inst_id is not exist.")
88
89     @mock.patch.object(restcall, 'call_req')
90     def test_instantiate_vnf_when_get_package_info_by_vnfdid_failed(self, mock_call_req):
91         NfInstModel.objects.create(nfinstid='1111', nf_name='vFW_01', package_id='222',
92                                    version='', vendor='', netype='', vnfd_model='', status='NOT_INSTANTIATED',
93                                    nf_desc='vFW in Nanjing TIC Edge', vnfdid='111', create_time=now_time())
94         r1 = [1, json.JSONEncoder().encode({'package_id':'222', 'csar_id':'2222'}), '200']  # get csar_id from nslcm by vnfd_id
95         mock_call_req.side_effect = [r1]
96         self.nf_inst_id = '1111'
97         self.job_id = JobUtil.create_job('NF', 'CREATE', self.nf_inst_id)
98         JobUtil.add_job_status(self.job_id, 0, "INST_VNF_READY")
99         data = inst_req_data
100         InstVnf(data, nf_inst_id=self.nf_inst_id, job_id=self.job_id).run()
101         self.assert_job_result(self.job_id, 255, "Failed to query package_info of vnfdid(111) from nslcm.")
102
103     @mock.patch.object(restcall, 'call_req')
104     def test_instantiate_vnf_when_get_rawdata_by_csarid_failed(self, mock_call_req):
105         NfInstModel.objects.create(nfinstid='1111', nf_name='vFW_01', package_id='222',
106                                    version='', vendor='', netype='', vnfd_model='', status='NOT_INSTANTIATED',
107                                    nf_desc='vFW in Nanjing TIC Edge', vnfdid='111', create_time=now_time())
108         r1 = [0, json.JSONEncoder().encode({'package_id':'222', 'csar_id':'2222'}), '200']  # get csar_id from nslcm by vnfd_id
109         r2 = [1, json.JSONEncoder().encode(vnfd_raw_data), '200']
110         mock_call_req.side_effect = [r1, r2]
111         self.nf_inst_id = '1111'
112         self.job_id = JobUtil.create_job('NF', 'CREATE', self.nf_inst_id)
113         JobUtil.add_job_status(self.job_id, 0, "INST_VNF_READY")
114         data = inst_req_data
115         InstVnf(data, nf_inst_id=self.nf_inst_id, job_id=self.job_id).run()
116         self.assert_job_result(self.job_id, 255, "Failed to query rawdata of CSAR(2222) from catalog.")
117
118     @mock.patch.object(restcall, 'call_req')
119     def test_instantiate_vnf_when_failed(self, mock_call_req):
120         NfInstModel.objects.create(nfinstid='1111', nf_name='vFW_01', package_id='222',
121                                    version='', vendor='', netype='', vnfd_model='', status='NOT_INSTANTIATED',
122                                    nf_desc='vFW in Nanjing TIC Edge', vnfdid='111', create_time=now_time())
123         r1 = [0, json.JSONEncoder().encode({'package_id': '222', 'csar_id': '2222'}), '200']  # get csar_id from nslcm by vnfd_id
124         r2 = [0, json.JSONEncoder().encode(vnfd_raw_data), '200']
125         r3 = [1, json.JSONEncoder().encode(''), '200']
126         mock_call_req.side_effect = [r1, r2, r3]
127         self.nf_inst_id = '1111'
128         self.job_id = JobUtil.create_job('NF', 'CREATE', self.nf_inst_id)
129         JobUtil.add_job_status(self.job_id, 0, "INST_VNF_READY")
130         data = inst_req_data
131         InstVnf(data, nf_inst_id=self.nf_inst_id, job_id=self.job_id).run()
132         self.assert_job_result(self.job_id, 255, "Nf instancing apply grant exception")
133
134
135
136     # @mock.patch.object(restcall, 'call_req')
137     # def test_instantiate_vnf_when_applay_grant_failed(self, mock_call_req):
138     #     NfvoRegInfoModel.objects.create(nfvoid='nfvo111', vnfminstid='vnfm111', apiurl='http://10.74.44.11',
139     #                                     nfvouser='root', nfvopassword='root123')
140     #     r1 = [0, json.JSONEncoder().encode(vnfd_model_dict), '200']
141     #     r2 = [0, json.JSONEncoder().encode(vnfd_model_dict), '200']
142     #     r3 = [1, json.JSONEncoder().encode(''), '200']
143     #     mock_call_req.side_effect = [r1, r2, r3]
144     #     create_data = {
145     #         "vnfdId": "111",
146     #         "vnfInstanceName": "vFW_01",
147     #         "vnfInstanceDescription": " vFW in Nanjing TIC Edge"}
148     #     self.nf_inst_id = CreateVnf(create_data).do_biz()
149     #     self.job_id = JobUtil.create_job('NF', 'CREATE', self.nf_inst_id)
150     #     JobUtil.add_job_status(self.job_id, 0, "INST_VNF_READY")
151     #     data = inst_req_data
152     #     InstVnf(data, nf_inst_id=self.nf_inst_id, job_id=self.job_id).run()
153     #     self.assert_job_result(self.job_id, 255, "Nf instancing apply grant exception")
154
155     # @mock.patch.object(restcall, 'call_req')
156     # # @mock.patch.object(adaptor, 'create_vim_res')
157     # def test_instantiate_vnf_when_create_res_failed(self, mock_call_req):
158     #     NfvoRegInfoModel.objects.create(nfvoid='nfvo111', vnfminstid='vnfm111', apiurl='http://10.74.44.11',
159     #                                     nfvouser='root', nfvopassword='root123')
160     #     r1 = [0, json.JSONEncoder().encode(vnfd_model_dict), '200']
161     #     r2 = [0, json.JSONEncoder().encode(vnfd_model_dict), '200']
162     #     r3 = [0, json.JSONEncoder().encode('Nf instancing apply grant'), '200']
163     #     # r4 = [0, json.JSONEncoder().encode('Nf instancing apply resource'), '200']
164     #     mock_call_req.side_effect = [r1, r2, r3]
165     #     # mock_create_vim_res.re.return_value = None
166     #     create_data = {
167     #         "vnfdId": "111",
168     #         "vnfInstanceName": "vFW_01",
169     #         "vnfInstanceDescription": " vFW in Nanjing TIC Edge"}
170     #     self.nf_inst_id = CreateVnf(create_data).do_biz()
171     #     self.job_id = JobUtil.create_job('NF', 'CREATE', self.nf_inst_id)
172     #     JobUtil.add_job_status(self.job_id, 0, "INST_VNF_READY")
173     #     data = inst_req_data
174     #     InstVnf(data, nf_inst_id=self.nf_inst_id, job_id=self.job_id).run()
175     #     self.assert_job_result(self.job_id, 255, "Create resource failed")
176
177     # @mock.patch.object(restcall, 'call_req')
178     # # @mock.patch.object(adaptor, 'create_vim_res')
179     # def test_instantiate_vnf_success(self, mock_call_req):
180     #     NfvoRegInfoModel.objects.create(nfvoid='nfvo111', vnfminstid='vnfm111', apiurl='http://10.74.44.11',
181     #                                     nfvouser='root', nfvopassword='root123')
182     #     r1 = [0, json.JSONEncoder().encode(vnfd_model_dict), '200']
183     #     r2 = [0, json.JSONEncoder().encode(vnfd_model_dict), '200']
184     #     r3 = [0, json.JSONEncoder().encode('Nf instancing apply grant'), '200']
185     #     r4 = [0, json.JSONEncoder().encode('None'), '200']
186     #     mock_call_req.side_effect = [r1, r2, r3, r4]
187     #     # mock_create_vim_res.re.return_value = None
188     #     create_data = {
189     #         "vnfdId": "111",
190     #         "vnfInstanceName": "vFW_01",
191     #         "vnfInstanceDescription": " vFW in Nanjing TIC Edge"}
192     #     self.nf_inst_id = CreateVnf(create_data).do_biz()
193     #     self.job_id = JobUtil.create_job('NF', 'CREATE', self.nf_inst_id)
194     #     JobUtil.add_job_status(self.job_id, 0, "INST_VNF_READY")
195     #     data = inst_req_data
196     #     InstVnf(data, nf_inst_id=self.nf_inst_id, job_id=self.job_id).run()
197     #     self.assert_job_result(self.job_id, 100, "Instantiate Vnf success.")
198
199 inst_req_data = {
200     "flavourId": "flavour_1",
201     "instantiationLevelId": "instantiationLevel_1",
202     "extVirtualLinks": [
203         {
204             "vlInstanceId": "1",
205             "vim": {
206                 "vimInfoId": "1",
207                 "vimId": "1",
208                 "interfaceInfo": {
209                     "vimType": "vim",
210                     "apiVersion": "v2",
211                     "protocolType": "http"
212                 },
213                 "accessInfo": {
214                     "tenant": "tenant_vCPE",
215                     "username": "vCPE",
216                     "password": "vCPE_321"
217                 },
218                 "interfaceEndpoint": "http://10.43.21.105:80/"
219             },
220             "resourceId": "1246",
221             "extCps": [
222                 {
223                     "cpdId": "11",
224                     "addresses": [
225                         {
226                             "addressType": "MAC",
227                             "l2AddressData": "00:f3:43:20:a2:a3"
228                         },
229                         {
230                             "addressType": "IP",
231                             "l3AddressData": {
232                                 "iPAddressType": "IPv4",
233                                 "iPAddress": "192.168.104.2"
234                             }
235                         }
236                     ],
237                     "numDynamicAddresses": 0
238                 }
239             ]
240         }
241     ],
242     "localizationLanguage": "en_US",
243     "additionalParams": {}
244 }
245
246 vnfd_model_dict = {
247     'local_storages': [],
248     'vdus': [
249         {
250             'volumn_storages': [],
251             'nfv_compute': {
252                 'mem_size': '',
253                 'num_cpus': u'2'},
254             'local_storages': [],
255             'vdu_id': u'vdu_omm.001',
256             'image_file': u'opencos_sss_omm_img_release_20150723-1-disk1',
257             'dependencies': [],
258             'vls': [],
259             'cps': [],
260             'properties': {
261                 'key_vdu': '',
262                 'support_scaling': False,
263                 'vdu_type': '',
264                 'name': '',
265                 'storage_policy': '',
266                 'location_info': {
267                     'vimId': '',
268                     'availability_zone': '',
269                     'region': '',
270                     'dc': '',
271                     'host': '',
272                     'tenant': ''},
273                 'inject_data_list': [],
274                 'watchdog': {
275                     'action': '',
276                     'enabledelay': ''},
277                 'local_affinity_antiaffinity_rule': {},
278                 'template_id': u'omm.001',
279                 'manual_scale_select_vim': False},
280             'description': u'singleommvm'},
281         {
282             'volumn_storages': [],
283             'nfv_compute': {
284                 'mem_size': '',
285                 'num_cpus': u'4'},
286             'local_storages': [],
287             'vdu_id': u'vdu_1',
288             'image_file': u'sss',
289             'dependencies': [],
290             'vls': [],
291             'cps': [],
292             'properties': {
293                 'key_vdu': '',
294                 'support_scaling': False,
295                 'vdu_type': '',
296                 'name': '',
297                 'storage_policy': '',
298                 'location_info': {
299                     'vimId': '',
300                     'availability_zone': '',
301                     'region': '',
302                     'dc': '',
303                     'host': '',
304                     'tenant': ''},
305                 'inject_data_list': [],
306                 'watchdog': {
307                     'action': '',
308                     'enabledelay': ''},
309                 'local_affinity_antiaffinity_rule': {},
310                 'template_id': u'1',
311                 'manual_scale_select_vim': False},
312             'description': u'ompvm'},
313         {
314             'volumn_storages': [],
315             'nfv_compute': {
316                 'mem_size': '',
317                 'num_cpus': u'14'},
318             'local_storages': [],
319             'vdu_id': u'vdu_2',
320             'image_file': u'sss',
321             'dependencies': [],
322             'vls': [],
323             'cps': [],
324             'properties': {
325                 'key_vdu': '',
326                 'support_scaling': False,
327                 'vdu_type': '',
328                 'name': '',
329                 'storage_policy': '',
330                 'location_info': {
331                     'vimId': '',
332                     'availability_zone': '',
333                     'region': '',
334                     'dc': '',
335                     'host': '',
336                     'tenant': ''},
337                 'inject_data_list': [],
338                 'watchdog': {
339                     'action': '',
340                     'enabledelay': ''},
341                 'local_affinity_antiaffinity_rule': {},
342                 'template_id': u'2',
343                 'manual_scale_select_vim': False},
344             'description': u'ompvm'},
345         {
346             'volumn_storages': [],
347             'nfv_compute': {
348                 'mem_size': '',
349                 'num_cpus': u'14'},
350             'local_storages': [],
351             'vdu_id': u'vdu_3',
352             'image_file': u'sss',
353             'dependencies': [],
354             'vls': [],
355             'cps': [],
356             'properties': {
357                 'key_vdu': '',
358                 'support_scaling': False,
359                 'vdu_type': '',
360                 'name': '',
361                 'storage_policy': '',
362                 'location_info': {
363                     'vimId': '',
364                     'availability_zone': '',
365                     'region': '',
366                     'dc': '',
367                     'host': '',
368                     'tenant': ''},
369                 'inject_data_list': [],
370                 'watchdog': {
371                     'action': '',
372                     'enabledelay': ''},
373                 'local_affinity_antiaffinity_rule': {},
374                 'template_id': u'3',
375                 'manual_scale_select_vim': False},
376             'description': u'ompvm'},
377         {
378             'volumn_storages': [],
379             'nfv_compute': {
380                 'mem_size': '',
381                 'num_cpus': u'4'},
382             'local_storages': [],
383             'vdu_id': u'vdu_10',
384             'image_file': u'sss',
385             'dependencies': [],
386             'vls': [],
387             'cps': [],
388             'properties': {
389                 'key_vdu': '',
390                 'support_scaling': False,
391                 'vdu_type': '',
392                 'name': '',
393                 'storage_policy': '',
394                 'location_info': {
395                     'vimId': '',
396                     'availability_zone': '',
397                     'region': '',
398                     'dc': '',
399                     'host': '',
400                     'tenant': ''},
401                 'inject_data_list': [],
402                 'watchdog': {
403                     'action': '',
404                     'enabledelay': ''},
405                 'local_affinity_antiaffinity_rule': {},
406                 'template_id': u'10',
407                 'manual_scale_select_vim': False},
408             'description': u'ppvm'},
409         {
410             'volumn_storages': [],
411             'nfv_compute': {
412                 'mem_size': '',
413                 'num_cpus': u'14'},
414             'local_storages': [],
415             'vdu_id': u'vdu_11',
416             'image_file': u'sss',
417             'dependencies': [],
418             'vls': [],
419             'cps': [],
420             'properties': {
421                 'key_vdu': '',
422                 'support_scaling': False,
423                 'vdu_type': '',
424                 'name': '',
425                 'storage_policy': '',
426                 'location_info': {
427                     'vimId': '',
428                     'availability_zone': '',
429                     'region': '',
430                     'dc': '',
431                     'host': '',
432                     'tenant': ''},
433                 'inject_data_list': [],
434                 'watchdog': {
435                     'action': '',
436                     'enabledelay': ''},
437                 'local_affinity_antiaffinity_rule': {},
438                 'template_id': u'11',
439                 'manual_scale_select_vim': False},
440             'description': u'ppvm'},
441         {
442             'volumn_storages': [],
443             'nfv_compute': {
444                 'mem_size': '',
445                 'num_cpus': u'14'},
446             'local_storages': [],
447             'vdu_id': u'vdu_12',
448             'image_file': u'sss',
449             'dependencies': [],
450             'vls': [],
451             'cps': [],
452             'properties': {
453                 'key_vdu': '',
454                 'support_scaling': False,
455                 'vdu_type': '',
456                 'name': '',
457                 'storage_policy': '',
458                 'location_info': {
459                     'vimId': '',
460                     'availability_zone': '',
461                     'region': '',
462                     'dc': '',
463                     'host': '',
464                     'tenant': ''},
465                 'inject_data_list': [],
466                 'watchdog': {
467                     'action': '',
468                     'enabledelay': ''},
469                 'local_affinity_antiaffinity_rule': {},
470                 'template_id': u'12',
471                 'manual_scale_select_vim': False},
472             'description': u'ppvm'}],
473     'volumn_storages': [],
474     'policies': {
475         'scaling': {
476             'targets': {},
477             'policy_id': u'policy_scale_sss-vnf-template',
478             'properties': {
479                 'policy_file': '*-vnfd.zip/*-vnf-policy.xml'},
480             'description': ''}},
481     'image_files': [
482         {
483             'description': '',
484             'properties': {
485                 'name': u'opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
486                 'checksum': '',
487                 'disk_format': u'VMDK',
488                 'file_url': u'./zte-cn-sss-main-image/OMM/opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
489                 'container_type': 'vm',
490                 'version': '',
491                 'hypervisor_type': 'kvm'},
492             'image_file_id': u'opencos_sss_omm_img_release_20150723-1-disk1'},
493         {
494             'description': '',
495             'properties': {
496                 'name': u'sss.vmdk',
497                 'checksum': '',
498                 'disk_format': u'VMDK',
499                 'file_url': u'./zte-cn-sss-main-image/NE/sss.vmdk',
500                 'container_type': 'vm',
501                 'version': '',
502                 'hypervisor_type': 'kvm'},
503             'image_file_id': u'sss'}],
504     'vls': [],
505     'cps': [],
506     'metadata': {
507         'vendor': u'zte',
508         'is_shared': False,
509         'description': '',
510         'domain_type': u'CN',
511         'version': u'v4.14.10',
512         'vmnumber_overquota_alarm': False,
513         'cross_dc': False,
514         'vnf_type': u'SSS',
515         'vnfd_version': u'V00000001',
516         'id': u'sss-vnf-template',
517         'name': u'sss-vnf-template'},
518     "flavourId": "flavour_1",
519     "instantiationLevelId": "instantiationLevel_1",
520     "extVirtualLinks": [
521         {
522             "vlInstanceId": "1",
523             "vim": {
524                 "vimInfoId": "1",
525                 "vimId": "1",
526                 "interfaceInfo": {
527                     "vimType": "vim",
528                     "apiVersion": "v2",
529                     "protocolType": "http"
530                 },
531                 "accessInfo": {
532                     "tenant": "tenant_vCPE",
533                     "username": "vCPE",
534                     "password": "vCPE_321"
535                 },
536                 "interfaceEndpoint": "http://10.43.21.105:80/"
537             },
538             "resourceId": "1246",
539             "extCps": [
540                 {
541                     "cpdId": "11",
542                     "addresses": [
543                         {
544                             "addressType": "MAC",
545                             "l2AddressData": "00:f3:43:20:a2:a3"
546                         },
547                         {
548                             "addressType": "IP",
549                             "l3AddressData": {
550                                 "iPAddressType": "IPv4",
551                                 "iPAddress": "192.168.104.2"
552                             }
553                         }
554                     ],
555                     "numDynamicAddresses": 0
556                 }
557             ]
558         }
559     ],
560     "localizationLanguage": "en_US",
561     "additionalParams": {}
562 }
563
564 vnfd_raw_data = {
565     "rawData": {
566         "instance": {
567             "metadata": {
568                 "is_shared": False,
569                 "plugin_info": "vbrasplugin_1.0",
570                 "vendor": "zte",
571                 "request_reclassification": False,
572                 "name": "vbras",
573                 "version": 1,
574                 "vnf_type": "vbras",
575                 "cross_dc": False,
576                 "vnfd_version": "1.0.0",
577                 "id": "zte_vbras_1.0",
578                 "nsh_aware": True
579             },
580             "nodes": [
581                 {
582                     "id": "aaa_dnet_cp_0xu2j5sbigxc8h1ega3if0ld1",
583                     "type_name": "tosca.nodes.nfv.ext.zte.CP",
584                     "template_name": "aaa_dnet_cp",
585                     "properties": {
586                         "bandwidth": {
587                             "type_name": "integer",
588                             "value": 0
589                         },
590                         "direction": {
591                             "type_name": "string",
592                             "value": "bidirectional"
593                         },
594                         "vnic_type": {
595                             "type_name": "string",
596                             "value": "normal"
597                         },
598                         "sfc_encapsulation": {
599                             "type_name": "string",
600                             "value": "mac"
601                         },
602                         "order": {
603                             "type_name": "integer",
604                             "value": 2
605                         }
606                     },
607                     "relationships": [
608                         {
609                             "name": "guest_os",
610                             "source_requirement_index": 0,
611                             "target_node_id": "AAA_image_d8aseebr120nbm7bo1ohkj194",
612                             "target_capability_name": "feature"
613                         }
614                     ]
615                 },
616                 {
617                     "id": "LB_Image_oj5l2ay8l2g6vcq6fsswzduha",
618                     "type_name": "tosca.nodes.nfv.ext.ImageFile",
619                     "template_name": "LB_Image",
620                     "properties": {
621                         "disk_format": {
622                             "type_name": "string",
623                             "value": "qcow2"
624                         },
625                         "file_url": {
626                             "type_name": "string",
627                             "value": "/SoftwareImages/image-lb"
628                         },
629                         "name": {
630                             "type_name": "string",
631                             "value": "image-lb"
632                         }
633                     }
634                 }
635             ]
636         },
637         "model": {
638             "metadata": {
639                 "is_shared": False,
640                 "plugin_info": "vbrasplugin_1.0",
641                 "vendor": "zte",
642                 "request_reclassification": False,
643                 "name": "vbras",
644                 "version": 1,
645                 "vnf_type": "vbras",
646                 "cross_dc": False,
647                 "vnfd_version": "1.0.0",
648                 "id": "zte_vbras_1.0",
649                 "nsh_aware": True
650             },
651             "node_templates": [
652                 {
653                     "name": "aaa_dnet_cp",
654                     "type_name": "tosca.nodes.nfv.ext.zte.CP",
655                     "default_instances": 1,
656                     "min_instances": 0,
657                     "properties": {
658                         "bandwidth": {
659                             "type_name": "integer",
660                             "value": 0
661                         }
662                     },
663                     "requirement_templates": [
664                         {
665                             "name": "virtualbinding",
666                             "target_node_template_name": "AAA",
667                             "target_capability_name": "virtualbinding"
668                         }
669                     ]
670                 }
671             ]
672         }
673     }
674 }