blob: b4a24d6251aeca545ae59f3f5afec0dab7facf7c [file] [log] [blame]
garciadeblas96b94f52024-07-08 16:18:21 +02001#######################################################################################
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#######################################################################################
17
18
garciadeblas96b94f52024-07-08 16:18:21 +020019import yaml
20import base64
rshrif8911b92025-06-11 18:19:07 +000021import json
garciadeblas96b94f52024-07-08 16:18:21 +020022
23
24def gather_age_key(cluster):
25 pubkey = cluster.get("age_pubkey")
26 privkey = cluster.get("age_privkey")
27 # return both public and private key
28 return pubkey, privkey
29
30
garciadeblasdde3a312024-09-17 13:25:06 +020031async def create_cluster(self, op_id, op_params, content):
garciadeblas9e532812024-10-22 14:04:36 +020032 self.logger.info(f"create_cluster Enter. Operation {op_id}. Params: {op_params}")
33 # self.logger.debug(f"Content: {content}")
garciadeblas96b94f52024-07-08 16:18:21 +020034
35 db_cluster = content["cluster"]
36 db_vim_account = content["vim_account"]
37
garciadeblas96b94f52024-07-08 16:18:21 +020038 workflow_template = "launcher-create-crossplane-cluster-and-bootstrap.j2"
39 workflow_name = f"create-cluster-{db_cluster['_id']}"
garciadeblas96b94f52024-07-08 16:18:21 +020040 cluster_name = db_cluster["git_name"].lower()
41
garciadeblas96b94f52024-07-08 16:18:21 +020042 # Get age key
43 public_key_new_cluster, private_key_new_cluster = gather_age_key(db_cluster)
garciadeblas41859ce2025-02-04 16:08:51 +010044 # self.logger.debug(f"public_key_new_cluster={public_key_new_cluster}")
45 # self.logger.debug(f"private_key_new_cluster={private_key_new_cluster}")
garciadeblas96b94f52024-07-08 16:18:21 +020046
47 # Test kubectl connection
garciadeblas6d8acf32025-02-06 13:34:37 +010048 self.logger.debug(f"Testing kubectl: {self._kubectl}")
49 self.logger.debug(f"Testing kubectl configuration: {self._kubectl.configuration}")
50 self.logger.debug(
51 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
52 )
garciadeblas96b94f52024-07-08 16:18:21 +020053 self.logger.debug(self._kubectl._get_kubectl_version())
54
garciadeblasdde3a312024-09-17 13:25:06 +020055 # Create temporal secret with agekey
garciadeblas96b94f52024-07-08 16:18:21 +020056 secret_name = f"secret-age-{cluster_name}"
57 secret_namespace = "osm-workflows"
58 secret_key = "agekey"
59 secret_value = private_key_new_cluster
garciadeblasadb81e82024-11-08 01:11:46 +010060 try:
garciadeblas6d8acf32025-02-06 13:34:37 +010061 self.logger.debug(f"Testing kubectl: {self._kubectl}")
62 self.logger.debug(
63 f"Testing kubectl configuration: {self._kubectl.configuration}"
64 )
65 self.logger.debug(
66 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
67 )
garciadeblasadb81e82024-11-08 01:11:46 +010068 await self.create_secret(
69 secret_name,
70 secret_namespace,
71 secret_key,
72 secret_value,
73 )
74 except Exception as e:
75 self.logger.info(f"Cannot create secret {secret_name}: {e}")
garciadeblas61a4c692025-07-17 13:04:13 +020076 return False, f"Cannot create secret {secret_name}: {e}", None
garciadeblas96b94f52024-07-08 16:18:21 +020077
78 # Additional params for the workflow
79 cluster_kustomization_name = cluster_name
80 osm_project_name = "osm_admin" # TODO: get project name from content
garciadeblasdde3a312024-09-17 13:25:06 +020081 vim_account_id = db_cluster["vim_account"]
82 providerconfig_name = f"{vim_account_id}-config"
83 vim_type = db_vim_account["vim_type"]
garciadeblas753b1e32024-11-06 12:56:33 +010084 if db_cluster.get("bootstrap", True):
85 skip_bootstrap = "false"
86 else:
87 skip_bootstrap = "true"
garciadeblasdde3a312024-09-17 13:25:06 +020088 if vim_type == "azure":
89 cluster_type = "aks"
90 elif vim_type == "aws":
91 cluster_type = "eks"
92 elif vim_type == "gcp":
93 cluster_type = "gke"
garciadeblas96b94f52024-07-08 16:18:21 +020094 else:
garciadeblasdde3a312024-09-17 13:25:06 +020095 raise Exception("Not suitable VIM account to register cluster")
garciadeblas96b94f52024-07-08 16:18:21 +020096
rshrif8911b92025-06-11 18:19:07 +000097 # Create configmap for subnet
98 configmap_name = None
99 data = {}
100 private_subnets = op_params.get("private_subnet")
101 public_subnets = op_params.get("public_subnet")
102 if private_subnets or public_subnets:
103 configmap_name = f"{cluster_name}-parameters"
104 configmap_namespace = "managed-resources"
105 data["private_subnets"] = f"{json.dumps(private_subnets)}"
106 data["public_subnets"] = f"{json.dumps(public_subnets)}"
107 try:
108 self.logger.debug(f"Testing kubectl: {self._kubectl}")
109 self.logger.debug(
110 f"Testing kubectl configuration: {self._kubectl.configuration}"
111 )
112 self.logger.debug(
113 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
114 )
115 await self.create_configmap(
116 configmap_name,
117 configmap_namespace,
118 data,
119 )
120 except Exception as e:
121 self.logger.info(f"Cannot create configmap {configmap_name}: {e}")
garciadeblas61a4c692025-07-17 13:04:13 +0200122 return False, f"Cannot create configmap {configmap_name}: {e}", None
rshrif8911b92025-06-11 18:19:07 +0000123
garciadeblas96b94f52024-07-08 16:18:21 +0200124 # Render workflow
125 # workflow_kwargs = {
garciadeblas56c3aa82025-05-26 15:29:46 +0200126 # "git_fleet_url": self._repo_fleet_url,
127 # "git_sw_catalogs_url": self._repo_sw_catalogs_url,
garciadeblas96b94f52024-07-08 16:18:21 +0200128 # }
129 # manifest = self.render_jinja_template(
130 # workflow_template,
131 # output_file=None,
132 # **workflow_kwargs
133 # )
134 manifest = self.render_jinja_template(
135 workflow_template,
136 output_file=None,
137 workflow_name=workflow_name,
garciadeblas56c3aa82025-05-26 15:29:46 +0200138 git_fleet_url=self._repo_fleet_url,
139 git_sw_catalogs_url=self._repo_sw_catalogs_url,
garciadeblas96b94f52024-07-08 16:18:21 +0200140 cluster_name=cluster_name,
141 cluster_type=cluster_type,
142 cluster_kustomization_name=cluster_kustomization_name,
143 providerconfig_name=providerconfig_name,
144 public_key_mgmt=self._pubkey,
145 public_key_new_cluster=public_key_new_cluster,
146 secret_name_private_key_new_cluster=secret_name,
rshrif8911b92025-06-11 18:19:07 +0000147 vm_size=db_cluster.get("node_size", "default"),
148 node_count=db_cluster.get("node_count", "default"),
garciadeblas96b94f52024-07-08 16:18:21 +0200149 k8s_version=db_cluster["k8s_version"],
150 cluster_location=db_cluster["region_name"],
rshrif8911b92025-06-11 18:19:07 +0000151 configmap_name=configmap_name if configmap_name else "default",
152 cluster_iam_role=db_cluster.get("iam_role", "default"),
153 cluster_private_subnets_id=db_cluster.get("private_subnet", "default"),
154 cluster_public_subnets_id=db_cluster.get("public_subnet", "default"),
garciadeblas96b94f52024-07-08 16:18:21 +0200155 osm_project_name=osm_project_name,
garciadeblasd84808e2024-11-18 17:10:00 +0100156 rg_name=db_cluster.get("resource_group", "''"),
157 preemptible_nodes=db_cluster.get("preemptible_nodes", "false"),
garciadeblas753b1e32024-11-06 12:56:33 +0100158 skip_bootstrap=skip_bootstrap,
garciadeblas96b94f52024-07-08 16:18:21 +0200159 workflow_debug=self._workflow_debug,
160 workflow_dry_run=self._workflow_dry_run,
161 )
garciadeblasf6dc6042026-02-04 17:40:30 +0100162 # self.logger.debug(f"Workflow manifest: {manifest}")
garciadeblas96b94f52024-07-08 16:18:21 +0200163
164 # Submit workflow
garciadeblas6d8acf32025-02-06 13:34:37 +0100165 self.logger.debug(f"Testing kubectl: {self._kubectl}")
166 self.logger.debug(f"Testing kubectl configuration: {self._kubectl.configuration}")
167 self.logger.debug(
168 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
169 )
garciadeblas96b94f52024-07-08 16:18:21 +0200170 self._kubectl.create_generic_object(
171 namespace="osm-workflows",
172 manifest_dict=yaml.safe_load(manifest),
173 api_group="argoproj.io",
174 api_plural="workflows",
175 api_version="v1alpha1",
176 )
garciadeblas61a4c692025-07-17 13:04:13 +0200177 return True, workflow_name, None
garciadeblas96b94f52024-07-08 16:18:21 +0200178
garciadeblas96b94f52024-07-08 16:18:21 +0200179
180async def update_cluster(self, op_id, op_params, content):
garciadeblas9e532812024-10-22 14:04:36 +0200181 self.logger.info(f"update_cluster Enter. Operation {op_id}. Params: {op_params}")
182 # self.logger.debug(f"Content: {content}")
garciadeblas96b94f52024-07-08 16:18:21 +0200183
184 db_cluster = content["cluster"]
185 db_vim_account = content["vim_account"]
garciadeblas73cd5a22024-11-06 10:45:22 +0100186 cluster_name = db_cluster["git_name"].lower()
garciadeblas96b94f52024-07-08 16:18:21 +0200187
188 workflow_template = "launcher-update-crossplane-cluster.j2"
garciadeblasc8c75d42024-11-13 12:36:13 +0100189 workflow_name = f"update-cluster-{op_id}"
garciadeblas96b94f52024-07-08 16:18:21 +0200190 # cluster_name = db_cluster["name"].lower()
garciadeblas96b94f52024-07-08 16:18:21 +0200191
192 # Get age key
193 public_key_cluster, private_key_cluster = gather_age_key(db_cluster)
194 self.logger.debug(f"public_key_new_cluster={public_key_cluster}")
195 self.logger.debug(f"private_key_new_cluster={private_key_cluster}")
196
197 # Create secret with agekey
198 secret_name = f"secret-age-{cluster_name}"
199 secret_namespace = "osm-workflows"
200 secret_key = "agekey"
201 secret_value = private_key_cluster
garciadeblasadb81e82024-11-08 01:11:46 +0100202 try:
garciadeblas6d8acf32025-02-06 13:34:37 +0100203 self.logger.debug(f"Testing kubectl: {self._kubectl}")
204 self.logger.debug(
205 f"Testing kubectl configuration: {self._kubectl.configuration}"
206 )
207 self.logger.debug(
208 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
209 )
garciadeblasadb81e82024-11-08 01:11:46 +0100210 await self.create_secret(
211 secret_name,
212 secret_namespace,
213 secret_key,
214 secret_value,
215 )
216 except Exception as e:
217 self.logger.info(f"Cannot create secret {secret_name}: {e}")
garciadeblas61a4c692025-07-17 13:04:13 +0200218 return False, f"Cannot create secret {secret_name}: {e}", None
garciadeblas96b94f52024-07-08 16:18:21 +0200219
220 # Additional params for the workflow
221 cluster_kustomization_name = cluster_name
222 osm_project_name = "osm_admin" # TODO: get project name from db_cluster
223 vim_account_id = db_cluster["vim_account"]
224 providerconfig_name = f"{vim_account_id}-config"
225 vim_type = db_vim_account["vim_type"]
garciadeblas73cd5a22024-11-06 10:45:22 +0100226 vm_size = op_params.get("node_size", db_cluster["node_size"])
227 node_count = op_params.get("node_count", db_cluster["node_count"])
228 k8s_version = op_params.get("k8s_version", db_cluster["k8s_version"])
garciadeblas96b94f52024-07-08 16:18:21 +0200229 if vim_type == "azure":
230 cluster_type = "aks"
231 elif vim_type == "aws":
232 cluster_type = "eks"
233 elif vim_type == "gcp":
234 cluster_type = "gke"
235 else:
236 raise Exception("Not suitable VIM account to update cluster")
237
238 # Render workflow
239 manifest = self.render_jinja_template(
240 workflow_template,
241 output_file=None,
242 workflow_name=workflow_name,
garciadeblas56c3aa82025-05-26 15:29:46 +0200243 git_fleet_url=self._repo_fleet_url,
244 git_sw_catalogs_url=self._repo_sw_catalogs_url,
garciadeblas96b94f52024-07-08 16:18:21 +0200245 cluster_name=cluster_name,
246 cluster_type=cluster_type,
247 cluster_kustomization_name=cluster_kustomization_name,
248 providerconfig_name=providerconfig_name,
249 public_key_mgmt=self._pubkey,
250 public_key_new_cluster=public_key_cluster,
251 secret_name_private_key_new_cluster=secret_name,
garciadeblas73cd5a22024-11-06 10:45:22 +0100252 vm_size=vm_size,
253 node_count=node_count,
254 k8s_version=k8s_version,
garciadeblas96b94f52024-07-08 16:18:21 +0200255 cluster_location=db_cluster["region_name"],
256 osm_project_name=osm_project_name,
garciadeblasd84808e2024-11-18 17:10:00 +0100257 rg_name=db_cluster.get("resource_group", "''"),
258 preemptible_nodes=db_cluster.get("preemptible_nodes", "false"),
garciadeblas96b94f52024-07-08 16:18:21 +0200259 workflow_debug=self._workflow_debug,
260 workflow_dry_run=self._workflow_dry_run,
261 )
garciadeblasf6dc6042026-02-04 17:40:30 +0100262 # self.logger.info(manifest)
garciadeblas96b94f52024-07-08 16:18:21 +0200263
264 # Submit workflow
garciadeblas6d8acf32025-02-06 13:34:37 +0100265 self.logger.debug(f"Testing kubectl: {self._kubectl}")
266 self.logger.debug(f"Testing kubectl configuration: {self._kubectl.configuration}")
267 self.logger.debug(
268 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
269 )
garciadeblas96b94f52024-07-08 16:18:21 +0200270 self._kubectl.create_generic_object(
271 namespace="osm-workflows",
272 manifest_dict=yaml.safe_load(manifest),
273 api_group="argoproj.io",
274 api_plural="workflows",
275 api_version="v1alpha1",
276 )
garciadeblas61a4c692025-07-17 13:04:13 +0200277 return True, workflow_name, None
garciadeblas96b94f52024-07-08 16:18:21 +0200278
279
280async def delete_cluster(self, op_id, op_params, content):
garciadeblas9e532812024-10-22 14:04:36 +0200281 self.logger.info(f"delete_cluster Enter. Operation {op_id}. Params: {op_params}")
282 # self.logger.debug(f"Content: {content}")
garciadeblas96b94f52024-07-08 16:18:21 +0200283
284 db_cluster = content["cluster"]
285
286 workflow_template = "launcher-delete-cluster.j2"
287 workflow_name = f"delete-cluster-{db_cluster['_id']}"
288 # cluster_name = db_cluster["name"].lower()
289 cluster_name = db_cluster["git_name"].lower()
290
291 # Additional params for the workflow
292 cluster_kustomization_name = cluster_name
293 osm_project_name = "osm_admin" # TODO: get project name from DB
294
295 # Render workflow
296 manifest = self.render_jinja_template(
297 workflow_template,
298 output_file=None,
299 workflow_name=workflow_name,
garciadeblas56c3aa82025-05-26 15:29:46 +0200300 git_fleet_url=self._repo_fleet_url,
301 git_sw_catalogs_url=self._repo_sw_catalogs_url,
garciadeblas96b94f52024-07-08 16:18:21 +0200302 cluster_name=cluster_name,
303 cluster_kustomization_name=cluster_kustomization_name,
304 osm_project_name=osm_project_name,
305 workflow_debug=self._workflow_debug,
306 workflow_dry_run=self._workflow_dry_run,
307 )
garciadeblasf6dc6042026-02-04 17:40:30 +0100308 # self.logger.info(manifest)
garciadeblas96b94f52024-07-08 16:18:21 +0200309
310 # Submit workflow
garciadeblas6d8acf32025-02-06 13:34:37 +0100311 self.logger.debug(f"Testing kubectl: {self._kubectl}")
312 self.logger.debug(f"Testing kubectl configuration: {self._kubectl.configuration}")
313 self.logger.debug(
314 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
315 )
garciadeblas96b94f52024-07-08 16:18:21 +0200316 self._kubectl.create_generic_object(
317 namespace="osm-workflows",
318 manifest_dict=yaml.safe_load(manifest),
319 api_group="argoproj.io",
320 api_plural="workflows",
321 api_version="v1alpha1",
322 )
garciadeblas61a4c692025-07-17 13:04:13 +0200323 return True, workflow_name, None
garciadeblas96b94f52024-07-08 16:18:21 +0200324
325
326async def register_cluster(self, op_id, op_params, content):
garciadeblas9e532812024-10-22 14:04:36 +0200327 self.logger.info(f"register_cluster Enter. Operation {op_id}. Params: {op_params}")
328 # self.logger.debug(f"Content: {content}")
garciadeblas96b94f52024-07-08 16:18:21 +0200329
330 db_cluster = content["cluster"]
garciadeblas96b94f52024-07-08 16:18:21 +0200331 cluster_name = db_cluster["git_name"].lower()
332
garciadeblasdde3a312024-09-17 13:25:06 +0200333 workflow_template = "launcher-bootstrap-cluster.j2"
334 workflow_name = f"register-cluster-{db_cluster['_id']}"
335
336 # Get age key
337 public_key_new_cluster, private_key_new_cluster = gather_age_key(db_cluster)
338 self.logger.debug(f"public_key_new_cluster={public_key_new_cluster}")
339 self.logger.debug(f"private_key_new_cluster={private_key_new_cluster}")
340
341 # Create temporal secret with agekey
342 secret_name = f"secret-age-{cluster_name}"
343 secret_namespace = "osm-workflows"
344 secret_key = "agekey"
345 secret_value = private_key_new_cluster
garciadeblasadb81e82024-11-08 01:11:46 +0100346 try:
garciadeblas6d8acf32025-02-06 13:34:37 +0100347 self.logger.debug(f"Testing kubectl: {self._kubectl}")
348 self.logger.debug(
349 f"Testing kubectl configuration: {self._kubectl.configuration}"
350 )
351 self.logger.debug(
352 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
353 )
garciadeblasadb81e82024-11-08 01:11:46 +0100354 await self.create_secret(
355 secret_name,
356 secret_namespace,
357 secret_key,
358 secret_value,
359 )
360 except Exception as e:
361 self.logger.info(
362 f"Cannot create secret {secret_name} in namespace {secret_namespace}: {e}"
363 )
garciadeblas41859ce2025-02-04 16:08:51 +0100364 return (
365 False,
366 f"Cannot create secret {secret_name} in namespace {secret_namespace}: {e}",
garciadeblas61a4c692025-07-17 13:04:13 +0200367 None,
garciadeblas41859ce2025-02-04 16:08:51 +0100368 )
garciadeblas96b94f52024-07-08 16:18:21 +0200369
garciadeblasdde3a312024-09-17 13:25:06 +0200370 # Create secret with kubeconfig
371 secret_name2 = f"kubeconfig-{cluster_name}"
372 secret_namespace2 = "managed-resources"
373 secret_key2 = "kubeconfig"
374 secret_value2 = yaml.safe_dump(
garciadeblasa82300f2024-11-18 10:24:26 +0100375 db_cluster["credentials"], indent=2, default_flow_style=False, sort_keys=False
garciadeblasdde3a312024-09-17 13:25:06 +0200376 )
garciadeblas91bb2c42024-11-12 11:17:12 +0100377 try:
garciadeblas6d8acf32025-02-06 13:34:37 +0100378 self.logger.debug(f"Testing kubectl: {self._kubectl}")
379 self.logger.debug(
380 f"Testing kubectl configuration: {self._kubectl.configuration}"
381 )
382 self.logger.debug(
383 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
384 )
garciadeblas91bb2c42024-11-12 11:17:12 +0100385 await self.create_secret(
386 secret_name2,
387 secret_namespace2,
388 secret_key2,
389 secret_value2,
390 )
391 except Exception as e:
392 self.logger.info(
393 f"Cannot create secret {secret_name} in namespace {secret_namespace}: {e}"
394 )
garciadeblas41859ce2025-02-04 16:08:51 +0100395 return (
396 False,
397 f"Cannot create secret {secret_name} in namespace {secret_namespace}: {e}",
garciadeblas61a4c692025-07-17 13:04:13 +0200398 None,
garciadeblas41859ce2025-02-04 16:08:51 +0100399 )
garciadeblasdde3a312024-09-17 13:25:06 +0200400
401 # Additional params for the workflow
402 cluster_kustomization_name = cluster_name
403 osm_project_name = "osm_admin" # TODO: get project name from content
garciadeblas65047492025-09-17 23:33:13 +0200404 if db_cluster.get("openshift", True):
405 templates_dir = "/sw-catalogs/sw-catalogs-osm/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates"
406 self.logger.info(
407 "Rendering OpenShift bootstrap templates from %s", templates_dir
408 )
409 else:
410 templates_dir = "/sw-catalogs/sw-catalogs-osm/cloud-resources/flux-remote-bootstrap/cluster-base/templates"
411 self.logger.info(
412 "Rendering Standard bootstrap templates from %s", templates_dir
413 )
garciadeblasdde3a312024-09-17 13:25:06 +0200414
415 manifest = self.render_jinja_template(
416 workflow_template,
417 output_file=None,
418 workflow_name=workflow_name,
garciadeblas56c3aa82025-05-26 15:29:46 +0200419 git_fleet_url=self._repo_fleet_url,
420 git_sw_catalogs_url=self._repo_sw_catalogs_url,
garciadeblasdde3a312024-09-17 13:25:06 +0200421 cluster_name=cluster_name,
422 cluster_kustomization_name=cluster_kustomization_name,
garciadeblasdde3a312024-09-17 13:25:06 +0200423 public_key_mgmt=self._pubkey,
424 public_key_new_cluster=public_key_new_cluster,
425 secret_name_private_key_new_cluster=secret_name,
426 osm_project_name=osm_project_name,
garciadeblas65047492025-09-17 23:33:13 +0200427 templates_dir=templates_dir,
garciadeblasdde3a312024-09-17 13:25:06 +0200428 workflow_debug=self._workflow_debug,
429 workflow_dry_run=self._workflow_dry_run,
430 )
garciadeblasf6dc6042026-02-04 17:40:30 +0100431 # self.logger.debug(f"Workflow manifest: {manifest}")
garciadeblasdde3a312024-09-17 13:25:06 +0200432
433 # Submit workflow
garciadeblas6d8acf32025-02-06 13:34:37 +0100434 self.logger.debug(f"Testing kubectl: {self._kubectl}")
435 self.logger.debug(f"Testing kubectl configuration: {self._kubectl.configuration}")
436 self.logger.debug(
437 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
438 )
garciadeblasdde3a312024-09-17 13:25:06 +0200439 self._kubectl.create_generic_object(
440 namespace="osm-workflows",
441 manifest_dict=yaml.safe_load(manifest),
442 api_group="argoproj.io",
443 api_plural="workflows",
444 api_version="v1alpha1",
445 )
garciadeblas61a4c692025-07-17 13:04:13 +0200446 return True, workflow_name, None
garciadeblas96b94f52024-07-08 16:18:21 +0200447
448
449async def deregister_cluster(self, op_id, op_params, content):
garciadeblas9e532812024-10-22 14:04:36 +0200450 self.logger.info(
451 f"deregister_cluster Enter. Operation {op_id}. Params: {op_params}"
452 )
453 # self.logger.debug(f"Content: {content}")
garciadeblasdde3a312024-09-17 13:25:06 +0200454
455 db_cluster = content["cluster"]
456 cluster_name = db_cluster["git_name"].lower()
457
458 workflow_template = "launcher-disconnect-flux-remote-cluster.j2"
459 workflow_name = f"deregister-cluster-{db_cluster['_id']}"
460
garciadeblasf6dc6042026-02-04 17:40:30 +0100461 # Create secret with kubeconfig
462 secret_name = f"kubeconfig-{cluster_name}"
463 secret_namespace = "osm-workflows"
464 secret_key = "kubeconfig"
465 secret_value = yaml.safe_dump(
466 db_cluster["credentials"], indent=2, default_flow_style=False, sort_keys=False
467 )
468 try:
469 self.logger.debug(f"Testing kubectl: {self._kubectl}")
470 self.logger.debug(
471 f"Testing kubectl configuration: {self._kubectl.configuration}"
472 )
473 self.logger.debug(
474 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
475 )
476 await self.create_secret(
477 secret_name,
478 secret_namespace,
479 secret_key,
480 secret_value,
481 )
482 except Exception as e:
483 self.logger.info(
484 f"Cannot create secret {secret_name} in namespace {secret_namespace}: {e}"
485 )
486 return (
487 False,
488 f"Cannot create secret {secret_name} in namespace {secret_namespace}: {e}",
489 None,
490 )
491
garciadeblasdde3a312024-09-17 13:25:06 +0200492 # Additional params for the workflow
493 cluster_kustomization_name = cluster_name
494 osm_project_name = "osm_admin" # TODO: get project name from DB
495
496 # Render workflow
497 manifest = self.render_jinja_template(
498 workflow_template,
499 output_file=None,
500 workflow_name=workflow_name,
garciadeblas56c3aa82025-05-26 15:29:46 +0200501 git_fleet_url=self._repo_fleet_url,
garciadeblasdde3a312024-09-17 13:25:06 +0200502 cluster_kustomization_name=cluster_kustomization_name,
503 osm_project_name=osm_project_name,
504 workflow_debug=self._workflow_debug,
505 workflow_dry_run=self._workflow_dry_run,
506 )
garciadeblasf6dc6042026-02-04 17:40:30 +0100507 # self.logger.info(manifest)
508
509 # Submit workflow
510 self.logger.debug(f"Testing kubectl: {self._kubectl}")
511 self.logger.debug(f"Testing kubectl configuration: {self._kubectl.configuration}")
512 self.logger.debug(
513 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
514 )
515 self._kubectl.create_generic_object(
516 namespace="osm-workflows",
517 manifest_dict=yaml.safe_load(manifest),
518 api_group="argoproj.io",
519 api_plural="workflows",
520 api_version="v1alpha1",
521 )
522 return True, workflow_name, None
523
524
525async def purge_cluster(self, op_id, op_params, content):
526 self.logger.info(f"purge_cluster Enter. Operation {op_id}. Params: {op_params}")
527 # self.logger.debug(f"Content: {content}")
528
529 db_cluster = content["cluster"]
530 cluster_name = db_cluster["git_name"].lower()
531
532 workflow_template = "launcher-purge-delete-cluster.yaml.j2"
533 workflow_name = f"purge-cluster-{db_cluster['_id']}"
534
535 # Create secret with kubeconfig
536 temp_kubeconfig_secret_name = f"kubeconfig-{cluster_name}"
537
538 # Additional params for the workflow
539 cluster_kustomization_name = cluster_name
540 osm_project_name = "osm_admin" # TODO: get project name from DB
541
542 # Render workflow
543 manifest = self.render_jinja_template(
544 workflow_template,
545 output_file=None,
546 workflow_name=workflow_name,
547 git_fleet_url=self._repo_fleet_url,
548 cluster_kustomization_name=cluster_kustomization_name,
549 osm_project_name=osm_project_name,
550 temp_kubeconfig_secret_name=temp_kubeconfig_secret_name,
551 workflow_debug=self._workflow_debug,
552 workflow_dry_run=self._workflow_dry_run,
553 )
554 # self.logger.info(manifest)
garciadeblasdde3a312024-09-17 13:25:06 +0200555
556 # Submit workflow
garciadeblas6d8acf32025-02-06 13:34:37 +0100557 self.logger.debug(f"Testing kubectl: {self._kubectl}")
558 self.logger.debug(f"Testing kubectl configuration: {self._kubectl.configuration}")
559 self.logger.debug(
560 f"Testing kubectl configuration Host: {self._kubectl.configuration.host}"
561 )
garciadeblasdde3a312024-09-17 13:25:06 +0200562 self._kubectl.create_generic_object(
563 namespace="osm-workflows",
564 manifest_dict=yaml.safe_load(manifest),
565 api_group="argoproj.io",
566 api_plural="workflows",
567 api_version="v1alpha1",
568 )
garciadeblas61a4c692025-07-17 13:04:13 +0200569 return True, workflow_name, None
garciadeblas96b94f52024-07-08 16:18:21 +0200570
571
572async def get_cluster_credentials(self, db_cluster):
573 """
574 returns the kubeconfig file of a K8s cluster in a dictionary
575 """
garciadeblas9e532812024-10-22 14:04:36 +0200576 self.logger.info("get_cluster_credentials Enter")
577 # self.logger.debug(f"Content: {db_cluster}")
garciadeblas96b94f52024-07-08 16:18:21 +0200578
579 secret_name = f"kubeconfig-{db_cluster['git_name'].lower()}"
580 secret_namespace = "managed-resources"
581 secret_key = "kubeconfig"
582
583 self.logger.info(f"Checking content of secret {secret_name} ...")
584 try:
585 returned_secret_data = await self._kubectl.get_secret_content(
586 name=secret_name,
587 namespace=secret_namespace,
588 )
589 returned_secret_value = base64.b64decode(
590 returned_secret_data[secret_key]
591 ).decode("utf-8")
592 return True, yaml.safe_load(returned_secret_value)
593 except Exception as e:
594 message = f"Not possible to get the credentials of the cluster. Exception: {e}"
595 self.logger.critical(message)
596 return False, message
597
598
garciadeblas28bff0f2024-09-16 12:53:07 +0200599async def clean_items_cluster_create(self, op_id, op_params, content):
garciadeblas9e532812024-10-22 14:04:36 +0200600 self.logger.info(
601 f"clean_items_cluster_create Enter. Operation {op_id}. Params: {op_params}"
602 )
603 self.logger.debug(f"Content: {content}")
garciadeblas28bff0f2024-09-16 12:53:07 +0200604 items = {
605 "secrets": [
606 {
607 "name": f"secret-age-{content['cluster']['git_name'].lower()}",
608 "namespace": "osm-workflows",
609 }
rshrif8911b92025-06-11 18:19:07 +0000610 ],
yshah4c0d1bc2025-09-23 09:53:26 +0000611 # "configmaps": [
612 # {
613 # "name": f"{content['cluster']['name']}-parameters",
614 # "namespace": "managed-resources",
615 # }
616 # ],
garciadeblas28bff0f2024-09-16 12:53:07 +0200617 }
618 try:
619 await self.clean_items(items)
620 return True, "OK"
621 except Exception as e:
622 return False, f"Error while cleaning items: {e}"
623
624
625async def clean_items_cluster_update(self, op_id, op_params, content):
garciadeblas9e532812024-10-22 14:04:36 +0200626 self.logger.info(
627 f"clean_items_cluster_update Enter. Operation {op_id}. Params: {op_params}"
628 )
629 # self.logger.debug(f"Content: {content}")
garciadeblas28bff0f2024-09-16 12:53:07 +0200630 return await self.clean_items_cluster_create(op_id, op_params, content)
631
632
garciadeblasdde3a312024-09-17 13:25:06 +0200633async def clean_items_cluster_register(self, op_id, op_params, content):
garciadeblas9e532812024-10-22 14:04:36 +0200634 self.logger.info(
635 f"clean_items_cluster_register Enter. Operation {op_id}. Params: {op_params}"
636 )
637 # self.logger.debug(f"Content: {content}")
garciadeblasdde3a312024-09-17 13:25:06 +0200638 # Clean secrets
639 cluster_name = content["cluster"]["git_name"].lower()
640 items = {
641 "secrets": [
642 {
643 "name": f"secret-age-{cluster_name}",
644 "namespace": "osm-workflows",
645 },
646 ]
647 }
648
649 try:
650 await self.clean_items(items)
garciadeblas28d6e692024-10-15 13:14:39 +0200651 return True, "OK"
garciadeblasdde3a312024-09-17 13:25:06 +0200652 except Exception as e:
653 return False, f"Error while cleaning items: {e}"
garciadeblas91bb2c42024-11-12 11:17:12 +0100654
655
garciadeblasf6dc6042026-02-04 17:40:30 +0100656async def clean_items_cluster_purge(self, op_id, op_params, content):
garciadeblas91bb2c42024-11-12 11:17:12 +0100657 self.logger.info(
garciadeblasf6dc6042026-02-04 17:40:30 +0100658 f"clean_items_cluster_purge Enter. Operation {op_id}. Params: {op_params}"
garciadeblas91bb2c42024-11-12 11:17:12 +0100659 )
660 # self.logger.debug(f"Content: {content}")
661 # Clean secrets
662 self.logger.info("Cleaning kubeconfig")
663 cluster_name = content["cluster"]["git_name"].lower()
664 items = {
665 "secrets": [
666 {
667 "name": f"kubeconfig-{cluster_name}",
garciadeblasf6dc6042026-02-04 17:40:30 +0100668 "namespace": "osm-workflows",
669 },
670 {
671 "name": f"kubeconfig-{cluster_name}",
garciadeblas91bb2c42024-11-12 11:17:12 +0100672 "namespace": "managed-resources",
673 },
674 ]
675 }
676
677 try:
678 await self.clean_items(items)
679 return True, "OK"
680 except Exception as e:
681 return False, f"Error while cleaning items: {e}"