]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.ts
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / shared / services / task-message.service.ts
1 import { Injectable } from '@angular/core';
2
3 import { I18n } from '@ngx-translate/i18n-polyfill';
4
5 import { Components } from '../enum/components.enum';
6 import { FinishedTask } from '../models/finished-task';
7 import { Task } from '../models/task';
8 import { ServicesModule } from './services.module';
9
10 export class TaskMessageOperation {
11 running: string;
12 failure: string;
13 success: string;
14
15 constructor(running: string, failure: string, success: string) {
16 this.running = running;
17 this.failure = failure;
18 this.success = success;
19 }
20 }
21
22 class TaskMessage {
23 i18n: I18n;
24
25 operation: TaskMessageOperation;
26 involves: (object) => string;
27 errors: (metadata) => object;
28
29 failure(metadata): string {
30 return this.i18n('Failed to {{failure}} {{metadata}}', {
31 failure: this.operation.failure,
32 metadata: this.involves(metadata)
33 });
34 }
35
36 running(metadata): string {
37 return `${this.operation.running} ${this.involves(metadata)}`;
38 }
39
40 success(metadata): string {
41 return `${this.operation.success} ${this.involves(metadata)}`;
42 }
43
44 constructor(
45 i18n: I18n,
46 operation: TaskMessageOperation,
47 involves: (metadata) => string,
48 errors?: (metadata) => object
49 ) {
50 this.i18n = i18n;
51 this.operation = operation;
52 this.involves = involves;
53 this.errors = errors || (() => ({}));
54 }
55 }
56
57 @Injectable({
58 providedIn: ServicesModule
59 })
60 export class TaskMessageService {
61 constructor(private i18n: I18n) {}
62
63 defaultMessage = this.newTaskMessage(
64 new TaskMessageOperation(this.i18n('Executing'), this.i18n('execute'), this.i18n('Executed')),
65 (metadata) => {
66 return (
67 (metadata && (Components[metadata.component] || metadata.component)) ||
68 this.i18n('unknown task')
69 );
70 },
71 () => {
72 return {};
73 }
74 );
75
76 commonOperations = {
77 create: new TaskMessageOperation(
78 this.i18n('Creating'),
79 this.i18n('create'),
80 this.i18n('Created')
81 ),
82 update: new TaskMessageOperation(
83 this.i18n('Updating'),
84 this.i18n('update'),
85 this.i18n('Updated')
86 ),
87 delete: new TaskMessageOperation(
88 this.i18n('Deleting'),
89 this.i18n('delete'),
90 this.i18n('Deleted')
91 )
92 };
93
94 rbd = {
95 default: (metadata) =>
96 this.i18n(`RBD '{{id}}'`, {
97 id: `${metadata.pool_name}/${metadata.image_name}`
98 }),
99 child: (metadata) =>
100 this.i18n(`RBD '{{id}}'`, {
101 id: `${metadata.child_pool_name}/${metadata.child_image_name}`
102 }),
103 destination: (metadata) =>
104 this.i18n(`RBD '{{id}}'`, {
105 id: `${metadata.dest_pool_name}/${metadata.dest_image_name}`
106 }),
107 snapshot: (metadata) =>
108 this.i18n(`RBD snapshot '{{id}}'`, {
109 id: `${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}`
110 })
111 };
112
113 rbd_mirroring = {
114 pool: (metadata) =>
115 this.i18n(`mirror mode for pool '{{id}}'`, {
116 id: `${metadata.pool_name}`
117 }),
118 pool_peer: (metadata) =>
119 this.i18n(`mirror peer for pool '{{id}}'`, {
120 id: `${metadata.pool_name}`
121 })
122 };
123
124 messages = {
125 // Pool tasks
126 'pool/create': this.newTaskMessage(
127 this.commonOperations.create,
128 (metadata) => this.pool(metadata),
129 (metadata) => ({
130 '17': this.i18n('Name is already used by {{pool_name}}.', {
131 pool_name: this.pool(metadata)
132 })
133 })
134 ),
135 'pool/edit': this.newTaskMessage(
136 this.commonOperations.update,
137 (metadata) => this.pool(metadata),
138 (metadata) => ({
139 '17': this.i18n('Name is already used by {{pool_name}}.', {
140 pool_name: this.pool(metadata)
141 })
142 })
143 ),
144 'pool/delete': this.newTaskMessage(this.commonOperations.delete, (metadata) =>
145 this.pool(metadata)
146 ),
147 // Erasure code profile tasks
148 'ecp/create': this.newTaskMessage(
149 this.commonOperations.create,
150 (metadata) => this.ecp(metadata),
151 (metadata) => ({
152 '17': this.i18n('Name is already used by {{name}}.', {
153 name: this.ecp(metadata)
154 })
155 })
156 ),
157 'ecp/delete': this.newTaskMessage(this.commonOperations.delete, (metadata) =>
158 this.ecp(metadata)
159 ),
160 // RBD tasks
161 'rbd/create': this.newTaskMessage(
162 this.commonOperations.create,
163 this.rbd.default,
164 (metadata) => ({
165 '17': this.i18n('Name is already used by {{rbd_name}}.', {
166 rbd_name: this.rbd.default(metadata)
167 })
168 })
169 ),
170 'rbd/edit': this.newTaskMessage(this.commonOperations.update, this.rbd.default, (metadata) => ({
171 '17': this.i18n('Name is already used by {{rbd_name}}.', {
172 rbd_name: this.rbd.default(metadata)
173 })
174 })),
175 'rbd/delete': this.newTaskMessage(
176 this.commonOperations.delete,
177 this.rbd.default,
178 (metadata) => ({
179 '39': this.i18n('{{rbd_name}} contains snapshots.', {
180 rbd_name: this.rbd.default(metadata)
181 })
182 })
183 ),
184 'rbd/clone': this.newTaskMessage(
185 new TaskMessageOperation(this.i18n('Cloning'), this.i18n('clone'), this.i18n('Cloned')),
186 this.rbd.child,
187 (metadata) => ({
188 '17': this.i18n('Name is already used by {{rbd_name}}.', {
189 rbd_name: this.rbd.child(metadata)
190 }),
191 '22': this.i18n('Snapshot of {{rbd_name}} must be protected.', {
192 rbd_name: this.rbd.child(metadata)
193 })
194 })
195 ),
196 'rbd/copy': this.newTaskMessage(
197 new TaskMessageOperation(this.i18n('Copying'), this.i18n('copy'), this.i18n('Copied')),
198 this.rbd.destination,
199 (metadata) => ({
200 '17': this.i18n('Name is already used by {{rbd_name}}.', {
201 rbd_name: this.rbd.destination(metadata)
202 })
203 })
204 ),
205 'rbd/flatten': this.newTaskMessage(
206 new TaskMessageOperation(
207 this.i18n('Flattening'),
208 this.i18n('flatten'),
209 this.i18n('Flattened')
210 ),
211 this.rbd.default
212 ),
213 // RBD snapshot tasks
214 'rbd/snap/create': this.newTaskMessage(
215 this.commonOperations.create,
216 this.rbd.snapshot,
217 (metadata) => ({
218 '17': this.i18n('Name is already used by {{snap_name}}.', {
219 snap_name: this.rbd.snapshot(metadata)
220 })
221 })
222 ),
223 'rbd/snap/edit': this.newTaskMessage(
224 this.commonOperations.update,
225 this.rbd.snapshot,
226 (metadata) => ({
227 '16': this.i18n('Cannot unprotect {{snap_name}} because it contains child images.', {
228 snap_name: this.rbd.snapshot(metadata)
229 })
230 })
231 ),
232 'rbd/snap/delete': this.newTaskMessage(
233 this.commonOperations.delete,
234 this.rbd.snapshot,
235 (metadata) => ({
236 '16': this.i18n(`Cannot delete {{snap_name}} because it's protected.`, {
237 snap_name: this.rbd.snapshot(metadata)
238 })
239 })
240 ),
241 'rbd/snap/rollback': this.newTaskMessage(
242 new TaskMessageOperation(
243 this.i18n('Rolling back'),
244 this.i18n('rollback'),
245 this.i18n('Rolled back')
246 ),
247 this.rbd.snapshot
248 ),
249 // RBD trash tasks
250 'rbd/trash/move': this.newTaskMessage(
251 new TaskMessageOperation(this.i18n('Moving'), this.i18n('move'), this.i18n('Moved')),
252 (metadata) =>
253 this.i18n(`image '{{id}}' to trash`, {
254 id: `${metadata.pool_name}/${metadata.image_name}`
255 }),
256 () => ({
257 2: this.i18n('Could not find image.')
258 })
259 ),
260 'rbd/trash/restore': this.newTaskMessage(
261 new TaskMessageOperation(this.i18n('Restoring'), this.i18n('restore'), this.i18n('Restored')),
262 (metadata) =>
263 this.i18n(`image '{{id}}' into '{{new_id}}'`, {
264 id: `${metadata.pool_name}@${metadata.image_id}`,
265 new_id: `${metadata.pool_name}/${metadata.new_image_name}`
266 }),
267 (metadata) => ({
268 17: this.i18n(`Image name '{{id}}' is already in use.`, {
269 id: `${metadata.pool_name}/${metadata.new_image_name}`
270 })
271 })
272 ),
273 'rbd/trash/remove': this.newTaskMessage(
274 new TaskMessageOperation(this.i18n('Deleting'), this.i18n('delete'), this.i18n('Deleted')),
275 (metadata) =>
276 this.i18n(`image '{{id}}'`, {
277 id: `${metadata.pool_name}/${metadata.image_name}@${metadata.image_id}`
278 })
279 ),
280 'rbd/trash/purge': this.newTaskMessage(
281 new TaskMessageOperation(this.i18n('Purging'), this.i18n('purge'), this.i18n('Purged')),
282 (metadata) => {
283 let message = this.i18n('all pools');
284 if (metadata.pool_name) {
285 message = `'${metadata.pool_name}'`;
286 }
287 return this.i18n('images from {{message}}', {
288 message: message
289 });
290 }
291 ),
292 // RBD mirroring tasks
293 'rbd/mirroring/pool/edit': this.newTaskMessage(
294 this.commonOperations.update,
295 this.rbd_mirroring.pool,
296 () => ({
297 16: this.i18n('Cannot disable mirroring because it contains a peer.')
298 })
299 ),
300 'rbd/mirroring/peer/add': this.newTaskMessage(
301 this.commonOperations.create,
302 this.rbd_mirroring.pool_peer,
303 () => ({})
304 ),
305 'rbd/mirroring/peer/edit': this.newTaskMessage(
306 this.commonOperations.update,
307 this.rbd_mirroring.pool_peer,
308 () => ({})
309 ),
310 'rbd/mirroring/peer/delete': this.newTaskMessage(
311 this.commonOperations.delete,
312 this.rbd_mirroring.pool_peer,
313 () => ({})
314 ),
315 // iSCSI target tasks
316 'iscsi/target/create': this.newTaskMessage(this.commonOperations.create, (metadata) =>
317 this.iscsiTarget(metadata)
318 ),
319 'iscsi/target/edit': this.newTaskMessage(this.commonOperations.update, (metadata) =>
320 this.iscsiTarget(metadata)
321 ),
322 'iscsi/target/delete': this.newTaskMessage(this.commonOperations.delete, (metadata) =>
323 this.iscsiTarget(metadata)
324 ),
325 'nfs/create': this.newTaskMessage(this.commonOperations.create, (metadata) =>
326 this.nfs(metadata)
327 ),
328 'nfs/edit': this.newTaskMessage(this.commonOperations.update, (metadata) => this.nfs(metadata)),
329 'nfs/delete': this.newTaskMessage(this.commonOperations.delete, (metadata) =>
330 this.nfs(metadata)
331 )
332 };
333
334 newTaskMessage(
335 operation: TaskMessageOperation,
336 involves: (metadata) => string,
337 errors?: (metadata) => object
338 ) {
339 return new TaskMessage(this.i18n, operation, involves, errors);
340 }
341
342 pool(metadata) {
343 return this.i18n(`pool '{{pool_name}}'`, {
344 pool_name: metadata.pool_name
345 });
346 }
347
348 ecp(metadata) {
349 return this.i18n(`erasure code profile '{{name}}'`, { name: metadata.name });
350 }
351
352 iscsiTarget(metadata) {
353 return this.i18n(`target '{{target_iqn}}'`, { target_iqn: metadata.target_iqn });
354 }
355
356 nfs(metadata) {
357 return this.i18n(`NFS {{nfs_id}}`, {
358 nfs_id: `'${metadata.cluster_id}:${metadata.export_id ? metadata.export_id : metadata.path}'`
359 });
360 }
361
362 _getTaskTitle(task: Task) {
363 return this.messages[task.name] || this.defaultMessage;
364 }
365
366 getSuccessTitle(task: FinishedTask) {
367 return this._getTaskTitle(task).success(task.metadata);
368 }
369
370 getErrorMessage(task: FinishedTask) {
371 return (
372 this._getTaskTitle(task).errors(task.metadata)[task.exception.code] || task.exception.detail
373 );
374 }
375
376 getErrorTitle(task: Task) {
377 return this._getTaskTitle(task).failure(task.metadata);
378 }
379
380 getRunningTitle(task: Task) {
381 return this._getTaskTitle(task).running(task.metadata);
382 }
383
384 getRunningText(task: Task) {
385 return this._getTaskTitle(task).operation.running;
386 }
387 }