110 lines
3.2 KiB
Python
110 lines
3.2 KiB
Python
"""Proxmox Container-Status Tools."""
|
|
|
|
import re
|
|
from core import config, proxmox_client
|
|
|
|
TOOLS = [
|
|
{
|
|
"type": "function",
|
|
"function": {
|
|
"name": "get_all_containers",
|
|
"description": "Status aller Container auf allen Proxmox-Servern (running/stopped, RAM, Uptime)",
|
|
"parameters": {"type": "object", "properties": {}, "required": []},
|
|
},
|
|
},
|
|
{
|
|
"type": "function",
|
|
"function": {
|
|
"name": "get_container_detail",
|
|
"description": "Detail-Status eines einzelnen Containers. Suche per VMID (z.B. 101) oder Name (z.B. wordpress, rss-manager, forgejo)",
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"query": {"type": "string", "description": "VMID (z.B. '109') oder Container-Name (z.B. 'wordpress')"}
|
|
},
|
|
"required": ["query"],
|
|
},
|
|
},
|
|
},
|
|
]
|
|
|
|
|
|
def _cfg():
|
|
return config.parse_config()
|
|
|
|
|
|
def _tokens(cfg):
|
|
tokens = {}
|
|
tn = cfg.raw.get("PVE_TOKEN_HETZNER_NAME", "")
|
|
tv = cfg.raw.get("PVE_TOKEN_HETZNER_VALUE", "")
|
|
if tn and tv:
|
|
tokens["pve-hetzner"] = {"name": tn, "value": tv}
|
|
return tokens
|
|
|
|
|
|
def _passwords(cfg):
|
|
pw_default = cfg.passwords.get("default", "")
|
|
pw_hetzner = cfg.passwords.get("hetzner", pw_default)
|
|
pws = {"default": pw_default, "pve-hetzner": pw_hetzner}
|
|
for host in proxmox_client.PROXMOX_HOSTS:
|
|
if host not in pws:
|
|
pws[host] = pw_default
|
|
return pws
|
|
|
|
|
|
def handle_get_all_containers(**kw):
|
|
cfg = _cfg()
|
|
containers = proxmox_client.get_all_containers(_passwords(cfg), _tokens(cfg))
|
|
return proxmox_client.format_containers(containers)
|
|
|
|
|
|
def handle_get_container_detail(query, **kw):
|
|
cfg = _cfg()
|
|
vmid = None
|
|
name = None
|
|
m = re.search(r'\b(\d{3})\b', query)
|
|
if m:
|
|
vmid = int(m.group(1))
|
|
else:
|
|
name = query.strip()
|
|
|
|
ct = config.get_container(cfg, vmid=vmid, name=name)
|
|
if not ct:
|
|
return f"Container nicht gefunden: {query}"
|
|
|
|
host_ip = proxmox_client.PROXMOX_HOSTS.get(ct.host)
|
|
if not host_ip:
|
|
return f"Host nicht erreichbar: {ct.host}"
|
|
|
|
token = _tokens(cfg).get(ct.host, {})
|
|
pw = _passwords(cfg).get(ct.host, "")
|
|
try:
|
|
client = proxmox_client.ProxmoxClient(
|
|
host_ip, password=pw,
|
|
token_name=token.get("name", ""),
|
|
token_value=token.get("value", ""),
|
|
)
|
|
status = client.get_container_status(ct.vmid)
|
|
except Exception as e:
|
|
return f"Proxmox-Fehler: {e}"
|
|
|
|
mem_mb = status.get("mem", 0) // (1024 * 1024)
|
|
maxmem_mb = status.get("maxmem", 0) // (1024 * 1024)
|
|
uptime_h = status.get("uptime", 0) // 3600
|
|
|
|
return (
|
|
f"CT {ct.vmid} — {ct.name}\n"
|
|
f"Host: {ct.host}\n"
|
|
f"Status: {status.get('status', '?')}\n"
|
|
f"RAM: {mem_mb}/{maxmem_mb} MB\n"
|
|
f"CPU: {status.get('cpus', '?')} Kerne\n"
|
|
f"Uptime: {uptime_h}h\n"
|
|
f"Tailscale: {ct.tailscale_ip or '—'}\n"
|
|
f"Dienste: {ct.services}"
|
|
)
|
|
|
|
|
|
HANDLERS = {
|
|
"get_all_containers": handle_get_all_containers,
|
|
"get_container_detail": handle_get_container_detail,
|
|
}
|