Refactor subnet discovery logic to allow auto-detection and improve error handling
This commit is contained in:
@@ -47,7 +47,7 @@ export function ClusterNodesComponent() {
|
|||||||
status: clusterStatus
|
status: clusterStatus
|
||||||
} = useCluster(currentInstance);
|
} = useCluster(currentInstance);
|
||||||
|
|
||||||
const [discoverSubnet, setDiscoverSubnet] = useState('192.168.8.0/24');
|
const [discoverSubnet, setDiscoverSubnet] = useState('');
|
||||||
const [addNodeIp, setAddNodeIp] = useState('');
|
const [addNodeIp, setAddNodeIp] = useState('');
|
||||||
const [discoverError, setDiscoverError] = useState<string | null>(null);
|
const [discoverError, setDiscoverError] = useState<string | null>(null);
|
||||||
const [detectError, setDetectError] = useState<string | null>(null);
|
const [detectError, setDetectError] = useState<string | null>(null);
|
||||||
@@ -92,9 +92,9 @@ export function ClusterNodesComponent() {
|
|||||||
if (prevDiscoveryActive === true && isActive === false && discoveryStatus) {
|
if (prevDiscoveryActive === true && isActive === false && discoveryStatus) {
|
||||||
const count = discoveryStatus.nodes_found?.length || 0;
|
const count = discoveryStatus.nodes_found?.length || 0;
|
||||||
if (count === 0) {
|
if (count === 0) {
|
||||||
setDiscoverSuccess(`Discovery complete! No nodes were found in the subnet.`);
|
setDiscoverSuccess(`Discovery complete! No nodes were found.`);
|
||||||
} else {
|
} else {
|
||||||
setDiscoverSuccess(`Discovery complete! Found ${count} node${count !== 1 ? 's' : ''} in subnet.`);
|
setDiscoverSuccess(`Discovery complete! Found ${count} node${count !== 1 ? 's' : ''}.`);
|
||||||
}
|
}
|
||||||
setDiscoverError(null);
|
setDiscoverError(null);
|
||||||
refetch();
|
refetch();
|
||||||
@@ -224,7 +224,8 @@ export function ClusterNodesComponent() {
|
|||||||
const handleDiscover = () => {
|
const handleDiscover = () => {
|
||||||
setDiscoverError(null);
|
setDiscoverError(null);
|
||||||
setDiscoverSuccess(null);
|
setDiscoverSuccess(null);
|
||||||
discover(discoverSubnet);
|
// Pass subnet only if it's not empty, otherwise auto-detect
|
||||||
|
discover(discoverSubnet || undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -421,7 +422,7 @@ export function ClusterNodesComponent() {
|
|||||||
Discover Nodes on Network
|
Discover Nodes on Network
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
<p className="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
||||||
Scan a subnet to find nodes in maintenance mode
|
Scan a specific subnet or leave empty to auto-detect all local networks
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="flex gap-3 mb-4">
|
<div className="flex gap-3 mb-4">
|
||||||
@@ -429,7 +430,7 @@ export function ClusterNodesComponent() {
|
|||||||
type="text"
|
type="text"
|
||||||
value={discoverSubnet}
|
value={discoverSubnet}
|
||||||
onChange={(e) => setDiscoverSubnet(e.target.value)}
|
onChange={(e) => setDiscoverSubnet(e.target.value)}
|
||||||
placeholder="192.168.8.0/24"
|
placeholder="192.168.1.0/24 (optional - leave empty to auto-detect)"
|
||||||
className="flex-1"
|
className="flex-1"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -12,18 +12,14 @@ export function useNodes(instanceName: string | null | undefined) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const discoverMutation = useMutation({
|
const discoverMutation = useMutation({
|
||||||
mutationFn: (subnet: string) => nodesApi.discover(instanceName!, subnet),
|
mutationFn: (subnet?: string) => nodesApi.discover(instanceName!, subnet),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['instances', instanceName, 'discovery'] });
|
queryClient.invalidateQueries({ queryKey: ['instances', instanceName, 'discovery'] });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const detectMutation = useMutation({
|
const detectMutation = useMutation({
|
||||||
mutationFn: (ip?: string) => nodesApi.detect(instanceName!, ip),
|
mutationFn: (ip: string) => nodesApi.detect(instanceName!, ip),
|
||||||
});
|
|
||||||
|
|
||||||
const autoDetectMutation = useMutation({
|
|
||||||
mutationFn: () => nodesApi.autoDetect(instanceName!),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const addMutation = useMutation({
|
const addMutation = useMutation({
|
||||||
@@ -88,10 +84,6 @@ export function useNodes(instanceName: string | null | undefined) {
|
|||||||
isDetecting: detectMutation.isPending,
|
isDetecting: detectMutation.isPending,
|
||||||
detectResult: detectMutation.data,
|
detectResult: detectMutation.data,
|
||||||
detectError: detectMutation.error,
|
detectError: detectMutation.error,
|
||||||
autoDetect: autoDetectMutation.mutate,
|
|
||||||
isAutoDetecting: autoDetectMutation.isPending,
|
|
||||||
autoDetectResult: autoDetectMutation.data,
|
|
||||||
autoDetectError: autoDetectMutation.error,
|
|
||||||
getHardware: getHardwareMutation.mutateAsync,
|
getHardware: getHardwareMutation.mutateAsync,
|
||||||
isGettingHardware: getHardwareMutation.isPending,
|
isGettingHardware: getHardwareMutation.isPending,
|
||||||
getHardwareError: getHardwareMutation.error,
|
getHardwareError: getHardwareMutation.error,
|
||||||
|
|||||||
@@ -35,17 +35,13 @@ export const nodesApi = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Discovery
|
// Discovery
|
||||||
async discover(instanceName: string, subnet: string): Promise<OperationResponse> {
|
async discover(instanceName: string, subnet?: string): Promise<OperationResponse> {
|
||||||
return apiClient.post(`/api/v1/instances/${instanceName}/nodes/discover`, { subnet });
|
const body = subnet ? { subnet } : {};
|
||||||
|
return apiClient.post(`/api/v1/instances/${instanceName}/nodes/discover`, body);
|
||||||
},
|
},
|
||||||
|
|
||||||
async detect(instanceName: string, ip?: string): Promise<OperationResponse> {
|
async detect(instanceName: string, ip: string): Promise<HardwareInfo> {
|
||||||
const body = ip ? { ip } : {};
|
return apiClient.post(`/api/v1/instances/${instanceName}/nodes/detect`, { ip });
|
||||||
return apiClient.post(`/api/v1/instances/${instanceName}/nodes/detect`, body);
|
|
||||||
},
|
|
||||||
|
|
||||||
async autoDetect(instanceName: string): Promise<{ networks: string[]; nodes: any[]; count: number }> {
|
|
||||||
return apiClient.post(`/api/v1/instances/${instanceName}/nodes/auto-detect`);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async discoveryStatus(instanceName: string): Promise<DiscoveryStatus> {
|
async discoveryStatus(instanceName: string): Promise<DiscoveryStatus> {
|
||||||
|
|||||||
@@ -108,10 +108,6 @@ export function mockUseNodes(nodes: Node[] = []) {
|
|||||||
isDetecting: false,
|
isDetecting: false,
|
||||||
detectResult: undefined,
|
detectResult: undefined,
|
||||||
detectError: null,
|
detectError: null,
|
||||||
autoDetect: vi.fn(),
|
|
||||||
isAutoDetecting: false,
|
|
||||||
autoDetectResult: undefined,
|
|
||||||
autoDetectError: null,
|
|
||||||
getHardware: vi.fn(),
|
getHardware: vi.fn(),
|
||||||
isGettingHardware: false,
|
isGettingHardware: false,
|
||||||
getHardwareError: null,
|
getHardwareError: null,
|
||||||
|
|||||||
Reference in New Issue
Block a user