Add lcm op occ to scale to level
[vfc/gvnfm/vnflcm.git] / lcm / lcm / nf / biz / scale_vnf_to_level.py
1 # Copyright (C) 2019 ZTE. All Rights Reserved.
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 import json
15 import logging
16
17 from lcm.nf.biz.scale_vnf import ScaleVnf
18 from lcm.nf.const import GRANT_TYPE
19 from lcm.nf.const import OPERATION_TYPE
20 from lcm.nf.const import OPERATION_TASK
21 from lcm.pub.database.models import VmInstModel
22 from lcm.pub.exceptions import NFLCMException
23 from .operate_vnf_lcm_op_occ import VnfLcmOpOcc
24
25 logger = logging.getLogger(__name__)
26
27
28 class ScaleVnfToLevel(ScaleVnf):
29     def __init__(self, data, nf_inst_id, job_id):
30         super(ScaleVnfToLevel, self).__init__(data=data,
31                                               nf_inst_id=nf_inst_id,
32                                               job_id=job_id)
33         self.aspect_id = ''
34         self.lcm_op_occ = VnfLcmOpOcc(
35             vnf_inst_id=nf_inst_id,
36             lcm_op_id=job_id,
37             operation=OPERATION_TYPE.SCALE_TO_LEVEL,
38             task=OPERATION_TASK.SCALE_TO_LEVEL
39         )
40         self.op_type = OPERATION_TYPE.SCALE_TO_LEVEL
41
42     def scale_pre(self):
43         self.vnfd_info = json.loads(self.vnf_insts[0].vnfd_model)
44         scale_in_vms = VmInstModel.objects.filter(instid=self.nf_inst_id)
45         vms_num = scale_in_vms.count()
46         self.instantiation_level_id = self.data.get("instantiationLevelId")
47         self.additional_params = self.data.get("additionalParams", {})
48         if not self.instantiation_level_id:
49             self.scale_info = self.data.get("scaleInfo")
50             self.aspect_id = self.scale_info.get("aspectId")
51             self.instantiation_level_id = self.get_instantiation_level_id()
52         else:
53             self.aspect_id = self.get_aspect_id()
54
55         number_of_instances = self.get_number_of_instances()
56         if number_of_instances == vms_num:
57             raise NFLCMException("Don't need scale in/out.")
58         elif number_of_instances > vms_num:
59             self.scale_type = GRANT_TYPE.SCALE_OUT
60         else:
61             self.scale_type = GRANT_TYPE.SCALE_IN
62
63         self.scale_inst_num = abs(number_of_instances - vms_num)
64         self.is_scale_in = (self.scale_type == GRANT_TYPE.SCALE_IN)
65         self.step_delta = self.get_scale_step_delta()
66         self.target_vdu, self.step_inst_num = self.get_vdu_scale_aspect_deltas()
67         self.min_instance_num, self.max_instance_num = self.get_instance_range()
68         self.check_if_can_scale()
69         self.scale_out_resource = {}
70
71     def get_number_of_instances(self):
72         for policy in self.vnfd_info.get("policies", []):
73             if policy.get("type") != "tosca.policies.nfv.VduInstantiationLevels":
74                 continue
75             # if not self.aspect_id:
76             #     self.aspect_id = policy.get("targets")[0]
77             levels = policy["properties"]["levels"]
78             number_of_instances = levels.get(self.instantiation_level_id)
79             if number_of_instances:
80                 return number_of_instances.get("number_of_instances")
81         raise NFLCMException("InstantiationLevelId(%s) does not exist" % self.instantiation_level_id)
82
83     def get_instantiation_level_id(self):
84         scale_level_in_request = self.scale_info.get("scaleLevel")
85         for policy in self.vnfd_info.get("policies", []):
86             if policy.get("type") != "tosca.policies.nfv.InstantiationLevels":
87                 continue
88             levels = policy["properties"]["levels"]
89             for level_id, level_info in levels.items():
90                 scale_aspect = level_info["scale_info"].get(self.aspect_id)
91                 scale_level_in_vnfd = scale_aspect["scale_level"]
92                 if scale_level_in_request == scale_level_in_vnfd:
93                     return level_id
94         raise NFLCMException("Failed to get scale_info in vnfd")
95
96     def get_aspect_id(self):
97         for policy in self.vnfd_info.get("policies", []):
98             if policy.get("type") != "tosca.policies.nfv.InstantiationLevels":
99                 continue
100             levels = policy["properties"]["levels"]
101             level_info = levels.get(self.instantiation_level_id)
102             return level_info.get("scale_info").keys()[0]
103         raise NFLCMException("Failed to get aspect_id in vnfd")