feat: add initial setup wizard, workload insights, and policy audit mode
Add setup wizard with status tracking via SystemSetting model, implement /setup/status and /setup/complete endpoints to create initial admin user and optional cluster configuration, add workload insights endpoint with traffic analysis and policy matching including audit mode detection, implement enforcement_mode property on Policy model with audit/enforced states, add Modal component for dialogs, create SetupWizard page with multi
This commit is contained in:
+48
-23
@@ -1,7 +1,8 @@
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { QueryClient, QueryClientProvider, useQuery } from "@tanstack/react-query";
|
||||
import { useEffect } from "react";
|
||||
import { BrowserRouter, Route, Routes } from "react-router-dom";
|
||||
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
|
||||
|
||||
import { publicApi, SetupStatus } from "./api/client";
|
||||
import { Layout } from "./components/Layout";
|
||||
import { Dashboard } from "./pages/Dashboard";
|
||||
import { FirewallPreview } from "./pages/FirewallPreview";
|
||||
@@ -14,12 +15,56 @@ import { Policies } from "./pages/Policies";
|
||||
import { PolicyDesigner } from "./pages/PolicyDesigner";
|
||||
import { SecurityGroups } from "./pages/SecurityGroups";
|
||||
import { ServiceCatalog } from "./pages/ServiceCatalog";
|
||||
import { SetupWizard } from "./pages/SetupWizard";
|
||||
import { TenantsProjects } from "./pages/TenantsProjects";
|
||||
import { UsersRoles } from "./pages/UsersRoles";
|
||||
import { Workloads } from "./pages/Workloads";
|
||||
import { useTheme } from "./stores/theme";
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
function AppRoutes() {
|
||||
const setup = useQuery({ queryKey: ["setup-status"], queryFn: () => publicApi<SetupStatus>("/setup/status") });
|
||||
|
||||
if (setup.isLoading) {
|
||||
return <div className="grid min-h-screen place-items-center bg-canvas text-sm">Loading NexaFabric...</div>;
|
||||
}
|
||||
|
||||
if (!setup.data?.complete) {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/setup" element={<SetupWizard />} />
|
||||
<Route path="*" element={<Navigate to="/setup" replace />} />
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/setup" element={<Navigate to="/login" replace />} />
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route element={<Layout />}>
|
||||
<Route index element={<Dashboard />} />
|
||||
<Route path="clusters" element={<Clusters />} />
|
||||
<Route path="nodes" element={<ListPage title="Nodes" subtitle="Cluster nodes, capacity, and health." path="/nodes" columns={[{ key: "name", label: "Name" }, { key: "status", label: "Status" }, { key: "cpu_count", label: "CPU" }, { key: "memory_mb", label: "Memory MB" }]} />} />
|
||||
<Route path="workloads" element={<Workloads />} />
|
||||
<Route path="networks" element={<Networks />} />
|
||||
<Route path="ipam" element={<Ipam />} />
|
||||
<Route path="tenants" element={<TenantsProjects />} />
|
||||
<Route path="security-groups" element={<SecurityGroups />} />
|
||||
<Route path="policies" element={<Policies />} />
|
||||
<Route path="services" element={<ServiceCatalog />} />
|
||||
<Route path="designer" element={<PolicyDesigner />} />
|
||||
<Route path="firewall" element={<FirewallPreview />} />
|
||||
<Route path="jobs" element={<ListPage title="Jobs" subtitle="Background task state and execution logs." path="/jobs" columns={[{ key: "kind", label: "Kind" }, { key: "status", label: "Status" }, { key: "progress", label: "Progress" }]} />} />
|
||||
<Route path="audit" element={<ListPage title="Audit Logs" subtitle="Security-relevant activity and change history." path="/audit" columns={[{ key: "created_at", label: "Time" }, { key: "action", label: "Action" }, { key: "object_type", label: "Object" }, { key: "result", label: "Result" }]} />} />
|
||||
<Route path="users" element={<UsersRoles />} />
|
||||
<Route path="settings" element={<ListPage title="Settings" subtitle="Runtime settings and safety defaults." path="/settings" columns={[{ key: "product", label: "Product" }, { key: "firewall_apply_requires_preview", label: "Preview Required" }, { key: "agent_optional", label: "Agent Optional" }]} />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
|
||||
export function App() {
|
||||
const dark = useTheme((state) => state.dark);
|
||||
|
||||
@@ -30,27 +75,7 @@ export function App() {
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route element={<Layout />}>
|
||||
<Route index element={<Dashboard />} />
|
||||
<Route path="clusters" element={<Clusters />} />
|
||||
<Route path="nodes" element={<ListPage title="Nodes" subtitle="Cluster nodes, capacity, and health." path="/nodes" columns={[{ key: "name", label: "Name" }, { key: "status", label: "Status" }, { key: "cpu_count", label: "CPU" }, { key: "memory_mb", label: "Memory MB" }]} />} />
|
||||
<Route path="workloads" element={<ListPage title="VMs/LXCs" subtitle="Virtual machine and container inventory." path="/vms" columns={[{ key: "name", label: "Name" }, { key: "kind", label: "Kind" }, { key: "status", label: "Status" }, { key: "external_id", label: "VMID" }]} />} />
|
||||
<Route path="networks" element={<Networks />} />
|
||||
<Route path="ipam" element={<Ipam />} />
|
||||
<Route path="tenants" element={<TenantsProjects />} />
|
||||
<Route path="security-groups" element={<SecurityGroups />} />
|
||||
<Route path="policies" element={<Policies />} />
|
||||
<Route path="services" element={<ServiceCatalog />} />
|
||||
<Route path="designer" element={<PolicyDesigner />} />
|
||||
<Route path="firewall" element={<FirewallPreview />} />
|
||||
<Route path="jobs" element={<ListPage title="Jobs" subtitle="Background task state and execution logs." path="/jobs" columns={[{ key: "kind", label: "Kind" }, { key: "status", label: "Status" }, { key: "progress", label: "Progress" }]} />} />
|
||||
<Route path="audit" element={<ListPage title="Audit Logs" subtitle="Security-relevant activity and change history." path="/audit" columns={[{ key: "created_at", label: "Time" }, { key: "action", label: "Action" }, { key: "object_type", label: "Object" }, { key: "result", label: "Result" }]} />} />
|
||||
<Route path="users" element={<UsersRoles />} />
|
||||
<Route path="settings" element={<ListPage title="Settings" subtitle="Runtime settings and safety defaults." path="/settings" columns={[{ key: "product", label: "Product" }, { key: "firewall_apply_requires_preview", label: "Preview Required" }, { key: "agent_optional", label: "Agent Optional" }]} />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
<AppRoutes />
|
||||
</BrowserRouter>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user