blob: eee43254f4a65027382d4cf8d9c1f407990d5d3b [file] [log] [blame]
Patricia Reinoso52431352023-04-05 15:35:48 +00001#######################################################################################
2# Copyright ETSI Contributors and Others.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13# implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import logging
18from time import time
19from temporalio import activity
20from osm_common.temporal_constants import (
Patricia Reinoso52431352023-04-05 15:35:48 +000021 ACTIVITY_CHECK_NS_INSTANTIATION_FINISHED,
Patricia Reinoso52431352023-04-05 15:35:48 +000022 ACTIVITY_DEPLOY_NS,
Patricia Reinoso911946d2023-04-12 15:54:43 +000023 ACTIVITY_GET_MODEL_INFO,
Patricia Reinoso911946d2023-04-12 15:54:43 +000024 ACTIVITY_UPDATE_NS_STATE,
Patricia Reinoso52431352023-04-05 15:35:48 +000025)
26from osm_common.dataclasses.temporal_dataclasses import (
Patricia Reinoso911946d2023-04-12 15:54:43 +000027 ModelInfo,
Patricia Reinoso52431352023-04-05 15:35:48 +000028 NsInstantiateInput,
29 UpdateNsStateInput,
30 VduInstantiateInput,
31)
32from osm_lcm.temporal.juju_paas_activities import CharmInfoUtils
33
34
35class NsOperations:
36 def __init__(self, db):
37 self.db = db
38 self.logger = logging.getLogger(f"lcm.act.{self.__class__.__name__}")
39
40 # TODO: Change to a workflow OSM-990
41 @activity.defn(name=ACTIVITY_DEPLOY_NS)
42 async def deploy_ns(self, ns_instantiate_input: NsInstantiateInput) -> None:
43 vnfrs = self.db.get_list("vnfrs", {"nsr-id-ref": ns_instantiate_input.ns_uuid})
44 for vnfr in vnfrs:
45 await self.deploy_vnf(vnfr)
46
47 async def deploy_vnf(self, vnfr: dict):
48 vim_id = vnfr.get("vim-account-id")
Patricia Reinoso911946d2023-04-12 15:54:43 +000049 model_name = "model-name"
Patricia Reinoso52431352023-04-05 15:35:48 +000050 vnfd_id = vnfr["vnfd-id"]
51 vnfd = self.db.get_one("vnfds", {"_id": vnfd_id})
52 sw_image_descs = vnfd.get("sw-image-desc")
53 for vdu in vnfd.get("vdu"):
54 await self.deploy_vdu(vdu, sw_image_descs, vim_id, model_name)
55
56 async def deploy_vdu(
57 self, vdu: dict, sw_image_descs: str, vim_id: str, model_name: str
58 ) -> None:
59 vdu_info = CharmInfoUtils.get_charm_info(vdu, sw_image_descs)
60 vdu_instantiate_input = VduInstantiateInput(vim_id, model_name, vdu_info)
61 workflow_id = (
62 vdu_instantiate_input.model_name + vdu_instantiate_input.charm_info.app_name
63 )
64 self.logger.info(f"TODO: Start VDU Workflow {workflow_id}")
65
66 @activity.defn(name=ACTIVITY_CHECK_NS_INSTANTIATION_FINISHED)
67 async def check_ns_instantiate_finished(
68 self, ns_instantiate: NsInstantiateInput
69 ) -> None:
70 # TODO: Implement OSM-993
71 pass
72
73
74class NsDbActivity:
75
76 """Perform Database operations for NS accounts.
77
78 Args:
79 db (object): Data Access Object
80 """
81
82 def __init__(self, db):
83 self.db = db
84 self.logger = logging.getLogger(f"lcm.act.{self.__class__.__name__}")
85
Patricia Reinoso911946d2023-04-12 15:54:43 +000086 @activity.defn(name=ACTIVITY_GET_MODEL_INFO)
87 async def get_model_info(
88 self, ns_instantiate_input: NsInstantiateInput
89 ) -> ModelInfo:
90 """Returns a ModelInfo. Contains VIM ID and model name.
91
92 Collaborators:
93 DB Read: nsrs
94
95 Raises (Retryable):
96 DbException If the target DB record does not exist or DB is not reachable.
97
98 Activity Lifecycle:
99 This activity will not report a heartbeat due to its
100 short-running nature.
101
102 As this is a direct DB update, it is not recommended to have
103 any specific retry policy
104
105 """
106 ns_uuid = ns_instantiate_input.ns_uuid
107 nsr = self.db.get_one("nsrs", {"_id": ns_uuid})
108 vim_uuid = nsr.get("datacenter")
109 model_name = self._get_namespace(ns_uuid, vim_uuid)
110 return ModelInfo(vim_uuid, model_name)
111
Dario Faccin39301762023-04-17 16:56:37 +0200112 @staticmethod
113 def _get_namespace(ns_id: str, vim_id: str) -> str:
Patricia Reinoso52431352023-04-05 15:35:48 +0000114 """The NS namespace is the combination if the NS ID and the VIM ID."""
115 return ns_id[-12:] + "-" + vim_id[-12:]
116
Patricia Reinoso52431352023-04-05 15:35:48 +0000117 @activity.defn(name=ACTIVITY_UPDATE_NS_STATE)
118 async def update_ns_state(self, data: UpdateNsStateInput) -> None:
119 """
120 Changes the state of the NS itself.
121
122 Collaborators:
123 DB Write: nsrs
124
125 Raises (Retryable):
126 DbException If the target DB record does not exist or DB is not reachable.
127
128 Activity Lifecycle:
129 This activity will not report a heartbeat due to its
130 short-running nature.
131
132 As this is a direct DB update, it is not recommended to have
133 any specific retry policy
134 """
135 update_ns_state = {
136 "nsState": data.state.name,
137 # "errorDescription" : data.message,
138 "_admin.nsState": data.state.name,
139 "_admin.detailed-status": data.message,
140 "_admin.modified": time(),
141 }
142 self.db.set_one("nsrs", {"_id": data.ns_uuid}, update_ns_state)
143 self.logger.debug(f"Updated NS {data.ns_uuid} to {data.state.name}")