feat(rest-api): add add_host route to pools (#9876)

This commit is contained in:
spacotte-vates
2026-06-08 11:29:31 +02:00
committed by GitHub
parent 7adcf9afd3
commit 53be744746
7 changed files with 66 additions and 11 deletions

View File

@@ -119,6 +119,12 @@ export type XsPatches = {
}
export interface Xapi {
status: string
pool?: { uuid: string }
sessionId: string
_auth: { user: string; password: string }
_url: { protocol: string; hostname: string; hostnameRaw: string; port?: string }
call: <ReturnType>(...args: unknown[]) => Promise<ReturnType>
callAsync: <ReturnType>(...args: unknown[]) => Promise<ReturnType>
@@ -176,6 +182,7 @@ export interface Xapi {
bypassAssert?: boolean
}
): Promise<void>
joinPool(masterAddress: string, masterUsername: string, masterPassword: string, force?: boolean): Promise<void>
listMissingPatches(host: XoHost['id']): Promise<XcpPatches[] | XsPatches[]>
pool_emergencyShutdown(): Promise<void>
resumeVm(id: XoVm['id']): Promise<void>

View File

@@ -50,13 +50,6 @@ import {
XoUserRole,
} from './index.mjs'
export type XapiConnection = Xapi & {
status: string
pool?: { uuid: string }
sessionId: string
_url?: { protocol: string; hostname: string; port?: string }
}
type FeatureCode =
| 'BACKUP.DELTA'
| 'BACKUP.DELTA_REPLICATION'
@@ -376,7 +369,7 @@ export type XoApp = {
url?: string
}
): Promise<XoBackupRepository>
getAllXapis(): Record<string, XapiConnection>
getAllXapis(): Record<string, Xapi>
getObjects(opts?: { filter?: Record<string, unknown>; limit?: number }): Record<string, XapiXoRecord>
getLicenses(params?: { productType?: LicenseProductType }): Promise<License[]>
bindLicense(params: { licenseId: string; boundObjectId: string }): Promise<License>

View File

@@ -6,6 +6,7 @@ export default {
export: {
logs: true,
},
'join-pool': true,
read: true,
update: {
tags: true,

View File

@@ -1,4 +1,5 @@
export default {
'add-host': true,
create: {
network: true,
vm: true,

View File

@@ -808,4 +808,56 @@ export class PoolController extends XapiXoController<XoPool> {
},
})
}
/**
* Required privileges:
* - resource: pool, action: add-host
* - resource: host, action: join-pool
*
* Add a host to the pool.
*
* @example id "355ee47d-ff4c-4924-3db2-fd86ae629676"
* @example body { "host": "c787b75c-3e0d-70fa-d0c3-cbfd382d7e33", "force": "false" }
*/
@Example(taskLocation)
@Post('{id}/actions/add_host')
@Middlewares([
json(),
acl([
{ resource: 'pool', action: 'add-host', objectId: 'params.id' },
{ resource: 'host', action: 'join-pool', objectId: 'body.host' },
]),
])
@SuccessResponse(asynchronousActionResp.status, asynchronousActionResp.description)
@Response(noContentResp.status, noContentResp.description)
@Response(badRequestResp.status, badRequestResp.description)
@Response(forbiddenOperationResp.status, forbiddenOperationResp.description)
@Response(notFoundResp.status, notFoundResp.description)
@Response(invalidParametersResp.status, invalidParametersResp.description)
@Response(internalServerErrorResp.status, internalServerErrorResp.description)
addHost(
@Path() id: string,
@Body() body: { host: string; force?: boolean },
@Query() sync?: boolean
): CreateActionReturnType<void> {
const poolId = id as XoPool['id']
const action = async () => {
const {
_auth: { user, password },
_url: { hostnameRaw },
} = this.restApi.xoApp.getXapi(poolId)
const hostXapi = this.restApi.xoApp.getXapi(body.host as XoHost['id'])
await hostXapi.joinPool(hostnameRaw, user, password, body.force)
}
return this.createAction<void>(action, {
sync,
statusCode: noContentResp.status,
taskProperties: {
name: 'add host',
objectId: poolId,
params: body,
},
})
}
}

View File

@@ -31,6 +31,7 @@
- [XO6] live update XO tasks (PR [#9901](https://github.com/vatesfr/xen-orchestra/pull/9901))
- [XO6/Backup] add progress for backups tasks(PR [#9901](https://github.com/vatesfr/xen-orchestra/pull/9901))
- [REST API] add `hosts/:id/actions/join_pool` REST route (PR [#9876](https://github.com/vatesfr/xen-orchestra/pull/9876))
### Bug fixes

View File

@@ -116,8 +116,8 @@ Actions are written using the exact string you pass in a privilege. A parent act
| `vif` | `connect`, `create`, `delete`, `disconnect`,`read` |
| `vbd` | `read`, `create`, `delete`, `connect`, `disconnect` |
| `sr` | `read`, `delete`, `forget`, `reclaim-space`, `scan`, `import:vdi`, `import:vm`, `update:tags` |
| `host` | `read`, `allow-vm`, `export:logs`, `update:tags`, `disable`, `enable`, `evacuate` |
| `pool` | `read`, `emergency-shutdown`, `rolling-reboot`, `rolling-update`, `create:network`, `create:vm`, `update:tags` |
| `host` | `read`, `allow-vm`, `join-pool`, `export:logs`, `update:tags`, `disable`, `enable`, `evacuate` |
| `pool` | `add-host`, `read`, `emergency-shutdown`, `rolling-reboot`, `rolling-update`, `create:network`, `create:vm`, `update:tags` |
| `network` | `read`, `create`, `delete`, `update:tags` |
| `pif` | `read`, `update:management` |
| `pbd` | `read`, `plug`, `unplug` |