update(app): refactor commands
This commit is contained in:
88
README.md
88
README.md
@@ -1,31 +1,103 @@
|
|||||||
# metalcheck-cli
|
# MetalCheck CLI
|
||||||
|
|
||||||
CLI tool for managing and visualizing Metal Check data"
|
**MetalCheck** CLI is a command-line tool for managing and visualizing Metal Check data, including physical nodes, virtual machines, and Kubernetes clusters.
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
|
Install the tool locally using pip:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
pip install -e .
|
pip install -e .
|
||||||
```
|
```
|
||||||
|
|
||||||
## Uninstallation
|
## Uninstallation
|
||||||
|
|
||||||
|
To remove the tool:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
pip uninstall metalcheck-cli
|
pip uninstall metalcheck-cli
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
|
||||||
|
You can configure the base URL for the Metal Check API by creating a configuration file at `~/.config/metalcheck.conf`:
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
[DEFAULT]
|
||||||
|
base_url = http://localhost:8000
|
||||||
|
```
|
||||||
|
|
||||||
|
If no configuration is provided, the CLI defaults to `http://localhost:8000`.
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
|
General Command Structure
|
||||||
|
|
||||||
```plaintext
|
```plaintext
|
||||||
Usage: metalcheck [OPTIONS] COMMAND [ARGS]...
|
Usage: metalcheck [OPTIONS] COMMAND [ARGS]...
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--help Show help message
|
--base-url TEXT Set the base URL for the Metal Check API (default: http://localhost:8000)
|
||||||
|
--help Show this message and exit.
|
||||||
|
|
||||||
Commands:
|
Commands:
|
||||||
export Export Metal Check data in the specified format (yaml or json).
|
export Export Metal Check data in the specified format (yaml or json)
|
||||||
k8s Commands for managing Kubernetes Nodes.
|
k8s Commands for managing Kubernetes Nodes
|
||||||
metal Commands for managing Metal Nodes.
|
metal Commands for managing Metal Nodes
|
||||||
visual Displays the visual dashboard with Metal Nodes, Virtual...
|
visual Displays the visual dashboard with Metal Nodes, Virtual Machines, and Kubernetes Nodes
|
||||||
vm Commands for managing Virtual Machines.
|
vm Commands for managing Virtual Machines
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
1. List Metal Nodes
|
||||||
|
|
||||||
|
```shell
|
||||||
|
metalcheck metal list
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Add a new Metal Node
|
||||||
|
|
||||||
|
```shell
|
||||||
|
metalcheck metal add
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Delete a Metal Node
|
||||||
|
|
||||||
|
```shell
|
||||||
|
metalcheck metal delete
|
||||||
|
```
|
||||||
|
|
||||||
|
4. List Kubernetes Nodes
|
||||||
|
|
||||||
|
```shell
|
||||||
|
metalcheck k8s list
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Analyze Kubernetes Cluster
|
||||||
|
|
||||||
|
```shell
|
||||||
|
metalcheck k8s think
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
6. Export Data
|
||||||
|
|
||||||
|
```shell
|
||||||
|
metalcheck export --format yaml exported-data.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
7. Visual Dashboard
|
||||||
|
|
||||||
|
Run the interactive dashboard to visualize Metal Nodes, Virtual Machines, and Kubernetes Nodes:
|
||||||
|
|
||||||
|
|
||||||
|
```shell
|
||||||
|
metalcheck visual
|
||||||
|
```
|
||||||
|
|
||||||
|
Run visual with the AI summary for Kubernetes cluster:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
metalcheck visual --summary
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import click
|
import click
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
BASE_URL = "http://localhost:8000/export" # Backend URL for exporting data
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
@click.option(
|
@click.option(
|
||||||
"--format",
|
"--format",
|
||||||
@@ -11,15 +9,20 @@ BASE_URL = "http://localhost:8000/export" # Backend URL for exporting data
|
|||||||
help="Specify the export format: yaml or json. Default is json.",
|
help="Specify the export format: yaml or json. Default is json.",
|
||||||
)
|
)
|
||||||
@click.argument("output", required=False, type=click.Path(writable=True))
|
@click.argument("output", required=False, type=click.Path(writable=True))
|
||||||
def export_data(format, output):
|
@click.pass_context
|
||||||
|
def export_data(ctx, format, output):
|
||||||
"""
|
"""
|
||||||
Export Metal Check data in the specified format (yaml or json).
|
Export Metal Check data in the specified format (yaml or json).
|
||||||
|
|
||||||
If an OUTPUT file is provided, the data will be saved to the file.
|
If an OUTPUT file is provided, the data will be saved to the file.
|
||||||
Otherwise, it will be printed to the console.
|
Otherwise, it will be printed to the console.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
base_url = ctx.obj["BASE_URL"]
|
||||||
|
export_url = f"{base_url}/export"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = requests.get(f"{BASE_URL}?format={format}")
|
response = requests.get(f"{export_url}?format={format}")
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
data = response.text
|
data = response.text
|
||||||
if output:
|
if output:
|
||||||
@@ -33,4 +36,3 @@ def export_data(format, output):
|
|||||||
click.echo(f"Error: {response.status_code} - {response.text}")
|
click.echo(f"Error: {response.status_code} - {response.text}")
|
||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
click.echo(f"Error: {e}")
|
click.echo(f"Error: {e}")
|
||||||
|
|
||||||
|
|||||||
@@ -1,33 +1,31 @@
|
|||||||
import click
|
import click
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
BASE_URL = "http://localhost:8000/k8s" # Backend URL for Kubernetes API
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
def kubernetes_nodes():
|
@click.pass_context
|
||||||
|
def kubernetes_nodes(ctx):
|
||||||
"""Commands for managing Kubernetes Nodes."""
|
"""Commands for managing Kubernetes Nodes."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@kubernetes_nodes.command("list")
|
@kubernetes_nodes.command("list")
|
||||||
def list_command():
|
@click.pass_context
|
||||||
handle_command("list")
|
def list_command(ctx):
|
||||||
|
|
||||||
@kubernetes_nodes.command("think")
|
|
||||||
def think_command():
|
|
||||||
handle_command("think")
|
|
||||||
|
|
||||||
|
|
||||||
def handle_command(action):
|
|
||||||
"""Handle commands related to Kubernetes nodes."""
|
|
||||||
if action == "list":
|
|
||||||
list_kubernetes_nodes()
|
|
||||||
elif action == "analyze":
|
|
||||||
analyze_kubernetes_cluster()
|
|
||||||
|
|
||||||
def list_kubernetes_nodes():
|
|
||||||
"""List all Kubernetes nodes."""
|
"""List all Kubernetes nodes."""
|
||||||
|
base_url = ctx.obj["BASE_URL"]
|
||||||
|
list_kubernetes_nodes(base_url)
|
||||||
|
|
||||||
|
@kubernetes_nodes.command("analyze")
|
||||||
|
@click.pass_context
|
||||||
|
def analyze_command(ctx):
|
||||||
|
"""Request an AI analysis of the Kubernetes cluster."""
|
||||||
|
base_url = ctx.obj["BASE_URL"]
|
||||||
|
analyze_kubernetes_cluster(base_url)
|
||||||
|
|
||||||
|
def list_kubernetes_nodes(base_url):
|
||||||
|
"""List all Kubernetes nodes."""
|
||||||
|
k8s_url = f"{base_url}/k8s/data"
|
||||||
try:
|
try:
|
||||||
response = requests.get(f"{BASE_URL}/data")
|
response = requests.get(k8s_url)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
nodes = response.json().get("nodes", [])
|
nodes = response.json().get("nodes", [])
|
||||||
click.echo("\n📦 Kubernetes Nodes:")
|
click.echo("\n📦 Kubernetes Nodes:")
|
||||||
@@ -43,10 +41,11 @@ def list_kubernetes_nodes():
|
|||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
click.echo(f"Error: {e}")
|
click.echo(f"Error: {e}")
|
||||||
|
|
||||||
def analyze_kubernetes_cluster():
|
def analyze_kubernetes_cluster(base_url):
|
||||||
"""Request an AI analysis of the Kubernetes cluster."""
|
"""Request an AI analysis of the Kubernetes cluster."""
|
||||||
|
analyze_url = f"{base_url}/think/k8s"
|
||||||
try:
|
try:
|
||||||
response = requests.get(f"{BASE_URL}/think/k8s")
|
response = requests.get(analyze_url)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
summary = response.json().get("summary", "No analysis provided.")
|
summary = response.json().get("summary", "No analysis provided.")
|
||||||
click.echo("\n🤖 AI Analysis of Kubernetes Cluster:")
|
click.echo("\n🤖 AI Analysis of Kubernetes Cluster:")
|
||||||
|
|||||||
@@ -1,38 +1,38 @@
|
|||||||
import click
|
import click
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
BASE_URL = "http://localhost:8000/metal" # Backend URL for Metal Nodes API
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
def metal_nodes():
|
@click.pass_context
|
||||||
|
def metal_nodes(ctx):
|
||||||
"""Commands for managing Metal Nodes."""
|
"""Commands for managing Metal Nodes."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@metal_nodes.command("list")
|
@metal_nodes.command("list")
|
||||||
def list_command():
|
@click.pass_context
|
||||||
handle_command("list")
|
def list_command(ctx):
|
||||||
|
"""List all metal nodes."""
|
||||||
|
base_url = ctx.obj["BASE_URL"]
|
||||||
|
list_metal_nodes(base_url)
|
||||||
|
|
||||||
@metal_nodes.command("add")
|
@metal_nodes.command("add")
|
||||||
def add_command():
|
@click.pass_context
|
||||||
handle_command("add")
|
def add_command(ctx):
|
||||||
|
"""Add a new metal node."""
|
||||||
|
base_url = ctx.obj["BASE_URL"]
|
||||||
|
add_metal_node(base_url)
|
||||||
|
|
||||||
@metal_nodes.command("delete")
|
@metal_nodes.command("delete")
|
||||||
def delete_command():
|
@click.pass_context
|
||||||
handle_command("delete")
|
def delete_command(ctx):
|
||||||
|
"""Delete a metal node."""
|
||||||
|
base_url = ctx.obj["BASE_URL"]
|
||||||
|
delete_metal_node(base_url)
|
||||||
|
|
||||||
def handle_command(action):
|
def list_metal_nodes(base_url):
|
||||||
"""Handle commands related to Metal Nodes."""
|
|
||||||
if action == "list":
|
|
||||||
list_metal_nodes()
|
|
||||||
elif action == "add":
|
|
||||||
add_metal_node()
|
|
||||||
elif action == "delete":
|
|
||||||
delete_metal_node()
|
|
||||||
|
|
||||||
def list_metal_nodes():
|
|
||||||
"""List all metal nodes."""
|
"""List all metal nodes."""
|
||||||
|
metal_url = f"{base_url}/metal/data"
|
||||||
try:
|
try:
|
||||||
response = requests.get(f"{BASE_URL}/data")
|
response = requests.get(metal_url)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
metal_nodes = response.json().get("metal_nodes", [])
|
metal_nodes = response.json().get("metal_nodes", [])
|
||||||
click.echo("\n🖥️ Metal Nodes:")
|
click.echo("\n🖥️ Metal Nodes:")
|
||||||
@@ -47,8 +47,9 @@ def list_metal_nodes():
|
|||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
click.echo(f"Error: {e}")
|
click.echo(f"Error: {e}")
|
||||||
|
|
||||||
def add_metal_node():
|
def add_metal_node(base_url):
|
||||||
"""Add a new metal node."""
|
"""Add a new metal node."""
|
||||||
|
metal_url = f"{base_url}/metal/data"
|
||||||
try:
|
try:
|
||||||
# Gather inputs from the prompt
|
# Gather inputs from the prompt
|
||||||
name = click.prompt("Name")
|
name = click.prompt("Name")
|
||||||
@@ -72,7 +73,7 @@ def add_metal_node():
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Send the POST request to the backend
|
# Send the POST request to the backend
|
||||||
response = requests.post(f"{BASE_URL}/data", json=data)
|
response = requests.post(metal_url, json=data)
|
||||||
|
|
||||||
if response.status_code in [200, 201]:
|
if response.status_code in [200, 201]:
|
||||||
response_data = response.json()
|
response_data = response.json()
|
||||||
@@ -83,11 +84,12 @@ def add_metal_node():
|
|||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
click.echo(f"Error: {e}")
|
click.echo(f"Error: {e}")
|
||||||
|
|
||||||
def delete_metal_node():
|
def delete_metal_node(base_url):
|
||||||
"""Delete a metal node."""
|
"""Delete a metal node."""
|
||||||
|
metal_url = f"{base_url}/metal/data"
|
||||||
try:
|
try:
|
||||||
node_id = click.prompt("Enter the ID of the metal node to delete", type=int)
|
node_id = click.prompt("Enter the ID of the metal node to delete", type=int)
|
||||||
response = requests.delete(f"{BASE_URL}/data/{node_id}")
|
response = requests.delete(f"{metal_url}/{node_id}")
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
click.echo("✅ Metal node deleted successfully!")
|
click.echo("✅ Metal node deleted successfully!")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1,38 +1,38 @@
|
|||||||
import click
|
import click
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
BASE_URL = "http://localhost:8000/vm" # Backend URL for Virtual Machines API
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
def virtual_machines():
|
@click.pass_context
|
||||||
|
def virtual_machines(ctx):
|
||||||
"""Commands for managing Virtual Machines."""
|
"""Commands for managing Virtual Machines."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@virtual_machines.command("list")
|
@virtual_machines.command("list")
|
||||||
def list_command():
|
@click.pass_context
|
||||||
handle_command("list")
|
def list_command(ctx):
|
||||||
|
"""List all virtual machines."""
|
||||||
|
base_url = ctx.obj["BASE_URL"]
|
||||||
|
list_virtual_machines(base_url)
|
||||||
|
|
||||||
@virtual_machines.command("add")
|
@virtual_machines.command("add")
|
||||||
def add_command():
|
@click.pass_context
|
||||||
handle_command("add")
|
def add_command(ctx):
|
||||||
|
"""Add a new virtual machine."""
|
||||||
|
base_url = ctx.obj["BASE_URL"]
|
||||||
|
add_virtual_machine(base_url)
|
||||||
|
|
||||||
@virtual_machines.command("delete")
|
@virtual_machines.command("delete")
|
||||||
def delete_command():
|
@click.pass_context
|
||||||
handle_command("delete")
|
def delete_command(ctx):
|
||||||
|
"""Delete a virtual machine."""
|
||||||
|
base_url = ctx.obj["BASE_URL"]
|
||||||
|
delete_virtual_machine(base_url)
|
||||||
|
|
||||||
def handle_command(action):
|
def list_virtual_machines(base_url):
|
||||||
"""Handle commands related to Virtual Machines."""
|
|
||||||
if action == "list":
|
|
||||||
list_virtual_machines()
|
|
||||||
elif action == "add":
|
|
||||||
add_virtual_machine()
|
|
||||||
elif action == "delete":
|
|
||||||
delete_virtual_machine()
|
|
||||||
|
|
||||||
def list_virtual_machines():
|
|
||||||
"""List all virtual machines."""
|
"""List all virtual machines."""
|
||||||
|
vm_url = f"{base_url}/vm/data"
|
||||||
try:
|
try:
|
||||||
response = requests.get(f"{BASE_URL}/data")
|
response = requests.get(vm_url)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
virtual_machines = response.json().get("virtual_machines", [])
|
virtual_machines = response.json().get("virtual_machines", [])
|
||||||
click.echo("\n💻 Virtual Machines:")
|
click.echo("\n💻 Virtual Machines:")
|
||||||
@@ -47,8 +47,9 @@ def list_virtual_machines():
|
|||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
click.echo(f"Error: {e}")
|
click.echo(f"Error: {e}")
|
||||||
|
|
||||||
def add_virtual_machine():
|
def add_virtual_machine(base_url):
|
||||||
"""Add a new virtual machine."""
|
"""Add a new virtual machine."""
|
||||||
|
vm_url = f"{base_url}/vm/data"
|
||||||
try:
|
try:
|
||||||
name = click.prompt("Name")
|
name = click.prompt("Name")
|
||||||
location = click.prompt("Location")
|
location = click.prompt("Location")
|
||||||
@@ -66,7 +67,7 @@ def add_virtual_machine():
|
|||||||
"type": vm_type,
|
"type": vm_type,
|
||||||
}
|
}
|
||||||
|
|
||||||
response = requests.post(f"{BASE_URL}/data", json=data)
|
response = requests.post(vm_url, json=data)
|
||||||
if response.status_code in [200, 201]:
|
if response.status_code in [200, 201]:
|
||||||
response_data = response.json()
|
response_data = response.json()
|
||||||
message = response_data.get("message", "Virtual machine added successfully!")
|
message = response_data.get("message", "Virtual machine added successfully!")
|
||||||
@@ -76,11 +77,12 @@ def add_virtual_machine():
|
|||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
click.echo(f"Error: {e}")
|
click.echo(f"Error: {e}")
|
||||||
|
|
||||||
def delete_virtual_machine():
|
def delete_virtual_machine(base_url):
|
||||||
"""Delete a virtual machine."""
|
"""Delete a virtual machine."""
|
||||||
|
vm_url = f"{base_url}/vm/data"
|
||||||
try:
|
try:
|
||||||
vm_id = click.prompt("Enter the ID of the virtual machine to delete", type=int)
|
vm_id = click.prompt("Enter the ID of the virtual machine to delete", type=int)
|
||||||
response = requests.delete(f"{BASE_URL}/data/{vm_id}")
|
response = requests.delete(f"{vm_url}/{vm_id}")
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
click.echo("✅ Virtual machine deleted successfully!")
|
click.echo("✅ Virtual machine deleted successfully!")
|
||||||
else:
|
else:
|
||||||
|
|||||||
22
cli/main.py
22
cli/main.py
@@ -1,3 +1,5 @@
|
|||||||
|
import os
|
||||||
|
import configparser
|
||||||
import click
|
import click
|
||||||
from .commands.metal import metal_nodes
|
from .commands.metal import metal_nodes
|
||||||
from .commands.vm import virtual_machines
|
from .commands.vm import virtual_machines
|
||||||
@@ -5,13 +7,29 @@ from .commands.k8s import kubernetes_nodes
|
|||||||
from .commands.export import export_data
|
from .commands.export import export_data
|
||||||
from .visual import visual_dashboard
|
from .visual import visual_dashboard
|
||||||
|
|
||||||
|
# Default configuration file path
|
||||||
|
CONFIG_FILE_PATH = os.path.expanduser("~/.config/metalcheck.conf")
|
||||||
|
|
||||||
|
# Load configuration
|
||||||
|
def load_config():
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
if os.path.exists(CONFIG_FILE_PATH):
|
||||||
|
config.read(CONFIG_FILE_PATH)
|
||||||
|
return config
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
def cli():
|
@click.option("--base-url", help="Set the backend base URL.")
|
||||||
|
@click.pass_context
|
||||||
|
def cli(ctx, base_url):
|
||||||
"""
|
"""
|
||||||
Metal Check CLI: A command-line interface for managing and monitoring Metal Check resources.
|
Metal Check CLI: A command-line interface for managing and monitoring Metal Check resources.
|
||||||
"""
|
"""
|
||||||
pass
|
config = load_config()
|
||||||
|
|
||||||
|
# Default backend URL
|
||||||
|
default_base_url = config.get("DEFAULT", "base_url", fallback="http://localhost:8000")
|
||||||
|
ctx.ensure_object(dict)
|
||||||
|
ctx.obj["BASE_URL"] = base_url or default_base_url
|
||||||
|
|
||||||
# Register commands
|
# Register commands
|
||||||
cli.add_command(metal_nodes, name="metal")
|
cli.add_command(metal_nodes, name="metal")
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
import click
|
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
from rich.progress import Progress
|
from rich.progress import Progress
|
||||||
import requests
|
import requests
|
||||||
|
import click
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
# Define constants
|
|
||||||
BACKEND_BASE_URL = "http://localhost:8000"
|
|
||||||
THINK_K8S_URL = f"{BACKEND_BASE_URL}/think/k8s"
|
|
||||||
METAL_NODES_URL = f"{BACKEND_BASE_URL}/metal/data"
|
|
||||||
VM_URL = f"{BACKEND_BASE_URL}/vm/data"
|
|
||||||
K8S_URL = f"{BACKEND_BASE_URL}/k8s/data"
|
|
||||||
|
|
||||||
console = Console()
|
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
|
# Helper functions for formatting
|
||||||
def calculate_time_on_duty_hours(hours):
|
def calculate_time_on_duty_hours(hours):
|
||||||
if hours < 1:
|
if hours < 1:
|
||||||
@@ -29,7 +31,7 @@ def calculate_time_on_duty_hours(hours):
|
|||||||
return f"{int(days)} days"
|
return f"{int(days)} days"
|
||||||
|
|
||||||
# Fetch and display metal nodes
|
# Fetch and display metal nodes
|
||||||
def display_metal_nodes():
|
def display_metal_nodes(metal_nodes_url):
|
||||||
table = Table(title="🖥️ Metal Nodes", style="bold green")
|
table = Table(title="🖥️ Metal Nodes", style="bold green")
|
||||||
table.add_column("ID", justify="right", style="cyan")
|
table.add_column("ID", justify="right", style="cyan")
|
||||||
table.add_column("Name", style="magenta")
|
table.add_column("Name", style="magenta")
|
||||||
@@ -41,7 +43,7 @@ def display_metal_nodes():
|
|||||||
table.add_column("Time on Duty", justify="right", style="magenta")
|
table.add_column("Time on Duty", justify="right", style="magenta")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = requests.get(METAL_NODES_URL)
|
response = requests.get(metal_nodes_url)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
metal_nodes = response.json().get("metal_nodes", [])
|
metal_nodes = response.json().get("metal_nodes", [])
|
||||||
for node in metal_nodes:
|
for node in metal_nodes:
|
||||||
@@ -64,7 +66,7 @@ def display_metal_nodes():
|
|||||||
console.print(table)
|
console.print(table)
|
||||||
|
|
||||||
# Fetch and display virtual machines
|
# Fetch and display virtual machines
|
||||||
def display_virtual_machines():
|
def display_virtual_machines(vm_url):
|
||||||
table = Table(title="💻 Virtual Machines", style="bold blue")
|
table = Table(title="💻 Virtual Machines", style="bold blue")
|
||||||
table.add_column("ID", justify="right", style="cyan")
|
table.add_column("ID", justify="right", style="cyan")
|
||||||
table.add_column("Name", style="magenta")
|
table.add_column("Name", style="magenta")
|
||||||
@@ -75,7 +77,7 @@ def display_virtual_machines():
|
|||||||
table.add_column("Type", style="green")
|
table.add_column("Type", style="green")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = requests.get(VM_URL)
|
response = requests.get(vm_url)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
virtual_machines = response.json().get("virtual_machines", [])
|
virtual_machines = response.json().get("virtual_machines", [])
|
||||||
for vm in virtual_machines:
|
for vm in virtual_machines:
|
||||||
@@ -96,7 +98,7 @@ def display_virtual_machines():
|
|||||||
console.print(table)
|
console.print(table)
|
||||||
|
|
||||||
# Fetch and display Kubernetes nodes
|
# Fetch and display Kubernetes nodes
|
||||||
def display_kubernetes_nodes():
|
def display_kubernetes_nodes(k8s_url):
|
||||||
table = Table(title="📦 Kubernetes Nodes", style="bold yellow")
|
table = Table(title="📦 Kubernetes Nodes", style="bold yellow")
|
||||||
table.add_column("Node Name", style="white")
|
table.add_column("Node Name", style="white")
|
||||||
table.add_column("CPU", justify="right", style="yellow")
|
table.add_column("CPU", justify="right", style="yellow")
|
||||||
@@ -107,7 +109,7 @@ def display_kubernetes_nodes():
|
|||||||
table.add_column("Time on Duty", justify="right", style="magenta")
|
table.add_column("Time on Duty", justify="right", style="magenta")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = requests.get(K8S_URL)
|
response = requests.get(k8s_url)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
nodes = response.json().get("nodes", [])
|
nodes = response.json().get("nodes", [])
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
@@ -128,7 +130,7 @@ def display_kubernetes_nodes():
|
|||||||
console.print(table)
|
console.print(table)
|
||||||
|
|
||||||
# Fetch and display AI summary
|
# Fetch and display AI summary
|
||||||
def display_ai_summary():
|
def display_ai_summary(think_k8s_url):
|
||||||
with Progress() as progress:
|
with Progress() as progress:
|
||||||
task = progress.add_task("[cyan]Fetching AI Summary...", total=100)
|
task = progress.add_task("[cyan]Fetching AI Summary...", total=100)
|
||||||
|
|
||||||
@@ -137,7 +139,7 @@ def display_ai_summary():
|
|||||||
progress.update(task, advance=10)
|
progress.update(task, advance=10)
|
||||||
import time; time.sleep(0.1)
|
import time; time.sleep(0.1)
|
||||||
|
|
||||||
response = requests.get(THINK_K8S_URL)
|
response = requests.get(think_k8s_url)
|
||||||
progress.update(task, completed=100)
|
progress.update(task, completed=100)
|
||||||
|
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
@@ -153,15 +155,19 @@ def display_ai_summary():
|
|||||||
# Click command for visual dashboard
|
# Click command for visual dashboard
|
||||||
@click.command()
|
@click.command()
|
||||||
@click.option('--summary', is_flag=True, help="Include AI summary in the dashboard.")
|
@click.option('--summary', is_flag=True, help="Include AI summary in the dashboard.")
|
||||||
def visual_dashboard(summary):
|
@click.pass_context
|
||||||
|
def visual_dashboard(ctx, summary):
|
||||||
"""
|
"""
|
||||||
Displays the visual dashboard with Metal Nodes, Virtual Machines,
|
Displays the visual dashboard with Metal Nodes, Virtual Machines,
|
||||||
Kubernetes Nodes, and optionally AI Summary.
|
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")
|
console.print("✨ [bold green]Welcome to the Metal Check Dashboard![/bold green] ✨\n")
|
||||||
display_metal_nodes()
|
display_metal_nodes(urls["METAL_NODES_URL"])
|
||||||
display_virtual_machines()
|
display_virtual_machines(urls["VM_URL"])
|
||||||
display_kubernetes_nodes()
|
display_kubernetes_nodes(urls["K8S_URL"])
|
||||||
|
|
||||||
if summary:
|
if summary:
|
||||||
display_ai_summary()
|
display_ai_summary(urls["THINK_K8S_URL"])
|
||||||
|
|||||||
Reference in New Issue
Block a user