94c349e9e12ea338402befc9ed5b8399b31a527c
[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_scale_vnf_data_list(filename, ns_instanceId, aspect, step, scale_type):
115
116     vnf_scale_list = get_vnf_scale_info(filename, ns_instanceId, aspect, step)
117     check_scale_list(vnf_scale_list, ns_instanceId, aspect, step)
118     scaleVnfDataList = set_scaleVnfData_type(vnf_scale_list, scale_type)
119     logger.debug("scaleVnfDataList = %s" % scaleVnfDataList)
120     return scaleVnfDataList
121
122
123 # Get the nsd id according to the ns instance id.
124 def get_nsdId(ns_instanceId):
125     if NSInstModel.objects.filter(id=ns_instanceId):
126         nsd_id = NSInstModel.objects.filter(id=ns_instanceId)[0].nsd_id
127         return nsd_id
128
129     return None
130
131
132 def get_and_check_params(scaleNsByStepsData, ns_InstanceId):
133
134     if scaleNsByStepsData is None:
135         pass
136         # raise NSLCMException("Error! scaleNsByStepsData in the request is Empty!")
137
138     aspect = scaleNsByStepsData["aspectId"]
139     numberOfSteps = scaleNsByStepsData["numberOfSteps"]
140     scale_type = scaleNsByStepsData["scalingDirection"]
141
142     return aspect, numberOfSteps, scale_type
143
144
145 def get_scale_vnf_data(scaleNsData, ns_InstanceId):
146     curdir_path = os.path.dirname(
147         os.path.dirname(
148             os.path.dirname(
149                 os.path.abspath(__file__))))
150     filename = curdir_path + "/ns/data/scalemapping.json"
151     logger.debug("filename = %s" % filename)
152     aspect, numberOfSteps, scale_type = get_and_check_params(
153         scaleNsData, ns_InstanceId)
154     return get_scale_vnf_data_list(
155         filename,
156         ns_InstanceId,
157         aspect,
158         numberOfSteps,
159         scale_type)
160
161
162 # Get scaling vnf data info list according to the ns instance id and request ScaleNsData.
163 def get_scale_vnf_data_info_list(scaleNsData, ns_InstanceId):
164     # Gets the nsd id accordign to the ns instance id.
165     nsd_id = get_nsdId(ns_InstanceId)
166
167     # Gets the scalingmap json data from the package according to the ns instance id.
168     scalingmap_json = catalog.get_scalingmap_json_package(ns_InstanceId)
169
170     # Gets and checks the values of parameters.
171     aspect, numberOfSteps, scale_type = get_and_check_params(
172         scaleNsData, ns_InstanceId)
173
174     # Firstly, gets the scaling vnf data info list from the scaling map json data.
175     scale_vnf_data_info_list_from_json = get_scale_vnf_data_from_json(scalingmap_json, nsd_id, aspect, numberOfSteps)
176     check_scale_list(scale_vnf_data_info_list_from_json, ns_InstanceId, aspect, numberOfSteps)
177
178     # Secondly, adds the property of vnfInstanceId to the list according to the vnfd id.
179     scale_vnf_data_info_list = set_scacle_vnf_instance_id(scale_vnf_data_info_list_from_json)
180     check_scale_list(scale_vnf_data_info_list, ns_InstanceId, aspect, numberOfSteps)
181
182     # Lastly, adds the property of type to the list acoording to the request ScaleNsData.
183     scale_vnf_data_info_list = set_scaleVnfData_type(scale_vnf_data_info_list, scale_type)
184     check_scale_list(scale_vnf_data_info_list, ns_InstanceId, aspect, numberOfSteps)
185
186     return scale_vnf_data_info_list
187
188
189 # Get the vnf scaling info from the scaling_map.json according to the ns package id.
190 def get_scale_vnf_data_from_json(scalingmap_json, nsd_id, aspect, step):
191     scale_options = ignorcase_get(scalingmap_json, "scale_options")
192     for i in range(scale_options.__len__()):
193         ns_scale_option = scale_options[i]
194         if (ignorcase_get(ns_scale_option, "nsd_id") == nsd_id) and (
195                 ignorcase_get(ns_scale_option, "ns_scale_aspect") == aspect):
196             ns_scale_info_list = ignorcase_get(
197                 ns_scale_option, "ns_scale_info")
198             for j in range(ns_scale_info_list.__len__()):
199                 ns_scale_info = ns_scale_info_list[j]
200                 if ns_scale_info["step"] == step:
201                     vnf_scale_info_list = ns_scale_info["vnf_scale_info"]
202
203                     return vnf_scale_info_list
204
205     return None
206
207
208 # Gets the vnf instance id according to the vnfd_id and modify the list of scaling vnf info accrodingly.
209 def set_scacle_vnf_instance_id(vnf_scale_info_list):
210     scale_vnf_data_info_list = []
211     for i in range(vnf_scale_info_list.__len__()):
212         vnf_scale_info = vnf_scale_info_list[i]
213         vnfd_id = vnf_scale_info["vnfd_id"]
214         vnf_instance_id_list = get_vnf_instance_id_list(vnfd_id)
215         index = 0
216         while index < vnf_instance_id_list.__len__():
217             copy_vnf_scale_info = copy.deepcopy(vnf_scale_info)
218             copy_vnf_scale_info.pop("vnfd_id")
219             copy_vnf_scale_info["vnfInstanceId"] = vnf_instance_id_list[index]
220             index += 1
221             scale_vnf_data_info_list.append(copy_vnf_scale_info)
222
223     return scale_vnf_data_info_list
224
225
226 # Sets the scaling type of vnf data info list.
227 def set_scaleVnfData_type(vnf_scale_list, scale_type):
228     logger.debug(
229         "vnf_scale_list = %s, type = %s" %
230         (vnf_scale_list, scale_type))
231     scaleVnfDataList = []
232     if vnf_scale_list is not None:
233         for i in range(vnf_scale_list.__len__()):
234             scaleVnfData = copy.deepcopy(scale_vnf_data_mapping)
235             scaleVnfData["vnfInstanceId"] = vnf_scale_list[i]["vnfInstanceId"]
236             scaleVnfData["scaleByStepData"]["type"] = scale_type
237             scaleVnfData["scaleByStepData"]["aspectId"] = vnf_scale_list[i]["vnf_scaleAspectId"]
238             scaleVnfData["scaleByStepData"]["numberOfSteps"] = vnf_scale_list[i]["numberOfSteps"]
239             scaleVnfDataList.append(scaleVnfData)
240     logger.debug("scaleVnfDataList = %s" % scaleVnfDataList)
241     return scaleVnfDataList