@xen-orchestra/rest-api 0.14.0 → 0.16.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 (49) hide show
  1. package/dist/abstract-classes/base-controller.mjs +4 -2
  2. package/dist/abstract-classes/xapi-xo-controller.mjs +2 -6
  3. package/dist/alarms/alarm.service.mjs +2 -1
  4. package/dist/backup-jobs/backup-job.controller.mjs +284 -0
  5. package/dist/backup-jobs/backup-job.service.mjs +25 -0
  6. package/dist/backup-jobs/backup-job.type.mjs +1 -0
  7. package/dist/backup-logs/backup-log.controller.mjs +75 -0
  8. package/dist/backup-logs/backup-log.service.mjs +5 -0
  9. package/dist/groups/group.controller.mjs +37 -1
  10. package/dist/helpers/error.helper.mjs +10 -0
  11. package/dist/hosts/host.controller.mjs +24 -4
  12. package/dist/hosts/host.service.mjs +6 -7
  13. package/dist/hosts/host.type.mjs +1 -0
  14. package/dist/index.mjs +4 -0
  15. package/dist/ioc/ioc.mjs +36 -0
  16. package/dist/middlewares/generic-error-handler.middleware.mjs +5 -1
  17. package/dist/open-api/common/response.common.mjs +8 -0
  18. package/dist/open-api/oa-examples/backup-job.oa-example.mjs +128 -0
  19. package/dist/open-api/oa-examples/backup-log.oa-example.mjs +93 -0
  20. package/dist/open-api/oa-examples/host.oa-example.mjs +30 -0
  21. package/dist/open-api/oa-examples/pool.oa-example.mjs +30 -0
  22. package/dist/open-api/oa-examples/proxy.oa-example.mjs +25 -0
  23. package/dist/open-api/oa-examples/restore-log.oa-example.mjs +53 -0
  24. package/dist/open-api/oa-examples/task.oa-example.mjs +46 -0
  25. package/dist/open-api/oa-examples/user.oa-example.mjs +32 -0
  26. package/dist/open-api/oa-examples/vdi.oa-example.mjs +3 -0
  27. package/dist/open-api/routes/routes.js +2079 -490
  28. package/dist/pools/pool.controller.mjs +16 -1
  29. package/dist/pools/pool.service.mjs +18 -8
  30. package/dist/proxies/proxy.controller.mjs +61 -0
  31. package/dist/rest-api/rest-api.mjs +6 -2
  32. package/dist/restore-logs/restore-log.controller.mjs +144 -0
  33. package/dist/srs/sr.controller.mjs +39 -2
  34. package/dist/tasks/task.controller.mjs +167 -0
  35. package/dist/tasks/task.service.mjs +24 -0
  36. package/dist/users/user.controller.mjs +91 -12
  37. package/dist/users/user.service.mjs +21 -0
  38. package/dist/vdi-snapshots/vdi-snapshot.controller.mjs +46 -4
  39. package/dist/vdis/vdi.controller.mjs +43 -4
  40. package/dist/vdis/vdi.service.mjs +21 -0
  41. package/dist/vm-snapshots/vm-snapshot.controller.mjs +72 -3
  42. package/dist/vm-templates/vm-template.controller.mjs +43 -2
  43. package/dist/vms/vm.controller.mjs +135 -5
  44. package/dist/vms/vm.service.mjs +18 -0
  45. package/dist/xoa/xoa.service.mjs +14 -4
  46. package/open-api/spec/swagger.json +11733 -6660
  47. package/package.json +6 -5
  48. package/tsconfig.json +1 -0
  49. package/tsoa.json +27 -0
@@ -8,28 +8,35 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
8
8
  return function (target, key) { decorator(target, key, paramIndex); }
9
9
  };
10
10
  import { Body, Delete, Example, Get, Middlewares, Patch, Path, Post, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
11
+ import { inject } from 'inversify';
11
12
  import { json } from 'express';
12
13
  import { provide } from 'inversify-binding-decorators';
13
14
  import { createdResp, forbiddenOperationResp, invalidParameters, noContentResp, notFoundResp, resourceAlreadyExists, unauthorizedResp, } from '../open-api/common/response.common.mjs';
14
15
  import { forbiddenOperation } from 'xo-common/api-errors.js';
15
- import { partialUsers, user, userId, userIds } from '../open-api/oa-examples/user.oa-example.mjs';
16
+ import { partialUsers, user, authenticationTokens, userId, userIds } from '../open-api/oa-examples/user.oa-example.mjs';
17
+ import { RestApi } from '../rest-api/rest-api.mjs';
18
+ import { limitAndFilterArray } from '../helpers/utils.helper.mjs';
19
+ import { UserService } from './user.service.mjs';
16
20
  import { XoController } from '../abstract-classes/xo-controller.mjs';
21
+ import { groupIds, partialGroups } from '../open-api/oa-examples/group.oa-example.mjs';
17
22
  let UserController = class UserController extends XoController {
23
+ #userService;
24
+ constructor(restApi, userService) {
25
+ super(restApi);
26
+ this.#userService = userService;
27
+ }
18
28
  // --- abstract methods
19
29
  async getAllCollectionObjects() {
20
- const users = await this.restApi.xoApp.getAllUsers();
21
- return users.map(user => this.#sanitizeUser(user));
30
+ return this.#userService.getUsers();
22
31
  }
23
32
  async getCollectionObject(id) {
24
- const user = await this.restApi.xoApp.getUser(id);
25
- return this.#sanitizeUser(user);
33
+ return this.#userService.getUser(id);
26
34
  }
27
- #sanitizeUser(user) {
28
- const sanitizedUser = { ...user };
29
- if (sanitizedUser.pw_hash !== undefined) {
30
- sanitizedUser.pw_hash = '***obfuscated***';
31
- }
32
- return sanitizedUser;
35
+ #redirectCurrentUser(req) {
36
+ const currentUser = this.restApi.getCurrentUser();
37
+ const originalUrl = req.originalUrl;
38
+ const res = req.res;
39
+ res.redirect(307, originalUrl.replace(/\/users\/me(?=\/|$)/, `/users/${currentUser.id}`));
33
40
  }
34
41
  /**
35
42
  * @example fields "permission,name,id"
@@ -40,6 +47,18 @@ let UserController = class UserController extends XoController {
40
47
  const users = Object.values(await this.getObjects({ filter, limit }));
41
48
  return this.sendObjects(users, req);
42
49
  }
50
+ /**
51
+ * Redirect to `/users/:id`
52
+ */
53
+ redirectMe(req) {
54
+ this.#redirectCurrentUser(req);
55
+ }
56
+ /**
57
+ * Redirect to `/users/:id/<rest-of-your-path>`
58
+ */
59
+ redirectMeWithPath(req) {
60
+ this.#redirectCurrentUser(req);
61
+ }
43
62
  /**
44
63
  * @example id "722d17b9-699b-49d2-8193-be1ac573d3de"
45
64
  */
@@ -87,6 +106,31 @@ let UserController = class UserController extends XoController {
87
106
  async deleteUser(id) {
88
107
  await this.restApi.xoApp.deleteUser(id);
89
108
  }
109
+ /**
110
+ * @example id "722d17b9-699b-49d2-8193-be1ac573d3de"
111
+ * @example fields "name,id,users"
112
+ * @example filter "users:length:>0"
113
+ * @example limit 42
114
+ */
115
+ async getUserGroups(req, id, fields, ndjson, filter, limit) {
116
+ const user = await this.getObject(id);
117
+ const groups = await Promise.all(user.groups.map(group => this.restApi.xoApp.getGroup(group)));
118
+ return this.sendObjects(limitAndFilterArray(groups, { filter, limit }), req, 'groups');
119
+ }
120
+ /**
121
+ * @example id "722d17b9-699b-49d2-8193-be1ac573d3de"
122
+ * @example filter "expiration:>1757371582496"
123
+ * @example limit 42
124
+ */
125
+ async getAuthenticationTokens(req, id, filter, limit) {
126
+ const user = await this.getObject(id);
127
+ const me = this.restApi.getCurrentUser();
128
+ if (me.id !== user.id) {
129
+ throw forbiddenOperation('get authentication tokens', 'can only see own authentication tokens');
130
+ }
131
+ const tokens = await this.restApi.xoApp.getAuthenticationTokensForUser(user.id);
132
+ return limitAndFilterArray(tokens, { filter, limit });
133
+ }
90
134
  };
91
135
  __decorate([
92
136
  Example(userIds),
@@ -98,6 +142,16 @@ __decorate([
98
142
  __param(3, Query()),
99
143
  __param(4, Query())
100
144
  ], UserController.prototype, "getUsers", null);
145
+ __decorate([
146
+ SuccessResponse(307, 'Temporary redirect'),
147
+ Get('me'),
148
+ __param(0, Request())
149
+ ], UserController.prototype, "redirectMe", null);
150
+ __decorate([
151
+ SuccessResponse(307, 'Temporary redirect'),
152
+ Get('me/*'),
153
+ __param(0, Request())
154
+ ], UserController.prototype, "redirectMeWithPath", null);
101
155
  __decorate([
102
156
  Example(user),
103
157
  Get('{id}'),
@@ -129,11 +183,36 @@ __decorate([
129
183
  Response(notFoundResp.status, notFoundResp.description),
130
184
  __param(0, Path())
131
185
  ], UserController.prototype, "deleteUser", null);
186
+ __decorate([
187
+ Example(groupIds),
188
+ Example(partialGroups),
189
+ Get('{id}/groups'),
190
+ Tags('groups'),
191
+ Response(notFoundResp.status, notFoundResp.description),
192
+ __param(0, Request()),
193
+ __param(1, Path()),
194
+ __param(2, Query()),
195
+ __param(3, Query()),
196
+ __param(4, Query()),
197
+ __param(5, Query())
198
+ ], UserController.prototype, "getUserGroups", null);
199
+ __decorate([
200
+ Example(authenticationTokens),
201
+ Get('{id}/authentication_tokens'),
202
+ Response(notFoundResp.status, notFoundResp.description),
203
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
204
+ __param(0, Request()),
205
+ __param(1, Path()),
206
+ __param(2, Query()),
207
+ __param(3, Query())
208
+ ], UserController.prototype, "getAuthenticationTokens", null);
132
209
  UserController = __decorate([
133
210
  Route('users'),
134
211
  Security('*'),
135
212
  Response(unauthorizedResp.status, unauthorizedResp.description),
136
213
  Tags('users'),
137
- provide(UserController)
214
+ provide(UserController),
215
+ __param(0, inject(RestApi)),
216
+ __param(1, inject(UserService))
138
217
  ], UserController);
139
218
  export { UserController };
@@ -0,0 +1,21 @@
1
+ export class UserService {
2
+ #restApi;
3
+ constructor(restApi) {
4
+ this.#restApi = restApi;
5
+ }
6
+ #sanitizeUser(user) {
7
+ const sanitizedUser = { ...user };
8
+ if (sanitizedUser.pw_hash !== undefined) {
9
+ sanitizedUser.pw_hash = '***obfuscated***';
10
+ }
11
+ return sanitizedUser;
12
+ }
13
+ async getUser(id) {
14
+ const user = await this.#restApi.xoApp.getUser(id);
15
+ return this.#sanitizeUser(user);
16
+ }
17
+ async getUsers() {
18
+ const users = await this.#restApi.xoApp.getAllUsers();
19
+ return users.map(user => this.#sanitizeUser(user));
20
+ }
21
+ }
@@ -7,21 +7,24 @@ 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 { Example, Get, Path, Query, Request, Response, Route, Security, Tags } from 'tsoa';
10
+ import { Delete, Example, Get, Path, Query, Request, Response, Route, Security, SuccessResponse, Tags } from 'tsoa';
11
11
  import { inject } from 'inversify';
12
12
  import { provide } from 'inversify-binding-decorators';
13
13
  import { escapeUnsafeComplexMatcher } from '../helpers/utils.helper.mjs';
14
- import { notFoundResp, unauthorizedResp } from '../open-api/common/response.common.mjs';
14
+ import { noContentResp, notFoundResp, unauthorizedResp } from '../open-api/common/response.common.mjs';
15
15
  import { RestApi } from '../rest-api/rest-api.mjs';
16
16
  import { partialVdiSnapshots, vdiSnapshot, vdiSnapshotIds } from '../open-api/oa-examples/vdi-snapshot.oa-example.mjs';
17
17
  import { XapiXoController } from '../abstract-classes/xapi-xo-controller.mjs';
18
18
  import { genericAlarmsExample } from '../open-api/oa-examples/alarm.oa-example.mjs';
19
19
  import { AlarmService } from '../alarms/alarm.service.mjs';
20
+ import { VdiService } from '../vdis/vdi.service.mjs';
20
21
  let VdiSnapshotController = class VdiSnapshotController extends XapiXoController {
21
22
  #alarmService;
22
- constructor(restApi, alarmService) {
23
+ #vdiService;
24
+ constructor(restApi, alarmService, vdiService) {
23
25
  super('VDI-snapshot', restApi);
24
26
  this.#alarmService = alarmService;
27
+ this.#vdiService = vdiService;
25
28
  }
26
29
  /**
27
30
  * @example fields "uuid,snapshot_time,$snapshot_of"
@@ -31,6 +34,22 @@ let VdiSnapshotController = class VdiSnapshotController extends XapiXoController
31
34
  getVdiSnapshots(req, fields, ndjson, filter, limit) {
32
35
  return this.sendObjects(Object.values(this.getObjects({ filter, limit })), req);
33
36
  }
37
+ /**
38
+ *
39
+ * Export VDI-snapshot content
40
+ *
41
+ * @example id "d2727772-735b-478f-b6f9-11e7db56dfd0"
42
+ */
43
+ async exportVdiSnapshotContent(req, id, format) {
44
+ const res = req.res;
45
+ const stream = await this.#vdiService.exportContent(id, 'VDI-snapshot', {
46
+ format,
47
+ response: res,
48
+ });
49
+ process.on('SIGTERM', () => req.destroy());
50
+ req.on('close', () => stream.destroy());
51
+ return stream;
52
+ }
34
53
  /**
35
54
  * @example id "d2727772-735b-478f-b6f9-11e7db56dfd0"
36
55
  */
@@ -51,6 +70,13 @@ let VdiSnapshotController = class VdiSnapshotController extends XapiXoController
51
70
  });
52
71
  return this.sendObjects(Object.values(alarms), req, 'alarms');
53
72
  }
73
+ /**
74
+ * @example id "d2727772-735b-478f-b6f9-11e7db56dfd0"
75
+ */
76
+ async deleteVdiSnapshot(id) {
77
+ const xapiVdiSnapshot = this.getXapiObject(id);
78
+ await xapiVdiSnapshot.$xapi.VDI_destroy(xapiVdiSnapshot.$ref);
79
+ }
54
80
  };
55
81
  __decorate([
56
82
  Example(vdiSnapshotIds),
@@ -62,6 +88,15 @@ __decorate([
62
88
  __param(3, Query()),
63
89
  __param(4, Query())
64
90
  ], VdiSnapshotController.prototype, "getVdiSnapshots", null);
91
+ __decorate([
92
+ Get('{id}.{format}'),
93
+ SuccessResponse(200, 'Download started', 'application/octet-stream'),
94
+ Response(notFoundResp.status, notFoundResp.description),
95
+ Response(422, 'Invalid format'),
96
+ __param(0, Request()),
97
+ __param(1, Path()),
98
+ __param(2, Path())
99
+ ], VdiSnapshotController.prototype, "exportVdiSnapshotContent", null);
65
100
  __decorate([
66
101
  Example(vdiSnapshot),
67
102
  Get('{id}'),
@@ -80,6 +115,12 @@ __decorate([
80
115
  __param(4, Query()),
81
116
  __param(5, Query())
82
117
  ], VdiSnapshotController.prototype, "getVdiSnapshotAlarms", null);
118
+ __decorate([
119
+ Delete('{id}'),
120
+ SuccessResponse(noContentResp.status, noContentResp.description),
121
+ Response(notFoundResp.status, notFoundResp.description),
122
+ __param(0, Path())
123
+ ], VdiSnapshotController.prototype, "deleteVdiSnapshot", null);
83
124
  VdiSnapshotController = __decorate([
84
125
  Route('vdi-snapshots'),
85
126
  Security('*'),
@@ -87,6 +128,7 @@ VdiSnapshotController = __decorate([
87
128
  Tags('vdis'),
88
129
  provide(VdiSnapshotController),
89
130
  __param(0, inject(RestApi)),
90
- __param(1, inject(AlarmService))
131
+ __param(1, inject(AlarmService)),
132
+ __param(2, inject(VdiService))
91
133
  ], VdiSnapshotController);
92
134
  export { VdiSnapshotController };
@@ -7,21 +7,24 @@ 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 { Example, Get, Path, Query, Request, Response, Route, Security, Tags } from 'tsoa';
10
+ import { Delete, Example, Get, Path, Query, Request, Response, Route, Security, SuccessResponse, Tags } from 'tsoa';
11
11
  import { inject } from 'inversify';
12
12
  import { provide } from 'inversify-binding-decorators';
13
13
  import { AlarmService } from '../alarms/alarm.service.mjs';
14
14
  import { escapeUnsafeComplexMatcher } from '../helpers/utils.helper.mjs';
15
15
  import { genericAlarmsExample } from '../open-api/oa-examples/alarm.oa-example.mjs';
16
- import { notFoundResp, unauthorizedResp } from '../open-api/common/response.common.mjs';
16
+ import { noContentResp, notFoundResp, unauthorizedResp } from '../open-api/common/response.common.mjs';
17
17
  import { RestApi } from '../rest-api/rest-api.mjs';
18
18
  import { XapiXoController } from '../abstract-classes/xapi-xo-controller.mjs';
19
19
  import { partialVdis, vdi, vdiIds } from '../open-api/oa-examples/vdi.oa-example.mjs';
20
+ import { VdiService } from './vdi.service.mjs';
20
21
  let VdiController = class VdiController extends XapiXoController {
21
22
  #alarmService;
22
- constructor(restApi, alarmService) {
23
+ #vdiService;
24
+ constructor(restApi, alarmService, vdiService) {
23
25
  super('VDI', restApi);
24
26
  this.#alarmService = alarmService;
27
+ this.#vdiService = vdiService;
25
28
  }
26
29
  /**
27
30
  * @example fields "*"
@@ -31,6 +34,19 @@ let VdiController = class VdiController extends XapiXoController {
31
34
  getVdis(req, fields, ndjson, filter, limit) {
32
35
  return this.sendObjects(Object.values(this.getObjects({ filter, limit })), req);
33
36
  }
37
+ /**
38
+ *
39
+ * Export VDI content
40
+ *
41
+ * @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
42
+ */
43
+ async exportVdiContent(req, id, format) {
44
+ const res = req.res;
45
+ const stream = await this.#vdiService.exportContent(id, 'VDI', { format, response: res });
46
+ process.on('SIGTERM', () => req.destroy());
47
+ req.on('close', () => stream.destroy());
48
+ return stream;
49
+ }
34
50
  /**
35
51
  * @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
36
52
  */
@@ -51,6 +67,13 @@ let VdiController = class VdiController extends XapiXoController {
51
67
  });
52
68
  return this.sendObjects(Object.values(alarms), req, 'alarms');
53
69
  }
70
+ /**
71
+ * @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
72
+ */
73
+ async deleteVdi(id) {
74
+ const xapiVdi = this.getXapiObject(id);
75
+ await xapiVdi.$xapi.VDI_destroy(xapiVdi.$ref);
76
+ }
54
77
  };
55
78
  __decorate([
56
79
  Example(vdiIds),
@@ -62,6 +85,15 @@ __decorate([
62
85
  __param(3, Query()),
63
86
  __param(4, Query())
64
87
  ], VdiController.prototype, "getVdis", null);
88
+ __decorate([
89
+ Get('{id}.{format}'),
90
+ SuccessResponse(200, 'Download started', 'application/octet-stream'),
91
+ Response(notFoundResp.status, notFoundResp.description),
92
+ Response(422, 'Invalid format'),
93
+ __param(0, Request()),
94
+ __param(1, Path()),
95
+ __param(2, Path())
96
+ ], VdiController.prototype, "exportVdiContent", null);
65
97
  __decorate([
66
98
  Example(vdi),
67
99
  Get('{id}'),
@@ -80,6 +112,12 @@ __decorate([
80
112
  __param(4, Query()),
81
113
  __param(5, Query())
82
114
  ], VdiController.prototype, "getVdiAlarms", null);
115
+ __decorate([
116
+ Delete('{id}'),
117
+ SuccessResponse(noContentResp.status, noContentResp.description),
118
+ Response(notFoundResp.status, notFoundResp.description),
119
+ __param(0, Path())
120
+ ], VdiController.prototype, "deleteVdi", null);
83
121
  VdiController = __decorate([
84
122
  Route('vdis'),
85
123
  Security('*'),
@@ -87,6 +125,7 @@ VdiController = __decorate([
87
125
  Tags('vdis'),
88
126
  provide(VdiController),
89
127
  __param(0, inject(RestApi)),
90
- __param(1, inject(AlarmService))
128
+ __param(1, inject(AlarmService)),
129
+ __param(2, inject(VdiService))
91
130
  ], VdiController);
92
131
  export { VdiController };
@@ -0,0 +1,21 @@
1
+ export class VdiService {
2
+ #restApi;
3
+ constructor(restApi) {
4
+ this.#restApi = restApi;
5
+ }
6
+ async exportContent(id, type, { format, response }) {
7
+ const xapiVdi = this.#restApi.getXapiObject(id, type);
8
+ const stream = await xapiVdi.$xapi.VDI_exportContent(xapiVdi.$ref, { format });
9
+ if (response !== undefined) {
10
+ const headers = new Headers({
11
+ 'content-disposition': `attachment; filename=${id}.${format}`,
12
+ 'content-type': 'application/octet-stream',
13
+ });
14
+ if (stream.length !== undefined) {
15
+ headers.append('content-length', stream.length.toString());
16
+ }
17
+ response.setHeaders(headers);
18
+ }
19
+ return stream;
20
+ }
21
+ }
@@ -7,17 +7,18 @@ 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 { Example, Get, Path, Query, Request, Response, Route, Security, Tags } from 'tsoa';
10
+ import { Delete, Example, Get, Path, Query, Request, Response, Route, Security, SuccessResponse, Tags } from 'tsoa';
11
11
  import { inject } from 'inversify';
12
- import { AlarmService } from '../alarms/alarm.service.mjs';
12
+ import { AlarmService, RAW_ALARM_FILTER } from '../alarms/alarm.service.mjs';
13
13
  import { escapeUnsafeComplexMatcher, limitAndFilterArray } from '../helpers/utils.helper.mjs';
14
14
  import { genericAlarmsExample } from '../open-api/oa-examples/alarm.oa-example.mjs';
15
- import { notFoundResp, unauthorizedResp } from '../open-api/common/response.common.mjs';
15
+ import { forbiddenOperationResp, incorrectStateResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
16
16
  import { RestApi } from '../rest-api/rest-api.mjs';
17
17
  import { XapiXoController } from '../abstract-classes/xapi-xo-controller.mjs';
18
18
  import { provide } from 'inversify-binding-decorators';
19
19
  import { partialVmSnapshots, vmSnapshot, vmSnapshotIds, vmSnapshotVdis, } from '../open-api/oa-examples/vm-snapshot.oa-example.mjs';
20
20
  import { VmService } from '../vms/vm.service.mjs';
21
+ import { messageIds, partialMessages } from '../open-api/oa-examples/message.oa-example.mjs';
21
22
  let VmSnapshotController = class VmSnapshotController extends XapiXoController {
22
23
  #alarmService;
23
24
  #vmService;
@@ -35,12 +36,35 @@ let VmSnapshotController = class VmSnapshotController extends XapiXoController {
35
36
  getVmSnapshots(req, fields, ndjson, filter, limit) {
36
37
  return this.sendObjects(Object.values(this.getObjects({ filter, limit })), req);
37
38
  }
39
+ /**
40
+ *
41
+ * Export VM-snapshot. Compress is only used for XVA format
42
+ *
43
+ * @example id "d68fca2c-41e6-be87-d790-105c1642a090"
44
+ */
45
+ async exportVmSnapshot(req, id, format, compress) {
46
+ const stream = await this.#vmService.export(id, 'VM-snapshot', {
47
+ compress,
48
+ format,
49
+ response: req.res,
50
+ });
51
+ process.on('SIGTERM', () => req.destroy());
52
+ req.on('close', () => stream.destroy());
53
+ return stream;
54
+ }
38
55
  /**
39
56
  * @example id "d68fca2c-41e6-be87-d790-105c1642a090"
40
57
  */
41
58
  getVmSnapshot(id) {
42
59
  return this.getObject(id);
43
60
  }
61
+ /**
62
+ * @example id "d68fca2c-41e6-be87-d790-105c1642a090"
63
+ */
64
+ async deleteVmSnapshot(id) {
65
+ const xapiVmSnapshot = this.getXapiObject(id);
66
+ await xapiVmSnapshot.$xapi.VM_destroy(xapiVmSnapshot.$ref);
67
+ }
44
68
  /**
45
69
  * @example id "d68fca2c-41e6-be87-d790-105c1642a090"
46
70
  * @example fields "id,time"
@@ -65,6 +89,20 @@ let VmSnapshotController = class VmSnapshotController extends XapiXoController {
65
89
  const vdis = this.#vmService.getVmVdis(id, 'VM-snapshot');
66
90
  return this.sendObjects(limitAndFilterArray(vdis, { filter, limit }), req, obj => obj.type.toLowerCase() + 's');
67
91
  }
92
+ /**
93
+ * @example id "d68fca2c-41e6-be87-d790-105c1642a090"
94
+ * @example fields "name,id,$object"
95
+ * @example filter "name:VM_STARTED"
96
+ * @example limit 42
97
+ */
98
+ getVmSnapshotsMessages(req, id, fields, ndjson, filter, limit) {
99
+ const vm = this.getObject(id);
100
+ const messages = this.restApi.getObjectsByType('message', {
101
+ filter: `${escapeUnsafeComplexMatcher(filter) ?? ''} $object:${vm.uuid} !${RAW_ALARM_FILTER}`,
102
+ limit,
103
+ });
104
+ return this.sendObjects(Object.values(messages), req, 'messages');
105
+ }
68
106
  };
69
107
  __decorate([
70
108
  Example(vmSnapshotIds),
@@ -76,12 +114,30 @@ __decorate([
76
114
  __param(3, Query()),
77
115
  __param(4, Query())
78
116
  ], VmSnapshotController.prototype, "getVmSnapshots", null);
117
+ __decorate([
118
+ Get('{id}.{format}'),
119
+ SuccessResponse(200, 'Download started', 'application/octet-stream'),
120
+ Response(notFoundResp.status, notFoundResp.description),
121
+ Response(422, 'Invalid format, Invalid compress'),
122
+ __param(0, Request()),
123
+ __param(1, Path()),
124
+ __param(2, Path()),
125
+ __param(3, Query())
126
+ ], VmSnapshotController.prototype, "exportVmSnapshot", null);
79
127
  __decorate([
80
128
  Example(vmSnapshot),
81
129
  Get('{id}'),
82
130
  Response(notFoundResp.status, notFoundResp.description),
83
131
  __param(0, Path())
84
132
  ], VmSnapshotController.prototype, "getVmSnapshot", null);
133
+ __decorate([
134
+ Delete('{id}'),
135
+ SuccessResponse(noContentResp.status, noContentResp.description),
136
+ Response(notFoundResp.status, notFoundResp.description),
137
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
138
+ Response(incorrectStateResp.status, incorrectStateResp.description),
139
+ __param(0, Path())
140
+ ], VmSnapshotController.prototype, "deleteVmSnapshot", null);
85
141
  __decorate([
86
142
  Example(genericAlarmsExample),
87
143
  Get('{id}/alarms'),
@@ -106,6 +162,19 @@ __decorate([
106
162
  __param(4, Query()),
107
163
  __param(5, Query())
108
164
  ], VmSnapshotController.prototype, "getVmSnapshotVdis", null);
165
+ __decorate([
166
+ Example(messageIds),
167
+ Example(partialMessages),
168
+ Get('{id}/messages'),
169
+ Tags('messages'),
170
+ Response(notFoundResp.status, notFoundResp.description),
171
+ __param(0, Request()),
172
+ __param(1, Path()),
173
+ __param(2, Query()),
174
+ __param(3, Query()),
175
+ __param(4, Query()),
176
+ __param(5, Query())
177
+ ], VmSnapshotController.prototype, "getVmSnapshotsMessages", null);
109
178
  VmSnapshotController = __decorate([
110
179
  Route('vm-snapshots'),
111
180
  Security('*'),
@@ -7,13 +7,13 @@ 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 { Example, Get, Security, Query, Request, Response, Route, Tags, Path } from 'tsoa';
10
+ import { Example, Get, Security, Query, Request, Response, Route, Tags, Path, Delete, SuccessResponse } from 'tsoa';
11
11
  import { inject } from 'inversify';
12
12
  import { provide } from 'inversify-binding-decorators';
13
13
  import { AlarmService } from '../alarms/alarm.service.mjs';
14
14
  import { escapeUnsafeComplexMatcher, limitAndFilterArray } from '../helpers/utils.helper.mjs';
15
15
  import { genericAlarmsExample } from '../open-api/oa-examples/alarm.oa-example.mjs';
16
- import { notFoundResp, unauthorizedResp } from '../open-api/common/response.common.mjs';
16
+ import { forbiddenOperationResp, incorrectStateResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
17
17
  import { RestApi } from '../rest-api/rest-api.mjs';
18
18
  import { XapiXoController } from '../abstract-classes/xapi-xo-controller.mjs';
19
19
  import { partialVmTemplates, vmTemplate, vmTemplateIds, vmTemplateVdis, } from '../open-api/oa-examples/vm-template.oa-example.mjs';
@@ -34,12 +34,35 @@ let VmTemplateController = class VmTemplateController extends XapiXoController {
34
34
  getVmTemplates(req, fields, ndjson, filter, limit) {
35
35
  return this.sendObjects(Object.values(this.getObjects({ filter, limit })), req);
36
36
  }
37
+ /**
38
+ *
39
+ * Export VM-template. Compress is only used for XVA format
40
+ *
41
+ * @example id "b7569d99-30f8-178a-7d94-801de3e29b5b-f873abe0-b138-4995-8f6f-498b423d234d"
42
+ */
43
+ async exportVmTemplate(req, id, format, compress) {
44
+ const stream = await this.#vmService.export(id, 'VM-template', {
45
+ compress,
46
+ format,
47
+ response: req.res,
48
+ });
49
+ process.on('SIGTERM', () => req.destroy());
50
+ req.on('close', () => stream.destroy());
51
+ return stream;
52
+ }
37
53
  /**
38
54
  * @example id "b7569d99-30f8-178a-7d94-801de3e29b5b-f873abe0-b138-4995-8f6f-498b423d234d"
39
55
  * */
40
56
  getVmTemplate(id) {
41
57
  return this.getObject(id);
42
58
  }
59
+ /**
60
+ * @example id "6d50ba76-0f11-1ff1-4f6a-b502afc31b8e"
61
+ */
62
+ async deleteVmTemplate(id) {
63
+ const xapiVmTemplate = this.getXapiObject(id);
64
+ await xapiVmTemplate.$xapi.VM_destroy(xapiVmTemplate.$ref);
65
+ }
43
66
  /**
44
67
  * @example id "b7569d99-30f8-178a-7d94-801de3e29b5b-f873abe0-b138-4995-8f6f-498b423d234d"
45
68
  * @example fields "id,time"
@@ -75,12 +98,30 @@ __decorate([
75
98
  __param(3, Query()),
76
99
  __param(4, Query())
77
100
  ], VmTemplateController.prototype, "getVmTemplates", null);
101
+ __decorate([
102
+ Get('{id}.{format}'),
103
+ SuccessResponse(200, 'Download started', 'application/octet-stream'),
104
+ Response(notFoundResp.status, notFoundResp.description),
105
+ Response(422, 'Invalid format, Invalid compress'),
106
+ __param(0, Request()),
107
+ __param(1, Path()),
108
+ __param(2, Path()),
109
+ __param(3, Query())
110
+ ], VmTemplateController.prototype, "exportVmTemplate", null);
78
111
  __decorate([
79
112
  Example(vmTemplate),
80
113
  Get('{id}'),
81
114
  Response(notFoundResp.status, notFoundResp.description),
82
115
  __param(0, Path())
83
116
  ], VmTemplateController.prototype, "getVmTemplate", null);
117
+ __decorate([
118
+ Delete('{id}'),
119
+ SuccessResponse(noContentResp.status, noContentResp.description),
120
+ Response(notFoundResp.status, notFoundResp.description),
121
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
122
+ Response(incorrectStateResp.status, incorrectStateResp.description),
123
+ __param(0, Path())
124
+ ], VmTemplateController.prototype, "deleteVmTemplate", null);
84
125
  __decorate([
85
126
  Example(genericAlarmsExample),
86
127
  Get('{id}/alarms'),