diff --git a/src/components/ClusterNodesComponent.tsx b/src/components/ClusterNodesComponent.tsx
index 032d04a..789551e 100644
--- a/src/components/ClusterNodesComponent.tsx
+++ b/src/components/ClusterNodesComponent.tsx
@@ -4,7 +4,7 @@ import { Button } from './ui/button';
import { Badge } from './ui/badge';
import { Alert } from './ui/alert';
import { Input } from './ui/input';
-import { Cpu, HardDrive, Network, Monitor, CheckCircle, AlertCircle, BookOpen, ExternalLink, Loader2 } from 'lucide-react';
+import { Cpu, HardDrive, Network, Monitor, CheckCircle, AlertCircle, BookOpen, ExternalLink, Loader2, RotateCcw } from 'lucide-react';
import { useInstanceContext } from '../hooks/useInstanceContext';
import { useNodes, useDiscoveryStatus } from '../hooks/useNodes';
import { useCluster } from '../hooks/useCluster';
@@ -36,6 +36,8 @@ export function ClusterNodesComponent() {
updateNode,
applyNode,
isApplying,
+ resetNode,
+ isResetting,
refetch
} = useNodes(currentInstance);
@@ -194,14 +196,12 @@ export function ClusterNodesComponent() {
nodeName: drawerState.node.hostname,
updates: {
role: data.role,
- config: {
- disk: data.disk,
- target_ip: data.targetIp,
- current_ip: data.currentIp,
- interface: data.interface,
- schematic_id: data.schematicId,
- maintenance: data.maintenance,
- },
+ disk: data.disk,
+ target_ip: data.targetIp,
+ current_ip: data.currentIp,
+ interface: data.interface,
+ schematic_id: data.schematicId,
+ maintenance: data.maintenance,
},
});
closeDrawer();
@@ -214,6 +214,16 @@ export function ClusterNodesComponent() {
await applyNode(drawerState.node.hostname);
};
+ const handleResetNode = (node: Node) => {
+ if (
+ confirm(
+ `Reset node ${node.hostname}?\n\nThis will wipe the node and return it to maintenance mode. The node will need to be reconfigured.`
+ )
+ ) {
+ resetNode(node.hostname);
+ }
+ };
+
const handleDeleteNode = (hostname: string) => {
if (!currentInstance) return;
if (confirm(`Are you sure you want to remove node ${hostname}?`)) {
@@ -576,10 +586,21 @@ export function ClusterNodesComponent() {
)}
)}
- {node.talosVersion && (
+ {(node.version || node.schematic_id) && (
- Talos: {node.talosVersion}
- {node.kubernetesVersion && ` • K8s: ${node.kubernetesVersion}`}
+ {node.version && Talos: {node.version}}
+ {node.version && node.schematic_id && • }
+ {node.schematic_id && (
+ {
+ navigator.clipboard.writeText(node.schematic_id!);
+ }}
+ className="cursor-pointer hover:text-primary hover:underline"
+ >
+ Schema: {node.schematic_id.substring(0, 8)}...
+
+ )}
)}
@@ -600,6 +621,18 @@ export function ClusterNodesComponent() {
{isApplying ? : 'Apply'}
)}
+ {!node.maintenance && (node.configured || node.applied) && (
+
+ )}