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