From: Tiago Melo Date: Fri, 16 Feb 2018 17:17:20 +0000 (+0000) Subject: mgr/dashboard_v2: add ceph configuration documentation page X-Git-Tag: wip-pdonnell-testing-20180317.202121~127^2~26 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=020afefd8eb24837c553da93380d228fc2aec370;p=ceph-ci.git mgr/dashboard_v2: add ceph configuration documentation page Signed-off-by: Tiago Melo --- diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/app-routing.module.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/app-routing.module.ts index 822159985eb..9e9ae715abc 100644 --- a/src/pybind/mgr/dashboard_v2/frontend/src/app/app-routing.module.ts +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/app-routing.module.ts @@ -5,6 +5,7 @@ import { IscsiComponent } from './ceph/block/iscsi/iscsi.component'; import { PoolDetailComponent } from './ceph/block/pool-detail/pool-detail.component'; import { CephfsComponent } from './ceph/cephfs/cephfs/cephfs.component'; import { ClientsComponent } from './ceph/cephfs/clients/clients.component'; +import { ConfigurationComponent } from './ceph/cluster/configuration/configuration.component'; import { HostsComponent } from './ceph/cluster/hosts/hosts.component'; import { MonitorComponent } from './ceph/cluster/monitor/monitor.component'; import { DashboardComponent } from './ceph/dashboard/dashboard/dashboard.component'; @@ -37,6 +38,7 @@ const routes: Routes = [ { path: 'monitor', component: MonitorComponent, canActivate: [AuthGuardService] }, { path: 'cephfs/:id/clients', component: ClientsComponent, canActivate: [AuthGuardService] }, { path: 'cephfs/:id', component: CephfsComponent, canActivate: [AuthGuardService] }, + { path: 'configuration', component: ConfigurationComponent, canActivate: [AuthGuardService] }, { path: '404', component: NotFoundComponent }, { path: '**', redirectTo: '/404'} ]; diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/ceph.module.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/ceph.module.ts index e9e278a59b0..7509789a3b9 100644 --- a/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/ceph.module.ts +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/ceph.module.ts @@ -1,6 +1,7 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; +import { SharedModule } from '../shared/shared.module'; import { BlockModule } from './block/block.module'; import { CephfsModule } from './cephfs/cephfs.module'; import { ClusterModule } from './cluster/cluster.module'; @@ -14,7 +15,8 @@ import { RgwModule } from './rgw/rgw.module'; DashboardModule, RgwModule, BlockModule, - CephfsModule + CephfsModule, + SharedModule ], declarations: [] }) diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/cluster.module.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/cluster.module.ts index 9992bfac456..dad1d6c59b6 100644 --- a/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/cluster.module.ts +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/cluster.module.ts @@ -1,9 +1,11 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; import { ComponentsModule } from '../../shared/components/components.module'; import { SharedModule } from '../../shared/shared.module'; +import { ConfigurationComponent } from './configuration/configuration.component'; import { HostsComponent } from './hosts/hosts.component'; import { MonitorService } from './monitor.service'; import { MonitorComponent } from './monitor/monitor.component'; @@ -13,11 +15,13 @@ import { MonitorComponent } from './monitor/monitor.component'; CommonModule, ComponentsModule, SharedModule, - RouterModule + RouterModule, + FormsModule ], declarations: [ HostsComponent, MonitorComponent, + ConfigurationComponent ], providers: [ MonitorService diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/configuration/configuration.component.html b/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/configuration/configuration.component.html new file mode 100644 index 00000000000..efe071a0227 --- /dev/null +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/configuration/configuration.component.html @@ -0,0 +1,67 @@ + + +
+
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionTypeLevelDefaultTagsServicesSee_alsoMaxMin
{{ row.name }} +

+ {{ row.desc }}

+

{{ row.long_desc }}

+
{{ row.type }}{{ row.level }} + {{ row.default }} {{ row.daemon_default }} + +

{{ item }}

+
+

{{ item }}

+
+

{{ item }}

+
{{ row.max }}{{ row.min }}
+
diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/configuration/configuration.component.scss b/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/configuration/configuration.component.scss new file mode 100644 index 00000000000..e968d6d9086 --- /dev/null +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/configuration/configuration.component.scss @@ -0,0 +1,5 @@ +@import '../../../shared/datatable/table/table.component.scss'; + +td.wrap { + word-break: break-all; +} diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/configuration/configuration.component.spec.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/configuration/configuration.component.spec.ts new file mode 100644 index 00000000000..0d98766efd4 --- /dev/null +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/configuration/configuration.component.spec.ts @@ -0,0 +1,41 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule } from '@angular/forms'; + +import { Observable } from 'rxjs/Observable'; + +import { ConfigurationService } from '../../../shared/services/configuration.service'; +import { SharedModule } from '../../../shared/shared.module'; +import { ConfigurationComponent } from './configuration.component'; + +describe('ConfigurationComponent', () => { + let component: ConfigurationComponent; + let fixture: ComponentFixture; + + const fakeService = { + getConfigData: () => { + return Observable.create(observer => { + return () => console.log('disposed'); + }); + } + }; + + beforeEach( + async(() => { + TestBed.configureTestingModule({ + declarations: [ConfigurationComponent], + providers: [{ provide: ConfigurationService, useValue: fakeService }], + imports: [SharedModule, FormsModule] + }).compileComponents(); + }) + ); + + beforeEach(() => { + fixture = TestBed.createComponent(ConfigurationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/configuration/configuration.component.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/configuration/configuration.component.ts new file mode 100644 index 00000000000..d6112e7d154 --- /dev/null +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/ceph/cluster/configuration/configuration.component.ts @@ -0,0 +1,79 @@ +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; + +import { ConfigurationService } from '../../../shared/services/configuration.service'; + +@Component({ + selector: 'cd-configuration', + templateUrl: './configuration.component.html', + styleUrls: ['./configuration.component.scss'] +}) +export class ConfigurationComponent implements OnInit { + @ViewChild('arrayTmpl') arrayTmpl: TemplateRef; + + data = []; + columns: any; + + filters = [ + { + label: 'Level', + prop: 'level', + value: 'basic', + options: ['basic', 'advanced', 'developer'], + applyFilter: (row, value) => { + enum Level { + basic = 0, + advanced = 1, + developer = 2 + } + + const levelVal = Level[value]; + + return Level[row.level] <= levelVal; + } + }, + { + label: 'Service', + prop: 'services', + value: 'any', + options: ['mon', 'mgr', 'osd', 'mds', 'common', 'mds_client', 'rgw', 'any'], + applyFilter: (row, value) => { + if (value === 'any') { + return true; + } + + return row.services.includes(value); + } + } + ]; + + constructor(private configurationService: ConfigurationService) {} + + ngOnInit() { + this.columns = [ + { flexGrow: 2, canAutoResize: true, prop: 'name' }, + { flexGrow: 2, prop: 'desc', name: 'Description' }, + { flexGrow: 2, prop: 'long_desc', name: 'Long description' }, + { flexGrow: 1, prop: 'type' }, + { flexGrow: 1, prop: 'level' }, + { flexGrow: 1, prop: 'default' }, + { flexGrow: 2, prop: 'daemon_default', name: 'Daemon default' }, + { flexGrow: 1, prop: 'tags', name: 'Tags', cellTemplate: this.arrayTmpl }, + { flexGrow: 1, prop: 'services', name: 'Services', cellTemplate: this.arrayTmpl }, + { flexGrow: 1, prop: 'see_also', name: 'See_also', cellTemplate: this.arrayTmpl }, + { flexGrow: 1, prop: 'max', name: 'Max' }, + { flexGrow: 1, prop: 'min', name: 'Min' } + ]; + + this.fetchData(); + } + + fetchData() { + this.configurationService.getConfigData().subscribe((data: any) => { + this.data = data; + }); + } + + updateFilter() { + this.data = [...this.data]; + } +} diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/core/navigation/navigation/navigation.component.html b/src/pybind/mgr/dashboard_v2/frontend/src/app/core/navigation/navigation/navigation.component.html index ae50c267c87..6b33769a2f4 100644 --- a/src/pybind/mgr/dashboard_v2/frontend/src/app/core/navigation/navigation/navigation.component.html +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/core/navigation/navigation/navigation.component.html @@ -64,6 +64,14 @@ routerLink="/monitor/"> Monitors + +
  • + Configuration Doc. + +
  • @@ -85,7 +93,8 @@ routerLink="/block/iscsi">iSCSI diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/pipes/filter.pipe.spec.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/pipes/filter.pipe.spec.ts new file mode 100644 index 00000000000..1427de361bd --- /dev/null +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/pipes/filter.pipe.spec.ts @@ -0,0 +1,8 @@ +import { FilterPipe } from './filter.pipe'; + +describe('FilterPipe', () => { + it('create an instance', () => { + const pipe = new FilterPipe(); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/pipes/filter.pipe.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/pipes/filter.pipe.ts new file mode 100644 index 00000000000..21115a7b6d0 --- /dev/null +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/pipes/filter.pipe.ts @@ -0,0 +1,25 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ + name: 'filter' +}) +export class FilterPipe implements PipeTransform { + transform(value: any, args?: any): any { + return value.filter(row => { + let result = true; + + args.forEach(filter => { + if (!filter.value) { + return; + } + + result = result && filter.applyFilter(row, filter.value); + if (!result) { + return result; + } + }); + + return result; + }); + } +} diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/pipes/pipes.module.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/pipes/pipes.module.ts index 0d59e4e92dd..51dc736c8a6 100644 --- a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/pipes/pipes.module.ts +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/pipes/pipes.module.ts @@ -4,6 +4,7 @@ import { NgModule } from '@angular/core'; import { CephShortVersionPipe } from './ceph-short-version.pipe'; import { DimlessBinaryPipe } from './dimless-binary.pipe'; import { DimlessPipe } from './dimless.pipe'; +import { FilterPipe } from './filter.pipe'; import { HealthColorPipe } from './health-color.pipe'; import { ListPipe } from './list.pipe'; import { RelativeDatePipe } from './relative-date.pipe'; @@ -16,7 +17,8 @@ import { RelativeDatePipe } from './relative-date.pipe'; DimlessPipe, CephShortVersionPipe, RelativeDatePipe, - ListPipe + ListPipe, + FilterPipe ], exports: [ DimlessBinaryPipe, @@ -24,7 +26,8 @@ import { RelativeDatePipe } from './relative-date.pipe'; DimlessPipe, CephShortVersionPipe, RelativeDatePipe, - ListPipe + ListPipe, + FilterPipe ], providers: [ CephShortVersionPipe, diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/configuration.service.spec.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/configuration.service.spec.ts new file mode 100644 index 00000000000..dcb5a9e10b9 --- /dev/null +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/configuration.service.spec.ts @@ -0,0 +1,21 @@ +import { HttpClientModule } from '@angular/common/http'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; +import { inject, TestBed } from '@angular/core/testing'; + +import { ConfigurationService } from './configuration.service'; + +describe('ConfigurationService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ConfigurationService], + imports: [HttpClientTestingModule, HttpClientModule] + }); + }); + + it( + 'should be created', + inject([ConfigurationService], (service: ConfigurationService) => { + expect(service).toBeTruthy(); + }) + ); +}); diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/configuration.service.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/configuration.service.ts new file mode 100644 index 00000000000..80b04aa50b1 --- /dev/null +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/configuration.service.ts @@ -0,0 +1,11 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; + +@Injectable() +export class ConfigurationService { + constructor(private http: HttpClient) {} + + getConfigData() { + return this.http.get('/api/cluster_conf/'); + } +} diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/services.module.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/services.module.ts index 71adc6212ad..2901b4b90e6 100644 --- a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/services.module.ts +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/services.module.ts @@ -1,6 +1,7 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; +import { ConfigurationService } from './configuration.service'; import { FormatterService } from './formatter.service'; import { TcmuIscsiService } from './tcmu-iscsi.service'; import { TopLevelService } from './top-level.service'; @@ -10,6 +11,6 @@ import { TopLevelService } from './top-level.service'; CommonModule ], declarations: [], - providers: [FormatterService, TopLevelService, TcmuIscsiService] + providers: [FormatterService, TopLevelService, TcmuIscsiService, ConfigurationService] }) export class ServicesModule { } diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/shared.module.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/shared.module.ts index 678c1b40524..4e453253427 100644 --- a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/shared.module.ts +++ b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/shared.module.ts @@ -26,7 +26,6 @@ import { ServicesModule } from './services/services.module'; ComponentsModule, ServicesModule, PasswordButtonDirective, - ComponentsModule, DataTableModule ], declarations: [