From 3fb43bc134c19df80d3adff820260dcf25daf731 Mon Sep 17 00:00:00 2001 From: Artem Goncharov Date: Thu, 9 Jul 2020 16:07:15 +0200 Subject: [PATCH] Add block_storage find functions in order to implement basic ansible block storage modules we also want to have an easy way to search to resources. Change-Id: Ibe800e08cc8ea0e4277e4dc6339fdc9b53194057 --- openstack/block_storage/v3/_proxy.py | 64 +++++++++++++++++++ .../tests/unit/block_storage/v3/test_proxy.py | 15 +++++ 2 files changed, 79 insertions(+) diff --git a/openstack/block_storage/v3/_proxy.py b/openstack/block_storage/v3/_proxy.py index 1fe43d933..6b0a94306 100644 --- a/openstack/block_storage/v3/_proxy.py +++ b/openstack/block_storage/v3/_proxy.py @@ -35,6 +35,21 @@ class Proxy(_base_proxy.BaseBlockStorageProxy): """ return self._get(_snapshot.Snapshot, snapshot) + def find_snapshot(self, name_or_id, ignore_missing=True, **attrs): + """Find a single snapshot + + :param snapshot: The name or ID a snapshot + :param bool ignore_missing: When set to ``False`` + :class:`~openstack.exceptions.ResourceNotFound` will be raised + when the snapshot does not exist. + + :returns: One :class:`~openstack.volume.v3.snapshot.Snapshot` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + return self._find(_snapshot.Snapshot, name_or_id, + ignore_missing=ignore_missing) + def snapshots(self, details=True, **query): """Retrieve a generator of snapshots @@ -98,6 +113,21 @@ class Proxy(_base_proxy.BaseBlockStorageProxy): """ return self._get(_type.Type, type) + def find_type(self, name_or_id, ignore_missing=True, **attrs): + """Find a single volume type + + :param snapshot: The name or ID a volume type + :param bool ignore_missing: When set to ``False`` + :class:`~openstack.exceptions.ResourceNotFound` will be raised + when the type does not exist. + + :returns: One :class:`~openstack.volume.v3.type.Type` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + return self._find(_type.Type, name_or_id, + ignore_missing=ignore_missing) + def types(self, **query): """Retrieve a generator of volume types @@ -144,6 +174,21 @@ class Proxy(_base_proxy.BaseBlockStorageProxy): """ return self._get(_volume.Volume, volume) + def find_volume(self, name_or_id, ignore_missing=True, **attrs): + """Find a single volume + + :param snapshot: The name or ID a volume + :param bool ignore_missing: When set to ``False`` + :class:`~openstack.exceptions.ResourceNotFound` will be raised + when the volume does not exist. + + :returns: One :class:`~openstack.volume.v3.volume.Volume` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + return self._find(_volume.Volume, name_or_id, + ignore_missing=ignore_missing) + def volumes(self, details=True, **query): """Retrieve a generator of volumes @@ -255,6 +300,25 @@ class Proxy(_base_proxy.BaseBlockStorageProxy): ) return self._get(_backup.Backup, backup) + def find_backup(self, name_or_id, ignore_missing=True, **attrs): + """Find a single backup + + :param snapshot: The name or ID a backup + :param bool ignore_missing: When set to ``False`` + :class:`~openstack.exceptions.ResourceNotFound` will be raised + when the backup does not exist. + + :returns: One :class:`~openstack.volume.v3.backup.Backup` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + if not self._connection.has_service('object-store'): + raise exceptions.SDKException( + 'Object-store service is required for block-store backups' + ) + return self._find(_backup.Backup, name_or_id, + ignore_missing=ignore_missing) + def create_backup(self, **attrs): """Create a new Backup from attributes with native API diff --git a/openstack/tests/unit/block_storage/v3/test_proxy.py b/openstack/tests/unit/block_storage/v3/test_proxy.py index 12a4c77c0..c2a9efe89 100644 --- a/openstack/tests/unit/block_storage/v3/test_proxy.py +++ b/openstack/tests/unit/block_storage/v3/test_proxy.py @@ -30,6 +30,9 @@ class TestVolumeProxy(test_proxy_base.TestProxyBase): def test_snapshot_get(self): self.verify_get(self.proxy.get_snapshot, snapshot.Snapshot) + def test_snapshot_find(self): + self.verify_find(self.proxy.find_snapshot, snapshot.Snapshot) + def test_snapshots_detailed(self): self.verify_list(self.proxy.snapshots, snapshot.SnapshotDetail, method_kwargs={"details": True, "query": 1}, @@ -54,6 +57,9 @@ class TestVolumeProxy(test_proxy_base.TestProxyBase): def test_type_get(self): self.verify_get(self.proxy.get_type, type.Type) + def test_type_find(self): + self.verify_find(self.proxy.find_type, type.Type) + def test_types(self): self.verify_list(self.proxy.types, type.Type) @@ -69,6 +75,9 @@ class TestVolumeProxy(test_proxy_base.TestProxyBase): def test_volume_get(self): self.verify_get(self.proxy.get_volume, volume.Volume) + def test_volume_find(self): + self.verify_find(self.proxy.find_volume, volume.Volume) + def test_volumes_detailed(self): self.verify_list(self.proxy.volumes, volume.Volume, method_kwargs={"details": True, "query": 1}, @@ -121,6 +130,12 @@ class TestVolumeProxy(test_proxy_base.TestProxyBase): self.proxy._connection.has_service = mock.Mock(return_value=True) self.verify_get(self.proxy.get_backup, backup.Backup) + def test_backup_find(self): + # NOTE: mock has_service + self.proxy._connection = mock.Mock() + self.proxy._connection.has_service = mock.Mock(return_value=True) + self.verify_find(self.proxy.find_backup, backup.Backup) + def test_backup_delete(self): # NOTE: mock has_service self.proxy._connection = mock.Mock()