Don't write information to resmanagement
[vfc/nfvo/lcm.git] / lcm / ns_vnfs / biz / grant_vnf.py
1 # Copyright 2018 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 uuid
18 import time
19 from lcm.pub.database.models import NfInstModel, OOFDataModel
20 from lcm.pub.exceptions import NSLCMException
21 from lcm.pub.msapi.sdc_run_catalog import query_vnfpackage_by_id
22 from lcm.pub.utils.values import ignore_case_get
23 from lcm.ns_vnfs.const import SCALAR_UNIT_DICT
24
25 logger = logging.getLogger(__name__)
26
27
28 class GrantVnf(object):
29     def __init__(self, grant_data):
30         self.data = grant_data
31
32     def exec_grant(self):
33         logger.debug("grant data from vnfm:%s", self.data)
34         if isinstance(self.data, str):
35             self.data = json.JSONDecoder().decode(self.data)
36         has_res_tpl = False
37         grant_type = None
38         action_type = ignore_case_get(self.data, "operation")
39         vimConnections = []
40         if ignore_case_get(self.data, "addResources"):
41             grant_type = "addResources"
42         elif ignore_case_get(self.data, "removeResources"):
43             grant_type = "removeResources"
44         else:
45             has_res_tpl = True
46
47         for res in ignore_case_get(self.data, grant_type):
48             if "resourceTemplate" in res:
49                 has_res_tpl = True
50                 break
51
52         if not has_res_tpl:
53             m_vnf_inst_id = ignore_case_get(self.data, "vnfInstanceId")
54             additional_param = ignore_case_get(self.data, "additionalparams")
55             vnfm_inst_id = ignore_case_get(additional_param, "vnfmid")
56             vim_id = ignore_case_get(additional_param, "vimid")
57             if vnfm_inst_id and vnfm_inst_id != "":
58                 vnfinsts = NfInstModel.objects.filter(
59                     mnfinstid=m_vnf_inst_id, vnfm_inst_id=vnfm_inst_id)
60             else:
61                 vnfinsts = NfInstModel.objects.filter(
62                     mnfinstid=m_vnf_inst_id)
63             if not vnfinsts:
64                 raise NSLCMException("Vnfinst(%s) is not found in vnfm(%s)" % (
65                     m_vnf_inst_id, vnfm_inst_id))
66
67             vnf_pkg_id = vnfinsts[0].package_id
68             nfpackage_info = query_vnfpackage_by_id(vnf_pkg_id)
69             vnf_pkg = nfpackage_info["packageInfo"]
70             vnfd = json.JSONDecoder().decode(vnf_pkg["vnfdModel"])
71
72             req_param = {
73                 "vnfInstanceId": m_vnf_inst_id,
74                 "vimId": vim_id,
75                 "vnfLcmOpOccId": ignore_case_get(self.data, "vnfLcmOpOccId"),
76                 "additionalParams": additional_param,
77                 grant_type: []
78             }
79             for res in ignore_case_get(self.data, grant_type):
80                 vdu_name = ignore_case_get(res, "vdu")
81                 grant_res = {
82                     "resourceDefinitionId": ignore_case_get(res, "resourceDefinitionId"),
83                     "type": ignore_case_get(res, "type"),
84                     "vdu": vdu_name
85                 }
86                 for vdu in vnfd["vdus"]:
87                     if vdu_name in (vdu["vdu_id"], vdu["properties"].get("name", "")):
88                         grant_res["resourceTemplate"] = self.get_res_tpl(vdu, vnfd)
89                         break
90                 req_param[grant_type].append(grant_res)
91             self.data = req_param
92         # tmp = resmgr.grant_vnf(self.data)
93         # vimConnections.append(
94         #     {
95         #         "id": tmp["vim"]["vimId"],
96         #         "vimId": tmp["vim"]["vimId"],
97         #         "vimType": None,
98         #         "interfaceInfo": None,
99         #         "accessInfo": tmp["vim"]["accessInfo"],
100         #         "extra": None
101         #     }
102         # )
103
104         grant_resp = {
105             "id": str(uuid.uuid4()),
106             "vnfInstanceId": ignore_case_get(self.data, 'vnfInstanceId'),
107             "vnfLcmOpOccId": ignore_case_get(self.data, "vnfLcmOpOccId"),
108             "vimConnections": vimConnections
109         }
110
111         logger.debug("action_type=%s" % action_type)
112         if action_type == 'INSTANTIATE':
113             for i in range(18):
114                 offs = OOFDataModel.objects.filter(service_resource_id=ignore_case_get(self.data, "vnfInstanceId"))
115                 if not (offs.exists() and offs[0].vdu_info):
116                     logger.debug("Cannot find oof data, retry%s" % (i + 1))
117                     time.sleep(5)
118                     continue
119                 try:
120                     vdu_info = json.loads(offs[0].vdu_info)
121                     grant_resp['vimAssets'] = {'computeResourceFlavours': []}
122                     for vdu in vdu_info:
123                         grant_resp['vimAssets']['computeResourceFlavours'].append({
124                             'vimConnectionId': offs[0].vim_id,
125                             'resourceProviderId': vdu.get("vduName"),
126                             'vnfdVirtualComputeDescId': None,  # TODO: required
127                             'vimFlavourId': vdu.get("flavorId")
128                         })
129                         # grant_resp['additionalparams'][off.vim_id] = off.directive
130                 except Exception:
131                     logger.debug("Load OOF data error")
132                 break
133
134         logger.debug("grant_resp=%s", grant_resp)
135         return grant_resp
136
137     def get_res_tpl(self, vdu, vnfd):
138         storage_size = 0
139         for storage_id in vdu["local_storages"]:
140             storage_size = storage_size + self.get_storage_size(storage_id, vnfd)
141         resourceTemplate = {
142             "virtualComputeDescriptor": {
143                 "virtualCpu": {
144                     "numVirtualCpu": int(vdu["virtual_compute"]["virtual_cpu"]["num_virtual_cpu"])
145                 },
146                 "virtualMemory": {
147                     "virtualMemSize": parse_unit(vdu["virtual_compute"]["virtual_memory"]["virtual_mem_size"], "MB")
148                 }
149             },
150             "virtualStorageDescriptor": {
151                 "typeOfStorage": "",
152                 "sizeOfStorage": storage_size,
153                 "swImageDescriptor": ""
154             }
155         }
156         return resourceTemplate
157
158     def get_storage_size(self, storage_id, vnfd):
159         for storage in vnfd["local_storages"]:
160             if storage_id == storage["local_storage_id"]:
161                 return parse_unit(storage["properties"]["size"], "GB")
162         return 0
163
164
165 def parse_unit(val, base_unit):
166     # recognized_units = ["B", "kB", "KiB", "MB", "MiB", "GB", "GiB", "TB", "TiB"]
167     # units_rate = [1, 1000, 1024, 1000000, 1048576, 1000000000, 1073741824, 1000000000000, 1099511627776]
168     # unit_rate_map = {unit.upper(): rate for unit, rate in zip(recognized_units, units_rate)}
169     num_unit = val.strip().split(" ")
170     if len(num_unit) != 2:
171         return val.strip()
172     num, unit = num_unit[0], num_unit[1]
173     return int(num) * SCALAR_UNIT_DICT[unit.upper()] / SCALAR_UNIT_DICT[base_unit.upper()]