diff --git a/cinderclient/tests/v2/fakes.py b/cinderclient/tests/v2/fakes.py index e224c3cfd..bba9faa83 100644 --- a/cinderclient/tests/v2/fakes.py +++ b/cinderclient/tests/v2/fakes.py @@ -956,11 +956,22 @@ class FakeHTTPClient(base_client.HTTPClient): return (202, {}, {}) def get_scheduler_stats_get_pools(self, **kw): - return (200, {}, { - "pools": [ - {"name": "test1@backend1#pool", - "capabilities": { - "pool_name": "pool", - "volume_backend_name": "backend", - "storage_protocol": "iSCSI"}}] - }) + stats = [ + { + "name": "ubuntu@lvm#backend_name", + "capabilities": { + "pool_name": "backend_name", + "QoS_support": False, + "timestamp": "2014-11-21T18:15:28.141161", + "allocated_capacity_gb": 0, + "volume_backend_name": "backend_name", + "free_capacity_gb": 7.01, + "driver_version": "2.0.0", + "total_capacity_gb": 10.01, + "reserved_percentage": 0, + "vendor_name": "Open Source", + "storage_protocol": "iSCSI", + } + }, + ] + return (200, {}, {"pools": stats}) diff --git a/cinderclient/tests/v2/test_pools.py b/cinderclient/tests/v2/test_pools.py new file mode 100644 index 000000000..79e417d60 --- /dev/null +++ b/cinderclient/tests/v2/test_pools.py @@ -0,0 +1,44 @@ +# Copyright (C) 2015 Hewlett-Packard Development Company, L.P. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from cinderclient.v2.pools import Pool +from cinderclient.tests import utils +from cinderclient.tests.v2 import fakes + +cs = fakes.FakeClient() + + +class PoolsTest(utils.TestCase): + + def test_get_pool_stats(self): + sl = cs.pools.list() + cs.assert_called('GET', '/scheduler-stats/get_pools') + for s in sl: + self.assertIsInstance(s, Pool) + self.assertTrue(hasattr(s, "name")) + self.assertFalse(hasattr(s, "capabilities")) + # basic list should not have volume_backend_name (or any other + # entries from capabilities) + self.assertFalse(hasattr(s, "volume_backend_name")) + + def test_get_detail_pool_stats(self): + sl = cs.pools.list(detailed=True) + cs.assert_called('GET', '/scheduler-stats/get_pools?detail=True') + for s in sl: + self.assertIsInstance(s, Pool) + self.assertTrue(hasattr(s, "name")) + self.assertFalse(hasattr(s, "capabilities")) + # detail list should have a volume_backend_name (from capabilities) + self.assertTrue(hasattr(s, "volume_backend_name")) diff --git a/cinderclient/v2/client.py b/cinderclient/v2/client.py index 88d51ceec..1cf805e01 100644 --- a/cinderclient/v2/client.py +++ b/cinderclient/v2/client.py @@ -18,6 +18,7 @@ from cinderclient.v2 import availability_zones from cinderclient.v2 import cgsnapshots from cinderclient.v2 import consistencygroups from cinderclient.v2 import limits +from cinderclient.v2 import pools from cinderclient.v2 import qos_specs from cinderclient.v2 import quota_classes from cinderclient.v2 import quotas @@ -75,6 +76,7 @@ class Client(object): self.cgsnapshots = cgsnapshots.CgsnapshotManager(self) self.availability_zones = \ availability_zones.AvailabilityZoneManager(self) + self.pools = pools.PoolManager(self) # Add in any extensions... if extensions: diff --git a/cinderclient/v2/pools.py b/cinderclient/v2/pools.py new file mode 100644 index 000000000..608e057d0 --- /dev/null +++ b/cinderclient/v2/pools.py @@ -0,0 +1,62 @@ +# Copyright (C) 2015 Hewlett-Packard Development Company, L.P. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Pools interface (v2 extension)""" + +import six + +from cinderclient import base + + +class Pool(base.Resource): + NAME_ATTR = 'name' + + def __repr__(self): + return "" % self.name + + +class PoolManager(base.Manager): + """Manage :class:`Pool` resources.""" + resource_class = Pool + + def list(self, detailed=False): + """Lists all + + :rtype: list of :class:`Pool` + """ + if detailed is True: + pools = self._list("/scheduler-stats/get_pools?detail=True", + "pools") + # Other than the name, all of the pool data is buried below in + # a 'capabilities' dictionary. In order to be consistent with the + # get-pools command line, these elements are moved up a level to + # be attributes of the pool itself. + for pool in pools: + if hasattr(pool, 'capabilities'): + for k, v in six.iteritems(pool.capabilities): + setattr(pool, k, v) + + # Remove the capabilities dictionary since all of its + # elements have been copied up to the containing pool + del pool.capabilities + return pools + else: + pools = self._list("/scheduler-stats/get_pools", "pools") + + # avoid cluttering the basic pool list with capabilities dict + for pool in pools: + if hasattr(pool, 'capabilities'): + del pool.capabilities + return pools