Fix Python linting issues in Python scripts
[integration.git] / test / vcpe / csar_parser.py
1 #!/usr/bin/env python
2
3 import os
4 import zipfile
5 import shutil
6 import yaml
7 import json
8 import logging
9
10
11 class 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(): # pylint: disable=W0612
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')) # pylint: disable=E0602
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()