Files
metalcheck-cli/cli/visual.py
2024-12-11 12:56:18 +00:00

174 lines
6.5 KiB
Python

from rich.console import Console
from rich.table import Table
from rich.progress import Progress
import requests
import click
from datetime import datetime, timezone
console = Console()
# Helper function to set backend URLs
def get_backend_urls(base_url):
return {
"THINK_K8S_URL": f"{base_url}/think/k8s",
"METAL_NODES_URL": f"{base_url}/metal/data",
"VM_URL": f"{base_url}/vm/data",
"K8S_URL": f"{base_url}/k8s/data",
}
# Helper functions for formatting
def calculate_time_on_duty_hours(hours):
if hours < 1:
minutes = round(hours * 60)
return f"{minutes} minutes" if minutes > 1 else "less than a minute"
elif hours < 24:
return f"{round(hours)} hours" if hours > 1 else "1 hour"
else:
days = hours // 24
remaining_hours = hours % 24
if remaining_hours:
return f"{int(days)} days {int(remaining_hours)} hours"
return f"{int(days)} days"
# Fetch and display metal nodes
def display_metal_nodes(metal_nodes_url):
table = Table(title="🖥️ Metal Nodes", style="bold green")
table.add_column("ID", justify="right", style="cyan")
table.add_column("Name", style="magenta")
table.add_column("Location", style="white")
table.add_column("Vendor", style="green")
table.add_column("CPU", justify="right", style="yellow")
table.add_column("Memory (GB)", justify="right", style="cyan")
table.add_column("Storage", style="magenta")
table.add_column("Time on Duty", justify="right", style="magenta")
try:
response = requests.get(metal_nodes_url)
if response.status_code == 200:
metal_nodes = response.json().get("metal_nodes", [])
for node in metal_nodes:
time_on_duty = calculate_time_on_duty_hours(node[7])
table.add_row(
f"{node[0]}",
node[1],
node[2],
node[3],
f"{node[4]}",
node[5],
node[6],
time_on_duty,
)
else:
console.print(f"[red]Failed to fetch metal nodes: {response.status_code}[/red]")
except requests.RequestException as e:
console.print(f"[red]Error fetching metal nodes: {e}[/red]")
console.print(table)
# Fetch and display virtual machines
def display_virtual_machines(vm_url):
table = Table(title="💻 Virtual Machines", style="bold blue")
table.add_column("ID", justify="right", style="cyan")
table.add_column("Name", style="magenta")
table.add_column("Location", style="white")
table.add_column("CPU", justify="right", style="yellow")
table.add_column("Memory (GB)", justify="right", style="cyan")
table.add_column("Storage", style="magenta")
table.add_column("Type", style="green")
try:
response = requests.get(vm_url)
if response.status_code == 200:
virtual_machines = response.json().get("virtual_machines", [])
for vm in virtual_machines:
table.add_row(
f"{vm[0]}",
vm[1],
vm[2],
f"{vm[3]}",
vm[4],
vm[5],
vm[6],
)
else:
console.print(f"[red]Failed to fetch virtual machines: {response.status_code}[/red]")
except requests.RequestException as e:
console.print(f"[red]Error fetching virtual machines: {e}[/red]")
console.print(table)
# Fetch and display Kubernetes nodes
def display_kubernetes_nodes(k8s_url):
table = Table(title="📦 Kubernetes Nodes", style="bold yellow")
table.add_column("Node Name", style="white")
table.add_column("CPU", justify="right", style="yellow")
table.add_column("Memory (MiB)", justify="right", style="cyan")
table.add_column("Storage (GB)", justify="right", style="green")
table.add_column("Type", style="blue")
table.add_column("Max Pods", justify="right", style="magenta")
table.add_column("Time on Duty", justify="right", style="magenta")
try:
response = requests.get(k8s_url)
if response.status_code == 200:
nodes = response.json().get("nodes", [])
for node in nodes:
table.add_row(
node["node_name"],
node["cpu"],
f"{node['memory']}",
f"{node['storage']}",
node["instance_type"],
node["pods_allocatable"],
node.get("time_on_duty", "N/A"),
)
else:
console.print(f"[red]Failed to fetch Kubernetes nodes: {response.status_code}[/red]")
except requests.RequestException as e:
console.print(f"[red]Error fetching Kubernetes nodes: {e}[/red]")
console.print(table)
# Fetch and display AI summary
def display_ai_summary(think_k8s_url):
with Progress() as progress:
task = progress.add_task("[cyan]Fetching AI Summary...", total=100)
try:
for _ in range(10): # Simulate progress
progress.update(task, advance=10)
import time; time.sleep(0.1)
response = requests.get(think_k8s_url)
progress.update(task, completed=100)
if response.status_code == 200:
data = response.json()
summary = data.get("summary", "No summary provided.")
console.print("\n[bold magenta]AI Summary of Kubernetes Cluster:[/bold magenta]")
console.print(f"[green]{summary}[/green]\n")
else:
console.print(f"[red]Failed to fetch AI summary: {response.status_code}[/red]")
except requests.RequestException as e:
console.print(f"[red]Error fetching AI summary: {e}[/red]")
# Click command for visual dashboard
@click.command()
@click.option('--summary', is_flag=True, help="Include AI summary in the dashboard.")
@click.pass_context
def visual_dashboard(ctx, summary):
"""
Displays the visual dashboard with Metal Nodes, Virtual Machines,
Kubernetes Nodes, and optionally AI Summary.
"""
base_url = ctx.obj["BASE_URL"]
urls = get_backend_urls(base_url)
console.print("✨ [bold green]Welcome to the Metal Check Dashboard![/bold green] ✨\n")
display_metal_nodes(urls["METAL_NODES_URL"])
display_virtual_machines(urls["VM_URL"])
display_kubernetes_nodes(urls["K8S_URL"])
if summary:
display_ai_summary(urls["THINK_K8S_URL"])