]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Use new ImageSpec class 31622/head
authorTiago Melo <tspmelo@gmail.com>
Wed, 13 Nov 2019 16:48:10 +0000 (15:48 -0100)
committerTiago Melo <tmelo@suse.com>
Wed, 20 Nov 2019 15:20:13 +0000 (14:20 -0100)
This class should be used when dealing with RBD image specs.
It allows the creation of an ImageSpec given the names of the pool, image and
namespace. Alternatively you can also create one with an already existing
image spec string.

With it you keep the access to each individual component and can also convert it
to a well formated string.

Fixes: https://tracker.ceph.com/issues/42787
Signed-off-by: Tiago Melo <tmelo@suse.com>
17 files changed:
src/pybind/mgr/dashboard/frontend/e2e/block/images.e2e-spec.ts
src/pybind/mgr/dashboard/frontend/e2e/block/images.po.ts
src/pybind/mgr/dashboard/frontend/e2e/pools/pools.e2e-spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/models/image-spec.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.ts

index f031a3ea72f7570c8a77f4f0976c7c62d24b3101..1d807e790176e34b17e1782fafcfbbc30c1feeb8 100644 (file)
@@ -37,8 +37,8 @@ describe('Images page', () => {
 
   describe('create, edit & delete image test', () => {
     const poolName = 'e2e_images_pool';
-    const imageName = 'e2e_images_image';
-    const newImageName = 'e2e_images_image_new';
+    const imageName = 'e2e_images#image';
+    const newImageName = 'e2e_images#image_new';
 
     beforeAll(async () => {
       await pools.navigateTo('create'); // Need pool for image testing
@@ -70,9 +70,9 @@ describe('Images page', () => {
   });
 
   describe('move to trash, restore and purge image tests', () => {
-    const poolName = 'trashpool';
-    const imageName = 'trashimage';
-    const newImageName = 'newtrashimage';
+    const poolName = 'trash_pool';
+    const imageName = 'trash#image';
+    const newImageName = 'newtrash#image';
 
     beforeAll(async () => {
       await pools.navigateTo('create'); // Need pool for image testing
index 33b3661d49e07c7e7edab4ee2b6318a22439d812..1d3dce134918638d5fcb94dfe7c4662c5b8597fe 100644 (file)
@@ -35,9 +35,9 @@ export class ImagesPageHelper extends PageHelper {
   async editImage(name, pool, newName, newSize) {
     const base_url = '/#/block/rbd/edit/';
     const editURL = base_url
-      .concat(pool)
+      .concat(encodeURIComponent(pool))
       .concat('%2F')
-      .concat(name);
+      .concat(encodeURIComponent(name));
     await browser.get(editURL);
 
     await element(by.id('name')).click(); // click name box and send new name
index 4b1712f44f185e0be5b9445666169f984e830038..7668dc2ccfa1fa49451ea5631c1f91bb16450a78 100644 (file)
@@ -2,7 +2,7 @@ import { PoolPageHelper } from './pools.po';
 
 describe('Pools page', () => {
   let pools: PoolPageHelper;
-  const poolName = 'pool_e2e_pool_test';
+  const poolName = 'pool_e2e_pool/test';
 
   beforeAll(async () => {
     pools = new PoolPageHelper();
index 04635367646aef1e4d89d278a1600867ddb18a37..e9d9e1f24a0d569f63b3943087d16a6895e3240f 100644 (file)
@@ -14,6 +14,7 @@ import { delay } from 'rxjs/operators';
 import { ActivatedRouteStub } from '../../../../testing/activated-route-stub';
 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { RbdService } from '../../../shared/api/rbd.service';
+import { ImageSpec } from '../../../shared/models/image-spec';
 import { SharedModule } from '../../../shared/shared.module';
 import { RbdConfigurationFormComponent } from '../rbd-configuration-form/rbd-configuration-form.component';
 import { RbdFormMode } from './rbd-form-mode.enum';
@@ -181,20 +182,20 @@ describe('RbdFormComponent', () => {
     it('with namespace', () => {
       activatedRoute.setParams({ image_spec: 'foo%2Fbar%2Fbaz' });
 
-      expect(rbdService.get).toHaveBeenCalledWith('foo', 'bar', 'baz');
+      expect(rbdService.get).toHaveBeenCalledWith(new ImageSpec('foo', 'bar', 'baz'));
     });
 
     it('without snapName', () => {
       activatedRoute.setParams({ image_spec: 'foo%2Fbar', snap: undefined });
 
-      expect(rbdService.get).toHaveBeenCalledWith('foo', null, 'bar');
+      expect(rbdService.get).toHaveBeenCalledWith(new ImageSpec('foo', null, 'bar'));
       expect(component.snapName).toBeUndefined();
     });
 
     it('with snapName', () => {
       activatedRoute.setParams({ image_spec: 'foo%2Fbar', snap: 'baz%2Fbaz' });
 
-      expect(rbdService.get).toHaveBeenCalledWith('foo', null, 'bar');
+      expect(rbdService.get).toHaveBeenCalledWith(new ImageSpec('foo', null, 'bar'));
       expect(component.snapName).toBe('baz/baz');
     });
   });
index 78a0a9f36b2aa16473372789d274e5f7f4fe20cd..82dbe49bdd6bec494b558effdee3a1b0eecc1407 100644 (file)
@@ -18,6 +18,7 @@ import {
   RbdConfigurationSourceField
 } from '../../../shared/models/configuration';
 import { FinishedTask } from '../../../shared/models/finished-task';
+import { ImageSpec } from '../../../shared/models/image-spec';
 import { Permission } from '../../../shared/models/permissions';
 import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
@@ -235,13 +236,11 @@ export class RbdFormComponent implements OnInit {
       this.mode === this.rbdFormMode.copying
     ) {
       this.route.params.subscribe((params: { image_spec: string; snap: string }) => {
-        const [poolName, namespace, rbdName] = this.rbdService.parseImageSpec(
-          decodeURIComponent(params.image_spec)
-        );
+        const imageSpec = ImageSpec.fromString(decodeURIComponent(params.image_spec));
         if (params.snap) {
           this.snapName = decodeURIComponent(params.snap);
         }
-        promisses[Promisse.RbdServiceGet] = this.rbdService.get(poolName, namespace, rbdName);
+        promisses[Promisse.RbdServiceGet] = this.rbdService.get(imageSpec);
       });
     } else {
       // New image
@@ -496,11 +495,11 @@ export class RbdFormComponent implements OnInit {
 
   setResponse(response: RbdFormResponseModel, snapName: string) {
     this.response = response;
-    const imageSpec = this.rbdService.getImageSpec(
+    const imageSpec = new ImageSpec(
       response.pool_name,
       response.namespace,
       response.name
-    );
+    ).toString();
     if (this.mode === this.rbdFormMode.cloning) {
       this.rbdForm.get('parent').setValue(`${imageSpec}@${snapName}`);
     } else if (this.mode === this.rbdFormMode.copying) {
@@ -618,44 +617,35 @@ export class RbdFormComponent implements OnInit {
   }
 
   editAction(): Observable<any> {
+    const imageSpec = new ImageSpec(
+      this.response.pool_name,
+      this.response.namespace,
+      this.response.name
+    );
     return this.taskWrapper.wrapTaskAroundCall({
       task: new FinishedTask('rbd/edit', {
-        image_spec: this.rbdService.getImageSpec(
-          this.response.pool_name,
-          this.response.namespace,
-          this.response.name
-        )
+        image_spec: imageSpec.toString()
       }),
-      call: this.rbdService.update(
-        this.response.pool_name,
-        this.response.namespace,
-        this.response.name,
-        this.editRequest()
-      )
+      call: this.rbdService.update(imageSpec, this.editRequest())
     });
   }
 
   cloneAction(): Observable<any> {
     const request = this.cloneRequest();
+    const imageSpec = new ImageSpec(
+      this.response.pool_name,
+      this.response.namespace,
+      this.response.name
+    );
     return this.taskWrapper.wrapTaskAroundCall({
       task: new FinishedTask('rbd/clone', {
-        parent_image_spec: this.rbdService.get(
-          this.response.pool_name,
-          this.response.namespace,
-          this.response.name
-        ),
+        parent_image_spec: imageSpec.toString(),
         parent_snap_name: this.snapName,
         child_pool_name: request.child_pool_name,
         child_namespace: request.child_namespace,
         child_image_name: request.child_image_name
       }),
-      call: this.rbdService.cloneSnapshot(
-        this.response.pool_name,
-        this.response.namespace,
-        this.response.name,
-        this.snapName,
-        request
-      )
+      call: this.rbdService.cloneSnapshot(imageSpec, this.snapName, request)
     });
   }
 
@@ -690,24 +680,19 @@ export class RbdFormComponent implements OnInit {
 
   copyAction(): Observable<any> {
     const request = this.copyRequest();
-
+    const imageSpec = new ImageSpec(
+      this.response.pool_name,
+      this.response.namespace,
+      this.response.name
+    );
     return this.taskWrapper.wrapTaskAroundCall({
       task: new FinishedTask('rbd/copy', {
-        src_image_spec: this.rbdService.getImageSpec(
-          this.response.pool_name,
-          this.response.namespace,
-          this.response.name
-        ),
+        src_image_spec: imageSpec.toString(),
         dest_pool_name: request.dest_pool_name,
         dest_namespace: request.dest_namespace,
         dest_image_name: request.dest_image_name
       }),
-      call: this.rbdService.copy(
-        this.response.pool_name,
-        this.response.namespace,
-        this.response.name,
-        request
-      )
+      call: this.rbdService.copy(imageSpec, request)
     });
   }
 
index 28a3a6e66882545c897aa595a9d97aeeb1724fce..b1101670924a80ef9c3131b4b9c13ec53b1443ec 100644 (file)
@@ -16,6 +16,7 @@ import { CdTableAction } from '../../../shared/models/cd-table-action';
 import { CdTableColumn } from '../../../shared/models/cd-table-column';
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
 import { FinishedTask } from '../../../shared/models/finished-task';
+import { ImageSpec } from '../../../shared/models/image-spec';
 import { Permission } from '../../../shared/models/permissions';
 import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
 import { DimlessPipe } from '../../../shared/pipes/dimless.pipe';
@@ -78,9 +79,9 @@ export class RbdListComponent implements OnInit {
       )
   };
 
-  private createRbdFromTaskImageSpec(imageSpec: string): RbdModel {
-    const [poolName, namespace, rbdName] = this.rbdService.parseImageSpec(imageSpec);
-    return this.createRbdFromTask(poolName, namespace, rbdName);
+  private createRbdFromTaskImageSpec(imageSpecStr: string): RbdModel {
+    const imageSpec = ImageSpec.fromString(imageSpecStr);
+    return this.createRbdFromTask(imageSpec.poolName, imageSpec.namespace, imageSpec.imageName);
   }
 
   private createRbdFromTask(pool: string, namespace: string, name: string): RbdModel {
@@ -107,13 +108,11 @@ export class RbdListComponent implements OnInit {
     this.permission = this.authStorageService.getPermissions().rbdImage;
     const getImageUri = () =>
       this.selection.first() &&
-      `${encodeURIComponent(
-        this.rbdService.getImageSpec(
-          this.selection.first().pool_name,
-          this.selection.first().namespace,
-          this.selection.first().name
-        )
-      )}`;
+      new ImageSpec(
+        this.selection.first().pool_name,
+        this.selection.first().namespace,
+        this.selection.first().name
+      ).toStringEncoded();
     const addAction: CdTableAction = {
       permission: 'create',
       icon: Icons.add,
@@ -231,32 +230,32 @@ export class RbdListComponent implements OnInit {
       let taskImageSpec: string;
       switch (task.name) {
         case 'rbd/copy':
-          taskImageSpec = this.rbdService.getImageSpec(
+          taskImageSpec = new ImageSpec(
             task.metadata['dest_pool_name'],
             task.metadata['dest_namespace'],
             task.metadata['dest_image_name']
-          );
+          ).toString();
           break;
         case 'rbd/clone':
-          taskImageSpec = this.rbdService.getImageSpec(
+          taskImageSpec = new ImageSpec(
             task.metadata['child_pool_name'],
             task.metadata['child_namespace'],
             task.metadata['child_image_name']
-          );
+          ).toString();
           break;
         case 'rbd/create':
-          taskImageSpec = this.rbdService.getImageSpec(
+          taskImageSpec = new ImageSpec(
             task.metadata['pool_name'],
             task.metadata['namespace'],
             task.metadata['image_name']
-          );
+          ).toString();
           break;
         default:
           taskImageSpec = task.metadata['image_spec'];
           break;
       }
       return (
-        taskImageSpec === this.rbdService.getImageSpec(entry.pool_name, entry.namespace, entry.name)
+        taskImageSpec === new ImageSpec(entry.pool_name, entry.namespace, entry.name).toString()
       );
     };
 
@@ -321,7 +320,7 @@ export class RbdListComponent implements OnInit {
     const poolName = this.selection.first().pool_name;
     const namespace = this.selection.first().namespace;
     const imageName = this.selection.first().name;
-    const imageSpec = this.rbdService.getImageSpec(poolName, namespace, imageName);
+    const imageSpec = new ImageSpec(poolName, namespace, imageName);
 
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
       initialState: {
@@ -330,9 +329,9 @@ export class RbdListComponent implements OnInit {
         submitActionObservable: () =>
           this.taskWrapper.wrapTaskAroundCall({
             task: new FinishedTask('rbd/delete', {
-              image_spec: imageSpec
+              image_spec: imageSpec.toString()
             }),
-            call: this.rbdService.delete(poolName, namespace, imageName)
+            call: this.rbdService.delete(imageSpec)
           })
       }
     });
@@ -348,13 +347,13 @@ export class RbdListComponent implements OnInit {
     this.modalRef = this.modalService.show(RbdTrashMoveModalComponent, { initialState });
   }
 
-  flattenRbd(poolName, namespace, imageName) {
+  flattenRbd(imageSpec: ImageSpec) {
     this.taskWrapper
       .wrapTaskAroundCall({
         task: new FinishedTask('rbd/flatten', {
-          image_spec: this.rbdService.getImageSpec(poolName, namespace, imageName)
+          image_spec: imageSpec.toString()
         }),
-        call: this.rbdService.flatten(poolName, namespace, imageName)
+        call: this.rbdService.flatten(imageSpec)
       })
       .subscribe(undefined, undefined, () => {
         this.modalRef.hide();
@@ -366,11 +365,12 @@ export class RbdListComponent implements OnInit {
     const namespace = this.selection.first().namespace;
     const imageName = this.selection.first().name;
     const parent: RbdParentModel = this.selection.first().parent;
-    const parentImageSpec = this.rbdService.getImageSpec(
+    const parentImageSpec = new ImageSpec(
       parent.pool_name,
       parent.pool_namespace,
       parent.image_name
     );
+    const childImageSpec = new ImageSpec(poolName, namespace, imageName);
 
     const initialState = {
       titleText: 'RBD flatten',
@@ -378,10 +378,10 @@ export class RbdListComponent implements OnInit {
       bodyTpl: this.flattenTpl,
       bodyData: {
         parent: `${parentImageSpec}@${parent.snap_name}`,
-        child: this.rbdService.getImageSpec(poolName, namespace, imageName)
+        child: childImageSpec.toString()
       },
       onSubmit: () => {
-        this.flattenRbd(poolName, namespace, imageName);
+        this.flattenRbd(childImageSpec);
       }
     };
 
index 2cb712b6aebd23e75ca885fb80582c3ddf6d2d14..8b267a187390b749b25faa42130a67db0d0b4446 100644 (file)
@@ -9,6 +9,7 @@ import { RbdService } from '../../../shared/api/rbd.service';
 import { ActionLabelsI18n } from '../../../shared/constants/app.constants';
 import { CdFormGroup } from '../../../shared/forms/cd-form-group';
 import { FinishedTask } from '../../../shared/models/finished-task';
+import { ImageSpec } from '../../../shared/models/image-spec';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { TaskManagerService } from '../../../shared/services/task-manager.service';
 
@@ -73,14 +74,15 @@ export class RbdSnapshotFormComponent implements OnInit {
 
   editAction() {
     const snapshotName = this.snapshotForm.getValue('snapshotName');
+    const imageSpec = new ImageSpec(this.poolName, this.namespace, this.imageName);
     const finishedTask = new FinishedTask();
     finishedTask.name = 'rbd/snap/edit';
     finishedTask.metadata = {
-      image_spec: this.rbdService.getImageSpec(this.poolName, this.namespace, this.imageName),
+      image_spec: imageSpec.toString(),
       snapshot_name: snapshotName
     };
     this.rbdService
-      .renameSnapshot(this.poolName, this.namespace, this.imageName, this.snapName, snapshotName)
+      .renameSnapshot(imageSpec, this.snapName, snapshotName)
       .toPromise()
       .then(() => {
         this.taskManagerService.subscribe(
@@ -100,14 +102,15 @@ export class RbdSnapshotFormComponent implements OnInit {
 
   createAction() {
     const snapshotName = this.snapshotForm.getValue('snapshotName');
+    const imageSpec = new ImageSpec(this.poolName, this.namespace, this.imageName);
     const finishedTask = new FinishedTask();
     finishedTask.name = 'rbd/snap/create';
     finishedTask.metadata = {
-      image_spec: this.rbdService.getImageSpec(this.poolName, this.namespace, this.imageName),
+      image_spec: imageSpec.toString(),
       snapshot_name: snapshotName
     };
     this.rbdService
-      .createSnapshot(this.poolName, this.namespace, this.imageName, snapshotName)
+      .createSnapshot(imageSpec, snapshotName)
       .toPromise()
       .then(() => {
         this.taskManagerService.subscribe(
index 96a14ee2f6b253e868e360a192891ea12271c425..225354329cbe1e99a0aaada5052ce4c194a1c383 100644 (file)
@@ -15,6 +15,7 @@ import { CdTableColumn } from '../../../shared/models/cd-table-column';
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
 import { ExecutingTask } from '../../../shared/models/executing-task';
 import { FinishedTask } from '../../../shared/models/finished-task';
+import { ImageSpec } from '../../../shared/models/image-spec';
 import { Permission } from '../../../shared/models/permissions';
 import { CdDatePipe } from '../../../shared/pipes/cd-date.pipe';
 import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
@@ -124,6 +125,8 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
   }
 
   ngOnChanges() {
+    const imageSpec = new ImageSpec(this.poolName, this.namespace, this.rbdName);
+
     const actions = new RbdSnapshotActionsModel(this.i18n, this.actionLabels, this.featuresName);
     actions.create.click = () => this.openCreateSnapshotModal();
     actions.rename.click = () => this.openEditSnapshotModal();
@@ -131,9 +134,7 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
     actions.unprotect.click = () => this.toggleProtection();
     const getImageUri = () =>
       this.selection.first() &&
-      `${encodeURIComponent(
-        this.rbdService.getImageSpec(this.poolName, this.namespace, this.rbdName)
-      )}/${encodeURIComponent(this.selection.first().name)}`;
+      `${imageSpec.toStringEncoded()}/${encodeURIComponent(this.selection.first().name)}`;
     actions.clone.routerLink = () => `/block/rbd/clone/${getImageUri()}`;
     actions.copy.routerLink = () => `/block/rbd/copy/${getImageUri()}`;
     actions.rollback.click = () => this.rollbackModal();
@@ -148,9 +149,7 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
       return (
         ['rbd/snap/create', 'rbd/snap/delete', 'rbd/snap/edit', 'rbd/snap/rollback'].includes(
           task.name
-        ) &&
-        this.rbdService.getImageSpec(this.poolName, this.namespace, this.rbdName) ===
-          task.metadata['image_spec']
+        ) && imageSpec.toString() === task.metadata['image_spec']
       );
     };
 
@@ -204,12 +203,13 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
     const isProtected = this.selection.first().is_protected;
     const finishedTask = new FinishedTask();
     finishedTask.name = 'rbd/snap/edit';
+    const imageSpec = new ImageSpec(this.poolName, this.namespace, this.rbdName);
     finishedTask.metadata = {
-      image_spec: this.rbdService.getImageSpec(this.poolName, this.namespace, this.rbdName),
+      image_spec: imageSpec.toString(),
       snapshot_name: snapshotName
     };
     this.rbdService
-      .protectSnapshot(this.poolName, this.namespace, this.rbdName, snapshotName, !isProtected)
+      .protectSnapshot(imageSpec, snapshotName, !isProtected)
       .toPromise()
       .then(() => {
         const executingTask = new ExecutingTask();
@@ -231,7 +231,7 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
     const finishedTask = new FinishedTask();
     finishedTask.name = taskName;
     finishedTask.metadata = {
-      image_spec: this.rbdService.getImageSpec(this.poolName, this.namespace, this.rbdName),
+      image_spec: new ImageSpec(this.poolName, this.namespace, this.rbdName).toString(),
       snapshot_name: snapshotName
     };
     this.rbdService[task](this.poolName, this.namespace, this.rbdName, snapshotName)
@@ -258,7 +258,7 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
 
   rollbackModal() {
     const snapshotName = this.selection.selected[0].name;
-    const imageSpec = this.rbdService.getImageSpec(this.poolName, this.namespace, this.rbdName);
+    const imageSpec = new ImageSpec(this.poolName, this.namespace, this.rbdName).toString();
     const initialState = {
       titleText: this.i18n('RBD snapshot rollback'),
       buttonText: this.i18n('Rollback'),
index 7f3d9ea705c93384020f1d3e61d3185715866a96..811a2145d498cdea1dfd0ef5ab933f2fa6496e90 100644 (file)
@@ -17,6 +17,7 @@ import { CdTableColumn } from '../../../shared/models/cd-table-column';
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
 import { ExecutingTask } from '../../../shared/models/executing-task';
 import { FinishedTask } from '../../../shared/models/finished-task';
+import { ImageSpec } from '../../../shared/models/image-spec';
 import { Permission } from '../../../shared/models/permissions';
 import { CdDatePipe } from '../../../shared/pipes/cd-date.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
@@ -115,10 +116,8 @@ export class RbdTrashListComponent implements OnInit {
     ];
 
     const itemFilter = (entry, task) => {
-      return (
-        this.rbdService.getImageSpec(entry.pool_name, entry.namespace, entry.id) ===
-        task.metadata['image_id_spec']
-      );
+      const imageSpec = new ImageSpec(entry.pool_name, entry.namespace, entry.id);
+      return imageSpec.toString() === task.metadata['image_id_spec'];
     };
 
     const taskFilter = (task) => {
@@ -191,7 +190,7 @@ export class RbdTrashListComponent implements OnInit {
     const namespace = this.selection.first().namespace;
     const imageId = this.selection.first().id;
     const expiresAt = this.selection.first().deferment_end_time;
-    const imageIdSpec = this.rbdService.getImageSpec(poolName, namespace, imageId);
+    const imageIdSpec = new ImageSpec(poolName, namespace, imageId);
 
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
       initialState: {
@@ -202,9 +201,9 @@ export class RbdTrashListComponent implements OnInit {
         submitActionObservable: () =>
           this.taskWrapper.wrapTaskAroundCall({
             task: new FinishedTask('rbd/trash/remove', {
-              image_id_spec: imageIdSpec
+              image_id_spec: imageIdSpec.toString()
             }),
-            call: this.rbdService.removeTrash(poolName, namespace, imageId, true)
+            call: this.rbdService.removeTrash(imageIdSpec, true)
           })
       }
     });
index 06d913bc3c64b91a8c373be96d33d029e22235a0..63386ae0b47367cc61f331f669d335c3c594853e 100644 (file)
@@ -9,7 +9,7 @@
           [formGroup]="moveForm"
           novalidate>
       <div class="modal-body">
-        <p i18n>To move <kbd>{{ imageSpec }}</kbd> to trash,
+        <p i18n>To move <kbd>{{ imageSpecStr }}</kbd> to trash,
           click <kbd>Move Image</kbd>. Optionally, you can pick an expiration date.</p>
 
         <div class="form-group">
index bf90ee7c8e4d040dd523b23a1bbca2fd9386d0b3..6f6a2ced65117729aab775bd0c94b7140694a4f9 100644 (file)
@@ -39,6 +39,8 @@ describe('RbdTrashMoveModalComponent', () => {
     component.metaType = 'RBD';
     component.poolName = 'foo';
     component.imageName = 'bar';
+
+    fixture.detectChanges();
   });
 
   it('should create', () => {
@@ -47,7 +49,6 @@ describe('RbdTrashMoveModalComponent', () => {
   });
 
   it('should finish running ngOnInit', () => {
-    fixture.detectChanges();
     expect(component.pattern).toEqual('foo/bar');
   });
 
@@ -88,7 +89,6 @@ describe('RbdTrashMoveModalComponent', () => {
       const oldDate = moment()
         .add(24, 'hour')
         .toISOString();
-      fixture.detectChanges();
       component.moveForm.patchValue({ expiresAt: oldDate });
 
       component.moveImage();
index 14a7543fbdcfe8476a3cefc9c5a69b6c32965cc3..53913a93b9606424bd0d2106b47135891d9440cb 100644 (file)
@@ -9,6 +9,7 @@ import { CdFormGroup } from '../../../shared/forms/cd-form-group';
 import { CdValidators } from '../../../shared/forms/cd-validators';
 import { ExecutingTask } from '../../../shared/models/executing-task';
 import { FinishedTask } from '../../../shared/models/finished-task';
+import { ImageSpec } from '../../../shared/models/image-spec';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
 
 @Component({
@@ -21,7 +22,8 @@ export class RbdTrashMoveModalComponent implements OnInit {
   poolName: string;
   namespace: string;
   imageName: string;
-  imageSpec: string;
+  imageSpec: ImageSpec;
+  imageSpecStr: string;
   executingTasks: ExecutingTask[];
 
   moveForm: CdFormGroup;
@@ -60,7 +62,8 @@ export class RbdTrashMoveModalComponent implements OnInit {
   }
 
   ngOnInit() {
-    this.imageSpec = this.rbdService.getImageSpec(this.poolName, this.namespace, this.imageName);
+    this.imageSpec = new ImageSpec(this.poolName, this.namespace, this.imageName);
+    this.imageSpecStr = this.imageSpec.toString();
     this.pattern = `${this.poolName}/${this.imageName}`;
   }
 
@@ -79,9 +82,9 @@ export class RbdTrashMoveModalComponent implements OnInit {
     this.taskWrapper
       .wrapTaskAroundCall({
         task: new FinishedTask('rbd/trash/move', {
-          image_spec: this.imageSpec
+          image_spec: this.imageSpecStr
         }),
-        call: this.rbdService.moveTrash(this.poolName, this.namespace, this.imageName, delay)
+        call: this.rbdService.moveTrash(this.imageSpec, delay)
       })
       .subscribe(undefined, undefined, () => {
         this.modalRef.hide();
index b45ef7bf8fe3dcf5ec98d087c7631d4bdc3bd492..40750922c34e9f2dc862e405bac296ae31f236f3 100644 (file)
@@ -7,6 +7,7 @@ import { CdFormBuilder } from '../../../shared/forms/cd-form-builder';
 import { CdFormGroup } from '../../../shared/forms/cd-form-group';
 import { ExecutingTask } from '../../../shared/models/executing-task';
 import { FinishedTask } from '../../../shared/models/finished-task';
+import { ImageSpec } from '../../../shared/models/image-spec';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
 
 @Component({
@@ -33,7 +34,7 @@ export class RbdTrashRestoreModalComponent implements OnInit {
   ) {}
 
   ngOnInit() {
-    this.imageSpec = this.rbdService.getImageSpec(this.poolName, this.namespace, this.imageName);
+    this.imageSpec = new ImageSpec(this.poolName, this.namespace, this.imageName).toString();
     this.restoreForm = this.fb.group({
       name: this.imageName
     });
@@ -41,14 +42,15 @@ export class RbdTrashRestoreModalComponent implements OnInit {
 
   restore() {
     const name = this.restoreForm.getValue('name');
+    const imageSpec = new ImageSpec(this.poolName, this.namespace, this.imageId);
 
     this.taskWrapper
       .wrapTaskAroundCall({
         task: new FinishedTask('rbd/trash/restore', {
-          image_id_spec: this.rbdService.getImageSpec(this.poolName, this.namespace, this.imageId),
+          image_id_spec: imageSpec.toString(),
           new_image_name: name
         }),
-        call: this.rbdService.restoreTrash(this.poolName, this.namespace, this.imageId, name)
+        call: this.rbdService.restoreTrash(imageSpec, name)
       })
       .subscribe(
         undefined,
index e636495bbd292e8e2f0359a4ceaed326d729fbcd..c688e0f3f421a33ea2ea7edf53a5efd91040bcad 100644 (file)
@@ -2,6 +2,7 @@ import { HttpClientTestingModule, HttpTestingController } from '@angular/common/
 import { TestBed } from '@angular/core/testing';
 
 import { configureTestBed, i18nProviders } from '../../../testing/unit-test-helper';
+import { ImageSpec } from '../models/image-spec';
 import { RbdConfigurationService } from '../services/rbd-configuration.service';
 import { RbdService } from './rbd.service';
 
@@ -35,20 +36,20 @@ describe('RbdService', () => {
   });
 
   it('should call delete', () => {
-    service.delete('poolName', null, 'rbdName').subscribe();
+    service.delete(new ImageSpec('poolName', null, 'rbdName')).subscribe();
     const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName');
     expect(req.request.method).toBe('DELETE');
   });
 
   it('should call update', () => {
-    service.update('poolName', null, 'rbdName', 'foo').subscribe();
+    service.update(new ImageSpec('poolName', null, 'rbdName'), 'foo').subscribe();
     const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName');
     expect(req.request.body).toEqual('foo');
     expect(req.request.method).toBe('PUT');
   });
 
   it('should call get', () => {
-    service.get('poolName', null, 'rbdName').subscribe();
+    service.get(new ImageSpec('poolName', null, 'rbdName')).subscribe();
     const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName');
     expect(req.request.method).toBe('GET');
   });
@@ -60,14 +61,14 @@ describe('RbdService', () => {
   });
 
   it('should call copy', () => {
-    service.copy('poolName', null, 'rbdName', 'foo').subscribe();
+    service.copy(new ImageSpec('poolName', null, 'rbdName'), 'foo').subscribe();
     const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/copy');
     expect(req.request.body).toEqual('foo');
     expect(req.request.method).toBe('POST');
   });
 
   it('should call flatten', () => {
-    service.flatten('poolName', null, 'rbdName').subscribe();
+    service.flatten(new ImageSpec('poolName', null, 'rbdName')).subscribe();
     const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/flatten');
     expect(req.request.body).toEqual(null);
     expect(req.request.method).toBe('POST');
@@ -80,7 +81,7 @@ describe('RbdService', () => {
   });
 
   it('should call createSnapshot', () => {
-    service.createSnapshot('poolName', null, 'rbdName', 'snapshotName').subscribe();
+    service.createSnapshot(new ImageSpec('poolName', null, 'rbdName'), 'snapshotName').subscribe();
     const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/snap');
     expect(req.request.body).toEqual({
       snapshot_name: 'snapshotName'
@@ -89,7 +90,9 @@ describe('RbdService', () => {
   });
 
   it('should call renameSnapshot', () => {
-    service.renameSnapshot('poolName', null, 'rbdName', 'snapshotName', 'foo').subscribe();
+    service
+      .renameSnapshot(new ImageSpec('poolName', null, 'rbdName'), 'snapshotName', 'foo')
+      .subscribe();
     const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/snap/snapshotName');
     expect(req.request.body).toEqual({
       new_snap_name: 'foo'
@@ -98,7 +101,9 @@ describe('RbdService', () => {
   });
 
   it('should call protectSnapshot', () => {
-    service.protectSnapshot('poolName', null, 'rbdName', 'snapshotName', true).subscribe();
+    service
+      .protectSnapshot(new ImageSpec('poolName', null, 'rbdName'), 'snapshotName', true)
+      .subscribe();
     const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/snap/snapshotName');
     expect(req.request.body).toEqual({
       is_protected: true
@@ -107,7 +112,9 @@ describe('RbdService', () => {
   });
 
   it('should call rollbackSnapshot', () => {
-    service.rollbackSnapshot('poolName', null, 'rbdName', 'snapshotName').subscribe();
+    service
+      .rollbackSnapshot(new ImageSpec('poolName', null, 'rbdName'), 'snapshotName')
+      .subscribe();
     const req = httpTesting.expectOne(
       'api/block/image/poolName%2FrbdName/snap/snapshotName/rollback'
     );
@@ -116,20 +123,22 @@ describe('RbdService', () => {
   });
 
   it('should call cloneSnapshot', () => {
-    service.cloneSnapshot('poolName', null, 'rbdName', 'snapshotName', null).subscribe();
+    service
+      .cloneSnapshot(new ImageSpec('poolName', null, 'rbdName'), 'snapshotName', null)
+      .subscribe();
     const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/snap/snapshotName/clone');
     expect(req.request.body).toEqual(null);
     expect(req.request.method).toBe('POST');
   });
 
   it('should call deleteSnapshot', () => {
-    service.deleteSnapshot('poolName', null, 'rbdName', 'snapshotName').subscribe();
+    service.deleteSnapshot(new ImageSpec('poolName', null, 'rbdName'), 'snapshotName').subscribe();
     const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/snap/snapshotName');
     expect(req.request.method).toBe('DELETE');
   });
 
   it('should call moveTrash', () => {
-    service.moveTrash('poolName', null, 'rbdName', 1).subscribe();
+    service.moveTrash(new ImageSpec('poolName', null, 'rbdName'), 1).subscribe();
     const req = httpTesting.expectOne('api/block/image/poolName%2FrbdName/move_trash');
     expect(req.request.method).toBe('POST');
     expect(req.request.body).toEqual({ delay: 1 });
@@ -137,27 +146,27 @@ describe('RbdService', () => {
 
   describe('should compose image spec', () => {
     it('with namespace', () => {
-      expect(service.getImageSpec('mypool', 'myns', 'myimage')).toBe('mypool/myns/myimage');
+      expect(new ImageSpec('mypool', 'myns', 'myimage').toString()).toBe('mypool/myns/myimage');
     });
 
     it('without namespace', () => {
-      expect(service.getImageSpec('mypool', null, 'myimage')).toBe('mypool/myimage');
+      expect(new ImageSpec('mypool', null, 'myimage').toString()).toBe('mypool/myimage');
     });
   });
 
   describe('should parse image spec', () => {
     it('with namespace', () => {
-      const [poolName, namespace, rbdName] = service.parseImageSpec('mypool/myns/myimage');
-      expect(poolName).toBe('mypool');
-      expect(namespace).toBe('myns');
-      expect(rbdName).toBe('myimage');
+      const imageSpec = ImageSpec.fromString('mypool/myns/myimage');
+      expect(imageSpec.poolName).toBe('mypool');
+      expect(imageSpec.namespace).toBe('myns');
+      expect(imageSpec.imageName).toBe('myimage');
     });
 
     it('without namespace', () => {
-      const [poolName, namespace, rbdName] = service.parseImageSpec('mypool/myimage');
-      expect(poolName).toBe('mypool');
-      expect(namespace).toBeNull();
-      expect(rbdName).toBe('myimage');
+      const imageSpec = ImageSpec.fromString('mypool/myimage');
+      expect(imageSpec.poolName).toBe('mypool');
+      expect(imageSpec.namespace).toBeNull();
+      expect(imageSpec.imageName).toBe('myimage');
     });
   });
 });
index aa2dfd764ed9f9090b4317a57753eef9c0687016..fb2497a8395a6427d694e9f1557e1ad2f2c89efa 100644 (file)
@@ -5,6 +5,7 @@ import * as _ from 'lodash';
 import { map } from 'rxjs/operators';
 
 import { cdEncode, cdEncodeNot } from '../decorators/cd-encode';
+import { ImageSpec } from '../models/image-spec';
 import { RbdConfigurationService } from '../services/rbd-configuration.service';
 import { ApiModule } from './api.module';
 import { RbdPool } from './rbd.model';
@@ -16,19 +17,6 @@ import { RbdPool } from './rbd.model';
 export class RbdService {
   constructor(private http: HttpClient, private rbdConfigurationService: RbdConfigurationService) {}
 
-  getImageSpec(poolName: string, namespace: string, rbdName: string) {
-    namespace = namespace ? `${namespace}/` : '';
-    return `${poolName}/${namespace}${rbdName}`;
-  }
-
-  parseImageSpec(@cdEncodeNot imageSpec: string) {
-    const imageSpecSplited = imageSpec.split('/');
-    const poolName = imageSpecSplited[0];
-    const namespace = imageSpecSplited.length >= 3 ? imageSpecSplited[1] : null;
-    const imageName = imageSpecSplited.length >= 3 ? imageSpecSplited[2] : imageSpecSplited[1];
-    return [poolName, namespace, imageName];
-  }
-
   isRBDPool(pool) {
     return _.indexOf(pool.application_metadata, 'rbd') !== -1 && !pool.pool_name.includes('/');
   }
@@ -37,23 +25,20 @@ export class RbdService {
     return this.http.post('api/block/image', rbd, { observe: 'response' });
   }
 
-  delete(poolName, namespace, rbdName) {
-    const imageSpec = this.getImageSpec(poolName, namespace, rbdName);
-    return this.http.delete(`api/block/image/${encodeURIComponent(imageSpec)}`, {
+  delete(imageSpec: ImageSpec) {
+    return this.http.delete(`api/block/image/${imageSpec.toStringEncoded()}`, {
       observe: 'response'
     });
   }
 
-  update(poolName, namespace, rbdName, rbd) {
-    const imageSpec = this.getImageSpec(poolName, namespace, rbdName);
-    return this.http.put(`api/block/image/${encodeURIComponent(imageSpec)}`, rbd, {
+  update(imageSpec: ImageSpec, rbd) {
+    return this.http.put(`api/block/image/${imageSpec.toStringEncoded()}`, rbd, {
       observe: 'response'
     });
   }
 
-  get(poolName, namespace, rbdName) {
-    const imageSpec = this.getImageSpec(poolName, namespace, rbdName);
-    return this.http.get(`api/block/image/${encodeURIComponent(imageSpec)}`);
+  get(imageSpec: ImageSpec) {
+    return this.http.get(`api/block/image/${imageSpec.toStringEncoded()}`);
   }
 
   list() {
@@ -75,16 +60,14 @@ export class RbdService {
     );
   }
 
-  copy(poolName, namespace, rbdName, rbd) {
-    const imageSpec = this.getImageSpec(poolName, namespace, rbdName);
-    return this.http.post(`api/block/image/${encodeURIComponent(imageSpec)}/copy`, rbd, {
+  copy(imageSpec: ImageSpec, rbd) {
+    return this.http.post(`api/block/image/${imageSpec.toStringEncoded()}/copy`, rbd, {
       observe: 'response'
     });
   }
 
-  flatten(poolName, namespace, rbdName) {
-    const imageSpec = this.getImageSpec(poolName, namespace, rbdName);
-    return this.http.post(`api/block/image/${encodeURIComponent(imageSpec)}/flatten`, null, {
+  flatten(imageSpec: ImageSpec) {
+    return this.http.post(`api/block/image/${imageSpec.toStringEncoded()}/flatten`, null, {
       observe: 'response'
     });
   }
@@ -93,23 +76,21 @@ export class RbdService {
     return this.http.get('api/block/image/default_features');
   }
 
-  createSnapshot(poolName, namespace, rbdName, @cdEncodeNot snapshotName) {
-    const imageSpec = this.getImageSpec(poolName, namespace, rbdName);
+  createSnapshot(imageSpec: ImageSpec, @cdEncodeNot snapshotName) {
     const request = {
       snapshot_name: snapshotName
     };
-    return this.http.post(`api/block/image/${encodeURIComponent(imageSpec)}/snap`, request, {
+    return this.http.post(`api/block/image/${imageSpec.toStringEncoded()}/snap`, request, {
       observe: 'response'
     });
   }
 
-  renameSnapshot(poolName, namespace, rbdName, snapshotName, @cdEncodeNot newSnapshotName) {
-    const imageSpec = this.getImageSpec(poolName, namespace, rbdName);
+  renameSnapshot(imageSpec: ImageSpec, snapshotName, @cdEncodeNot newSnapshotName) {
     const request = {
       new_snap_name: newSnapshotName
     };
     return this.http.put(
-      `api/block/image/${encodeURIComponent(imageSpec)}/snap/${snapshotName}`,
+      `api/block/image/${imageSpec.toStringEncoded()}/snap/${snapshotName}`,
       request,
       {
         observe: 'response'
@@ -117,13 +98,12 @@ export class RbdService {
     );
   }
 
-  protectSnapshot(poolName, namespace, rbdName, snapshotName, @cdEncodeNot isProtected) {
-    const imageSpec = this.getImageSpec(poolName, namespace, rbdName);
+  protectSnapshot(imageSpec: ImageSpec, snapshotName, @cdEncodeNot isProtected) {
     const request = {
       is_protected: isProtected
     };
     return this.http.put(
-      `api/block/image/${encodeURIComponent(imageSpec)}/snap/${snapshotName}`,
+      `api/block/image/${imageSpec.toStringEncoded()}/snap/${snapshotName}`,
       request,
       {
         observe: 'response'
@@ -131,32 +111,26 @@ export class RbdService {
     );
   }
 
-  rollbackSnapshot(poolName, namespace, rbdName, snapshotName) {
-    const imageSpec = this.getImageSpec(poolName, namespace, rbdName);
+  rollbackSnapshot(imageSpec: ImageSpec, snapshotName) {
     return this.http.post(
-      `api/block/image/${encodeURIComponent(imageSpec)}/snap/${snapshotName}/rollback`,
+      `api/block/image/${imageSpec.toStringEncoded()}/snap/${snapshotName}/rollback`,
       null,
       { observe: 'response' }
     );
   }
 
-  cloneSnapshot(poolName, namespace, rbdName, snapshotName, request) {
-    const imageSpec = this.getImageSpec(poolName, namespace, rbdName);
+  cloneSnapshot(imageSpec: ImageSpec, snapshotName, request) {
     return this.http.post(
-      `api/block/image/${encodeURIComponent(imageSpec)}/snap/${snapshotName}/clone`,
+      `api/block/image/${imageSpec.toStringEncoded()}/snap/${snapshotName}/clone`,
       request,
       { observe: 'response' }
     );
   }
 
-  deleteSnapshot(poolName, namespace, rbdName, snapshotName) {
-    const imageSpec = this.getImageSpec(poolName, namespace, rbdName);
-    return this.http.delete(
-      `api/block/image/${encodeURIComponent(imageSpec)}/snap/${snapshotName}`,
-      {
-        observe: 'response'
-      }
-    );
+  deleteSnapshot(imageSpec: ImageSpec, snapshotName) {
+    return this.http.delete(`api/block/image/${imageSpec.toStringEncoded()}/snap/${snapshotName}`, {
+      observe: 'response'
+    });
   }
 
   listTrash() {
@@ -180,10 +154,9 @@ export class RbdService {
     });
   }
 
-  moveTrash(poolName, namespace, rbdName, delay) {
-    const imageSpec = this.getImageSpec(poolName, namespace, rbdName);
+  moveTrash(imageSpec: ImageSpec, delay) {
     return this.http.post(
-      `api/block/image/${encodeURIComponent(imageSpec)}/move_trash`,
+      `api/block/image/${imageSpec.toStringEncoded()}/move_trash`,
       { delay: delay },
       { observe: 'response' }
     );
@@ -195,19 +168,17 @@ export class RbdService {
     });
   }
 
-  restoreTrash(poolName, namespace, imageId, @cdEncodeNot newImageName) {
-    const imageSpec = this.getImageSpec(poolName, namespace, imageId);
+  restoreTrash(imageSpec: ImageSpec, @cdEncodeNot newImageName: string) {
     return this.http.post(
-      `api/block/image/trash/${encodeURIComponent(imageSpec)}/restore`,
+      `api/block/image/trash/${imageSpec.toStringEncoded()}/restore`,
       { new_image_name: newImageName },
       { observe: 'response' }
     );
   }
 
-  removeTrash(poolName, namespace, imageId, force = false) {
-    const imageSpec = this.getImageSpec(poolName, namespace, imageId);
+  removeTrash(imageSpec: ImageSpec, force = false) {
     return this.http.delete(
-      `api/block/image/trash/${encodeURIComponent(imageSpec)}/?force=${force}`,
+      `api/block/image/trash/${imageSpec.toStringEncoded()}/?force=${force}`,
       { observe: 'response' }
     );
   }
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/image-spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/image-spec.ts
new file mode 100644 (file)
index 0000000..8b56b29
--- /dev/null
@@ -0,0 +1,25 @@
+export class ImageSpec {
+  static fromString(imageSpec: string) {
+    const imageSpecSplited = imageSpec.split('/');
+
+    const poolName = imageSpecSplited[0];
+    const namespace = imageSpecSplited.length >= 3 ? imageSpecSplited[1] : null;
+    const imageName = imageSpecSplited.length >= 3 ? imageSpecSplited[2] : imageSpecSplited[1];
+
+    return new this(poolName, namespace, imageName);
+  }
+
+  constructor(public poolName: string, public namespace: string, public imageName: string) {}
+
+  private getNameSpace() {
+    return this.namespace ? `${this.namespace}/` : '';
+  }
+
+  toString() {
+    return `${this.poolName}/${this.getNameSpace()}${this.imageName}`;
+  }
+
+  toStringEncoded() {
+    return encodeURIComponent(`${this.poolName}/${this.getNameSpace()}${this.imageName}`);
+  }
+}
index 9aa7073496f3ee0fbfa09a188fd1fc213a8a0339..c4ce8834cda20ab1b08e107c55b0bab4794e5009 100644 (file)
@@ -2,9 +2,9 @@ import { Injectable } from '@angular/core';
 
 import { I18n } from '@ngx-translate/i18n-polyfill';
 
-import { RbdService } from '../api/rbd.service';
 import { Components } from '../enum/components.enum';
 import { FinishedTask } from '../models/finished-task';
+import { ImageSpec } from '../models/image-spec';
 import { Task } from '../models/task';
 
 export class TaskMessageOperation {
@@ -58,7 +58,7 @@ class TaskMessage {
   providedIn: 'root'
 })
 export class TaskMessageService {
-  constructor(private i18n: I18n, private rbdService: RbdService) {}
+  constructor(private i18n: I18n) {}
 
   defaultMessage = this.newTaskMessage(
     new TaskMessageOperation(this.i18n('Executing'), this.i18n('execute'), this.i18n('Executed')),
@@ -103,31 +103,31 @@ export class TaskMessageService {
         id: `${metadata.image_spec}`
       }),
     create: (metadata) => {
-      const id = this.rbdService.getImageSpec(
+      const id = new ImageSpec(
         metadata.pool_name,
         metadata.namespace,
         metadata.image_name
-      );
+      ).toString();
       return this.i18n(`RBD '{{id}}'`, {
         id: id
       });
     },
     child: (metadata) => {
-      const id = this.rbdService.getImageSpec(
+      const id = new ImageSpec(
         metadata.child_pool_name,
         metadata.child_namespace,
         metadata.child_image_name
-      );
+      ).toString();
       return this.i18n(`RBD '{{id}}'`, {
         id: id
       });
     },
     destination: (metadata) => {
-      const id = this.rbdService.getImageSpec(
+      const id = new ImageSpec(
         metadata.dest_pool_name,
         metadata.dest_namespace,
         metadata.dest_image_name
-      );
+      ).toString();
       return this.i18n(`RBD '{{id}}'`, {
         id: id
       });