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:
Jose Idar 2015-06-17 12:09:10 -05:00
parent 8700ab625d
commit a8c1b3a387
8 changed files with 135 additions and 10 deletions

View File

@ -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:

View File

@ -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)

View 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)

View File

@ -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'))

View File

@ -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):

View File

@ -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'

View File

@ -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):

View File

@ -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'