Browse Source

Remove v2 classes

Remove all cinderclient.v2 classes, mostly incorporating them into
their v3 counterparts and updating the tests and test fixtures.

Depends-on: https://review.opendev.org/c/openstack/horizon/+/800814

Change-Id: I335db5c1799edb2273bf8bfc9e1bc9de404a4ba5
changes/59/792959/3
Brian Rosmaita 4 months ago
parent
commit
cb5235250c
  1. 16
      cinderclient/tests/unit/fixture_data/client.py
  2. 4
      cinderclient/tests/unit/test_base.py
  3. 1
      cinderclient/tests/unit/test_client.py
  4. 4
      cinderclient/tests/unit/test_utils.py
  5. 0
      cinderclient/tests/unit/v2/contrib/__init__.py
  6. 83
      cinderclient/tests/unit/v2/test_quotas.py
  7. 58
      cinderclient/tests/unit/v2/test_volume_transfers.py
  8. 0
      cinderclient/tests/unit/v3/contrib/__init__.py
  9. 4
      cinderclient/tests/unit/v3/contrib/test_list_extensions.py
  10. 38
      cinderclient/tests/unit/v3/fakes.py
  11. 14
      cinderclient/tests/unit/v3/fakes_base.py
  12. 2
      cinderclient/tests/unit/v3/test_auth.py
  13. 7
      cinderclient/tests/unit/v3/test_capabilities.py
  14. 5
      cinderclient/tests/unit/v3/test_cgsnapshots.py
  15. 5
      cinderclient/tests/unit/v3/test_consistencygroups.py
  16. 2
      cinderclient/tests/unit/v3/test_limits.py
  17. 8
      cinderclient/tests/unit/v3/test_pools.py
  18. 5
      cinderclient/tests/unit/v3/test_qos.py
  19. 5
      cinderclient/tests/unit/v3/test_quota_classes.py
  20. 63
      cinderclient/tests/unit/v3/test_quotas.py
  21. 8
      cinderclient/tests/unit/v3/test_services_base.py
  22. 2
      cinderclient/tests/unit/v3/test_shell.py
  23. 2
      cinderclient/tests/unit/v3/test_snapshot_actions.py
  24. 4
      cinderclient/tests/unit/v3/test_type_access.py
  25. 4
      cinderclient/tests/unit/v3/test_types.py
  26. 21
      cinderclient/tests/unit/v3/test_volume_backups.py
  27. 21
      cinderclient/tests/unit/v3/test_volume_backups_30.py
  28. 4
      cinderclient/tests/unit/v3/test_volume_encryption_types.py
  29. 19
      cinderclient/tests/unit/v3/test_volumes.py
  30. 35
      cinderclient/tests/unit/v3/test_volumes_base.py
  31. 17
      cinderclient/v2/__init__.py
  32. 41
      cinderclient/v2/availability_zones.py
  33. 38
      cinderclient/v2/capabilities.py
  34. 112
      cinderclient/v2/cgsnapshots.py
  35. 141
      cinderclient/v2/client.py
  36. 149
      cinderclient/v2/consistencygroups.py
  37. 0
      cinderclient/v2/contrib/__init__.py
  38. 44
      cinderclient/v2/contrib/list_extensions.py
  39. 99
      cinderclient/v2/limits.py
  40. 60
      cinderclient/v2/pools.py
  41. 155
      cinderclient/v2/qos_specs.py
  42. 47
      cinderclient/v2/quota_classes.py
  43. 56
      cinderclient/v2/quotas.py
  44. 80
      cinderclient/v2/services.py
  45. 137
      cinderclient/v2/volume_backups.py
  46. 44
      cinderclient/v2/volume_backups_restore.py
  47. 104
      cinderclient/v2/volume_encryption_types.py
  48. 39
      cinderclient/v2/volume_snapshots.py
  49. 88
      cinderclient/v2/volume_transfers.py
  50. 53
      cinderclient/v2/volume_type_access.py
  51. 153
      cinderclient/v2/volume_types.py
  52. 22
      cinderclient/v3/capabilities.py
  53. 96
      cinderclient/v3/cgsnapshots.py
  54. 133
      cinderclient/v3/consistencygroups.py
  55. 30
      cinderclient/v3/contrib/list_extensions.py
  56. 84
      cinderclient/v3/limits.py
  57. 44
      cinderclient/v3/pools.py
  58. 136
      cinderclient/v3/qos_specs.py
  59. 33
      cinderclient/v3/quota_classes.py
  60. 31
      cinderclient/v3/quotas.py
  61. 63
      cinderclient/v3/services.py
  62. 2
      cinderclient/v3/shell_base.py
  63. 91
      cinderclient/v3/volume_backups.py
  64. 25
      cinderclient/v3/volume_backups_restore.py
  65. 86
      cinderclient/v3/volume_encryption_types.py
  66. 12
      cinderclient/v3/volume_snapshots.py
  67. 17
      cinderclient/v3/volume_transfers.py
  68. 38
      cinderclient/v3/volume_type_access.py
  69. 20
      cinderclient/v3/volumes.py
  70. 88
      cinderclient/v3/volumes_base.py
  71. 4
      doc/source/contributor/unit_tests.rst
  72. 5
      releasenotes/notes/drop-v2-support-e578ca21c7c6b532.yaml

16
cinderclient/tests/unit/fixture_data/client.py

@ -13,7 +13,6 @@
from keystoneauth1 import fixture
from cinderclient.tests.unit.fixture_data import base
from cinderclient.v2 import client as v2client
from cinderclient.v3 import client as v3client
@ -34,21 +33,6 @@ class Base(base.Fixture):
headers=self.json_headers)
class V2(Base):
def __init__(self, *args, **kwargs):
super(V2, self).__init__(*args, **kwargs)
svc = self.token.add_service('volumev2')
svc.add_endpoint(self.volume_url)
def new_client(self):
return v2client.Client(username='xx',
api_key='xx',
project_id='xx',
auth_url=self.identity_url)
class V3(Base):
def __init__(self, *args, **kwargs):

4
cinderclient/tests/unit/test_base.py

@ -22,13 +22,13 @@ from cinderclient import base
from cinderclient import exceptions
from cinderclient.tests.unit import test_utils
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.tests.unit.v3 import fakes
from cinderclient.v3 import client
from cinderclient.v3 import volumes
cs = fakes.FakeClient()
REQUEST_ID = 'req-test-request-id'
REQUEST_ID = test_utils.REQUEST_ID
def create_response_obj_with_header():

1
cinderclient/tests/unit/test_client.py

@ -26,7 +26,6 @@ import cinderclient.client
from cinderclient import exceptions
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v3 import fakes
import cinderclient.v2.client
@ddt.ddt

4
cinderclient/tests/unit/test_utils.py

@ -24,9 +24,9 @@ from cinderclient import base
from cinderclient import exceptions
from cinderclient import shell_utils
from cinderclient.tests.unit import utils as test_utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient import utils
REQUEST_ID = 'req-test-request-id'
UUID = '8e8ec658-c7b0-4243-bdf8-6f7f2952c0d0'
@ -61,7 +61,7 @@ class FakeManager(base.ManagerWithFind):
raise exceptions.NotFound(resource_id)
def list(self, search_opts, **kwargs):
return common_base.ListWithMeta(self.resources, fakes.REQUEST_ID)
return common_base.ListWithMeta(self.resources, REQUEST_ID)
class FakeManagerWithApi(base.Manager):

0
cinderclient/tests/unit/v2/contrib/__init__.py

83
cinderclient/tests/unit/v2/test_quotas.py

@ -1,83 +0,0 @@
# Copyright (c) 2013 OpenStack Foundation
# 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.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
cs = fakes.FakeClient()
class QuotaSetsTest(utils.TestCase):
def test_tenant_quotas_get(self):
tenant_id = 'test'
quota = cs.quotas.get(tenant_id)
cs.assert_called('GET', '/os-quota-sets/%s?usage=False' % tenant_id)
self._assert_request_id(quota)
def test_tenant_quotas_defaults(self):
tenant_id = 'test'
quota = cs.quotas.defaults(tenant_id)
cs.assert_called('GET', '/os-quota-sets/%s/defaults' % tenant_id)
self._assert_request_id(quota)
def test_update_quota(self):
q = cs.quotas.get('test')
q.update(volumes=2)
q.update(snapshots=2)
q.update(gigabytes=2000)
q.update(backups=2)
q.update(backup_gigabytes=2000)
q.update(per_volume_gigabytes=100)
cs.assert_called('PUT', '/os-quota-sets/test')
self._assert_request_id(q)
def test_refresh_quota(self):
q = cs.quotas.get('test')
q2 = cs.quotas.get('test')
self.assertEqual(q.volumes, q2.volumes)
self.assertEqual(q.snapshots, q2.snapshots)
self.assertEqual(q.gigabytes, q2.gigabytes)
self.assertEqual(q.backups, q2.backups)
self.assertEqual(q.backup_gigabytes, q2.backup_gigabytes)
self.assertEqual(q.per_volume_gigabytes, q2.per_volume_gigabytes)
q2.volumes = 0
self.assertNotEqual(q.volumes, q2.volumes)
q2.snapshots = 0
self.assertNotEqual(q.snapshots, q2.snapshots)
q2.gigabytes = 0
self.assertNotEqual(q.gigabytes, q2.gigabytes)
q2.backups = 0
self.assertNotEqual(q.backups, q2.backups)
q2.backup_gigabytes = 0
self.assertNotEqual(q.backup_gigabytes, q2.backup_gigabytes)
q2.per_volume_gigabytes = 0
self.assertNotEqual(q.per_volume_gigabytes, q2.per_volume_gigabytes)
q2.get()
self.assertEqual(q.volumes, q2.volumes)
self.assertEqual(q.snapshots, q2.snapshots)
self.assertEqual(q.gigabytes, q2.gigabytes)
self.assertEqual(q.backups, q2.backups)
self.assertEqual(q.backup_gigabytes, q2.backup_gigabytes)
self.assertEqual(q.per_volume_gigabytes, q2.per_volume_gigabytes)
self._assert_request_id(q)
self._assert_request_id(q2)
def test_delete_quota(self):
tenant_id = 'test'
quota = cs.quotas.delete(tenant_id)
cs.assert_called('DELETE', '/os-quota-sets/test')
self._assert_request_id(quota)

58
cinderclient/tests/unit/v2/test_volume_transfers.py

@ -1,58 +0,0 @@
# Copyright (C) 2013 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.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
cs = fakes.FakeClient()
class VolumeTransfersTest(utils.TestCase):
def test_create(self):
vol = cs.transfers.create('1234')
cs.assert_called('POST', '/os-volume-transfer')
self._assert_request_id(vol)
def test_get(self):
transfer_id = '5678'
vol = cs.transfers.get(transfer_id)
cs.assert_called('GET', '/os-volume-transfer/%s' % transfer_id)
self._assert_request_id(vol)
def test_list(self):
lst = cs.transfers.list()
cs.assert_called('GET', '/os-volume-transfer/detail')
self._assert_request_id(lst)
def test_delete(self):
b = cs.transfers.list()[0]
vol = b.delete()
cs.assert_called('DELETE', '/os-volume-transfer/5678')
self._assert_request_id(vol)
vol = cs.transfers.delete('5678')
self._assert_request_id(vol)
cs.assert_called('DELETE', '/os-volume-transfer/5678')
vol = cs.transfers.delete(b)
cs.assert_called('DELETE', '/os-volume-transfer/5678')
self._assert_request_id(vol)
def test_accept(self):
transfer_id = '5678'
auth_key = '12345'
vol = cs.transfers.accept(transfer_id, auth_key)
cs.assert_called('POST', '/os-volume-transfer/%s/accept' % transfer_id)
self._assert_request_id(vol)

0
cinderclient/tests/unit/v2/__init__.py → cinderclient/tests/unit/v3/contrib/__init__.py

4
cinderclient/tests/unit/v2/contrib/test_list_extensions.py → cinderclient/tests/unit/v3/contrib/test_list_extensions.py

@ -16,8 +16,8 @@
from cinderclient import extension
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.v2.contrib import list_extensions
from cinderclient.tests.unit.v3 import fakes
from cinderclient.v3.contrib import list_extensions
extensions = [
extension.Extension(list_extensions.__name__.split(".")[-1],

38
cinderclient/tests/unit/v3/fakes.py

@ -15,7 +15,7 @@
from datetime import datetime
from cinderclient.tests.unit import fakes
from cinderclient.tests.unit.v2 import fakes as fake_v2
from cinderclient.tests.unit.v3 import fakes_base
from cinderclient.v3 import client
@ -133,7 +133,7 @@ class FakeClient(fakes.FakeClient, client.Client):
return self.client.get_volume_api_version_from_endpoint()
class FakeHTTPClient(fake_v2.FakeHTTPClient):
class FakeHTTPClient(fakes_base.FakeHTTPClient):
def __init__(self, **kwargs):
super(FakeHTTPClient, self).__init__()
@ -194,6 +194,19 @@ class FakeHTTPClient(fake_v2.FakeHTTPClient):
del svc['backend_state']
return (200, {}, {'services': services})
def put_os_services_enable(self, body, **kw):
return (200, {}, {'host': body['host'], 'binary': body['binary'],
'status': 'enabled'})
def put_os_services_disable(self, body, **kw):
return (200, {}, {'host': body['host'], 'binary': body['binary'],
'status': 'disabled'})
def put_os_services_disable_log_reason(self, body, **kw):
return (200, {}, {'host': body['host'], 'binary': body['binary'],
'status': 'disabled',
'disabled_reason': body['disabled_reason']})
#
# Clusters
#
@ -285,7 +298,7 @@ class FakeHTTPClient(fake_v2.FakeHTTPClient):
# Backups
#
def put_backups_1234(self, **kw):
backup = fake_v2._stub_backup(
backup = fakes_base._stub_backup(
id='1234',
base_uri='http://localhost:8776',
tenant_id='0fa851f6668144cf9cd8c8419c1646c1')
@ -640,10 +653,10 @@ class FakeHTTPClient(fake_v2.FakeHTTPClient):
transfer2 = 'f625ec3e-13dd-4498-a22a-50afd534cc41'
return (200, {},
{'transfers': [
fake_v2._stub_transfer_full(transfer1, base_uri,
tenant_id),
fake_v2._stub_transfer_full(transfer2, base_uri,
tenant_id)]})
fakes_base._stub_transfer_full(transfer1, base_uri,
tenant_id),
fakes_base._stub_transfer_full(transfer2, base_uri,
tenant_id)]})
def get_volume_transfers_5678(self, **kw):
base_uri = 'http://localhost:8776'
@ -651,7 +664,8 @@ class FakeHTTPClient(fake_v2.FakeHTTPClient):
transfer1 = '5678'
return (200, {},
{'transfer':
fake_v2._stub_transfer_full(transfer1, base_uri, tenant_id)})
fakes_base._stub_transfer_full(transfer1, base_uri,
tenant_id)})
def delete_volume_transfers_5678(self, **kw):
return (202, {}, None)
@ -661,16 +675,16 @@ class FakeHTTPClient(fake_v2.FakeHTTPClient):
tenant_id = '0fa851f6668144cf9cd8c8419c1646c1'
transfer1 = '5678'
return (202, {},
{'transfer': fake_v2._stub_transfer(transfer1, base_uri,
tenant_id)})
{'transfer': fakes_base._stub_transfer(transfer1, base_uri,
tenant_id)})
def post_volume_transfers_5678_accept(self, **kw):
base_uri = 'http://localhost:8776'
tenant_id = '0fa851f6668144cf9cd8c8419c1646c1'
transfer1 = '5678'
return (200, {},
{'transfer': fake_v2._stub_transfer(transfer1, base_uri,
tenant_id)})
{'transfer': fakes_base._stub_transfer(transfer1, base_uri,
tenant_id)})
def fake_request_get():

14
cinderclient/tests/unit/v2/fakes.py → cinderclient/tests/unit/v3/fakes_base.py

@ -18,7 +18,6 @@ from urllib import parse as urlparse
from cinderclient import client as base_client
from cinderclient.tests.unit import fakes
import cinderclient.tests.unit.utils as utils
from cinderclient.v2 import client
REQUEST_ID = 'req-test-request-id'
@ -332,19 +331,6 @@ def stub_default_types():
}
class FakeClient(fakes.FakeClient, client.Client):
def __init__(self, api_version=None, *args, **kwargs):
client.Client.__init__(self, 'username', 'password',
'project_id', 'auth_url',
extensions=kwargs.get('extensions'))
self.api_version = api_version
self.client = FakeHTTPClient(**kwargs)
def get_volume_api_version_from_endpoint(self):
return self.client.get_volume_api_version_from_endpoint()
class FakeHTTPClient(base_client.HTTPClient):
def __init__(self, version_header=None, **kwargs):

2
cinderclient/tests/unit/v2/test_auth.py → cinderclient/tests/unit/v3/test_auth.py

@ -21,7 +21,7 @@ import requests
from cinderclient import exceptions
from cinderclient.tests.unit import utils
from cinderclient.v2 import client
from cinderclient.v3 import client
class AuthenticateAgainstKeystoneTests(utils.TestCase):

7
cinderclient/tests/unit/v2/test_capabilities.py → cinderclient/tests/unit/v3/test_capabilities.py

@ -13,11 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
from cinderclient import api_versions
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.v2.capabilities import Capabilities
from cinderclient.tests.unit.v3 import fakes
from cinderclient.v3.capabilities import Capabilities
cs = fakes.FakeClient()
cs = fakes.FakeClient(api_versions.APIVersion('3.0'))
FAKE_CAPABILITY = {
'namespace': 'OS::Storage::Capabilities::fake',

5
cinderclient/tests/unit/v2/test_cgsnapshots.py → cinderclient/tests/unit/v3/test_cgsnapshots.py

@ -14,11 +14,12 @@
# License for the specific language governing permissions and limitations
# under the License.
from cinderclient import api_versions
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.tests.unit.v3 import fakes
cs = fakes.FakeClient()
cs = fakes.FakeClient(api_versions.APIVersion('3.0'))
class cgsnapshotsTest(utils.TestCase):

5
cinderclient/tests/unit/v2/test_consistencygroups.py → cinderclient/tests/unit/v3/test_consistencygroups.py

@ -14,10 +14,11 @@
# License for the specific language governing permissions and limitations
# under the License.
from cinderclient import api_versions
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.tests.unit.v3 import fakes
cs = fakes.FakeClient()
cs = fakes.FakeClient(api_versions.APIVersion('3.0'))
class ConsistencygroupsTest(utils.TestCase):

2
cinderclient/tests/unit/v2/test_limits.py → cinderclient/tests/unit/v3/test_limits.py

@ -18,7 +18,7 @@ from unittest import mock
import ddt
from cinderclient.tests.unit import utils
from cinderclient.v2 import limits
from cinderclient.v3 import limits
REQUEST_ID = 'req-test-request-id'

8
cinderclient/tests/unit/v2/test_pools.py → cinderclient/tests/unit/v3/test_pools.py

@ -13,11 +13,13 @@
# License for the specific language governing permissions and limitations
# under the License.
from cinderclient import api_versions
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.v2.pools import Pool
from cinderclient.tests.unit.v3 import fakes
from cinderclient.v3.pools import Pool
cs = fakes.FakeClient()
cs = fakes.FakeClient(api_versions.APIVersion('3.0'))
class PoolsTest(utils.TestCase):

5
cinderclient/tests/unit/v2/test_qos.py → cinderclient/tests/unit/v3/test_qos.py

@ -13,11 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
from cinderclient import api_versions
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.tests.unit.v3 import fakes
cs = fakes.FakeClient()
cs = fakes.FakeClient(api_versions.APIVersion('3.0'))
class QoSSpecsTest(utils.TestCase):

5
cinderclient/tests/unit/v2/test_quota_classes.py → cinderclient/tests/unit/v3/test_quota_classes.py

@ -13,11 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
from cinderclient import api_versions
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.tests.unit.v3 import fakes
cs = fakes.FakeClient()
cs = fakes.FakeClient(api_versions.APIVersion('3.0'))
class QuotaClassSetsTest(utils.TestCase):

63
cinderclient/tests/unit/v3/test_quotas.py

@ -13,17 +13,78 @@
# License for the specific language governing permissions and limitations
# under the License.
from cinderclient import api_versions
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v3 import fakes
cs = fakes.FakeClient()
cs = fakes.FakeClient(api_versions.APIVersion('3.0'))
class QuotaSetsTest(utils.TestCase):
def test_tenant_quotas_get(self):
tenant_id = 'test'
quota = cs.quotas.get(tenant_id)
cs.assert_called('GET', '/os-quota-sets/%s?usage=False' % tenant_id)
self._assert_request_id(quota)
def test_tenant_quotas_defaults(self):
tenant_id = 'test'
quota = cs.quotas.defaults(tenant_id)
cs.assert_called('GET', '/os-quota-sets/%s/defaults' % tenant_id)
self._assert_request_id(quota)
def test_update_quota(self):
q = cs.quotas.get('test')
q.update(volumes=2)
q.update(snapshots=2)
q.update(gigabytes=2000)
q.update(backups=2)
q.update(backup_gigabytes=2000)
q.update(per_volume_gigabytes=100)
cs.assert_called('PUT', '/os-quota-sets/test')
self._assert_request_id(q)
def test_update_quota_with_skip_(self):
q = cs.quotas.get('test')
q.update(skip_validation=False)
cs.assert_called('PUT', '/os-quota-sets/test?skip_validation=False')
self._assert_request_id(q)
def test_refresh_quota(self):
q = cs.quotas.get('test')
q2 = cs.quotas.get('test')
self.assertEqual(q.volumes, q2.volumes)
self.assertEqual(q.snapshots, q2.snapshots)
self.assertEqual(q.gigabytes, q2.gigabytes)
self.assertEqual(q.backups, q2.backups)
self.assertEqual(q.backup_gigabytes, q2.backup_gigabytes)
self.assertEqual(q.per_volume_gigabytes, q2.per_volume_gigabytes)
q2.volumes = 0
self.assertNotEqual(q.volumes, q2.volumes)
q2.snapshots = 0
self.assertNotEqual(q.snapshots, q2.snapshots)
q2.gigabytes = 0
self.assertNotEqual(q.gigabytes, q2.gigabytes)
q2.backups = 0
self.assertNotEqual(q.backups, q2.backups)
q2.backup_gigabytes = 0
self.assertNotEqual(q.backup_gigabytes, q2.backup_gigabytes)
q2.per_volume_gigabytes = 0
self.assertNotEqual(q.per_volume_gigabytes, q2.per_volume_gigabytes)
q2.get()
self.assertEqual(q.volumes, q2.volumes)
self.assertEqual(q.snapshots, q2.snapshots)
self.assertEqual(q.gigabytes, q2.gigabytes)
self.assertEqual(q.backups, q2.backups)
self.assertEqual(q.backup_gigabytes, q2.backup_gigabytes)
self.assertEqual(q.per_volume_gigabytes, q2.per_volume_gigabytes)
self._assert_request_id(q)
self._assert_request_id(q2)
def test_delete_quota(self):
tenant_id = 'test'
quota = cs.quotas.delete(tenant_id)
cs.assert_called('DELETE', '/os-quota-sets/test')
self._assert_request_id(quota)

8
cinderclient/tests/unit/v2/test_services.py → cinderclient/tests/unit/v3/test_services_base.py

@ -13,15 +13,17 @@
# License for the specific language governing permissions and limitations
# under the License.
from cinderclient import api_versions
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.v2 import services
from cinderclient.tests.unit.v3 import fakes
from cinderclient.v3 import services
cs = fakes.FakeClient()
cs = fakes.FakeClient(api_version=api_versions.APIVersion('3.0'))
class ServicesTest(utils.TestCase):
"""Tests for v3.0 behavior"""
def test_list_services(self):
svs = cs.services.list()

2
cinderclient/tests/unit/v3/test_shell.py

@ -1745,7 +1745,7 @@ class ShellTest(utils.TestCase):
)
@ddt.unpack
@mock.patch('cinderclient.utils.print_dict')
@mock.patch('cinderclient.tests.unit.v2.fakes._stub_restore')
@mock.patch('cinderclient.tests.unit.v3.fakes_base._stub_restore')
def test_do_backup_restore(self,
mock_stub_restore,
mock_print_dict,

2
cinderclient/tests/unit/v2/test_snapshot_actions.py → cinderclient/tests/unit/v3/test_snapshot_actions.py

@ -20,7 +20,7 @@ from cinderclient.tests.unit import utils
class SnapshotActionsTest(utils.FixturedTestCase):
client_fixture_class = client.V2
client_fixture_class = client.V3
data_fixture_class = snapshots.Fixture
def test_update_snapshot_status(self):

4
cinderclient/tests/unit/v2/test_type_access.py → cinderclient/tests/unit/v3/test_type_access.py

@ -15,8 +15,8 @@
# under the License.
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.v2 import volume_type_access
from cinderclient.tests.unit.v3 import fakes
from cinderclient.v3 import volume_type_access
cs = fakes.FakeClient()

4
cinderclient/tests/unit/v2/test_types.py → cinderclient/tests/unit/v3/test_types.py

@ -15,8 +15,8 @@
# under the License.
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.v2 import volume_types
from cinderclient.tests.unit.v3 import fakes
from cinderclient.v3 import volume_types
cs = fakes.FakeClient()

21
cinderclient/tests/unit/v3/test_volume_backups.py

@ -17,6 +17,7 @@ from cinderclient import api_versions
from cinderclient import exceptions as exc
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v3 import fakes
from cinderclient.v3 import volume_backups_restore
class VolumesTest(utils.TestCase):
@ -35,3 +36,23 @@ class VolumesTest(utils.TestCase):
b = cs.backups.get('1234')
self.assertRaises(exc.VersionNotFoundForAPIMethod,
b.update, name='new-name')
def test_restore(self):
cs = fakes.FakeClient(api_version=api_versions.APIVersion('3.0'))
backup_id = '76a17945-3c6f-435c-975b-b5685db10b62'
info = cs.restores.restore(backup_id)
cs.assert_called('POST', '/backups/%s/restore' % backup_id)
self.assertIsInstance(info,
volume_backups_restore.VolumeBackupsRestore)
self._assert_request_id(info)
def test_restore_with_name(self):
cs = fakes.FakeClient(api_version=api_versions.APIVersion('3.0'))
backup_id = '76a17945-3c6f-435c-975b-b5685db10b62'
name = 'restore_vol'
info = cs.restores.restore(backup_id, name=name)
expected_body = {'restore': {'volume_id': None, 'name': name}}
cs.assert_called('POST', '/backups/%s/restore' % backup_id,
body=expected_body)
self.assertIsInstance(info,
volume_backups_restore.VolumeBackupsRestore)

21
cinderclient/tests/unit/v2/test_volume_backups.py → cinderclient/tests/unit/v3/test_volume_backups_30.py

@ -14,8 +14,7 @@
# under the License.
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.v2 import volume_backups_restore
from cinderclient.tests.unit.v3 import fakes
cs = fakes.FakeClient()
@ -118,24 +117,6 @@ class VolumeBackupsTest(utils.TestCase):
'/backups/76a17945-3c6f-435c-975b-b5685db10b62')
self._assert_request_id(del_back)
def test_restore(self):
backup_id = '76a17945-3c6f-435c-975b-b5685db10b62'
info = cs.restores.restore(backup_id)
cs.assert_called('POST', '/backups/%s/restore' % backup_id)
self.assertIsInstance(info,
volume_backups_restore.VolumeBackupsRestore)
self._assert_request_id(info)
def test_restore_with_name(self):
backup_id = '76a17945-3c6f-435c-975b-b5685db10b62'
name = 'restore_vol'
info = cs.restores.restore(backup_id, name=name)
expected_body = {'restore': {'volume_id': None, 'name': name}}
cs.assert_called('POST', '/backups/%s/restore' % backup_id,
body=expected_body)
self.assertIsInstance(info,
volume_backups_restore.VolumeBackupsRestore)
def test_reset_state(self):
b = cs.backups.list()[0]
api = '/backups/76a17945-3c6f-435c-975b-b5685db10b62/action'

4
cinderclient/tests/unit/v2/test_volume_encryption_types.py → cinderclient/tests/unit/v3/test_volume_encryption_types.py

@ -14,8 +14,8 @@
# under the License.
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.v2.volume_encryption_types import VolumeEncryptionType
from cinderclient.tests.unit.v3 import fakes
from cinderclient.v3.volume_encryption_types import VolumeEncryptionType
cs = fakes.FakeClient()

19
cinderclient/tests/unit/v3/test_volumes.py

@ -87,6 +87,25 @@ class VolumesTest(utils.TestCase):
cs.assert_called('POST', '/volumes', body=expected)
self._assert_request_id(vol)
def test_create_volume_with_hint(self):
cs = fakes.FakeClient(api_versions.APIVersion('3.0'))
vol = cs.volumes.create(1, scheduler_hints='uuid')
expected = {'volume': {'description': None,
'availability_zone': None,
'source_volid': None,
'snapshot_id': None,
'size': 1,
'name': None,
'imageRef': None,
'volume_type': None,
'metadata': {},
'consistencygroup_id': None,
'backup_id': None,
},
'OS-SCH-HNT:scheduler_hints': 'uuid'}
cs.assert_called('POST', '/volumes', body=expected)
self._assert_request_id(vol)
@ddt.data((False, '/volumes/summary'),
(True, '/volumes/summary?all_tenants=True'))
def test_volume_summary(self, all_tenants_input):

35
cinderclient/tests/unit/v2/test_volumes.py → cinderclient/tests/unit/v3/test_volumes_base.py

@ -15,14 +15,16 @@
# License for the specific language governing permissions and limitations
# under the License.
from cinderclient import api_versions
from cinderclient.tests.unit import utils
from cinderclient.tests.unit.v2 import fakes
from cinderclient.v2.volumes import Volume
from cinderclient.tests.unit.v3 import fakes
from cinderclient.v3.volumes import Volume
cs = fakes.FakeClient()
cs = fakes.FakeClient(api_version=api_versions.APIVersion('3.0'))
class VolumesTest(utils.TestCase):
"""Block Storage API v3.0"""
def test_list_volumes_with_marker_limit(self):
lst = cs.volumes.list(marker=1234, limit=2)
@ -58,6 +60,11 @@ class VolumesTest(utils.TestCase):
self._assert_request_id(volumes)
cs.client.osapi_max_limit = 1000
def test_create_volume(self):
vol = cs.volumes.create(1)
cs.assert_called('POST', '/volumes')
self._assert_request_id(vol)
def test_delete_volume(self):
v = cs.volumes.list()[0]
del_v = v.delete()
@ -70,28 +77,6 @@ class VolumesTest(utils.TestCase):
cs.assert_called('DELETE', '/volumes/1234')
self._assert_request_id(del_v)
def test_create_volume(self):
vol = cs.volumes.create(1)
cs.assert_called('POST', '/volumes')
self._assert_request_id(vol)
def test_create_volume_with_hint(self):
vol = cs.volumes.create(1, scheduler_hints='uuid')
expected = {'volume': {'description': None,
'availability_zone': None,
'source_volid': None,
'snapshot_id': None,
'size': 1,
'name': None,
'imageRef': None,
'volume_type': None,
'metadata': {},
'consistencygroup_id': None,
},
'OS-SCH-HNT:scheduler_hints': 'uuid'}
cs.assert_called('POST', '/volumes', body=expected)
self._assert_request_id(vol)
def test_attach(self):
v = cs.volumes.get('1234')
self._assert_request_id(v)

17
cinderclient/v2/__init__.py

@ -1,17 +0,0 @@
# Copyright (c) 2013 OpenStack Foundation
#
# 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.client import Client # noqa

41
cinderclient/v2/availability_zones.py

@ -1,41 +0,0 @@
# Copyright 2011-2013 OpenStack Foundation
# Copyright 2013 IBM Corp.
# 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.
"""Availability Zone interface (v2 extension)"""
from cinderclient import base
class AvailabilityZone(base.Resource):
NAME_ATTR = 'display_name'
def __repr__(self):
return "<AvailabilityZone: %s>" % self.zoneName
class AvailabilityZoneManager(base.ManagerWithFind):
"""Manage :class:`AvailabilityZone` resources."""
resource_class = AvailabilityZone
def list(self, detailed=False):
"""Lists all availability zones.
:rtype: list of :class:`AvailabilityZone`
"""
if detailed is True:
return self._list("/os-availability-zone/detail",
"availabilityZoneInfo")
else:
return self._list("/os-availability-zone", "availabilityZoneInfo")

38
cinderclient/v2/capabilities.py

@ -1,38 +0,0 @@
# Copyright (c) 2015 Hitachi Data Systems, Inc.
# 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.
"""Capabilities interface (v2 extension)"""
from cinderclient import base
class Capabilities(base.Resource):
NAME_ATTR = 'name'
def __repr__(self):
return "<Capabilities: %s>" % self._info.get('namespace')
class CapabilitiesManager(base.Manager):
"""Manage :class:`Capabilities` resources."""
resource_class = Capabilities
def get(self, host):
"""Show backend volume stats and properties.
:param host: Specified backend to obtain volume stats and properties.
:rtype: :class:`Capabilities`
"""
return self._get('/capabilities/%s' % host, None)

112
cinderclient/v2/cgsnapshots.py

@ -1,112 +0,0 @@
# Copyright (C) 2012 - 2014 EMC Corporation.
# 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.
"""cgsnapshot interface (v2 extension)."""
from cinderclient.apiclient import base as common_base
from cinderclient import base
from cinderclient import utils
class Cgsnapshot(base.Resource):
"""A cgsnapshot is snapshot of a consistency group."""
def __repr__(self):
return "<cgsnapshot: %s>" % self.id
def delete(self):
"""Delete this cgsnapshot."""
return self.manager.delete(self)
def update(self, **kwargs):
"""Update the name or description for this cgsnapshot."""
return self.manager.update(self, **kwargs)
class CgsnapshotManager(base.ManagerWithFind):
"""Manage :class:`Cgsnapshot` resources."""
resource_class = Cgsnapshot
def create(self, consistencygroup_id, name=None, description=None,
user_id=None,
project_id=None):
"""Creates a cgsnapshot.
:param consistencygroup: Name or uuid of a consistency group
:param name: Name of the cgsnapshot
:param description: Description of the cgsnapshot
:param user_id: User id derived from context
:param project_id: Project id derived from context
:rtype: :class:`Cgsnapshot`
"""
body = {'cgsnapshot': {'consistencygroup_id': consistencygroup_id,
'name': name,
'description': description,
'user_id': user_id,
'project_id': project_id,
'status': "creating",
}}
return self._create('/cgsnapshots', body, 'cgsnapshot')
def get(self, cgsnapshot_id):
"""Get a cgsnapshot.
:param cgsnapshot_id: The ID of the cgsnapshot to get.
:rtype: :class:`Cgsnapshot`
"""
return self._get("/cgsnapshots/%s" % cgsnapshot_id, "cgsnapshot")
def list(self, detailed=True, search_opts=None):
"""Lists all cgsnapshots.
:rtype: list of :class:`Cgsnapshot`
"""
query_string = utils.build_query_param(search_opts)
detail = ""
if detailed:
detail = "/detail"
return self._list("/cgsnapshots%s%s" % (detail, query_string),
"cgsnapshots")
def delete(self, cgsnapshot):
"""Delete a cgsnapshot.
:param cgsnapshot: The :class:`Cgsnapshot` to delete.
"""
return self._delete("/cgsnapshots/%s" % base.getid(cgsnapshot))
def update(self, cgsnapshot, **kwargs):
"""Update the name or description for a cgsnapshot.
:param cgsnapshot: The :class:`Cgsnapshot` to update.
"""
if not kwargs:
return
body = {"cgsnapshot": kwargs}
return self._update("/cgsnapshots/%s" % base.getid(cgsnapshot), body)
def _action(self, action, cgsnapshot, info=None, **kwargs):
"""Perform a cgsnapshot "action."
"""
body = {action: info}
self.run_hooks('modify_body_for_action', body, **kwargs)
url = '/cgsnapshots/%s/action' % base.getid(cgsnapshot)
resp, body = self.api.client.post(url, body=body)
return common_base.TupleWithMeta((resp, body), resp)

141
cinderclient/v2/client.py

@ -1,141 +0,0 @@
# Copyright (c) 2013 OpenStack Foundation
# 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.
import logging
from cinderclient import api_versions
from cinderclient import client
from cinderclient.v2 import availability_zones
from cinderclient.v2 import capabilities
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
from cinderclient.v2 import services
from cinderclient.v2 import volume_backups
from cinderclient.v2 import volume_backups_restore
from cinderclient.v2 import volume_encryption_types
from cinderclient.v2 import volume_snapshots
from cinderclient.v2 import volume_transfers
from cinderclient.v2 import volume_type_access
from cinderclient.v2 import volume_types
from cinderclient.v2 import volumes
class Client(object):
"""Top-level object to access the OpenStack Volume API.
Create an instance with your creds::
>>> client = Client(USERNAME, PASSWORD, PROJECT_ID, AUTH_URL)
Then call methods on its managers::
>>> client.volumes.list()
...
"""
def __init__(self, username=None, api_key=None, project_id=None,
auth_url='', insecure=False, timeout=None, tenant_id=None,
proxy_tenant_id=None, proxy_token=None, region_name=None,
endpoint_type='publicURL', extensions=None,
service_type='volumev2', service_name=None,
volume_service_name=None, os_endpoint=None, retries=0,
http_log_debug=False, cacert=None, cert=None,
auth_system='keystone', auth_plugin=None, session=None,
api_version=None, logger=None, **kwargs):
# FIXME(comstud): Rename the api_key argument above when we
# know it's not being used as keyword argument
password = api_key
self.version = '2.0'
self.limits = limits.LimitsManager(self)
# extensions
self.volumes = volumes.VolumeManager(self)
self.volume_snapshots = volume_snapshots.SnapshotManager(self)
self.volume_types = volume_types.VolumeTypeManager(self)
self.volume_type_access = \
volume_type_access.VolumeTypeAccessManager(self)
self.volume_encryption_types = \
volume_encryption_types.VolumeEncryptionTypeManager(self)
self.qos_specs = qos_specs.QoSSpecsManager(self)
self.quota_classes = quota_classes.QuotaClassSetManager(self)
self.quotas = quotas.QuotaSetManager(self)
self.backups = volume_backups.VolumeBackupManager(self)
self.restores = volume_backups_restore.VolumeBackupRestoreManager(self)
self.transfers = volume_transfers.VolumeTransferManager(self)
self.services = services.ServiceManager(self)
self.consistencygroups = consistencygroups.\
ConsistencygroupManager(self)
self.cgsnapshots = cgsnapshots.CgsnapshotManager(self)
self.availability_zones = \
availability_zones.AvailabilityZoneManager(self)
self.pools = pools.PoolManager(self)
self.capabilities = capabilities.CapabilitiesManager(self)
self.api_version = api_version or api_versions.APIVersion(self.version)
# Add in any extensions...
if extensions:
for extension in extensions:
if extension.manager_class:
setattr(self, extension.name,
extension.manager_class(self))
if not logger:
logger = logging.getLogger(__name__)
self.client = client._construct_http_client(
username=username,
password=password,
project_id=project_id,
auth_url=auth_url,
insecure=insecure,
timeout=timeout,
tenant_id=tenant_id,
proxy_tenant_id=tenant_id,
proxy_token=proxy_token,
region_name=region_name,
endpoint_type=endpoint_type,
service_type=service_type,
service_name=service_name,
volume_service_name=volume_service_name,
os_endpoint=os_endpoint,
retries=retries,
http_log_debug=http_log_debug,
cacert=cacert,
cert=cert,
auth_system=auth_system,
auth_plugin=auth_plugin,
session=session,
api_version=self.api_version,
logger=logger,
**kwargs)
def authenticate(self):
"""Authenticate against the server.
Normally this is called automatically when you first access the API,
but you can call this method to force authentication right now.
Returns on success; raises :exc:`exceptions.Unauthorized` if the
credentials are wrong.
"""
self.client.authenticate()
def get_volume_api_version_from_endpoint(self):
return self.client.get_volume_api_version_from_endpoint()

149
cinderclient/v2/consistencygroups.py

@ -1,149 +0,0 @@
# Copyright (C) 2012 - 2014 EMC Corporation.
# 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.
"""Consistencygroup interface (v2 extension)."""
from cinderclient.apiclient import base as common_base
from cinderclient import base
from cinderclient import utils
class Consistencygroup(base.Resource):
"""A Consistencygroup of volumes."""
def __repr__(self):
return "<Consistencygroup: %s>" % self.id
def delete(self, force='False'):
"""Delete this consistency group."""
return self.manager.delete(self, force)
def update(self, **kwargs):
"""Update the name or description for this consistency group."""
return self.manager.update(self, **kwargs)
class ConsistencygroupManager(base.ManagerWithFind):
"""Manage :class:`Consistencygroup` resources."""
resource_class = Consistencygroup
def create(self, volume_types, name=None,
description=None, user_id=None,
project_id=None, availability_zone=None):
"""Creates a consistency group.
:param name: Name of the ConsistencyGroup
:param description: Description of the ConsistencyGroup
:param volume_types: Types of volume
:param user_id: User id derived from context
:param project_id: Project id derived from context
:param availability_zone: Availability Zone to use
:rtype: :class:`Consistencygroup`
"""
body = {'consistencygroup': {'name': name,
'description': description,
'volume_types': volume_types,
'user_id': user_id,
'project_id': project_id,
'availability_zone': availability_zone,
'status': "creating",
}}
return self._create('/consistencygroups', body, 'consistencygroup')
def create_from_src(self, cgsnapshot_id, source_cgid, name=None,
description=None, user_id=None,
project_id=None):
"""Creates a consistency group from a cgsnapshot or a source CG.
:param cgsnapshot_id: UUID of a CGSnapshot
:param source_cgid: UUID of a source CG
:param name: Name of the ConsistencyGroup
:param description: Description of the ConsistencyGroup
:param user_id: User id derived from context
:param project_id: Project id derived from context
:rtype: A dictionary containing Consistencygroup metadata
"""
body = {'consistencygroup-from-src': {'name': name,
'description': description,
'cgsnapshot_id': cgsnapshot_id,
'source_cgid': source_cgid,
'user_id': user_id,
'project_id': project_id,
'status': "creating",
}}
self.run_hooks('modify_body_for_update', body,
'consistencygroup-from-src')
resp, body = self.api.client.post(
"/consistencygroups/create_from_src", body=body)
return common_base.DictWithMeta(body['consistencygroup'], resp)
def get(self, group_id):
"""Get a consistency group.
:param group_id: The ID of the consistency group to get.
:rtype: :class:`Consistencygroup`
"""
return self._get("/consistencygroups/%s" % group_id,
"consistencygroup")
def list(self, detailed=True, search_opts=None):
"""Lists all consistency groups.
:rtype: list of :class:`Consistencygroup`
"""
query_string = utils.build_query_param(search_opts)
detail = ""
if detailed:
detail = "/detail"
return self._list("/consistencygroups%s%s" % (detail, query_string),
"consistencygroups")
def delete(self, consistencygroup, force=False):
"""Delete a consistency group.
:param Consistencygroup: The :class:`Consistencygroup` to delete.
"""
body = {'consistencygroup': {'force': force}}
self.run_hooks('modify_body_for_action', body, 'consistencygroup')
url = '/consistencygroups/%s/delete' % base.getid(consistencygroup)
resp, body = self.api.client.post(url, body=body)
return common_base.TupleWithMeta((resp, body), resp)
def update(self, consistencygroup, **kwargs):
"""Update the name or description for a consistency group.
:param Consistencygroup: The :class:`Consistencygroup` to update.
"""
if not kwargs:
return
body = {"consistencygroup": kwargs}
return self._update("/consistencygroups/%s" %
base.getid(consistencygroup), body)
def _action(self, action, consistencygroup, info=None, **kwargs):
"""Perform a consistency group "action."
"""
body = {action: info}
self.run_hooks('modify_body_for_action', body, **kwargs)
url = '/consistencygroups/%s/action' % base.getid(consistencygroup)
resp, body = self.api.client.post(url, body=body)
return common_base.TupleWithMeta((resp, body), resp)

0
cinderclient/v2/contrib/__init__.py

44
cinderclient/v2/contrib/list_extensions.py

@ -1,44 +0,0 @@
# Copyright (c) 2013 OpenStack Foundation
# 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 import base
from cinderclient import utils
class ListExtResource(base.Resource):
@property
def summary(self):
descr = self.description.strip()
if not descr:
return '??'
lines = descr.split("\n")
if len(lines) == 1:
return lines[0]
else:
return lines[0] + "..."
class ListExtManager(base.Manager):
resource_class = ListExtResource
def show_all(self):
return self._list("/extensions", 'extensions')
def do_list_extensions(client, _args):
"""Lists all available os-api extensions."""
extensions = client.list_extensions.show_all()
fields = ["Name", "Summary", "Alias", "Updated"]
utils.print_list(extensions, fields)

99
cinderclient/v2/limits.py

@ -1,99 +0,0 @@
# Copyright 2013 OpenStack Foundation
#
# 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.
"""Limits interface (v2 extension)"""
from cinderclient import base
from cinderclient import utils
class Limits(base.Resource):
"""A collection of RateLimit and AbsoluteLimit objects."""
def __repr__(self):
return "<Limits>"
@property
def absolute(self):
for (name, value) in list(self._info['absolute'].items()):
yield AbsoluteLimit(name, value)
@property
def rate(self):