blob: 92cfc4354f859fedd6b9f65650f18f3d5c7557b6 [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
garciadeblas96b94f52024-07-08 16:18:21 +020020
rshri932105f2024-07-05 15:11:55 +000021
22class OduWorkflow(LcmBase):
23 def __init__(self, msg, lcm_tasks, config):
24 """
25 Init, Connect to database, filesystem storage, and messaging
26 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
27 :return: None
28 """
29
garciadeblas40539872024-09-11 14:28:38 +020030 self.logger = logging.getLogger("lcm.gitops")
rshri932105f2024-07-05 15:11:55 +000031 self.lcm_tasks = lcm_tasks
32 self.logger.info("Msg: {} lcm_tasks: {} ".format(msg, lcm_tasks))
33
garciadeblas96b94f52024-07-08 16:18:21 +020034 # self._kubeconfig = kubeconfig # TODO: get it from config
garciadeblas3364c472024-09-11 14:30:26 +020035 self.gitops_config = config["gitops"]
36 self.logger.debug(f"Config: {self.gitops_config}")
garciadeblasb8976952024-10-18 11:36:15 +020037 self._odu_checkloop_retry_time = 15
garciadeblas72412282024-11-07 12:41:54 +010038 self._kubeconfig = self.gitops_config["mgmtcluster_kubeconfig"]
garciadeblas96b94f52024-07-08 16:18:21 +020039 self._kubectl = kubectl.Kubectl(config_file=self._kubeconfig)
garciadeblas3364c472024-09-11 14:30:26 +020040 self._repo_base_url = self.gitops_config["git_base_url"]
41 self._repo_user = self.gitops_config["user"]
42 self._pubkey = self.gitops_config["pubkey"]
garciadeblas326144e2025-01-27 11:16:27 +010043 self._workflow_debug = str(self.gitops_config["workflow_debug"]).lower()
44 self._workflow_dry_run = str(self.gitops_config["workflow_dry_run"]).lower()
garciadeblas96b94f52024-07-08 16:18:21 +020045 self._workflows = {
46 "create_cluster": {
47 "workflow_function": self.create_cluster,
garciadeblas28bff0f2024-09-16 12:53:07 +020048 "clean_function": self.clean_items_cluster_create,
garciadeblas96b94f52024-07-08 16:18:21 +020049 },
50 "update_cluster": {
51 "workflow_function": self.update_cluster,
garciadeblas28bff0f2024-09-16 12:53:07 +020052 "clean_function": self.clean_items_cluster_update,
garciadeblas96b94f52024-07-08 16:18:21 +020053 },
54 "delete_cluster": {
55 "workflow_function": self.delete_cluster,
garciadeblas96b94f52024-07-08 16:18:21 +020056 },
57 "register_cluster": {
58 "workflow_function": self.register_cluster,
garciadeblasdde3a312024-09-17 13:25:06 +020059 "clean_function": self.clean_items_cluster_register,
garciadeblas96b94f52024-07-08 16:18:21 +020060 },
61 "deregister_cluster": {
62 "workflow_function": self.deregister_cluster,
garciadeblas91bb2c42024-11-12 11:17:12 +010063 "clean_function": self.clean_items_cluster_deregister,
garciadeblas96b94f52024-07-08 16:18:21 +020064 },
65 "create_profile": {
66 "workflow_function": self.create_profile,
garciadeblas96b94f52024-07-08 16:18:21 +020067 },
68 "delete_profile": {
69 "workflow_function": self.delete_profile,
garciadeblas96b94f52024-07-08 16:18:21 +020070 },
71 "attach_profile_to_cluster": {
72 "workflow_function": self.attach_profile_to_cluster,
garciadeblas96b94f52024-07-08 16:18:21 +020073 },
74 "detach_profile_from_cluster": {
75 "workflow_function": self.detach_profile_from_cluster,
garciadeblas96b94f52024-07-08 16:18:21 +020076 },
77 "create_oka": {
78 "workflow_function": self.create_oka,
garciadeblasb23d2dc2025-02-21 10:15:49 +010079 "clean_function": self.clean_items_oka_create,
garciadeblas96b94f52024-07-08 16:18:21 +020080 },
81 "update_oka": {
82 "workflow_function": self.update_oka,
garciadeblasb23d2dc2025-02-21 10:15:49 +010083 "clean_function": self.clean_items_oka_update,
garciadeblas96b94f52024-07-08 16:18:21 +020084 },
85 "delete_oka": {
86 "workflow_function": self.delete_oka,
garciadeblasb23d2dc2025-02-21 10:15:49 +010087 "clean_function": self.clean_items_oka_delete,
garciadeblas96b94f52024-07-08 16:18:21 +020088 },
89 "create_ksus": {
90 "workflow_function": self.create_ksus,
garciadeblasd8429852024-10-17 15:30:30 +020091 "clean_function": self.clean_items_ksu_create,
garciadeblas96b94f52024-07-08 16:18:21 +020092 },
93 "update_ksus": {
94 "workflow_function": self.update_ksus,
garciadeblasd8429852024-10-17 15:30:30 +020095 "clean_function": self.clean_items_ksu_update,
garciadeblas96b94f52024-07-08 16:18:21 +020096 },
97 "delete_ksus": {
98 "workflow_function": self.delete_ksus,
garciadeblas96b94f52024-07-08 16:18:21 +020099 },
100 "clone_ksu": {
101 "workflow_function": self.clone_ksu,
garciadeblas96b94f52024-07-08 16:18:21 +0200102 },
103 "move_ksu": {
104 "workflow_function": self.move_ksu,
garciadeblas96b94f52024-07-08 16:18:21 +0200105 },
106 "create_cloud_credentials": {
107 "workflow_function": self.create_cloud_credentials,
garciadeblas28bff0f2024-09-16 12:53:07 +0200108 "clean_function": self.clean_items_cloud_credentials_create,
garciadeblas96b94f52024-07-08 16:18:21 +0200109 },
110 "update_cloud_credentials": {
111 "workflow_function": self.update_cloud_credentials,
garciadeblas28bff0f2024-09-16 12:53:07 +0200112 "clean_function": self.clean_items_cloud_credentials_update,
garciadeblas96b94f52024-07-08 16:18:21 +0200113 },
114 "delete_cloud_credentials": {
115 "workflow_function": self.delete_cloud_credentials,
garciadeblas96b94f52024-07-08 16:18:21 +0200116 },
117 "dummy_operation": {
118 "workflow_function": self.dummy_operation,
garciadeblas96b94f52024-07-08 16:18:21 +0200119 },
120 }
121
rshri932105f2024-07-05 15:11:55 +0000122 super().__init__(msg, self.logger)
123
garciadeblas96b94f52024-07-08 16:18:21 +0200124 @property
125 def kubeconfig(self):
126 return self._kubeconfig
127
128 # Imported methods
129 from osm_lcm.odu_libs.vim_mgmt import (
130 create_cloud_credentials,
131 update_cloud_credentials,
132 delete_cloud_credentials,
garciadeblas28bff0f2024-09-16 12:53:07 +0200133 clean_items_cloud_credentials_create,
134 clean_items_cloud_credentials_update,
garciadeblas96b94f52024-07-08 16:18:21 +0200135 )
136 from osm_lcm.odu_libs.cluster_mgmt import (
137 create_cluster,
138 update_cluster,
139 delete_cluster,
140 register_cluster,
141 deregister_cluster,
garciadeblas28bff0f2024-09-16 12:53:07 +0200142 clean_items_cluster_create,
143 clean_items_cluster_update,
garciadeblasdde3a312024-09-17 13:25:06 +0200144 clean_items_cluster_register,
garciadeblas91bb2c42024-11-12 11:17:12 +0100145 clean_items_cluster_deregister,
garciadeblas96b94f52024-07-08 16:18:21 +0200146 get_cluster_credentials,
147 )
148 from osm_lcm.odu_libs.ksu import (
149 create_ksus,
150 update_ksus,
151 delete_ksus,
152 clone_ksu,
153 move_ksu,
garciadeblasd8429852024-10-17 15:30:30 +0200154 clean_items_ksu_create,
155 clean_items_ksu_update,
garciadeblasb23d2dc2025-02-21 10:15:49 +0100156 clean_items_ksu_delete,
garciadeblas96b94f52024-07-08 16:18:21 +0200157 )
158 from osm_lcm.odu_libs.oka import (
159 create_oka,
160 update_oka,
161 delete_oka,
garciadeblasb23d2dc2025-02-21 10:15:49 +0100162 clean_items_oka_create,
163 clean_items_oka_update,
164 clean_items_oka_delete,
garciadeblas96b94f52024-07-08 16:18:21 +0200165 )
166 from osm_lcm.odu_libs.profiles import (
167 create_profile,
168 delete_profile,
169 attach_profile_to_cluster,
170 detach_profile_from_cluster,
garciadeblas96b94f52024-07-08 16:18:21 +0200171 )
172 from osm_lcm.odu_libs.workflows import (
173 check_workflow_status,
garciadeblas40811852024-10-22 11:35:17 +0200174 readiness_loop,
garciadeblas96b94f52024-07-08 16:18:21 +0200175 )
176 from osm_lcm.odu_libs.render import (
177 render_jinja_template,
178 render_yaml_template,
179 )
garciadeblas28bff0f2024-09-16 12:53:07 +0200180 from osm_lcm.odu_libs.common import (
181 create_secret,
182 delete_secret,
183 )
garciadeblas96b94f52024-07-08 16:18:21 +0200184
185 async def launch_workflow(self, key, op_id, op_params, content):
rshri932105f2024-07-05 15:11:55 +0000186 self.logger.info(
garciadeblas96b94f52024-07-08 16:18:21 +0200187 f"Workflow is getting into launch. Key: {key}. Operation: {op_id}. Params: {op_params}. Content: {content}"
rshri932105f2024-07-05 15:11:55 +0000188 )
garciadeblas96b94f52024-07-08 16:18:21 +0200189 workflow_function = self._workflows[key]["workflow_function"]
190 self.logger.info("workflow function : {}".format(workflow_function))
garciadeblas41859ce2025-02-04 16:08:51 +0100191 try:
192 result, workflow_name = await workflow_function(op_id, op_params, content)
193 return result, workflow_name
194 except Exception as e:
195 self.logger.error(f"Error launching workflow: {e}")
196 return False, str(e)
rshri932105f2024-07-05 15:11:55 +0000197
garciadeblas5359e992024-12-13 11:09:04 +0100198 async def dummy_clean_items(self, op_id, op_params, content):
garciadeblas98f9a3d2024-12-10 13:42:47 +0100199 self.logger.info(
garciadeblas5359e992024-12-13 11:09:04 +0100200 f"dummy_clean_items Enter. Operation {op_id}. Params: {op_params}"
garciadeblas98f9a3d2024-12-10 13:42:47 +0100201 )
garciadeblas5359e992024-12-13 11:09:04 +0100202 self.logger.debug(f"Content: {content}")
garciadeblas98f9a3d2024-12-10 13:42:47 +0100203 return True, "OK"
204
garciadeblas28bff0f2024-09-16 12:53:07 +0200205 async def clean_items_workflow(self, key, op_id, op_params, content):
206 self.logger.info(
207 f"Cleaning items created during workflow launch. Key: {key}. Operation: {op_id}. Params: {op_params}. Content: {content}"
208 )
garciadeblas98f9a3d2024-12-10 13:42:47 +0100209 clean_items_function = self._workflows[key].get(
210 "clean_function", self.dummy_clean_items
211 )
garciadeblas28bff0f2024-09-16 12:53:07 +0200212 self.logger.info("clean items function : {}".format(clean_items_function))
213 return await clean_items_function(op_id, op_params, content)
214
garciadeblas96b94f52024-07-08 16:18:21 +0200215 async def dummy_operation(self, op_id, op_params, content):
216 self.logger.info("Empty operation status Enter")
217 self.logger.info(f"Operation {op_id}. Params: {op_params}. Content: {content}")
218 return content["workflow_name"]
rshri932105f2024-07-05 15:11:55 +0000219
garciadeblas28bff0f2024-09-16 12:53:07 +0200220 async def clean_items(self, items):
garciadeblasb23d2dc2025-02-21 10:15:49 +0100221 # Delete pods
222 for pod in items.get("pods", []):
223 name = pod["name"]
224 namespace = pod["namespace"]
225 self.logger.info(f"Deleting pod {name} in namespace {namespace}")
226 self.logger.debug(f"Testing kubectl: {self._kubectl}")
227 self.logger.debug(
228 f"Testing kubectl configuration: {self._kubectl.configuration}"
229 )
230 self.logger.debug(
231 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
232 )
233 await self._kubectl.delete_pod(name, namespace)
garciadeblas28bff0f2024-09-16 12:53:07 +0200234 # Delete secrets
235 for secret in items.get("secrets", []):
236 name = secret["name"]
237 namespace = secret["namespace"]
238 self.logger.info(f"Deleting secret {name} in namespace {namespace}")
garciadeblas6d8acf32025-02-06 13:34:37 +0100239 self.logger.debug(f"Testing kubectl: {self._kubectl}")
240 self.logger.debug(
241 f"Testing kubectl configuration: {self._kubectl.configuration}"
242 )
243 self.logger.debug(
244 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
245 )
garciadeblas28bff0f2024-09-16 12:53:07 +0200246 self.delete_secret(name, namespace)
247 # Delete pvcs
248 for pvc in items.get("pvcs", []):
249 name = pvc["name"]
250 namespace = pvc["namespace"]
251 self.logger.info(f"Deleting pvc {name} in namespace {namespace}")
garciadeblas6d8acf32025-02-06 13:34:37 +0100252 self.logger.debug(f"Testing kubectl: {self._kubectl}")
253 self.logger.debug(
254 f"Testing kubectl configuration: {self._kubectl.configuration}"
255 )
256 self.logger.debug(
257 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
258 )
garciadeblas28bff0f2024-09-16 12:53:07 +0200259 await self._kubectl.delete_pvc(name, namespace)