switching context
This commit is contained in:
parent
68f9d01469
commit
9548206532
@ -5,6 +5,7 @@
|
|||||||
## Особенности
|
## Особенности
|
||||||
|
|
||||||
- 🎯 Интерактивное меню с навигацией стрелками
|
- 🎯 Интерактивное меню с навигацией стрелками
|
||||||
|
- 🔄 Переключение между Kubernetes контекстами/кластерами
|
||||||
- ⭐ Избранные namespaces для быстрого доступа
|
- ⭐ Избранные namespaces для быстрого доступа
|
||||||
- 🎨 Красивый вывод с использованием Rich
|
- 🎨 Красивый вывод с использованием Rich
|
||||||
- 📦 Управление namespaces, deployments, pods, ConfigMaps
|
- 📦 Управление namespaces, deployments, pods, ConfigMaps
|
||||||
@ -57,6 +58,14 @@ poetry run k8s-tool
|
|||||||
|
|
||||||
### Основные функции
|
### Основные функции
|
||||||
|
|
||||||
|
#### Переключение контекста Kubernetes
|
||||||
|
Быстрое переключение между различными Kubernetes кластерами/контекстами:
|
||||||
|
- Просмотр всех доступных контекстов в виде таблицы
|
||||||
|
- Отображение текущего активного контекста (✓)
|
||||||
|
- Переключение на другой контекст
|
||||||
|
- Автоматическая переинициализация подключения к новому кластеру
|
||||||
|
- После переключения контекста namespace сбрасывается и нужно выбрать заново
|
||||||
|
|
||||||
#### Выбор Namespace
|
#### Выбор Namespace
|
||||||
Выберите namespace для работы. Все последующие операции будут выполняться в выбранном namespace.
|
Выберите namespace для работы. Все последующие операции будут выполняться в выбранном namespace.
|
||||||
|
|
||||||
|
|||||||
@ -19,11 +19,52 @@ class K8sClient:
|
|||||||
config.load_kube_config()
|
config.load_kube_config()
|
||||||
self.v1 = client.CoreV1Api()
|
self.v1 = client.CoreV1Api()
|
||||||
self.apps_v1 = client.AppsV1Api()
|
self.apps_v1 = client.AppsV1Api()
|
||||||
console.print("[green]✓[/green] Connected to Kubernetes cluster")
|
self.current_context = self.get_current_context()
|
||||||
|
console.print(f"[green]✓[/green] Connected to Kubernetes cluster")
|
||||||
|
if self.current_context:
|
||||||
|
console.print(f"[dim]Current context: {self.current_context}[/dim]")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
console.print(f"[red]✗[/red] Failed to connect to Kubernetes: {e}")
|
console.print(f"[red]✗[/red] Failed to connect to Kubernetes: {e}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
def get_contexts(self) -> List[Dict[str, str]]:
|
||||||
|
"""Get list of available contexts."""
|
||||||
|
try:
|
||||||
|
contexts, active_context = config.list_kube_config_contexts()
|
||||||
|
return [{
|
||||||
|
'name': ctx['name'],
|
||||||
|
'cluster': ctx['context'].get('cluster', ''),
|
||||||
|
'user': ctx['context'].get('user', ''),
|
||||||
|
'is_active': ctx['name'] == active_context['name']
|
||||||
|
} for ctx in contexts]
|
||||||
|
except Exception as e:
|
||||||
|
console.print(f"[red]Error fetching contexts:[/red] {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
def get_current_context(self) -> Optional[str]:
|
||||||
|
"""Get current context name."""
|
||||||
|
try:
|
||||||
|
contexts, active_context = config.list_kube_config_contexts()
|
||||||
|
return active_context['name'] if active_context else None
|
||||||
|
except Exception as e:
|
||||||
|
console.print(f"[red]Error getting current context:[/red] {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def switch_context(self, context_name: str) -> bool:
|
||||||
|
"""Switch to a different context."""
|
||||||
|
try:
|
||||||
|
# Load the new context
|
||||||
|
config.load_kube_config(context=context_name)
|
||||||
|
# Reinitialize API clients
|
||||||
|
self.v1 = client.CoreV1Api()
|
||||||
|
self.apps_v1 = client.AppsV1Api()
|
||||||
|
self.current_context = context_name
|
||||||
|
console.print(f"[green]✓[/green] Switched to context: [cyan]{context_name}[/cyan]")
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
console.print(f"[red]Error switching context:[/red] {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
def get_namespaces(self) -> List[str]:
|
def get_namespaces(self) -> List[str]:
|
||||||
"""Get list of all namespaces."""
|
"""Get list of all namespaces."""
|
||||||
try:
|
try:
|
||||||
@ -232,3 +273,22 @@ class K8sClient:
|
|||||||
)
|
)
|
||||||
|
|
||||||
console.print(table)
|
console.print(table)
|
||||||
|
|
||||||
|
def display_contexts_table(self, contexts: List[Dict[str, str]]):
|
||||||
|
"""Display contexts in a table."""
|
||||||
|
table = Table(title="Kubernetes Contexts")
|
||||||
|
table.add_column("Name", style="cyan")
|
||||||
|
table.add_column("Cluster", style="magenta")
|
||||||
|
table.add_column("User", style="yellow")
|
||||||
|
table.add_column("Active", style="green")
|
||||||
|
|
||||||
|
for ctx in contexts:
|
||||||
|
active_mark = "✓" if ctx['is_active'] else ""
|
||||||
|
table.add_row(
|
||||||
|
ctx['name'],
|
||||||
|
ctx['cluster'],
|
||||||
|
ctx['user'],
|
||||||
|
active_mark
|
||||||
|
)
|
||||||
|
|
||||||
|
console.print(table)
|
||||||
|
|||||||
@ -63,12 +63,18 @@ class K8sTool:
|
|||||||
|
|
||||||
def _main_menu(self):
|
def _main_menu(self):
|
||||||
"""Display main menu."""
|
"""Display main menu."""
|
||||||
|
# Display current context
|
||||||
|
current_context = self.k8s_client.current_context or "[dim]unknown[/dim]"
|
||||||
|
console.print(f"[bold]Current context:[/bold] [cyan]{current_context}[/cyan]")
|
||||||
|
|
||||||
|
# Display current namespace
|
||||||
namespace_info = f"[cyan]{self.current_namespace}[/cyan]" if self.current_namespace else "[dim]not selected[/dim]"
|
namespace_info = f"[cyan]{self.current_namespace}[/cyan]" if self.current_namespace else "[dim]not selected[/dim]"
|
||||||
is_favorite = self.config.is_favorite(self.current_namespace) if self.current_namespace else False
|
is_favorite = self.config.is_favorite(self.current_namespace) if self.current_namespace else False
|
||||||
fav_indicator = " ⭐" if is_favorite else ""
|
fav_indicator = " ⭐" if is_favorite else ""
|
||||||
console.print(f"\n[bold]Current namespace:[/bold] {namespace_info}{fav_indicator}")
|
console.print(f"[bold]Current namespace:[/bold] {namespace_info}{fav_indicator}")
|
||||||
|
|
||||||
choices = [
|
choices = [
|
||||||
|
"Switch Context",
|
||||||
"Select Namespace",
|
"Select Namespace",
|
||||||
"Manage Favorites",
|
"Manage Favorites",
|
||||||
"List Deployments",
|
"List Deployments",
|
||||||
@ -86,7 +92,9 @@ class K8sTool:
|
|||||||
style=custom_style
|
style=custom_style
|
||||||
).ask()
|
).ask()
|
||||||
|
|
||||||
if action == "Select Namespace":
|
if action == "Switch Context":
|
||||||
|
self._switch_context()
|
||||||
|
elif action == "Select Namespace":
|
||||||
self._select_namespace()
|
self._select_namespace()
|
||||||
elif action == "Manage Favorites":
|
elif action == "Manage Favorites":
|
||||||
self._manage_favorites()
|
self._manage_favorites()
|
||||||
@ -144,6 +152,40 @@ class K8sTool:
|
|||||||
fav_text = " (favorite)" if is_fav else ""
|
fav_text = " (favorite)" if is_fav else ""
|
||||||
console.print(f"[green]✓[/green] Namespace set to: [cyan]{namespace}[/cyan]{fav_text}")
|
console.print(f"[green]✓[/green] Namespace set to: [cyan]{namespace}[/cyan]{fav_text}")
|
||||||
|
|
||||||
|
def _switch_context(self):
|
||||||
|
"""Switch Kubernetes context."""
|
||||||
|
console.print("[dim]Fetching contexts...[/dim]")
|
||||||
|
contexts = self.k8s_client.get_contexts()
|
||||||
|
|
||||||
|
if not contexts:
|
||||||
|
console.print("[red]No contexts found[/red]")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Show contexts table
|
||||||
|
self.k8s_client.display_contexts_table(contexts)
|
||||||
|
|
||||||
|
# Filter out current context for selection
|
||||||
|
available_contexts = [ctx['name'] for ctx in contexts if not ctx['is_active']]
|
||||||
|
|
||||||
|
if not available_contexts:
|
||||||
|
console.print("[yellow]Only one context available[/yellow]")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Add option to view current
|
||||||
|
choices = available_contexts + [questionary.Separator(), "Cancel"]
|
||||||
|
|
||||||
|
selected = questionary.select(
|
||||||
|
"Select context to switch to:",
|
||||||
|
choices=choices,
|
||||||
|
style=custom_style
|
||||||
|
).ask()
|
||||||
|
|
||||||
|
if selected and selected != "Cancel":
|
||||||
|
if self.k8s_client.switch_context(selected):
|
||||||
|
# Reset namespace selection after context switch
|
||||||
|
self.current_namespace = None
|
||||||
|
console.print("[yellow]Note:[/yellow] Namespace selection reset. Please select a namespace.")
|
||||||
|
|
||||||
def _manage_favorites(self):
|
def _manage_favorites(self):
|
||||||
"""Manage favorite namespaces."""
|
"""Manage favorite namespaces."""
|
||||||
choices = []
|
choices = []
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user