feat: add IPAM discovery from Proxmox with IP enrichment, improve workload insights, and enhance DataTable interactivity
Add /ipam/discover endpoint to automatically import IP addresses from Proxmox clusters with error tracking and audit logging, implement ensure_discovered_network helper to create "discovered-ipam" network for auto-discovered IPs, add import_discovered_ips function to parse IP interfaces and create subnet/address records with assignment tracking, enhance ProxmoxProvider.enrich_work
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
import { useState } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Activity, Server } from "lucide-react";
|
||||
import { Activity } from "lucide-react";
|
||||
|
||||
import { api, Workload, WorkloadInsight } from "../api/client";
|
||||
import { DataTable } from "../components/DataTable";
|
||||
import { secondaryButtonClass } from "../components/FormControls";
|
||||
import { PageHeader } from "../components/PageHeader";
|
||||
|
||||
export function Workloads() {
|
||||
@@ -25,15 +24,9 @@ export function Workloads() {
|
||||
<DataTable
|
||||
rows={(workloads.data ?? []) as unknown as Record<string, unknown>[]}
|
||||
columns={[{ key: "name", label: "Name" }, { key: "kind", label: "Kind" }, { key: "status", label: "Status" }, { key: "external_id", label: "VMID" }]}
|
||||
selectedId={selected}
|
||||
onRowClick={(row) => setSelectedId(String(row.id))}
|
||||
/>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{(workloads.data ?? []).map((workload) => (
|
||||
<button key={workload.id} className={secondaryButtonClass} onClick={() => setSelectedId(workload.id)}>
|
||||
<Server size={16} />
|
||||
{workload.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
<aside className="rounded-md border border-border bg-panel p-4">
|
||||
<div className="mb-4 flex items-center gap-2 font-medium"><Activity size={18} /> Workload Detail</div>
|
||||
@@ -46,12 +39,13 @@ export function Workloads() {
|
||||
<section>
|
||||
<div className="mb-2 font-medium">Traffic</div>
|
||||
<div className="space-y-2">
|
||||
{insight.data.traffic.map((flow, index) => (
|
||||
{insight.data.traffic.length ? insight.data.traffic.map((flow, index) => (
|
||||
<div key={index} className="rounded-md border border-border p-3">
|
||||
<div>{String(flow.source)} → {String(flow.destination)}</div>
|
||||
<div className="text-xs text-slate-500">{String(flow.protocol)}:{String(flow.port)} · {String(flow.bytes)} bytes · {String(flow.decision)}</div>
|
||||
{Array.isArray(flow.ip_addresses) ? <div className="mt-1 text-xs text-slate-500">IPs: {flow.ip_addresses.join(", ")}</div> : null}
|
||||
</div>
|
||||
))}
|
||||
)) : <div className="rounded-md border border-border p-3 text-xs text-slate-500">No real traffic telemetry has been collected yet. Install the node agent or enable a flow source to populate this section.</div>}
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
@@ -80,4 +74,3 @@ export function Workloads() {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user