Skip to content

Commit 18826ae

Browse files
authored
Merge pull request ceph#61873 from rhcs-dashboard/nfs-create-cluster
mgr/dashboard: NFS Cluster and Export Listing
2 parents 35b2e50 + e541dca commit 18826ae

20 files changed

+334
-34
lines changed

src/pybind/mgr/dashboard/controllers/nfs.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from ..services.cephfs import CephFS
1515
from ..services.exception import DashboardException, handle_cephfs_error, \
1616
serialize_dashboard_exception
17+
from ..tools import str_to_bool
1718
from . import APIDoc, APIRouter, BaseController, Endpoint, EndpointDoc, \
1819
ReadPermission, RESTController, Task, UIRouter
1920
from ._version import APIVersion
@@ -87,7 +88,11 @@ def composed_decorator(func):
8788
class NFSGaneshaCluster(RESTController):
8889
@ReadPermission
8990
@RESTController.MethodMap(version=APIVersion.EXPERIMENTAL)
90-
def list(self):
91+
def list(self, info: Optional[bool] = False):
92+
if str_to_bool(info):
93+
return [
94+
{"name": key, **value} for key, value in mgr.remote('nfs', 'cluster_info').items()
95+
]
9196
return mgr.remote('nfs', 'cluster_ls')
9297

9398

@@ -109,11 +114,11 @@ def _get_schema_export(export: Dict[str, Any]) -> Dict[str, Any]:
109114
export['fsal'] = schema_fsal_info
110115
return export
111116

112-
@EndpointDoc("List all NFS-Ganesha exports",
117+
@EndpointDoc("List all or cluster specific NFS-Ganesha exports ",
113118
responses={200: [EXPORT_SCHEMA]})
114-
def list(self) -> List[Dict[str, Any]]:
119+
def list(self, cluster_id=None) -> List[Dict[str, Any]]:
115120
exports = []
116-
for export in mgr.remote('nfs', 'export_ls'):
121+
for export in mgr.remote('nfs', 'export_ls', cluster_id, True):
117122
exports.append(self._get_schema_export(export))
118123

119124
return exports

src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import { ServicesComponent } from './ceph/cluster/services/services.component';
2626
import { TelemetryComponent } from './ceph/cluster/telemetry/telemetry.component';
2727
import { DashboardComponent } from './ceph/dashboard/dashboard/dashboard.component';
2828
import { NfsFormComponent } from './ceph/nfs/nfs-form/nfs-form.component';
29-
import { NfsListComponent } from './ceph/nfs/nfs-list/nfs-list.component';
3029
import { PerformanceCounterComponent } from './ceph/performance-counter/performance-counter/performance-counter.component';
3130
import { LoginPasswordFormComponent } from './core/auth/login-password-form/login-password-form.component';
3231
import { LoginComponent } from './core/auth/login/login.component';
@@ -56,6 +55,7 @@ import { SmbTabsComponent } from './ceph/smb/smb-tabs/smb-tabs.component';
5655
import { SmbShareFormComponent } from './ceph/smb/smb-share-form/smb-share-form.component';
5756
import { SmbJoinAuthFormComponent } from './ceph/smb/smb-join-auth-form/smb-join-auth-form.component';
5857
import { SmbUsersgroupsFormComponent } from './ceph/smb/smb-usersgroups-form/smb-usersgroups-form.component';
58+
import { NfsClusterComponent } from './ceph/nfs/nfs-cluster/nfs-cluster.component';
5959

6060
@Injectable()
6161
export class PerformanceCounterBreadcrumbsResolver extends BreadcrumbsResolver {
@@ -417,7 +417,7 @@ const routes: Routes = [
417417
breadcrumbs: 'File/NFS'
418418
},
419419
children: [
420-
{ path: '', component: NfsListComponent },
420+
{ path: '', component: NfsClusterComponent },
421421
{
422422
path: `${URLVerbs.CREATE}/:fs_name/:subvolume_group`,
423423
component: NfsFormComponent,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export interface NFSBackend {
2+
hostname: string;
3+
ip: string;
4+
port: number;
5+
}
6+
7+
export interface NFSCluster {
8+
name: string;
9+
virtual_ip: number;
10+
port: number;
11+
backend: NFSBackend[];
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<ng-container *ngIf="!!selection">
2+
<legend
3+
i18n
4+
>
5+
{{title | titlecase}}
6+
<cd-help-text>
7+
Lists exports for a cluster
8+
</cd-help-text>
9+
</legend>
10+
<cd-nfs-list [clusterId]="selection.name"></cd-nfs-list>
11+
</ng-container>

src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-cluster-details/nfs-cluster-details.component.scss

Whitespace-only changes.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { ComponentFixture, TestBed } from '@angular/core/testing';
2+
import { NfsClusterDetailsComponent } from './nfs-cluster-details.component';
3+
import { configureTestBed } from '~/testing/unit-test-helper';
4+
import { SharedModule } from '~/app/shared/shared.module';
5+
import { HttpClientTestingModule } from '@angular/common/http/testing';
6+
7+
describe('NfsClusterDetailsComponent', () => {
8+
let component: NfsClusterDetailsComponent;
9+
let fixture: ComponentFixture<NfsClusterDetailsComponent>;
10+
11+
configureTestBed({
12+
declarations: [NfsClusterDetailsComponent],
13+
imports: [HttpClientTestingModule, SharedModule]
14+
});
15+
16+
beforeEach(() => {
17+
fixture = TestBed.createComponent(NfsClusterDetailsComponent);
18+
component = fixture.componentInstance;
19+
});
20+
it('should create', () => {
21+
expect(component).toBeTruthy();
22+
});
23+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Component, Input } from '@angular/core';
2+
import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
3+
4+
@Component({
5+
selector: 'cd-nfs-cluster-details',
6+
templateUrl: './nfs-cluster-details.component.html',
7+
styleUrls: ['./nfs-cluster-details.component.scss']
8+
})
9+
export class NfsClusterDetailsComponent {
10+
title = $localize`Export`;
11+
@Input()
12+
selection: CdTableSelection;
13+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<ng-container *ngIf="orchStatus?.available && clusters$ | async as clusters">
2+
<cd-table [autoReload]="true"
3+
[data]="clusters"
4+
columnMode="flex"
5+
[columns]="columns"
6+
selectionType="single"
7+
[hasDetails]="true"
8+
(setExpandedRow)="setExpandedRow($event)"
9+
(fetchData)="loadData()"
10+
(updateSelection)="updateSelection($event)">
11+
<cd-table-actions class="table-actions"
12+
[selection]="selection"
13+
[permission]="permission"
14+
[tableActions]="tableActions"></cd-table-actions>
15+
<cd-nfs-cluster-details *cdTableDetail
16+
[selection]="expandedRow"></cd-nfs-cluster-details>
17+
</cd-table>
18+
</ng-container>
19+
20+
<ng-template
21+
#virtualIpTpl
22+
let-row="data.row"
23+
>
24+
<span *ngIf="row.virtual_ip || row.ports">
25+
<cds-tag size="md">
26+
{{ row.virtual_ip }}:{{row.ports}}
27+
</cds-tag>
28+
</span>
29+
</ng-template>
30+
31+
<ng-template
32+
#ipAddrTpl
33+
let-backends="data.value"
34+
>
35+
<span *ngFor="let backend of backends">
36+
<span *ngIf="backend.ip || backend.port">
37+
<cds-tag size="md">
38+
{{ backend.ip }}:{{backend.port}}
39+
</cds-tag>
40+
</span>
41+
</span>
42+
</ng-template>
43+
44+
<ng-template #hostnameTpl
45+
let-backends="data.value">
46+
<span *ngFor="let backend of backends">
47+
<span *ngIf="backend.hostname">
48+
<cds-tag size="md">{{backend.hostname }}</cds-tag>
49+
</span>
50+
</span>
51+
</ng-template>

src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-cluster/nfs-cluster.component.scss

Whitespace-only changes.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { ComponentFixture, TestBed } from '@angular/core/testing';
2+
import { configureTestBed } from '~/testing/unit-test-helper';
3+
import { SharedModule } from '~/app/shared/shared.module';
4+
import { HttpClientTestingModule } from '@angular/common/http/testing';
5+
import { NfsClusterComponent } from './nfs-cluster.component';
6+
7+
describe('NfsClusterComponent', () => {
8+
let component: NfsClusterComponent;
9+
let fixture: ComponentFixture<NfsClusterComponent>;
10+
11+
configureTestBed({
12+
declarations: [NfsClusterComponent],
13+
imports: [HttpClientTestingModule, SharedModule]
14+
});
15+
16+
beforeEach(() => {
17+
fixture = TestBed.createComponent(NfsClusterComponent);
18+
component = fixture.componentInstance;
19+
});
20+
it('should create', () => {
21+
expect(component).toBeTruthy();
22+
});
23+
});

0 commit comments

Comments
 (0)