| #! /usr/bin/python |
| import os |
| import zipfile |
| import shutil |
| import yaml |
| import json |
| import logging |
| |
| |
| class CsarParser: |
| def __init__(self): |
| self.logger = logging.getLogger(__name__) |
| self.svc_model = {} |
| self.net_models = [] # there could be multiple networks |
| self.vnf_models = [] # this version only support a single VNF in the service template |
| self.vfmodule_models = [] # this version only support a single VF module in the service template |
| |
| def get_service_yaml_from_csar(self, csar_file): |
| """ |
| :param csar_file: csar file path name, e.g. 'csar/vgmux.csar' |
| :return: |
| """ |
| tmpdir = './__tmp' |
| if os.path.isdir(tmpdir): |
| shutil.rmtree(tmpdir) |
| os.mkdir(tmpdir) |
| |
| with zipfile.ZipFile(csar_file, "r") as zip_ref: |
| zip_ref.extractall(tmpdir) |
| |
| yamldir = tmpdir + '/Definitions' |
| if os.path.isdir(yamldir): |
| for filename in os.listdir(yamldir): |
| # look for service template like this: service-Vcpesvcbrgemu111601-template.yml |
| if filename.startswith('service-') and filename.endswith('-template.yml'): |
| return os.path.join(yamldir, filename) |
| |
| self.logger.error('Invalid file: ' + csar_file) |
| return '' |
| |
| def get_service_model_info(self, svc_template): |
| """ extract service model info from yaml and convert to what to be used in SO request |
| Sample from yaml: |
| { |
| "UUID": "aed4fc5e-b871-4e26-8531-ceabd46df85e", |
| "category": "Network L1-3", |
| "description": "Infra service", |
| "ecompGeneratedNaming": true, |
| "invariantUUID": "c806682a-5b3a-44d8-9e88-0708be151296", |
| "name": "vcpesvcinfra111601", |
| "namingPolicy": "", |
| "serviceEcompNaming": true, |
| "serviceRole": "", |
| "serviceType": "", |
| "type": "Service" |
| }, |
| |
| Convert to |
| { |
| "modelType": "service", |
| "modelInvariantId": "ca4c7a70-06fd-45d8-8b9e-c9745d25bf2b", |
| "modelVersionId": "5d8911b4-e50c-4096-a81e-727a8157193c", |
| "modelName": "vcpesvcbrgemu111601", |
| "modelVersion": "1.0" |
| }, |
| |
| """ |
| if svc_template['metadata']['type'] != 'Service': |
| self.logger.error('csar error: metadata->type is not Service') |
| return |
| |
| metadata = svc_template['metadata'] |
| self.svc_model = { |
| 'modelType': 'service', |
| 'modelInvariantId': metadata['invariantUUID'], |
| 'modelVersionId': metadata['UUID'], |
| 'modelName': metadata['name'] |
| } |
| if 'version' in metadata: |
| self.svc_model['modelVersion'] = metadata['version'] |
| else: |
| self.svc_model['modelVersion'] = '1.0' |
| |
| def get_vnf_and_network_model_info(self, svc_template): |
| """ extract vnf and network model info from yaml and convert to what to be used in SO request |
| Sample from yaml: |
| "topology_template": { |
| "node_templates": { |
| "CPE_PUBLIC": { |
| "metadata": { |
| "UUID": "33b2c367-a165-4bb3-81c3-0150cd06ceff", |
| "category": "Generic", |
| "customizationUUID": "db1d4ac2-62cd-4e5d-b2dc-300dbd1a5da1", |
| "description": "Generic NeutronNet", |
| "invariantUUID": "3d4c0e47-4794-4e98-a794-baaced668930", |
| "name": "Generic NeutronNet", |
| "resourceVendor": "ATT (Tosca)", |
| "resourceVendorModelNumber": "", |
| "resourceVendorRelease": "1.0.0.wd03", |
| "subcategory": "Network Elements", |
| "type": "VL", |
| "version": "1.0" |
| }, |
| "type": "org.openecomp.resource.vl.GenericNeutronNet" |
| }, |
| Convert to |
| { |
| "modelType": "network", |
| "modelInvariantId": "3d4c0e47-4794-4e98-a794-baaced668930", |
| "modelVersionId": "33b2c367-a165-4bb3-81c3-0150cd06ceff", |
| "modelName": "Generic NeutronNet", |
| "modelVersion": "1.0", |
| "modelCustomizationId": "db1d4ac2-62cd-4e5d-b2dc-300dbd1a5da1", |
| "modelCustomizationName": "CPE_PUBLIC" |
| }, |
| """ |
| node_dic = svc_template['topology_template']['node_templates'] |
| for node_name, v in node_dic.items(): |
| model = { |
| 'modelInvariantId': v['metadata']['invariantUUID'], |
| 'modelVersionId': v['metadata']['UUID'], |
| 'modelName': v['metadata']['name'], |
| 'modelVersion': v['metadata']['version'], |
| 'modelCustomizationId': v['metadata']['customizationUUID'], |
| 'modelCustomizationName': node_name |
| } |
| |
| if v['type'].startswith('org.openecomp.resource.vl.GenericNeutronNet'): |
| # a neutron network is found |
| self.logger.info('Parser found a network: ' + node_name) |
| model['modelType'] = 'network' |
| self.net_models.append(model) |
| elif v['type'].startswith('org.openecomp.resource.vf.'): |
| # a VNF is found |
| self.logger.info('Parser found a VNF: ' + node_name) |
| model['modelType'] = 'vnf' |
| self.vnf_models.append(model) |
| else: |
| self.logger.warning('Parser found a node that is neither a network nor a VNF: ' + node_name) |
| |
| def get_vfmodule_model_info(self, svc_template): |
| """ extract network model info from yaml and convert to what to be used in SO request |
| Sample from yaml: |
| "topology_template": { |
| "groups": { |
| "vspinfra1116010..Vspinfra111601..base_vcpe_infra..module-0": { |
| "metadata": { |
| "vfModuleModelCustomizationUUID": "11ddac51-30e3-4a3f-92eb-2eb99c2cb288", |
| "vfModuleModelInvariantUUID": "02f70416-581e-4f00-bde1-d65e69af95c5", |
| "vfModuleModelName": "Vspinfra111601..base_vcpe_infra..module-0", |
| "vfModuleModelUUID": "88c78078-f1fd-4f73-bdd9-10420b0f6353", |
| "vfModuleModelVersion": "1" |
| }, |
| "properties": { |
| "availability_zone_count": null, |
| "initial_count": 1, |
| "max_vf_module_instances": 1, |
| "min_vf_module_instances": 1, |
| "vf_module_description": null, |
| "vf_module_label": "base_vcpe_infra", |
| "vf_module_type": "Base", |
| "vfc_list": null, |
| "volume_group": false |
| }, |
| "type": "org.openecomp.groups.VfModule" |
| } |
| }, |
| Convert to |
| { |
| "modelType": "vfModule", |
| "modelInvariantId": "02f70416-581e-4f00-bde1-d65e69af95c5", |
| "modelVersionId": "88c78078-f1fd-4f73-bdd9-10420b0f6353", |
| "modelName": "Vspinfra111601..base_vcpe_infra..module-0", |
| "modelVersion": "1", |
| "modelCustomizationId": "11ddac51-30e3-4a3f-92eb-2eb99c2cb288", |
| "modelCustomizationName": "Vspinfra111601..base_vcpe_infra..module-0" |
| }, |
| """ |
| node_dic = svc_template['topology_template']['groups'] |
| for node_name, v in node_dic.items(): |
| if v['type'].startswith('org.openecomp.groups.VfModule'): |
| model = { |
| 'modelType': 'vfModule', |
| 'modelInvariantId': v['metadata']['vfModuleModelInvariantUUID'], |
| 'modelVersionId': v['metadata']['vfModuleModelUUID'], |
| 'modelName': v['metadata']['vfModuleModelName'], |
| 'modelVersion': v['metadata']['vfModuleModelVersion'], |
| 'modelCustomizationId': v['metadata']['vfModuleModelCustomizationUUID'], |
| 'modelCustomizationName': v['metadata']['vfModuleModelName'] |
| } |
| self.vfmodule_models.append(model) |
| self.logger.info('Parser found a VF module: ' + model['modelCustomizationName']) |
| |
| def parse_service_yaml(self, filename): |
| # clean up |
| self.svc_model = {} |
| self.net_models = [] # there could be multiple networks |
| self.vnf_models = [] # this version only support a single VNF in the service template |
| self.vfmodule_models = [] # this version only support a single VF module in the service template |
| |
| svc_template = yaml.load(file(filename, 'r')) |
| self.get_service_model_info(svc_template) |
| self.get_vnf_and_network_model_info(svc_template) |
| self.get_vfmodule_model_info(svc_template) |
| |
| return True |
| |
| def parse_csar(self, csar_file): |
| yaml_file = self.get_service_yaml_from_csar(csar_file) |
| if yaml_file != '': |
| return self.parse_service_yaml(yaml_file) |
| |
| def print_models(self): |
| print('---------Service Model----------') |
| print(json.dumps(self.svc_model, indent=2, sort_keys=True)) |
| |
| print('---------Network Model(s)----------') |
| for model in self.net_models: |
| print(json.dumps(model, indent=2, sort_keys=True)) |
| |
| print('---------VNF Model(s)----------') |
| for model in self.vnf_models: |
| print(json.dumps(model, indent=2, sort_keys=True)) |
| |
| print('---------VF Module Model(s)----------') |
| for model in self.vfmodule_models: |
| print(json.dumps(model, indent=2, sort_keys=True)) |
| |
| def test(self): |
| self.parse_csar('csar/service-Vcpesvcinfra111601-csar.csar') |
| self.print_models() |