@xen-orchestra/rest-api 0.32.0 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/open-api/routes/routes.js +85 -4
- package/dist/vms/vm.controller.mjs +49 -2
- package/dist/vms/vm.service.mjs +17 -0
- package/open-api/spec/swagger.json +975 -5
- package/package.json +3 -3
|
@@ -7,13 +7,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { Body, Delete, Example, Extension, Get, Middlewares, Path, Post, Put, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
|
|
10
|
+
import { Body, Delete, Example, Extension, Get, Middlewares, Patch, Path, Post, Put, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
|
|
11
11
|
import { json } from 'express';
|
|
12
12
|
import { inject } from 'inversify';
|
|
13
13
|
import { incorrectState, invalidParameters } from 'xo-common/api-errors.js';
|
|
14
14
|
import { provide } from 'inversify-binding-decorators';
|
|
15
15
|
import { PassThrough } from 'node:stream';
|
|
16
|
-
import {
|
|
16
|
+
import { SUPPORTED_ACTIONS_BY_RESOURCE } from '@xen-orchestra/acl';
|
|
17
|
+
import { acl, actionsFromBody } from '../middlewares/acl.middleware.mjs';
|
|
17
18
|
import { asynchronousActionResp, badRequestResp, createdResp, forbiddenOperationResp, incorrectStateResp, internalServerErrorResp, invalidParameters as invalidParametersResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
18
19
|
import { BASE_URL } from '../index.mjs';
|
|
19
20
|
import { limitAndFilterArray, NDJSON_CONTENT_TYPE } from '../helpers/utils.helper.mjs';
|
|
@@ -28,6 +29,11 @@ import { partialVmBackupJobs, vmBackupJobIds } from '../open-api/oa-examples/bac
|
|
|
28
29
|
import { messageIds, partialMessages } from '../open-api/oa-examples/message.oa-example.mjs';
|
|
29
30
|
import { Task } from '@vates/task';
|
|
30
31
|
const IGNORED_VDIS_TAG = '[NOSNAP]';
|
|
32
|
+
// `datasources` is managed through the dedicated `/vms/{id}/stats/data_source`
|
|
33
|
+
// endpoints, not as a direct VM property, so it cannot be updated via PATCH /vms.
|
|
34
|
+
const UPDATE_VM_ACTIONS = Object.keys(SUPPORTED_ACTIONS_BY_RESOURCE.vm.update)
|
|
35
|
+
.filter(action => action !== 'datasources')
|
|
36
|
+
.map(k => `update:${k}`);
|
|
31
37
|
let VmController = class VmController extends XapiXoController {
|
|
32
38
|
#vmService;
|
|
33
39
|
#backupJobService;
|
|
@@ -74,6 +80,29 @@ let VmController = class VmController extends XapiXoController {
|
|
|
74
80
|
getVm(id) {
|
|
75
81
|
return this.getObject(id);
|
|
76
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Partial update of a VM. Only the fields present in the body are modified;
|
|
85
|
+
* everything else is left untouched.
|
|
86
|
+
*
|
|
87
|
+
* Operations are applied sequentially: if one fails, previously applied
|
|
88
|
+
* changes are not rolled back.
|
|
89
|
+
*
|
|
90
|
+
* Required privilege per field provided in the body:
|
|
91
|
+
* - resource: vm, action: update:<field> (e.g. update:nameLabel, update:cpus, ...)
|
|
92
|
+
*
|
|
93
|
+
* Special fields:
|
|
94
|
+
* - `xenStoreData` keys are automatically prefixed with `vm-data/` when missing
|
|
95
|
+
*
|
|
96
|
+
* @example id "f07ab729-c0e8-721c-45ec-f11276377030"
|
|
97
|
+
* @example body {
|
|
98
|
+
* "nameLabel": "web-prod-01",
|
|
99
|
+
* "nameDescription": "Production web frontend — managed by n8n",
|
|
100
|
+
* "notes": "Docker containers: nginx, app-1, app-2"
|
|
101
|
+
* }
|
|
102
|
+
*/
|
|
103
|
+
async updateVm(id, body) {
|
|
104
|
+
await this.#vmService.updateVm(id, body);
|
|
105
|
+
}
|
|
77
106
|
/**
|
|
78
107
|
* Required privilege:
|
|
79
108
|
* - resource: vm, action: delete
|
|
@@ -663,6 +692,24 @@ __decorate([
|
|
|
663
692
|
Response(notFoundResp.status, notFoundResp.description),
|
|
664
693
|
__param(0, Path())
|
|
665
694
|
], VmController.prototype, "getVm", null);
|
|
695
|
+
__decorate([
|
|
696
|
+
Patch('{id}'),
|
|
697
|
+
Middlewares([
|
|
698
|
+
json(),
|
|
699
|
+
acl({
|
|
700
|
+
resource: 'vm',
|
|
701
|
+
actions: actionsFromBody(UPDATE_VM_ACTIONS),
|
|
702
|
+
objectId: 'params.id',
|
|
703
|
+
}),
|
|
704
|
+
]),
|
|
705
|
+
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
706
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
707
|
+
Response(notFoundResp.status, notFoundResp.description),
|
|
708
|
+
Response(invalidParametersResp.status, invalidParametersResp.description),
|
|
709
|
+
Response(internalServerErrorResp.status, internalServerErrorResp.description),
|
|
710
|
+
__param(0, Path()),
|
|
711
|
+
__param(1, Body())
|
|
712
|
+
], VmController.prototype, "updateVm", null);
|
|
666
713
|
__decorate([
|
|
667
714
|
Extension('x-mcp-exposure', 'confirm'),
|
|
668
715
|
Delete('{id}'),
|
package/dist/vms/vm.service.mjs
CHANGED
|
@@ -146,6 +146,23 @@ export class VmService {
|
|
|
146
146
|
});
|
|
147
147
|
return alarms;
|
|
148
148
|
}
|
|
149
|
+
async updateVm(id, body) {
|
|
150
|
+
const { resourceSet, share, ...editProps } = body;
|
|
151
|
+
// Touch the object so 404 is raised before any side effect.
|
|
152
|
+
void this.#restApi.getObject(id, 'VM');
|
|
153
|
+
const xoApp = this.#restApi.xoApp;
|
|
154
|
+
if (resourceSet !== undefined) {
|
|
155
|
+
await xoApp.setVmResourceSet(id, resourceSet, true);
|
|
156
|
+
}
|
|
157
|
+
else if (share) {
|
|
158
|
+
// `share: false` is a no-op.
|
|
159
|
+
await xoApp.shareVmResourceSet(id);
|
|
160
|
+
}
|
|
161
|
+
if (Object.keys(editProps).length === 0) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
await xoApp.getXapi(id).editVm(id, editProps);
|
|
165
|
+
}
|
|
149
166
|
#getDashboardQuickInfo(id) {
|
|
150
167
|
const { power_state, uuid, name_description, CPUs, mainIpAddress, os_version, memory, creation, $pool, virtualizationMode, tags, $container, startTime, pvDriversDetected, pvDriversVersion, pvDriversUpToDate, } = this.#restApi.getObject(id, 'VM');
|
|
151
168
|
return {
|