521bf583d4699d47d3dc7082923ebea386bd4757
[vfc/nfvo/lcm.git] / lcm / pub / utils / scaleaspect.py
1 # Copyright 2017 ZTE Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 import json
16 import logging
17 import os
18 import copy
19 from lcm.pub.database.models import NfInstModel
20 from lcm.pub.database.models import NSInstModel
21 from lcm.ns.vnfs.const import VNF_STATUS
22 from lcm.pub.msapi import catalog
23
24
25 logger = logging.getLogger(__name__)
26 SCALE_TYPE = ("SCALE_NS", "SCALE_VNF")
27
28 scale_vnf_data_mapping = {
29     "vnfInstanceId": "",
30     "scaleByStepData": [
31         {
32             "type": "",
33             "aspectId": "",
34             "numberOfSteps": ""
35         }
36     ]
37 }
38
39
40 def ignorcase_get(args, key):
41     if not key:
42         return ""
43     if not args:
44         return ""
45     if key in args:
46         return args[key]
47     for old_key in args:
48         if old_key.upper() == key.upper():
49             return args[old_key]
50     return ""
51
52
53 def mapping_conv(keyword_map, rest_return):
54     resp_data = {}
55     for param in keyword_map:
56         if keyword_map[param]:
57             if isinstance(keyword_map[param], dict):
58                 resp_data[param] = mapping_conv(
59                     keyword_map[param], ignorcase_get(
60                         rest_return, param))
61             else:
62                 resp_data[param] = ignorcase_get(rest_return, param)
63     return resp_data
64
65
66 def get_vnf_scale_info(filename, ns_instanceId, aspect, step):
67     json_data = get_json_data(filename)
68     scale_options = ignorcase_get(json_data, "scale_options")
69     for i in range(scale_options.__len__()):
70         ns_scale_option = scale_options[i]
71         if (ignorcase_get(ns_scale_option, "ns_instanceId") == ns_instanceId) \
72                 and (ignorcase_get(ns_scale_option, "ns_scale_aspect") == aspect):
73             ns_scale_info_list = ignorcase_get(
74                 ns_scale_option, "ns_scale_info_list")
75             for j in range(ns_scale_info_list.__len__()):
76                 ns_scale_info = ns_scale_info_list[j]
77                 if ns_scale_info["step"] == step:
78                     return ns_scale_info["vnf_scale_info"]
79
80     return None
81
82
83 # Get the vnf scaling info according to the ns package id.
84 def get_vnf_scale_info_package(scalingmap_json, nsd_id, aspect, step):
85     scale_options = ignorcase_get(scalingmap_json, "scale_options")
86     for i in range(scale_options.__len__()):
87         ns_scale_option = scale_options[i]
88         if (ignorcase_get(ns_scale_option, "nsd_id") == nsd_id) and (
89                 ignorcase_get(ns_scale_option, "ns_scale_aspect") == aspect):
90             ns_scale_info_list = ignorcase_get(
91                 ns_scale_option, "ns_scale_info")
92             for j in range(ns_scale_info_list.__len__()):
93                 ns_scale_info = ns_scale_info_list[j]
94                 if ns_scale_info["step"] == step:
95                     vnf_scale_info_list = ns_scale_info["vnf_scale_info"]
96
97                     return vnf_scale_info_list
98
99     return None
100
101
102 # Gets the vnf instance id according to the vnfd_id and modify the list of
103 # scaling vnf info accrodingly.
104 def deal_vnf_scale_info(vnf_scale_info_list):
105     result = list()
106     for i in range(vnf_scale_info_list.__len__()):
107         vnf_scale_info = vnf_scale_info_list[i]
108         vnfd_id = vnf_scale_info["vnfd_id"]
109         vnf_instance_id_list = get_vnf_instance_id_list(vnfd_id)
110         copy_vnf_scale_info = copy.deepcopy(vnf_scale_info)
111         copy_vnf_scale_info.pop("vnfd_id")
112         index = 0
113         while index < vnf_instance_id_list.__len__():
114             copy_vnf_scale_info["vnfInstanceId"] = vnf_instance_id_list[index]
115             index += 1
116             result.append(copy_vnf_scale_info)
117
118     return result
119
120
121 def get_vnf_instance_id_list(vnfd_id):
122     kwargs = {}
123     kwargs['package_id'] = vnfd_id
124     kwargs['status'] = VNF_STATUS.ACTIVE
125
126     nf_model_list = NfInstModel.objects.filter(**kwargs)
127     vnf_instance_id_list = list()
128     for i in range(nf_model_list.__len__()):
129         vnf_instance_id_list.append(nf_model_list[i].nfinstid)
130
131     return vnf_instance_id_list
132
133
134 def get_json_data(filename):
135     f = open(filename)
136     json_str = f.read()
137     data = json.JSONDecoder().decode(json_str)
138     f.close()
139     return data
140
141
142 def check_scale_list(vnf_scale_list, ns_instanceId, aspect, step):
143     if vnf_scale_list is None:
144         logger.debug(
145             "The scaling option[ns=%s, aspect=%s, step=%s] does not exist. Pls check the config file." %
146             (ns_instanceId, aspect, step))
147         raise Exception(
148             "The scaling option[ns=%s, aspect=%s, step=%s] does not exist. Pls check the config file." %
149             (ns_instanceId, aspect, step))
150     else:
151         return vnf_scale_list
152
153
154 def set_scaleVnfData_type(vnf_scale_list, scale_type):
155     logger.debug(
156         "vnf_scale_list = %s, type = %s" %
157         (vnf_scale_list, scale_type))
158     scaleVnfDataList = []
159     if vnf_scale_list is not None:
160         for i in range(vnf_scale_list.__len__()):
161             scaleVnfData = scale_vnf_data_mapping
162             scaleVnfData["vnfInstanceId"] = get_vnfInstanceIdByName(
163                 vnf_scale_list[i]["vnfInstanceId"])
164             scaleVnfData["scaleByStepData"][0]["type"] = scale_type
165             scaleVnfData["scaleByStepData"][0]["aspectId"] = vnf_scale_list[i]["vnf_scaleAspectId"]
166             scaleVnfData["scaleByStepData"][0]["numberOfSteps"] = vnf_scale_list[i]["numberOfSteps"]
167             scaleVnfDataList.append(scaleVnfData)
168     logger.debug("scaleVnfDataList = %s" % scaleVnfDataList)
169     return scaleVnfDataList
170
171
172 def get_vnfInstanceIdByName(name):
173     return name
174
175
176 def get_vnf_data(filename, ns_instanceId, aspect, step, scale_type):
177
178     vnf_scale_list = get_vnf_scale_info(filename, ns_instanceId, aspect, step)
179     check_scale_list(vnf_scale_list, ns_instanceId, aspect, step)
180     scaleVnfDataList = set_scaleVnfData_type(vnf_scale_list, scale_type)
181     logger.debug("scaleVnfDataList = %s" % scaleVnfDataList)
182     return scaleVnfDataList
183
184     # return Response(data={'error': e.message},status=status.HTTP_204_NO_CONTENT)
185     # return Response(data={'success': 'success'},status=status.HTTP_200_OK)
186
187
188 # Get scaling data of vnf according to the package
189 def get_vnf_data_package(
190         scalingmap_json,
191         ns_instanceId,
192         aspect,
193         step,
194         scale_type):
195     nsd_id = get_nsdId(ns_instanceId)
196     vnf_scale_list = get_vnf_scale_info_package(
197         scalingmap_json, nsd_id, aspect, step)
198     check_scale_list(vnf_scale_list, ns_instanceId, aspect, step)
199     vnf_scale_list = deal_vnf_scale_info(vnf_scale_list)
200     scaleVnfDataList = set_scaleVnfData_type(vnf_scale_list, scale_type)
201     logger.debug("scaleVnfDataList = %s" % scaleVnfDataList)
202
203     return scaleVnfDataList
204
205
206 # Get the nsd id according to the ns instance id.
207 def get_nsdId(ns_instanceId):
208     if NSInstModel.objects.filter(id=ns_instanceId):
209         nsd_id = NSInstModel.objects.filter(id=ns_instanceId)[0].nsd_id
210         return nsd_id
211
212     return None
213
214
215 def get_and_check_params(scaleNsData, ns_InstanceId):
216
217     if scaleNsData is None:
218         pass
219         # raise NSLCMException("Error! scaleNsData in the request is Empty!")
220
221     scaleNsByStepsData = scaleNsData[0]["scaleNsByStepsData"]
222     if scaleNsByStepsData is None:
223         pass
224         # raise NSLCMException("Error! scaleNsByStepsData in the request is Empty!")
225
226     aspect = scaleNsByStepsData[0]["aspectId"]
227     numberOfSteps = scaleNsByStepsData[0]["numberOfSteps"]
228     scale_type = scaleNsByStepsData[0]["scalingDirection"]
229
230     return ns_InstanceId, aspect, numberOfSteps, scale_type
231
232
233 def get_scale_vnf_data(scaleNsData, ns_InstanceId):
234     curdir_path = os.path.dirname(
235         os.path.dirname(
236             os.path.dirname(
237                 os.path.abspath(__file__))))
238     filename = curdir_path + "/ns/data/scalemapping.json"
239     logger.debug("filename = %s" % filename)
240     ns_InstanceId, aspect, numberOfSteps, scale_type = get_and_check_params(
241         scaleNsData, ns_InstanceId)
242     return get_vnf_data(
243         filename,
244         ns_InstanceId,
245         aspect,
246         numberOfSteps,
247         scale_type)
248
249
250 # Get scaling vnf data according to package by the scaling map json file.
251 def get_scale_vnf_data_package(scaleNsData, ns_InstanceId):
252
253     scalingmap_json = catalog.get_scalingmap_json_package(ns_InstanceId)
254     logger.debug("scalingmap_json = %s" % scalingmap_json)
255     ns_InstanceId, aspect, numberOfSteps, scale_type = get_and_check_params(
256         scaleNsData, ns_InstanceId)
257     return get_vnf_data_package(
258         scalingmap_json,
259         ns_InstanceId,
260         aspect,
261         numberOfSteps,
262         scale_type)