Refactor the method name
[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         "type": "",
32         "aspectId": "",
33         "numberOfSteps": ""
34     }
35 }
36
37
38 def ignorcase_get(args, key):
39     if not key:
40         return ""
41     if not args:
42         return ""
43     if key in args:
44         return args[key]
45     for old_key in args:
46         if old_key.upper() == key.upper():
47             return args[old_key]
48     return ""
49
50
51 def mapping_conv(keyword_map, rest_return):
52     resp_data = {}
53     for param in keyword_map:
54         if keyword_map[param]:
55             if isinstance(keyword_map[param], dict):
56                 resp_data[param] = mapping_conv(
57                     keyword_map[param], ignorcase_get(
58                         rest_return, param))
59             else:
60                 resp_data[param] = ignorcase_get(rest_return, param)
61     return resp_data
62
63
64 def get_vnf_scale_info(filename, ns_instanceId, aspect, step):
65     json_data = get_json_data(filename)
66     scale_options = ignorcase_get(json_data, "scale_options")
67     for i in range(scale_options.__len__()):
68         ns_scale_option = scale_options[i]
69         if (ignorcase_get(ns_scale_option, "ns_instanceId") == ns_instanceId) \
70                 and (ignorcase_get(ns_scale_option, "ns_scale_aspect") == aspect):
71             ns_scale_info_list = ignorcase_get(
72                 ns_scale_option, "ns_scale_info_list")
73             for j in range(ns_scale_info_list.__len__()):
74                 ns_scale_info = ns_scale_info_list[j]
75                 if ns_scale_info["step"] == step:
76                     return ns_scale_info["vnf_scale_info"]
77
78     return None
79
80
81 def get_vnf_instance_id_list(vnfd_id):
82     kwargs = {}
83     kwargs['package_id'] = vnfd_id
84     kwargs['status'] = VNF_STATUS.ACTIVE
85
86     nf_model_list = NfInstModel.objects.filter(**kwargs)
87     vnf_instance_id_list = list()
88     nf_model_len = nf_model_list.__len__()
89     if nf_model_len == 0:
90         logger.error("No VNF instances found(vnfd_id=%s)" % vnfd_id)
91     else:
92         for i in range(nf_model_len):
93             vnf_instance_id_list.append(nf_model_list[i].nfinstid)
94
95     return vnf_instance_id_list
96
97
98 def get_json_data(filename):
99     f = open(filename)
100     json_str = f.read()
101     data = json.JSONDecoder().decode(json_str)
102     f.close()
103     return data
104
105
106 def check_scale_list(vnf_scale_list, ns_instanceId, aspect, step):
107     if vnf_scale_list is None or vnf_scale_list.__len__() == 0:
108         logger.debug(
109             "The scaling option[ns=%s, aspect=%s, step=%s] does not exist. Pls check the config file." %
110             (ns_instanceId, aspect, step))
111         raise Exception(
112             "The scaling option[ns=%s, aspect=%s, step=%s] does not exist. Pls check the config file." %
113             (ns_instanceId, aspect, step))
114     else:
115         return vnf_scale_list
116
117
118 def get_scale_vnf_data_list(filename, ns_instanceId, aspect, step, scale_type):
119
120     vnf_scale_list = get_vnf_scale_info(filename, ns_instanceId, aspect, step)
121     check_scale_list(vnf_scale_list, ns_instanceId, aspect, step)
122     scaleVnfDataList = set_scaleVnfData_type(vnf_scale_list, scale_type)
123     logger.debug("scaleVnfDataList = %s" % scaleVnfDataList)
124     return scaleVnfDataList
125
126
127 # Get the nsd id according to the ns instance id.
128 def get_nsdId(ns_instanceId):
129     if NSInstModel.objects.filter(id=ns_instanceId):
130         nsd_id = NSInstModel.objects.filter(id=ns_instanceId)[0].nsd_id
131         return nsd_id
132
133     return None
134
135
136 def check_and_set_params(scaleNsData, ns_InstanceId):
137     if scaleNsData is None:
138         raise Exception("Error! scaleNsData in the request is Empty!")
139
140     scaleNsByStepsData = scaleNsData[0]["scaleNsByStepsData"][0]
141     if scaleNsByStepsData is None:
142         raise Exception("Error! scaleNsByStepsData in the request is Empty!")
143
144     aspect = scaleNsByStepsData["aspectId"]
145     numberOfSteps = scaleNsByStepsData["numberOfSteps"]
146     scale_type = scaleNsByStepsData["scalingDirection"]
147
148     return aspect, numberOfSteps, scale_type
149
150
151 def get_scale_vnf_data(scaleNsData, ns_InstanceId):
152     curdir_path = os.path.dirname(
153         os.path.dirname(
154             os.path.dirname(
155                 os.path.abspath(__file__))))
156     filename = curdir_path + "/ns/data/scalemapping.json"
157     logger.debug("filename = %s" % filename)
158     aspect, numberOfSteps, scale_type = check_and_set_params(
159         scaleNsData, ns_InstanceId)
160     return get_scale_vnf_data_list(
161         filename,
162         ns_InstanceId,
163         aspect,
164         numberOfSteps,
165         scale_type)
166
167
168 # Get scaling vnf data info list according to the ns instance id and request ScaleNsData.
169 def get_scale_vnf_data_info_list(scaleNsData, ns_InstanceId):
170     # Gets the nsd id accordign to the ns instance id.
171     nsd_id = get_nsdId(ns_InstanceId)
172
173     # Gets the scalingmap json data from the package according to the ns instance id.
174     scalingmap_json = catalog.get_scalingmap_json_package(ns_InstanceId)
175
176     # Gets and checks the values of parameters.
177     aspect, numberOfSteps, scale_type = check_and_set_params(
178         scaleNsData, ns_InstanceId)
179
180     # Firstly, gets the scaling vnf data info list from the scaling map json data.
181     scale_vnf_data_info_list_from_json = get_scale_vnf_data_from_json(scalingmap_json, nsd_id, aspect, numberOfSteps)
182     check_scale_list(scale_vnf_data_info_list_from_json, ns_InstanceId, aspect, numberOfSteps)
183
184     # Secondly, adds the property of vnfInstanceId to the list according to the vnfd id.
185     scale_vnf_data_info_list = set_scacle_vnf_instance_id(scale_vnf_data_info_list_from_json)
186     check_scale_list(scale_vnf_data_info_list, ns_InstanceId, aspect, numberOfSteps)
187
188     # Lastly, adds the property of type to the list acoording to the request ScaleNsData.
189     scale_vnf_data_info_list = set_scaleVnfData_type(scale_vnf_data_info_list, scale_type)
190     check_scale_list(scale_vnf_data_info_list, ns_InstanceId, aspect, numberOfSteps)
191
192     return scale_vnf_data_info_list
193
194
195 # Get the vnf scaling info from the scaling_map.json according to the ns package id.
196 def get_scale_vnf_data_from_json(scalingmap_json, nsd_id, aspect, step):
197     scale_options = ignorcase_get(scalingmap_json, "scale_options")
198     for i in range(scale_options.__len__()):
199         ns_scale_option = scale_options[i]
200         if (ignorcase_get(ns_scale_option, "nsd_id") == nsd_id) and (
201                 ignorcase_get(ns_scale_option, "ns_scale_aspect") == aspect):
202             ns_scale_info_list = ignorcase_get(
203                 ns_scale_option, "ns_scale_info")
204             for j in range(ns_scale_info_list.__len__()):
205                 ns_scale_info = ns_scale_info_list[j]
206                 if ns_scale_info["step"] == step:
207                     vnf_scale_info_list = ns_scale_info["vnf_scale_info"]
208
209                     return vnf_scale_info_list
210
211     logger.error("get_scale_vnf_data_from_json method retuan null")
212     return None
213
214
215 # Gets the vnf instance id according to the vnfd_id and modify the list of scaling vnf info accrodingly.
216 def set_scacle_vnf_instance_id(vnf_scale_info_list):
217     scale_vnf_data_info_list = []
218     for i in range(vnf_scale_info_list.__len__()):
219         vnf_scale_info = vnf_scale_info_list[i]
220         vnfd_id = vnf_scale_info["vnfd_id"]
221         vnf_instance_id_list = get_vnf_instance_id_list(vnfd_id)
222         index = 0
223         while index < vnf_instance_id_list.__len__():
224             copy_vnf_scale_info = copy.deepcopy(vnf_scale_info)
225             copy_vnf_scale_info.pop("vnfd_id")
226             copy_vnf_scale_info["vnfInstanceId"] = vnf_instance_id_list[index]
227             index += 1
228             scale_vnf_data_info_list.append(copy_vnf_scale_info)
229
230     return scale_vnf_data_info_list
231
232
233 # Sets the scaling type of vnf data info list.
234 def set_scaleVnfData_type(vnf_scale_list, scale_type):
235     logger.debug(
236         "vnf_scale_list = %s, type = %s" %
237         (vnf_scale_list, scale_type))
238     scaleVnfDataList = []
239     if vnf_scale_list is not None:
240         for i in range(vnf_scale_list.__len__()):
241             scaleVnfData = copy.deepcopy(scale_vnf_data_mapping)
242             scaleVnfData["vnfInstanceId"] = vnf_scale_list[i]["vnfInstanceId"]
243             scaleVnfData["scaleByStepData"]["type"] = scale_type
244             scaleVnfData["scaleByStepData"]["aspectId"] = vnf_scale_list[i]["vnf_scaleAspectId"]
245             scaleVnfData["scaleByStepData"]["numberOfSteps"] = vnf_scale_list[i]["numberOfSteps"]
246             scaleVnfDataList.append(scaleVnfData)
247     logger.debug("scaleVnfDataList = %s" % scaleVnfDataList)
248     return scaleVnfDataList