From 164b29d49173cdc333adc9bbee1e714a20bb9950 Mon Sep 17 00:00:00 2001 From: Kiefer Chang Date: Tue, 3 Nov 2020 15:09:42 +0800 Subject: [PATCH] mgr/dashboard: allow selecting all daemons for Orchestrator NFS clusters Allow users to select or deselect all daemons with a single click in NFS export form when the cluster type is Orchestrator. Fixes: https://tracker.ceph.com/issues/48176 Signed-off-by: Kiefer Chang --- .../src/app/ceph/nfs/nfs-cluster-type.enum.ts | 4 ++ .../ceph/nfs/nfs-form/nfs-form.component.html | 27 +++++++-- .../nfs/nfs-form/nfs-form.component.spec.ts | 14 ++++- .../ceph/nfs/nfs-form/nfs-form.component.ts | 58 ++++++++++++------- 4 files changed, 76 insertions(+), 27 deletions(-) create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-cluster-type.enum.ts diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-cluster-type.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-cluster-type.enum.ts new file mode 100644 index 00000000000..7a775e5ab2d --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-cluster-type.enum.ts @@ -0,0 +1,4 @@ +export enum NFSClusterType { + user = 'user', + orchestrator = 'orchestrator' +} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html index 3f596d40080..cdcb2cb6bf9 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html @@ -31,7 +31,7 @@ value="" i18n>-- Select the cluster -- + [value]="cluster.cluster_id">{{ cluster.cluster_id }} -
+
-
+
+ +
+
+ +
+
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.spec.ts index 1ad45854d00..9911d18d8ed 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.spec.ts @@ -11,6 +11,7 @@ import { LoadingPanelComponent } from '~/app/shared/components/loading-panel/loa import { SharedModule } from '~/app/shared/shared.module'; import { ActivatedRouteStub } from '~/testing/activated-route-stub'; import { configureTestBed } from '~/testing/unit-test-helper'; +import { NFSClusterType } from '../nfs-cluster-type.enum'; import { NfsFormClientComponent } from '../nfs-form-client/nfs-form-client.component'; import { NfsFormComponent } from './nfs-form.component'; @@ -49,9 +50,9 @@ describe('NfsFormComponent', () => { fixture.detectChanges(); httpTesting.expectOne('api/nfs-ganesha/daemon').flush([ - { daemon_id: 'node1', cluster_id: 'cluster1' }, - { daemon_id: 'node2', cluster_id: 'cluster1' }, - { daemon_id: 'node5', cluster_id: 'cluster2' } + { daemon_id: 'node1', cluster_id: 'cluster1', cluster_type: NFSClusterType.user }, + { daemon_id: 'node2', cluster_id: 'cluster1', cluster_type: NFSClusterType.user }, + { daemon_id: 'node5', cluster_id: 'cluster2', cluster_type: NFSClusterType.orchestrator } ]); httpTesting.expectOne('ui-api/nfs-ganesha/fsals').flush(['CEPH', 'RGW']); httpTesting.expectOne('ui-api/nfs-ganesha/cephx/clients').flush(['admin', 'fs', 'rgw']); @@ -112,6 +113,7 @@ describe('NfsFormComponent', () => { it('should prepare data when selecting an cluster', () => { expect(component.allDaemons).toEqual({ cluster1: ['node1', 'node2'], cluster2: ['node5'] }); expect(component.daemonsSelections).toEqual([]); + expect(component.clusterType).toBeNull(); component.nfsForm.patchValue({ cluster_id: 'cluster1' }); component.onClusterChange(); @@ -120,6 +122,12 @@ describe('NfsFormComponent', () => { { description: '', name: 'node1', selected: false, enabled: true }, { description: '', name: 'node2', selected: false, enabled: true } ]); + expect(component.clusterType).toBe(NFSClusterType.user); + + component.nfsForm.patchValue({ cluster_id: 'cluster2' }); + component.onClusterChange(); + expect(component.clusterType).toBe(NFSClusterType.orchestrator); + expect(component.daemonsSelections).toEqual([]); }); it('should clean data when changing cluster', () => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts index d24c0709655..5234be1404e 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts @@ -20,6 +20,7 @@ import { FinishedTask } from '~/app/shared/models/finished-task'; import { Permission } from '~/app/shared/models/permissions'; import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service'; +import { NFSClusterType } from '../nfs-cluster-type.enum'; import { NfsFormClientComponent } from '../nfs-form-client/nfs-form-client.component'; @Component({ @@ -38,13 +39,14 @@ export class NfsFormComponent extends CdForm implements OnInit { isEdit = false; cluster_id: string = null; + clusterType: string = null; export_id: string = null; isNewDirectory = false; isNewBucket = false; isDefaultCluster = false; - allClusters: string[] = null; + allClusters: { cluster_id: string; cluster_type: string }[] = null; allDaemons = {}; icons = Icons; @@ -227,11 +229,13 @@ export class NfsFormComponent extends CdForm implements OnInit { res.sec_label_xattr = res.fsal.sec_label_xattr; } - this.daemonsSelections = _.map( - this.allDaemons[res.cluster_id], - (daemon) => new SelectOption(res.daemons.indexOf(daemon) !== -1, daemon, '') - ); - this.daemonsSelections = [...this.daemonsSelections]; + if (this.clusterType === NFSClusterType.user) { + this.daemonsSelections = _.map( + this.allDaemons[res.cluster_id], + (daemon) => new SelectOption(res.daemons.indexOf(daemon) !== -1, daemon, '') + ); + this.daemonsSelections = [...this.daemonsSelections]; + } res.protocolNfsv3 = res.protocols.indexOf(3) !== -1; res.protocolNfsv4 = res.protocols.indexOf(4) !== -1; @@ -259,25 +263,27 @@ export class NfsFormComponent extends CdForm implements OnInit { resolveDaemons(daemons: Record) { daemons = _.sortBy(daemons, ['daemon_id']); + const clusters = _.groupBy(daemons, 'cluster_id'); - this.allClusters = _(daemons) - .map((daemon) => daemon.cluster_id) - .sortedUniq() - .value(); - - _.forEach(this.allClusters, (cluster) => { - this.allDaemons[cluster] = []; + this.allClusters = []; + _.forIn(clusters, (cluster, cluster_id) => { + this.allClusters.push({ cluster_id: cluster_id, cluster_type: cluster[0].cluster_type }); + this.allDaemons[cluster_id] = []; }); _.forEach(daemons, (daemon) => { this.allDaemons[daemon.cluster_id].push(daemon.daemon_id); }); + if (this.isEdit) { + this.clusterType = _.find(this.allClusters, { cluster_id: this.cluster_id })?.cluster_type; + } + const hasOneCluster = _.isArray(this.allClusters) && this.allClusters.length === 1; - this.isDefaultCluster = hasOneCluster && this.allClusters[0] === '_default_'; + this.isDefaultCluster = hasOneCluster && this.allClusters[0].cluster_id === '_default_'; if (hasOneCluster) { this.nfsForm.patchValue({ - cluster_id: this.allClusters[0] + cluster_id: this.allClusters[0].cluster_id }); this.onClusterChange(); } @@ -467,11 +473,16 @@ export class NfsFormComponent extends CdForm implements OnInit { onClusterChange() { const cluster_id = this.nfsForm.getValue('cluster_id'); - this.daemonsSelections = _.map( - this.allDaemons[cluster_id], - (daemon) => new SelectOption(false, daemon, '') - ); - this.daemonsSelections = [...this.daemonsSelections]; + this.clusterType = _.find(this.allClusters, { cluster_id: cluster_id })?.cluster_type; + if (this.clusterType === NFSClusterType.user) { + this.daemonsSelections = _.map( + this.allDaemons[cluster_id], + (daemon) => new SelectOption(false, daemon, '') + ); + this.daemonsSelections = [...this.daemonsSelections]; + } else { + this.daemonsSelections = []; + } this.nfsForm.patchValue({ daemons: [] }); } @@ -493,6 +504,13 @@ export class NfsFormComponent extends CdForm implements OnInit { this.nfsForm.get('daemons').setValue(this.nfsForm.getValue('daemons')); } + onToggleAllDaemonsSelection() { + const cluster_id = this.nfsForm.getValue('cluster_id'); + const daemons = + this.nfsForm.getValue('daemons').length === 0 ? this.allDaemons[cluster_id] : []; + this.nfsForm.patchValue({ daemons: daemons }); + } + submitAction() { let action: Observable; const requestModel = this._buildRequest(); -- 2.47.3