From 64d164300b17ceff624957baffa950b2ec921fff Mon Sep 17 00:00:00 2001 From: Mathieu <70369997+MathieuRA@users.noreply.github.com> Date: Tue, 14 Oct 2025 14:44:26 +0200 Subject: [PATCH] feat(@xen-orchestra/rest-api): expose pbds (#9106) --- @vates/types/src/xen-api.mts | 2 + @vates/types/src/xo.mts | 13 +++++ .../open-api/oa-examples/pbd.oa-example.mts | 43 ++++++++++++++++ .../rest-api/src/pbds/pbd.controller.mts | 50 +++++++++++++++++++ .../rest-api/src/rest-api/rest-api.type.mts | 2 + CHANGELOG.unreleased.md | 1 + 6 files changed, 111 insertions(+) create mode 100644 @xen-orchestra/rest-api/src/open-api/oa-examples/pbd.oa-example.mts create mode 100644 @xen-orchestra/rest-api/src/pbds/pbd.controller.mts diff --git a/@vates/types/src/xen-api.mts b/@vates/types/src/xen-api.mts index 99620b5c1d..259e0dd23e 100644 --- a/@vates/types/src/xen-api.mts +++ b/@vates/types/src/xen-api.mts @@ -933,6 +933,7 @@ export interface XenApiPbd { SR: XenApiSr['$ref'] uuid: string } +export type XenApiPbdWrapped = WrapperXenApi /** @deprecated */ export interface XenApiCrashdump { @@ -1369,6 +1370,7 @@ export type XenApiRecord = export type WrappedXenApiRecord = | XenApiHostWrapped | XenApiNetworkWrapped + | XenApiPbdWrapped | XenApiPifWrapped | XenApiPoolWrapped | XenApiSrWrapped diff --git a/@vates/types/src/xo.mts b/@vates/types/src/xo.mts index 400f1dbfa7..04635fc3e2 100644 --- a/@vates/types/src/xo.mts +++ b/@vates/types/src/xo.mts @@ -289,7 +289,19 @@ export type XoNetwork = BaseXapiXo & { } export type XoPbd = BaseXapiXo & { + attached: boolean + device_config: + | { device: string } + | { location: string } + | { path: string; location: string; legacy_mode: string } + | { provisioning: string; redundancy: string; 'group-name': string } + | { server: string; serverpath: string } + | { type: string; location: string } + | Record + host: XoHost['id'] id: Branded<'PBD'> + otherConfig: Record + SR: XoSr['id'] type: 'PBD' } @@ -741,6 +753,7 @@ export type XapiXoRecord = | XoHost | XoMessage | XoNetwork + | XoPbd | XoPci | XoPgpu | XoPif diff --git a/@xen-orchestra/rest-api/src/open-api/oa-examples/pbd.oa-example.mts b/@xen-orchestra/rest-api/src/open-api/oa-examples/pbd.oa-example.mts new file mode 100644 index 0000000000..ec29097522 --- /dev/null +++ b/@xen-orchestra/rest-api/src/open-api/oa-examples/pbd.oa-example.mts @@ -0,0 +1,43 @@ +export const pbdIds = [ + '/rest/v0/pbds/16b2a60f-7c4d-f45f-7c7a-963b06fc587d', + '/rest/v0/pbds/28d93f56-23cb-527c-080a-805e54593a0d', +] + +export const partialPbds = [ + { + attached: true, + id: '16b2a60f-7c4d-f45f-7c7a-963b06fc587d', + device_config: { + device: '/dev/disk/by-id/ata-YP0120GWCGV_2H5020013956-part3', + }, + href: '/rest/v0/pbds/16b2a60f-7c4d-f45f-7c7a-963b06fc587d', + }, + { + attached: true, + id: '28d93f56-23cb-527c-080a-805e54593a0d', + device_config: { + path: '/opt/xensource/packages/iso', + location: '/opt/xensource/packages/iso', + legacy_mode: 'true', + }, + href: '/rest/v0/pbds/28d93f56-23cb-527c-080a-805e54593a0d', + }, +] + +export const pbd = { + type: 'PBD', + attached: true, + host: '669df518-4e5d-4d84-b93a-9be2cdcdfca1', + SR: '8aa2fb4a-143e-c2bc-05d4-c68bbb101d41', + device_config: { + device: '/dev/disk/by-id/ata-YP0120GWCGV_2H5020013956-part3', + }, + otherConfig: { + storage_driver_domain: 'OpaqueRef:6a7cfe18-1b68-205f-080a-3a64fb5f0e19', + }, + id: '16b2a60f-7c4d-f45f-7c7a-963b06fc587d', + uuid: '16b2a60f-7c4d-f45f-7c7a-963b06fc587d', + $pool: 'b7569d99-30f8-178a-7d94-801de3e29b5b', + $poolId: 'b7569d99-30f8-178a-7d94-801de3e29b5b', + _xapiRef: 'OpaqueRef:fc6b3830-610b-adc8-2ea4-b7769f0931bf', +} diff --git a/@xen-orchestra/rest-api/src/pbds/pbd.controller.mts b/@xen-orchestra/rest-api/src/pbds/pbd.controller.mts new file mode 100644 index 0000000000..13db0f8895 --- /dev/null +++ b/@xen-orchestra/rest-api/src/pbds/pbd.controller.mts @@ -0,0 +1,50 @@ +import { inject } from 'inversify' +import { provide } from 'inversify-binding-decorators' +import type { Request as ExRequest } from 'express' +import { Route, Security, Request, Response, Get, Query, Path, Tags, Example } from 'tsoa' +import type { XoPbd } from '@vates/types' + +import { badRequestResp, unauthorizedResp, Unbrand } from '../open-api/common/response.common.mjs' +import { RestApi } from '../rest-api/rest-api.mjs' +import type { SendObjects } from '../helpers/helper.type.mjs' +import { XapiXoController } from '../abstract-classes/xapi-xo-controller.mjs' +import { partialPbds, pbd, pbdIds } from '../open-api/oa-examples/pbd.oa-example.mjs' + +@Route('pbds') +@Security('*') +@Response(unauthorizedResp.status, unauthorizedResp.description) +@Response(badRequestResp.status, badRequestResp.description) +@Tags('pbds') +@provide(PbdController) +export class PbdController extends XapiXoController { + constructor(@inject(RestApi) restApi: RestApi) { + super('PBD', restApi) + } + + /** + * @example fields "attached,id,device_config" + * @example filter "attached?" + * @example limit 42 + */ + @Example(pbdIds) + @Example(partialPbds) + @Get('') + getPbds( + @Request() req: ExRequest, + @Query() fields?: string, + @Query() ndjson?: boolean, + @Query() filter?: string, + @Query() limit?: number + ): SendObjects>> { + return this.sendObjects(Object.values(this.getObjects({ filter, limit })), req) + } + + /** + * @example id "16b2a60f-7c4d-f45f-7c7a-963b06fc587d" + */ + @Example(pbd) + @Get('{id}') + getPbd(@Path() id: string): Unbrand { + return this.getObject(id as XoPbd['id']) + } +} diff --git a/@xen-orchestra/rest-api/src/rest-api/rest-api.type.mts b/@xen-orchestra/rest-api/src/rest-api/rest-api.type.mts index b12bccb80c..a2208cffc4 100644 --- a/@xen-orchestra/rest-api/src/rest-api/rest-api.type.mts +++ b/@xen-orchestra/rest-api/src/rest-api/rest-api.type.mts @@ -7,6 +7,7 @@ import type { XenApiHostWrapped, XenApiMessage, XenApiNetworkWrapped, + XenApiPbdWrapped, XenApiPciWrapped, XenApiPgpuWrapped, XenApiPifWrapped, @@ -47,6 +48,7 @@ type XapiRecordByXapiXoRecord = { host: XenApiHostWrapped message: XenApiMessage network: XenApiNetworkWrapped + PBD: XenApiPbdWrapped PCI: XenApiPciWrapped PGPU: XenApiPgpuWrapped PIF: XenApiPifWrapped diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index a48fce0b16..e9097567eb 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -65,6 +65,7 @@ - [REST API] `/rest/v0` redirect now to `/rest/v0/docs` and the swagger is now available for unauthenticated users (PR [#9101](https://github.com/vatesfr/xen-orchestra/pull/9101)) - [REST API] Expose `/rest/v0/users/:id/authentication_tokens` (PR [#9102](https://github.com/vatesfr/xen-orchestra/pull/9102)) - [REST API] Possibility to use `Basic Auth` for authenticated endpoints (PR [#9102](https://github.com/vatesfr/xen-orchestra/pull/9102)) +- [REST API] Expose `/rest/v0/pbds` and `/rest/v0/pbds/:id` (PR [#9106](https://github.com/vatesfr/xen-orchestra/pull/9106)) ### Bug fixes