blob: f101364d5cc62858ddba4aa5fc85bdde2f811256 [file] [log] [blame]
Kang Xi11d278c2018-04-06 16:56:04 -04001#! /usr/bin/python
2import os
3import zipfile
4import shutil
5import yaml
6import json
7import logging
8
9
10class CsarParser:
11 def __init__(self):
12 self.logger = logging.getLogger(__name__)
13 self.svc_model = {}
14 self.net_models = [] # there could be multiple networks
15 self.vnf_models = [] # this version only support a single VNF in the service template
16 self.vfmodule_models = [] # this version only support a single VF module in the service template
17
18 def get_service_yaml_from_csar(self, csar_file):
19 """
20 :param csar_file: csar file path name, e.g. 'csar/vgmux.csar'
21 :return:
22 """
23 tmpdir = './__tmp'
24 if os.path.isdir(tmpdir):
25 shutil.rmtree(tmpdir)
26 os.mkdir(tmpdir)
27
28 with zipfile.ZipFile(csar_file, "r") as zip_ref:
29 zip_ref.extractall(tmpdir)
30
31 yamldir = tmpdir + '/Definitions'
32 if os.path.isdir(yamldir):
33 for filename in os.listdir(yamldir):
34 # look for service template like this: service-Vcpesvcbrgemu111601-template.yml
35 if filename.startswith('service-') and filename.endswith('-template.yml'):
36 return os.path.join(yamldir, filename)
37
38 self.logger.error('Invalid file: ' + csar_file)
39 return ''
40
41 def get_service_model_info(self, svc_template):
42 """ extract service model info from yaml and convert to what to be used in SO request
43 Sample from yaml:
44 {
45 "UUID": "aed4fc5e-b871-4e26-8531-ceabd46df85e",
46 "category": "Network L1-3",
47 "description": "Infra service",
48 "ecompGeneratedNaming": true,
49 "invariantUUID": "c806682a-5b3a-44d8-9e88-0708be151296",
50 "name": "vcpesvcinfra111601",
51 "namingPolicy": "",
52 "serviceEcompNaming": true,
53 "serviceRole": "",
54 "serviceType": "",
55 "type": "Service"
56 },
57
58 Convert to
59 {
60 "modelType": "service",
61 "modelInvariantId": "ca4c7a70-06fd-45d8-8b9e-c9745d25bf2b",
62 "modelVersionId": "5d8911b4-e50c-4096-a81e-727a8157193c",
63 "modelName": "vcpesvcbrgemu111601",
64 "modelVersion": "1.0"
65 },
66
67 """
68 if svc_template['metadata']['type'] != 'Service':
69 self.logger.error('csar error: metadata->type is not Service')
70 return
71
72 metadata = svc_template['metadata']
73 self.svc_model = {
74 'modelType': 'service',
75 'modelInvariantId': metadata['invariantUUID'],
76 'modelVersionId': metadata['UUID'],
77 'modelName': metadata['name']
78 }
79 if 'version' in metadata:
80 self.svc_model['modelVersion'] = metadata['version']
81 else:
82 self.svc_model['modelVersion'] = '1.0'
83
84 def get_vnf_and_network_model_info(self, svc_template):
85 """ extract vnf and network model info from yaml and convert to what to be used in SO request
86 Sample from yaml:
87 "topology_template": {
88 "node_templates": {
89 "CPE_PUBLIC": {
90 "metadata": {
91 "UUID": "33b2c367-a165-4bb3-81c3-0150cd06ceff",
92 "category": "Generic",
93 "customizationUUID": "db1d4ac2-62cd-4e5d-b2dc-300dbd1a5da1",
94 "description": "Generic NeutronNet",
95 "invariantUUID": "3d4c0e47-4794-4e98-a794-baaced668930",
96 "name": "Generic NeutronNet",
97 "resourceVendor": "ATT (Tosca)",
98 "resourceVendorModelNumber": "",
99 "resourceVendorRelease": "1.0.0.wd03",
100 "subcategory": "Network Elements",
101 "type": "VL",
102 "version": "1.0"
103 },
104 "type": "org.openecomp.resource.vl.GenericNeutronNet"
105 },
106 Convert to
107 {
108 "modelType": "network",
109 "modelInvariantId": "3d4c0e47-4794-4e98-a794-baaced668930",
110 "modelVersionId": "33b2c367-a165-4bb3-81c3-0150cd06ceff",
111 "modelName": "Generic NeutronNet",
112 "modelVersion": "1.0",
113 "modelCustomizationId": "db1d4ac2-62cd-4e5d-b2dc-300dbd1a5da1",
114 "modelCustomizationName": "CPE_PUBLIC"
115 },
116 """
117 node_dic = svc_template['topology_template']['node_templates']
118 for node_name, v in node_dic.items():
119 model = {
120 'modelInvariantId': v['metadata']['invariantUUID'],
121 'modelVersionId': v['metadata']['UUID'],
122 'modelName': v['metadata']['name'],
123 'modelVersion': v['metadata']['version'],
124 'modelCustomizationId': v['metadata']['customizationUUID'],
125 'modelCustomizationName': node_name
126 }
127
128 if v['type'].startswith('org.openecomp.resource.vl.GenericNeutronNet'):
129 # a neutron network is found
130 self.logger.info('Parser found a network: ' + node_name)
131 model['modelType'] = 'network'
132 self.net_models.append(model)
133 elif v['type'].startswith('org.openecomp.resource.vf.'):
134 # a VNF is found
135 self.logger.info('Parser found a VNF: ' + node_name)
136 model['modelType'] = 'vnf'
137 self.vnf_models.append(model)
138 else:
139 self.logger.warning('Parser found a node that is neither a network nor a VNF: ' + node_name)
140
141 def get_vfmodule_model_info(self, svc_template):
142 """ extract network model info from yaml and convert to what to be used in SO request
143 Sample from yaml:
144 "topology_template": {
145 "groups": {
146 "vspinfra1116010..Vspinfra111601..base_vcpe_infra..module-0": {
147 "metadata": {
148 "vfModuleModelCustomizationUUID": "11ddac51-30e3-4a3f-92eb-2eb99c2cb288",
149 "vfModuleModelInvariantUUID": "02f70416-581e-4f00-bde1-d65e69af95c5",
150 "vfModuleModelName": "Vspinfra111601..base_vcpe_infra..module-0",
151 "vfModuleModelUUID": "88c78078-f1fd-4f73-bdd9-10420b0f6353",
152 "vfModuleModelVersion": "1"
153 },
154 "properties": {
155 "availability_zone_count": null,
156 "initial_count": 1,
157 "max_vf_module_instances": 1,
158 "min_vf_module_instances": 1,
159 "vf_module_description": null,
160 "vf_module_label": "base_vcpe_infra",
161 "vf_module_type": "Base",
162 "vfc_list": null,
163 "volume_group": false
164 },
165 "type": "org.openecomp.groups.VfModule"
166 }
167 },
168 Convert to
169 {
170 "modelType": "vfModule",
171 "modelInvariantId": "02f70416-581e-4f00-bde1-d65e69af95c5",
172 "modelVersionId": "88c78078-f1fd-4f73-bdd9-10420b0f6353",
173 "modelName": "Vspinfra111601..base_vcpe_infra..module-0",
174 "modelVersion": "1",
175 "modelCustomizationId": "11ddac51-30e3-4a3f-92eb-2eb99c2cb288",
176 "modelCustomizationName": "Vspinfra111601..base_vcpe_infra..module-0"
177 },
178 """
179 node_dic = svc_template['topology_template']['groups']
180 for node_name, v in node_dic.items():
181 if v['type'].startswith('org.openecomp.groups.VfModule'):
182 model = {
183 'modelType': 'vfModule',
184 'modelInvariantId': v['metadata']['vfModuleModelInvariantUUID'],
185 'modelVersionId': v['metadata']['vfModuleModelUUID'],
186 'modelName': v['metadata']['vfModuleModelName'],
187 'modelVersion': v['metadata']['vfModuleModelVersion'],
188 'modelCustomizationId': v['metadata']['vfModuleModelCustomizationUUID'],
189 'modelCustomizationName': v['metadata']['vfModuleModelName']
190 }
191 self.vfmodule_models.append(model)
192 self.logger.info('Parser found a VF module: ' + model['modelCustomizationName'])
193
194 def parse_service_yaml(self, filename):
195 # clean up
196 self.svc_model = {}
197 self.net_models = [] # there could be multiple networks
198 self.vnf_models = [] # this version only support a single VNF in the service template
199 self.vfmodule_models = [] # this version only support a single VF module in the service template
200
201 svc_template = yaml.load(file(filename, 'r'))
202 self.get_service_model_info(svc_template)
203 self.get_vnf_and_network_model_info(svc_template)
204 self.get_vfmodule_model_info(svc_template)
205
206 return True
207
208 def parse_csar(self, csar_file):
209 yaml_file = self.get_service_yaml_from_csar(csar_file)
210 if yaml_file != '':
211 return self.parse_service_yaml(yaml_file)
212
213 def print_models(self):
214 print('---------Service Model----------')
215 print(json.dumps(self.svc_model, indent=2, sort_keys=True))
216
217 print('---------Network Model(s)----------')
218 for model in self.net_models:
219 print(json.dumps(model, indent=2, sort_keys=True))
220
221 print('---------VNF Model(s)----------')
222 for model in self.vnf_models:
223 print(json.dumps(model, indent=2, sort_keys=True))
224
225 print('---------VF Module Model(s)----------')
226 for model in self.vfmodule_models:
227 print(json.dumps(model, indent=2, sort_keys=True))
228
229 def test(self):
230 self.parse_csar('csar/service-Vcpesvcinfra111601-csar.csar')
231 self.print_models()