Files
docker_dashboard/frontend/src/lib/netbox.ts

152 lines
4.2 KiB
TypeScript

export interface NetboxIP {
id: number;
address: string;
}
export interface NetboxCluster {
id: number;
name: string;
url: string;
}
export interface NetboxDevice {
id: number;
name: string;
url: string;
}
export interface NetboxCustomFields {
docker_run_command?: string;
docker_volumes?: string;
[key: string]: any;
}
export interface NetboxVM {
id: number;
name: string;
description?: string; // Kurze Beschreibung
comments?: string; // Markdown Kommentare
status: { value: string; label: string };
primary_ip?: NetboxIP;
primary_ip4?: NetboxIP;
cluster?: NetboxCluster;
device?: NetboxDevice; // Das Host-Gerät
custom_fields?: NetboxCustomFields;
netboxUrl?: string; // Computed URL to NetBox UI
}
export interface NetboxResponse<T> {
count: number;
next: string | null;
previous: string | null;
results: T[];
}
// Helper to group containers by host (device)
export type GroupedContainers = Record<string, NetboxVM[]>;
const MOCK_DATA: NetboxVM[] = [
{
id: 1,
name: "nginx-proxy",
description: "Reverse Proxy",
comments: "Dies ist ein **wichtiger** Container.\nBitte nicht stoppen!",
status: { value: "active", label: "Active" },
primary_ip4: { id: 10, address: "192.168.1.50/24" },
device: { id: 1, name: "docker-host-01", url: "" },
cluster: { id: 99, name: "Docker-Hosts", url: "" },
custom_fields: {
docker_run_command: "docker run -d -p 80:80 --name nginx-proxy nginx:latest",
docker_volumes: "-v /etc/nginx:/etc/nginx\n-v /var/log/nginx:/var/log/nginx"
},
netboxUrl: "#",
},
{
id: 2,
name: "postgres-db",
description: "DB Main",
status: { value: "active", label: "Active" },
primary_ip4: { id: 11, address: "192.168.1.51/24" },
device: { id: 1, name: "docker-host-01", url: "" },
cluster: { id: 99, name: "Docker-Hosts", url: "" },
custom_fields: {
docker_run_command: "docker run -d postgres:14",
},
netboxUrl: "#",
},
{
id: 3,
name: "grafana",
description: "Monitoring",
status: { value: "staged", label: "Staged" },
device: { id: 2, name: "docker-host-02", url: "" },
cluster: { id: 99, name: "Docker-Hosts", url: "" },
custom_fields: {
docker_run_command: "docker run -d grafana/grafana"
},
netboxUrl: "#",
},
];
export async function getDockerContainers(): Promise<GroupedContainers> {
const apiUrl = process.env.NETBOX_API_URL;
const apiToken = process.env.NETBOX_API_TOKEN;
if (!apiUrl || !apiToken) {
console.warn("NETBOX_API_URL or NETBOX_API_TOKEN not set. Using mock data.");
return groupContainers(MOCK_DATA);
}
try {
// Fetch VMs with role 'docker-container'.
const res = await fetch(
`${apiUrl}/api/virtualization/virtual-machines/?role=docker-container&limit=1000`,
{
headers: {
Authorization: `Token ${apiToken}`,
Accept: "application/json",
},
next: { revalidate: 10 }, // Short cache for testing
}
);
if (!res.ok) {
console.error("Failed to fetch from Netbox:", res.status, res.statusText);
return groupContainers(MOCK_DATA);
}
const data: NetboxResponse<NetboxVM> = await res.json();
// Compute NetBox UI URL
// Assumes apiUrl is something like "https://netbox.local/api" or "https://netbox.local/"
// We want "https://netbox.local/virtualization/virtual-machines/{id}/"
const baseUrl = apiUrl.replace(new RegExp("/api/?$"), "").replace(new RegExp("$"), "");
const enrichedResults = data.results.map(vm => ({
...vm,
netboxUrl: `${baseUrl}/virtualization/virtual-machines/${vm.id}/`
}));
return groupContainers(enrichedResults);
} catch (error) {
console.error("Error fetching netbox data:", error);
return groupContainers(MOCK_DATA);
}
}
function groupContainers(vms: NetboxVM[]): GroupedContainers {
const grouped: GroupedContainers = {};
vms.forEach((vm) => {
// Prioritize 'device' name, fallback to 'cluster' name, then "Unassigned"
const hostName = vm.device?.name || vm.cluster?.name || "Unassigned";
if (!grouped[hostName]) {
grouped[hostName] = [];
}
grouped[hostName].push(vm);
});
return grouped;
}