@xen-orchestra/rest-api 0.28.2 → 0.30.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.
Files changed (55) hide show
  1. package/README.md +108 -1
  2. package/dist/abstract-classes/base-controller.mjs +28 -3
  3. package/dist/abstract-classes/listener.mjs +124 -15
  4. package/dist/acl-privileges/acl-privilege.controller.mjs +172 -0
  5. package/dist/acl-roles/acl-role.controller.mjs +384 -0
  6. package/dist/alarms/alarm.controller.mjs +25 -11
  7. package/dist/alarms/alarm.service.mjs +8 -0
  8. package/dist/backup-archives/backup-archive.controller.mjs +33 -23
  9. package/dist/backup-archives/backup-archive.service.mjs +21 -0
  10. package/dist/backup-jobs/backup-job.controller.mjs +74 -25
  11. package/dist/backup-jobs/backup-job.service.mjs +7 -0
  12. package/dist/backup-logs/backup-log.controller.mjs +28 -13
  13. package/dist/backup-logs/backup-log.service.mjs +19 -0
  14. package/dist/backup-repositories/backup-repositories.controller.mjs +24 -5
  15. package/dist/events/event.class.mjs +36 -18
  16. package/dist/events/event.controller.mjs +3 -0
  17. package/dist/events/event.service.mjs +4 -4
  18. package/dist/groups/group.controller.mjs +99 -12
  19. package/dist/helpers/markdown.helper.mjs +20 -0
  20. package/dist/helpers/object-wrapper.helper.mjs +3 -3
  21. package/dist/hosts/host.controller.mjs +90 -15
  22. package/dist/ioc/ioc.mjs +13 -4
  23. package/dist/messages/message.controller.mjs +32 -10
  24. package/dist/middlewares/acl.middleware.mjs +202 -0
  25. package/dist/middlewares/authentication.middleware.mjs +15 -6
  26. package/dist/middlewares/tsoa-to-xo-error.middleware.mjs +19 -1
  27. package/dist/networks/network.controller.mjs +72 -17
  28. package/dist/open-api/oa-examples/acl-privilege.oa-example.mjs +25 -0
  29. package/dist/open-api/oa-examples/acl-role.oa-example.mjs +22 -0
  30. package/dist/open-api/oa-examples/backup-archive.oa-example.mjs +6 -6
  31. package/dist/open-api/oa-examples/common.oa-example.mjs +3 -0
  32. package/dist/open-api/routes/routes.js +856 -172
  33. package/dist/pbds/pbd.controller.mjs +20 -5
  34. package/dist/pcis/pci.controller.mjs +19 -5
  35. package/dist/pgpus/pgpu.controller.mjs +19 -5
  36. package/dist/pifs/pif.controller.mjs +56 -16
  37. package/dist/pools/pool.controller.mjs +166 -17
  38. package/dist/proxies/proxy.controller.mjs +25 -6
  39. package/dist/restore-logs/restore-log.controller.mjs +42 -23
  40. package/dist/schedules/schedule.controller.mjs +36 -5
  41. package/dist/servers/server.controller.mjs +71 -9
  42. package/dist/sms/sm.controller.mjs +17 -4
  43. package/dist/srs/sr.controller.mjs +74 -18
  44. package/dist/tasks/task.controller.mjs +74 -13
  45. package/dist/users/user.controller.mjs +124 -22
  46. package/dist/vbds/vbd.controller.mjs +76 -38
  47. package/dist/vdi-snapshots/vdi-snapshot.controller.mjs +48 -14
  48. package/dist/vdis/vdi.controller.mjs +81 -16
  49. package/dist/vifs/vif.controller.mjs +118 -16
  50. package/dist/vm-controller/vm-controller.controller.mjs +77 -19
  51. package/dist/vm-snapshots/vm-snapshot.controller.mjs +85 -18
  52. package/dist/vm-templates/vm-template.controller.mjs +86 -18
  53. package/dist/vms/vm.controller.mjs +182 -24
  54. package/open-api/spec/swagger.json +12112 -3537
  55. package/package.json +12 -11
@@ -12,10 +12,11 @@ import { json } from 'express';
12
12
  import { inject } from 'inversify';
13
13
  import { invalidParameters as invalidParametersError } from 'xo-common/api-errors.js';
14
14
  import { provide } from 'inversify-binding-decorators';
15
+ import { acl } from '../middlewares/acl.middleware.mjs';
15
16
  import { AlarmService } from '../alarms/alarm.service.mjs';
16
17
  import { escapeUnsafeComplexMatcher } from '../helpers/utils.helper.mjs';
17
18
  import { genericAlarmsExample } from '../open-api/oa-examples/alarm.oa-example.mjs';
18
- import { asynchronousActionResp, badRequestResp, createdResp, internalServerErrorResp, invalidParameters, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
19
+ import { asynchronousActionResp, badRequestResp, createdResp, internalServerErrorResp, invalidParameters, noContentResp, forbiddenOperationResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
19
20
  import { BASE_URL } from '../index.mjs';
20
21
  import { partialVbds, vbd, vbdId, vbdIds } from '../open-api/oa-examples/vbd.oa-example.mjs';
21
22
  import { RestApi } from '../rest-api/rest-api.mjs';
@@ -28,6 +29,29 @@ let VbdController = class VbdController extends XapiXoController {
28
29
  super('VBD', restApi);
29
30
  this.#alarmService = alarmService;
30
31
  }
32
+ /**
33
+ * Returns all VBDs that match the following privilege:
34
+ * - resource: vbd, action: read
35
+ *
36
+ * @example fields "device,bootable,uuid"
37
+ * @example filter "!bootable?"
38
+ * @example limit 42
39
+ */
40
+ getVbds(req, fields, ndjson, markdown, filter, limit) {
41
+ return this.sendObjects(Object.values(this.getObjects({ filter })), req, {
42
+ limit,
43
+ privilege: { action: 'read', resource: 'vbd' },
44
+ });
45
+ }
46
+ /**
47
+ * Required privilege:
48
+ * - resource: vbd, action: read
49
+ *
50
+ * @example id "f07ab729-c0e8-721c-45ec-f11276377030"
51
+ */
52
+ getVbd(id) {
53
+ return this.getObject(id);
54
+ }
31
55
  /**
32
56
  * Create a VBD to attach a VDI to a VM
33
57
  *
@@ -51,22 +75,6 @@ let VbdController = class VbdController extends XapiXoController {
51
75
  this.setHeader('Location', `${BASE_URL}/vbds/${vbdUuid}`);
52
76
  return { id: vbdUuid };
53
77
  }
54
- /**
55
- *
56
- * @example fields "device,bootable,uuid"
57
- * @example filter "!bootable?"
58
- * @example limit 42
59
- */
60
- getVbds(req, fields, ndjson, filter, limit) {
61
- return this.sendObjects(Object.values(this.getObjects({ filter, limit })), req);
62
- }
63
- /**
64
- *
65
- * @example id "f07ab729-c0e8-721c-45ec-f11276377030"
66
- */
67
- getVbd(id) {
68
- return this.getObject(id);
69
- }
70
78
  /**
71
79
  * Delete a VBD
72
80
  *
@@ -80,38 +88,58 @@ let VbdController = class VbdController extends XapiXoController {
80
88
  await xapiVbd.$xapi.VBD_destroy(xapiVbd.$ref);
81
89
  }
82
90
  /**
91
+ * Returns all alarms that match the following privilege:
92
+ * - resource: alarm, action: read
93
+ *
83
94
  * @example id "f07ab729-c0e8-721c-45ec-f11276377030"
84
95
  * @example fields "id,time"
85
96
  * @example filter "time:>1747053793"
86
97
  * @example limit 42
87
98
  */
88
- getVbdAlarms(req, id, fields, ndjson, filter, limit) {
99
+ getVbdAlarms(req, id, fields, ndjson, markdown, filter, limit) {
89
100
  const vbd = this.getObject(id);
90
101
  const alarms = this.#alarmService.getAlarms({
91
102
  filter: `${escapeUnsafeComplexMatcher(filter) ?? ''} object:uuid:${vbd.uuid}`,
103
+ });
104
+ return this.sendObjects(Object.values(alarms), req, {
105
+ path: 'alarms',
92
106
  limit,
107
+ privilege: { action: 'read', resource: 'alarm' },
93
108
  });
94
- return this.sendObjects(Object.values(alarms), req, 'alarms');
95
109
  }
96
110
  /**
111
+ * Returns all messages that match the following privilege:
112
+ * - resource: message, action: read
113
+ *
97
114
  * @example id "f07ab729-c0e8-721c-45ec-f11276377030"
98
115
  * @example fields "name,id,$object"
99
116
  * @example filter "name:VM_STARTED"
100
117
  * @example limit 42
101
118
  */
102
- getVbdMessages(req, id, fields, ndjson, filter, limit) {
103
- const messages = this.getMessagesForObject(id, { filter, limit });
104
- return this.sendObjects(Object.values(messages), req, 'messages');
119
+ getVbdMessages(req, id, fields, ndjson, markdown, filter, limit) {
120
+ const messages = this.getMessagesForObject(id, { filter });
121
+ return this.sendObjects(Object.values(messages), req, {
122
+ path: 'messages',
123
+ limit,
124
+ privilege: { action: 'read', resource: 'message' },
125
+ });
105
126
  }
106
127
  /**
128
+ * Returns all tasks that match the following privilege:
129
+ * - resource: task, action: read
130
+ *
107
131
  * @example id "f07ab729-c0e8-721c-45ec-f11276377030"
108
132
  * @example fields "id,status,properties"
109
133
  * @example filter "status:failure"
110
134
  * @example limit 42
111
135
  */
112
- async getVbdTasks(req, id, fields, ndjson, filter, limit) {
113
- const tasks = await this.getTasksForObject(id, { filter, limit });
114
- return this.sendObjects(Object.values(tasks), req, 'tasks');
136
+ async getVbdTasks(req, id, fields, ndjson, markdown, filter, limit) {
137
+ const tasks = await this.getTasksForObject(id, { filter });
138
+ return this.sendObjects(Object.values(tasks), req, {
139
+ path: 'tasks',
140
+ limit,
141
+ privilege: { action: 'read', resource: 'task' },
142
+ });
115
143
  }
116
144
  /**
117
145
  * Hotplug the VBD, dynamically attaching it to the running VM
@@ -152,31 +180,35 @@ let VbdController = class VbdController extends XapiXoController {
152
180
  });
153
181
  }
154
182
  };
155
- __decorate([
156
- Example(vbdId),
157
- Post(''),
158
- Middlewares(json()),
159
- SuccessResponse(createdResp.status, createdResp.description),
160
- Response(notFoundResp.status, notFoundResp.description),
161
- Response(invalidParameters.status, invalidParameters.description),
162
- __param(0, Body())
163
- ], VbdController.prototype, "createVbd", null);
164
183
  __decorate([
165
184
  Example(vbdIds),
166
185
  Example(partialVbds),
167
186
  Get(''),
187
+ Security('*', ['acl']),
168
188
  __param(0, Request()),
169
189
  __param(1, Query()),
170
190
  __param(2, Query()),
171
191
  __param(3, Query()),
172
- __param(4, Query())
192
+ __param(4, Query()),
193
+ __param(5, Query())
173
194
  ], VbdController.prototype, "getVbds", null);
174
195
  __decorate([
175
196
  Example(vbd),
176
197
  Get('{id}'),
198
+ Middlewares(acl({ resource: 'vbd', action: 'read', objectId: 'params.id' })),
199
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
177
200
  Response(notFoundResp.status, notFoundResp.description),
178
201
  __param(0, Path())
179
202
  ], VbdController.prototype, "getVbd", null);
203
+ __decorate([
204
+ Example(vbdId),
205
+ Post(''),
206
+ Middlewares(json()),
207
+ SuccessResponse(createdResp.status, createdResp.description),
208
+ Response(notFoundResp.status, notFoundResp.description),
209
+ Response(invalidParameters.status, invalidParameters.description),
210
+ __param(0, Body())
211
+ ], VbdController.prototype, "createVbd", null);
180
212
  __decorate([
181
213
  Delete('{id}'),
182
214
  SuccessResponse(noContentResp.status, noContentResp.description),
@@ -186,6 +218,7 @@ __decorate([
186
218
  __decorate([
187
219
  Example(genericAlarmsExample),
188
220
  Get('{id}/alarms'),
221
+ Security('*', ['acl']),
189
222
  Tags('alarms'),
190
223
  Response(notFoundResp.status, notFoundResp.description),
191
224
  __param(0, Request()),
@@ -193,12 +226,14 @@ __decorate([
193
226
  __param(2, Query()),
194
227
  __param(3, Query()),
195
228
  __param(4, Query()),
196
- __param(5, Query())
229
+ __param(5, Query()),
230
+ __param(6, Query())
197
231
  ], VbdController.prototype, "getVbdAlarms", null);
198
232
  __decorate([
199
233
  Example(messageIds),
200
234
  Example(partialMessages),
201
235
  Get('{id}/messages'),
236
+ Security('*', ['acl']),
202
237
  Tags('messages'),
203
238
  Response(notFoundResp.status, notFoundResp.description),
204
239
  __param(0, Request()),
@@ -206,12 +241,14 @@ __decorate([
206
241
  __param(2, Query()),
207
242
  __param(3, Query()),
208
243
  __param(4, Query()),
209
- __param(5, Query())
244
+ __param(5, Query()),
245
+ __param(6, Query())
210
246
  ], VbdController.prototype, "getVbdMessages", null);
211
247
  __decorate([
212
248
  Example(taskIds),
213
249
  Example(partialTasks),
214
250
  Get('{id}/tasks'),
251
+ Security('*', ['acl']),
215
252
  Tags('tasks'),
216
253
  Response(notFoundResp.status, notFoundResp.description),
217
254
  __param(0, Request()),
@@ -219,7 +256,8 @@ __decorate([
219
256
  __param(2, Query()),
220
257
  __param(3, Query()),
221
258
  __param(4, Query()),
222
- __param(5, Query())
259
+ __param(5, Query()),
260
+ __param(6, Query())
223
261
  ], VbdController.prototype, "getVbdTasks", null);
224
262
  __decorate([
225
263
  Example(taskLocation),
@@ -29,12 +29,18 @@ let VdiSnapshotController = class VdiSnapshotController extends XapiXoController
29
29
  this.#vdiService = vdiService;
30
30
  }
31
31
  /**
32
+ * Returns all VDI snapshots that match the following privilege:
33
+ * - resource: vdi-snapshot, action: read
34
+ *
32
35
  * @example fields "uuid,snapshot_time,$snapshot_of"
33
36
  * @example filter "snapshot_time:>1725020038"
34
37
  * @example limit 42
35
38
  */
36
- getVdiSnapshots(req, fields, ndjson, filter, limit) {
37
- return this.sendObjects(Object.values(this.getObjects({ filter, limit })), req);
39
+ getVdiSnapshots(req, fields, ndjson, markdown, filter, limit) {
40
+ return this.sendObjects(Object.values(this.getObjects({ filter })), req, {
41
+ limit,
42
+ privilege: { action: 'read', resource: 'vdi-snapshot' },
43
+ });
38
44
  }
39
45
  /**
40
46
  *
@@ -59,18 +65,24 @@ let VdiSnapshotController = class VdiSnapshotController extends XapiXoController
59
65
  return this.getObject(id);
60
66
  }
61
67
  /**
68
+ * Returns all alarms that match the following privilege:
69
+ * - resource: alarm, action: read
70
+ *
62
71
  * @example id "d2727772-735b-478f-b6f9-11e7db56dfd0"
63
72
  * @example fields "id,time"
64
73
  * @example filter "time:>1747053793"
65
74
  * @example limit 42
66
75
  */
67
- getVdiSnapshotAlarms(req, id, fields, ndjson, filter, limit) {
76
+ getVdiSnapshotAlarms(req, id, fields, ndjson, markdown, filter, limit) {
68
77
  const vdiSnapshot = this.getObject(id);
69
78
  const alarms = this.#alarmService.getAlarms({
70
79
  filter: `${escapeUnsafeComplexMatcher(filter) ?? ''} object:uuid:${vdiSnapshot.uuid}`,
80
+ });
81
+ return this.sendObjects(Object.values(alarms), req, {
82
+ path: 'alarms',
71
83
  limit,
84
+ privilege: { action: 'read', resource: 'alarm' },
72
85
  });
73
- return this.sendObjects(Object.values(alarms), req, 'alarms');
74
86
  }
75
87
  /**
76
88
  * @example id "d2727772-735b-478f-b6f9-11e7db56dfd0"
@@ -80,24 +92,38 @@ let VdiSnapshotController = class VdiSnapshotController extends XapiXoController
80
92
  await xapiVdiSnapshot.$xapi.VDI_destroy(xapiVdiSnapshot.$ref);
81
93
  }
82
94
  /**
95
+ * Returns all messages that match the following privilege:
96
+ * - resource: message, action: read
97
+ *
83
98
  * @example id "d2727772-735b-478f-b6f9-11e7db56dfd0"
84
99
  * @example fields "name,id,$object"
85
100
  * @example filter "name:VM_STARTED"
86
101
  * @example limit 42
87
102
  */
88
- getVdiSnapshotMessages(req, id, fields, ndjson, filter, limit) {
89
- const messages = this.getMessagesForObject(id, { filter, limit });
90
- return this.sendObjects(Object.values(messages), req, 'messages');
103
+ getVdiSnapshotMessages(req, id, fields, ndjson, markdown, filter, limit) {
104
+ const messages = this.getMessagesForObject(id, { filter });
105
+ return this.sendObjects(Object.values(messages), req, {
106
+ path: 'messages',
107
+ limit,
108
+ privilege: { action: 'read', resource: 'message' },
109
+ });
91
110
  }
92
111
  /**
112
+ * Returns all tasks that match the following privilege:
113
+ * - resource: task, action: read
114
+ *
93
115
  * @example id "d2727772-735b-478f-b6f9-11e7db56dfd0"
94
116
  * @example fields "id,status,properties"
95
117
  * @example filter "status:failure"
96
118
  * @example limit 42
97
119
  */
98
- async getVdiSnapshotTasks(req, id, fields, ndjson, filter, limit) {
99
- const tasks = await this.getTasksForObject(id, { filter, limit });
100
- return this.sendObjects(Object.values(tasks), req, 'tasks');
120
+ async getVdiSnapshotTasks(req, id, fields, ndjson, markdown, filter, limit) {
121
+ const tasks = await this.getTasksForObject(id, { filter });
122
+ return this.sendObjects(Object.values(tasks), req, {
123
+ path: 'tasks',
124
+ limit,
125
+ privilege: { action: 'read', resource: 'task' },
126
+ });
101
127
  }
102
128
  /**
103
129
  * @example id "d2727772-735b-478f-b6f9-11e7db56dfd0"
@@ -120,11 +146,13 @@ __decorate([
120
146
  Example(vdiSnapshotIds),
121
147
  Example(partialVdiSnapshots),
122
148
  Get(''),
149
+ Security('*', ['acl']),
123
150
  __param(0, Request()),
124
151
  __param(1, Query()),
125
152
  __param(2, Query()),
126
153
  __param(3, Query()),
127
- __param(4, Query())
154
+ __param(4, Query()),
155
+ __param(5, Query())
128
156
  ], VdiSnapshotController.prototype, "getVdiSnapshots", null);
129
157
  __decorate([
130
158
  Get('{id}.{format}'),
@@ -144,6 +172,7 @@ __decorate([
144
172
  __decorate([
145
173
  Example(genericAlarmsExample),
146
174
  Get('{id}/alarms'),
175
+ Security('*', ['acl']),
147
176
  Tags('alarms'),
148
177
  Response(notFoundResp.status, notFoundResp.description),
149
178
  __param(0, Request()),
@@ -151,7 +180,8 @@ __decorate([
151
180
  __param(2, Query()),
152
181
  __param(3, Query()),
153
182
  __param(4, Query()),
154
- __param(5, Query())
183
+ __param(5, Query()),
184
+ __param(6, Query())
155
185
  ], VdiSnapshotController.prototype, "getVdiSnapshotAlarms", null);
156
186
  __decorate([
157
187
  Delete('{id}'),
@@ -163,6 +193,7 @@ __decorate([
163
193
  Example(messageIds),
164
194
  Example(partialMessages),
165
195
  Get('{id}/messages'),
196
+ Security('*', ['acl']),
166
197
  Tags('messages'),
167
198
  Response(notFoundResp.status, notFoundResp.description),
168
199
  __param(0, Request()),
@@ -170,12 +201,14 @@ __decorate([
170
201
  __param(2, Query()),
171
202
  __param(3, Query()),
172
203
  __param(4, Query()),
173
- __param(5, Query())
204
+ __param(5, Query()),
205
+ __param(6, Query())
174
206
  ], VdiSnapshotController.prototype, "getVdiSnapshotMessages", null);
175
207
  __decorate([
176
208
  Example(taskIds),
177
209
  Example(partialTasks),
178
210
  Get('{id}/tasks'),
211
+ Security('*', ['acl']),
179
212
  Tags('tasks'),
180
213
  Response(notFoundResp.status, notFoundResp.description),
181
214
  __param(0, Request()),
@@ -183,7 +216,8 @@ __decorate([
183
216
  __param(2, Query()),
184
217
  __param(3, Query()),
185
218
  __param(4, Query()),
186
- __param(5, Query())
219
+ __param(5, Query()),
220
+ __param(6, Query())
187
221
  ], VdiSnapshotController.prototype, "getVdiSnapshotTasks", null);
188
222
  __decorate([
189
223
  Put('{id}/tags/{tag}'),
@@ -11,10 +11,11 @@ import { Body, Delete, Example, Get, Middlewares, Path, Post, Put, Query, Reques
11
11
  import { inject } from 'inversify';
12
12
  import { provide } from 'inversify-binding-decorators';
13
13
  import { json } from 'express';
14
+ import { acl } from '../middlewares/acl.middleware.mjs';
14
15
  import { AlarmService } from '../alarms/alarm.service.mjs';
15
16
  import { escapeUnsafeComplexMatcher } from '../helpers/utils.helper.mjs';
16
17
  import { genericAlarmsExample } from '../open-api/oa-examples/alarm.oa-example.mjs';
17
- import { asynchronousActionResp, badRequestResp, createdResp, internalServerErrorResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
18
+ import { asynchronousActionResp, badRequestResp, createdResp, forbiddenOperationResp, internalServerErrorResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
18
19
  import { BASE_URL } from '../index.mjs';
19
20
  import { RestApi } from '../rest-api/rest-api.mjs';
20
21
  import { XapiXoController } from '../abstract-classes/xapi-xo-controller.mjs';
@@ -31,17 +32,26 @@ let VdiController = class VdiController extends XapiXoController {
31
32
  this.#vdiService = vdiService;
32
33
  }
33
34
  /**
35
+ * Returns all VDIs that match the following privilege:
36
+ * - resource: vdi, action: read
37
+ *
34
38
  * @example fields "*"
35
39
  * @example filter "snapshots:length:>2"
36
40
  * @example limit 42
37
41
  */
38
- getVdis(req, fields, ndjson, filter, limit) {
39
- return this.sendObjects(Object.values(this.getObjects({ filter, limit })), req);
42
+ getVdis(req, fields, ndjson, markdown, filter, limit) {
43
+ return this.sendObjects(Object.values(this.getObjects({ filter })), req, {
44
+ limit,
45
+ privilege: { action: 'read', resource: 'vdi' },
46
+ });
40
47
  }
41
48
  /**
42
49
  *
43
50
  * Export VDI content
44
51
  *
52
+ * Required privilege:
53
+ * - resource: vdi, action: export-content
54
+ *
45
55
  * @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
46
56
  */
47
57
  async exportVdiContent(req, id, format) {
@@ -55,6 +65,9 @@ let VdiController = class VdiController extends XapiXoController {
55
65
  *
56
66
  * Import VDI content
57
67
  *
68
+ * Required privilege:
69
+ * - resource: vdi, action: import-content
70
+ *
58
71
  * @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
59
72
  */
60
73
  async importVdiContent(req, id, format) {
@@ -66,27 +79,36 @@ let VdiController = class VdiController extends XapiXoController {
66
79
  await xapiVdi.$xapi.VDI_importContent(xapiVdi.$ref, req, { format });
67
80
  }
68
81
  /**
82
+ * Required privilege:
83
+ * - resource: vdi, action: read
84
+ *
69
85
  * @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
70
86
  */
71
87
  getVdi(id) {
72
88
  return this.getObject(id);
73
89
  }
74
90
  /**
91
+ * Returns all alarms that match the following privilege:
92
+ * - resource: alarm, action: read
93
+ *
75
94
  * @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
76
95
  * @example fields "id,time"
77
96
  * @example filter "time:>1747053793"
78
97
  * @example limit 42
79
98
  */
80
- getVdiAlarms(req, id, fields, ndjson, filter, limit) {
99
+ getVdiAlarms(req, id, fields, ndjson, markdown, filter, limit) {
81
100
  const vdi = this.getObject(id);
82
101
  const alarms = this.#alarmService.getAlarms({
83
102
  filter: `${escapeUnsafeComplexMatcher(filter) ?? ''} object:uuid:${vdi.uuid}`,
103
+ });
104
+ return this.sendObjects(Object.values(alarms), req, {
105
+ path: 'alarms',
84
106
  limit,
107
+ privilege: { action: 'read', resource: 'alarm' },
85
108
  });
86
- return this.sendObjects(Object.values(alarms), req, 'alarms');
87
109
  }
88
110
  /**
89
- * Create an empty VDI on the given SR.
111
+ * Create an empty VDI.
90
112
  *
91
113
  * @example body { "srId": "c4284e12-37c9-7967-b9e8-83ef229c3e03", "virtual_size": 10737418240, "name_label": "test VDI" }
92
114
  */
@@ -105,6 +127,9 @@ let VdiController = class VdiController extends XapiXoController {
105
127
  return { id: vdiUuid };
106
128
  }
107
129
  /**
130
+ * Required privilege:
131
+ * - resource: vdi, action: delete
132
+ *
108
133
  * @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
109
134
  */
110
135
  async deleteVdi(id) {
@@ -112,24 +137,38 @@ let VdiController = class VdiController extends XapiXoController {
112
137
  await xapiVdi.$xapi.VDI_destroy(xapiVdi.$ref);
113
138
  }
114
139
  /**
140
+ * Returns all messages that match the following privilege:
141
+ * - resource: message, action: read
142
+ *
115
143
  * @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
116
144
  * @example fields "name,id,$object"
117
145
  * @example filter "name:VM_STARTED"
118
146
  * @example limit 42
119
147
  */
120
- getVdiMessages(req, id, fields, ndjson, filter, limit) {
121
- const messages = this.getMessagesForObject(id, { filter, limit });
122
- return this.sendObjects(Object.values(messages), req, 'messages');
148
+ getVdiMessages(req, id, fields, ndjson, markdown, filter, limit) {
149
+ const messages = this.getMessagesForObject(id, { filter });
150
+ return this.sendObjects(Object.values(messages), req, {
151
+ path: 'messages',
152
+ limit,
153
+ privilege: { action: 'read', resource: 'message' },
154
+ });
123
155
  }
124
156
  /**
157
+ * Returns all tasks that match the following privilege:
158
+ * - resource: task, action: read
159
+ *
125
160
  * @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
126
161
  * @example fields "id,status,properties"
127
162
  * @example filter "status:failure"
128
163
  * @example limit 42
129
164
  */
130
- async getVdiTasks(req, id, fields, ndjson, filter, limit) {
131
- const tasks = await this.getTasksForObject(id, { filter, limit });
132
- return this.sendObjects(Object.values(tasks), req, 'tasks');
165
+ async getVdiTasks(req, id, fields, ndjson, markdown, filter, limit) {
166
+ const tasks = await this.getTasksForObject(id, { filter });
167
+ return this.sendObjects(Object.values(tasks), req, {
168
+ path: 'tasks',
169
+ limit,
170
+ privilege: { action: 'read', resource: 'task' },
171
+ });
133
172
  }
134
173
  /**
135
174
  * Migrate a VDI to another SR.
@@ -153,6 +192,9 @@ let VdiController = class VdiController extends XapiXoController {
153
192
  });
154
193
  }
155
194
  /**
195
+ * Required privilege:
196
+ * - resource: vdi, action: update:tags
197
+ *
156
198
  * @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
157
199
  * @example tag "from-rest-api"
158
200
  */
@@ -161,6 +203,9 @@ let VdiController = class VdiController extends XapiXoController {
161
203
  await vdi.$call('add_tags', tag);
162
204
  }
163
205
  /**
206
+ * Required privilege:
207
+ * - resource: vdi, action: update:tags
208
+ *
164
209
  * @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
165
210
  * @example tag "from-rest-api"
166
211
  */
@@ -173,15 +218,19 @@ __decorate([
173
218
  Example(vdiIds),
174
219
  Example(partialVdis),
175
220
  Get(''),
221
+ Security('*', ['acl']),
176
222
  __param(0, Request()),
177
223
  __param(1, Query()),
178
224
  __param(2, Query()),
179
225
  __param(3, Query()),
180
- __param(4, Query())
226
+ __param(4, Query()),
227
+ __param(5, Query())
181
228
  ], VdiController.prototype, "getVdis", null);
182
229
  __decorate([
183
230
  Get('{id}.{format}'),
231
+ Middlewares(acl({ resource: 'vdi', action: 'export-content', objectId: 'params.id' })),
184
232
  SuccessResponse(200, 'Download started', 'application/octet-stream'),
233
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
185
234
  Response(notFoundResp.status, notFoundResp.description),
186
235
  Response(422, 'Invalid format'),
187
236
  __param(0, Request()),
@@ -190,7 +239,9 @@ __decorate([
190
239
  ], VdiController.prototype, "exportVdiContent", null);
191
240
  __decorate([
192
241
  Put('{id}.{format}'),
242
+ Middlewares(acl({ resource: 'vdi', action: 'import-content', objectId: 'params.id' })),
193
243
  SuccessResponse(noContentResp.status, noContentResp.description),
244
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
194
245
  Response(notFoundResp.status, notFoundResp.description),
195
246
  Response(422, 'Invalid format'),
196
247
  Response(internalServerErrorResp.status, internalServerErrorResp.description),
@@ -201,12 +252,15 @@ __decorate([
201
252
  __decorate([
202
253
  Example(vdi),
203
254
  Get('{id}'),
255
+ Middlewares(acl({ resource: 'vdi', action: 'read', objectId: 'params.id' })),
256
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
204
257
  Response(notFoundResp.status, notFoundResp.description),
205
258
  __param(0, Path())
206
259
  ], VdiController.prototype, "getVdi", null);
207
260
  __decorate([
208
261
  Example(genericAlarmsExample),
209
262
  Get('{id}/alarms'),
263
+ Security('*', ['acl']),
210
264
  Tags('alarms'),
211
265
  Response(notFoundResp.status, notFoundResp.description),
212
266
  __param(0, Request()),
@@ -214,7 +268,8 @@ __decorate([
214
268
  __param(2, Query()),
215
269
  __param(3, Query()),
216
270
  __param(4, Query()),
217
- __param(5, Query())
271
+ __param(5, Query()),
272
+ __param(6, Query())
218
273
  ], VdiController.prototype, "getVdiAlarms", null);
219
274
  __decorate([
220
275
  Example(vdiId),
@@ -227,7 +282,9 @@ __decorate([
227
282
  ], VdiController.prototype, "createVdi", null);
228
283
  __decorate([
229
284
  Delete('{id}'),
285
+ Middlewares(acl({ resource: 'vdi', action: 'delete', objectId: 'params.id' })),
230
286
  SuccessResponse(noContentResp.status, noContentResp.description),
287
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
231
288
  Response(notFoundResp.status, notFoundResp.description),
232
289
  __param(0, Path())
233
290
  ], VdiController.prototype, "deleteVdi", null);
@@ -235,6 +292,7 @@ __decorate([
235
292
  Example(messageIds),
236
293
  Example(partialMessages),
237
294
  Get('{id}/messages'),
295
+ Security('*', ['acl']),
238
296
  Tags('messages'),
239
297
  Response(notFoundResp.status, notFoundResp.description),
240
298
  __param(0, Request()),
@@ -242,12 +300,14 @@ __decorate([
242
300
  __param(2, Query()),
243
301
  __param(3, Query()),
244
302
  __param(4, Query()),
245
- __param(5, Query())
303
+ __param(5, Query()),
304
+ __param(6, Query())
246
305
  ], VdiController.prototype, "getVdiMessages", null);
247
306
  __decorate([
248
307
  Example(taskIds),
249
308
  Example(partialTasks),
250
309
  Get('{id}/tasks'),
310
+ Security('*', ['acl']),
251
311
  Tags('tasks'),
252
312
  Response(notFoundResp.status, notFoundResp.description),
253
313
  __param(0, Request()),
@@ -255,7 +315,8 @@ __decorate([
255
315
  __param(2, Query()),
256
316
  __param(3, Query()),
257
317
  __param(4, Query()),
258
- __param(5, Query())
318
+ __param(5, Query()),
319
+ __param(6, Query())
259
320
  ], VdiController.prototype, "getVdiTasks", null);
260
321
  __decorate([
261
322
  Example(taskLocation),
@@ -272,14 +333,18 @@ __decorate([
272
333
  ], VdiController.prototype, "migrateVdi", null);
273
334
  __decorate([
274
335
  Put('{id}/tags/{tag}'),
336
+ Middlewares(acl({ resource: 'vdi', action: 'update:tags', objectId: 'params.id' })),
275
337
  SuccessResponse(noContentResp.status, noContentResp.description),
338
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
276
339
  Response(notFoundResp.status, notFoundResp.description),
277
340
  __param(0, Path()),
278
341
  __param(1, Path())
279
342
  ], VdiController.prototype, "putVdiTag", null);
280
343
  __decorate([
281
344
  Delete('{id}/tags/{tag}'),
345
+ Middlewares(acl({ resource: 'vdi', action: 'update:tags', objectId: 'params.id' })),
282
346
  SuccessResponse(noContentResp.status, noContentResp.description),
347
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
283
348
  Response(notFoundResp.status, notFoundResp.description),
284
349
  __param(0, Path()),
285
350
  __param(1, Path())