]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: add smb share delete action 61353/head
authorPedro Gonzalez Gomez <pegonzal@redhat.com>
Mon, 13 Jan 2025 19:28:33 +0000 (20:28 +0100)
committerPedro Gonzalez Gomez <pegonzal@redhat.com>
Wed, 19 Feb 2025 19:13:08 +0000 (20:13 +0100)
Fixes: https://tracker.ceph.com/issues/69521
Signed-off-by: Pedro Gonzalez Gomez <pegonzal@redhat.com>
src/pybind/mgr/dashboard/frontend/src/app/ceph/smb/smb-cluster-list/smb-cluster-list.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/smb/smb-share-list/smb-share-list.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/smb/smb-share-list/smb-share-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/smb/smb-share-list/smb-share-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/api/smb.service.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/api/smb.service.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.ts

index 73e7deb2fac8398bf60fb12639fa964e6f1fdde6..269152a257ee6fb67eb882c10136461ad7d16c2e 100644 (file)
@@ -18,7 +18,6 @@
       >
       </cd-table-actions>
     </div>
-  >
     <cd-smb-cluster-tabs
       *cdTableDetail
       [selection]="expandedRow">
index 010b510f3ee4e9460e0ba49d4f5ce6abed6384c4..cc41f447ead59e462c306d35405c01e548e76ede 100644 (file)
@@ -6,6 +6,7 @@
     selectionType="single"
     [hasDetails]="false"
     (fetchData)="loadSMBShares()"
+    (updateSelection)="updateSelection($event)"
   >
     <div class="table-actions">
       <cd-table-actions
index 933a874816491ade422877b13a81f601e416bec6..9822fe2ed92856f4304c789636193bf053690744 100644 (file)
@@ -1,7 +1,10 @@
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { SmbShareListComponent } from './smb-share-list.component';
-import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { provideHttpClientTesting } from '@angular/common/http/testing';
+import { provideHttpClient } from '@angular/common/http';
+import { ToastrModule } from 'ngx-toastr';
+import { SharedModule } from '~/app/shared/shared.module';
 
 describe('SmbShareListComponent', () => {
   let component: SmbShareListComponent;
@@ -9,8 +12,9 @@ describe('SmbShareListComponent', () => {
 
   beforeEach(async () => {
     await TestBed.configureTestingModule({
-      imports: [HttpClientTestingModule],
-      declarations: [SmbShareListComponent]
+      imports: [ToastrModule.forRoot(), SharedModule],
+      declarations: [SmbShareListComponent],
+      providers: [provideHttpClient(), provideHttpClientTesting()]
     }).compileComponents();
 
     fixture = TestBed.createComponent(SmbShareListComponent);
index d352533a423a8b63ae179842a42fcb1a6f590e49..9b9aa86204a1eb7854e9ee84d9bc098ccec0c8c0 100644 (file)
@@ -13,6 +13,11 @@ import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
 import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
 import { Icons } from '~/app/shared/enum/icons.enum';
+import { DeleteConfirmationModalComponent } from '~/app/shared/components/delete-confirmation-modal/delete-confirmation-modal.component';
+import { FinishedTask } from '~/app/shared/models/finished-task';
+import { ModalCdsService } from '~/app/shared/services/modal-cds.service';
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
 
 @Component({
   selector: 'cd-smb-share-list',
@@ -32,11 +37,14 @@ export class SmbShareListComponent implements OnInit {
 
   smbShares$: Observable<SMBShare[]>;
   subject$ = new BehaviorSubject<SMBShare[]>([]);
+  modalRef: NgbModalRef;
 
   constructor(
     private authStorageService: AuthStorageService,
     public actionLabels: ActionLabelsI18n,
-    private smbService: SmbService
+    private smbService: SmbService,
+    private taskWrapper: TaskWrapperService,
+    private modalService: ModalCdsService
   ) {
     this.permission = this.authStorageService.getPermissions().smb;
   }
@@ -87,6 +95,12 @@ export class SmbShareListComponent implements OnInit {
         icon: Icons.add,
         routerLink: () => ['/cephfs/smb/share/create', this.clusterId],
         canBePrimary: (selection: CdTableSelection) => !selection.hasSingleSelection
+      },
+      {
+        permission: 'delete',
+        icon: Icons.destroy,
+        click: () => this.deleteShareModal(),
+        name: this.actionLabels.DELETE
       }
     ];
 
@@ -105,4 +119,26 @@ export class SmbShareListComponent implements OnInit {
   loadSMBShares() {
     this.subject$.next([]);
   }
+
+  updateSelection(selection: CdTableSelection) {
+    this.selection = selection;
+  }
+
+  deleteShareModal() {
+    const cluster_id = this.selection.first().cluster_id;
+    const share_id = this.selection.first().share_id;
+    const name = this.selection.first().name;
+
+    this.modalRef = this.modalService.show(DeleteConfirmationModalComponent, {
+      itemDescription: $localize`SMB Share`,
+      itemNames: [`Share: ${share_id} (${name}) from cluster: ${cluster_id}`],
+      submitActionObservable: () =>
+        this.taskWrapper.wrapTaskAroundCall({
+          task: new FinishedTask('smb/share/delete', {
+            share_id: share_id
+          }),
+          call: this.smbService.deleteShare(cluster_id, share_id)
+        })
+    });
+  }
 }
index 014d614dda8bfa306991ac7b0384b1b71a21ebda..34f1156a72fb5015f38f3721dc9cbfaf9cef461e 100644 (file)
@@ -101,4 +101,14 @@ describe('SmbService', () => {
     const req = httpTesting.expectOne('api/smb/share');
     expect(req.request.method).toBe('POST');
   });
+
+  it('should call delete for given share of a cluster', () => {
+    const cluster_id = 'foo';
+    const share_id = 'bar';
+    service.deleteShare(cluster_id, share_id).subscribe((response: null) => {
+      expect(response).toBeUndefined();
+    });
+    const req = httpTesting.expectOne(`api/smb/share/${cluster_id}/${share_id}`);
+    expect(req.request.method).toBe('DELETE');
+  });
 });
index ae6ef3303237c86755b763d99d133d667f41d664..c719519c12d74766ddd5dfa03963471d52337655 100644 (file)
@@ -1,4 +1,4 @@
-import { HttpClient } from '@angular/common/http';
+import { HttpClient, HttpResponse } from '@angular/common/http';
 import { Injectable } from '@angular/core';
 import { Observable, Subject } from 'rxjs';
 
@@ -55,4 +55,10 @@ export class SmbService {
   createShare(requestModel: ShareRequestModel) {
     return this.http.post(`${this.baseURL}/share`, requestModel);
   }
+
+  deleteShare(clusterId: string, shareId: string): Observable<HttpResponse<null>> {
+    return this.http.delete<null>(`${this.baseURL}/share/${clusterId}/${shareId}`, {
+      observe: 'response'
+    });
+  }
 }
index 05f7c460712ab98647c8bab350e42a62ba790f6d..a943abe0febe4a7e7f29f46991225d80768c0b17 100644 (file)
@@ -498,6 +498,9 @@ export class TaskMessageService {
     ),
     'smb/share/create': this.newTaskMessage(this.commonOperations.create, (metadata) =>
       this.smbShare(metadata)
+    ),
+    'smb/share/delete': this.newTaskMessage(this.commonOperations.delete, (metadata) =>
+      this.smbShare(metadata)
     )
   };
 
@@ -565,10 +568,6 @@ export class TaskMessageService {
     return $localize`SMB Cluster  '${metadata.cluster_id}'`;
   }
 
-  smbShare(metadata: { share_id: string }) {
-    return $localize`SMB Share  '${metadata.share_id}'`;
-  }
-
   service(metadata: any) {
     return $localize`service '${metadata.service_name}'`;
   }
@@ -611,6 +610,11 @@ export class TaskMessageService {
   snapshotSchedule(metadata: any) {
     return $localize`snapshot schedule for path '${metadata?.path}'`;
   }
+
+  smbShare(metadata: Record<'share_id', string>) {
+    return $localize`SMB share '${metadata?.share_id}'`;
+  }
+
   crudMessageId(id: string) {
     return $localize`${id}`;
   }