Update volume and volume transfer schema
Fix the volume transfers client so that it supports microversions, by deriving from the volume service's base client. Define volume transfer schema for mv 3.55 and 3.57, and volume schema for mv 3.65 and 3.69. Change-Id: I4ad7fe336c5193604d95fca5a72695d82adaa9f0
This commit is contained in:
@@ -110,9 +110,7 @@ class VolumesTransfersV355Test(VolumesTransfersTest):
|
||||
"""Test volume transfer for the "new" Transfers API mv 3.55"""
|
||||
|
||||
volume_min_microversion = '3.55'
|
||||
volume_max_microversion = 'latest'
|
||||
|
||||
credentials = ['primary', 'alt', 'admin']
|
||||
volume_max_microversion = '3.56'
|
||||
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
@@ -131,3 +129,22 @@ class VolumesTransfersV355Test(VolumesTransfersTest):
|
||||
"""Test create, list, delete with volume-transfers API mv 3.55"""
|
||||
super(VolumesTransfersV355Test, self). \
|
||||
test_create_list_delete_volume_transfer()
|
||||
|
||||
|
||||
class VolumesTransfersV357Test(VolumesTransfersV355Test):
|
||||
"""Test volume transfer for the "new" Transfers API mv 3.57"""
|
||||
|
||||
volume_min_microversion = '3.57'
|
||||
volume_max_microversion = 'latest'
|
||||
|
||||
@decorators.idempotent_id('d746bd69-bb30-4414-9a1c-577959fac6a1')
|
||||
def test_create_get_list_accept_volume_transfer(self):
|
||||
"""Test create, get, list, accept with volume-transfers API mv 3.57"""
|
||||
super(VolumesTransfersV357Test, self). \
|
||||
test_create_get_list_accept_volume_transfer()
|
||||
|
||||
@decorators.idempotent_id('d4b20ec2-e1bb-4068-adcf-6c20020a8e05')
|
||||
def test_create_list_delete_volume_transfer(self):
|
||||
"""Test create, list, delete with volume-transfers API mv 3.57"""
|
||||
super(VolumesTransfersV357Test, self). \
|
||||
test_create_list_delete_volume_transfer()
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# Copyright 2022 Red Hat, 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.
|
||||
|
||||
import copy
|
||||
|
||||
from tempest.lib.api_schema.response.volume import transfers
|
||||
|
||||
# Volume microversion 3.55:
|
||||
# Add 'no_snapshots' attribute in 'transfer' responses.
|
||||
|
||||
create_volume_transfer = copy.deepcopy(transfers.create_volume_transfer)
|
||||
create_volume_transfer['response_body']['properties']['transfer'][
|
||||
'properties'].update({'no_snapshots': {'type': 'boolean'}})
|
||||
|
||||
common_show_volume_transfer = copy.deepcopy(
|
||||
transfers.common_show_volume_transfer)
|
||||
common_show_volume_transfer['properties'].update(
|
||||
{'no_snapshots': {'type': 'boolean'}})
|
||||
|
||||
show_volume_transfer = copy.deepcopy(transfers.show_volume_transfer)
|
||||
show_volume_transfer['response_body']['properties'][
|
||||
'transfer'] = common_show_volume_transfer
|
||||
|
||||
list_volume_transfers_no_detail = copy.deepcopy(
|
||||
transfers.list_volume_transfers_no_detail)
|
||||
|
||||
list_volume_transfers_with_detail = copy.deepcopy(
|
||||
transfers.list_volume_transfers_with_detail)
|
||||
list_volume_transfers_with_detail['response_body']['properties']['transfers'][
|
||||
'items'] = common_show_volume_transfer
|
||||
|
||||
delete_volume_transfer = copy.deepcopy(transfers.delete_volume_transfer)
|
||||
|
||||
accept_volume_transfer = copy.deepcopy(transfers.accept_volume_transfer)
|
||||
@@ -0,0 +1,61 @@
|
||||
# Copyright 2022 Red Hat, 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.
|
||||
|
||||
import copy
|
||||
|
||||
from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
|
||||
from tempest.lib.api_schema.response.volume.v3_55 import transfers
|
||||
|
||||
# Volume microversion 3.57:
|
||||
# Add these attributes in 'transfer' responses.
|
||||
# 'destination_project_id'
|
||||
# 'source_project_id'
|
||||
# 'accepted'
|
||||
|
||||
create_volume_transfer = copy.deepcopy(transfers.create_volume_transfer)
|
||||
create_volume_transfer['response_body']['properties']['transfer'][
|
||||
'properties'].update(
|
||||
{'destination_project_id': parameter_types.uuid_or_null})
|
||||
create_volume_transfer['response_body']['properties']['transfer'][
|
||||
'properties'].update(
|
||||
{'source_project_id': {'type': 'string', 'format': 'uuid'}})
|
||||
create_volume_transfer['response_body']['properties']['transfer'][
|
||||
'properties'].update(
|
||||
{'accepted': {'type': 'boolean'}})
|
||||
|
||||
common_show_volume_transfer = copy.deepcopy(
|
||||
transfers.common_show_volume_transfer)
|
||||
common_show_volume_transfer['properties'].update(
|
||||
{'destination_project_id': parameter_types.uuid_or_null})
|
||||
common_show_volume_transfer['properties'].update(
|
||||
{'source_project_id': {'type': 'string', 'format': 'uuid'}})
|
||||
common_show_volume_transfer['properties'].update(
|
||||
{'accepted': {'type': 'boolean'}})
|
||||
|
||||
show_volume_transfer = copy.deepcopy(transfers.show_volume_transfer)
|
||||
show_volume_transfer['response_body']['properties'][
|
||||
'transfer'] = common_show_volume_transfer
|
||||
|
||||
list_volume_transfers_no_detail = copy.deepcopy(
|
||||
transfers.list_volume_transfers_no_detail)
|
||||
|
||||
list_volume_transfers_with_detail = copy.deepcopy(
|
||||
transfers.list_volume_transfers_with_detail)
|
||||
list_volume_transfers_with_detail['response_body']['properties']['transfers'][
|
||||
'items'] = common_show_volume_transfer
|
||||
|
||||
delete_volume_transfer = copy.deepcopy(transfers.delete_volume_transfer)
|
||||
|
||||
accept_volume_transfer = copy.deepcopy(transfers.accept_volume_transfer)
|
||||
@@ -0,0 +1,65 @@
|
||||
# Copyright 2022 Red Hat, 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.
|
||||
|
||||
import copy
|
||||
|
||||
from tempest.lib.api_schema.response.volume.v3_64 import volumes
|
||||
|
||||
# Volume microversion 3.65:
|
||||
# Add 'consumes_quota' attribute in volume details.
|
||||
|
||||
common_show_volume = copy.deepcopy(volumes.common_show_volume)
|
||||
common_show_volume['properties'].update(
|
||||
{'consumes_quota': {'type': 'boolean'}})
|
||||
|
||||
create_volume = copy.deepcopy(volumes.create_volume)
|
||||
create_volume['response_body']['properties']['volume']['properties'].update(
|
||||
{'consumes_quota': {'type': 'boolean'}})
|
||||
|
||||
# copy unchanged volumes schema
|
||||
attachments = copy.deepcopy(volumes.attachments)
|
||||
list_volumes_no_detail = copy.deepcopy(volumes.list_volumes_no_detail)
|
||||
# show_volume refers to common_show_volume
|
||||
show_volume = copy.deepcopy(volumes.show_volume)
|
||||
show_volume['response_body']['properties']['volume'] = common_show_volume
|
||||
# list_volumes_detail refers to latest common_show_volume
|
||||
list_volumes_detail = copy.deepcopy(common_show_volume)
|
||||
list_volumes_with_detail = copy.deepcopy(volumes.list_volumes_with_detail)
|
||||
list_volumes_with_detail['response_body']['properties']['volumes']['items'] \
|
||||
= list_volumes_detail
|
||||
update_volume = copy.deepcopy(volumes.update_volume)
|
||||
delete_volume = copy.deepcopy(volumes.delete_volume)
|
||||
show_volume_summary = copy.deepcopy(volumes.show_volume_summary)
|
||||
attach_volume = copy.deepcopy(volumes.attach_volume)
|
||||
set_bootable_volume = copy.deepcopy(volumes.set_bootable_volume)
|
||||
detach_volume = copy.deepcopy(volumes.detach_volume)
|
||||
reserve_volume = copy.deepcopy(volumes.reserve_volume)
|
||||
unreserve_volume = copy.deepcopy(volumes.unreserve_volume)
|
||||
extend_volume = copy.deepcopy(volumes.extend_volume)
|
||||
reset_volume_status = copy.deepcopy(volumes.reset_volume_status)
|
||||
update_volume_readonly = copy.deepcopy(volumes.update_volume_readonly)
|
||||
force_delete_volume = copy.deepcopy(volumes.force_delete_volume)
|
||||
retype_volume = copy.deepcopy(volumes.retype_volume)
|
||||
force_detach_volume = copy.deepcopy(volumes.force_detach_volume)
|
||||
create_volume_metadata = copy.deepcopy(volumes.create_volume_metadata)
|
||||
show_volume_metadata = copy.deepcopy(volumes.show_volume_metadata)
|
||||
update_volume_metadata = copy.deepcopy(volumes.update_volume_metadata)
|
||||
update_volume_metadata_item = copy.deepcopy(
|
||||
volumes.update_volume_metadata_item)
|
||||
update_volume_image_metadata = copy.deepcopy(
|
||||
volumes.update_volume_image_metadata)
|
||||
delete_volume_image_metadata = copy.deepcopy(
|
||||
volumes.delete_volume_image_metadata)
|
||||
unmanage_volume = copy.deepcopy(volumes.unmanage_volume)
|
||||
@@ -0,0 +1,65 @@
|
||||
# Copyright 2022 Red Hat, 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.
|
||||
|
||||
import copy
|
||||
|
||||
from tempest.lib.api_schema.response.volume.v3_65 import volumes
|
||||
|
||||
# Volume microversion 3.69:
|
||||
# The 'shared_targets' attribute is now a tristate boolean.
|
||||
|
||||
common_show_volume = copy.deepcopy(volumes.common_show_volume)
|
||||
common_show_volume['properties'].update(
|
||||
{'shared_targets': {'type': ['boolean', 'null']}})
|
||||
|
||||
create_volume = copy.deepcopy(volumes.create_volume)
|
||||
create_volume['response_body']['properties']['volume']['properties'].update(
|
||||
{'shared_targets': {'type': ['boolean', 'null']}})
|
||||
|
||||
# copy unchanged volumes schema
|
||||
attachments = copy.deepcopy(volumes.attachments)
|
||||
list_volumes_no_detail = copy.deepcopy(volumes.list_volumes_no_detail)
|
||||
# show_volume refers to common_show_volume
|
||||
show_volume = copy.deepcopy(volumes.show_volume)
|
||||
show_volume['response_body']['properties']['volume'] = common_show_volume
|
||||
# list_volumes_detail refers to latest common_show_volume
|
||||
list_volumes_detail = copy.deepcopy(common_show_volume)
|
||||
list_volumes_with_detail = copy.deepcopy(volumes.list_volumes_with_detail)
|
||||
list_volumes_with_detail['response_body']['properties']['volumes']['items'] \
|
||||
= list_volumes_detail
|
||||
update_volume = copy.deepcopy(volumes.update_volume)
|
||||
delete_volume = copy.deepcopy(volumes.delete_volume)
|
||||
show_volume_summary = copy.deepcopy(volumes.show_volume_summary)
|
||||
attach_volume = copy.deepcopy(volumes.attach_volume)
|
||||
set_bootable_volume = copy.deepcopy(volumes.set_bootable_volume)
|
||||
detach_volume = copy.deepcopy(volumes.detach_volume)
|
||||
reserve_volume = copy.deepcopy(volumes.reserve_volume)
|
||||
unreserve_volume = copy.deepcopy(volumes.unreserve_volume)
|
||||
extend_volume = copy.deepcopy(volumes.extend_volume)
|
||||
reset_volume_status = copy.deepcopy(volumes.reset_volume_status)
|
||||
update_volume_readonly = copy.deepcopy(volumes.update_volume_readonly)
|
||||
force_delete_volume = copy.deepcopy(volumes.force_delete_volume)
|
||||
retype_volume = copy.deepcopy(volumes.retype_volume)
|
||||
force_detach_volume = copy.deepcopy(volumes.force_detach_volume)
|
||||
create_volume_metadata = copy.deepcopy(volumes.create_volume_metadata)
|
||||
show_volume_metadata = copy.deepcopy(volumes.show_volume_metadata)
|
||||
update_volume_metadata = copy.deepcopy(volumes.update_volume_metadata)
|
||||
update_volume_metadata_item = copy.deepcopy(
|
||||
volumes.update_volume_metadata_item)
|
||||
update_volume_image_metadata = copy.deepcopy(
|
||||
volumes.update_volume_image_metadata)
|
||||
delete_volume_image_metadata = copy.deepcopy(
|
||||
volumes.delete_volume_image_metadata)
|
||||
unmanage_volume = copy.deepcopy(volumes.unmanage_volume)
|
||||
@@ -18,12 +18,23 @@ from urllib import parse as urllib
|
||||
from oslo_serialization import jsonutils as json
|
||||
|
||||
from tempest.lib.api_schema.response.volume import transfers as schema
|
||||
from tempest.lib.api_schema.response.volume.v3_55 \
|
||||
import transfers as schemav355
|
||||
from tempest.lib.api_schema.response.volume.v3_57 \
|
||||
import transfers as schemav357
|
||||
from tempest.lib.common import rest_client
|
||||
from tempest.lib.services.volume import base_client
|
||||
|
||||
|
||||
class TransfersClient(rest_client.RestClient):
|
||||
class TransfersClient(base_client.BaseClient):
|
||||
"""Client class to send CRUD Volume Transfer API requests"""
|
||||
|
||||
schema_versions_info = [
|
||||
{'min': None, 'max': '3.54', 'schema': schema},
|
||||
{'min': '3.55', 'max': '3.56', 'schema': schemav355},
|
||||
{'min': '3.57', 'max': None, 'schema': schemav357}
|
||||
]
|
||||
|
||||
resource_path = 'os-volume-transfer'
|
||||
|
||||
def create_volume_transfer(self, **kwargs):
|
||||
@@ -36,6 +47,7 @@ class TransfersClient(rest_client.RestClient):
|
||||
post_body = json.dumps({'transfer': kwargs})
|
||||
resp, body = self.post(self.resource_path, post_body)
|
||||
body = json.loads(body)
|
||||
schema = self.get_schema(self.schema_versions_info)
|
||||
self.validate_response(schema.create_volume_transfer, resp, body)
|
||||
return rest_client.ResponseBody(resp, body)
|
||||
|
||||
@@ -44,6 +56,7 @@ class TransfersClient(rest_client.RestClient):
|
||||
url = "%s/%s" % (self.resource_path, transfer_id)
|
||||
resp, body = self.get(url)
|
||||
body = json.loads(body)
|
||||
schema = self.get_schema(self.schema_versions_info)
|
||||
self.validate_response(schema.show_volume_transfer, resp, body)
|
||||
return rest_client.ResponseBody(resp, body)
|
||||
|
||||
@@ -56,6 +69,7 @@ class TransfersClient(rest_client.RestClient):
|
||||
https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-volume-transfers-and-details
|
||||
"""
|
||||
url = self.resource_path
|
||||
schema = self.get_schema(self.schema_versions_info)
|
||||
schema_list_transfers = schema.list_volume_transfers_no_detail
|
||||
if detail:
|
||||
url += '/detail'
|
||||
@@ -70,6 +84,7 @@ class TransfersClient(rest_client.RestClient):
|
||||
def delete_volume_transfer(self, transfer_id):
|
||||
"""Delete a volume transfer."""
|
||||
resp, body = self.delete("%s/%s" % (self.resource_path, transfer_id))
|
||||
schema = self.get_schema(self.schema_versions_info)
|
||||
self.validate_response(schema.delete_volume_transfer, resp, body)
|
||||
return rest_client.ResponseBody(resp, body)
|
||||
|
||||
@@ -84,6 +99,7 @@ class TransfersClient(rest_client.RestClient):
|
||||
post_body = json.dumps({'accept': kwargs})
|
||||
resp, body = self.post(url, post_body)
|
||||
body = json.loads(body)
|
||||
schema = self.get_schema(self.schema_versions_info)
|
||||
self.validate_response(schema.accept_volume_transfer, resp, body)
|
||||
return rest_client.ResponseBody(resp, body)
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ from oslo_serialization import jsonutils as json
|
||||
from tempest.lib.api_schema.response.volume.v3_61 import volumes as schemav361
|
||||
from tempest.lib.api_schema.response.volume.v3_63 import volumes as schemav363
|
||||
from tempest.lib.api_schema.response.volume.v3_64 import volumes as schemav364
|
||||
from tempest.lib.api_schema.response.volume.v3_65 import volumes as schemav365
|
||||
from tempest.lib.api_schema.response.volume.v3_69 import volumes as schemav369
|
||||
from tempest.lib.api_schema.response.volume import volumes as schema
|
||||
from tempest.lib.common import rest_client
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
@@ -33,7 +35,9 @@ class VolumesClient(base_client.BaseClient):
|
||||
{'min': None, 'max': '3.60', 'schema': schema},
|
||||
{'min': '3.61', 'max': '3.62', 'schema': schemav361},
|
||||
{'min': '3.63', 'max': '3.63', 'schema': schemav363},
|
||||
{'min': '3.64', 'max': None, 'schema': schemav364}
|
||||
{'min': '3.64', 'max': '3.64', 'schema': schemav364},
|
||||
{'min': '3.65', 'max': '3.68', 'schema': schemav365},
|
||||
{'min': '3.69', 'max': None, 'schema': schemav369}
|
||||
]
|
||||
|
||||
def _prepare_params(self, params):
|
||||
|
||||
Reference in New Issue
Block a user