Nodes
This commit is contained in:
+13
-1
@@ -13,9 +13,21 @@ export async function read<T extends object>(
|
||||
await fs.access(filePath);
|
||||
} catch {
|
||||
await fs.mkdir(dirPath, { recursive: true });
|
||||
await fs.writeFile(filePath, JSON.stringify(template, null, 2), "utf-8");
|
||||
await fs.writeFile(filePath, JSON.stringify(template(), null, 2), "utf-8");
|
||||
}
|
||||
|
||||
const content = await fs.readFile(filePath, "utf-8");
|
||||
return JSON.parse(content);
|
||||
}
|
||||
|
||||
export async function write<T extends object>(
|
||||
val: T,
|
||||
fp: string,
|
||||
...filePaths: string[]
|
||||
) {
|
||||
const filePath = path.join(process.cwd(), fp, ...filePaths);
|
||||
const dirPath = path.dirname(filePath);
|
||||
|
||||
await fs.mkdir(dirPath, { recursive: true });
|
||||
await fs.writeFile(filePath, JSON.stringify(val, null, 2), "utf-8");
|
||||
}
|
||||
|
||||
+23
-36
@@ -16,6 +16,9 @@ import {
|
||||
} from "lucide-react";
|
||||
import { Progress } from "@/components/ui/progress";
|
||||
import Link from "next/link";
|
||||
import { getLiveNodes, getNodes } from "@/core/client/node";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Node, NodeLiveData } from "@/lib/types";
|
||||
|
||||
const recentDeployments = [
|
||||
{
|
||||
@@ -86,34 +89,13 @@ const applications = [
|
||||
},
|
||||
];
|
||||
|
||||
const nodes = [
|
||||
{
|
||||
name: "node-01",
|
||||
ip: "10.0.1.10",
|
||||
cpu: 72,
|
||||
memory: 68,
|
||||
containers: 8,
|
||||
status: "running" as const,
|
||||
},
|
||||
{
|
||||
name: "node-02",
|
||||
ip: "10.0.1.11",
|
||||
cpu: 45,
|
||||
memory: 52,
|
||||
containers: 6,
|
||||
status: "running" as const,
|
||||
},
|
||||
{
|
||||
name: "node-03",
|
||||
ip: "10.0.1.12",
|
||||
cpu: 89,
|
||||
memory: 85,
|
||||
containers: 12,
|
||||
status: "running" as const,
|
||||
},
|
||||
];
|
||||
|
||||
export default function OverviewPage() {
|
||||
const [nodes, setNodes] = useState<NodeLiveData[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
getLiveNodes().then(setNodes);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<DashboardLayout title="Overview" subtitle="System status and metrics">
|
||||
{/* Stats Grid */}
|
||||
@@ -246,7 +228,7 @@ export default function OverviewPage() {
|
||||
>
|
||||
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between mb-3 gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<StatusIndicator status={node.status} />
|
||||
<StatusIndicator status={node.liveData.status} />
|
||||
<span className="font-mono text-sm">{node.name}</span>
|
||||
</div>
|
||||
<span className="text-xs text-muted-foreground font-mono">
|
||||
@@ -256,20 +238,25 @@ export default function OverviewPage() {
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<span className="text-muted-foreground">CPU</span>
|
||||
<span className="font-mono">{node.cpu}%</span>
|
||||
</div>
|
||||
<Progress value={node.cpu} className="[&>div]:bg-chart-1" />
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<span className="text-muted-foreground">Memory</span>
|
||||
<span className="font-mono">{node.memory}%</span>
|
||||
<span className="font-mono">{node.liveData.cpu}%</span>
|
||||
</div>
|
||||
<Progress
|
||||
value={node.memory}
|
||||
value={node.liveData.cpu}
|
||||
className="[&>div]:bg-chart-1"
|
||||
/>
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<span className="text-muted-foreground">Memory</span>
|
||||
<span className="font-mono">{node.liveData.memory}%</span>
|
||||
</div>
|
||||
<Progress
|
||||
value={node.liveData.memory}
|
||||
className="w-full [&>div]:bg-chart-3"
|
||||
/>
|
||||
<div className="flex items-center justify-between text-xs pt-2 border-t border-border mt-2">
|
||||
<span className="text-muted-foreground">Containers</span>
|
||||
<span className="font-mono">{node.containers}</span>
|
||||
<span className="font-mono">
|
||||
{node.liveData.containers}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
"use server";
|
||||
|
||||
import axios from "axios";
|
||||
import { Node } from "@/lib/types";
|
||||
|
||||
export async function getDocker(node: Node): Promise<{ version: string }> {
|
||||
return await (
|
||||
await axios.get(`http://${node.ip}:3000/api/get-docker`, {
|
||||
headers: { Authorization: `ApiKey ${node.key}` },
|
||||
})
|
||||
).data;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
"use server";
|
||||
|
||||
import axios from "axios";
|
||||
|
||||
export async function getDocker(
|
||||
node_ip: string,
|
||||
key: string
|
||||
): Promise<{ version: string }> {
|
||||
return await (
|
||||
await axios.get(`http://${node_ip}:3000/api/get-docker`, {
|
||||
headers: { Authorization: `ApiKey ${key}` },
|
||||
})
|
||||
).data;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
"use server";
|
||||
|
||||
import { read, write } from "@/app/api/file";
|
||||
import { Node, NodeLiveData } from "@/lib/types";
|
||||
import axios from "axios";
|
||||
|
||||
export async function getNodes(): Promise<Node[]> {
|
||||
return await read(() => [], "data", "nodes.json");
|
||||
}
|
||||
|
||||
export async function setNodes(nodes: Node[]) {
|
||||
await write(nodes, "data", "nodes.json");
|
||||
}
|
||||
|
||||
export async function getNode(node_id: string): Promise<Node | undefined> {
|
||||
const nodes = await read<Node[]>(() => [], "data", "nodes.json");
|
||||
return nodes.find((v) => v.node_id === node_id);
|
||||
}
|
||||
|
||||
export async function getLiveNodes(): Promise<NodeLiveData[]> {
|
||||
const nodes = await read(() => [], "data", "nodes.json");
|
||||
return await Promise.all(nodes.map(getLiveNode));
|
||||
}
|
||||
|
||||
export async function getLiveNode(node: Node): Promise<NodeLiveData> {
|
||||
const data = await (
|
||||
await axios.get(`http://${node.ip}:3000/api/status`, {
|
||||
headers: { Authorization: `ApiKey ${node.key}` },
|
||||
})
|
||||
).data;
|
||||
return { ...node, liveData: data.liveData };
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
export interface Node {
|
||||
name: string;
|
||||
node_id: string;
|
||||
ip: string;
|
||||
key: string;
|
||||
}
|
||||
|
||||
export interface NodeLiveData {
|
||||
name: string;
|
||||
node_id: string;
|
||||
ip: string;
|
||||
key: string;
|
||||
liveData: {
|
||||
status: "running" | "pending" | "error";
|
||||
cpu: number;
|
||||
memory: number;
|
||||
disk: number;
|
||||
containers: number;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user