]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.ts
29b435900df6f22ed3f0085cf38ef6daaac080e1
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / ceph / block / mirroring / pool-list / pool-list.component.ts
1 import { Component, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
2
3 import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
4 import { Observable, Subscriber, Subscription } from 'rxjs';
5
6 import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
7 import { TableStatusViewCache } from '~/app/shared/classes/table-status-view-cache';
8 import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
9 import { Icons } from '~/app/shared/enum/icons.enum';
10 import { CdTableAction } from '~/app/shared/models/cd-table-action';
11 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
12 import { FinishedTask } from '~/app/shared/models/finished-task';
13 import { Permission } from '~/app/shared/models/permissions';
14 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
15 import { ModalService } from '~/app/shared/services/modal.service';
16 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
17 import { PoolEditModeModalComponent } from '../pool-edit-mode-modal/pool-edit-mode-modal.component';
18 import { PoolEditPeerModalComponent } from '../pool-edit-peer-modal/pool-edit-peer-modal.component';
19
20 @Component({
21 selector: 'cd-mirroring-pools',
22 templateUrl: './pool-list.component.html',
23 styleUrls: ['./pool-list.component.scss']
24 })
25 export class PoolListComponent implements OnInit, OnDestroy {
26 @ViewChild('healthTmpl', { static: true })
27 healthTmpl: TemplateRef<any>;
28
29 subs: Subscription;
30
31 permission: Permission;
32 tableActions: CdTableAction[];
33 selection = new CdTableSelection();
34
35 modalRef: NgbModalRef;
36
37 data: [];
38 columns: {};
39
40 tableStatus = new TableStatusViewCache();
41
42 constructor(
43 private authStorageService: AuthStorageService,
44 private rbdMirroringService: RbdMirroringService,
45 private modalService: ModalService,
46 private taskWrapper: TaskWrapperService
47 ) {
48 this.data = [];
49 this.permission = this.authStorageService.getPermissions().rbdMirroring;
50
51 const editModeAction: CdTableAction = {
52 permission: 'update',
53 icon: Icons.edit,
54 click: () => this.editModeModal(),
55 name: $localize`Edit Mode`,
56 canBePrimary: () => true
57 };
58 const addPeerAction: CdTableAction = {
59 permission: 'create',
60 icon: Icons.add,
61 name: $localize`Add Peer`,
62 click: () => this.editPeersModal('add'),
63 disable: () => !this.selection.first() || this.selection.first().mirror_mode === 'disabled',
64 visible: () => !this.getPeerUUID(),
65 canBePrimary: () => false
66 };
67 const editPeerAction: CdTableAction = {
68 permission: 'update',
69 icon: Icons.exchange,
70 name: $localize`Edit Peer`,
71 click: () => this.editPeersModal('edit'),
72 visible: () => !!this.getPeerUUID()
73 };
74 const deletePeerAction: CdTableAction = {
75 permission: 'delete',
76 icon: Icons.destroy,
77 name: $localize`Delete Peer`,
78 click: () => this.deletePeersModal(),
79 visible: () => !!this.getPeerUUID()
80 };
81 this.tableActions = [editModeAction, addPeerAction, editPeerAction, deletePeerAction];
82 }
83
84 ngOnInit() {
85 this.columns = [
86 { prop: 'name', name: $localize`Name`, flexGrow: 2 },
87 { prop: 'mirror_mode', name: $localize`Mode`, flexGrow: 2 },
88 { prop: 'leader_id', name: $localize`Leader`, flexGrow: 2 },
89 { prop: 'image_local_count', name: $localize`# Local`, flexGrow: 2 },
90 { prop: 'image_remote_count', name: $localize`# Remote`, flexGrow: 2 },
91 {
92 prop: 'health',
93 name: $localize`Health`,
94 cellTemplate: this.healthTmpl,
95 flexGrow: 1
96 }
97 ];
98
99 this.subs = this.rbdMirroringService.subscribeSummary((data) => {
100 this.data = data.content_data.pools;
101 this.tableStatus = new TableStatusViewCache(data.status);
102 });
103 }
104
105 ngOnDestroy(): void {
106 this.subs.unsubscribe();
107 }
108
109 refresh() {
110 this.rbdMirroringService.refresh();
111 }
112
113 editModeModal() {
114 const initialState = {
115 poolName: this.selection.first().name
116 };
117 this.modalRef = this.modalService.show(PoolEditModeModalComponent, initialState);
118 }
119
120 editPeersModal(mode: string) {
121 const initialState = {
122 poolName: this.selection.first().name,
123 mode: mode
124 };
125 if (mode === 'edit') {
126 initialState['peerUUID'] = this.getPeerUUID();
127 }
128 this.modalRef = this.modalService.show(PoolEditPeerModalComponent, initialState);
129 }
130
131 deletePeersModal() {
132 const poolName = this.selection.first().name;
133 const peerUUID = this.getPeerUUID();
134
135 this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
136 itemDescription: $localize`mirror peer`,
137 itemNames: [`${poolName} (${peerUUID})`],
138 submitActionObservable: () =>
139 new Observable((observer: Subscriber<any>) => {
140 this.taskWrapper
141 .wrapTaskAroundCall({
142 task: new FinishedTask('rbd/mirroring/peer/delete', {
143 pool_name: poolName
144 }),
145 call: this.rbdMirroringService.deletePeer(poolName, peerUUID)
146 })
147 .subscribe({
148 error: (resp) => observer.error(resp),
149 complete: () => {
150 this.rbdMirroringService.refresh();
151 observer.complete();
152 }
153 });
154 })
155 });
156 }
157
158 getPeerUUID(): any {
159 const selection = this.selection.first();
160 const pool = this.data.find((o) => selection && selection.name === o['name']);
161 if (pool && pool['peer_uuids']) {
162 return pool['peer_uuids'][0];
163 }
164
165 return undefined;
166 }
167
168 updateSelection(selection: CdTableSelection) {
169 this.selection = selection;
170 }
171 }