7e9c65190cc6712dc4b57d62b4672ff5ddfbc9b1
[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     for i in range(nf_model_list.__len__()):
89         vnf_instance_id_list.append(nf_model_list[i].nfinstid)
90
91     return vnf_instance_id_list
92
93
94 def get_json_data(filename):
95     f = open(filename)
96     json_str = f.read()
97     data = json.JSONDecoder().decode(json_str)
98     f.close()
99     return data
100
101
102 def check_scale_list(vnf_scale_list, ns_instanceId, aspect, step):
103     if vnf_scale_list is None:
104         logger.debug(
105             "The scaling option[ns=%s, aspect=%s, step=%s] does not exist. Pls check the config file." %
106             (ns_instanceId, aspect, step))
107         raise Exception(
108             "The scaling option[ns=%s, aspect=%s, step=%s] does not exist. Pls check the config file." %
109             (ns_instanceId, aspect, step))
110     else:
111         return vnf_scale_list
112
113
114 def get_vnfInstanceIdByName(name):
115     return name
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     # return Response(data={'error': e.message},status=status.HTTP_204_NO_CONTENT)
127     # return Response(data={'success': 'success'},status=status.HTTP_200_OK)
128
129
130 # Get the nsd id according to the ns instance id.
131 def get_nsdId(ns_instanceId):
132     if NSInstModel.objects.filter(id=ns_instanceId):
133         nsd_id = NSInstModel.objects.filter(id=ns_instanceId)[0].nsd_id
134         return nsd_id
135
136     return None
137
138
139 def get_and_check_params(scaleNsByStepsData, ns_InstanceId):
140
141     if scaleNsByStepsData is None:
142         pass
143         # raise NSLCMException("Error! scaleNsByStepsData in the request is Empty!")
144
145     aspect = scaleNsByStepsData["aspectId"]
146     numberOfSteps = scaleNsByStepsData["numberOfSteps"]
147     scale_type = scaleNsByStepsData["scalingDirection"]
148
149     return aspect, numberOfSteps, scale_type
150
151
152 def get_scale_vnf_data(scaleNsData, ns_InstanceId):
153     curdir_path = os.path.dirname(
154         os.path.dirname(
155             os.path.dirname(
156                 os.path.abspath(__file__))))
157     filename = curdir_path + "/ns/data/scalemapping.json"
158     logger.debug("filename = %s" % filename)
159     aspect, numberOfSteps, scale_type = get_and_check_params(
160         scaleNsData, ns_InstanceId)
161     return get_scale_vnf_data_list(
162         filename,
163         ns_InstanceId,
164         aspect,
165         numberOfSteps,
166         scale_type)
167
168
169 # Get scaling vnf data info list according to the ns instance id and request ScaleNsData.
170 def get_scale_vnf_data_info_list(scaleNsData, ns_InstanceId):
171     # Gets the nsd id accordign to the ns instance id.
172     nsd_id = get_nsdId(ns_InstanceId)
173
174     # Gets the scalingmap json data from the package according to the ns instance id.
175     scalingmap_json = catalog.get_scalingmap_json_package(ns_InstanceId)
176
177     # Gets and checks the values of parameters.
178     aspect, numberOfSteps, scale_type = get_and_check_params(
179         scaleNsData, ns_InstanceId)
180
181     # Firstly, gets the scaling vnf data info list from the scaling map json data.
182     scale_vnf_data_info_list_from_json = get_scale_vnf_data_from_json(scalingmap_json, nsd_id, aspect, numberOfSteps)
183     check_scale_list(scale_vnf_data_info_list_from_json, ns_InstanceId, aspect, numberOfSteps)
184
185     # Secondly, adds the property of vnfInstanceId to the list according to the vnfd id.
186     scale_vnf_data_info_list = set_scacle_vnf_instance_id(scale_vnf_data_info_list_from_json)
187     check_scale_list(scale_vnf_data_info_list, ns_InstanceId, aspect, numberOfSteps)
188
189     # Lastly, adds the property of type to the list acoording to the request ScaleNsData.
190     scale_vnf_data_info_list = set_scaleVnfData_type(scale_vnf_data_info_list, scale_type)
191     check_scale_list(scale_vnf_data_info_list, ns_InstanceId, aspect, numberOfSteps)
192
193     return scale_vnf_data_info_list
194
195
196 # Get the vnf scaling info from the scaling_map.json according to the ns package id.
197 def get_scale_vnf_data_from_json(scalingmap_json, nsd_id, aspect, step):
198     scale_options = ignorcase_get(scalingmap_json, "scale_options")
199     for i in range(scale_options.__len__()):
200         ns_scale_option = scale_options[i]
201         if (ignorcase_get(ns_scale_option, "nsd_id") == nsd_id) and (
202                 ignorcase_get(ns_scale_option, "ns_scale_aspect") == aspect):
203             ns_scale_info_list = ignorcase_get(
204                 ns_scale_option, "ns_scale_info")
205             for j in range(ns_scale_info_list.__len__()):
206                 ns_scale_info = ns_scale_info_list[j]
207                 if ns_scale_info["step"] == step:
208                     vnf_scale_info_list = ns_scale_info["vnf_scale_info"]
209
210                     return vnf_scale_info_list
211
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"] = get_vnfInstanceIdByName(
243                 vnf_scale_list[i]["vnfInstanceId"])
244             scaleVnfData["scaleByStepData"]["type"] = scale_type
245             scaleVnfData["scaleByStepData"]["aspectId"] = vnf_scale_list[i]["vnf_scaleAspectId"]
246             scaleVnfData["scaleByStepData"]["numberOfSteps"] = vnf_scale_list[i]["numberOfSteps"]
247             scaleVnfDataList.append(scaleVnfData)
248     logger.debug("scaleVnfDataList = %s" % scaleVnfDataList)
249     return scaleVnfDataList