mgr/dashboard: Pool controller implementation and tests
authorRicardo Dias <rdias@suse.com>
Fri, 9 Mar 2018 16:44:34 +0000 (16:44 +0000)
committerRicardo Dias <rdias@suse.com>
Mon, 12 Mar 2018 11:43:48 +0000 (11:43 +0000)
Signed-off-by: Ricardo Dias <rdias@suse.com>
qa/suites/rados/mgr/tasks/dashboard_v2.yaml
qa/tasks/mgr/dashboard_v2/test_pool.py [new file with mode: 0644]
src/pybind/mgr/dashboard_v2/controllers/pool.py [new file with mode: 0644]

index be3ffc62985af1b61974fc3d7880377e3e2328d5..cd5e347a8bb40af839920400c464081c86815cba 100644 (file)
@@ -31,3 +31,4 @@ tasks:
         - tasks.mgr.dashboard_v2.test_summary
         - tasks.mgr.dashboard_v2.test_rgw
         - tasks.mgr.dashboard_v2.test_rbd
+        - tasks.mgr.dashboard_v2.test_pool
diff --git a/qa/tasks/mgr/dashboard_v2/test_pool.py b/qa/tasks/mgr/dashboard_v2/test_pool.py
new file mode 100644 (file)
index 0000000..6852ddb
--- /dev/null
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import
+
+from .helper import DashboardTestCase, authenticate
+
+
+class DashboardTest(DashboardTestCase):
+    @authenticate
+    def test_pool_list(self):
+        data = self._get("/api/pool")
+        self.assertStatus(200)
+
+        cluster_pools = self.ceph_cluster.mon_manager.list_pools()
+        self.assertEqual(len(cluster_pools), len(data))
+        for pool in data:
+            self.assertIn('pool_name', pool)
+            self.assertIn('type', pool)
+            self.assertIn('flags', pool)
+            self.assertIn('flags_names', pool)
+            self.assertNotIn('stats', pool)
+            self.assertIn(pool['pool_name'], cluster_pools)
+
+    @authenticate
+    def test_pool_list_attrs(self):
+        data = self._get("/api/pool?attrs=type,flags")
+        self.assertStatus(200)
+
+        cluster_pools = self.ceph_cluster.mon_manager.list_pools()
+        self.assertEqual(len(cluster_pools), len(data))
+        for pool in data:
+            self.assertIn('pool_name', pool)
+            self.assertIn('type', pool)
+            self.assertIn('flags', pool)
+            self.assertNotIn('flags_names', pool)
+            self.assertNotIn('stats', pool)
+            self.assertIn(pool['pool_name'], cluster_pools)
+
+    @authenticate
+    def test_pool_list_stats(self):
+        data = self._get("/api/pool?stats=true")
+        self.assertStatus(200)
+
+        cluster_pools = self.ceph_cluster.mon_manager.list_pools()
+        self.assertEqual(len(cluster_pools), len(data))
+        for pool in data:
+            self.assertIn('pool_name', pool)
+            self.assertIn('type', pool)
+            self.assertIn('flags', pool)
+            self.assertIn('stats', pool)
+            self.assertIn('flags_names', pool)
+            self.assertIn(pool['pool_name'], cluster_pools)
+
+    @authenticate
+    def test_pool_get(self):
+        cluster_pools = self.ceph_cluster.mon_manager.list_pools()
+        pool = self._get("/api/pool/{}?stats=true&attrs=type,flags,stats"
+                         .format(cluster_pools[0]))
+        self.assertEqual(pool['pool_name'], cluster_pools[0])
+        self.assertIn('type', pool)
+        self.assertIn('flags', pool)
+        self.assertIn('stats', pool)
+        self.assertNotIn('flags_names', pool)
diff --git a/src/pybind/mgr/dashboard_v2/controllers/pool.py b/src/pybind/mgr/dashboard_v2/controllers/pool.py
new file mode 100644 (file)
index 0000000..2eac9f5
--- /dev/null
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import
+
+from ..services.ceph_service import CephService
+from ..tools import ApiController, RESTController, AuthRequired
+
+
+@ApiController('pool')
+@AuthRequired()
+class Pool(RESTController):
+
+    @classmethod
+    def _serialize_pool(cls, pool, attrs):
+        if not attrs or not isinstance(attrs, list):
+            return pool
+
+        res = {}
+        for attr in attrs:
+            if attr not in pool:
+                continue
+            if attr == 'type':
+                res[attr] = {1: 'replicated', 3: 'erasure'}[pool[attr]]
+            else:
+                res[attr] = pool[attr]
+
+        # pool_name is mandatory
+        res['pool_name'] = pool['pool_name']
+        return res
+
+    @staticmethod
+    def _str_to_bool(var):
+        if isinstance(var, bool):
+            return var
+        return var.lower() in ("true", "yes", "1", 1)
+
+    def list(self, attrs=None, stats=False):
+        if attrs:
+            attrs = attrs.split(',')
+
+        if self._str_to_bool(stats):
+            pools = CephService.get_pool_list_with_stats()
+        else:
+            pools = CephService.get_pool_list()
+
+        return [self._serialize_pool(pool, attrs) for pool in pools]
+
+    def get(self, pool_name, attrs=None, stats=False):
+        pools = self.list(attrs, stats)
+        return [pool for pool in pools if pool['pool_name'] == pool_name][0]