Volumes API refactor
* Added v1/2 common models * Added v1/2 common client * Bugfix in datasets * Added dataset tagging on create Change-Id: Ic65317dc53cc0dff0d0aa4af08cf9acdd805afca
This commit is contained in:
parent
8700ab625d
commit
a8c1b3a387
@ -30,9 +30,11 @@ except Exception as ex:
|
||||
warnings.warn(msg)
|
||||
# Dummy class to prevent errors when non-integrating consumers import
|
||||
# this class while compute services are unavailable
|
||||
|
||||
class ComputeDatasets(object):
|
||||
pass
|
||||
|
||||
|
||||
class BlockstorageDatasets(ModelBasedDatasetToolkit):
|
||||
"""Collection of dataset generators for blockstorage data driven tests"""
|
||||
_volumes = VolumesAutoComposite()
|
||||
@ -52,7 +54,7 @@ class BlockstorageDatasets(ModelBasedDatasetToolkit):
|
||||
or vtype.name == cls._volumes.config.default_volume_type):
|
||||
return vtype
|
||||
|
||||
raise Exception("Unable to get configured default volume type")
|
||||
raise Exception("Unable to get configured default volume type")
|
||||
|
||||
@classmethod
|
||||
def default_volume_type(cls):
|
||||
@ -69,7 +71,7 @@ class BlockstorageDatasets(ModelBasedDatasetToolkit):
|
||||
@classmethod
|
||||
def volume_types(
|
||||
cls, max_datasets=None, randomize=None, model_filter=None,
|
||||
filter_mode=ModelBasedDatasetToolkit.INCLUSION_MODE):
|
||||
filter_mode=ModelBasedDatasetToolkit.INCLUSION_MODE, tags=None):
|
||||
"""Returns a DatasetList of all VolumeTypes
|
||||
Filters should be dictionaries with model attributes as keys and
|
||||
lists of attributes as key values
|
||||
@ -87,11 +89,18 @@ class BlockstorageDatasets(ModelBasedDatasetToolkit):
|
||||
dataset_list.append_new_dataset(vol_type.name, data)
|
||||
|
||||
# Apply modifiers
|
||||
return cls._modify_dataset_list(
|
||||
dataset_list = cls._modify_dataset_list(
|
||||
dataset_list, max_datasets=max_datasets, randomize=randomize)
|
||||
|
||||
# Apply Tags
|
||||
if tags:
|
||||
dataset_list.apply_test_tags(*tags)
|
||||
|
||||
return dataset_list
|
||||
|
||||
@classmethod
|
||||
def configured_volume_types(cls, max_datasets=None, randomize=False):
|
||||
def configured_volume_types(
|
||||
cls, max_datasets=None, randomize=False, tags=None):
|
||||
"""Returns a DatasetList of permuations of Volume Types and Images.
|
||||
Requests all available images and volume types from API, and applies
|
||||
pre-configured image and volume_type filters.
|
||||
@ -103,7 +112,8 @@ class BlockstorageDatasets(ModelBasedDatasetToolkit):
|
||||
max_datasets=max_datasets,
|
||||
randomize=randomize,
|
||||
model_filter=volume_type_filter,
|
||||
filter_mode=volume_type_filter_mode)
|
||||
filter_mode=volume_type_filter_mode,
|
||||
tags=tags)
|
||||
|
||||
|
||||
class ComputeIntegrationDatasets(ComputeDatasets, BlockstorageDatasets):
|
||||
@ -172,7 +182,8 @@ class ComputeIntegrationDatasets(ComputeDatasets, BlockstorageDatasets):
|
||||
volume_type_list, model_filter=volume_type_filter,
|
||||
filter_mode=volume_type_filter_mode)
|
||||
|
||||
# Create dataset from all combinations of all images and volume types
|
||||
# Create dataset from all combinations of all images, flavors, and
|
||||
# volume types
|
||||
dataset_list = DatasetList()
|
||||
for vtype in volume_type_list:
|
||||
for flavor in flavor_list:
|
||||
|
@ -55,6 +55,7 @@ class BaseVolumesClient(AutoMarshallingHTTPClient):
|
||||
def create_snapshot(self):
|
||||
pass
|
||||
|
||||
# Volumes
|
||||
def list_all_volumes(self, requestslib_kwargs=None):
|
||||
|
||||
"""GET /volumes"""
|
||||
@ -95,6 +96,16 @@ class BaseVolumesClient(AutoMarshallingHTTPClient):
|
||||
response_entity_type=self.response_models.VolumeResponse,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
def set_volume_status(self, volume_id, status, requestslib_kwargs=None):
|
||||
url = '{0}/volumes/{1}/action'.format(self.url, volume_id)
|
||||
|
||||
request_entity = self.request_models.StatusResetRequest(
|
||||
status=status)
|
||||
|
||||
return self.request(
|
||||
'POST', url, request_entity=request_entity,
|
||||
requestslib_kwargs=None)
|
||||
|
||||
# Volume Types
|
||||
def list_all_volume_types(self, requestslib_kwargs=None):
|
||||
|
||||
@ -165,6 +176,7 @@ class BaseVolumesClient(AutoMarshallingHTTPClient):
|
||||
return self.request(
|
||||
'DELETE', url, requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
# Snapshots
|
||||
def list_all_snapshots(self, requestslib_kwargs=None):
|
||||
|
||||
"""GET /snapshots"""
|
||||
@ -172,8 +184,7 @@ class BaseVolumesClient(AutoMarshallingHTTPClient):
|
||||
url = '{0}/snapshots'.format(self.url)
|
||||
|
||||
return self.request(
|
||||
'GET', url,
|
||||
response_entity_type=
|
||||
'GET', url, response_entity_type=
|
||||
self.response_models.VolumeSnapshotListResponse,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
@ -183,8 +194,7 @@ class BaseVolumesClient(AutoMarshallingHTTPClient):
|
||||
|
||||
url = '{0}/snapshots/detail'.format(self.url)
|
||||
return self.request(
|
||||
'GET', url,
|
||||
response_entity_type=
|
||||
'GET', url, response_entity_type=
|
||||
self.response_models.VolumeSnapshotListResponse,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
@ -208,3 +218,39 @@ class BaseVolumesClient(AutoMarshallingHTTPClient):
|
||||
'DELETE', url,
|
||||
response_entity_type=self.response_models.VolumeSnapshotResponse,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
def set_snapshot_status(
|
||||
self, snapshot_id, status, requestslib_kwargs=None):
|
||||
url = '{0}/snapshots/{1}/action'.format(self.url, snapshot_id)
|
||||
|
||||
request_entity = self.request_models.StatusResetRequest(
|
||||
status=status)
|
||||
|
||||
return self.request(
|
||||
'POST', url, request_entity=request_entity,
|
||||
requestslib_kwargs=None)
|
||||
|
||||
# Quotas
|
||||
def list_quotas(self, target_tenant_id, requestslib_kwargs=None):
|
||||
"""GET /{admin_tenant_id}/os-quota-sets/{target_tenant_id}"""
|
||||
|
||||
url = '{url}/os-quota-sets/{target_tenant_id}'.format(
|
||||
url=self.url, target_tenant_id=target_tenant_id)
|
||||
|
||||
return self.request(
|
||||
'GET', url,
|
||||
response_entity_type=self.response_models.QuotaListResponse,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
def list_quotas_usage(self, target_tenant_id, requestslib_kwargs=None):
|
||||
"""GET /{admin_tenant_id}/os-quota-sets/{target_tenant_id}"""
|
||||
|
||||
url = '{url}/os-quota-sets/{target_tenant_id}'.format(
|
||||
url=self.url, target_tenant_id=target_tenant_id)
|
||||
|
||||
params = {'usage': True}
|
||||
|
||||
return self.request(
|
||||
'GET', url,
|
||||
response_entity_type=self.response_models.QuotaUsageResponse,
|
||||
params=params, requestslib_kwargs=requestslib_kwargs)
|
||||
|
12
cloudcafe/blockstorage/volumes_api/common/models/requests.py
Normal file
12
cloudcafe/blockstorage/volumes_api/common/models/requests.py
Normal file
@ -0,0 +1,12 @@
|
||||
from cafe.engine.models.base import AutoMarshallingModel
|
||||
import json
|
||||
|
||||
|
||||
class StatusResetRequest(AutoMarshallingModel):
|
||||
def __init__(self, status=None):
|
||||
super(StatusResetRequest, self).__init__()
|
||||
self.status = status
|
||||
|
||||
def _obj_to_json(self):
|
||||
data = {"os-reset_status": {"status": self.status}}
|
||||
return json.dumps(data)
|
@ -0,0 +1,40 @@
|
||||
from cafe.engine.models.base import AutoMarshallingDictModel
|
||||
import json
|
||||
|
||||
|
||||
class QuotaUsageResponse(AutoMarshallingDictModel):
|
||||
""" This model represents the content of a dictionary of dictionaries.
|
||||
The key-names are arbitrary, and so no conversion to a namespace is
|
||||
attempted
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def _json_to_obj(cls, json_dict):
|
||||
quotaset = QuotaListResponse()
|
||||
|
||||
data = json.loads(json_dict).get('quota_set')
|
||||
quotaset['id'] = data.get('id')
|
||||
for k, v in data.items():
|
||||
if type(v) == type(dict()):
|
||||
quotaset[k] = _QuotaUsageResponseItem(**v)
|
||||
|
||||
return quotaset
|
||||
|
||||
|
||||
class _QuotaUsageResponseItem(object):
|
||||
|
||||
def __init__(self, in_use=None, limit=None, reserved=None):
|
||||
self.in_use = in_use
|
||||
self.limit = limit
|
||||
self.reserved = reserved
|
||||
|
||||
|
||||
class QuotaListResponse(AutoMarshallingDictModel):
|
||||
""" This model represents the content of a dictionary of dictionaries.
|
||||
The key-names are arbitrary, and so no conversion to a namespace is
|
||||
attempted
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def _json_to_obj(cls, json_dict):
|
||||
return QuotaListResponse(**json.loads(json_dict).get('quota_set'))
|
@ -21,6 +21,10 @@ from cafe.engine.models.base import AutoMarshallingModel
|
||||
from cloudcafe.blockstorage.volumes_api.common.models.automarshalling import \
|
||||
CommonModelProperties
|
||||
|
||||
# Import common requests
|
||||
from cloudcafe.blockstorage.volumes_api.common.models.requests import \
|
||||
StatusResetRequest
|
||||
|
||||
|
||||
class VolumeRequest(CommonModelProperties, AutoMarshallingModel):
|
||||
|
||||
|
@ -19,6 +19,10 @@ from cloudcafe.blockstorage.volumes_api.common.models.automarshalling import \
|
||||
from cloudcafe.blockstorage.volumes_api.common.models.automarshalling import \
|
||||
CommonModelProperties
|
||||
|
||||
# Import common responses
|
||||
from cloudcafe.blockstorage.volumes_api.common.models.responses import \
|
||||
QuotaUsageResponse, QuotaListResponse
|
||||
|
||||
|
||||
class VolumeResponse(CommonModelProperties, _VolumesAPIBaseModel):
|
||||
obj_model_key = 'volume'
|
||||
|
@ -21,6 +21,10 @@ from cafe.engine.models.base import AutoMarshallingModel
|
||||
from cloudcafe.blockstorage.volumes_api.common.models.automarshalling import \
|
||||
CommonModelProperties
|
||||
|
||||
# Import common requests
|
||||
from cloudcafe.blockstorage.volumes_api.common.models.requests import \
|
||||
StatusResetRequest
|
||||
|
||||
|
||||
class VolumeRequest(CommonModelProperties, AutoMarshallingModel):
|
||||
|
||||
|
@ -19,6 +19,10 @@ from cloudcafe.blockstorage.volumes_api.common.models.automarshalling import \
|
||||
from cloudcafe.blockstorage.volumes_api.common.models.automarshalling import \
|
||||
CommonModelProperties
|
||||
|
||||
# Import common responses
|
||||
from cloudcafe.blockstorage.volumes_api.common.models.responses import \
|
||||
QuotaUsageResponse, QuotaListResponse
|
||||
|
||||
|
||||
class VolumeResponse(CommonModelProperties, _VolumesAPIBaseModel):
|
||||
obj_model_key = 'volume'
|
||||
|
Loading…
Reference in New Issue
Block a user