2 # Copyright 2019 Huawei Technologies Co., Ltd.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 # This script uses the ONAP CLI for providing the end-end service creation and termination.
17 # Used in devops, testing, certification and production
18 # NOTE: This feature is avaialble as ONAP CLI vnf-tosca-lcm
20 # Author: kanagaraj.manickam@huawei.com
35 from argparse import RawTextHelpFormatter
37 if platform.system() == 'Windows':
38 CMD_NAME = 'oclip.cmd'
42 class OcompException(Exception):
43 def __init__(self, code, message):
44 super(OcompException, self).__init__()
46 self.message = message;
50 request_id = os.environ.get('OPEN_CLI_REQUEST_ID'),
53 product = os.environ.get('OPEN_CLI_PRODUCT_IN_USE'),
54 profile = os.environ.get('OPEN_CLI_PROFILE')):
56 request_id = str(uuid.uuid4())
57 self.request_id = request_id
60 self.product = product
61 self.profile = profile
64 return str(vars(self))
71 return os.popen('{} --version'.format(CMD_NAME)).read()
73 def run(self, command, params={}, product=None, profile=None, request_id=None):
77 request_id = self.request_id
80 CMD.append('--request-id')
81 CMD.append(request_id)
84 product = self.product
87 CMD.append('--product')
91 profile = self.profile
94 CMD.append('--profile')
100 CMD.append('--debug')
102 CMD.append('--format')
103 CMD.append(self.format)
105 for name, value in params.items():
106 CMD.append('--{}'.format(name))
109 cmd_string = ' '.join(CMD)
113 res = subprocess.Popen(CMD, stdout=subprocess.PIPE)
115 result = res.stdout.read().strip()
116 print (res.returncode, result)
118 if res.returncode != 0:# and res.returncode != 1:
119 raise OcompException(9999, result)
121 return json.loads(result)
125 sys.stderr.write(str(e))
126 msg = 'failed to executed the command {}'.format(cmd_string)
128 raise OcompException(9999, msg)
137 self.conf = conf or {}
138 self.ocomp = OCOMP(request_id, debug, product=product, profile=profile)
140 self.tag = 'Powered by Open Command Platform - OCOMP'
143 if self.conf['ONAP']:
144 for attr in self.conf['ONAP']:
145 setattr(self, attr, self.conf['ONAP'][attr])
147 self.conf['ONAP'] = {}
149 def create_vlm(self):
152 if not self.vlm_id and not self.vlm_version:
153 output = self.ocomp.run(command='vlm-create',
154 params={'vendor-name': self.conf['vnf']['vendor-name'],
155 'description': self.tag})
157 self.vlm_id = output['id']
158 self.vlm_version = output['version']
161 if not self.entitlement_id:
162 output = self.ocomp.run(command='vlm-entitlement-pool-create',
163 params={'name': '{} Entitlement Pool'.format(self.conf['vnf']['vendor-name']),
164 'vlm-id': self.vlm_id,
165 'vlm-version': self.vlm_version,
166 'manufacture-reference-number': 'OCOMP',
167 'start-date': datetime.datetime.strftime(datetime.datetime.today(),'%m/%d/%Y'),
168 'expiry-date': datetime.datetime.strftime(datetime.datetime.today() + datetime.timedelta(1),'%m/%d/%Y')})
169 self.entitlement_id = output['id']
172 if not self.key_group_id:
173 output = self.ocomp.run(command='vlm-key-group-create',
174 params={'name': '{} Key goroup'.format(self.conf['vnf']['vendor-name']),
175 'vlm-id': self.vlm_id,
176 'vlm-version': self.vlm_version,
177 'type': 'Universal'})
179 self.key_group_id = output['id']
182 if not self.feature_group_id:
183 output = self.ocomp.run(command='vlm-feature-group-create',
184 params={'name': '{} Feature group'.format(self.conf['vnf']['vendor-name']),
185 'vlm-id': self.vlm_id,
186 'vlm-version': self.vlm_version,
187 'vlm-key-group-id': self.key_group_id,
188 'vlm-entitle-pool-id': self.entitlement_id,
189 'part-number': '100000'})
191 self.feature_group_id = output['id']
194 if not self.agreement_id:
195 output = self.ocomp.run(command='vlm-aggreement-create',
196 params={'name': '{} Agreement'.format(self.conf['vnf']['vendor-name']),
197 'vlm-id': self.vlm_id,
198 'vlm-version': self.vlm_version,
199 'vlm-feature-group-id': self.feature_group_id})
201 self.agreement_id = output['id']
205 self.ocomp.run(command='vlm-submit',
206 params={'vlm-id': self.vlm_id,
207 'vlm-version': self.vlm_version})
209 def create_vsp(self):
210 if not self.vsp_id and not self.vsp_version and not self.vsp_version_id:
211 output = self.ocomp.run(command='vsp-create',
212 params={'vlm-id': self.vlm_id,
213 'vlm-version': self.vlm_version,
214 'vlm-vendor': self.conf['vnf']['vendor-name'],
215 'vsp-name': self.conf['vnf']['name'],
216 'vsp-description': self.tag,
217 'vlm-agreement-id': self.agreement_id,
218 'vlm-feature-group-id': self.feature_group_id})
219 self.vsp_id = output['id']
220 self.vsp_version_id = output['version-id']
221 self.vsp_version = output['version']
223 self.ocomp.run(command='vsp-add-artifact',
224 params={'vsp-id': self.vsp_id,
225 'vsp-version': self.vsp_version_id,
226 'vsp-file': self.conf['vnf']['vsp-csar']})
228 output = self.ocomp.run(command='vsp-validate',
229 params={'vsp-id': self.vsp_id,
230 'vsp-version': self.vsp_version_id})
231 if not output['status'] == "Success":
232 raise Exception("Invalid VSP package, please check it compliance using VTP")
234 self.ocomp.run(command='vsp-commit',
235 params={'vsp-id': self.vsp_id,
236 'vsp-version': self.vsp_version_id,
237 'remarks': self.tag})
239 self.ocomp.run(command='vsp-submit',
240 params={'vsp-id': self.vsp_id,
241 'vsp-version': self.vsp_version_id})
243 self.ocomp.run(command='vsp-package',
244 params={'vsp-id': self.vsp_id,
245 'vsp-version': self.vsp_version_id})
247 def create_vf_model(self):
248 if not self.vf_id and not self.vf_version:
249 output = self.ocomp.run(command='vf-model-create',
250 params={'name': '{} Vnf'.format(self.conf['vnf']['name']),
251 'vendor-name': self.conf['vnf']['vendor-name'],
252 'vsp-id': self.vsp_id,
253 'vsp-version': self.vsp_version, # TODO: SDC fails to add VSP, check it
254 'description': self.tag})
257 inputs = output['inputs'].replace('[', '').replace(']', '').split(',')
259 self.ocomp.run(command='vf-model-add-artifact',
260 params={'vf-id': vf_id,
262 'artifact': self.conf['vnf']['vnf-csar'],
263 'artifact-name': 'vnf.csar'})
265 output = self.ocomp.run(command='vf-model-certify',
266 params={'vf-id': vf_id,
267 'remarks': self.tag})
268 self.vf_id = output['id']
269 self.vf_version = output['version']
270 self.vf_uuid = output['uuid']
271 self.vf_inputs = inputs
273 def create_service_model(self):
274 if not self.ns_id and not self.ns_version:
275 output = self.ocomp.run(command='service-model-create',
276 params={'service-name': '{} Service'.format(self.conf['vnf']['name']),
277 'description': self.tag,
278 'project-code': 'OCOMP',
279 'category': 'network l1-3',
280 'category-display-name': 'Network L1-3',
281 'icon-id': 'network_l_1-3'})
284 if not self.ns_vf_resource_id:
285 output = self.ocomp.run(command='service-model-add-vf',
286 params={'service-id': ns_id,
288 'vf-version': self.vf_version,
289 'vf-name': self.conf['vnf']['name']})
290 self.ns_vf_resource_id = output['id']
293 self.ocomp.run(command='service-model-add-artifact',
294 params={'service-id': ns_id,
296 'artifact': self.conf['vnf']['ns-csar'],
297 'artifact-group-type': 'DEPLOYMENT',
298 'artifact-name': 'ns.csar'})
299 #set property vnfmdriver
300 for input in self.vf_inputs:
301 if input.endswith('.nf_type'):
302 tkns = input.strip().split('.')
304 self.ocomp.run(command='service-model-set-property',
305 params={'service-id': ns_id,
307 'vf-resource-id': self.ns_vf_resource_id,
308 'property-name': 'nf_type',
309 'property-value': self.conf['vnf']['vnfm-driver'],
310 'input-uuid': input_uuid})
313 self.ocomp.run(command='service-model-test-request',
314 params={'service-id': ns_id,
315 'remarks': self.tag})
317 self.ocomp.run(command='service-model-test-start',
318 params={'service-id': ns_id})
320 output = self.ocomp.run(command='service-model-test-accept',
321 params={'service-id': ns_id,
322 'remarks': self.tag})
323 self.ns_id = output['id']
324 self.ns_version = output['version']
325 self.ns_uuid = output['uuid']
327 self.ocomp.run(command='service-model-approve',
328 params={'service-id': self.ns_id,
329 'remarks': self.tag})
331 self.ocomp.run(command='service-model-distribute',
332 params={'service-id': self.ns_id})
334 def setup_cloud_and_subscription(self):
336 if not self.location_id and not self.location_version:
337 location_id = 'ocomp-region-{}'.format(self.conf['ONAP']['uid'])
338 self.ocomp.run(command='complex-create',
339 params={'physical-location-id': location_id,
340 'data-center-code': 'ocomp',
341 'complex-name': location_id,
342 'identity-url': self.conf['cloud']['identity-url'],
343 'physical-location-type': 'phy_type',
344 'street1': 'ocomp-street1',
345 'street2': 'ocomp-street2',
346 'city': 'ocomp-city',
347 'state': 'ocomp-state',
348 'postal-code': '001481',
353 'elevation': 'ocomp-elelation',
354 'lata': 'ocomp-lata'})
355 self.location_id = location_id
358 output = self.ocomp.run(command='complex-list')
360 for location in output:
361 if location['complex-name'] == self.location_id:
362 self.location_version = location['resource-version']
365 if not self.cloud_id and not self.cloud_version:
366 cloud_id = 'OCOMP-{}'.format(self.conf['ONAP']['uid'])
367 self.ocomp.run(command='cloud-create',
368 params={'region-name': self.conf['cloud']['region'],
369 'complex-name': self.location_id,
370 'identity-url': self.conf['cloud']['identity-url'],
371 'cloud-owner': cloud_id,
372 'cloud-type': 'openstack',
373 'owner-type': 'ocomp',
374 'cloud-region-version': self.conf['cloud']['version'],
377 'service-url': self.conf['cloud']['identity-url'],
378 'username': self.conf['cloud']['username'],
379 'password': self.conf['cloud']['password'],
380 'system-type': 'VIM',
381 'ssl-insecure': 'true',
382 'cloud-domain': 'Default',
383 'default-tenant': self.conf['cloud']['tenant'],
384 'system-status': "active"})
385 self.cloud_id = cloud_id
388 output = self.ocomp.run(command='cloud-list')
391 if cloud['cloud'] == self.cloud_id:
392 self.cloud_version = cloud['resource-version']
396 self.ocomp.run(command='complex-associate',
397 params={'complex-name': self.location_id,
398 'cloud-region': self.conf['cloud']['region'],
399 'cloud-owner': self.cloud_id})
401 self.ocomp.run(command='multicloud-register-cloud',
402 params={'cloud-region': self.conf['cloud']['region'], 'cloud-owner': self.cloud_id})
405 if not self.service_type_id and not self.service_type_version:
406 service_type_id = '{}-{}'.format(self.conf['subscription']['service-type'], self.conf['ONAP']['uid'])
407 self.ocomp.run(command='service-type-create',
408 params={'service-type': service_type_id,
409 'service-type-id': service_type_id})
410 self.service_type_id = service_type_id
413 output = self.ocomp.run(command='service-type-list')
416 if st['service-type'] == self.service_type_id:
417 self.service_type_version = st['resource-version']
420 if not self.customer_id and not self.customer_version:
421 customer_id = '{}-{}'.format(self.conf['subscription']['customer-name'], self.conf['ONAP']['uid'])
422 self.ocomp.run(command='customer-create',
423 params={'customer-name': customer_id,
424 'subscriber-name': customer_id})
425 self.customer_id = customer_id
428 output = self.ocomp.run(command='customer-list')
430 for customer in output:
431 if customer['name'] == self.customer_id:
432 self.customer_version = customer['resource-version']
435 if not self.tenant_id and not self.tenant_version:
436 output = self.ocomp.run(command='tenant-list', params={
437 'cloud': self.cloud_id,
438 'region': self.conf['cloud']['region']
441 for tenant in output:
442 if tenant['tenant-name'] == self.conf['cloud']['tenant']:
443 self.tenant_id = tenant['tenant-id']
444 self.tenant_version = tenant['resource-version']
449 self.ocomp.run(command='subscription-create',
450 params={'customer-name': self.customer_id,
451 'cloud-owner': self.cloud_id,
452 'cloud-region': self.conf['cloud']['region'],
453 'cloud-tenant-id': self.tenant_id,
454 'service-type': self.service_type_id,
455 'tenant-name': self.conf['cloud']['tenant']})
457 if not self.subscription_version:
458 output = self.ocomp.run(command='subscription-list', params={
459 'customer-name': self.customer_id
462 for subscription in output:
463 if subscription['service-type'] == self.service_type_id:
464 self.subscription_version = subscription['resource-version']
467 if not self.esr_vnfm_id and not self.esr_vnfm_version:
468 vnfmdriver = self.conf['vnf']['vnfm-driver']
470 esr_vnfm_id = str(uuid.uuid4())
471 self.ocomp.run(command='vnfm-create',
472 params={'vim-id': self.cloud_id + "_" + self.conf['cloud']['region'],
473 'vnfm-id': esr_vnfm_id,
474 'name': 'OCOMP {}'.format(vnfmdriver),
476 'vendor': self.conf['vnf']['vendor-name'],
477 'vnfm-version': self.conf['vnfm'][vnfmdriver]['version'],
478 'url': self.conf['vnfm'][vnfmdriver]['url'],
479 'username': self.conf['vnfm'][vnfmdriver]['username'] ,
480 'password': self.conf['vnfm'][vnfmdriver]['password']})
481 self.esr_vnfm_id = esr_vnfm_id
483 output = self.ocomp.run(command='vnfm-list')
486 if vnfm['vnfm-id'] == self.esr_vnfm_id:
487 self.esr_vnfm_version = vnfm['resource-version']
490 # self.ocomp.run(command='multicloud-register-cloud',
491 # params={'cloud-region': self.conf['cloud']['region'],
492 # 'cloud-owner': self.cloud_id})
494 def create_vnf(self):
495 self.ocomp.run(command='vfc-catalog-onboard-vnf',
496 params={'vnf-csar-uuid': self.vf_uuid})
500 output = self.ocomp.run(command='vfc-catalog-get-vnf')
502 if csar.get("csar-id") == self.vf_uuid:
510 self.ocomp.run(command='vfc-catalog-onboard-ns',
511 params={'ns-csar-uuid': self.ns_uuid})
513 output = self.ocomp.run(command='vfc-nslcm-create',
514 params={'ns-csar-uuid': self.ns_uuid,
515 'ns-csar-name': '{} Service'.format(self.conf['vnf']['name']),
516 'customer-name': self.customer_id,
517 'service-type': self.service_type_id})
519 self.ns_instance_id = output['ns-instance-id']
521 output = self.ocomp.run(command='vfc-nslcm-instantiate',
522 params={'ns-instance-id': self.ns_instance_id,
523 'location': self.cloud_id + "_" + self.conf['cloud']['region'],
524 'sdn-controller-id': self.esr_vnfm_id})
526 jobid = output['job-id']
527 self.waitProcessFinished(jobid)
529 def vnf_status_check(self):
530 self.vnf_status = 'active'
531 self.ns_instance_status = 'active'
533 def waitProcessFinished(self, job_id):
535 output = self.ocomp.run(command='vfc-nslcm-get-jobid',
536 params={'ns-job-id': job_id})
537 progress_rep = int(output["job-progress"])
538 if 100 != progress_rep:
539 if 255 == progress_rep:
546 if self.ns_instance_id:
547 output = self.ocomp.run(command='vfc-nslcm-terminate',
548 params={'ns-instance-id': self.ns_instance_id})
549 jobid = output['job-id']
550 self.waitProcessFinished(jobid)
551 self.ocomp.run(command='vfc-nslcm-delete',
552 params={'ns-instance-id': self.ns_instance_id})
553 self.ns_instance_id = None
556 self.ocomp.run(command='service-model-archive',
557 params={'service-id': self.ns_id})
558 self.ns_id = self.ns_uuid = self.ns_version = self.ns_vf_resource_id = None
561 self.ocomp.run(command='vf-model-archive',
562 params={'vf-id': self.vf_id})
563 self.vf_id = self.vf_uuid = self.vf_inputs = self.vf_version = None
566 self.ocomp.run(command='vsp-archive',
567 params={'vsp-id': self.vsp_id})
568 self.vsp_id = self.vsp_version_id = self.vsp_version = None
571 self.ocomp.run(command='vlm-archive',
572 params={'vlm-id': self.vlm_id})
573 self.vlm_id = self.vlm_version = self.entitlement_id = self.key_group_id = self.feature_group_id = self.agreement_id = None
575 if self.subscription_version and self.customer_id and self.service_type_id:
576 self.ocomp.run(command='subscription-delete',
577 params={'customer-name': self.customer_id,
578 'service-type': self.service_type_id,
579 'resource-version': self.subscription_version})
580 self.subscription_version = None
582 if self.customer_id and self.customer_version:
583 self.ocomp.run(command='customer-delete',
584 params={'customer-id': self.customer_id,
585 'resource-version': self.customer_version})
586 self.customer_id = self.customer_version = None
588 if self.service_type_id and self.service_type_version:
589 output = self.ocomp.run(command='service-type-list')
592 if st['service-type-id'] == self.service_type_id:
593 self.service_type_version = st['resource-version']
596 self.ocomp.run(command='service-type-delete',
597 params={'service-type-id': self.service_type_id,
598 'resource-version': self.service_type_version})
599 self.service_type_id = self.service_type_version = None
601 if self.tenant_id and self.tenant_version:
602 self.ocomp.run(command='tenant-delete',
603 params={'cloud': self.cloud_id,
604 'region': self.conf['cloud']['region'],
605 'tenant-id': self.tenant_id,
606 'resource-version': self.tenant_version})
607 self.tenant_id = self.tenant_version = None
610 self.ocomp.run(command='multicloud-cloud-delete',
611 params={'cloud-owner': self.cloud_id,
612 'cloud-region': self.conf['cloud']['region']})
616 output = self.ocomp.run(command='cloud-list')
618 if cloud.get('cloud') == self.cloud_id:
626 self.cloud_id = self.cloud_version = None
628 if self.location_id and self.location_version:
629 self.ocomp.run(command='complex-delete',
630 params={'complex-name': self.location_id,
631 'resource-version': self.location_version})
632 self.location_id = self.location_version = None
634 if self.esr_vnfm_id and self.esr_vnfm_version:
635 self.ocomp.run(command='vnfm-delete',
636 params={'vnfm-id': self.esr_vnfm_id,
637 'resource-version': self.esr_vnfm_version})
638 self.esr_vnfm_id = self.esr_vnfm_version = None
641 return str(vars(self))
644 if __name__ == '__main__':
645 parser = argparse.ArgumentParser(description="ONAP TOSCA VNF validation using ONAP CLI and Open Command Platform (OCOMP)", formatter_class=RawTextHelpFormatter)
646 parser.add_argument('--product', action='store', dest='product', help='OCOMP product to use, default to onap-dublin',
647 default=os.environ.get('OPEN_CLI_PRODUCT_IN_USE'))
648 parser.add_argument('--profile', action='store', dest='profile', help='OCOMP profile to use, default to onap-dublin',
649 default=os.environ.get('OPEN_CLI_PROFILE'))
650 parser.add_argument('--request-id', action='store', dest='request_id',
651 help='Request Id to track the progress of running this script',
652 default=os.environ.get('OPEN_CLI_REQUEST_ID'))
653 parser.add_argument('--conf', action='store', dest='config_file_path', help='Configuration file path')
654 parser.add_argument('--vsp', action='store', dest='vsp', help='ONAP VSP file path')
655 parser.add_argument('--vnf-csar', action='store', dest='vnf_csar', help='TOSCA VNF CSAR file path')
656 parser.add_argument('--ns-csar', action='store', dest='ns_csar', help='TOSCA VNF CSAR file path')
657 parser.add_argument('--vnfm-driver', action='store', dest='vnfm_driver', help='VNFM dirver type one of gvnfmdriver or hwvnfmdriver',
658 choices=('gvnfmdriver', 'hwvnfmdriver'))
659 parser.add_argument('--vnf-name', action='store', dest='vnf_name', help='VNF Name')
660 parser.add_argument('--vendor-name', action='store', dest='vendor_name', help='VNF Vendor name')
661 parser.add_argument('--result-json', action='store', dest='result', help='Result json file. ' \
662 '\nInstead of creating new ONAP objects while running this script \nand to use the existing ONAP object Ids, '\
663 'use this \nresult json parameter. Object Id names are provided in configuration \nfile under ONAP section')
664 parser.add_argument('--mode', action='store', dest='mode', help='Supports 5 mode.'\
665 '\nsetup - Create the required VLM, service type, cloud, customer and \nsubscription as given in conf file' \
666 '\nstandup - Create the VSP, VF Model, Service Model and provision\n the service using VFC'\
667 '\ncleanup - Remove the ONAP objects which are either created during \nsetup and standup phase or provided by the user in result-json file ' \
668 '\nCAUTION: If required, do not provide the existing ONAP object ids \nin result-json while doing the cleanup, to avoid them getting deleted.'\
669 '\ncheckup - Check the deployment weather OCOMP is working properly or not' \
670 '\nprovision - Run thru setup -> standup' \
671 '\nvalidate - run thru setup -> standup -> cleanup modes for end to end vnf validation',
672 choices=('setup', 'standup', 'cleanup', 'checkup', 'provision', 'validate'))
674 args = parser.parse_args()
678 product = 'onap-dublin'
680 product = args.product
683 profile = 'onap-dublin'
685 profile = args.profile
687 request_id = args.request_id
689 request_id = str(uuid.uuid4())
691 vnf_csar = args.vnf_csar
692 ns_csar = args.ns_csar
699 vnfm_driver = args.vnfm_driver
701 vnfm_driver = 'gvnfmdriver'
704 vnf_name = args.vnf_name
709 vendor_name = args.vendor_name
714 config_file = args.config_file_path
715 with open(config_file) as json_file:
716 conf = json.load(json_file)
717 if not 'uid' in conf['ONAP']:
718 conf['ONAP']['uid'] = ''.join(random.sample(string.ascii_lowercase,5))
720 conf['vnf']['vsp-csar'] = vsp_csar
722 conf['vnf']['vnf-csar'] = vnf_csar
724 conf['vnf']['ns-csar'] = ns_csar
726 conf['vnf']['name'] = vnf_name
727 conf['vnf']['name'] = '{}{}'.format(conf['vnf']['name'], conf['ONAP']['uid'])
729 conf['vnf']['vendor-name'] = vendor_name
730 conf['vnf']['vendor-name'] = '{}-{}'.format(conf['vnf']['vendor-name'], conf['ONAP']['uid'])
732 conf['vnf']['vnfm-driver'] = vnfm_driver
735 result_file = args.result
736 with open(result_file) as r_file:
737 result_json = json.load(r_file)
738 for r in result_json:
739 if r in conf['ONAP']:
740 conf['ONAP'][r] = result_json[r]
744 print (OCOMP.version())
746 onap = ONAP(product, profile, conf, request_id)
750 onap.setup_cloud_and_subscription()
754 onap.create_vf_model()
755 onap.create_service_model()
757 onap.vnf_status_check()
765 elif mode == 'standup':
767 elif mode == 'cleanup':
769 elif mode == 'checkup':
770 onap.ocomp.product = 'open-cli'
771 onap.ocomp.run(command='schema-list', params={'product': 'open-cli'})
772 elif mode == 'provision':
775 elif mode == 'validate':
782 onap_result = json.dumps(onap, default=lambda x: x.__dict__)
786 #Remove conf and ocomp from the onap object
787 for attr in ['ocomp', 'tag', 'conf']:
790 with open(result_file, "w") as f:
791 f.write(json.dumps(onap, default=lambda x: x.__dict__))