152 lines
4.2 KiB
TypeScript
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;
|
|
} |