--Removed hard coded node details
This commit is contained in:
george committed 2026-09-22 13:09:40 +05:30
1 parent 8f43344c84
commit 3b8e1dca3e
2 files changed
+59 -25

No files matched your search

+2 -2
View File
@@ -616,8 +616,8 @@ function Workspace({ page: activePage }: { page: PageId | 'node-details' }) {
Back to cluster Back to cluster
</button> </button>
</div> </div>
{clusterDetails.nodes.some((node) => node.uuid === nodeId) && ( {nodeId && clusterDetails.nodes.some((node) => node.uuid === nodeId) && (
<NodeConnections key={`${clusterId}/${nodeId}`} /> <NodeConnections key={`${clusterId}/${nodeId}`} nodeId={nodeId} />
)} )}
</section> </section>
)} )}
+57 -23
View File
@@ -25,40 +25,66 @@ function isReplicationHealth(value: unknown): value is ReplicationHealth {
}) })
} }
export default function NodeConnections() { export default function NodeConnections({ nodeId }: { nodeId: string }) {
const [health, setHealth] = useState<ReplicationHealth | null>(null) const [health, setHealth] = useState<ReplicationHealth | null>(null)
const [status, setStatus] = useState('Connecting to replication health…') const [status, setStatus] = useState('Loading node connection details…')
const [error, setError] = useState('') const [error, setError] = useState('')
const [attempt, setAttempt] = useState(0) const [attempt, setAttempt] = useState(0)
useEffect(() => { useEffect(() => {
let active = true let active = true
let socket: WebSocket let socket: WebSocket | undefined
const controller = new AbortController()
const connect = async () => {
try { try {
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL
const baseUrl = import.meta.env.VITE_WS_BASE_URL const baseUrl = import.meta.env.VITE_WS_BASE_URL
if (!apiBaseUrl) throw new Error('VITE_API_BASE_URL is not configured.')
if (!baseUrl) throw new Error('VITE_WS_BASE_URL is not configured.') if (!baseUrl) throw new Error('VITE_WS_BASE_URL is not configured.')
socket = new WebSocket(`${baseUrl.replace(/\/$/, '')}/ws/node/replication-health`)
} catch (cause) {
setStatus('')
setError(cause instanceof Error ? cause.message : 'Unable to open replication health connection.')
return
}
socket.onopen = () => { const token = localStorage.getItem('access_token')
const response = await fetch(
`${apiBaseUrl.replace(/\/$/, '')}/spock/node-interfaces/${encodeURIComponent(nodeId)}`,
{
headers: token ? { Authorization: `Bearer ${token}` } : {},
signal: controller.signal,
},
)
if (!response.ok) {
throw new Error(response.status === 404
? 'Node not found.'
: `Failed to load node connection details (${response.status}).`)
}
const data = await response.json()
const node = data?.node
if (data?.status !== 'success' || !node
|| node.uuid !== nodeId
|| typeof node.if_name !== 'string'
|| typeof node.host !== 'string'
|| typeof node.port !== 'number'
|| typeof node.dbname !== 'string'
|| typeof node.user !== 'string') {
throw new Error('Invalid node connection details response.')
}
if (!active) return
setStatus('Connecting to replication health…')
const connection = new WebSocket(`${baseUrl.replace(/\/$/, '')}/ws/node/replication-health`)
socket = connection
connection.onopen = () => {
if (!active) return if (!active) return
setStatus('Waiting for replication health…') setStatus('Waiting for replication health…')
// Temporary connection details until the API supports the selected node. connection.send(JSON.stringify({
socket.send(JSON.stringify({ node_name: node.if_name,
node_name: 'node3', host: node.host,
host: '172.16.10.178', port: node.port,
port: 5444, dbname: node.dbname,
dbname: 'postgres', user: node.user,
user: 'postgres',
password: 'postgres', password: 'postgres',
})) }))
} }
socket.onmessage = (event) => { connection.onmessage = (event) => {
if (!active) return if (!active) return
try { try {
const data: unknown = JSON.parse(event.data) const data: unknown = JSON.parse(event.data)
@@ -72,24 +98,32 @@ export default function NodeConnections() {
setError('Received an invalid replication health response.') setError('Received an invalid replication health response.')
} }
} }
socket.onerror = () => { connection.onerror = () => {
if (!active) return if (!active) return
setHealth(null) setHealth(null)
setStatus('') setStatus('')
setError('Unable to receive replication health. Check that the WebSocket server is running.') setError('Unable to receive replication health. Check that the WebSocket server is running.')
} }
socket.onclose = () => { connection.onclose = () => {
if (!active) return if (!active) return
setHealth(null) setHealth(null)
setStatus('') setStatus('')
setError((current) => current || 'Replication health connection closed. Reconnect to receive updates.') setError((current) => current || 'Replication health connection closed. Reconnect to receive updates.')
} }
} catch (cause) {
if (!active) return
setStatus('')
setError(cause instanceof Error ? cause.message : 'Unable to load node connection details.')
}
}
void connect()
return () => { return () => {
active = false active = false
socket.close() controller.abort()
socket?.close()
} }
}, [attempt]) }, [attempt, nodeId])
return ( return (
<div> <div>
@@ -101,7 +135,7 @@ export default function NodeConnections() {
<button className="secondary-button" type="button" onClick={() => { <button className="secondary-button" type="button" onClick={() => {
setHealth(null) setHealth(null)
setError('') setError('')
setStatus('Connecting to replication health…') setStatus('Loading node connection details…')
setAttempt((current) => current + 1) setAttempt((current) => current + 1)
}}> }}>
Reconnect Reconnect