Expose cinder's scheduler pool API

Make the scheduler pool API available to other clients.

DocImpact
Change-Id: I3f0e0c2ed806b5bfda3129ed2c5b210b9210daa5
Partially-Implements: blueprint get-volume-type-extra-specs
This commit is contained in:
Gary W. Smith 2014-12-04 15:47:44 -08:00
parent fdf6fd1d67
commit e5779d352b
4 changed files with 127 additions and 8 deletions

View File

@ -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})

View File

@ -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"))

View File

@ -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:

62
cinderclient/v2/pools.py Normal file
View File

@ -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 "<Pool: %s>" % 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