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