fix:
--Removed hard coded node details
This commit is contained in:
1 parent
8f43344c84
commit
3b8e1dca3e
2 files changed
+87
-53
No files matched your search
+2
-2
@@ -616,8 +616,8 @@ function Workspace({ page: activePage }: { page: PageId | 'node-details' }) {
|
||||
Back to cluster
|
||||
</button>
|
||||
</div>
|
||||
{clusterDetails.nodes.some((node) => node.uuid === nodeId) && (
|
||||
<NodeConnections key={`${clusterId}/${nodeId}`} />
|
||||
{nodeId && clusterDetails.nodes.some((node) => node.uuid === nodeId) && (
|
||||
<NodeConnections key={`${clusterId}/${nodeId}`} nodeId={nodeId} />
|
||||
)}
|
||||
</section>
|
||||
)}
|
||||
|
||||
+85
-51
@@ -25,71 +25,105 @@ 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 [status, setStatus] = useState('Connecting to replication health…')
|
||||
const [status, setStatus] = useState('Loading node connection details…')
|
||||
const [error, setError] = useState('')
|
||||
const [attempt, setAttempt] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
let active = true
|
||||
let socket: WebSocket
|
||||
let socket: WebSocket | undefined
|
||||
const controller = new AbortController()
|
||||
|
||||
try {
|
||||
const baseUrl = import.meta.env.VITE_WS_BASE_URL
|
||||
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 = () => {
|
||||
if (!active) return
|
||||
setStatus('Waiting for replication health…')
|
||||
// Temporary connection details until the API supports the selected node.
|
||||
socket.send(JSON.stringify({
|
||||
node_name: 'node3',
|
||||
host: '172.16.10.178',
|
||||
port: 5444,
|
||||
dbname: 'postgres',
|
||||
user: 'postgres',
|
||||
password: 'postgres',
|
||||
}))
|
||||
}
|
||||
socket.onmessage = (event) => {
|
||||
if (!active) return
|
||||
const connect = async () => {
|
||||
try {
|
||||
const data: unknown = JSON.parse(event.data)
|
||||
if (!isReplicationHealth(data)) throw new Error('Invalid replication health response.')
|
||||
setHealth(data)
|
||||
setError('')
|
||||
setStatus('Live updates connected')
|
||||
} catch {
|
||||
setHealth(null)
|
||||
const apiBaseUrl = import.meta.env.VITE_API_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.')
|
||||
|
||||
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
|
||||
setStatus('Waiting for replication health…')
|
||||
connection.send(JSON.stringify({
|
||||
node_name: node.if_name,
|
||||
host: node.host,
|
||||
port: node.port,
|
||||
dbname: node.dbname,
|
||||
user: node.user,
|
||||
password: 'postgres',
|
||||
}))
|
||||
}
|
||||
connection.onmessage = (event) => {
|
||||
if (!active) return
|
||||
try {
|
||||
const data: unknown = JSON.parse(event.data)
|
||||
if (!isReplicationHealth(data)) throw new Error('Invalid replication health response.')
|
||||
setHealth(data)
|
||||
setError('')
|
||||
setStatus('Live updates connected')
|
||||
} catch {
|
||||
setHealth(null)
|
||||
setStatus('')
|
||||
setError('Received an invalid replication health response.')
|
||||
}
|
||||
}
|
||||
connection.onerror = () => {
|
||||
if (!active) return
|
||||
setHealth(null)
|
||||
setStatus('')
|
||||
setError('Unable to receive replication health. Check that the WebSocket server is running.')
|
||||
}
|
||||
connection.onclose = () => {
|
||||
if (!active) return
|
||||
setHealth(null)
|
||||
setStatus('')
|
||||
setError((current) => current || 'Replication health connection closed. Reconnect to receive updates.')
|
||||
}
|
||||
} catch (cause) {
|
||||
if (!active) return
|
||||
setStatus('')
|
||||
setError('Received an invalid replication health response.')
|
||||
setError(cause instanceof Error ? cause.message : 'Unable to load node connection details.')
|
||||
}
|
||||
}
|
||||
socket.onerror = () => {
|
||||
if (!active) return
|
||||
setHealth(null)
|
||||
setStatus('')
|
||||
setError('Unable to receive replication health. Check that the WebSocket server is running.')
|
||||
}
|
||||
socket.onclose = () => {
|
||||
if (!active) return
|
||||
setHealth(null)
|
||||
setStatus('')
|
||||
setError((current) => current || 'Replication health connection closed. Reconnect to receive updates.')
|
||||
}
|
||||
void connect()
|
||||
|
||||
return () => {
|
||||
active = false
|
||||
socket.close()
|
||||
controller.abort()
|
||||
socket?.close()
|
||||
}
|
||||
}, [attempt])
|
||||
}, [attempt, nodeId])
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -101,7 +135,7 @@ export default function NodeConnections() {
|
||||
<button className="secondary-button" type="button" onClick={() => {
|
||||
setHealth(null)
|
||||
setError('')
|
||||
setStatus('Connecting to replication health…')
|
||||
setStatus('Loading node connection details…')
|
||||
setAttempt((current) => current + 1)
|
||||
}}>
|
||||
Reconnect
|
||||
|
||||
Reference in new issue
Block a user