editing deployment
This commit is contained in:
parent
1374935d2d
commit
cc43885279
@ -339,6 +339,59 @@ class K8sClient:
|
||||
console.print(f"[red]Error scaling deployment:[/red] {e}")
|
||||
return False
|
||||
|
||||
def get_deployment_yaml(self, namespace: str, name: str) -> Optional[str]:
|
||||
"""Get deployment as YAML string."""
|
||||
try:
|
||||
from kubernetes import utils
|
||||
|
||||
deployment = self.apps_v1.read_namespaced_deployment(name, namespace)
|
||||
|
||||
# Convert to dict and remove managed fields and status
|
||||
deployment_dict = deployment.to_dict()
|
||||
|
||||
# Remove fields that shouldn't be edited
|
||||
if 'metadata' in deployment_dict:
|
||||
deployment_dict['metadata'].pop('managed_fields', None)
|
||||
deployment_dict['metadata'].pop('resource_version', None)
|
||||
deployment_dict['metadata'].pop('uid', None)
|
||||
deployment_dict['metadata'].pop('self_link', None)
|
||||
deployment_dict['metadata'].pop('creation_timestamp', None)
|
||||
deployment_dict['metadata'].pop('generation', None)
|
||||
|
||||
# Remove status
|
||||
deployment_dict.pop('status', None)
|
||||
|
||||
# Convert to YAML
|
||||
import yaml
|
||||
yaml_str = yaml.dump(deployment_dict, default_flow_style=False, sort_keys=False)
|
||||
return yaml_str
|
||||
except ApiException as e:
|
||||
console.print(f"[red]Error reading deployment:[/red] {e}")
|
||||
return None
|
||||
|
||||
def update_deployment_yaml(self, namespace: str, name: str, yaml_str: str) -> bool:
|
||||
"""Update deployment from YAML string."""
|
||||
try:
|
||||
import yaml
|
||||
|
||||
# Parse YAML
|
||||
deployment_dict = yaml.safe_load(yaml_str)
|
||||
|
||||
# Update deployment
|
||||
self.apps_v1.patch_namespaced_deployment(
|
||||
name=name,
|
||||
namespace=namespace,
|
||||
body=deployment_dict
|
||||
)
|
||||
console.print(f"[green]✓[/green] Deployment {name} updated successfully")
|
||||
return True
|
||||
except ApiException as e:
|
||||
console.print(f"[red]Error updating deployment:[/red] {e}")
|
||||
return False
|
||||
except yaml.YAMLError as e:
|
||||
console.print(f"[red]Error parsing YAML:[/red] {e}")
|
||||
return False
|
||||
|
||||
def get_pod_logs(self, namespace: str, pod_name: str, container: Optional[str] = None,
|
||||
tail_lines: int = 100) -> Optional[str]:
|
||||
"""Get logs from pod."""
|
||||
|
||||
@ -80,6 +80,7 @@ class K8sTool:
|
||||
"List Deployments",
|
||||
"Restart Deployment",
|
||||
"Scale Deployment",
|
||||
"Edit Deployment",
|
||||
"View ConfigMaps",
|
||||
"Edit ConfigMap",
|
||||
"View Pod Logs",
|
||||
@ -104,6 +105,8 @@ class K8sTool:
|
||||
self._restart_deployment()
|
||||
elif action == "Scale Deployment":
|
||||
self._scale_deployment()
|
||||
elif action == "Edit Deployment":
|
||||
self._edit_deployment()
|
||||
elif action == "View ConfigMaps":
|
||||
self._view_configmaps()
|
||||
elif action == "Edit ConfigMap":
|
||||
@ -134,14 +137,14 @@ class K8sTool:
|
||||
choices = []
|
||||
if fav_namespaces:
|
||||
choices.extend([f"⭐ {ns}" for ns in fav_namespaces])
|
||||
if other_namespaces:
|
||||
choices.append(questionary.Separator("─" * 40))
|
||||
choices.extend(other_namespaces)
|
||||
|
||||
selected = questionary.select(
|
||||
"Select namespace:",
|
||||
# Use autocomplete for filtering
|
||||
selected = questionary.autocomplete(
|
||||
"Select namespace (type to filter):",
|
||||
choices=choices,
|
||||
style=custom_style
|
||||
style=custom_style,
|
||||
match_middle=True
|
||||
).ask()
|
||||
|
||||
if selected:
|
||||
@ -554,6 +557,88 @@ class K8sTool:
|
||||
if replicas:
|
||||
self.k8s_client.scale_deployment(self.current_namespace, dep_name, int(replicas))
|
||||
|
||||
def _edit_deployment(self):
|
||||
"""Edit a deployment."""
|
||||
if not self._ensure_namespace_selected():
|
||||
return
|
||||
|
||||
console.print(f"[dim]Fetching deployments in {self.current_namespace}...[/dim]")
|
||||
deployments = self.k8s_client.get_deployments(self.current_namespace)
|
||||
|
||||
if not deployments:
|
||||
console.print("[yellow]No deployments found[/yellow]")
|
||||
return
|
||||
|
||||
dep_names = [dep['name'] for dep in deployments]
|
||||
dep_name = questionary.select(
|
||||
"Select deployment to edit:",
|
||||
choices=dep_names,
|
||||
style=custom_style
|
||||
).ask()
|
||||
|
||||
if not dep_name:
|
||||
return
|
||||
|
||||
# Get deployment YAML
|
||||
deployment_yaml = self.k8s_client.get_deployment_yaml(self.current_namespace, dep_name)
|
||||
if deployment_yaml:
|
||||
self._edit_deployment_yaml(dep_name, deployment_yaml)
|
||||
|
||||
def _edit_deployment_yaml(self, dep_name: str, current_yaml: str):
|
||||
"""Edit deployment YAML in text editor."""
|
||||
# Get editor from environment or use default
|
||||
editor = os.environ.get('EDITOR', os.environ.get('VISUAL', 'vi'))
|
||||
|
||||
# Create temporary file with deployment YAML
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as tf:
|
||||
temp_file = tf.name
|
||||
tf.write(current_yaml)
|
||||
|
||||
try:
|
||||
# Get modification time before editing
|
||||
mtime_before = os.path.getmtime(temp_file)
|
||||
|
||||
# Open editor
|
||||
subprocess.call([editor, temp_file])
|
||||
|
||||
# Check if file was modified
|
||||
mtime_after = os.path.getmtime(temp_file)
|
||||
|
||||
if mtime_after == mtime_before:
|
||||
console.print("[yellow]No changes made[/yellow]")
|
||||
return
|
||||
|
||||
# Read edited data
|
||||
with open(temp_file, 'r') as f:
|
||||
try:
|
||||
new_yaml = f.read()
|
||||
# Validate YAML
|
||||
yaml.safe_load(new_yaml)
|
||||
except yaml.YAMLError as e:
|
||||
console.print(f"[red]Error parsing YAML:[/red] {e}")
|
||||
if questionary.confirm("Retry editing?", style=custom_style, default=False).ask():
|
||||
self._edit_deployment_yaml(dep_name, current_yaml)
|
||||
return
|
||||
|
||||
# Show confirmation
|
||||
console.print("\n[bold]Deployment YAML has been modified[/bold]")
|
||||
console.print("[yellow]Warning:[/yellow] Editing deployment directly can be risky.")
|
||||
|
||||
# Confirm update
|
||||
if questionary.confirm(
|
||||
f"Apply changes to deployment '{dep_name}'?",
|
||||
style=custom_style,
|
||||
default=False
|
||||
).ask():
|
||||
self.k8s_client.update_deployment_yaml(self.current_namespace, dep_name, new_yaml)
|
||||
|
||||
finally:
|
||||
# Clean up temp file
|
||||
try:
|
||||
os.unlink(temp_file)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _view_configmaps(self):
|
||||
"""View ConfigMaps."""
|
||||
if not self._ensure_namespace_selected():
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user