This commit is contained in:
@@ -20,6 +20,16 @@ adminRoutes.get('/admin/tailscale/nodes', async (c) => {
|
||||
})
|
||||
})
|
||||
|
||||
adminRoutes.delete('/admin/tailscale/nodes/:nodeId', async (c) => {
|
||||
const nodeId = c.req.param('nodeId').trim()
|
||||
if (!nodeId) {
|
||||
return c.json({ error: 'node_id_required' }, 400)
|
||||
}
|
||||
|
||||
await headscaleNodeDiscovery.deleteNode(nodeId)
|
||||
return c.json({ deleted: true, nodeId })
|
||||
})
|
||||
|
||||
adminRoutes.get('/admin/tailscale/routes', async (c) => {
|
||||
return c.json({
|
||||
routes: await headscaleNodeDiscovery.listRouteStatus(),
|
||||
|
||||
@@ -71,6 +71,23 @@ class HeadscaleNodeDiscovery {
|
||||
})
|
||||
}
|
||||
|
||||
async deleteNode(nodeId: string): Promise<void> {
|
||||
if (!config.headscaleApiKey) {
|
||||
throw new Error('HEADSCALE_API_KEY is not configured')
|
||||
}
|
||||
|
||||
const encodedNodeId = encodeURIComponent(nodeId)
|
||||
let response = await this.fetchHeadscale(`/api/v1/node/${encodedNodeId}`, { method: 'DELETE' })
|
||||
if (response.status === 404) {
|
||||
response = await this.fetchHeadscale(`/api/v1/machine/${encodedNodeId}`, { method: 'DELETE' })
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
const detail = await response.text().catch(() => '')
|
||||
throw new Error(`Headscale node deletion failed (${response.status})${detail ? `: ${detail}` : ''}`)
|
||||
}
|
||||
}
|
||||
|
||||
async listRouteStatus(): Promise<HeadscaleRouteStatus[]> {
|
||||
const nodes = await this.listNodes()
|
||||
return nodes.flatMap((node) => {
|
||||
@@ -141,9 +158,10 @@ class HeadscaleNodeDiscovery {
|
||||
return this.extractNodeList(await response.json().catch(() => null))
|
||||
}
|
||||
|
||||
private fetchHeadscale(path: string) {
|
||||
private fetchHeadscale(path: string, init?: RequestInit) {
|
||||
return fetch(`${config.headscaleBaseUrl}${path}`, {
|
||||
headers: { authorization: `Bearer ${config.headscaleApiKey}` },
|
||||
...init,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user