blob: 3ea8c6477cd2174117ac0f0b38b59a4b2722e940 [file] [log] [blame]
Patricia Reinoso38fb5da2023-04-27 13:48:50 +00001#########################################################################
Mark Beierl9e1379d2023-04-06 15:12:46 +00002#
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
12# implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
Dario Faccinf5d65b52023-06-19 12:35:33 +020016from temporalio import activity
Gulsum Atici50d12e02023-04-27 16:41:43 +030017from typing import List, Any
18
Dario Faccinf5d65b52023-06-19 12:35:33 +020019from osm_common.temporal.activities.vnf import (
20 GetTaskQueue,
21 GetVimCloud,
22 GetVnfDescriptor,
23 GetVnfRecord,
Daniel Arndtc5982f52023-07-10 09:51:58 -030024 GetModelNames,
Dario Faccinf5d65b52023-06-19 12:35:33 +020025 ChangeVnfState,
26 ChangeVnfInstantiationState,
27 SetVnfModel,
28 SendNotificationForVnf,
29)
30from osm_common.temporal.dataclasses_common import VduComputeConstraints
31from osm_common.temporal_task_queues.task_queues_mappings import (
Gulsum Atici36365402023-04-07 00:07:07 +030032 VIM_TYPE_TASK_QUEUE_MAPPINGS,
Mark Beierl9e1379d2023-04-06 15:12:46 +000033)
Mark Beierl9e1379d2023-04-06 15:12:46 +000034
Gulsum Atici50d12e02023-04-27 16:41:43 +030035CONFIG_IDENTIFIER = "config::"
36
37
Mark Beierl82629422023-06-29 20:22:36 +000038@activity.defn(name=GetTaskQueue.__name__)
Dario Faccinf5d65b52023-06-19 12:35:33 +020039class GetTaskQueueImpl(GetTaskQueue):
Dario Faccinf5d65b52023-06-19 12:35:33 +020040 async def __call__(self, activity_input: GetTaskQueue.Input) -> GetTaskQueue.Output:
41 vnfr = self.db.get_one("vnfrs", {"_id": activity_input.vnfr_uuid})
Gulsum Atici36365402023-04-07 00:07:07 +030042 vim_record = self.db.get_one("vim_accounts", {"_id": vnfr["vim-account-id"]})
Gulsum Atici625a6542023-04-18 15:27:18 +030043 task_queue = VIM_TYPE_TASK_QUEUE_MAPPINGS[vim_record["vim_type"]]
Mark Beierl9e1379d2023-04-06 15:12:46 +000044 self.logger.debug(f"Got the task queue {task_queue} for VNF operations.")
Dario Faccinf5d65b52023-06-19 12:35:33 +020045 return GetTaskQueue.Output(task_queue)
Mark Beierl9e1379d2023-04-06 15:12:46 +000046
Gulsum Aticia1898b42023-04-25 15:48:10 +030047
Mark Beierl82629422023-06-29 20:22:36 +000048@activity.defn(name=GetVimCloud.__name__)
Dario Faccinf5d65b52023-06-19 12:35:33 +020049class GetVimCloudImpl(GetVimCloud):
Dario Faccinf5d65b52023-06-19 12:35:33 +020050 async def __call__(self, activity_input: GetVimCloud.Input) -> GetVimCloud.Output:
51 vnfr = self.db.get_one("vnfrs", {"_id": activity_input.vnfr_uuid})
Gulsum Aticia1898b42023-04-25 15:48:10 +030052 vim_record = self.db.get_one("vim_accounts", {"_id": vnfr["vim-account-id"]})
53 cloud = vim_record["config"].get("cloud", "")
54 self.logger.debug(f"Got the cloud type {cloud} for VNF operations.")
Dario Faccinf5d65b52023-06-19 12:35:33 +020055 return GetVimCloud.Output(cloud=cloud)
Gulsum Aticia1898b42023-04-25 15:48:10 +030056
Gulsum Atici36365402023-04-07 00:07:07 +030057
Mark Beierl82629422023-06-29 20:22:36 +000058@activity.defn(name=GetVnfRecord.__name__)
Dario Faccinf5d65b52023-06-19 12:35:33 +020059class GetVnfRecordImpl(GetVnfRecord):
Dario Faccinf5d65b52023-06-19 12:35:33 +020060 async def __call__(self, activity_input: GetVnfRecord.Input) -> GetVnfRecord.Output:
61 vnfr = self.db.get_one("vnfrs", {"_id": activity_input.vnfr_uuid})
Gulsum Atici50d12e02023-04-27 16:41:43 +030062 self.logger.debug("Got the vnfr from Database for VNF operations.")
Dario Faccinf5d65b52023-06-19 12:35:33 +020063 return GetVnfRecord.Output(vnfr=vnfr)
Gulsum Atici50d12e02023-04-27 16:41:43 +030064
Gulsum Atici50d12e02023-04-27 16:41:43 +030065
Mark Beierl82629422023-06-29 20:22:36 +000066@activity.defn(name=GetVnfDescriptor.__name__)
Dario Faccinf5d65b52023-06-19 12:35:33 +020067class GetVnfDescriptorImpl(GetVnfDescriptor):
Dario Faccinf5d65b52023-06-19 12:35:33 +020068 async def __call__(
69 self, activity_input: GetVnfDescriptor.Input
70 ) -> GetVnfDescriptor.Output:
71 vnfd = self.db.get_one("vnfds", {"_id": activity_input.vnfd_uuid})
72 return GetVnfDescriptor.Output(vnfd=vnfd)
Gulsum Atici50d12e02023-04-27 16:41:43 +030073
Gulsum Atici50d12e02023-04-27 16:41:43 +030074
Dario Faccinf5d65b52023-06-19 12:35:33 +020075class VnfSpecifications:
Gulsum Atici50d12e02023-04-27 16:41:43 +030076 @staticmethod
77 def get_vdu_instantiation_params(
78 vdu_id: str, vnf_instantiation_config: dict
79 ) -> dict:
80 for vdu in vnf_instantiation_config.get("vdu", []):
81 if vdu.get("id") == vdu_id:
82 return vdu.get("configurable-properties", {})
83 return {}
84
85 @staticmethod
86 def get_compute_constraints(vdu: dict, vnfd: dict) -> VduComputeConstraints:
87 compute_desc_id = vdu.get("virtual-compute-desc")
88 if not compute_desc_id:
89 return VduComputeConstraints(cores=0, mem=0)
Dario Faccinf5d65b52023-06-19 12:35:33 +020090 flavor_details = VnfSpecifications._get_flavor_details(compute_desc_id, vnfd)
Gulsum Atici50d12e02023-04-27 16:41:43 +030091 if not flavor_details:
92 return VduComputeConstraints(cores=0, mem=0)
93
94 cpu_cores = flavor_details.get("virtual-cpu", {}).get("num-virtual-cpu", 0)
95 memory_gb = flavor_details.get("virtual-memory", {}).get("size", 0)
96 return VduComputeConstraints(cores=cpu_cores, mem=int(memory_gb))
97
98 @staticmethod
99 def _get_flavor_details(compute_desc_id: str, vnfd: dict) -> Any:
100 for flavor in vnfd.get("virtual-compute-desc", []):
101 if flavor.get("id") == compute_desc_id:
102 return flavor
103 return None
104
105 @staticmethod
106 def get_application_config(vdu: dict, vdu_instantiation_config: dict) -> dict:
107 configurable_properties = vdu.get("configurable-properties", [])
108
Dario Faccinf5d65b52023-06-19 12:35:33 +0200109 config_from_descriptor = VnfSpecifications._get_only_config_items(
110 VnfSpecifications._list_to_dict(configurable_properties)
Gulsum Atici50d12e02023-04-27 16:41:43 +0300111 )
112
Dario Faccinf5d65b52023-06-19 12:35:33 +0200113 config_from_instantiation = VnfSpecifications._get_only_config_items(
Gulsum Atici50d12e02023-04-27 16:41:43 +0300114 vdu_instantiation_config
115 )
116 return {**config_from_descriptor, **config_from_instantiation}
117
118 @staticmethod
119 def _get_only_config_items(config: dict) -> dict:
120 return {
121 key[len(CONFIG_IDENTIFIER) :]: value
122 for key, value in config.items()
123 if key.startswith(CONFIG_IDENTIFIER)
124 }
125
126 @staticmethod
127 def _list_to_dict(indata: List[dict]) -> dict:
128 return {
129 item["key"]: item["value"]
130 for item in indata
131 if item.get("key") and item.get("value")
132 }
Gulsum Atici36365402023-04-07 00:07:07 +0300133
Mark Beierl9e1379d2023-04-06 15:12:46 +0000134
Mark Beierl82629422023-06-29 20:22:36 +0000135@activity.defn(name=ChangeVnfState.__name__)
Dario Faccinf5d65b52023-06-19 12:35:33 +0200136class ChangeVnfStateImpl(ChangeVnfState):
Dario Faccinf5d65b52023-06-19 12:35:33 +0200137 async def __call__(self, activity_input: ChangeVnfState.Input) -> None:
138 update_vnf_state = {"vnfState": activity_input.state.name}
139 self.db.set_one("vnfrs", {"_id": activity_input.vnfr_uuid}, update_vnf_state)
Mark Beierl9e1379d2023-04-06 15:12:46 +0000140 self.logger.debug(
Dario Faccinf5d65b52023-06-19 12:35:33 +0200141 f"VNF {activity_input.vnfr_uuid} state is updated to {activity_input.state.name}."
Mark Beierl9e1379d2023-04-06 15:12:46 +0000142 )
143
Mark Beierl9e1379d2023-04-06 15:12:46 +0000144
Mark Beierl82629422023-06-29 20:22:36 +0000145@activity.defn(name=ChangeVnfInstantiationState.__name__)
Dario Faccinf5d65b52023-06-19 12:35:33 +0200146class ChangeVnfInstantiationStateImpl(ChangeVnfInstantiationState):
Dario Faccinf5d65b52023-06-19 12:35:33 +0200147 async def __call__(self, activity_input: ChangeVnfInstantiationState.Input) -> None:
Dario Faccin0568c6c2023-04-14 10:19:07 +0200148 update_vnf_instantiation_state = {
Dario Faccinf5d65b52023-06-19 12:35:33 +0200149 "instantiationState": activity_input.state.name
Mark Beierl9e1379d2023-04-06 15:12:46 +0000150 }
151 self.db.set_one(
152 "vnfrs",
Dario Faccinf5d65b52023-06-19 12:35:33 +0200153 {"_id": activity_input.vnfr_uuid},
Dario Faccin0568c6c2023-04-14 10:19:07 +0200154 update_vnf_instantiation_state,
Mark Beierl9e1379d2023-04-06 15:12:46 +0000155 )
156 self.logger.debug(
Dario Faccinf5d65b52023-06-19 12:35:33 +0200157 f"VNF {activity_input.vnfr_uuid} state is updated to {activity_input.state.name}."
Mark Beierl9e1379d2023-04-06 15:12:46 +0000158 )
159
Dario Faccin39301762023-04-17 16:56:37 +0200160
Mark Beierl82629422023-06-29 20:22:36 +0000161@activity.defn(name=SetVnfModel.__name__)
Dario Faccinf5d65b52023-06-19 12:35:33 +0200162class SetVnfModelImpl(SetVnfModel):
Dario Faccinf5d65b52023-06-19 12:35:33 +0200163 async def __call__(self, activity_input: SetVnfModel.Input) -> None:
164 update_namespace = {"namespace": activity_input.model_name}
165 self.db.set_one("vnfrs", {"_id": activity_input.vnfr_uuid}, update_namespace)
Dario Faccin39301762023-04-17 16:56:37 +0200166 self.logger.debug(
Dario Faccinf5d65b52023-06-19 12:35:33 +0200167 f"VNF {activity_input.vnfr_uuid} model name is updated to {activity_input.model_name}."
Dario Faccin39301762023-04-17 16:56:37 +0200168 )
169
Dario Faccin0568c6c2023-04-14 10:19:07 +0200170
Mark Beierl82629422023-06-29 20:22:36 +0000171@activity.defn(name=SendNotificationForVnf.__name__)
Dario Faccinf5d65b52023-06-19 12:35:33 +0200172class SendNotificationForVnfImpl(SendNotificationForVnf):
Dario Faccinf5d65b52023-06-19 12:35:33 +0200173 async def __call__(self, activity_input: SendNotificationForVnf.Input) -> None:
Dario Faccin0568c6c2023-04-14 10:19:07 +0200174 self.logger.debug("Send notification for VNF not implemented.")
Daniel Arndtc5982f52023-07-10 09:51:58 -0300175
176
177@activity.defn(name=GetModelNames.__name__)
178class GetModelNamesImpl(GetModelNames):
179 async def __call__(
180 self, activity_input: GetModelNames.Input
181 ) -> GetModelNames.Output:
182 ns_id = activity_input.ns_uuid
183
184 vnfrs = self.db.get_list("vnfrs", {"nsr-id-ref": ns_id})
185 self.logger.debug(
186 f"Retrieved {len(vnfrs)} vnf records matching {ns_id} from database."
187 )
188
189 return GetModelNames.Output(
190 model_names={vnfr["namespace"] for vnfr in vnfrs if "namespace" in vnfr}
191 )