]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard_v2: Move `dashboard/toplevel` to a new controller
authorSebastian Wagner <sebastian.wagner@suse.com>
Thu, 22 Feb 2018 13:52:08 +0000 (14:52 +0100)
committerRicardo Dias <rdias@suse.com>
Mon, 5 Mar 2018 13:07:15 +0000 (13:07 +0000)
Details:

* Moved `/dashboard/toplevel` API endpoint to `/summary`.
* Moved testcase to `tests/test_summary.py`.
* Also renamed service in the frontend.

Signed-off-by: Sebastian Wagner <sebastian.wagner@suse.com>
src/pybind/mgr/dashboard_v2/controllers/dashboard.py
src/pybind/mgr/dashboard_v2/controllers/summary.py [new file with mode: 0644]
src/pybind/mgr/dashboard_v2/frontend/src/app/core/navigation/navigation/navigation.component.html
src/pybind/mgr/dashboard_v2/frontend/src/app/core/navigation/navigation/navigation.component.ts
src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/services.module.ts
src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/summary.service.spec.ts [new file with mode: 0644]
src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/summary.service.ts [new file with mode: 0644]
src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/top-level.service.spec.ts [deleted file]
src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/top-level.service.ts [deleted file]
src/pybind/mgr/dashboard_v2/tests/test_dashboard.py
src/pybind/mgr/dashboard_v2/tests/test_summary.py [new file with mode: 0644]

index 21637f4f97862ba67ebaeb5ac1847af6acf3c4b7..da8a3b341c4f9136a33ecebf3b60d6d71efaae43 100644 (file)
@@ -9,8 +9,7 @@ import time
 import cherrypy
 from mgr_module import CommandResult
 
-from ..services.ceph_service import CephService
-from ..tools import ApiController, AuthRequired, BaseController, NotificationQueue, ViewCache
+from ..tools import ApiController, AuthRequired, BaseController, NotificationQueue
 
 
 LOG_BUFFER_SIZE = 30
@@ -55,35 +54,6 @@ class Dashboard(BaseController):
                 for l in lines:
                     buf.appendleft(l)
 
-    @ViewCache()
-    def _rbd_pool_ls(self):
-        return [pool['pool_name'] for pool in CephService.get_pool_list('rbd')]
-
-    @cherrypy.expose
-    @cherrypy.tools.json_out()
-    def toplevel(self):
-        fsmap = self.mgr.get("fs_map")
-
-        filesystems = [
-            {
-                "id": f['id'],
-                "name": f['mdsmap']['fs_name']
-            }
-            for f in fsmap['filesystems']
-        ]
-
-        _, data = self._rbd_pool_ls()
-        if data is None:
-            self.mgr.log.warning("Failed to get RBD pool list")
-            data = []
-        data.sort()
-
-        return {
-            'health_status': self.health_data()['status'],
-            'filesystems': filesystems,
-            'rbd_pools': data
-        }
-
     # pylint: disable=R0914
     @cherrypy.expose
     @cherrypy.tools.json_out()
diff --git a/src/pybind/mgr/dashboard_v2/controllers/summary.py b/src/pybind/mgr/dashboard_v2/controllers/summary.py
new file mode 100644 (file)
index 0000000..a3c0ed0
--- /dev/null
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import
+
+import json
+
+import cherrypy
+
+from ..tools import AuthRequired, ApiController, BaseController
+from ..services.ceph_service import CephService
+
+
+@ApiController('summary')
+@AuthRequired()
+class Summary(BaseController):
+    def _rbd_pool_data(self):
+        pool_names = [pool['pool_name'] for pool in CephService.get_pool_list('rbd')]
+        return sorted(pool_names)
+
+    def _health_status(self):
+        health_data = self.mgr.get("health")
+        return json.loads(health_data["json"])['status']
+
+    def _filesystems(self):
+        fsmap = self.mgr.get("fs_map")
+        return [
+            {
+                "id": f['id'],
+                "name": f['mdsmap']['fs_name']
+            }
+            for f in fsmap['filesystems']
+        ]
+
+    @cherrypy.expose
+    @cherrypy.tools.json_out()
+    def default(self):
+        return {
+            'rbd_pools': self._rbd_pool_data(),
+            'health_status': self._health_status(),
+            'filesystems': self._filesystems(),
+            'mgr_id': self.mgr.get_mgr_id(),
+            'have_mon_connection': self.mgr.have_mon_connection()
+        }
index 6b33769a2f4a1922e2e3a45763224fcc18f54f77..1b7d6dfb2f166fdc8fa316737c4cf5ce44d382f3 100644 (file)
@@ -32,7 +32,7 @@
         <a i18n
            routerLink="/dashboard">
           <i class="fa fa-heartbeat fa-fw"
-             [ngStyle]="topLevelData?.health_status | healthColor"></i>
+             [ngStyle]="summaryData?.health_status | healthColor"></i>
           <span>Dashboard</span>
         </a>
       </li>
             class="dropdown-menu">
           <li routerLinkActive="active"
               class="tc_submenuitem tc_submenuitem_cephfs_fs"
-              *ngFor="let fs of topLevelData?.filesystems">
+              *ngFor="let fs of summaryData?.filesystems">
             <a i18n
                class="dropdown-item"
                routerLink="/cephfs/{{fs.id}}">{{ fs.name }}
             </a>
           </li>
           <li class="tc_submenuitem tc_submenuitem_cephfs_nofs"
-              *ngIf="topLevelData.filesystems.length === 0">
+              *ngIf="summaryData.filesystems.length === 0">
             <span i18n>There are no filesystems</span>
           </li>
         </ul>
index 37fae9d9e747e054e133a227cd8412d9a86431d1..70087338dadefc4603346353cab4e13de035637f 100644 (file)
@@ -1,5 +1,5 @@
 import { Component, OnInit } from '@angular/core';
-import { TopLevelService } from '../../../shared/services/top-level.service';
+import { SummaryService } from '../../../shared/services/summary.service';
 
 @Component({
   selector: 'cd-navigation',
@@ -7,14 +7,14 @@ import { TopLevelService } from '../../../shared/services/top-level.service';
   styleUrls: ['./navigation.component.scss']
 })
 export class NavigationComponent implements OnInit {
-  topLevelData: any;
+  summaryData: any;
   rbdPools: Array<any> = [];
 
-  constructor(private topLevelService: TopLevelService) {}
+  constructor(private summaryService: SummaryService) {}
 
   ngOnInit() {
-    this.topLevelService.topLevelData$.subscribe((data: any) => {
-      this.topLevelData = data;
+    this.summaryService.summaryData$.subscribe((data: any) => {
+      this.summaryData = data;
       this.rbdPools = data.rbd_pools;
     });
   }
index 2901b4b90e61b74c6d7164200f7ba07a2a5a9870..051f970ac6d453042e0a495b9a0e308f91167812 100644 (file)
@@ -3,14 +3,14 @@ import { NgModule } from '@angular/core';
 
 import { ConfigurationService } from './configuration.service';
 import { FormatterService } from './formatter.service';
+import { SummaryService } from './summary.service';
 import { TcmuIscsiService } from './tcmu-iscsi.service';
-import { TopLevelService } from './top-level.service';
 
 @NgModule({
   imports: [
     CommonModule
   ],
   declarations: [],
-  providers: [FormatterService, TopLevelService, TcmuIscsiService, ConfigurationService]
+  providers: [FormatterService, SummaryService, TcmuIscsiService, ConfigurationService]
 })
 export class ServicesModule { }
diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/summary.service.spec.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/summary.service.spec.ts
new file mode 100644 (file)
index 0000000..23af983
--- /dev/null
@@ -0,0 +1,21 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { inject, TestBed } from '@angular/core/testing';
+
+import { SharedModule } from '../shared.module';
+import { SummaryService } from './summary.service';
+
+describe('SummaryService', () => {
+  beforeEach(() => {
+    TestBed.configureTestingModule({
+      providers: [SummaryService],
+      imports: [HttpClientTestingModule, SharedModule]
+    });
+  });
+
+  it(
+    'should be created',
+    inject([SummaryService], (service: SummaryService) => {
+      expect(service).toBeTruthy();
+    })
+  );
+});
diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/summary.service.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/summary.service.ts
new file mode 100644 (file)
index 0000000..0bc4566
--- /dev/null
@@ -0,0 +1,31 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import { Subject } from 'rxjs/Subject';
+
+import { AuthStorageService } from './auth-storage.service';
+
+@Injectable()
+export class SummaryService {
+  // Observable sources
+  private summaryDataSource = new Subject();
+
+  // Observable streams
+  summaryData$ = this.summaryDataSource.asObservable();
+
+  constructor(private http: HttpClient, private authStorageService: AuthStorageService) {
+    this.refresh();
+  }
+
+  refresh() {
+    if (this.authStorageService.isLoggedIn()) {
+      this.http.get('/api/summary').subscribe(data => {
+        this.summaryDataSource.next(data);
+      });
+    }
+
+    setTimeout(() => {
+      this.refresh();
+    }, 5000);
+  }
+}
diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/top-level.service.spec.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/top-level.service.spec.ts
deleted file mode 100644 (file)
index 3962cb6..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-import { HttpClientTestingModule } from '@angular/common/http/testing';
-import { inject, TestBed } from '@angular/core/testing';
-
-import { SharedModule } from '../shared.module';
-import { TopLevelService } from './top-level.service';
-
-describe('TopLevelService', () => {
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      providers: [TopLevelService],
-      imports: [HttpClientTestingModule, SharedModule]
-    });
-  });
-
-  it(
-    'should be created',
-    inject([TopLevelService], (service: TopLevelService) => {
-      expect(service).toBeTruthy();
-    })
-  );
-});
diff --git a/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/top-level.service.ts b/src/pybind/mgr/dashboard_v2/frontend/src/app/shared/services/top-level.service.ts
deleted file mode 100644 (file)
index 5df5ee9..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-import { HttpClient } from '@angular/common/http';
-import { Injectable } from '@angular/core';
-
-import { Subject } from 'rxjs/Subject';
-
-import { AuthStorageService } from './auth-storage.service';
-
-@Injectable()
-export class TopLevelService {
-  // Observable sources
-  private topLevelDataSource = new Subject();
-
-  // Observable streams
-  topLevelData$ = this.topLevelDataSource.asObservable();
-
-  constructor(private http: HttpClient, private authStorageService: AuthStorageService) {
-    this.refresh();
-  }
-
-  refresh() {
-    if (this.authStorageService.isLoggedIn()) {
-      this.http.get('/api/dashboard/toplevel').subscribe(data => {
-        this.topLevelDataSource.next(data);
-      });
-    }
-
-    setTimeout(() => {
-      this.refresh();
-    }, 5000);
-  }
-}
index 739cb24bf8d5021b8996ad940384adb61e5e3236..833ebd542a963b0f995b45273ea1b83a10fef2a4 100644 (file)
@@ -6,18 +6,6 @@ from .helper import ControllerTestCase, authenticate
 
 class DashboardTest(ControllerTestCase):
 
-    @authenticate
-    def test_toplevel(self):
-        data = self._get("/api/dashboard/toplevel")
-        self.assertStatus(200)
-
-        self.assertIn('filesystems', data)
-        self.assertIn('health_status', data)
-        self.assertIn('rbd_pools', data)
-        self.assertIsNotNone(data['filesystems'])
-        self.assertIsNotNone(data['health_status'])
-        self.assertIsNotNone(data['rbd_pools'])
-
     @authenticate
     def test_health(self):
         data = self._get("/api/dashboard/health")
diff --git a/src/pybind/mgr/dashboard_v2/tests/test_summary.py b/src/pybind/mgr/dashboard_v2/tests/test_summary.py
new file mode 100644 (file)
index 0000000..91a9f7a
--- /dev/null
@@ -0,0 +1,20 @@
+from dashboard_v2.tests.helper import ControllerTestCase, authenticate
+
+
+class SummaryTest(ControllerTestCase):
+
+    @authenticate
+    def test_summary(self):
+        data = self._get("/api/summary")
+        self.assertStatus(200)
+
+        self.assertIn('filesystems', data)
+        self.assertIn('health_status', data)
+        self.assertIn('rbd_pools', data)
+        self.assertIn('mgr_id', data)
+        self.assertIn('have_mon_connection', data)
+        self.assertIsNotNone(data['filesystems'])
+        self.assertIsNotNone(data['health_status'])
+        self.assertIsNotNone(data['rbd_pools'])
+        self.assertIsNotNone(data['mgr_id'])
+        self.assertIsNotNone(data['have_mon_connection'])