diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts
index b9c97d6badf..36606c6f302 100644
--- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts
@@ -19,6 +19,7 @@ import { RbdSnapshotFormComponent } from './rbd-snapshot-form/rbd-snapshot-form.
 import { RbdSnapshotListComponent } from './rbd-snapshot-list/rbd-snapshot-list.component';
 import { RbdTrashListComponent } from './rbd-trash-list/rbd-trash-list.component';
 import { RbdTrashMoveModalComponent } from './rbd-trash-move-modal/rbd-trash-move-modal.component';
+import { RbdTrashPurgeModalComponent } from './rbd-trash-purge-modal/rbd-trash-purge-modal.component';
 import { RbdTrashRestoreModalComponent } from './rbd-trash-restore-modal/rbd-trash-restore-modal.component';
 
 @NgModule({
@@ -26,7 +27,8 @@ import { RbdTrashRestoreModalComponent } from './rbd-trash-restore-modal/rbd-tra
     RbdDetailsComponent,
     RbdSnapshotFormComponent,
     RbdTrashMoveModalComponent,
-    RbdTrashRestoreModalComponent
+    RbdTrashRestoreModalComponent,
+    RbdTrashPurgeModalComponent
   ],
   imports: [
     CommonModule,
@@ -53,7 +55,8 @@ import { RbdTrashRestoreModalComponent } from './rbd-trash-restore-modal/rbd-tra
     RbdTrashListComponent,
     RbdTrashMoveModalComponent,
     RbdImagesComponent,
-    RbdTrashRestoreModalComponent
+    RbdTrashRestoreModalComponent,
+    RbdTrashPurgeModalComponent
   ]
 })
 export class BlockModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html
index e033ab841ff..a16ece60f8b 100644
--- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html
@@ -15,6 +15,14 @@
                       [selection]="selection"
                       [tableActions]="tableActions">
     </cd-table-actions>
+
+    <button class="btn btn-sm btn-default btn-label"
+            type="button"
+            (click)="purgeModal()">
+      <i class="fa fa-fw fa-times"
+         aria-hidden="true"></i>
+      <ng-container i18n>Purge Trash</ng-container>
+    </button>
   </div>
 </cd-table>
 
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts
index 6f0f6437c6f..6a505b3f6bd 100644
--- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts
@@ -19,6 +19,7 @@ import { CdDatePipe } from '../../../shared/pipes/cd-date.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
 import { TaskListService } from '../../../shared/services/task-list.service';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
+import { RbdTrashPurgeModalComponent } from '../rbd-trash-purge-modal/rbd-trash-purge-modal.component';
 import { RbdTrashRestoreModalComponent } from '../rbd-trash-restore-modal/rbd-trash-restore-modal.component';
 
 @Component({
@@ -197,4 +198,8 @@ export class RbdTrashListComponent implements OnInit {
   isExpired(expiresAt): boolean {
     return moment().isAfter(expiresAt);
   }
+
+  purgeModal() {
+    this.modalService.show(RbdTrashPurgeModalComponent);
+  }
 }
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html
new file mode 100644
index 00000000000..1a3e52ac119
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html
@@ -0,0 +1,53 @@
+<cd-modal>
+  <ng-container i18n
+                class="modal-title">Purge Trash</ng-container>
+
+  <ng-container class="modal-content">
+    <form name="purgeForm"
+          class="form"
+          #formDir="ngForm"
+          [formGroup]="purgeForm"
+          novalidate>
+      <div class="modal-body">
+        <p>
+          <ng-container i18n>To purge, select one or All images and click</ng-container>&nbsp;
+          <kbd i18n>Purge Trash</kbd>.&nbsp;
+        </p>
+
+        <div class="form-group">
+          <label class="center-block"
+                 i18n>Pool:
+          </label>
+          <input class="form-control"
+                 type="text"
+                 placeholder="Pool name..."
+                 i18n-placeholder
+                 formControlName="poolName"
+                 *ngIf="!poolPermission.read">
+          <select class="form-control"
+                  formControlName="poolName"
+                  *ngIf="poolPermission.read">
+            <option value=""
+                    i18n>All</option>
+            <option *ngFor="let pool of pools"
+                    [value]="pool">{{ pool }}</option>
+          </select>
+        </div>
+      </div>
+
+      <div class="modal-footer">
+        <div class="button-group text-right">
+          <cd-submit-button i18n
+                            [form]="purgeForm"
+                            (submitAction)="purge()">
+            Purge Trash
+          </cd-submit-button>
+          <button i18n
+                  type="button"
+                  class="btn btn-sm btn-default"
+                  (click)="modalRef.hide()">Cancel</button>
+        </div>
+      </div>
+    </form>
+  </ng-container>
+</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.scss
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.spec.ts
new file mode 100644
index 00000000000..95ad297283c
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.spec.ts
@@ -0,0 +1,105 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ToastModule } from 'ng2-toastr';
+import { BsModalRef } from 'ngx-bootstrap';
+
+import { configureTestBed } from '../../../../testing/unit-test-helper';
+import { Permission } from '../../../shared/models/permissions';
+import { NotificationService } from '../../../shared/services/notification.service';
+import { SharedModule } from '../../../shared/shared.module';
+import { RbdTrashPurgeModalComponent } from './rbd-trash-purge-modal.component';
+
+describe('RbdTrashPurgeModalComponent', () => {
+  let component: RbdTrashPurgeModalComponent;
+  let fixture: ComponentFixture<RbdTrashPurgeModalComponent>;
+  let httpTesting: HttpTestingController;
+
+  configureTestBed({
+    imports: [
+      HttpClientTestingModule,
+      ReactiveFormsModule,
+      SharedModule,
+      ToastModule.forRoot(),
+      RouterTestingModule
+    ],
+    declarations: [RbdTrashPurgeModalComponent],
+    providers: [BsModalRef]
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(RbdTrashPurgeModalComponent);
+    httpTesting = TestBed.get(HttpTestingController);
+    component = fixture.componentInstance;
+  });
+
+  it('should create', () => {
+    fixture.detectChanges();
+    expect(component).toBeTruthy();
+  });
+
+  it(
+    'should finish ngOnInit',
+    fakeAsync(() => {
+      component.poolPermission = new Permission(['read', 'create', 'update', 'delete']);
+      fixture.detectChanges();
+      const req = httpTesting.expectOne('api/pool?attrs=pool_name,application_metadata');
+      req.flush([
+        {
+          application_metadata: ['foo'],
+          pool_name: 'bar'
+        },
+        {
+          application_metadata: ['rbd'],
+          pool_name: 'baz'
+        }
+      ]);
+      tick();
+      expect(component.pools).toEqual(['baz']);
+      expect(component.purgeForm).toBeTruthy();
+    })
+  );
+
+  it('should call ngOnInit without pool permissions', () => {
+    component.poolPermission = new Permission([]);
+    component.ngOnInit();
+    httpTesting.expectOne('api/summary');
+    httpTesting.verify();
+  });
+
+  describe('should call purge', () => {
+    let notificationService: NotificationService;
+    let modalRef: BsModalRef;
+    let req;
+
+    beforeEach(() => {
+      fixture.detectChanges();
+      notificationService = TestBed.get(NotificationService);
+      modalRef = TestBed.get(BsModalRef);
+
+      component.purgeForm.patchValue({ poolName: 'foo' });
+
+      spyOn(modalRef, 'hide').and.stub();
+      spyOn(component.purgeForm, 'setErrors').and.stub();
+      spyOn(notificationService, 'show').and.stub();
+
+      component.purge();
+
+      req = httpTesting.expectOne('api/block/image/trash/purge/?pool_name=foo');
+    });
+
+    it('with success', () => {
+      req.flush(null);
+      expect(component.purgeForm.setErrors).toHaveBeenCalledTimes(0);
+      expect(component.modalRef.hide).toHaveBeenCalledTimes(1);
+    });
+
+    it('with failure', () => {
+      req.flush(null, { status: 500, statusText: 'failure' });
+      expect(component.purgeForm.setErrors).toHaveBeenCalledTimes(1);
+      expect(component.modalRef.hide).toHaveBeenCalledTimes(0);
+    });
+  });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.ts
new file mode 100644
index 00000000000..cda71e538c3
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.ts
@@ -0,0 +1,72 @@
+import { Component, OnInit } from '@angular/core';
+
+import { BsModalRef } from 'ngx-bootstrap';
+
+import { PoolService } from '../../../shared/api/pool.service';
+import { RbdService } from '../../../shared/api/rbd.service';
+import { CdFormBuilder } from '../../../shared/forms/cd-form-builder';
+import { CdFormGroup } from '../../../shared/forms/cd-form-group';
+import { FinishedTask } from '../../../shared/models/finished-task';
+import { Permission } from '../../../shared/models/permissions';
+import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
+
+@Component({
+  selector: 'cd-rbd-trash-purge-modal',
+  templateUrl: './rbd-trash-purge-modal.component.html',
+  styleUrls: ['./rbd-trash-purge-modal.component.scss']
+})
+export class RbdTrashPurgeModalComponent implements OnInit {
+  poolPermission: Permission;
+  purgeForm: CdFormGroup;
+  pools: any[];
+
+  constructor(
+    private authStorageService: AuthStorageService,
+    private rbdService: RbdService,
+    public modalRef: BsModalRef,
+    private fb: CdFormBuilder,
+    private poolService: PoolService,
+    private taskWrapper: TaskWrapperService
+  ) {
+    this.poolPermission = this.authStorageService.getPermissions().pool;
+  }
+
+  createForm() {
+    this.purgeForm = this.fb.group({
+      poolName: ''
+    });
+  }
+
+  ngOnInit() {
+    if (this.poolPermission.read) {
+      this.poolService.list(['pool_name', 'application_metadata']).then((resp) => {
+        this.pools = resp
+          .filter((pool) => pool.application_metadata.includes('rbd'))
+          .map((pool) => pool.pool_name);
+      });
+    }
+
+    this.createForm();
+  }
+
+  purge() {
+    const poolName = this.purgeForm.getValue('poolName') || '';
+    this.taskWrapper
+      .wrapTaskAroundCall({
+        task: new FinishedTask('rbd/trash/purge', {
+          pool_name: poolName
+        }),
+        call: this.rbdService.purgeTrash(poolName)
+      })
+      .subscribe(
+        undefined,
+        () => {
+          this.purgeForm.setErrors({ cdSubmitButton: true });
+        },
+        () => {
+          this.modalRef.hide();
+        }
+      );
+  }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.ts
index 765d2054f86..02e1bcdc152 100644
--- a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.ts
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.ts
@@ -108,6 +108,12 @@ export class RbdService {
     );
   }
 
+  purgeTrash(poolName) {
+    return this.http.post(`api/block/image/trash/purge/?pool_name=${poolName}`, null, {
+      observe: 'response'
+    });
+  }
+
   restoreTrash(poolName, imageId, newImageName) {
     return this.http.post(
       `api/block/image/trash/${poolName}/${imageId}/restore`,