kubectl-mcp-server 1.14.0__py3-none-any.whl → 1.16.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. kubectl_mcp_server-1.16.0.dist-info/METADATA +1047 -0
  2. kubectl_mcp_server-1.16.0.dist-info/RECORD +61 -0
  3. kubectl_mcp_tool/__init__.py +1 -1
  4. kubectl_mcp_tool/crd_detector.py +247 -0
  5. kubectl_mcp_tool/k8s_config.py +304 -63
  6. kubectl_mcp_tool/mcp_server.py +27 -0
  7. kubectl_mcp_tool/tools/__init__.py +20 -0
  8. kubectl_mcp_tool/tools/backup.py +881 -0
  9. kubectl_mcp_tool/tools/capi.py +727 -0
  10. kubectl_mcp_tool/tools/certs.py +709 -0
  11. kubectl_mcp_tool/tools/cilium.py +582 -0
  12. kubectl_mcp_tool/tools/cluster.py +395 -121
  13. kubectl_mcp_tool/tools/core.py +157 -60
  14. kubectl_mcp_tool/tools/cost.py +97 -41
  15. kubectl_mcp_tool/tools/deployments.py +173 -56
  16. kubectl_mcp_tool/tools/diagnostics.py +40 -13
  17. kubectl_mcp_tool/tools/gitops.py +552 -0
  18. kubectl_mcp_tool/tools/helm.py +133 -46
  19. kubectl_mcp_tool/tools/keda.py +464 -0
  20. kubectl_mcp_tool/tools/kiali.py +652 -0
  21. kubectl_mcp_tool/tools/kubevirt.py +803 -0
  22. kubectl_mcp_tool/tools/networking.py +106 -32
  23. kubectl_mcp_tool/tools/operations.py +176 -50
  24. kubectl_mcp_tool/tools/pods.py +162 -50
  25. kubectl_mcp_tool/tools/policy.py +554 -0
  26. kubectl_mcp_tool/tools/rollouts.py +790 -0
  27. kubectl_mcp_tool/tools/security.py +89 -36
  28. kubectl_mcp_tool/tools/storage.py +35 -16
  29. tests/test_browser.py +2 -2
  30. tests/test_ecosystem.py +331 -0
  31. tests/test_tools.py +73 -10
  32. kubectl_mcp_server-1.14.0.dist-info/METADATA +0 -780
  33. kubectl_mcp_server-1.14.0.dist-info/RECORD +0 -49
  34. {kubectl_mcp_server-1.14.0.dist-info → kubectl_mcp_server-1.16.0.dist-info}/WHEEL +0 -0
  35. {kubectl_mcp_server-1.14.0.dist-info → kubectl_mcp_server-1.16.0.dist-info}/entry_points.txt +0 -0
  36. {kubectl_mcp_server-1.14.0.dist-info → kubectl_mcp_server-1.16.0.dist-info}/licenses/LICENSE +0 -0
  37. {kubectl_mcp_server-1.14.0.dist-info → kubectl_mcp_server-1.16.0.dist-info}/top_level.txt +0 -0
@@ -2,13 +2,15 @@
2
2
  Kubernetes configuration loader utility.
3
3
 
4
4
  Handles both in-cluster and out-of-cluster (kubeconfig) configurations.
5
+ Supports multi-cluster operations with context targeting.
5
6
 
6
- This module patches the kubernetes.config.load_kube_config function to
7
- automatically try in-cluster config first when running inside a pod.
7
+ This module provides context-aware client creation for multi-cluster support.
8
+ All get_*_client() functions accept an optional 'context' parameter.
8
9
  """
9
10
 
10
11
  import os
11
12
  import logging
13
+ from typing import Optional, Any
12
14
 
13
15
  logger = logging.getLogger("mcp-server")
14
16
 
@@ -16,20 +18,20 @@ _config_loaded = False
16
18
  _original_load_kube_config = None
17
19
 
18
20
 
19
- def load_kubernetes_config():
21
+ def load_kubernetes_config(context: str = ""):
20
22
  """Load Kubernetes configuration.
21
23
 
22
24
  Tries in-cluster config first (when running inside a pod),
23
25
  then falls back to kubeconfig file.
24
26
 
27
+ Args:
28
+ context: Optional context name for kubeconfig provider
29
+
25
30
  Returns:
26
31
  bool: True if config loaded successfully, False otherwise
27
32
  """
28
33
  global _config_loaded
29
34
 
30
- if _config_loaded:
31
- return True
32
-
33
35
  from kubernetes import config
34
36
  from kubernetes.config.config_exception import ConfigException
35
37
 
@@ -46,8 +48,14 @@ def load_kubernetes_config():
46
48
  try:
47
49
  kubeconfig_path = os.environ.get('KUBECONFIG', '~/.kube/config')
48
50
  kubeconfig_path = os.path.expanduser(kubeconfig_path)
49
- config.load_kube_config(config_file=kubeconfig_path)
50
- logger.info(f"Loaded kubeconfig from {kubeconfig_path}")
51
+
52
+ if context:
53
+ config.load_kube_config(config_file=kubeconfig_path, context=context)
54
+ logger.info(f"Loaded kubeconfig context '{context}' from {kubeconfig_path}")
55
+ else:
56
+ config.load_kube_config(config_file=kubeconfig_path)
57
+ logger.info(f"Loaded kubeconfig from {kubeconfig_path}")
58
+
51
59
  _config_loaded = True
52
60
  return True
53
61
  except ConfigException as e:
@@ -102,8 +110,52 @@ def patch_kubernetes_config():
102
110
  patch_kubernetes_config()
103
111
 
104
112
 
105
- def get_k8s_client():
106
- """Get a configured Kubernetes API client.
113
+ def _load_config_for_context(context: str = "") -> Any:
114
+ """
115
+ Load kubernetes config for a specific context and return ApiClient.
116
+
117
+ Args:
118
+ context: Context name (empty for default)
119
+
120
+ Returns:
121
+ kubernetes.client.ApiClient configured for the context
122
+ """
123
+ from kubernetes import client, config
124
+ from kubernetes.config.config_exception import ConfigException
125
+
126
+ # Try in-cluster first
127
+ try:
128
+ config.load_incluster_config()
129
+ return client.ApiClient()
130
+ except ConfigException:
131
+ pass
132
+
133
+ # Load kubeconfig with optional context
134
+ kubeconfig_path = os.environ.get('KUBECONFIG', '~/.kube/config')
135
+ kubeconfig_path = os.path.expanduser(kubeconfig_path)
136
+
137
+ api_config = client.Configuration()
138
+
139
+ if context:
140
+ config.load_kube_config(
141
+ config_file=kubeconfig_path,
142
+ context=context,
143
+ client_configuration=api_config
144
+ )
145
+ else:
146
+ config.load_kube_config(
147
+ config_file=kubeconfig_path,
148
+ client_configuration=api_config
149
+ )
150
+
151
+ return client.ApiClient(configuration=api_config)
152
+
153
+
154
+ def get_k8s_client(context: str = ""):
155
+ """Get a configured Kubernetes Core API client.
156
+
157
+ Args:
158
+ context: Optional context name for multi-cluster support
107
159
 
108
160
  Returns:
109
161
  kubernetes.client.CoreV1Api: Configured Kubernetes client
@@ -113,15 +165,19 @@ def get_k8s_client():
113
165
  """
114
166
  from kubernetes import client
115
167
 
116
- if not load_kubernetes_config():
117
- raise RuntimeError("Invalid kube-config file. No configuration found.")
118
-
119
- return client.CoreV1Api()
168
+ try:
169
+ api_client = _load_config_for_context(context)
170
+ return client.CoreV1Api(api_client=api_client)
171
+ except Exception as e:
172
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
120
173
 
121
174
 
122
- def get_apps_client():
175
+ def get_apps_client(context: str = ""):
123
176
  """Get a configured Kubernetes Apps API client.
124
177
 
178
+ Args:
179
+ context: Optional context name for multi-cluster support
180
+
125
181
  Returns:
126
182
  kubernetes.client.AppsV1Api: Configured Apps API client
127
183
 
@@ -130,15 +186,19 @@ def get_apps_client():
130
186
  """
131
187
  from kubernetes import client
132
188
 
133
- if not load_kubernetes_config():
134
- raise RuntimeError("Invalid kube-config file. No configuration found.")
135
-
136
- return client.AppsV1Api()
189
+ try:
190
+ api_client = _load_config_for_context(context)
191
+ return client.AppsV1Api(api_client=api_client)
192
+ except Exception as e:
193
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
137
194
 
138
195
 
139
- def get_rbac_client():
196
+ def get_rbac_client(context: str = ""):
140
197
  """Get a configured Kubernetes RBAC API client.
141
198
 
199
+ Args:
200
+ context: Optional context name for multi-cluster support
201
+
142
202
  Returns:
143
203
  kubernetes.client.RbacAuthorizationV1Api: Configured RBAC client
144
204
 
@@ -147,15 +207,19 @@ def get_rbac_client():
147
207
  """
148
208
  from kubernetes import client
149
209
 
150
- if not load_kubernetes_config():
151
- raise RuntimeError("Invalid kube-config file. No configuration found.")
152
-
153
- return client.RbacAuthorizationV1Api()
210
+ try:
211
+ api_client = _load_config_for_context(context)
212
+ return client.RbacAuthorizationV1Api(api_client=api_client)
213
+ except Exception as e:
214
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
154
215
 
155
216
 
156
- def get_networking_client():
217
+ def get_networking_client(context: str = ""):
157
218
  """Get a configured Kubernetes Networking API client.
158
219
 
220
+ Args:
221
+ context: Optional context name for multi-cluster support
222
+
159
223
  Returns:
160
224
  kubernetes.client.NetworkingV1Api: Configured Networking client
161
225
 
@@ -164,15 +228,19 @@ def get_networking_client():
164
228
  """
165
229
  from kubernetes import client
166
230
 
167
- if not load_kubernetes_config():
168
- raise RuntimeError("Invalid kube-config file. No configuration found.")
169
-
170
- return client.NetworkingV1Api()
231
+ try:
232
+ api_client = _load_config_for_context(context)
233
+ return client.NetworkingV1Api(api_client=api_client)
234
+ except Exception as e:
235
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
171
236
 
172
237
 
173
- def get_storage_client():
238
+ def get_storage_client(context: str = ""):
174
239
  """Get a configured Kubernetes Storage API client.
175
240
 
241
+ Args:
242
+ context: Optional context name for multi-cluster support
243
+
176
244
  Returns:
177
245
  kubernetes.client.StorageV1Api: Configured Storage client
178
246
 
@@ -181,15 +249,19 @@ def get_storage_client():
181
249
  """
182
250
  from kubernetes import client
183
251
 
184
- if not load_kubernetes_config():
185
- raise RuntimeError("Invalid kube-config file. No configuration found.")
186
-
187
- return client.StorageV1Api()
252
+ try:
253
+ api_client = _load_config_for_context(context)
254
+ return client.StorageV1Api(api_client=api_client)
255
+ except Exception as e:
256
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
188
257
 
189
258
 
190
- def get_batch_client():
259
+ def get_batch_client(context: str = ""):
191
260
  """Get a configured Kubernetes Batch API client.
192
261
 
262
+ Args:
263
+ context: Optional context name for multi-cluster support
264
+
193
265
  Returns:
194
266
  kubernetes.client.BatchV1Api: Configured Batch client
195
267
 
@@ -198,15 +270,19 @@ def get_batch_client():
198
270
  """
199
271
  from kubernetes import client
200
272
 
201
- if not load_kubernetes_config():
202
- raise RuntimeError("Invalid kube-config file. No configuration found.")
203
-
204
- return client.BatchV1Api()
273
+ try:
274
+ api_client = _load_config_for_context(context)
275
+ return client.BatchV1Api(api_client=api_client)
276
+ except Exception as e:
277
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
205
278
 
206
279
 
207
- def get_autoscaling_client():
280
+ def get_autoscaling_client(context: str = ""):
208
281
  """Get a configured Kubernetes Autoscaling API client.
209
282
 
283
+ Args:
284
+ context: Optional context name for multi-cluster support
285
+
210
286
  Returns:
211
287
  kubernetes.client.AutoscalingV1Api: Configured Autoscaling client
212
288
 
@@ -215,15 +291,19 @@ def get_autoscaling_client():
215
291
  """
216
292
  from kubernetes import client
217
293
 
218
- if not load_kubernetes_config():
219
- raise RuntimeError("Invalid kube-config file. No configuration found.")
220
-
221
- return client.AutoscalingV1Api()
294
+ try:
295
+ api_client = _load_config_for_context(context)
296
+ return client.AutoscalingV1Api(api_client=api_client)
297
+ except Exception as e:
298
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
222
299
 
223
300
 
224
- def get_policy_client():
301
+ def get_policy_client(context: str = ""):
225
302
  """Get a configured Kubernetes Policy API client.
226
303
 
304
+ Args:
305
+ context: Optional context name for multi-cluster support
306
+
227
307
  Returns:
228
308
  kubernetes.client.PolicyV1Api: Configured Policy client
229
309
 
@@ -232,15 +312,19 @@ def get_policy_client():
232
312
  """
233
313
  from kubernetes import client
234
314
 
235
- if not load_kubernetes_config():
236
- raise RuntimeError("Invalid kube-config file. No configuration found.")
237
-
238
- return client.PolicyV1Api()
315
+ try:
316
+ api_client = _load_config_for_context(context)
317
+ return client.PolicyV1Api(api_client=api_client)
318
+ except Exception as e:
319
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
239
320
 
240
321
 
241
- def get_custom_objects_client():
322
+ def get_custom_objects_client(context: str = ""):
242
323
  """Get a configured Kubernetes Custom Objects API client.
243
324
 
325
+ Args:
326
+ context: Optional context name for multi-cluster support
327
+
244
328
  Returns:
245
329
  kubernetes.client.CustomObjectsApi: Configured Custom Objects client
246
330
 
@@ -249,15 +333,19 @@ def get_custom_objects_client():
249
333
  """
250
334
  from kubernetes import client
251
335
 
252
- if not load_kubernetes_config():
253
- raise RuntimeError("Invalid kube-config file. No configuration found.")
254
-
255
- return client.CustomObjectsApi()
336
+ try:
337
+ api_client = _load_config_for_context(context)
338
+ return client.CustomObjectsApi(api_client=api_client)
339
+ except Exception as e:
340
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
256
341
 
257
342
 
258
- def get_version_client():
343
+ def get_version_client(context: str = ""):
259
344
  """Get a configured Kubernetes Version API client.
260
345
 
346
+ Args:
347
+ context: Optional context name for multi-cluster support
348
+
261
349
  Returns:
262
350
  kubernetes.client.VersionApi: Configured Version client
263
351
 
@@ -266,15 +354,19 @@ def get_version_client():
266
354
  """
267
355
  from kubernetes import client
268
356
 
269
- if not load_kubernetes_config():
270
- raise RuntimeError("Invalid kube-config file. No configuration found.")
271
-
272
- return client.VersionApi()
357
+ try:
358
+ api_client = _load_config_for_context(context)
359
+ return client.VersionApi(api_client=api_client)
360
+ except Exception as e:
361
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
273
362
 
274
363
 
275
- def get_admissionregistration_client():
364
+ def get_admissionregistration_client(context: str = ""):
276
365
  """Get a configured Kubernetes Admission Registration API client.
277
366
 
367
+ Args:
368
+ context: Optional context name for multi-cluster support
369
+
278
370
  Returns:
279
371
  kubernetes.client.AdmissionregistrationV1Api: Configured Admission client
280
372
 
@@ -283,7 +375,156 @@ def get_admissionregistration_client():
283
375
  """
284
376
  from kubernetes import client
285
377
 
286
- if not load_kubernetes_config():
287
- raise RuntimeError("Invalid kube-config file. No configuration found.")
378
+ try:
379
+ api_client = _load_config_for_context(context)
380
+ return client.AdmissionregistrationV1Api(api_client=api_client)
381
+ except Exception as e:
382
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
383
+
384
+
385
+ def get_apiextensions_client(context: str = ""):
386
+ """Get a configured Kubernetes API Extensions client.
387
+
388
+ Args:
389
+ context: Optional context name for multi-cluster support
288
390
 
289
- return client.AdmissionregistrationV1Api()
391
+ Returns:
392
+ kubernetes.client.ApiextensionsV1Api: Configured API Extensions client
393
+
394
+ Raises:
395
+ RuntimeError: If Kubernetes config cannot be loaded
396
+ """
397
+ from kubernetes import client
398
+
399
+ try:
400
+ api_client = _load_config_for_context(context)
401
+ return client.ApiextensionsV1Api(api_client=api_client)
402
+ except Exception as e:
403
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
404
+
405
+
406
+ def get_coordination_client(context: str = ""):
407
+ """Get a configured Kubernetes Coordination API client.
408
+
409
+ Args:
410
+ context: Optional context name for multi-cluster support
411
+
412
+ Returns:
413
+ kubernetes.client.CoordinationV1Api: Configured Coordination client
414
+
415
+ Raises:
416
+ RuntimeError: If Kubernetes config cannot be loaded
417
+ """
418
+ from kubernetes import client
419
+
420
+ try:
421
+ api_client = _load_config_for_context(context)
422
+ return client.CoordinationV1Api(api_client=api_client)
423
+ except Exception as e:
424
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
425
+
426
+
427
+ def get_events_client(context: str = ""):
428
+ """Get a configured Kubernetes Events API client.
429
+
430
+ Args:
431
+ context: Optional context name for multi-cluster support
432
+
433
+ Returns:
434
+ kubernetes.client.EventsV1Api: Configured Events client
435
+
436
+ Raises:
437
+ RuntimeError: If Kubernetes config cannot be loaded
438
+ """
439
+ from kubernetes import client
440
+
441
+ try:
442
+ api_client = _load_config_for_context(context)
443
+ return client.EventsV1Api(api_client=api_client)
444
+ except Exception as e:
445
+ raise RuntimeError(f"Invalid kube-config. Context: {context or 'default'}. Error: {e}")
446
+
447
+
448
+ # Utility functions for context management
449
+
450
+ def list_contexts() -> list:
451
+ """
452
+ List all available kubeconfig contexts.
453
+
454
+ Returns:
455
+ List of context dictionaries with name, cluster, user, namespace
456
+ """
457
+ from kubernetes import config
458
+
459
+ try:
460
+ kubeconfig_path = os.environ.get('KUBECONFIG', '~/.kube/config')
461
+ kubeconfig_path = os.path.expanduser(kubeconfig_path)
462
+
463
+ contexts, active = config.list_kube_config_contexts(config_file=kubeconfig_path)
464
+
465
+ return [
466
+ {
467
+ "name": ctx.get("name"),
468
+ "cluster": ctx.get("context", {}).get("cluster"),
469
+ "user": ctx.get("context", {}).get("user"),
470
+ "namespace": ctx.get("context", {}).get("namespace", "default"),
471
+ "active": ctx.get("name") == (active.get("name") if active else None)
472
+ }
473
+ for ctx in contexts
474
+ ]
475
+ except Exception as e:
476
+ logger.error(f"Error listing contexts: {e}")
477
+ return []
478
+
479
+
480
+ def get_active_context() -> Optional[str]:
481
+ """
482
+ Get the current active context name.
483
+
484
+ Returns:
485
+ Active context name or None
486
+ """
487
+ from kubernetes import config
488
+
489
+ try:
490
+ kubeconfig_path = os.environ.get('KUBECONFIG', '~/.kube/config')
491
+ kubeconfig_path = os.path.expanduser(kubeconfig_path)
492
+
493
+ _, active = config.list_kube_config_contexts(config_file=kubeconfig_path)
494
+ return active.get("name") if active else None
495
+ except Exception as e:
496
+ logger.error(f"Error getting active context: {e}")
497
+ return None
498
+
499
+
500
+ def context_exists(context: str) -> bool:
501
+ """
502
+ Check if a context exists in kubeconfig.
503
+
504
+ Args:
505
+ context: Context name to check
506
+
507
+ Returns:
508
+ True if context exists
509
+ """
510
+ contexts = list_contexts()
511
+ return any(ctx["name"] == context for ctx in contexts)
512
+
513
+
514
+ def _get_kubectl_context_args(context: str = "") -> list:
515
+ """
516
+ Get kubectl command arguments for specifying a context.
517
+
518
+ This utility function returns the appropriate --context flag arguments
519
+ for kubectl commands when targeting a specific cluster.
520
+
521
+ Args:
522
+ context: Context name (empty string for default context)
523
+
524
+ Returns:
525
+ List of command arguments, e.g., ["--context", "my-cluster"]
526
+ or empty list if no context specified
527
+ """
528
+ if context and context.strip():
529
+ return ["--context", context.strip()]
530
+ return []
@@ -45,6 +45,16 @@ from kubectl_mcp_tool.tools import (
45
45
  is_browser_available,
46
46
  register_ui_tools,
47
47
  is_ui_available,
48
+ register_gitops_tools,
49
+ register_certs_tools,
50
+ register_policy_tools,
51
+ register_backup_tools,
52
+ register_keda_tools,
53
+ register_cilium_tools,
54
+ register_rollouts_tools,
55
+ register_capi_tools,
56
+ register_kubevirt_tools,
57
+ register_istio_tools,
48
58
  )
49
59
  from kubectl_mcp_tool.resources import register_resources
50
60
  from kubectl_mcp_tool.prompts import register_prompts
@@ -196,6 +206,23 @@ class MCPServer:
196
206
  else:
197
207
  logger.debug("MCP-UI tools disabled (install mcp-ui-server to enable)")
198
208
 
209
+ # Register ecosystem tools (GitOps, Cert-Manager, Policy, Backup)
210
+ # These tools auto-detect installed CRDs and gracefully handle missing components
211
+ register_gitops_tools(self.server, self.non_destructive)
212
+ register_certs_tools(self.server, self.non_destructive)
213
+ register_policy_tools(self.server, self.non_destructive)
214
+ register_backup_tools(self.server, self.non_destructive)
215
+ logger.debug("Ecosystem tools registered (GitOps, Certs, Policy, Backup)")
216
+
217
+ # Register advanced ecosystem tools (KEDA, Cilium, Rollouts, CAPI, KubeVirt, Istio)
218
+ register_keda_tools(self.server, self.non_destructive)
219
+ register_cilium_tools(self.server, self.non_destructive)
220
+ register_rollouts_tools(self.server, self.non_destructive)
221
+ register_capi_tools(self.server, self.non_destructive)
222
+ register_kubevirt_tools(self.server, self.non_destructive)
223
+ register_istio_tools(self.server, self.non_destructive)
224
+ logger.debug("Advanced ecosystem tools registered (KEDA, Cilium, Rollouts, CAPI, KubeVirt, Istio)")
225
+
199
226
  def setup_resources(self):
200
227
  """Set up MCP resources for Kubernetes data exposure."""
201
228
  register_resources(self.server)
@@ -11,6 +11,16 @@ from .diagnostics import register_diagnostics_tools
11
11
  from .cost import register_cost_tools
12
12
  from .browser import register_browser_tools, is_browser_available
13
13
  from .ui import register_ui_tools, is_ui_available
14
+ from .gitops import register_gitops_tools
15
+ from .certs import register_certs_tools
16
+ from .policy import register_policy_tools
17
+ from .backup import register_backup_tools
18
+ from .keda import register_keda_tools
19
+ from .cilium import register_cilium_tools
20
+ from .rollouts import register_rollouts_tools
21
+ from .capi import register_capi_tools
22
+ from .kubevirt import register_kubevirt_tools
23
+ from .kiali import register_istio_tools
14
24
 
15
25
  __all__ = [
16
26
  "register_helm_tools",
@@ -28,4 +38,14 @@ __all__ = [
28
38
  "is_browser_available",
29
39
  "register_ui_tools",
30
40
  "is_ui_available",
41
+ "register_gitops_tools",
42
+ "register_certs_tools",
43
+ "register_policy_tools",
44
+ "register_backup_tools",
45
+ "register_keda_tools",
46
+ "register_cilium_tools",
47
+ "register_rollouts_tools",
48
+ "register_capi_tools",
49
+ "register_kubevirt_tools",
50
+ "register_istio_tools",
31
51
  ]