blob: ccaaf33a56ebcfdb9ebd8bd9b286da722acb7b80 [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
garciadeblasde963862025-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):
garciadeblasde963862025-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
garciadeblas0b7311d2025-07-08 10:44:07 +020054 self._kubeconfig = self.gitops_config.get("mgmtcluster_kubeconfig")
garciadeblas96b94f52024-07-08 16:18:21 +020055 self._kubectl = kubectl.Kubectl(config_file=self._kubeconfig)
garciadeblas0b7311d2025-07-08 10:44:07 +020056 self._repo_base_url = self.gitops_config.get("git_base_url")
57 self._repo_user = self.gitops_config.get("user")
garciadeblas1c62c112025-05-26 15:29:46 +020058 self._repo_fleet_url = self.gitops_config.get(
59 "fleet_repo_url", f"{self._repo_base_url}/{self._repo_user}/fleet-osm.git"
60 )
61 self._repo_sw_catalogs_url = self.gitops_config.get(
62 "sw_catalogs_repo_url",
63 f"{self._repo_base_url}/{self._repo_user}/sw-catalogs-osm.git",
64 )
garciadeblas3364c472024-09-11 14:30:26 +020065 self._pubkey = self.gitops_config["pubkey"]
garciadeblas0283bb22025-01-27 11:16:27 +010066 self._workflow_debug = str(self.gitops_config["workflow_debug"]).lower()
67 self._workflow_dry_run = str(self.gitops_config["workflow_dry_run"]).lower()
garciadeblas96b94f52024-07-08 16:18:21 +020068 self._workflows = {
69 "create_cluster": {
70 "workflow_function": self.create_cluster,
garciadeblas28bff0f2024-09-16 12:53:07 +020071 "clean_function": self.clean_items_cluster_create,
garciadeblas96b94f52024-07-08 16:18:21 +020072 },
73 "update_cluster": {
74 "workflow_function": self.update_cluster,
garciadeblas28bff0f2024-09-16 12:53:07 +020075 "clean_function": self.clean_items_cluster_update,
garciadeblas96b94f52024-07-08 16:18:21 +020076 },
77 "delete_cluster": {
78 "workflow_function": self.delete_cluster,
garciadeblas96b94f52024-07-08 16:18:21 +020079 },
80 "register_cluster": {
81 "workflow_function": self.register_cluster,
garciadeblasdde3a312024-09-17 13:25:06 +020082 "clean_function": self.clean_items_cluster_register,
garciadeblas96b94f52024-07-08 16:18:21 +020083 },
84 "deregister_cluster": {
85 "workflow_function": self.deregister_cluster,
garciadeblas91bb2c42024-11-12 11:17:12 +010086 "clean_function": self.clean_items_cluster_deregister,
garciadeblas96b94f52024-07-08 16:18:21 +020087 },
88 "create_profile": {
89 "workflow_function": self.create_profile,
garciadeblas96b94f52024-07-08 16:18:21 +020090 },
91 "delete_profile": {
92 "workflow_function": self.delete_profile,
garciadeblas96b94f52024-07-08 16:18:21 +020093 },
94 "attach_profile_to_cluster": {
95 "workflow_function": self.attach_profile_to_cluster,
garciadeblas96b94f52024-07-08 16:18:21 +020096 },
97 "detach_profile_from_cluster": {
98 "workflow_function": self.detach_profile_from_cluster,
garciadeblas96b94f52024-07-08 16:18:21 +020099 },
100 "create_oka": {
101 "workflow_function": self.create_oka,
garciadeblasc1c67892025-02-21 10:15:49 +0100102 "clean_function": self.clean_items_oka_create,
garciadeblas96b94f52024-07-08 16:18:21 +0200103 },
104 "update_oka": {
105 "workflow_function": self.update_oka,
garciadeblasc1c67892025-02-21 10:15:49 +0100106 "clean_function": self.clean_items_oka_update,
garciadeblas96b94f52024-07-08 16:18:21 +0200107 },
108 "delete_oka": {
109 "workflow_function": self.delete_oka,
garciadeblasc1c67892025-02-21 10:15:49 +0100110 "clean_function": self.clean_items_oka_delete,
garciadeblas96b94f52024-07-08 16:18:21 +0200111 },
112 "create_ksus": {
113 "workflow_function": self.create_ksus,
garciadeblasd8429852024-10-17 15:30:30 +0200114 "clean_function": self.clean_items_ksu_create,
garciadeblas96b94f52024-07-08 16:18:21 +0200115 },
116 "update_ksus": {
117 "workflow_function": self.update_ksus,
garciadeblasd8429852024-10-17 15:30:30 +0200118 "clean_function": self.clean_items_ksu_update,
garciadeblas96b94f52024-07-08 16:18:21 +0200119 },
120 "delete_ksus": {
121 "workflow_function": self.delete_ksus,
garciadeblas96b94f52024-07-08 16:18:21 +0200122 },
123 "clone_ksu": {
124 "workflow_function": self.clone_ksu,
garciadeblas96b94f52024-07-08 16:18:21 +0200125 },
126 "move_ksu": {
127 "workflow_function": self.move_ksu,
garciadeblas96b94f52024-07-08 16:18:21 +0200128 },
129 "create_cloud_credentials": {
130 "workflow_function": self.create_cloud_credentials,
garciadeblas28bff0f2024-09-16 12:53:07 +0200131 "clean_function": self.clean_items_cloud_credentials_create,
garciadeblas96b94f52024-07-08 16:18:21 +0200132 },
133 "update_cloud_credentials": {
134 "workflow_function": self.update_cloud_credentials,
garciadeblas28bff0f2024-09-16 12:53:07 +0200135 "clean_function": self.clean_items_cloud_credentials_update,
garciadeblas96b94f52024-07-08 16:18:21 +0200136 },
137 "delete_cloud_credentials": {
138 "workflow_function": self.delete_cloud_credentials,
garciadeblas96b94f52024-07-08 16:18:21 +0200139 },
140 "dummy_operation": {
141 "workflow_function": self.dummy_operation,
garciadeblas96b94f52024-07-08 16:18:21 +0200142 },
143 }
144
rshri932105f2024-07-05 15:11:55 +0000145 super().__init__(msg, self.logger)
146
garciadeblas96b94f52024-07-08 16:18:21 +0200147 @property
148 def kubeconfig(self):
149 return self._kubeconfig
150
151 # Imported methods
garciadeblasde963862025-05-26 15:14:47 +0200152 create_cloud_credentials = odu_vim_mgmt.create_cloud_credentials
153 update_cloud_credentials = odu_vim_mgmt.update_cloud_credentials
154 delete_cloud_credentials = odu_vim_mgmt.delete_cloud_credentials
155 clean_items_cloud_credentials_create = (
156 odu_vim_mgmt.clean_items_cloud_credentials_create
garciadeblas96b94f52024-07-08 16:18:21 +0200157 )
garciadeblasde963862025-05-26 15:14:47 +0200158 clean_items_cloud_credentials_update = (
159 odu_vim_mgmt.clean_items_cloud_credentials_update
garciadeblas96b94f52024-07-08 16:18:21 +0200160 )
garciadeblasde963862025-05-26 15:14:47 +0200161 create_cluster = odu_cluster_mgmt.create_cluster
162 update_cluster = odu_cluster_mgmt.update_cluster
163 delete_cluster = odu_cluster_mgmt.delete_cluster
164 register_cluster = odu_cluster_mgmt.register_cluster
165 deregister_cluster = odu_cluster_mgmt.deregister_cluster
166 clean_items_cluster_create = odu_cluster_mgmt.clean_items_cluster_create
167 clean_items_cluster_update = odu_cluster_mgmt.clean_items_cluster_update
168 clean_items_cluster_register = odu_cluster_mgmt.clean_items_cluster_register
169 clean_items_cluster_deregister = odu_cluster_mgmt.clean_items_cluster_deregister
170 get_cluster_credentials = odu_cluster_mgmt.get_cluster_credentials
171 create_ksus = odu_ksu.create_ksus
172 update_ksus = odu_ksu.update_ksus
173 delete_ksus = odu_ksu.delete_ksus
174 clone_ksu = odu_ksu.clone_ksu
175 move_ksu = odu_ksu.move_ksu
176 clean_items_ksu_create = odu_ksu.clean_items_ksu_create
177 clean_items_ksu_update = odu_ksu.clean_items_ksu_update
178 clean_items_ksu_delete = odu_ksu.clean_items_ksu_delete
179 create_oka = odu_oka.create_oka
180 update_oka = odu_oka.update_oka
181 delete_oka = odu_oka.delete_oka
182 clean_items_oka_create = odu_oka.clean_items_oka_create
183 clean_items_oka_update = odu_oka.clean_items_oka_update
184 clean_items_oka_delete = odu_oka.clean_items_oka_delete
185 create_profile = odu_profiles.create_profile
186 delete_profile = odu_profiles.delete_profile
187 attach_profile_to_cluster = odu_profiles.attach_profile_to_cluster
188 detach_profile_from_cluster = odu_profiles.detach_profile_from_cluster
189 check_workflow_status = workflows.check_workflow_status
190 readiness_loop = workflows.readiness_loop
191 render_jinja_template = odu_render.render_jinja_template
192 render_yaml_template = odu_render.render_yaml_template
193 create_secret = odu_common.create_secret
194 delete_secret = odu_common.delete_secret
garciadeblas96b94f52024-07-08 16:18:21 +0200195
196 async def launch_workflow(self, key, op_id, op_params, content):
rshri932105f2024-07-05 15:11:55 +0000197 self.logger.info(
garciadeblas96b94f52024-07-08 16:18:21 +0200198 f"Workflow is getting into launch. Key: {key}. Operation: {op_id}. Params: {op_params}. Content: {content}"
rshri932105f2024-07-05 15:11:55 +0000199 )
garciadeblas96b94f52024-07-08 16:18:21 +0200200 workflow_function = self._workflows[key]["workflow_function"]
201 self.logger.info("workflow function : {}".format(workflow_function))
garciadeblasdc805482025-02-04 16:08:51 +0100202 try:
203 result, workflow_name = await workflow_function(op_id, op_params, content)
204 return result, workflow_name
205 except Exception as e:
206 self.logger.error(f"Error launching workflow: {e}")
207 return False, str(e)
rshri932105f2024-07-05 15:11:55 +0000208
garciadeblas5359e992024-12-13 11:09:04 +0100209 async def dummy_clean_items(self, op_id, op_params, content):
garciadeblas98f9a3d2024-12-10 13:42:47 +0100210 self.logger.info(
garciadeblas5359e992024-12-13 11:09:04 +0100211 f"dummy_clean_items Enter. Operation {op_id}. Params: {op_params}"
garciadeblas98f9a3d2024-12-10 13:42:47 +0100212 )
garciadeblas5359e992024-12-13 11:09:04 +0100213 self.logger.debug(f"Content: {content}")
garciadeblas98f9a3d2024-12-10 13:42:47 +0100214 return True, "OK"
215
garciadeblas28bff0f2024-09-16 12:53:07 +0200216 async def clean_items_workflow(self, key, op_id, op_params, content):
217 self.logger.info(
218 f"Cleaning items created during workflow launch. Key: {key}. Operation: {op_id}. Params: {op_params}. Content: {content}"
219 )
garciadeblas98f9a3d2024-12-10 13:42:47 +0100220 clean_items_function = self._workflows[key].get(
221 "clean_function", self.dummy_clean_items
222 )
garciadeblas28bff0f2024-09-16 12:53:07 +0200223 self.logger.info("clean items function : {}".format(clean_items_function))
224 return await clean_items_function(op_id, op_params, content)
225
garciadeblas96b94f52024-07-08 16:18:21 +0200226 async def dummy_operation(self, op_id, op_params, content):
227 self.logger.info("Empty operation status Enter")
228 self.logger.info(f"Operation {op_id}. Params: {op_params}. Content: {content}")
229 return content["workflow_name"]
rshri932105f2024-07-05 15:11:55 +0000230
garciadeblas28bff0f2024-09-16 12:53:07 +0200231 async def clean_items(self, items):
garciadeblasc1c67892025-02-21 10:15:49 +0100232 # Delete pods
233 for pod in items.get("pods", []):
234 name = pod["name"]
235 namespace = pod["namespace"]
236 self.logger.info(f"Deleting pod {name} in namespace {namespace}")
237 self.logger.debug(f"Testing kubectl: {self._kubectl}")
238 self.logger.debug(
239 f"Testing kubectl configuration: {self._kubectl.configuration}"
240 )
241 self.logger.debug(
242 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
243 )
244 await self._kubectl.delete_pod(name, namespace)
garciadeblas28bff0f2024-09-16 12:53:07 +0200245 # Delete secrets
246 for secret in items.get("secrets", []):
247 name = secret["name"]
248 namespace = secret["namespace"]
249 self.logger.info(f"Deleting secret {name} in namespace {namespace}")
garciadeblas619a0a32025-02-06 13:34:37 +0100250 self.logger.debug(f"Testing kubectl: {self._kubectl}")
251 self.logger.debug(
252 f"Testing kubectl configuration: {self._kubectl.configuration}"
253 )
254 self.logger.debug(
255 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
256 )
garciadeblas28bff0f2024-09-16 12:53:07 +0200257 self.delete_secret(name, namespace)
258 # Delete pvcs
259 for pvc in items.get("pvcs", []):
260 name = pvc["name"]
261 namespace = pvc["namespace"]
262 self.logger.info(f"Deleting pvc {name} in namespace {namespace}")
garciadeblas619a0a32025-02-06 13:34:37 +0100263 self.logger.debug(f"Testing kubectl: {self._kubectl}")
264 self.logger.debug(
265 f"Testing kubectl configuration: {self._kubectl.configuration}"
266 )
267 self.logger.debug(
268 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
269 )
garciadeblas28bff0f2024-09-16 12:53:07 +0200270 await self._kubectl.delete_pvc(name, namespace)