diff --git a/doc/source/users/proxies/block_storage.rst b/doc/source/users/proxies/block_storage.rst index 460624151..ba9f7e355 100644 --- a/doc/source/users/proxies/block_storage.rst +++ b/doc/source/users/proxies/block_storage.rst @@ -41,3 +41,10 @@ Snapshot Operations .. automethod:: openstack.block_storage.v2._proxy.Proxy.delete_snapshot .. automethod:: openstack.block_storage.v2._proxy.Proxy.get_snapshot .. automethod:: openstack.block_storage.v2._proxy.Proxy.snapshots + +Stats Operations +^^^^^^^^^^^^^^^^^^^ + +.. autoclass:: openstack.block_storage.v2._proxy.Proxy + + .. automethod:: openstack.block_storage.v2._proxy.Proxy.backend_pools diff --git a/openstack/block_storage/v2/_proxy.py b/openstack/block_storage/v2/_proxy.py index 202a2d8a0..90bb623b3 100644 --- a/openstack/block_storage/v2/_proxy.py +++ b/openstack/block_storage/v2/_proxy.py @@ -11,6 +11,7 @@ # under the License. from openstack.block_storage.v2 import snapshot as _snapshot +from openstack.block_storage.v2 import stats as _stats from openstack.block_storage.v2 import type as _type from openstack.block_storage.v2 import volume as _volume from openstack import proxy2 @@ -187,3 +188,10 @@ class Proxy(proxy2.BaseProxy): :returns: ``None`` """ self._delete(_volume.Volume, volume, ignore_missing=ignore_missing) + + def backend_pools(self): + """Returns a generator of cinder Back-end storage pools + + :returns A generator of cinder Back-end storage pools objects + """ + return self._list(_stats.Pools, paginated=False) diff --git a/openstack/block_storage/v2/stats.py b/openstack/block_storage/v2/stats.py new file mode 100644 index 000000000..80a9c0b60 --- /dev/null +++ b/openstack/block_storage/v2/stats.py @@ -0,0 +1,34 @@ +# 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 openstack.block_storage import block_storage_service +from openstack import resource2 + + +class Pools(resource2.Resource): + resource_key = "pool" + resources_key = "pools" + base_path = "/scheduler-stats/get_pools?detail=True" + service = block_storage_service.BlockStorageService() + + # capabilities + allow_get = False + allow_create = False + allow_delete = False + allow_list = True + + # Properties + #: The Cinder name for the pool + name = resource2.Body("name") + #: returns a dict with information about the pool + capabilities = resource2.Body("capabilities", + type=dict) diff --git a/openstack/tests/functional/block_store/v2/test_stats.py b/openstack/tests/functional/block_store/v2/test_stats.py new file mode 100644 index 000000000..581f6e33e --- /dev/null +++ b/openstack/tests/functional/block_store/v2/test_stats.py @@ -0,0 +1,45 @@ +# 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 openstack.block_storage.v2 import stats as _stats +from openstack.tests.functional import base + + +class TestStats(base.BaseFunctionalTest): + + @classmethod + def setUpClass(cls): + super(TestStats, cls).setUpClass() + sot = cls.conn.block_storage.backend_pools() + for pool in sot: + assert isinstance(pool, _stats.Pools) + + def test_list(self): + capList = ['volume_backend_name', 'storage_protocol', + 'free_capacity_gb', 'driver_version', + 'goodness_function', 'QoS_support', + 'vendor_name', 'pool_name', 'thin_provisioning_support', + 'thick_provisioning_support', 'timestamp', + 'max_over_subscription_ratio', 'total_volumes', + 'total_capacity_gb', 'filter_function', + 'multiattach', 'provisioned_capacity_gb', + 'allocated_capacity_gb', 'reserved_percentage', + 'location_info'] + capList.sort() + pools = self.conn.block_storage.backend_pools() + for pool in pools: + caps = pool.capabilities + keys = caps.keys() + keys.sort() + assert isinstance(caps, dict) + self.assertListEqual(keys, capList) diff --git a/openstack/tests/unit/block_storage/v2/test_proxy.py b/openstack/tests/unit/block_storage/v2/test_proxy.py index 431b5f48a..ac616e89d 100644 --- a/openstack/tests/unit/block_storage/v2/test_proxy.py +++ b/openstack/tests/unit/block_storage/v2/test_proxy.py @@ -12,6 +12,7 @@ from openstack.block_storage.v2 import _proxy from openstack.block_storage.v2 import snapshot +from openstack.block_storage.v2 import stats from openstack.block_storage.v2 import type from openstack.block_storage.v2 import volume from openstack.tests.unit import test_proxy_base2 @@ -86,3 +87,7 @@ class TestVolumeProxy(test_proxy_base2.TestProxyBase): def test_volume_delete_ignore(self): self.verify_delete(self.proxy.delete_volume, volume.Volume, True) + + def test_backend_pools(self): + self.verify_list(self.proxy.backend_pools, stats.Pools, + paginated=False) diff --git a/openstack/tests/unit/block_store/v2/test_stats.py b/openstack/tests/unit/block_store/v2/test_stats.py new file mode 100644 index 000000000..a8991a81b --- /dev/null +++ b/openstack/tests/unit/block_store/v2/test_stats.py @@ -0,0 +1,47 @@ +# 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. + +import testtools + +from openstack.block_storage.v2 import stats + +POOLS = {"name": "pool1", + "capabilities": { + "updated": "2014-10-28T00=00=00-00=00", + "total_capacity": 1024, + "free_capacity": 100, + "volume_backend_name": "pool1", + "reserved_percentage": "0", + "driver_version": "1.0.0", + "storage_protocol": "iSCSI", + "QoS_support": "false" + } + } + + +class TestBackendPools(testtools.TestCase): + + def setUp(self): + super(TestBackendPools, self).setUp() + + def test_basic(self): + sot = stats.Pools(POOLS) + self.assertEqual("pool", sot.resource_key) + self.assertEqual("pools", sot.resources_key) + self.assertEqual("/scheduler-stats/get_pools?detail=True", + sot.base_path) + self.assertEqual("volume", sot.service.service_type) + self.assertFalse(sot.allow_create) + self.assertFalse(sot.allow_get) + self.assertFalse(sot.allow_delete) + self.assertTrue(sot.allow_list) + self.assertFalse(sot.allow_update)