blob: 9516a704ba1fcc325f0254d8c8de66078dedd243 [file] [log] [blame]
garciadeblas96b94f52024-07-08 16:18:21 +02001#######################################################################################
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at
rshri932105f2024-07-05 15:11:55 +00005#
garciadeblas96b94f52024-07-08 16:18:21 +02006# http://www.apache.org/licenses/LICENSE-2.0
rshri932105f2024-07-05 15:11:55 +00007#
8# Unless required by applicable law or agreed to in writing, software
garciadeblas96b94f52024-07-08 16:18:21 +02009# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
11# implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14#######################################################################################
rshri932105f2024-07-05 15:11:55 +000015
16
17import logging
18from osm_lcm.lcm_utils import LcmBase
almagiacdd20ae2024-12-13 09:45:45 +010019from osm_lcm.n2vc import kubectl
garciadeblasc8d217d2025-05-26 15:14:47 +020020from osm_lcm.odu_libs import (
21 vim_mgmt as odu_vim_mgmt,
22 cluster_mgmt as odu_cluster_mgmt,
23 ksu as odu_ksu,
24 oka as odu_oka,
25 profiles as odu_profiles,
26 workflows,
27 render as odu_render,
28 common as odu_common,
29)
garciadeblas96b94f52024-07-08 16:18:21 +020030
rshri932105f2024-07-05 15:11:55 +000031
32class OduWorkflow(LcmBase):
garciadeblasc8d217d2025-05-26 15:14:47 +020033 """
34 Class to manage the workflows for the OSM Deployment Unit (ODU).
35 This class is responsible for executing various workflows related to
36 cluster management, profile management, and other operations.
37 """
38
rshri932105f2024-07-05 15:11:55 +000039 def __init__(self, msg, lcm_tasks, config):
40 """
41 Init, Connect to database, filesystem storage, and messaging
42 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
43 :return: None
44 """
45
garciadeblas40539872024-09-11 14:28:38 +020046 self.logger = logging.getLogger("lcm.gitops")
rshri932105f2024-07-05 15:11:55 +000047 self.lcm_tasks = lcm_tasks
48 self.logger.info("Msg: {} lcm_tasks: {} ".format(msg, lcm_tasks))
49
garciadeblas96b94f52024-07-08 16:18:21 +020050 # self._kubeconfig = kubeconfig # TODO: get it from config
garciadeblas3364c472024-09-11 14:30:26 +020051 self.gitops_config = config["gitops"]
52 self.logger.debug(f"Config: {self.gitops_config}")
garciadeblasb8976952024-10-18 11:36:15 +020053 self._odu_checkloop_retry_time = 15
garciadeblas72412282024-11-07 12:41:54 +010054 self._kubeconfig = self.gitops_config["mgmtcluster_kubeconfig"]
garciadeblas96b94f52024-07-08 16:18:21 +020055 self._kubectl = kubectl.Kubectl(config_file=self._kubeconfig)
garciadeblas3364c472024-09-11 14:30:26 +020056 self._repo_base_url = self.gitops_config["git_base_url"]
57 self._repo_user = self.gitops_config["user"]
58 self._pubkey = self.gitops_config["pubkey"]
garciadeblas326144e2025-01-27 11:16:27 +010059 self._workflow_debug = str(self.gitops_config["workflow_debug"]).lower()
60 self._workflow_dry_run = str(self.gitops_config["workflow_dry_run"]).lower()
garciadeblas96b94f52024-07-08 16:18:21 +020061 self._workflows = {
62 "create_cluster": {
63 "workflow_function": self.create_cluster,
garciadeblas28bff0f2024-09-16 12:53:07 +020064 "clean_function": self.clean_items_cluster_create,
garciadeblas96b94f52024-07-08 16:18:21 +020065 },
66 "update_cluster": {
67 "workflow_function": self.update_cluster,
garciadeblas28bff0f2024-09-16 12:53:07 +020068 "clean_function": self.clean_items_cluster_update,
garciadeblas96b94f52024-07-08 16:18:21 +020069 },
70 "delete_cluster": {
71 "workflow_function": self.delete_cluster,
garciadeblas96b94f52024-07-08 16:18:21 +020072 },
73 "register_cluster": {
74 "workflow_function": self.register_cluster,
garciadeblasdde3a312024-09-17 13:25:06 +020075 "clean_function": self.clean_items_cluster_register,
garciadeblas96b94f52024-07-08 16:18:21 +020076 },
77 "deregister_cluster": {
78 "workflow_function": self.deregister_cluster,
garciadeblas91bb2c42024-11-12 11:17:12 +010079 "clean_function": self.clean_items_cluster_deregister,
garciadeblas96b94f52024-07-08 16:18:21 +020080 },
81 "create_profile": {
82 "workflow_function": self.create_profile,
garciadeblas96b94f52024-07-08 16:18:21 +020083 },
84 "delete_profile": {
85 "workflow_function": self.delete_profile,
garciadeblas96b94f52024-07-08 16:18:21 +020086 },
87 "attach_profile_to_cluster": {
88 "workflow_function": self.attach_profile_to_cluster,
garciadeblas96b94f52024-07-08 16:18:21 +020089 },
90 "detach_profile_from_cluster": {
91 "workflow_function": self.detach_profile_from_cluster,
garciadeblas96b94f52024-07-08 16:18:21 +020092 },
93 "create_oka": {
94 "workflow_function": self.create_oka,
garciadeblasb23d2dc2025-02-21 10:15:49 +010095 "clean_function": self.clean_items_oka_create,
garciadeblas96b94f52024-07-08 16:18:21 +020096 },
97 "update_oka": {
98 "workflow_function": self.update_oka,
garciadeblasb23d2dc2025-02-21 10:15:49 +010099 "clean_function": self.clean_items_oka_update,
garciadeblas96b94f52024-07-08 16:18:21 +0200100 },
101 "delete_oka": {
102 "workflow_function": self.delete_oka,
garciadeblasb23d2dc2025-02-21 10:15:49 +0100103 "clean_function": self.clean_items_oka_delete,
garciadeblas96b94f52024-07-08 16:18:21 +0200104 },
105 "create_ksus": {
106 "workflow_function": self.create_ksus,
garciadeblasd8429852024-10-17 15:30:30 +0200107 "clean_function": self.clean_items_ksu_create,
garciadeblas96b94f52024-07-08 16:18:21 +0200108 },
109 "update_ksus": {
110 "workflow_function": self.update_ksus,
garciadeblasd8429852024-10-17 15:30:30 +0200111 "clean_function": self.clean_items_ksu_update,
garciadeblas96b94f52024-07-08 16:18:21 +0200112 },
113 "delete_ksus": {
114 "workflow_function": self.delete_ksus,
garciadeblas96b94f52024-07-08 16:18:21 +0200115 },
116 "clone_ksu": {
117 "workflow_function": self.clone_ksu,
garciadeblas96b94f52024-07-08 16:18:21 +0200118 },
119 "move_ksu": {
120 "workflow_function": self.move_ksu,
garciadeblas96b94f52024-07-08 16:18:21 +0200121 },
122 "create_cloud_credentials": {
123 "workflow_function": self.create_cloud_credentials,
garciadeblas28bff0f2024-09-16 12:53:07 +0200124 "clean_function": self.clean_items_cloud_credentials_create,
garciadeblas96b94f52024-07-08 16:18:21 +0200125 },
126 "update_cloud_credentials": {
127 "workflow_function": self.update_cloud_credentials,
garciadeblas28bff0f2024-09-16 12:53:07 +0200128 "clean_function": self.clean_items_cloud_credentials_update,
garciadeblas96b94f52024-07-08 16:18:21 +0200129 },
130 "delete_cloud_credentials": {
131 "workflow_function": self.delete_cloud_credentials,
garciadeblas96b94f52024-07-08 16:18:21 +0200132 },
133 "dummy_operation": {
134 "workflow_function": self.dummy_operation,
garciadeblas96b94f52024-07-08 16:18:21 +0200135 },
136 }
137
rshri932105f2024-07-05 15:11:55 +0000138 super().__init__(msg, self.logger)
139
garciadeblas96b94f52024-07-08 16:18:21 +0200140 @property
141 def kubeconfig(self):
142 return self._kubeconfig
143
144 # Imported methods
garciadeblasc8d217d2025-05-26 15:14:47 +0200145 create_cloud_credentials = odu_vim_mgmt.create_cloud_credentials
146 update_cloud_credentials = odu_vim_mgmt.update_cloud_credentials
147 delete_cloud_credentials = odu_vim_mgmt.delete_cloud_credentials
148 clean_items_cloud_credentials_create = (
149 odu_vim_mgmt.clean_items_cloud_credentials_create
garciadeblas96b94f52024-07-08 16:18:21 +0200150 )
garciadeblasc8d217d2025-05-26 15:14:47 +0200151 clean_items_cloud_credentials_update = (
152 odu_vim_mgmt.clean_items_cloud_credentials_update
garciadeblas96b94f52024-07-08 16:18:21 +0200153 )
garciadeblasc8d217d2025-05-26 15:14:47 +0200154 create_cluster = odu_cluster_mgmt.create_cluster
155 update_cluster = odu_cluster_mgmt.update_cluster
156 delete_cluster = odu_cluster_mgmt.delete_cluster
157 register_cluster = odu_cluster_mgmt.register_cluster
158 deregister_cluster = odu_cluster_mgmt.deregister_cluster
159 clean_items_cluster_create = odu_cluster_mgmt.clean_items_cluster_create
160 clean_items_cluster_update = odu_cluster_mgmt.clean_items_cluster_update
161 clean_items_cluster_register = odu_cluster_mgmt.clean_items_cluster_register
162 clean_items_cluster_deregister = odu_cluster_mgmt.clean_items_cluster_deregister
163 get_cluster_credentials = odu_cluster_mgmt.get_cluster_credentials
164 create_ksus = odu_ksu.create_ksus
165 update_ksus = odu_ksu.update_ksus
166 delete_ksus = odu_ksu.delete_ksus
167 clone_ksu = odu_ksu.clone_ksu
168 move_ksu = odu_ksu.move_ksu
169 clean_items_ksu_create = odu_ksu.clean_items_ksu_create
170 clean_items_ksu_update = odu_ksu.clean_items_ksu_update
171 clean_items_ksu_delete = odu_ksu.clean_items_ksu_delete
172 create_oka = odu_oka.create_oka
173 update_oka = odu_oka.update_oka
174 delete_oka = odu_oka.delete_oka
175 clean_items_oka_create = odu_oka.clean_items_oka_create
176 clean_items_oka_update = odu_oka.clean_items_oka_update
177 clean_items_oka_delete = odu_oka.clean_items_oka_delete
178 create_profile = odu_profiles.create_profile
179 delete_profile = odu_profiles.delete_profile
180 attach_profile_to_cluster = odu_profiles.attach_profile_to_cluster
181 detach_profile_from_cluster = odu_profiles.detach_profile_from_cluster
182 check_workflow_status = workflows.check_workflow_status
183 readiness_loop = workflows.readiness_loop
184 render_jinja_template = odu_render.render_jinja_template
185 render_yaml_template = odu_render.render_yaml_template
186 create_secret = odu_common.create_secret
187 delete_secret = odu_common.delete_secret
garciadeblas96b94f52024-07-08 16:18:21 +0200188
189 async def launch_workflow(self, key, op_id, op_params, content):
rshri932105f2024-07-05 15:11:55 +0000190 self.logger.info(
garciadeblas96b94f52024-07-08 16:18:21 +0200191 f"Workflow is getting into launch. Key: {key}. Operation: {op_id}. Params: {op_params}. Content: {content}"
rshri932105f2024-07-05 15:11:55 +0000192 )
garciadeblas96b94f52024-07-08 16:18:21 +0200193 workflow_function = self._workflows[key]["workflow_function"]
194 self.logger.info("workflow function : {}".format(workflow_function))
garciadeblas41859ce2025-02-04 16:08:51 +0100195 try:
196 result, workflow_name = await workflow_function(op_id, op_params, content)
197 return result, workflow_name
198 except Exception as e:
199 self.logger.error(f"Error launching workflow: {e}")
200 return False, str(e)
rshri932105f2024-07-05 15:11:55 +0000201
garciadeblas5359e992024-12-13 11:09:04 +0100202 async def dummy_clean_items(self, op_id, op_params, content):
garciadeblas98f9a3d2024-12-10 13:42:47 +0100203 self.logger.info(
garciadeblas5359e992024-12-13 11:09:04 +0100204 f"dummy_clean_items Enter. Operation {op_id}. Params: {op_params}"
garciadeblas98f9a3d2024-12-10 13:42:47 +0100205 )
garciadeblas5359e992024-12-13 11:09:04 +0100206 self.logger.debug(f"Content: {content}")
garciadeblas98f9a3d2024-12-10 13:42:47 +0100207 return True, "OK"
208
garciadeblas28bff0f2024-09-16 12:53:07 +0200209 async def clean_items_workflow(self, key, op_id, op_params, content):
210 self.logger.info(
211 f"Cleaning items created during workflow launch. Key: {key}. Operation: {op_id}. Params: {op_params}. Content: {content}"
212 )
garciadeblas98f9a3d2024-12-10 13:42:47 +0100213 clean_items_function = self._workflows[key].get(
214 "clean_function", self.dummy_clean_items
215 )
garciadeblas28bff0f2024-09-16 12:53:07 +0200216 self.logger.info("clean items function : {}".format(clean_items_function))
217 return await clean_items_function(op_id, op_params, content)
218
garciadeblas96b94f52024-07-08 16:18:21 +0200219 async def dummy_operation(self, op_id, op_params, content):
220 self.logger.info("Empty operation status Enter")
221 self.logger.info(f"Operation {op_id}. Params: {op_params}. Content: {content}")
222 return content["workflow_name"]
rshri932105f2024-07-05 15:11:55 +0000223
garciadeblas28bff0f2024-09-16 12:53:07 +0200224 async def clean_items(self, items):
garciadeblasb23d2dc2025-02-21 10:15:49 +0100225 # Delete pods
226 for pod in items.get("pods", []):
227 name = pod["name"]
228 namespace = pod["namespace"]
229 self.logger.info(f"Deleting pod {name} in namespace {namespace}")
230 self.logger.debug(f"Testing kubectl: {self._kubectl}")
231 self.logger.debug(
232 f"Testing kubectl configuration: {self._kubectl.configuration}"
233 )
234 self.logger.debug(
235 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
236 )
237 await self._kubectl.delete_pod(name, namespace)
garciadeblas28bff0f2024-09-16 12:53:07 +0200238 # Delete secrets
239 for secret in items.get("secrets", []):
240 name = secret["name"]
241 namespace = secret["namespace"]
242 self.logger.info(f"Deleting secret {name} in namespace {namespace}")
garciadeblas6d8acf32025-02-06 13:34:37 +0100243 self.logger.debug(f"Testing kubectl: {self._kubectl}")
244 self.logger.debug(
245 f"Testing kubectl configuration: {self._kubectl.configuration}"
246 )
247 self.logger.debug(
248 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
249 )
garciadeblas28bff0f2024-09-16 12:53:07 +0200250 self.delete_secret(name, namespace)
251 # Delete pvcs
252 for pvc in items.get("pvcs", []):
253 name = pvc["name"]
254 namespace = pvc["namespace"]
255 self.logger.info(f"Deleting pvc {name} in namespace {namespace}")
garciadeblas6d8acf32025-02-06 13:34:37 +0100256 self.logger.debug(f"Testing kubectl: {self._kubectl}")
257 self.logger.debug(
258 f"Testing kubectl configuration: {self._kubectl.configuration}"
259 )
260 self.logger.debug(
261 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
262 )
garciadeblas28bff0f2024-09-16 12:53:07 +0200263 await self._kubectl.delete_pvc(name, namespace)