diff --git a/releasenotes/notes/add-volume-clients-as-a-library-d05b6bc35e66c6ef.yaml b/releasenotes/notes/add-volume-clients-as-a-library-d05b6bc35e66c6ef.yaml new file mode 100644 index 0000000000..8125ab9887 --- /dev/null +++ b/releasenotes/notes/add-volume-clients-as-a-library-d05b6bc35e66c6ef.yaml @@ -0,0 +1,12 @@ +--- +features: + - | + Define volume service clients as libraries. + The following volume service clients are defined as library interface, + so the other projects can use these modules as stable libraries without + any maintenance changes. + + * encryption_types_client (v1) + * snapshots_client (v1) + * snapshots_client (v2) + diff --git a/tempest/lib/services/volume/v1/snapshots_client.py b/tempest/lib/services/volume/v1/snapshots_client.py new file mode 100644 index 0000000000..188107886d --- /dev/null +++ b/tempest/lib/services/volume/v1/snapshots_client.py @@ -0,0 +1,182 @@ +# 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 oslo_serialization import jsonutils as json +from six.moves.urllib import parse as urllib + +from tempest.lib.common import rest_client +from tempest.lib import exceptions as lib_exc + + +class SnapshotsClient(rest_client.RestClient): + """Client class to send CRUD Volume V1 API requests.""" + + create_resp = 200 + + def list_snapshots(self, detail=False, **params): + """List all the snapshot. + + Available params: see http://developer.openstack.org/ + api-ref-blockstorage-v1.html#listSnapshots + """ + url = 'snapshots' + if detail: + url += '/detail' + if params: + url += '?%s' % urllib.urlencode(params) + + resp, body = self.get(url) + body = json.loads(body) + self.expected_success(200, resp.status) + return rest_client.ResponseBody(resp, body) + + def show_snapshot(self, snapshot_id): + """Returns the details of a single snapshot. + + Available params: see http://developer.openstack.org/ + api-ref-blockstorage-v1.html#showSnapshot + """ + url = "snapshots/%s" % snapshot_id + resp, body = self.get(url) + body = json.loads(body) + self.expected_success(200, resp.status) + return rest_client.ResponseBody(resp, body) + + def create_snapshot(self, **kwargs): + """Creates a new snapshot. + + Available params: see http://developer.openstack.org/ + api-ref-blockstorage-v1.html#createSnapshot + """ + post_body = json.dumps({'snapshot': kwargs}) + resp, body = self.post('snapshots', post_body) + body = json.loads(body) + self.expected_success(self.create_resp, resp.status) + return rest_client.ResponseBody(resp, body) + + def delete_snapshot(self, snapshot_id): + """Delete Snapshot. + + Available params: see http://developer.openstack.org/ + api-ref-blockstorage-v1.html#deleteSnapshot + """ + resp, body = self.delete("snapshots/%s" % snapshot_id) + self.expected_success(202, resp.status) + return rest_client.ResponseBody(resp, body) + + def is_resource_deleted(self, id): + try: + self.show_snapshot(id) + except lib_exc.NotFound: + return True + return False + + @property + def resource_type(self): + """Returns the primary type of resource this client works with.""" + return 'volume-snapshot' + + def reset_snapshot_status(self, snapshot_id, status): + """Reset the specified snapshot's status.""" + post_body = json.dumps({'os-reset_status': {"status": status}}) + resp, body = self.post('snapshots/%s/action' % snapshot_id, post_body) + self.expected_success(202, resp.status) + return rest_client.ResponseBody(resp, body) + + def update_snapshot_status(self, snapshot_id, **kwargs): + """Update the specified snapshot's status.""" + # TODO(gmann): api-site doesn't contain doc ref + # for this API. After fixing the api-site, we need to + # add the link here. + # Bug https://bugs.launchpad.net/openstack-api-site/+bug/1532645 + + post_body = json.dumps({'os-update_snapshot_status': kwargs}) + url = 'snapshots/%s/action' % snapshot_id + resp, body = self.post(url, post_body) + self.expected_success(202, resp.status) + return rest_client.ResponseBody(resp, body) + + def create_snapshot_metadata(self, snapshot_id, metadata): + """Create metadata for the snapshot.""" + put_body = json.dumps({'metadata': metadata}) + url = "snapshots/%s/metadata" % snapshot_id + resp, body = self.post(url, put_body) + body = json.loads(body) + self.expected_success(200, resp.status) + return rest_client.ResponseBody(resp, body) + + def update_snapshot(self, snapshot_id, **kwargs): + """Updates a snapshot. + + Available params: see http://developer.openstack.org/ + api-ref-blockstorage-v1.html# + updateSnapshotMetadata + """ + put_body = json.dumps({'snapshot': kwargs}) + resp, body = self.put('snapshots/%s' % snapshot_id, put_body) + body = json.loads(body) + self.expected_success(200, resp.status) + return rest_client.ResponseBody(resp, body) + + def show_snapshot_metadata(self, snapshot_id): + """Get metadata of the snapshot. + + Available params: see http://developer.openstack.org/ + api-ref-blockstorage-v1.html# + showSnapshotMetadata + """ + url = "snapshots/%s/metadata" % snapshot_id + resp, body = self.get(url) + body = json.loads(body) + self.expected_success(200, resp.status) + return rest_client.ResponseBody(resp, body) + + def update_snapshot_metadata(self, snapshot_id, **kwargs): + """Update metadata for the snapshot. + + Available params: see http://developer.openstack.org/ + api-ref-blockstorage-v1.html# + updateSnapshotMetadata + """ + put_body = json.dumps(kwargs) + url = "snapshots/%s/metadata" % snapshot_id + resp, body = self.put(url, put_body) + body = json.loads(body) + self.expected_success(200, resp.status) + return rest_client.ResponseBody(resp, body) + + def update_snapshot_metadata_item(self, snapshot_id, id, **kwargs): + """Update metadata item for the snapshot.""" + # TODO(piyush): Current api-site doesn't contain this API description. + # After fixing the api-site, we need to fix here also for putting the + # link to api-site. + # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1529064 + put_body = json.dumps(kwargs) + url = "snapshots/%s/metadata/%s" % (snapshot_id, id) + resp, body = self.put(url, put_body) + body = json.loads(body) + self.expected_success(200, resp.status) + return rest_client.ResponseBody(resp, body) + + def delete_snapshot_metadata_item(self, snapshot_id, id): + """Delete metadata item for the snapshot.""" + url = "snapshots/%s/metadata/%s" % (snapshot_id, id) + resp, body = self.delete(url) + self.expected_success(200, resp.status) + return rest_client.ResponseBody(resp, body) + + def force_delete_snapshot(self, snapshot_id): + """Force Delete Snapshot.""" + post_body = json.dumps({'os-force_delete': {}}) + resp, body = self.post('snapshots/%s/action' % snapshot_id, post_body) + self.expected_success(202, resp.status) + return rest_client.ResponseBody(resp, body) diff --git a/tempest/services/volume/base/base_snapshots_client.py b/tempest/lib/services/volume/v2/snapshots_client.py old mode 100755 new mode 100644 similarity index 97% rename from tempest/services/volume/base/base_snapshots_client.py rename to tempest/lib/services/volume/v2/snapshots_client.py index 38a6dc77dc..c84e557c5a --- a/tempest/services/volume/base/base_snapshots_client.py +++ b/tempest/lib/services/volume/v2/snapshots_client.py @@ -17,10 +17,10 @@ from tempest.lib.common import rest_client from tempest.lib import exceptions as lib_exc -class BaseSnapshotsClient(rest_client.RestClient): - """Base Client class to send CRUD Volume API requests.""" - - create_resp = 200 +class SnapshotsClient(rest_client.RestClient): + """Client class to send CRUD Volume V2 API requests.""" + api_version = "v2" + create_resp = 202 def list_snapshots(self, detail=False, **params): """List all the snapshot. diff --git a/tempest/services/volume/v1/__init__.py b/tempest/services/volume/v1/__init__.py index a7d9270f2e..02eaa7f8ab 100644 --- a/tempest/services/volume/v1/__init__.py +++ b/tempest/services/volume/v1/__init__.py @@ -20,13 +20,13 @@ from tempest.lib.services.volume.v1.extensions_client import ExtensionsClient from tempest.lib.services.volume.v1.hosts_client import HostsClient from tempest.lib.services.volume.v1.quotas_client import QuotasClient from tempest.lib.services.volume.v1.services_client import ServicesClient +from tempest.lib.services.volume.v1.snapshots_client import SnapshotsClient from tempest.lib.services.volume.v1.types_client import TypesClient from tempest.services.volume.v1.json.backups_client import BackupsClient from tempest.services.volume.v1.json.qos_client import QosSpecsClient -from tempest.services.volume.v1.json.snapshots_client import SnapshotsClient from tempest.services.volume.v1.json.volumes_client import VolumesClient __all__ = ['AvailabilityZoneClient', 'EncryptionTypesClient', 'ExtensionsClient', 'HostsClient', 'QuotasClient', 'ServicesClient', - 'TypesClient', 'BackupsClient', 'QosSpecsClient', 'SnapshotsClient', + 'SnapshotsClient', 'TypesClient', 'BackupsClient', 'QosSpecsClient', 'VolumesClient', ] diff --git a/tempest/services/volume/v1/json/snapshots_client.py b/tempest/services/volume/v1/json/snapshots_client.py deleted file mode 100644 index b039c2b83d..0000000000 --- a/tempest/services/volume/v1/json/snapshots_client.py +++ /dev/null @@ -1,17 +0,0 @@ -# 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 tempest.services.volume.base import base_snapshots_client - - -class SnapshotsClient(base_snapshots_client.BaseSnapshotsClient): - """Client class to send CRUD Volume V1 API requests.""" diff --git a/tempest/services/volume/v2/__init__.py b/tempest/services/volume/v2/__init__.py index c99a81a8e9..58f7af41ad 100644 --- a/tempest/services/volume/v2/__init__.py +++ b/tempest/services/volume/v2/__init__.py @@ -18,15 +18,15 @@ from tempest.lib.services.volume.v2.extensions_client import ExtensionsClient from tempest.lib.services.volume.v2.hosts_client import HostsClient from tempest.lib.services.volume.v2.quotas_client import QuotasClient from tempest.lib.services.volume.v2.services_client import ServicesClient +from tempest.lib.services.volume.v2.snapshots_client import SnapshotsClient from tempest.lib.services.volume.v2.types_client import TypesClient from tempest.services.volume.v2.json.backups_client import BackupsClient from tempest.services.volume.v2.json.encryption_types_client import \ EncryptionTypesClient from tempest.services.volume.v2.json.qos_client import QosSpecsClient -from tempest.services.volume.v2.json.snapshots_client import SnapshotsClient from tempest.services.volume.v2.json.volumes_client import VolumesClient __all__ = ['AvailabilityZoneClient', 'ExtensionsClient', 'HostsClient', - 'QuotasClient', 'ServicesClient', 'TypesClient', 'BackupsClient', - 'EncryptionTypesClient', 'QosSpecsClient', 'SnapshotsClient', + 'QuotasClient', 'ServicesClient', 'SnapshotsClient', 'TypesClient', + 'BackupsClient', 'EncryptionTypesClient', 'QosSpecsClient', 'VolumesClient', ] diff --git a/tempest/services/volume/v2/json/snapshots_client.py b/tempest/services/volume/v2/json/snapshots_client.py deleted file mode 100644 index a2d415f96a..0000000000 --- a/tempest/services/volume/v2/json/snapshots_client.py +++ /dev/null @@ -1,19 +0,0 @@ -# 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 tempest.services.volume.base import base_snapshots_client - - -class SnapshotsClient(base_snapshots_client.BaseSnapshotsClient): - """Client class to send CRUD Volume V2 API requests.""" - api_version = "v2" - create_resp = 202