Add support of new API URLs after port of extensions to core API
Make manilaclient support API URLs and actions rename after port of extensions to core API. Depends-on: I82f00114db985b4b3bf4db0a64191559508ac600 Implements bp ext-to-core Change-Id: I44f71ca094f230f3c22ade241884a1b23865c81a
This commit is contained in:
parent
c34e3b7d2c
commit
28263b936d
@ -31,7 +31,7 @@ if not LOG.handlers:
|
||||
LOG.addHandler(logging.StreamHandler())
|
||||
|
||||
|
||||
MAX_VERSION = '2.6'
|
||||
MAX_VERSION = '2.7'
|
||||
MIN_VERSION = '2.0'
|
||||
DEPRECATED_VERSION = '1.0'
|
||||
_VERSIONED_METHOD_MAP = {}
|
||||
|
@ -19,6 +19,8 @@ import os
|
||||
from oslo_config import cfg
|
||||
import oslo_log._options as log_options
|
||||
|
||||
from manilaclient import api_versions
|
||||
|
||||
# 1. Define opts
|
||||
|
||||
# "auth_opts" are used by functional tests that are located in
|
||||
@ -67,6 +69,17 @@ base_opts = [
|
||||
]
|
||||
|
||||
share_opts = [
|
||||
cfg.StrOpt("min_api_microversion",
|
||||
default="1.0",
|
||||
help="The minimum API microversion is configured to be the "
|
||||
"value of the minimum microversion supported by "
|
||||
"Manilaclient functional tests. Defaults to 1.0."),
|
||||
cfg.StrOpt("max_api_microversion",
|
||||
default=api_versions.MAX_VERSION,
|
||||
help="The maximum API microversion is configured to be the "
|
||||
"value of the latest microversion supported by "
|
||||
"Manilaclient functional tests. Defaults to "
|
||||
"manilaclient's max supported API microversion."),
|
||||
cfg.StrOpt("share_network",
|
||||
default=None,
|
||||
help="Share network Name or ID, that will be used for shares. "
|
||||
|
@ -21,6 +21,7 @@ from tempest_lib import exceptions as lib_exc
|
||||
|
||||
from manilaclient import config
|
||||
from manilaclient.tests.functional import client
|
||||
from manilaclient.tests.functional import utils
|
||||
|
||||
CONF = config.CONF
|
||||
LOG = log.getLogger(__name__)
|
||||
@ -85,19 +86,25 @@ class BaseTestCase(base.ClientTestBase):
|
||||
if "client" not in res:
|
||||
res["client"] = cls.get_cleanup_client()
|
||||
if not(res["deleted"]):
|
||||
res_id = res['id']
|
||||
res_id = res["id"]
|
||||
client = res["client"]
|
||||
with handle_cleanup_exceptions():
|
||||
# TODO(vponomaryov): add support for other resources
|
||||
if res["type"] is "share_type":
|
||||
client.delete_share_type(res_id)
|
||||
client.wait_for_share_type_deletion(res_id)
|
||||
client.delete_share_type(
|
||||
res_id, microversion=res["microversion"])
|
||||
client.wait_for_share_type_deletion(
|
||||
res_id, microversion=res["microversion"])
|
||||
elif res["type"] is "share_network":
|
||||
client.delete_share_network(res_id)
|
||||
client.wait_for_share_network_deletion(res_id)
|
||||
client.delete_share_network(
|
||||
res_id, microversion=res["microversion"])
|
||||
client.wait_for_share_network_deletion(
|
||||
res_id, microversion=res["microversion"])
|
||||
elif res["type"] is "share":
|
||||
client.delete_share(res_id)
|
||||
client.wait_for_share_deletion(res_id)
|
||||
client.delete_share(
|
||||
res_id, microversion=res["microversion"])
|
||||
client.wait_for_share_deletion(
|
||||
res_id, microversion=res["microversion"])
|
||||
else:
|
||||
LOG.warn("Provided unsupported resource type for "
|
||||
"cleanup '%s'. Skipping." % res["type"])
|
||||
@ -142,21 +149,29 @@ class BaseTestCase(base.ClientTestBase):
|
||||
def _get_clients(self):
|
||||
return {'admin': self.admin_client, 'user': self.user_client}
|
||||
|
||||
def skip_if_microversion_not_supported(self, microversion):
|
||||
if not utils.is_microversion_supported(microversion):
|
||||
raise self.skipException(
|
||||
"Microversion '%s' is not supported." % microversion)
|
||||
|
||||
@classmethod
|
||||
def create_share_type(cls, name=None, driver_handles_share_servers=True,
|
||||
snapshot_support=True,
|
||||
is_public=True, client=None, cleanup_in_class=True):
|
||||
snapshot_support=True, is_public=True, client=None,
|
||||
cleanup_in_class=True, microversion=None):
|
||||
if client is None:
|
||||
client = cls.get_admin_client()
|
||||
share_type = client.create_share_type(
|
||||
name=name,
|
||||
driver_handles_share_servers=driver_handles_share_servers,
|
||||
snapshot_support=snapshot_support,
|
||||
is_public=is_public)
|
||||
is_public=is_public,
|
||||
microversion=microversion,
|
||||
)
|
||||
resource = {
|
||||
"type": "share_type",
|
||||
"id": share_type["ID"],
|
||||
"client": client,
|
||||
"microversion": microversion,
|
||||
}
|
||||
if cleanup_in_class:
|
||||
cls.class_resources.insert(0, resource)
|
||||
@ -168,7 +183,7 @@ class BaseTestCase(base.ClientTestBase):
|
||||
def create_share_network(cls, name=None, description=None,
|
||||
nova_net_id=None, neutron_net_id=None,
|
||||
neutron_subnet_id=None, client=None,
|
||||
cleanup_in_class=True):
|
||||
cleanup_in_class=True, microversion=None):
|
||||
if client is None:
|
||||
client = cls.get_admin_client()
|
||||
share_network = client.create_share_network(
|
||||
@ -176,11 +191,14 @@ class BaseTestCase(base.ClientTestBase):
|
||||
description=description,
|
||||
nova_net_id=nova_net_id,
|
||||
neutron_net_id=neutron_net_id,
|
||||
neutron_subnet_id=neutron_subnet_id)
|
||||
neutron_subnet_id=neutron_subnet_id,
|
||||
microversion=microversion,
|
||||
)
|
||||
resource = {
|
||||
"type": "share_network",
|
||||
"id": share_network["id"],
|
||||
"client": client,
|
||||
"microversion": microversion,
|
||||
}
|
||||
if cleanup_in_class:
|
||||
cls.class_resources.insert(0, resource)
|
||||
@ -193,7 +211,7 @@ class BaseTestCase(base.ClientTestBase):
|
||||
share_type=None, name=None, description=None,
|
||||
public=False, snapshot=None, metadata=None,
|
||||
client=None, cleanup_in_class=False,
|
||||
wait_for_creation=True):
|
||||
wait_for_creation=True, microversion=None):
|
||||
if client is None:
|
||||
client = cls.get_admin_client()
|
||||
data = {
|
||||
@ -204,6 +222,7 @@ class BaseTestCase(base.ClientTestBase):
|
||||
'public': public,
|
||||
'snapshot': snapshot,
|
||||
'metadata': metadata,
|
||||
'microversion': microversion,
|
||||
}
|
||||
share_network = share_network or client.share_network
|
||||
share_type = share_type or CONF.share_type
|
||||
@ -216,6 +235,7 @@ class BaseTestCase(base.ClientTestBase):
|
||||
"type": "share",
|
||||
"id": share["id"],
|
||||
"client": client,
|
||||
"microversion": microversion,
|
||||
}
|
||||
if cleanup_in_class:
|
||||
cls.class_resources.insert(0, resource)
|
||||
@ -229,7 +249,7 @@ class BaseTestCase(base.ClientTestBase):
|
||||
def create_security_service(cls, type='ldap', name=None, description=None,
|
||||
dns_ip=None, server=None, domain=None,
|
||||
user=None, password=None, client=None,
|
||||
cleanup_in_class=False):
|
||||
cleanup_in_class=False, microversion=None):
|
||||
if client is None:
|
||||
client = cls.get_admin_client()
|
||||
data = {
|
||||
@ -241,12 +261,14 @@ class BaseTestCase(base.ClientTestBase):
|
||||
'server': server,
|
||||
'domain': domain,
|
||||
'dns_ip': dns_ip,
|
||||
'microversion': microversion,
|
||||
}
|
||||
ss = client.create_security_service(**data)
|
||||
resource = {
|
||||
"type": "share",
|
||||
"id": ss["id"],
|
||||
"client": client,
|
||||
"microversion": microversion,
|
||||
}
|
||||
if cleanup_in_class:
|
||||
cls.class_resources.insert(0, resource)
|
||||
|
@ -74,12 +74,14 @@ class ManilaCLIClient(base.CLIClient):
|
||||
self.build_timeout = CONF.build_timeout
|
||||
|
||||
def manila(self, action, flags='', params='', fail_ok=False,
|
||||
endpoint_type='publicURL', merge_stderr=False):
|
||||
endpoint_type='publicURL', merge_stderr=False,
|
||||
microversion=None):
|
||||
"""Executes manila command for the given action.
|
||||
|
||||
:param action: the cli command to run using manila
|
||||
:type action: string
|
||||
:param flags: any optional cli flags to use
|
||||
:param flags: any optional cli flags to use. For specifying
|
||||
microversion, please, use 'microversion' param
|
||||
:type flags: string
|
||||
:param params: any optional positional args to use
|
||||
:type params: string
|
||||
@ -90,13 +92,24 @@ class ManilaCLIClient(base.CLIClient):
|
||||
:type endpoint_type: string
|
||||
:param merge_stderr: if True the stderr buffer is merged into stdout
|
||||
:type merge_stderr: boolean
|
||||
:param microversion: API microversion to be used for request
|
||||
:type microversion: str
|
||||
"""
|
||||
flags += ' --endpoint-type %s' % endpoint_type
|
||||
if not microversion:
|
||||
# NOTE(vponomaryov): use max API version from config
|
||||
microversion = CONF.max_api_microversion
|
||||
|
||||
# NOTE(vponomaryov): it is possible that param 'flags' already
|
||||
# can contain '--os-share-api-version' key. If it is so and we
|
||||
# reached this part then value of 'microversion' param will be
|
||||
# used and existing one in 'flags' param will be ignored.
|
||||
flags += ' --os-share-api-version %s' % microversion
|
||||
return self.cmd_with_auth(
|
||||
'manila', action, flags, params, fail_ok, merge_stderr)
|
||||
|
||||
def wait_for_resource_deletion(self, res_type, res_id, interval=3,
|
||||
timeout=180):
|
||||
timeout=180, microversion=None):
|
||||
"""Resource deletion waiter.
|
||||
|
||||
:param res_type: text -- type of resource. Supported only 'share_type'.
|
||||
@ -116,11 +129,11 @@ class ManilaCLIClient(base.CLIClient):
|
||||
raise exceptions.InvalidResource(message=res_type)
|
||||
|
||||
end_loop_time = time.time() + timeout
|
||||
deleted = func(res_id)
|
||||
deleted = func(res_id, microversion=microversion)
|
||||
|
||||
while not (deleted or time.time() > end_loop_time):
|
||||
time.sleep(interval)
|
||||
deleted = func(res_id)
|
||||
deleted = func(res_id, microversion=microversion)
|
||||
|
||||
if not deleted:
|
||||
raise exceptions.ResourceReleaseFailed(
|
||||
@ -129,7 +142,8 @@ class ManilaCLIClient(base.CLIClient):
|
||||
# Share types
|
||||
|
||||
def create_share_type(self, name=None, driver_handles_share_servers=True,
|
||||
snapshot_support=True, is_public=True):
|
||||
snapshot_support=True, is_public=True,
|
||||
microversion=None):
|
||||
"""Creates share type.
|
||||
|
||||
:param name: text -- name of share type to use, if not set then
|
||||
@ -154,7 +168,7 @@ class ManilaCLIClient(base.CLIClient):
|
||||
'--snapshot-support %(snapshot_support)s') % {
|
||||
'name': name, 'dhss': dhss, 'is_public': is_public,
|
||||
'snapshot_support': snapshot_support}
|
||||
share_type_raw = self.manila(cmd)
|
||||
share_type_raw = self.manila(cmd, microversion=microversion)
|
||||
|
||||
# NOTE(vponomaryov): share type creation response is "list"-like with
|
||||
# only one element:
|
||||
@ -169,11 +183,12 @@ class ManilaCLIClient(base.CLIClient):
|
||||
return share_type
|
||||
|
||||
@not_found_wrapper
|
||||
def delete_share_type(self, share_type):
|
||||
def delete_share_type(self, share_type, microversion=None):
|
||||
"""Deletes share type by its Name or ID."""
|
||||
return self.manila('type-delete %s' % share_type)
|
||||
return self.manila(
|
||||
'type-delete %s' % share_type, microversion=microversion)
|
||||
|
||||
def list_share_types(self, list_all=True):
|
||||
def list_share_types(self, list_all=True, microversion=None):
|
||||
"""List share types.
|
||||
|
||||
:param list_all: bool -- whether to list all share types or only public
|
||||
@ -181,41 +196,43 @@ class ManilaCLIClient(base.CLIClient):
|
||||
cmd = 'type-list'
|
||||
if list_all:
|
||||
cmd += ' --all'
|
||||
share_types_raw = self.manila(cmd)
|
||||
share_types_raw = self.manila(cmd, microversion=microversion)
|
||||
share_types = output_parser.listing(share_types_raw)
|
||||
return share_types
|
||||
|
||||
def get_share_type(self, share_type):
|
||||
def get_share_type(self, share_type, microversion=None):
|
||||
"""Get share type.
|
||||
|
||||
:param share_type: str -- Name or ID of share type
|
||||
"""
|
||||
share_types = self.list_share_types(True)
|
||||
share_types = self.list_share_types(True, microversion=microversion)
|
||||
for st in share_types:
|
||||
if share_type in (st['ID'], st['Name']):
|
||||
return st
|
||||
raise tempest_lib_exc.NotFound()
|
||||
|
||||
def is_share_type_deleted(self, share_type):
|
||||
def is_share_type_deleted(self, share_type, microversion=None):
|
||||
"""Says whether share type is deleted or not.
|
||||
|
||||
:param share_type: text -- Name or ID of share type
|
||||
"""
|
||||
# NOTE(vponomaryov): we use 'list' operation because there is no
|
||||
# 'get/show' operation for share-types available for CLI
|
||||
share_types = self.list_share_types(list_all=True)
|
||||
share_types = self.list_share_types(
|
||||
list_all=True, microversion=microversion)
|
||||
for list_element in share_types:
|
||||
if share_type in (list_element['ID'], list_element['Name']):
|
||||
return False
|
||||
return True
|
||||
|
||||
def wait_for_share_type_deletion(self, share_type):
|
||||
def wait_for_share_type_deletion(self, share_type, microversion=None):
|
||||
"""Wait for share type deletion by its Name or ID.
|
||||
|
||||
:param share_type: text -- Name or ID of share type
|
||||
"""
|
||||
self.wait_for_resource_deletion(
|
||||
SHARE_TYPE, res_id=share_type, interval=2, timeout=6)
|
||||
SHARE_TYPE, res_id=share_type, interval=2, timeout=6,
|
||||
microversion=microversion)
|
||||
|
||||
def get_project_id(self, name_or_id):
|
||||
try:
|
||||
@ -228,24 +245,30 @@ class ManilaCLIClient(base.CLIClient):
|
||||
return project_id.strip()
|
||||
|
||||
@not_found_wrapper
|
||||
def add_share_type_access(self, share_type_name_or_id, project_id):
|
||||
def add_share_type_access(self, share_type_name_or_id, project_id,
|
||||
microversion=None):
|
||||
data = dict(st=share_type_name_or_id, project=project_id)
|
||||
self.manila('type-access-add %(st)s %(project)s' % data)
|
||||
self.manila('type-access-add %(st)s %(project)s' % data,
|
||||
microversion=microversion)
|
||||
|
||||
@not_found_wrapper
|
||||
def remove_share_type_access(self, share_type_name_or_id, project_id):
|
||||
def remove_share_type_access(self, share_type_name_or_id, project_id,
|
||||
microversion=None):
|
||||
data = dict(st=share_type_name_or_id, project=project_id)
|
||||
self.manila('type-access-remove %(st)s %(project)s' % data)
|
||||
self.manila('type-access-remove %(st)s %(project)s' % data,
|
||||
microversion=microversion)
|
||||
|
||||
@not_found_wrapper
|
||||
def list_share_type_access(self, share_type_id):
|
||||
projects_raw = self.manila('type-access-list %s' % share_type_id)
|
||||
def list_share_type_access(self, share_type_id, microversion=None):
|
||||
projects_raw = self.manila(
|
||||
'type-access-list %s' % share_type_id, microversion=microversion)
|
||||
projects = output_parser.listing(projects_raw)
|
||||
project_ids = [pr['Project_ID'] for pr in projects]
|
||||
return project_ids
|
||||
|
||||
@not_found_wrapper
|
||||
def set_share_type_extra_specs(self, share_type_name_or_id, extra_specs):
|
||||
def set_share_type_extra_specs(self, share_type_name_or_id, extra_specs,
|
||||
microversion=None):
|
||||
"""Set key-value pair for share type."""
|
||||
if not (isinstance(extra_specs, dict) and extra_specs):
|
||||
raise exceptions.InvalidData(
|
||||
@ -253,29 +276,33 @@ class ManilaCLIClient(base.CLIClient):
|
||||
cmd = 'type-key %s set ' % share_type_name_or_id
|
||||
for key, value in extra_specs.items():
|
||||
cmd += '%(key)s=%(value)s ' % {'key': key, 'value': value}
|
||||
return self.manila(cmd)
|
||||
return self.manila(cmd, microversion=microversion)
|
||||
|
||||
@not_found_wrapper
|
||||
def unset_share_type_extra_specs(self, share_type_name_or_id,
|
||||
extra_specs_keys):
|
||||
extra_specs_keys, microversion=None):
|
||||
"""Unset key-value pair for share type."""
|
||||
if not (isinstance(extra_specs_keys, list) and extra_specs_keys):
|
||||
if not (isinstance(extra_specs_keys, (list, tuple, set)) and
|
||||
extra_specs_keys):
|
||||
raise exceptions.InvalidData(
|
||||
message='Provided invalid extra specs - %s' % extra_specs_keys)
|
||||
cmd = 'type-key %s unset ' % share_type_name_or_id
|
||||
for key in extra_specs_keys:
|
||||
cmd += '%s ' % key
|
||||
return self.manila(cmd)
|
||||
return self.manila(cmd, microversion=microversion)
|
||||
|
||||
def list_all_share_type_extra_specs(self):
|
||||
def list_all_share_type_extra_specs(self, microversion=None):
|
||||
"""List extra specs for all share types."""
|
||||
extra_specs_raw = self.manila('extra-specs-list')
|
||||
extra_specs_raw = self.manila(
|
||||
'extra-specs-list', microversion=microversion)
|
||||
extra_specs = utils.listing(extra_specs_raw)
|
||||
return extra_specs
|
||||
|
||||
def list_share_type_extra_specs(self, share_type_name_or_id):
|
||||
def list_share_type_extra_specs(self, share_type_name_or_id,
|
||||
microversion=None):
|
||||
"""List extra specs for specific share type by its Name or ID."""
|
||||
all_share_types = self.list_all_share_type_extra_specs()
|
||||
all_share_types = self.list_all_share_type_extra_specs(
|
||||
microversion=microversion)
|
||||
for share_type in all_share_types:
|
||||
if share_type_name_or_id in (share_type['ID'], share_type['Name']):
|
||||
return share_type['all_extra_specs']
|
||||
@ -285,7 +312,7 @@ class ManilaCLIClient(base.CLIClient):
|
||||
|
||||
def create_share_network(self, name=None, description=None,
|
||||
nova_net_id=None, neutron_net_id=None,
|
||||
neutron_subnet_id=None):
|
||||
neutron_subnet_id=None, microversion=None):
|
||||
"""Creates share network.
|
||||
|
||||
:param name: text -- desired name of new share network
|
||||
@ -303,7 +330,8 @@ class ManilaCLIClient(base.CLIClient):
|
||||
nova_net_id=nova_net_id,
|
||||
neutron_net_id=neutron_net_id,
|
||||
neutron_subnet_id=neutron_subnet_id)
|
||||
share_network_raw = self.manila('share-network-create %s' % params)
|
||||
share_network_raw = self.manila(
|
||||
'share-network-create %s' % params, microversion=microversion)
|
||||
share_network = output_parser.details(share_network_raw)
|
||||
return share_network
|
||||
|
||||
@ -331,17 +359,17 @@ class ManilaCLIClient(base.CLIClient):
|
||||
return cmd
|
||||
|
||||
@not_found_wrapper
|
||||
def get_share_network(self, share_network):
|
||||
def get_share_network(self, share_network, microversion=None):
|
||||
"""Returns share network by its Name or ID."""
|
||||
share_network_raw = self.manila(
|
||||
'share-network-show %s' % share_network)
|
||||
'share-network-show %s' % share_network, microversion=microversion)
|
||||
share_network = output_parser.details(share_network_raw)
|
||||
return share_network
|
||||
|
||||
@not_found_wrapper
|
||||
def update_share_network(self, share_network, name=None, description=None,
|
||||
nova_net_id=None, neutron_net_id=None,
|
||||
neutron_subnet_id=None):
|
||||
neutron_subnet_id=None, microversion=None):
|
||||
"""Updates share-network by its name or ID.
|
||||
|
||||
:param name: text -- new name for share network
|
||||
@ -361,14 +389,16 @@ class ManilaCLIClient(base.CLIClient):
|
||||
neutron_subnet_id=neutron_subnet_id)
|
||||
share_network_raw = self.manila(
|
||||
'share-network-update %(sn)s %(params)s' % dict(
|
||||
sn=share_network, params=sn_params))
|
||||
sn=share_network, params=sn_params),
|
||||
microversion=microversion)
|
||||
share_network = output_parser.details(share_network_raw)
|
||||
return share_network
|
||||
|
||||
@not_found_wrapper
|
||||
def delete_share_network(self, share_network):
|
||||
def delete_share_network(self, share_network, microversion=None):
|
||||
"""Deletes share network by its Name or ID."""
|
||||
return self.manila('share-network-delete %s' % share_network)
|
||||
return self.manila('share-network-delete %s' % share_network,
|
||||
microversion=microversion)
|
||||
|
||||
@staticmethod
|
||||
def _stranslate_to_cli_optional_param(param):
|
||||
@ -379,7 +409,8 @@ class ManilaCLIClient(base.CLIClient):
|
||||
param = '-' + param
|
||||
return param.replace('_', '-')
|
||||
|
||||
def list_share_networks(self, all_tenants=False, filters=None):
|
||||
def list_share_networks(self, all_tenants=False, filters=None,
|
||||
microversion=None):
|
||||
"""List share networks.
|
||||
|
||||
:param all_tenants: bool -- whether to list share-networks that belong
|
||||
@ -399,34 +430,37 @@ class ManilaCLIClient(base.CLIClient):
|
||||
for k, v in filters.items():
|
||||
cmd += '%(k)s=%(v)s ' % {
|
||||
'k': self._stranslate_to_cli_optional_param(k), 'v': v}
|
||||
share_networks_raw = self.manila(cmd)
|
||||
share_networks_raw = self.manila(cmd, microversion=microversion)
|
||||
share_networks = utils.listing(share_networks_raw)
|
||||
return share_networks
|
||||
|
||||
def is_share_network_deleted(self, share_network):
|
||||
def is_share_network_deleted(self, share_network, microversion=None):
|
||||
"""Says whether share network is deleted or not.
|
||||
|
||||
:param share_network: text -- Name or ID of share network
|
||||
"""
|
||||
share_types = self.list_share_networks(True)
|
||||
share_types = self.list_share_networks(True, microversion=microversion)
|
||||
for list_element in share_types:
|
||||
if share_network in (list_element['id'], list_element['name']):
|
||||
return False
|
||||
return True
|
||||
|
||||
def wait_for_share_network_deletion(self, share_network):
|
||||
def wait_for_share_network_deletion(self, share_network,
|
||||
microversion=None):
|
||||
"""Wait for share network deletion by its Name or ID.
|
||||
|
||||
:param share_network: text -- Name or ID of share network
|
||||
"""
|
||||
self.wait_for_resource_deletion(
|
||||
SHARE_NETWORK, res_id=share_network, interval=2, timeout=6)
|
||||
SHARE_NETWORK, res_id=share_network, interval=2, timeout=6,
|
||||
microversion=microversion)
|
||||
|
||||
# Shares
|
||||
|
||||
def create_share(self, share_protocol, size, share_network=None,
|
||||
share_type=None, name=None, description=None,
|
||||
public=False, snapshot=None, metadata=None):
|
||||
public=False, snapshot=None, metadata=None,
|
||||
microversion=None):
|
||||
"""Creates a share.
|
||||
|
||||
:param share_protocol: str -- share protocol of a share.
|
||||
@ -439,6 +473,7 @@ class ManilaCLIClient(base.CLIClient):
|
||||
Default is False.
|
||||
:param snapshot: str -- Name or ID of a snapshot to use as source.
|
||||
:param metadata: dict -- key-value data to provide with share creation.
|
||||
:param microversion: str -- API microversion that should be used.
|
||||
"""
|
||||
cmd = 'create %(share_protocol)s %(size)s ' % {
|
||||
'share_protocol': share_protocol, 'size': size}
|
||||
@ -462,20 +497,20 @@ class ManilaCLIClient(base.CLIClient):
|
||||
metadata_cli += '%(k)s=%(v)s ' % {'k': k, 'v': v}
|
||||
if metadata_cli:
|
||||
cmd += '--metadata %s ' % metadata_cli
|
||||
share_raw = self.manila(cmd)
|
||||
share_raw = self.manila(cmd, microversion=microversion)
|
||||
share = output_parser.details(share_raw)
|
||||
return share
|
||||
|
||||
@not_found_wrapper
|
||||
def get_share(self, share):
|
||||
def get_share(self, share, microversion=None):
|
||||
"""Returns a share by its Name or ID."""
|
||||
share_raw = self.manila('show %s' % share)
|
||||
share_raw = self.manila('show %s' % share, microversion=microversion)
|
||||
share = output_parser.details(share_raw)
|
||||
return share
|
||||
|
||||
@not_found_wrapper
|
||||
def update_share(self, share, name=None, description=None,
|
||||
is_public=False):
|
||||
is_public=False, microversion=None):
|
||||
"""Updates a share.
|
||||
|
||||
:param share: str -- name or ID of a share that should be updated.
|
||||
@ -492,11 +527,11 @@ class ManilaCLIClient(base.CLIClient):
|
||||
is_public = strutils.bool_from_string(is_public, strict=True)
|
||||
cmd += '--is-public %s ' % is_public
|
||||
|
||||
return self.manila(cmd)
|
||||
return self.manila(cmd, microversion=microversion)
|
||||
|
||||
@not_found_wrapper
|
||||
@forbidden_wrapper
|
||||
def delete_share(self, shares):
|
||||
def delete_share(self, shares, microversion=None):
|
||||
"""Deletes share[s] by Names or IDs.
|
||||
|
||||
:param shares: either str or list of str that can be either Name
|
||||
@ -507,9 +542,10 @@ class ManilaCLIClient(base.CLIClient):
|
||||
cmd = 'delete '
|
||||
for share in shares:
|
||||
cmd += '%s ' % share
|
||||
return self.manila(cmd)
|
||||
return self.manila(cmd, microversion=microversion)
|
||||
|
||||
def list_shares(self, all_tenants=False, filters=None, columns=None):
|
||||
def list_shares(self, all_tenants=False, filters=None, columns=None,
|
||||
microversion=None):
|
||||
"""List shares.
|
||||
|
||||
:param all_tenants: bool -- whether to list shares that belong
|
||||
@ -533,39 +569,40 @@ class ManilaCLIClient(base.CLIClient):
|
||||
'k': self._stranslate_to_cli_optional_param(k), 'v': v}
|
||||
if columns is not None:
|
||||
cmd += '--columns ' + columns
|
||||
shares_raw = self.manila(cmd)
|
||||
shares_raw = self.manila(cmd, microversion=microversion)
|
||||
shares = utils.listing(shares_raw)
|
||||
return shares
|
||||
|
||||
def is_share_deleted(self, share):
|
||||
def is_share_deleted(self, share, microversion=None):
|
||||
"""Says whether share is deleted or not.
|
||||
|
||||
:param share: str -- Name or ID of share
|
||||
"""
|
||||
try:
|
||||
self.get_share(share)
|
||||
self.get_share(share, microversion=microversion)
|
||||
return False
|
||||
except tempest_lib_exc.NotFound:
|
||||
return True
|
||||
|
||||
def wait_for_share_deletion(self, share):
|
||||
def wait_for_share_deletion(self, share, microversion=None):
|
||||
"""Wait for share deletion by its Name or ID.
|
||||
|
||||
:param share: str -- Name or ID of share
|
||||
"""
|
||||
self.wait_for_resource_deletion(
|
||||
SHARE, res_id=share, interval=5, timeout=300)
|
||||
SHARE, res_id=share, interval=5, timeout=300,
|
||||
microversion=microversion)
|
||||
|
||||
def wait_for_share_status(self, share, status):
|
||||
def wait_for_share_status(self, share, status, microversion=None):
|
||||
"""Waits for a share to reach a given status."""
|
||||
body = self.get_share(share)
|
||||
body = self.get_share(share, microversion=microversion)
|
||||
share_name = body['name']
|
||||
share_status = body['status']
|
||||
start = int(time.time())
|
||||
|
||||
while share_status != status:
|
||||
time.sleep(self.build_interval)
|
||||
body = self.get_share(share)
|
||||
body = self.get_share(share, microversion=microversion)
|
||||
share_status = body['status']
|
||||
|
||||
if share_status == status:
|
||||
@ -582,7 +619,8 @@ class ManilaCLIClient(base.CLIClient):
|
||||
raise tempest_lib_exc.TimeoutException(message)
|
||||
|
||||
@not_found_wrapper
|
||||
def _set_share_metadata(self, share, data, update_all=False):
|
||||
def _set_share_metadata(self, share, data, update_all=False,
|
||||
microversion=None):
|
||||
"""Sets a share metadata.
|
||||
|
||||
:param share: str -- Name or ID of a share.
|
||||
@ -600,18 +638,20 @@ class ManilaCLIClient(base.CLIClient):
|
||||
cmd = 'metadata %s set ' % share
|
||||
for k, v in data.items():
|
||||
cmd += '%(k)s=%(v)s ' % {'k': k, 'v': v}
|
||||
return self.manila(cmd)
|
||||
return self.manila(cmd, microversion=microversion)
|
||||
|
||||
def update_all_share_metadata(self, share, data):
|
||||
metadata_raw = self._set_share_metadata(share, data, True)
|
||||
def update_all_share_metadata(self, share, data, microversion=None):
|
||||
metadata_raw = self._set_share_metadata(
|
||||
share, data, True, microversion=microversion)
|
||||
metadata = output_parser.details(metadata_raw)
|
||||
return metadata
|
||||
|
||||
def set_share_metadata(self, share, data):
|
||||
return self._set_share_metadata(share, data, False)
|
||||
def set_share_metadata(self, share, data, microversion=None):
|
||||
return self._set_share_metadata(
|
||||
share, data, False, microversion=microversion)
|
||||
|
||||
@not_found_wrapper
|
||||
def unset_share_metadata(self, share, keys):
|
||||
def unset_share_metadata(self, share, keys, microversion=None):
|
||||
"""Unsets some share metadata by keys.
|
||||
|
||||
:param share: str -- Name or ID of a share
|
||||
@ -624,32 +664,35 @@ class ManilaCLIClient(base.CLIClient):
|
||||
cmd = 'metadata %s unset ' % share
|
||||
for key in keys:
|
||||
cmd += '%s ' % key
|
||||
return self.manila(cmd)
|
||||
return self.manila(cmd, microversion=microversion)
|
||||
|
||||
@not_found_wrapper
|
||||
def get_share_metadata(self, share):
|
||||
def get_share_metadata(self, share, microversion=None):
|
||||
"""Returns list of all share metadata.
|
||||
|
||||
:param share: str -- Name or ID of a share.
|
||||
"""
|
||||
metadata_raw = self.manila('metadata-show %s' % share)
|
||||
metadata_raw = self.manila(
|
||||
'metadata-show %s' % share, microversion=microversion)
|
||||
metadata = output_parser.details(metadata_raw)
|
||||
return metadata
|
||||
|
||||
@not_found_wrapper
|
||||
def list_access(self, share_id):
|
||||
access_list_raw = self.manila('access-list %s' % share_id)
|
||||
def list_access(self, share_id, microversion=None):
|
||||
access_list_raw = self.manila(
|
||||
'access-list %s' % share_id, microversion=microversion)
|
||||
return output_parser.listing(access_list_raw)
|
||||
|
||||
@not_found_wrapper
|
||||
def get_access(self, share_id, access_id):
|
||||
for access in self.list_access(share_id):
|
||||
def get_access(self, share_id, access_id, microversion=None):
|
||||
for access in self.list_access(share_id, microversion=microversion):
|
||||
if access['id'] == access_id:
|
||||
return access
|
||||
raise tempest_lib_exc.NotFound()
|
||||
|
||||
@not_found_wrapper
|
||||
def access_allow(self, share_id, access_type, access_to, access_level):
|
||||
def access_allow(self, share_id, access_type, access_to, access_level,
|
||||
microversion=None):
|
||||
raw_access = self.manila(
|
||||
'access-allow --access-level %(level)s %(id)s %(type)s '
|
||||
'%(access_to)s' % {
|
||||
@ -657,23 +700,29 @@ class ManilaCLIClient(base.CLIClient):
|
||||
'id': share_id,
|
||||
'type': access_type,
|
||||
'access_to': access_to,
|
||||
})
|
||||
},
|
||||
microversion=microversion)
|
||||
return output_parser.details(raw_access)
|
||||
|
||||
@not_found_wrapper
|
||||
def access_deny(self, share_id, access_id):
|
||||
self.manila('access-deny %(share_id)s %(access_id)s' % {
|
||||
'share_id': share_id,
|
||||
'access_id': access_id,
|
||||
})
|
||||
def access_deny(self, share_id, access_id, microversion=None):
|
||||
return self.manila(
|
||||
'access-deny %(share_id)s %(access_id)s' % {
|
||||
'share_id': share_id,
|
||||
'access_id': access_id,
|
||||
},
|
||||
microversion=microversion)
|
||||
|
||||
def wait_for_access_rule_status(self, share_id, access_id, state='active'):
|
||||
access = self.get_access(share_id, access_id)
|
||||
def wait_for_access_rule_status(self, share_id, access_id, state='active',
|
||||
microversion=None):
|
||||
access = self.get_access(
|
||||
share_id, access_id, microversion=microversion)
|
||||
|
||||
start = int(time.time())
|
||||
while access['state'] != state:
|
||||
time.sleep(self.build_interval)
|
||||
access = self.get_access(share_id, access_id)
|
||||
access = self.get_access(
|
||||
share_id, access_id, microversion=microversion)
|
||||
|
||||
if access['state'] == state:
|
||||
return
|
||||
@ -689,9 +738,11 @@ class ManilaCLIClient(base.CLIClient):
|
||||
"build_timeout": self.build_timeout})
|
||||
raise tempest_lib_exc.TimeoutException(message)
|
||||
|
||||
def wait_for_access_rule_deletion(self, share_id, access_id):
|
||||
def wait_for_access_rule_deletion(self, share_id, access_id,
|
||||
microversion=None):
|
||||
try:
|
||||
access = self.get_access(share_id, access_id)
|
||||
access = self.get_access(
|
||||
share_id, access_id, microversion=microversion)
|
||||
except tempest_lib_exc.NotFound:
|
||||
return
|
||||
|
||||
@ -699,7 +750,8 @@ class ManilaCLIClient(base.CLIClient):
|
||||
while True:
|
||||
time.sleep(self.build_interval)
|
||||
try:
|
||||
access = self.get_access(share_id, access_id)
|
||||
access = self.get_access(
|
||||
share_id, access_id, microversion=microversion)
|
||||
except tempest_lib_exc.NotFound:
|
||||
return
|
||||
|
||||
@ -715,7 +767,7 @@ class ManilaCLIClient(base.CLIClient):
|
||||
|
||||
def create_security_service(self, type='ldap', name=None, description=None,
|
||||
dns_ip=None, server=None, domain=None,
|
||||
user=None, password=None):
|
||||
user=None, password=None, microversion=None):
|
||||
"""Creates security service.
|
||||
|
||||
:param type: security service type (ldap, kerberos or active_directory)
|
||||
@ -738,14 +790,15 @@ class ManilaCLIClient(base.CLIClient):
|
||||
user=user,
|
||||
password=password)
|
||||
|
||||
ss_raw = self.manila(cmd)
|
||||
ss_raw = self.manila(cmd, microversion=microversion)
|
||||
security_service = output_parser.details(ss_raw)
|
||||
return security_service
|
||||
|
||||
@not_found_wrapper
|
||||
def update_security_service(self, security_service, name=None,
|
||||
description=None, dns_ip=None, server=None,
|
||||
domain=None, user=None, password=None):
|
||||
domain=None, user=None, password=None,
|
||||
microversion=None):
|
||||
cmd = 'security-service-update %s ' % security_service
|
||||
cmd += self. _combine_security_service_data(
|
||||
name=name,
|
||||
@ -755,7 +808,8 @@ class ManilaCLIClient(base.CLIClient):
|
||||
domain=domain,
|
||||
user=user,
|
||||
password=password)
|
||||
return output_parser.details(self.manila(cmd))
|
||||
return output_parser.details(
|
||||
self.manila(cmd, microversion=microversion))
|
||||
|
||||
def _combine_security_service_data(self, name=None, description=None,
|
||||
dns_ip=None, server=None, domain=None,
|
||||
|
@ -17,6 +17,7 @@ import ddt
|
||||
from tempest_lib import exceptions
|
||||
|
||||
from manilaclient.tests.functional import base
|
||||
from manilaclient.tests.functional import utils
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@ -25,7 +26,7 @@ class ManilaClientTestQuotasReadOnly(base.BaseTestCase):
|
||||
def test_quota_class_show_by_admin(self):
|
||||
roles = self.parser.listing(
|
||||
self.clients['admin'].manila('quota-class-show', params='abc'))
|
||||
self.assertTableStruct(roles, ['Property', 'Value'])
|
||||
self.assertTableStruct(roles, ('Property', 'Value'))
|
||||
|
||||
def test_quota_class_show_by_user(self):
|
||||
self.assertRaises(
|
||||
@ -34,13 +35,47 @@ class ManilaClientTestQuotasReadOnly(base.BaseTestCase):
|
||||
'quota-class-show',
|
||||
params='abc')
|
||||
|
||||
@ddt.data('admin', 'user')
|
||||
def test_quota_defaults(self, role):
|
||||
roles = self.parser.listing(
|
||||
self.clients[role].manila('quota-defaults'))
|
||||
self.assertTableStruct(roles, ['Property', 'Value'])
|
||||
def _get_quotas(self, role, operation, microversion):
|
||||
roles = self.parser.listing(self.clients[role].manila(
|
||||
'quota-%s' % operation, microversion=microversion))
|
||||
self.assertTableStruct(roles, ('Property', 'Value'))
|
||||
|
||||
@ddt.data('admin', 'user')
|
||||
def test_quota_show(self, role):
|
||||
roles = self.parser.listing(self.clients[role].manila('quota-show'))
|
||||
self.assertTableStruct(roles, ['Property', 'Value'])
|
||||
@utils.skip_if_microversion_not_supported("1.0")
|
||||
def test_quota_defaults_api_1_0(self, role):
|
||||
self._get_quotas(role, "defaults", "1.0")
|
||||
|
||||
@ddt.data('admin', 'user')
|
||||
@utils.skip_if_microversion_not_supported("2.0")
|
||||
def test_quota_defaults_api_2_0(self, role):
|
||||
self._get_quotas(role, "defaults", "2.0")
|
||||
|
||||
@ddt.data('admin', 'user')
|
||||
@utils.skip_if_microversion_not_supported("2.6")
|
||||
def test_quota_defaults_api_2_6(self, role):
|
||||
self._get_quotas(role, "defaults", "2.6")
|
||||
|
||||
@ddt.data('admin', 'user')
|
||||
@utils.skip_if_microversion_not_supported("2.7")
|
||||
def test_quota_defaults_api_2_7(self, role):
|
||||
self._get_quotas(role, "defaults", "2.7")
|
||||
|
||||
@ddt.data('admin', 'user')
|
||||
@utils.skip_if_microversion_not_supported("1.0")
|
||||
def test_quota_show_api_1_0(self, role):
|
||||
self._get_quotas(role, "show", "1.0")
|
||||
|
||||
@ddt.data('admin', 'user')
|
||||
@utils.skip_if_microversion_not_supported("2.0")
|
||||
def test_quota_show_api_2_0(self, role):
|
||||
self._get_quotas(role, "show", "2.0")
|
||||
|
||||
@ddt.data('admin', 'user')
|
||||
@utils.skip_if_microversion_not_supported("2.6")
|
||||
def test_quota_show_api_2_6(self, role):
|
||||
self._get_quotas(role, "show", "2.6")
|
||||
|
||||
@ddt.data('admin', 'user')
|
||||
@utils.skip_if_microversion_not_supported("2.7")
|
||||
def test_quota_show_api_2_7(self, role):
|
||||
self._get_quotas(role, "show", "2.7")
|
||||
|
@ -21,8 +21,10 @@ from manilaclient.tests.functional import base
|
||||
@ddt.ddt
|
||||
class ManilaClientTestServicesReadOnly(base.BaseTestCase):
|
||||
|
||||
def test_services_list(self):
|
||||
self.clients['admin'].manila('service-list')
|
||||
@ddt.data("1.0", "2.0", "2.6", "2.7")
|
||||
def test_services_list(self, microversion):
|
||||
self.skip_if_microversion_not_supported(microversion)
|
||||
self.admin_client.manila('service-list', microversion=microversion)
|
||||
|
||||
def test_list_with_debug_flag(self):
|
||||
self.clients['admin'].manila('service-list', flags='--debug')
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import ddt
|
||||
from tempest_lib import exceptions as tempest_lib_exc
|
||||
|
||||
from manilaclient import config
|
||||
@ -21,6 +22,7 @@ from manilaclient.tests.functional import base
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class ShareAccessReadWriteBase(base.BaseTestCase):
|
||||
protocol = None
|
||||
access_level = None
|
||||
@ -47,30 +49,51 @@ class ShareAccessReadWriteBase(base.BaseTestCase):
|
||||
cls.share = cls.create_share(share_protocol=cls.protocol,
|
||||
public=True,
|
||||
cleanup_in_class=True)
|
||||
cls.share_id = cls.share['id']
|
||||
|
||||
# NOTE(vponomaryov): increase following int range when significant
|
||||
# amount of new tests is added.
|
||||
int_range = range(20, 50)
|
||||
cls.access_to = {
|
||||
'ip': '10.0.0.1',
|
||||
'user': CONF.username_for_user_rules,
|
||||
'cert': 'tenant.example.com',
|
||||
# NOTE(vponomaryov): list of unique values is required for ability
|
||||
# to create lots of access rules for one share using different
|
||||
# API microversions.
|
||||
'ip': ['99.88.77.%d' % i for i in int_range],
|
||||
# NOTE(vponomaryov): following users are fakes and access rules
|
||||
# that use it are expected to fail, but they are used only for
|
||||
# API testing.
|
||||
'user': ['foo_user_%d' % i for i in int_range],
|
||||
'cert': ['tenant_%d.example.com' % i for i in int_range],
|
||||
}
|
||||
|
||||
def test_list_access_rule_for_share(self):
|
||||
access_to = {
|
||||
'ip': '10.0.0.1',
|
||||
'user': CONF.username_for_user_rules,
|
||||
'cert': 'tenant.example.com',
|
||||
}
|
||||
@ddt.data("1.0", "2.0", "2.6", "2.7")
|
||||
def test_create_list_access_rule_for_share(self, microversion):
|
||||
self.skip_if_microversion_not_supported(microversion)
|
||||
|
||||
access_type = self.access_types[0]
|
||||
access = self.user_client.access_allow(self.share['id'], access_type,
|
||||
access_to[access_type],
|
||||
self.access_level)
|
||||
access_list = self.user_client.list_access(self.share['id'])
|
||||
|
||||
access = self.user_client.access_allow(
|
||||
self.share['id'], access_type, self.access_to[access_type].pop(),
|
||||
self.access_level, microversion=microversion)
|
||||
|
||||
access_list = self.user_client.list_access(
|
||||
self.share['id'], microversion=microversion)
|
||||
|
||||
self.assertTrue(any(
|
||||
[item for item in access_list if access['id'] == item['id']]))
|
||||
|
||||
def _create_delete_access_rule(self, share_id, access_type, access_to):
|
||||
access = self.user_client.access_allow(share_id, access_type,
|
||||
access_to, self.access_level)
|
||||
def _create_delete_access_rule(self, share_id, access_type, access_to,
|
||||
microversion=None):
|
||||
self.skip_if_microversion_not_supported(microversion)
|
||||
if access_type not in self.access_types:
|
||||
raise self.skipException(
|
||||
"'%(access_type)s' access rules is disabled for protocol "
|
||||
"'%(protocol)s'." % {"access_type": access_type,
|
||||
"protocol": self.protocol})
|
||||
|
||||
access = self.user_client.access_allow(
|
||||
share_id, access_type, access_to, self.access_level,
|
||||
microversion=microversion)
|
||||
|
||||
self.assertEqual(share_id, access.get('share_id'))
|
||||
self.assertEqual(access_type, access.get('access_type'))
|
||||
@ -85,25 +108,20 @@ class ShareAccessReadWriteBase(base.BaseTestCase):
|
||||
self.assertRaises(tempest_lib_exc.NotFound,
|
||||
self.user_client.get_access, share_id, access['id'])
|
||||
|
||||
def test_create_delete_ip_access_rule(self):
|
||||
if 'ip' not in self.access_types:
|
||||
raise self.skipException("IP access rule is disabled for protocol "
|
||||
"%s." % self.protocol)
|
||||
self._create_delete_access_rule(self.share['id'], 'ip', '10.0.0.1')
|
||||
@ddt.data("1.0", "2.0", "2.6", "2.7")
|
||||
def test_create_delete_ip_access_rule(self, microversion):
|
||||
self._create_delete_access_rule(
|
||||
self.share_id, 'ip', self.access_to['ip'].pop(), microversion)
|
||||
|
||||
def test_create_delete_user_access_rule(self):
|
||||
if 'user' not in self.access_types:
|
||||
raise self.skipException("User access rule is disabled for "
|
||||
"protocol %s." % self.protocol)
|
||||
self._create_delete_access_rule(self.share['id'], 'user',
|
||||
CONF.username_for_user_rules)
|
||||
@ddt.data("1.0", "2.0", "2.6", "2.7")
|
||||
def test_create_delete_user_access_rule(self, microversion):
|
||||
self._create_delete_access_rule(
|
||||
self.share_id, 'user', CONF.username_for_user_rules, microversion)
|
||||
|
||||
def test_create_delete_cert_access_rule(self):
|
||||
if 'cert' not in self.access_types:
|
||||
raise self.skipException("Cert access rule is disabled for "
|
||||
"protocol %s." % self.protocol)
|
||||
self._create_delete_access_rule(self.share['id'], 'cert',
|
||||
'tenant.example.com')
|
||||
@ddt.data("1.0", "2.0", "2.6", "2.7")
|
||||
def test_create_delete_cert_access_rule(self, microversion):
|
||||
self._create_delete_access_rule(
|
||||
self.share_id, 'cert', self.access_to['cert'].pop(), microversion)
|
||||
|
||||
|
||||
class NFSShareRWAccessReadWriteTest(ShareAccessReadWriteBase):
|
||||
|
@ -22,12 +22,25 @@ from manilaclient.tests.functional import base
|
||||
@ddt.ddt
|
||||
class ShareTypesReadOnlyTest(base.BaseTestCase):
|
||||
|
||||
@ddt.data('admin', 'user')
|
||||
def test_share_type_list(self, role):
|
||||
self.clients[role].manila('type-list')
|
||||
@ddt.data(
|
||||
("admin", "1.0"),
|
||||
("admin", "2.0"),
|
||||
("admin", "2.6"),
|
||||
("admin", "2.7"),
|
||||
("user", "1.0"),
|
||||
("user", "2.0"),
|
||||
("user", "2.6"),
|
||||
("user", "2.7"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_share_type_list(self, role, microversion):
|
||||
self.skip_if_microversion_not_supported(microversion)
|
||||
self.clients[role].manila("type-list", microversion=microversion)
|
||||
|
||||
def test_extra_specs_list(self):
|
||||
self.admin_client.manila('extra-specs-list')
|
||||
@ddt.data("1.0", "2.0", "2.6", "2.7")
|
||||
def test_extra_specs_list(self, microversion):
|
||||
self.skip_if_microversion_not_supported(microversion)
|
||||
self.admin_client.manila("extra-specs-list", microversion=microversion)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@ -37,44 +50,50 @@ class ShareTypesReadWriteTest(base.BaseTestCase):
|
||||
'ID', 'Name', 'Visibility', 'is_default', 'required_extra_specs')
|
||||
|
||||
def _share_type_listed_by(self, share_type_id, by_admin=False,
|
||||
list_all=False):
|
||||
if by_admin:
|
||||
client = self.admin_client
|
||||
else:
|
||||
client = self.user_client
|
||||
share_types = client.list_share_types(list_all=list_all)
|
||||
list_all=False, microversion=None):
|
||||
client = self.admin_client if by_admin else self.user_client
|
||||
share_types = client.list_share_types(
|
||||
list_all=list_all, microversion=microversion)
|
||||
return any(share_type_id == st['ID'] for st in share_types)
|
||||
|
||||
def _verify_access(self, share_type_id, is_public):
|
||||
def _verify_access(self, share_type_id, is_public, microversion=None):
|
||||
if is_public:
|
||||
# Verify that it is listed with common 'type-list' operation.
|
||||
share_types = self.admin_client.list_share_types(list_all=False)
|
||||
share_types = self.admin_client.list_share_types(
|
||||
list_all=False, microversion=microversion)
|
||||
self.assertTrue(
|
||||
any(share_type_id == st['ID'] for st in share_types))
|
||||
else:
|
||||
# Verify that it is not listed for user
|
||||
self.assertFalse(self._share_type_listed_by(
|
||||
share_type_id=share_type_id, by_admin=False, list_all=True))
|
||||
share_type_id=share_type_id, by_admin=False, list_all=True,
|
||||
microversion=microversion))
|
||||
|
||||
# Verify it is listed for admin
|
||||
self.assertTrue(self._share_type_listed_by(
|
||||
share_type_id=share_type_id, by_admin=True, list_all=True))
|
||||
share_type_id=share_type_id, by_admin=True, list_all=True,
|
||||
microversion=microversion))
|
||||
|
||||
# Verify it is not listed by default
|
||||
self.assertFalse(self._share_type_listed_by(
|
||||
share_type_id=share_type_id, by_admin=True, list_all=False))
|
||||
share_type_id=share_type_id, by_admin=True, list_all=False,
|
||||
microversion=microversion))
|
||||
|
||||
@ddt.data(
|
||||
{'is_public': True, 'dhss': False},
|
||||
{'is_public': True, 'dhss': True},
|
||||
{'is_public': False, 'dhss': True},
|
||||
{'is_public': False, 'dhss': False},
|
||||
{'is_public': False, 'dhss': True, 'snapshot_support': False},
|
||||
{'is_public': False, 'dhss': False, 'snapshot_support': True},
|
||||
(True, False),
|
||||
(True, True),
|
||||
(False, True),
|
||||
(False, False),
|
||||
(False, True, False, "2.6"),
|
||||
(False, False, True, "2.7"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_create_delete_share_type(self, is_public, dhss,
|
||||
snapshot_support=True):
|
||||
snapshot_support=True,
|
||||
microversion=None):
|
||||
if microversion:
|
||||
self.skip_if_microversion_not_supported(microversion)
|
||||
|
||||
share_type_name = data_utils.rand_name('manilaclient_functional_test')
|
||||
dhss_expected = 'driver_handles_share_servers : %s' % dhss
|
||||
snapshot_support_expected = 'snapshot_support : %s' % snapshot_support
|
||||
@ -84,7 +103,9 @@ class ShareTypesReadWriteTest(base.BaseTestCase):
|
||||
name=share_type_name,
|
||||
driver_handles_share_servers=dhss,
|
||||
snapshot_support=snapshot_support,
|
||||
is_public=is_public)
|
||||
is_public=is_public,
|
||||
microversion=microversion,
|
||||
)
|
||||
|
||||
st_id = share_type['ID']
|
||||
|
||||
@ -100,20 +121,27 @@ class ShareTypesReadWriteTest(base.BaseTestCase):
|
||||
self.assertEqual('-', share_type['is_default'])
|
||||
|
||||
# Verify its access
|
||||
self._verify_access(share_type_id=st_id, is_public=is_public)
|
||||
self._verify_access(
|
||||
share_type_id=st_id, is_public=is_public,
|
||||
microversion=microversion)
|
||||
|
||||
# Delete share type
|
||||
self.admin_client.delete_share_type(st_id)
|
||||
self.admin_client.delete_share_type(st_id, microversion=microversion)
|
||||
|
||||
# Wait for share type deletion
|
||||
self.admin_client.wait_for_share_type_deletion(st_id)
|
||||
self.admin_client.wait_for_share_type_deletion(
|
||||
st_id, microversion=microversion)
|
||||
|
||||
# Verify that it is not listed with common 'type-list' operation.
|
||||
share_types = self.admin_client.list_share_types(list_all=False)
|
||||
share_types = self.admin_client.list_share_types(
|
||||
list_all=False, microversion=microversion)
|
||||
self.assertFalse(
|
||||
any(st_id == st['ID'] for st in share_types))
|
||||
|
||||
def test_add_remove_access_to_private_share_type(self):
|
||||
@ddt.data("2.6", "2.7")
|
||||
def test_add_remove_access_to_private_share_type(self, microversion):
|
||||
self.skip_if_microversion_not_supported(microversion)
|
||||
|
||||
share_type_name = data_utils.rand_name('manilaclient_functional_test')
|
||||
is_public = False
|
||||
|
||||
@ -121,20 +149,28 @@ class ShareTypesReadWriteTest(base.BaseTestCase):
|
||||
share_type = self.create_share_type(
|
||||
name=share_type_name,
|
||||
driver_handles_share_servers='False',
|
||||
is_public=is_public)
|
||||
is_public=is_public,
|
||||
microversion=microversion,
|
||||
)
|
||||
|
||||
st_id = share_type['ID']
|
||||
user_project_id = self.admin_client.get_project_id(
|
||||
self.user_client.tenant_name)
|
||||
|
||||
self._verify_access(share_type_id=st_id, is_public=is_public)
|
||||
self._verify_access(
|
||||
share_type_id=st_id,
|
||||
is_public=is_public,
|
||||
microversion=microversion,
|
||||
)
|
||||
|
||||
# Project ID is in access list - false
|
||||
st_access_list = self.admin_client.list_share_type_access(st_id)
|
||||
st_access_list = self.admin_client.list_share_type_access(
|
||||
st_id, microversion=microversion)
|
||||
self.assertNotIn(user_project_id, st_access_list)
|
||||
|
||||
# Add access for project of user
|
||||
self.admin_client.add_share_type_access(st_id, user_project_id)
|
||||
self.admin_client.add_share_type_access(
|
||||
st_id, user_project_id, microversion=microversion)
|
||||
|
||||
# Verify it is listed for user as well as for admin
|
||||
self.assertTrue(self._share_type_listed_by(
|
||||
@ -143,16 +179,23 @@ class ShareTypesReadWriteTest(base.BaseTestCase):
|
||||
share_type_id=st_id, by_admin=True, list_all=True))
|
||||
|
||||
# Project ID is in access list - true
|
||||
st_access_list = self.admin_client.list_share_type_access(st_id)
|
||||
st_access_list = self.admin_client.list_share_type_access(
|
||||
st_id, microversion=microversion)
|
||||
self.assertIn(user_project_id, st_access_list)
|
||||
|
||||
# Remove access
|
||||
self.admin_client.remove_share_type_access(st_id, user_project_id)
|
||||
self.admin_client.remove_share_type_access(
|
||||
st_id, user_project_id, microversion=microversion)
|
||||
|
||||
self._verify_access(share_type_id=st_id, is_public=is_public)
|
||||
self._verify_access(
|
||||
share_type_id=st_id,
|
||||
is_public=is_public,
|
||||
microversion=microversion,
|
||||
)
|
||||
|
||||
# Project ID is in access list - false
|
||||
st_access_list = self.admin_client.list_share_type_access(st_id)
|
||||
st_access_list = self.admin_client.list_share_type_access(
|
||||
st_id, microversion=microversion)
|
||||
self.assertNotIn(user_project_id, st_access_list)
|
||||
|
||||
|
||||
@ -160,33 +203,42 @@ class ShareTypesReadWriteTest(base.BaseTestCase):
|
||||
class ShareTypeExtraSpecsReadWriteTest(base.BaseTestCase):
|
||||
|
||||
@ddt.data(
|
||||
{'is_public': True, 'dhss': False},
|
||||
{'is_public': True, 'dhss': True},
|
||||
{'is_public': False, 'dhss': True},
|
||||
{'is_public': False, 'dhss': False},
|
||||
(True, False),
|
||||
(True, True),
|
||||
(False, True),
|
||||
(False, False),
|
||||
(False, False, "2.6"),
|
||||
(False, False, "2.7"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_share_type_extra_specs_life_cycle(self, is_public, dhss):
|
||||
def test_share_type_extra_specs_life_cycle(self, is_public, dhss,
|
||||
microversion=None):
|
||||
if microversion:
|
||||
self.skip_if_microversion_not_supported(microversion)
|
||||
|
||||
# Create share type
|
||||
st = self.create_share_type(
|
||||
driver_handles_share_servers=dhss, is_public=is_public)
|
||||
driver_handles_share_servers=dhss, is_public=is_public,
|
||||
microversion=microversion)
|
||||
|
||||
# Add extra specs to share type
|
||||
st_extra_specs = dict(foo_key='foo_value', bar_key='bar_value')
|
||||
self.admin_client.set_share_type_extra_specs(
|
||||
st['ID'], st_extra_specs)
|
||||
st['ID'], st_extra_specs, microversion=microversion)
|
||||
|
||||
# View list of extra specs
|
||||
extra_specs = self.admin_client.list_share_type_extra_specs(st['ID'])
|
||||
extra_specs = self.admin_client.list_share_type_extra_specs(
|
||||
st['ID'], microversion=microversion)
|
||||
for k, v in st_extra_specs.items():
|
||||
self.assertIn('%s : %s' % (k, v), extra_specs)
|
||||
|
||||
# Remove one extra spec
|
||||
self.admin_client.unset_share_type_extra_specs(st['ID'], ['foo_key'])
|
||||
self.admin_client.unset_share_type_extra_specs(
|
||||
st['ID'], ('foo_key', ), microversion=microversion)
|
||||
|
||||
# Verify that removed extra spec is absent
|
||||
extra_specs = self.admin_client.list_share_type_extra_specs(st['ID'])
|
||||
extra_specs = self.admin_client.list_share_type_extra_specs(
|
||||
st['ID'], microversion=microversion)
|
||||
self.assertNotIn('foo_key : foo_value', extra_specs)
|
||||
self.assertIn('bar_key : bar_value', extra_specs)
|
||||
self.assertIn('driver_handles_share_servers : %s' % dhss, extra_specs)
|
||||
|
@ -15,6 +15,11 @@
|
||||
|
||||
import six
|
||||
from tempest_lib.cli import output_parser
|
||||
import testtools
|
||||
|
||||
from manilaclient import config
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
def multi_line_row_table(output_lines, group_by_column_index=0):
|
||||
@ -85,3 +90,19 @@ def listing(output_lines):
|
||||
item[col_key] = row[col_idx]
|
||||
items.append(item)
|
||||
return items
|
||||
|
||||
|
||||
def is_microversion_supported(microversion):
|
||||
if (float(microversion) > float(CONF.max_api_microversion) or
|
||||
float(microversion) < float(CONF.min_api_microversion)):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def skip_if_microversion_not_supported(microversion):
|
||||
"""Decorator for tests that are microversion-specific."""
|
||||
if not is_microversion_supported(microversion):
|
||||
reason = ("Skipped. Test requires microversion %s that is not "
|
||||
"allowed to be used by configuration." % microversion)
|
||||
return testtools.skip(reason)
|
||||
return lambda f: f
|
||||
|
@ -106,6 +106,8 @@ class FakeHTTPClient(httpclient.HTTPClient):
|
||||
}
|
||||
return (200, {}, quota_set)
|
||||
|
||||
get_quota_sets_test = get_os_quota_sets_test
|
||||
|
||||
def get_os_quota_sets_test_defaults(self):
|
||||
quota_set = {
|
||||
'quota_set': {
|
||||
@ -120,6 +122,8 @@ class FakeHTTPClient(httpclient.HTTPClient):
|
||||
}
|
||||
return (200, {}, quota_set)
|
||||
|
||||
get_quota_sets_test_defaults = get_os_quota_sets_test_defaults
|
||||
|
||||
def put_os_quota_sets_test(self, body, **kw):
|
||||
assert list(body) == ['quota_set']
|
||||
fakes.assert_has_keys(body['quota_set'],
|
||||
@ -137,6 +141,8 @@ class FakeHTTPClient(httpclient.HTTPClient):
|
||||
}
|
||||
return (200, {}, quota_set)
|
||||
|
||||
put_quota_sets_test = put_os_quota_sets_test
|
||||
|
||||
#
|
||||
# Quota Classes
|
||||
#
|
||||
@ -155,6 +161,8 @@ class FakeHTTPClient(httpclient.HTTPClient):
|
||||
}
|
||||
return (200, {}, quota_class_set)
|
||||
|
||||
get_quota_class_sets_test = get_os_quota_class_sets_test
|
||||
|
||||
def put_os_quota_class_sets_test(self, body, **kw):
|
||||
assert list(body) == ['quota_class_set']
|
||||
fakes.assert_has_keys(body['quota_class_set'],
|
||||
@ -172,8 +180,13 @@ class FakeHTTPClient(httpclient.HTTPClient):
|
||||
}
|
||||
return (200, {}, quota_class_set)
|
||||
|
||||
put_quota_class_sets_test = put_os_quota_class_sets_test
|
||||
|
||||
def delete_os_quota_sets_test(self, **kw):
|
||||
return (202, {}, {})
|
||||
|
||||
delete_quota_sets_test = delete_os_quota_sets_test
|
||||
|
||||
#
|
||||
# List all extensions
|
||||
#
|
||||
|
@ -90,14 +90,20 @@ class FakeHTTPClient(fakes.FakeHTTPClient):
|
||||
}
|
||||
return (200, {}, services)
|
||||
|
||||
get_services = get_os_services
|
||||
|
||||
def put_os_services_enable(self, **kw):
|
||||
return (200, {}, {'host': 'foo', 'binary': 'manila-share',
|
||||
'disabled': False})
|
||||
|
||||
put_services_enable = put_os_services_enable
|
||||
|
||||
def put_os_services_disable(self, **kw):
|
||||
return (200, {}, {'host': 'foo', 'binary': 'manila-share',
|
||||
'disabled': True})
|
||||
|
||||
put_services_disable = put_os_services_disable
|
||||
|
||||
def get_v2(self, **kw):
|
||||
body = {
|
||||
"versions": [
|
||||
@ -179,9 +185,10 @@ class FakeHTTPClient(fakes.FakeHTTPClient):
|
||||
resp = 202
|
||||
assert len(list(body)) == 1
|
||||
action = list(body)[0]
|
||||
if action == 'os-reset_status':
|
||||
assert 'status' in body['os-reset_status']
|
||||
elif action == 'os-force_delete':
|
||||
if action in ('reset_status', 'os-reset_status'):
|
||||
assert 'status' in body.get(
|
||||
'reset_status', body.get('os-reset_status'))
|
||||
elif action in ('force_delete', 'os-force_delete'):
|
||||
assert body[action] is None
|
||||
else:
|
||||
raise AssertionError("Unexpected action: %s" % action)
|
||||
@ -212,8 +219,9 @@ class FakeHTTPClient(fakes.FakeHTTPClient):
|
||||
resp = 202
|
||||
assert len(list(body)) == 1
|
||||
action = list(body)[0]
|
||||
if action == 'os-reset_status':
|
||||
assert 'status' in body['os-reset_status']
|
||||
if action in ('reset_status', 'os-reset_status'):
|
||||
assert 'status' in body.get(
|
||||
'reset_status', body.get('os-reset_status'))
|
||||
elif action == 'os-force_delete':
|
||||
assert body[action] is None
|
||||
else:
|
||||
@ -260,6 +268,8 @@ class FakeHTTPClient(fakes.FakeHTTPClient):
|
||||
result = (resp, {}, _body)
|
||||
return result
|
||||
|
||||
post_shares_manage = post_os_share_manage
|
||||
|
||||
def post_os_share_unmanage_1234_unmanage(self, **kw):
|
||||
_body = None
|
||||
resp = 202
|
||||
@ -271,23 +281,26 @@ class FakeHTTPClient(fakes.FakeHTTPClient):
|
||||
resp = 202
|
||||
assert len(list(body)) == 1
|
||||
action = list(body)[0]
|
||||
if action == 'os-allow_access':
|
||||
if action in ('os-allow_access', 'allow_access'):
|
||||
expected = ['access_to', 'access_type']
|
||||
actual = sorted(list(body[action]))
|
||||
err_msg = "expected '%s', actual is '%s'" % (expected, actual)
|
||||
assert expected == actual, err_msg
|
||||
_body = {'access': {}}
|
||||
elif action == 'os-deny_access':
|
||||
elif action in ('os-deny_access', 'deny_access'):
|
||||
assert list(body[action]) == ['access_id']
|
||||
elif action == 'os-access_list':
|
||||
elif action in ('os-access_list', 'access_list'):
|
||||
assert body[action] is None
|
||||
elif action == 'os-reset_status':
|
||||
assert 'status' in body['os-reset_status']
|
||||
elif action == 'os-force_delete':
|
||||
elif action in ('os-reset_status', 'reset_status'):
|
||||
assert 'status' in body.get(
|
||||
'reset_status', body.get('os-reset_status'))
|
||||
elif action in ('os-force_delete', 'force_delete'):
|
||||
assert body[action] is None
|
||||
elif action in ('os-extend', 'os-shrink'):
|
||||
elif action in ('os-extend', 'os-shrink', 'extend', 'shrink'):
|
||||
assert body[action] is not None
|
||||
assert body[action]['new_size'] is not None
|
||||
elif action in ('unmanage', ):
|
||||
assert body[action] is None
|
||||
else:
|
||||
raise AssertionError("Unexpected share action: %s" % action)
|
||||
return (resp, {}, _body)
|
||||
@ -297,13 +310,13 @@ class FakeHTTPClient(fakes.FakeHTTPClient):
|
||||
resp = 202
|
||||
assert len(list(body)) == 1
|
||||
action = list(body)[0]
|
||||
if action == 'os-allow_access':
|
||||
if action in ('allow_access', 'os-allow_access'):
|
||||
expected = ['access_level', 'access_to', 'access_type']
|
||||
actual = sorted(list(body[action]))
|
||||
err_msg = "expected '%s', actual is '%s'" % (expected, actual)
|
||||
assert expected == actual, err_msg
|
||||
_body = {'access': {}}
|
||||
elif action == 'os-access_list':
|
||||
elif action in ('access_list', 'os-access_list'):
|
||||
assert body[action] is None
|
||||
_body = {
|
||||
'access_list': [{
|
||||
@ -628,6 +641,8 @@ class FakeHTTPClient(fakes.FakeHTTPClient):
|
||||
'project_id': '00000000-0000-0000-0000-000000000000'}
|
||||
]})
|
||||
|
||||
get_types_3_share_type_access = get_types_3_os_share_type_access
|
||||
|
||||
|
||||
def fake_create(url, body, response_key):
|
||||
return {'url': url, 'body': body, 'resp_key': response_key}
|
||||
|
@ -13,30 +13,61 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient.tests.unit import utils
|
||||
from manilaclient.tests.unit.v2 import fakes
|
||||
|
||||
|
||||
cs = fakes.FakeClient()
|
||||
from manilaclient.v2 import quota_classes
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class QuotaClassSetsTest(utils.TestCase):
|
||||
|
||||
def test_class_quotas_get(self):
|
||||
def _get_manager(self, microversion):
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
return quota_classes.QuotaClassSetManager(api=mock_microversion)
|
||||
|
||||
def _get_resource_path(self, microversion):
|
||||
if float(microversion) > 2.6:
|
||||
return quota_classes.RESOURCE_PATH
|
||||
return quota_classes.RESOURCE_PATH_LEGACY
|
||||
|
||||
@ddt.data("2.6", "2.7")
|
||||
def test_class_quotas_get(self, microversion):
|
||||
class_name = 'test'
|
||||
cs.quota_classes.get(class_name)
|
||||
cs.assert_called('GET', '/os-quota-class-sets/%s' % class_name)
|
||||
manager = self._get_manager(microversion)
|
||||
resource_path = self._get_resource_path(microversion)
|
||||
expected_url = "%s/test" % resource_path
|
||||
with mock.patch.object(manager, '_get',
|
||||
mock.Mock(return_value='fake_get')):
|
||||
manager.get(class_name)
|
||||
|
||||
def test_update_quota(self):
|
||||
q = cs.quota_classes.get('test')
|
||||
q.update(shares=2)
|
||||
cs.assert_called('PUT', '/os-quota-class-sets/test')
|
||||
manager._get.assert_called_once_with(
|
||||
expected_url, "quota_class_set")
|
||||
|
||||
def test_refresh_quota(self):
|
||||
q = cs.quota_classes.get('test')
|
||||
q2 = cs.quota_classes.get('test')
|
||||
self.assertEqual(q.shares, q2.shares)
|
||||
q2.shares = 0
|
||||
self.assertNotEqual(q.shares, q2.shares)
|
||||
q2.get()
|
||||
self.assertEqual(q.shares, q2.shares)
|
||||
@ddt.data("2.6", "2.7")
|
||||
def test_update_quota(self, microversion):
|
||||
class_name = 'test'
|
||||
manager = self._get_manager(microversion)
|
||||
resource_path = self._get_resource_path(microversion)
|
||||
expected_url = "%s/test" % resource_path
|
||||
expected_body = {
|
||||
'quota_class_set': {
|
||||
'class_name': class_name,
|
||||
'shares': 1,
|
||||
'snapshots': 2,
|
||||
'gigabytes': 3,
|
||||
'snapshot_gigabytes': 4,
|
||||
'share_networks': 5,
|
||||
},
|
||||
}
|
||||
with mock.patch.object(manager, '_update',
|
||||
mock.Mock(return_value='fake_update')):
|
||||
manager.update(
|
||||
class_name, shares=1, snapshots=2, gigabytes=3,
|
||||
snapshot_gigabytes=4, share_networks=5)
|
||||
|
||||
manager._update.assert_called_once_with(
|
||||
expected_url, expected_body)
|
||||
|
@ -13,83 +13,143 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient.tests.unit import utils
|
||||
from manilaclient.tests.unit.v2 import fakes
|
||||
|
||||
|
||||
cs = fakes.FakeClient()
|
||||
from manilaclient.v2 import quotas
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class QuotaSetsTest(utils.TestCase):
|
||||
|
||||
def test_tenant_quotas_get(self):
|
||||
tenant_id = 'test'
|
||||
cs.quotas.get(tenant_id)
|
||||
cs.assert_called('GET', '/os-quota-sets/%s' % tenant_id)
|
||||
def _get_manager(self, microversion):
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
return quotas.QuotaSetManager(api=mock_microversion)
|
||||
|
||||
def test_user_quotas_get(self):
|
||||
def _get_resource_path(self, microversion):
|
||||
if float(microversion) > 2.6:
|
||||
return quotas.RESOURCE_PATH
|
||||
return quotas.RESOURCE_PATH_LEGACY
|
||||
|
||||
@ddt.data("2.6", "2.7")
|
||||
def test_tenant_quotas_get(self, microversion):
|
||||
tenant_id = 'test'
|
||||
manager = self._get_manager(microversion)
|
||||
resource_path = self._get_resource_path(microversion)
|
||||
expected_url = "%s/test" % resource_path
|
||||
with mock.patch.object(manager, '_get',
|
||||
mock.Mock(return_value='fake_get')):
|
||||
manager.get(tenant_id)
|
||||
|
||||
manager._get.assert_called_once_with(expected_url, "quota_set")
|
||||
|
||||
@ddt.data("2.6", "2.7")
|
||||
def test_user_quotas_get(self, microversion):
|
||||
tenant_id = 'test'
|
||||
user_id = 'fake_user'
|
||||
cs.quotas.get(tenant_id, user_id=user_id)
|
||||
url = '/os-quota-sets/%s?user_id=%s' % (tenant_id, user_id)
|
||||
cs.assert_called('GET', url)
|
||||
manager = self._get_manager(microversion)
|
||||
resource_path = self._get_resource_path(microversion)
|
||||
expected_url = "%s/test?user_id=fake_user" % resource_path
|
||||
with mock.patch.object(manager, '_get',
|
||||
mock.Mock(return_value='fake_get')):
|
||||
manager.get(tenant_id, user_id=user_id)
|
||||
|
||||
def test_tenant_quotas_defaults(self):
|
||||
manager._get.assert_called_once_with(expected_url, "quota_set")
|
||||
|
||||
@ddt.data("2.6", "2.7")
|
||||
def test_tenant_quotas_defaults(self, microversion):
|
||||
tenant_id = 'test'
|
||||
cs.quotas.defaults(tenant_id)
|
||||
cs.assert_called('GET', '/os-quota-sets/%s/defaults' % tenant_id)
|
||||
manager = self._get_manager(microversion)
|
||||
resource_path = self._get_resource_path(microversion)
|
||||
expected_url = "%s/test/defaults" % resource_path
|
||||
with mock.patch.object(manager, '_get',
|
||||
mock.Mock(return_value='fake_get')):
|
||||
manager.defaults(tenant_id)
|
||||
|
||||
def test_update_quota(self):
|
||||
q = cs.quotas.get('test')
|
||||
q.update(shares=1)
|
||||
q.update(snapshots=2)
|
||||
q.update(gigabytes=3)
|
||||
q.update(snapshot_gigabytes=4)
|
||||
q.update(share_networks=5)
|
||||
cs.assert_called('PUT', '/os-quota-sets/test')
|
||||
manager._get.assert_called_once_with(expected_url, "quota_set")
|
||||
|
||||
def test_update_user_quota(self):
|
||||
@ddt.data(
|
||||
("2.6", {}),
|
||||
("2.6", {"force": True}),
|
||||
("2.7", {}),
|
||||
("2.7", {"force": True}),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_update_quota(self, microversion, extra_data):
|
||||
tenant_id = 'test'
|
||||
manager = self._get_manager(microversion)
|
||||
resource_path = self._get_resource_path(microversion)
|
||||
expected_url = "%s/test" % resource_path
|
||||
expected_body = {
|
||||
'quota_set': {
|
||||
'tenant_id': tenant_id,
|
||||
'shares': 1,
|
||||
'snapshots': 2,
|
||||
'gigabytes': 3,
|
||||
'snapshot_gigabytes': 4,
|
||||
'share_networks': 5,
|
||||
},
|
||||
}
|
||||
expected_body['quota_set'].update(extra_data)
|
||||
with mock.patch.object(manager, '_update',
|
||||
mock.Mock(return_value='fake_update')):
|
||||
manager.update(
|
||||
tenant_id, shares=1, snapshots=2, gigabytes=3,
|
||||
snapshot_gigabytes=4, share_networks=5, **extra_data)
|
||||
|
||||
manager._update.assert_called_once_with(
|
||||
expected_url, expected_body, "quota_set")
|
||||
|
||||
@ddt.data("2.6", "2.7")
|
||||
def test_update_user_quota(self, microversion):
|
||||
tenant_id = 'test'
|
||||
user_id = 'fake_user'
|
||||
q = cs.quotas.get(tenant_id)
|
||||
q.update(shares=1, user_id=user_id)
|
||||
q.update(snapshots=2, user_id=user_id)
|
||||
q.update(gigabytes=3, user_id=user_id)
|
||||
q.update(snapshot_gigabytes=4, user_id=user_id)
|
||||
q.update(share_networks=5, user_id=user_id)
|
||||
url = '/os-quota-sets/%s?user_id=%s' % (tenant_id, user_id)
|
||||
cs.assert_called('PUT', url)
|
||||
manager = self._get_manager(microversion)
|
||||
resource_path = self._get_resource_path(microversion)
|
||||
expected_url = "%s/test?user_id=fake_user" % resource_path
|
||||
expected_body = {
|
||||
'quota_set': {
|
||||
'tenant_id': tenant_id,
|
||||
'shares': 1,
|
||||
'snapshots': 2,
|
||||
'gigabytes': 3,
|
||||
'snapshot_gigabytes': 4,
|
||||
'share_networks': 5,
|
||||
},
|
||||
}
|
||||
with mock.patch.object(manager, '_update',
|
||||
mock.Mock(return_value='fake_update')):
|
||||
manager.update(
|
||||
tenant_id, shares=1, snapshots=2, gigabytes=3,
|
||||
snapshot_gigabytes=4, share_networks=5, user_id=user_id)
|
||||
|
||||
def test_force_update_quota(self):
|
||||
q = cs.quotas.get('test')
|
||||
q.update(shares=2, force=True)
|
||||
cs.assert_called(
|
||||
'PUT', '/os-quota-sets/test',
|
||||
{'quota_set': {'force': True,
|
||||
'shares': 2,
|
||||
'tenant_id': 'test'}})
|
||||
manager._update.assert_called_once_with(
|
||||
expected_url, expected_body, "quota_set")
|
||||
|
||||
def test_quotas_delete(self):
|
||||
@ddt.data("2.6", "2.7")
|
||||
def test_quotas_delete(self, microversion):
|
||||
tenant_id = 'test'
|
||||
cs.quotas.delete(tenant_id)
|
||||
cs.assert_called('DELETE', '/os-quota-sets/%s' % tenant_id)
|
||||
manager = self._get_manager(microversion)
|
||||
resource_path = self._get_resource_path(microversion)
|
||||
expected_url = "%s/test" % resource_path
|
||||
with mock.patch.object(manager, '_delete',
|
||||
mock.Mock(return_value='fake_delete')):
|
||||
manager.delete(tenant_id)
|
||||
|
||||
def test_user_quotas_delete(self):
|
||||
manager._delete.assert_called_once_with(expected_url)
|
||||
|
||||
@ddt.data("2.6", "2.7")
|
||||
def test_user_quotas_delete(self, microversion):
|
||||
tenant_id = 'test'
|
||||
user_id = 'fake_user'
|
||||
cs.quotas.delete(tenant_id, user_id=user_id)
|
||||
url = '/os-quota-sets/%s?user_id=%s' % (tenant_id, user_id)
|
||||
cs.assert_called('DELETE', url)
|
||||
manager = self._get_manager(microversion)
|
||||
resource_path = self._get_resource_path(microversion)
|
||||
expected_url = "%s/test?user_id=fake_user" % resource_path
|
||||
with mock.patch.object(manager, '_delete',
|
||||
mock.Mock(return_value='fake_delete')):
|
||||
manager.delete(tenant_id, user_id=user_id)
|
||||
|
||||
def test_refresh_quota(self):
|
||||
q = cs.quotas.get('test')
|
||||
q2 = cs.quotas.get('test')
|
||||
self.assertEqual(q.shares, q2.shares)
|
||||
self.assertEqual(q.snapshots, q2.snapshots)
|
||||
q2.shares = 0
|
||||
self.assertNotEqual(q.shares, q2.shares)
|
||||
q2.snapshots = 0
|
||||
self.assertNotEqual(q.snapshots, q2.snapshots)
|
||||
q2.get()
|
||||
self.assertEqual(q.shares, q2.shares)
|
||||
self.assertEqual(q.snapshots, q2.snapshots)
|
||||
manager._delete.assert_called_once_with(expected_url)
|
||||
|
@ -13,66 +13,86 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient.tests.unit import utils
|
||||
from manilaclient.v2 import services
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class ServicesTest(utils.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ServicesTest, self).setUp()
|
||||
self.manager = services.ServiceManager(api=None)
|
||||
def _get_manager(self, microversion):
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
return services.ServiceManager(api=mock_microversion)
|
||||
|
||||
def test_list(self):
|
||||
with mock.patch.object(self.manager, '_list',
|
||||
mock.Mock(return_value=None)):
|
||||
self.manager.list()
|
||||
self.manager._list.assert_called_once_with(
|
||||
services.RESOURCES_PATH,
|
||||
services.RESOURCES_NAME,
|
||||
)
|
||||
def _get_resource_path(self, microversion):
|
||||
if float(microversion) > 2.6:
|
||||
return services.RESOURCE_PATH
|
||||
return services.RESOURCE_PATH_LEGACY
|
||||
|
||||
@ddt.data("2.6", "2.7")
|
||||
def test_list(self, microversion):
|
||||
manager = self._get_manager(microversion)
|
||||
resource_path = self._get_resource_path(microversion)
|
||||
with mock.patch.object(manager, '_list',
|
||||
mock.Mock(return_value='fake')):
|
||||
result = manager.list()
|
||||
|
||||
manager._list.assert_called_once_with(
|
||||
resource_path, services.RESOURCE_NAME)
|
||||
self.assertEqual("fake", result)
|
||||
|
||||
def test_list_services_with_one_search_opt(self):
|
||||
manager = self._get_manager("2.7")
|
||||
host = 'fake_host'
|
||||
query_string = "?host=%s" % host
|
||||
with mock.patch.object(self.manager, '_list',
|
||||
with mock.patch.object(manager, '_list',
|
||||
mock.Mock(return_value=None)):
|
||||
self.manager.list({'host': host})
|
||||
self.manager._list.assert_called_once_with(
|
||||
services.RESOURCES_PATH + query_string,
|
||||
services.RESOURCES_NAME,
|
||||
manager.list({'host': host})
|
||||
manager._list.assert_called_once_with(
|
||||
services.RESOURCE_PATH + query_string,
|
||||
services.RESOURCE_NAME,
|
||||
)
|
||||
|
||||
def test_list_services_with_two_search_opts(self):
|
||||
manager = self._get_manager("2.7")
|
||||
host = 'fake_host'
|
||||
binary = 'fake_binary'
|
||||
query_string = "?binary=%s&host=%s" % (binary, host)
|
||||
with mock.patch.object(self.manager, '_list',
|
||||
with mock.patch.object(manager, '_list',
|
||||
mock.Mock(return_value=None)):
|
||||
self.manager.list({'binary': binary, 'host': host})
|
||||
self.manager._list.assert_called_once_with(
|
||||
services.RESOURCES_PATH + query_string,
|
||||
services.RESOURCES_NAME,
|
||||
manager.list({'binary': binary, 'host': host})
|
||||
manager._list.assert_called_once_with(
|
||||
services.RESOURCE_PATH + query_string,
|
||||
services.RESOURCE_NAME,
|
||||
)
|
||||
|
||||
def test_enable_service(self):
|
||||
@ddt.data("2.6", "2.7")
|
||||
def test_enable_service(self, microversion):
|
||||
manager = self._get_manager(microversion)
|
||||
host = 'fake_host'
|
||||
binary = 'fake_binary'
|
||||
with mock.patch.object(self.manager, '_update'):
|
||||
self.manager.enable(binary=binary, host=host)
|
||||
self.manager._update.assert_called_once_with(
|
||||
services.RESOURCES_PATH + '/enable',
|
||||
with mock.patch.object(manager, '_update'):
|
||||
manager.enable(binary=binary, host=host)
|
||||
|
||||
manager._update.assert_called_once_with(
|
||||
self._get_resource_path(microversion) + '/enable',
|
||||
{"host": host, "binary": binary},
|
||||
)
|
||||
|
||||
def test_disable_service(self):
|
||||
@ddt.data("2.6", "2.7")
|
||||
def test_disable_service(self, microversion):
|
||||
manager = self._get_manager(microversion)
|
||||
host = 'fake_host'
|
||||
binary = 'fake_binary'
|
||||
with mock.patch.object(self.manager, '_update'):
|
||||
self.manager.disable(binary=binary, host=host)
|
||||
self.manager._update.assert_called_once_with(
|
||||
services.RESOURCES_PATH + '/disable',
|
||||
with mock.patch.object(manager, '_update'):
|
||||
manager.disable(binary=binary, host=host)
|
||||
|
||||
manager._update.assert_called_once_with(
|
||||
self._get_resource_path(microversion) + '/disable',
|
||||
{"host": host, "binary": binary},
|
||||
)
|
||||
|
@ -14,7 +14,9 @@
|
||||
# under the License.
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import extension
|
||||
from manilaclient.tests.unit import utils
|
||||
from manilaclient.tests.unit.v2 import fakes
|
||||
@ -30,6 +32,11 @@ cs = fakes.FakeClient(extensions=extensions)
|
||||
@ddt.ddt
|
||||
class ShareInstancesTest(utils.TestCase):
|
||||
|
||||
def _get_manager(self, microversion):
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
return share_instances.ShareInstanceManager(api=mock_microversion)
|
||||
|
||||
def test_list(self):
|
||||
cs.share_instances.list()
|
||||
cs.assert_called('GET', '/share_instances')
|
||||
@ -39,15 +46,44 @@ class ShareInstancesTest(utils.TestCase):
|
||||
cs.share_instances.get(instance)
|
||||
cs.assert_called('GET', '/share_instances/1234')
|
||||
|
||||
def test_force_delete(self):
|
||||
instance = cs.share_instances.get('1234')
|
||||
cs.share_instances.force_delete(instance)
|
||||
cs.assert_called('POST', '/share_instances/1234/action',
|
||||
{'os-force_delete': None})
|
||||
|
||||
def test_reset_state(self):
|
||||
@ddt.data(
|
||||
("2.6", type("InstanceUUID", (object, ), {"uuid": "1234"})),
|
||||
("2.7", type("InstanceUUID", (object, ), {"uuid": "1234"})),
|
||||
("2.6", type("InstanceID", (object, ), {"id": "1234"})),
|
||||
("2.7", type("InstanceID", (object, ), {"id": "1234"})),
|
||||
("2.6", "1234"),
|
||||
("2.7", "1234"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_reset_instance_state(self, microversion, instance):
|
||||
manager = self._get_manager(microversion)
|
||||
state = 'available'
|
||||
expected_body = {'os-reset_status': {'status': 'available'}}
|
||||
instance = cs.share_instances.get('1234')
|
||||
cs.share_instances.reset_state(instance, state)
|
||||
cs.assert_called('POST', '/share_instances/1234/action', expected_body)
|
||||
if float(microversion) > 2.6:
|
||||
action_name = "reset_status"
|
||||
else:
|
||||
action_name = "os-reset_status"
|
||||
|
||||
with mock.patch.object(manager, "_action", mock.Mock()):
|
||||
manager.reset_state(instance, state)
|
||||
|
||||
manager._action.assert_called_once_with(
|
||||
action_name, instance, {"status": state})
|
||||
|
||||
@ddt.data(
|
||||
("2.6", type('InstanceUUID', (object, ), {"uuid": "1234"})),
|
||||
("2.6", "1234"),
|
||||
("2.7", type('InstanceUUID', (object, ), {"uuid": "1234"})),
|
||||
("2.7", "1234"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_force_delete_share_snapshot(self, microversion, instance):
|
||||
manager = self._get_manager(microversion)
|
||||
if float(microversion) > 2.6:
|
||||
action_name = "force_delete"
|
||||
else:
|
||||
action_name = "os-force_delete"
|
||||
|
||||
with mock.patch.object(manager, "_action", mock.Mock()):
|
||||
manager.force_delete(instance)
|
||||
|
||||
manager._action.assert_called_once_with(action_name, "1234")
|
||||
|
@ -16,7 +16,9 @@
|
||||
# under the License.
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import extension
|
||||
from manilaclient.tests.unit import utils
|
||||
from manilaclient.tests.unit.v2 import fakes
|
||||
@ -32,6 +34,11 @@ cs = fakes.FakeClient(extensions=extensions)
|
||||
@ddt.ddt
|
||||
class ShareSnapshotsTest(utils.TestCase):
|
||||
|
||||
def _get_manager(self, microversion):
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
return share_snapshots.ShareSnapshotManager(api=mock_microversion)
|
||||
|
||||
def test_create_share_snapshot(self):
|
||||
cs.share_snapshots.create(1234)
|
||||
cs.assert_called('POST', '/snapshots')
|
||||
@ -54,25 +61,51 @@ class ShareSnapshotsTest(utils.TestCase):
|
||||
cs.assert_called('PUT', '/snapshots/1234', {'snapshot': data})
|
||||
|
||||
@ddt.data(
|
||||
type('SnapshotUUID', (object, ), {'uuid': '1234'}),
|
||||
type('SnapshotID', (object, ), {'id': '1234'}),
|
||||
'1234')
|
||||
def test_reset_snapshot_state(self, snapshot):
|
||||
("2.6", type('SnapshotUUID', (object, ), {'uuid': '1234'})),
|
||||
("2.7", type('SnapshotUUID', (object, ), {'uuid': '1234'})),
|
||||
("2.6", type('SnapshotID', (object, ), {'id': '1234'})),
|
||||
("2.7", type('SnapshotID', (object, ), {'id': '1234'})),
|
||||
("2.6", "1234"),
|
||||
("2.7", "1234"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_reset_snapshot_state(self, microversion, snapshot):
|
||||
manager = self._get_manager(microversion)
|
||||
state = 'available'
|
||||
expected_body = {'os-reset_status': {'status': 'available'}}
|
||||
cs.share_snapshots.reset_state(snapshot, state)
|
||||
cs.assert_called('POST', '/snapshots/1234/action', expected_body)
|
||||
if float(microversion) > 2.6:
|
||||
action_name = "reset_status"
|
||||
else:
|
||||
action_name = "os-reset_status"
|
||||
|
||||
with mock.patch.object(manager, "_action", mock.Mock()):
|
||||
manager.reset_state(snapshot, state)
|
||||
|
||||
manager._action.assert_called_once_with(
|
||||
action_name, snapshot, {"status": state})
|
||||
|
||||
def test_delete_share_snapshot(self):
|
||||
snapshot = cs.share_snapshots.get(1234)
|
||||
cs.share_snapshots.delete(snapshot)
|
||||
cs.assert_called('DELETE', '/snapshots/1234')
|
||||
|
||||
def test_force_delete_share_snapshot(self):
|
||||
snapshot = cs.share_snapshots.get(1234)
|
||||
cs.share_snapshots.force_delete(snapshot)
|
||||
cs.assert_called('POST', '/snapshots/1234/action',
|
||||
{'os-force_delete': None})
|
||||
@ddt.data(
|
||||
("2.6", type('SnapshotUUID', (object, ), {"uuid": "1234"})),
|
||||
("2.6", "1234"),
|
||||
("2.7", type('SnapshotUUID', (object, ), {"uuid": "1234"})),
|
||||
("2.7", "1234"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_force_delete_share_snapshot(self, microversion, snapshot):
|
||||
manager = self._get_manager(microversion)
|
||||
if float(microversion) > 2.6:
|
||||
action_name = "force_delete"
|
||||
else:
|
||||
action_name = "os-force_delete"
|
||||
|
||||
with mock.patch.object(manager, "_action", mock.Mock()):
|
||||
manager.force_delete(snapshot)
|
||||
|
||||
manager._action.assert_called_once_with(action_name, "1234")
|
||||
|
||||
def test_list_share_snapshots_index(self):
|
||||
cs.share_snapshots.list(detailed=False)
|
||||
|
@ -18,13 +18,13 @@
|
||||
import ddt
|
||||
import mock
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import exceptions
|
||||
from manilaclient import extension
|
||||
from manilaclient.tests.unit import utils
|
||||
from manilaclient.tests.unit.v2 import fakes
|
||||
from manilaclient.v2 import shares
|
||||
|
||||
|
||||
extensions = [
|
||||
extension.Extension('shares', shares),
|
||||
]
|
||||
@ -206,20 +206,92 @@ class SharesTest(utils.TestCase):
|
||||
cs.shares.delete(share)
|
||||
cs.assert_called('DELETE', '/shares/1234')
|
||||
|
||||
def test_manage_share(self):
|
||||
cs.shares.manage('fake_service', 'fake_proto', 'fake_export_path', {})
|
||||
cs.assert_called('POST', '/os-share-manage')
|
||||
@ddt.data(
|
||||
("2.6", "/os-share-manage"),
|
||||
("2.7", "/shares/manage"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_manage_share(self, microversion, resource_path):
|
||||
service_host = "fake_service_host"
|
||||
protocol = "fake_protocol"
|
||||
export_path = "fake_export_path"
|
||||
driver_options = "fake_driver_options"
|
||||
share_type = "fake_share_type"
|
||||
name = "foo_name"
|
||||
description = "bar_description"
|
||||
expected_body = {
|
||||
"service_host": service_host,
|
||||
"share_type": share_type,
|
||||
"protocol": protocol,
|
||||
"export_path": export_path,
|
||||
"driver_options": driver_options,
|
||||
"name": name,
|
||||
"description": description,
|
||||
}
|
||||
|
||||
def test_unmanage_share(self):
|
||||
share = cs.shares.get('1234')
|
||||
cs.shares.unmanage(share)
|
||||
cs.assert_called('POST', '/os-share-unmanage/1234/unmanage')
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
manager = shares.ShareManager(api=mock_microversion)
|
||||
|
||||
def test_force_delete_share(self):
|
||||
share = cs.shares.get('1234')
|
||||
cs.shares.force_delete(share)
|
||||
cs.assert_called('POST', '/shares/1234/action',
|
||||
{'os-force_delete': None})
|
||||
with mock.patch.object(manager, "_create",
|
||||
mock.Mock(return_value="fake")):
|
||||
result = manager.manage(
|
||||
service_host, protocol, export_path, driver_options,
|
||||
share_type, name, description)
|
||||
|
||||
self.assertEqual(manager._create.return_value, result)
|
||||
manager._create.assert_called_once_with(
|
||||
resource_path, {"share": expected_body}, "share")
|
||||
|
||||
@ddt.data(
|
||||
type("ShareUUID", (object, ), {"uuid": "1234"}),
|
||||
type("ShareID", (object, ), {"id": "1234"}),
|
||||
"1234")
|
||||
def test_unmanage_share_v2_6(self, share):
|
||||
version = api_versions.APIVersion("2.6")
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
manager = shares.ShareManager(api=mock_microversion)
|
||||
|
||||
with mock.patch.object(manager, "_action",
|
||||
mock.Mock(return_value="fake")):
|
||||
result = manager.unmanage(share)
|
||||
|
||||
self.assertFalse(manager._action.called)
|
||||
self.assertNotEqual("fake", result)
|
||||
self.assertEqual(manager.api.client.post.return_value, result)
|
||||
manager.api.client.post.assert_called_once_with(
|
||||
"/os-share-unmanage/1234/unmanage")
|
||||
|
||||
def test_unmanage_share_v2_7(self):
|
||||
share = "fake_share"
|
||||
version = api_versions.APIVersion("2.7")
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
manager = shares.ShareManager(api=mock_microversion)
|
||||
|
||||
with mock.patch.object(manager, "_action",
|
||||
mock.Mock(return_value="fake")):
|
||||
result = manager.unmanage(share)
|
||||
|
||||
manager._action.assert_called_once_with("unmanage", share)
|
||||
self.assertEqual("fake", result)
|
||||
|
||||
@ddt.data(
|
||||
("2.6", "os-force_delete"),
|
||||
("2.7", "force_delete"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_force_delete_share(self, microversion, action_name):
|
||||
share = "fake_share"
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
manager = shares.ShareManager(api=mock_microversion)
|
||||
|
||||
with mock.patch.object(manager, "_action",
|
||||
mock.Mock(return_value="fake")):
|
||||
result = manager.force_delete(share)
|
||||
|
||||
manager._action.assert_called_once_with(action_name, share)
|
||||
self.assertEqual("fake", result)
|
||||
|
||||
def test_list_shares_index(self):
|
||||
cs.shares.list(detailed=False)
|
||||
@ -279,17 +351,50 @@ class SharesTest(utils.TestCase):
|
||||
def test_list_shares_by_improper_key(self):
|
||||
self.assertRaises(ValueError, cs.shares.list, sort_key='fake')
|
||||
|
||||
def test_allow_access_to_share(self):
|
||||
share = cs.shares.get(1234)
|
||||
ip = '192.168.0.1'
|
||||
cs.shares.allow(share, 'ip', ip, None)
|
||||
cs.assert_called('POST', '/shares/1234/action')
|
||||
@ddt.data(
|
||||
("2.6", "os-allow_access"),
|
||||
("2.7", "allow_access"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_allow_access_to_share(self, microversion, action_name):
|
||||
access_level = "fake_access_level"
|
||||
access_to = "fake_access_to"
|
||||
access_type = "fake_access_type"
|
||||
share = "fake_share"
|
||||
access = ("foo", {"access": "bar"})
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
manager = shares.ShareManager(api=mock_microversion)
|
||||
|
||||
def test_allow_access_to_share_with_cert(self):
|
||||
share = cs.shares.get(1234)
|
||||
common_name = 'test.example.com'
|
||||
cs.shares.allow(share, 'cert', common_name, None)
|
||||
cs.assert_called('POST', '/shares/1234/action')
|
||||
with mock.patch.object(manager, "_action",
|
||||
mock.Mock(return_value=access)):
|
||||
result = manager.allow(share, access_type, access_to, access_level)
|
||||
|
||||
manager._action.assert_called_once_with(
|
||||
action_name, share, {"access_level": access_level,
|
||||
"access_type": access_type,
|
||||
"access_to": access_to})
|
||||
self.assertEqual("bar", result)
|
||||
|
||||
@ddt.data(
|
||||
("2.6", "os-deny_access"),
|
||||
("2.7", "deny_access"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_deny_access_to_share(self, microversion, action_name):
|
||||
access_id = "fake_access_id"
|
||||
share = "fake_share"
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
manager = shares.ShareManager(api=mock_microversion)
|
||||
|
||||
with mock.patch.object(manager, "_action",
|
||||
mock.Mock(return_value="fake")):
|
||||
result = manager.deny(share, access_id)
|
||||
|
||||
manager._action.assert_called_once_with(
|
||||
action_name, share, {"access_id": access_id})
|
||||
self.assertEqual("fake", result)
|
||||
|
||||
def test_get_metadata(self):
|
||||
cs.shares.get_metadata(1234)
|
||||
@ -319,41 +424,88 @@ class SharesTest(utils.TestCase):
|
||||
{'metadata': {'k1': 'v1'}})
|
||||
|
||||
@ddt.data(
|
||||
type('ShareUUID', (object, ), {'uuid': '1234'}),
|
||||
type('ShareID', (object, ), {'id': '1234'}),
|
||||
'1234')
|
||||
def test_reset_share_state(self, share):
|
||||
state = 'available'
|
||||
expected_body = {'os-reset_status': {'status': 'available'}}
|
||||
cs.shares.reset_state(share, state)
|
||||
cs.assert_called('POST', '/shares/1234/action', expected_body)
|
||||
("2.6", "os-reset_status"),
|
||||
("2.7", "reset_status"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_reset_share_state(self, microversion, action_name):
|
||||
state = "available"
|
||||
share = "fake_share"
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
manager = shares.ShareManager(api=mock_microversion)
|
||||
|
||||
with mock.patch.object(manager, "_action",
|
||||
mock.Mock(return_value="fake")):
|
||||
result = manager.reset_state(share, state)
|
||||
|
||||
manager._action.assert_called_once_with(
|
||||
action_name, share, {"status": state})
|
||||
self.assertEqual("fake", result)
|
||||
|
||||
@ddt.data(
|
||||
type('ShareUUID', (object, ), {'uuid': '1234'}),
|
||||
type('ShareID', (object, ), {'id': '1234'}),
|
||||
'1234')
|
||||
def test_extend_share(self, share):
|
||||
("2.6", "os-extend"),
|
||||
("2.7", "extend"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_extend_share(self, microversion, action_name):
|
||||
size = 123
|
||||
expected_body = {'os-extend': {'new_size': size}}
|
||||
cs.shares.extend(share, size)
|
||||
cs.assert_called('POST', '/shares/1234/action', expected_body)
|
||||
share = "fake_share"
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
manager = shares.ShareManager(api=mock_microversion)
|
||||
|
||||
with mock.patch.object(manager, "_action",
|
||||
mock.Mock(return_value="fake")):
|
||||
result = manager.extend(share, size)
|
||||
|
||||
manager._action.assert_called_once_with(
|
||||
action_name, share, {"new_size": size})
|
||||
self.assertEqual("fake", result)
|
||||
|
||||
@ddt.data(
|
||||
type('ShareUUID', (object, ), {'uuid': '1234'}),
|
||||
type('ShareID', (object, ), {'id': '1234'}),
|
||||
'1234')
|
||||
def test_shrink_share(self, share):
|
||||
("2.6", "os-shrink"),
|
||||
("2.7", "shrink"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_shrink_share(self, microversion, action_name):
|
||||
size = 123
|
||||
expected_body = {'os-shrink': {'new_size': size}}
|
||||
cs.shares.shrink(share, size)
|
||||
cs.assert_called('POST', '/shares/1234/action', expected_body)
|
||||
share = "fake_share"
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
manager = shares.ShareManager(api=mock_microversion)
|
||||
|
||||
with mock.patch.object(manager, "_action",
|
||||
mock.Mock(return_value="fake")):
|
||||
result = manager.shrink(share, size)
|
||||
|
||||
manager._action.assert_called_once_with(
|
||||
action_name, share, {"new_size": size})
|
||||
self.assertEqual("fake", result)
|
||||
|
||||
def test_list_share_instances(self):
|
||||
share = type('ShareID', (object, ), {'id': '1234'})
|
||||
cs.shares.list_instances(share)
|
||||
cs.assert_called('GET', '/shares/1234/instances')
|
||||
|
||||
def test_migrate_share(self):
|
||||
host = 'fake_host'
|
||||
self.share.migrate_share(host, True)
|
||||
self.assertTrue(self.share.manager.migrate_share.called)
|
||||
@ddt.data(
|
||||
("2.6", "os-migrate_share"),
|
||||
("2.7", "migrate_share"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_migrate_share(self, microversion, action_name):
|
||||
share = "fake_share"
|
||||
host = "fake_host"
|
||||
force_host_copy = "fake_force_host_copy"
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
manager = shares.ShareManager(api=mock_microversion)
|
||||
|
||||
with mock.patch.object(manager, "_action",
|
||||
mock.Mock(return_value="fake")):
|
||||
result = manager.migrate_share(share, host, force_host_copy)
|
||||
|
||||
manager._action.assert_called_once_with(
|
||||
action_name, share,
|
||||
{"host": host, "force_host_copy": force_host_copy})
|
||||
self.assertEqual("fake", result)
|
||||
|
@ -101,20 +101,20 @@ class ShellTest(test_utils.TestCase):
|
||||
|
||||
def test_service_list(self):
|
||||
self.run_command('service-list')
|
||||
self.assert_called('GET', '/os-services')
|
||||
self.assert_called('GET', '/services')
|
||||
|
||||
def test_service_enable(self):
|
||||
self.run_command('service-enable foo_host@bar_backend manila-share')
|
||||
self.assert_called(
|
||||
'PUT',
|
||||
'/os-services/enable',
|
||||
'/services/enable',
|
||||
{'host': 'foo_host@bar_backend', 'binary': 'manila-share'})
|
||||
|
||||
def test_service_disable(self):
|
||||
self.run_command('service-disable foo_host@bar_backend manila-share')
|
||||
self.assert_called(
|
||||
'PUT',
|
||||
'/os-services/disable',
|
||||
'/services/disable',
|
||||
{'host': 'foo_host@bar_backend', 'binary': 'manila-share'})
|
||||
|
||||
def test_list(self):
|
||||
@ -315,7 +315,7 @@ class ShellTest(test_utils.TestCase):
|
||||
|
||||
def test_share_instance_reset_state(self):
|
||||
self.run_command('share-instance-reset-state 1234')
|
||||
expected = {'os-reset_status': {'status': 'available'}}
|
||||
expected = {'reset_status': {'status': 'available'}}
|
||||
self.assert_called('POST', '/share_instances/1234/action',
|
||||
body=expected)
|
||||
|
||||
@ -357,7 +357,7 @@ class ShellTest(test_utils.TestCase):
|
||||
'driver_handles_share_servers': False,
|
||||
'snapshot_support': True,
|
||||
},
|
||||
'os-share-type-access:is_public': public
|
||||
'share_type_access:is_public': public
|
||||
}
|
||||
}
|
||||
self.run_command(
|
||||
@ -367,7 +367,7 @@ class ShellTest(test_utils.TestCase):
|
||||
|
||||
def test_type_access_list(self):
|
||||
self.run_command('type-access-list 3')
|
||||
self.assert_called('GET', '/types/3/os-share-type-access')
|
||||
self.assert_called('GET', '/types/3/share_type_access')
|
||||
|
||||
def test_type_access_add_project(self):
|
||||
expected = {'addProjectAccess': {'project': '101'}}
|
||||
@ -438,11 +438,11 @@ class ShellTest(test_utils.TestCase):
|
||||
}
|
||||
expected['share'].update(valid_params)
|
||||
|
||||
self.assert_called('POST', '/os-share-manage', body=expected)
|
||||
self.assert_called('POST', '/shares/manage', body=expected)
|
||||
|
||||
def test_unmanage(self):
|
||||
self.run_command('unmanage 1234')
|
||||
self.assert_called('POST', '/os-share-unmanage/1234/unmanage')
|
||||
self.assert_called('POST', '/shares/1234/action')
|
||||
|
||||
def test_delete(self):
|
||||
self.run_command('delete 1234')
|
||||
@ -595,7 +595,7 @@ class ShellTest(test_utils.TestCase):
|
||||
expected = {
|
||||
"share_type": {
|
||||
"name": "test",
|
||||
"os-share-type-access:is_public": True,
|
||||
"share_type_access:is_public": True,
|
||||
"extra_specs": {
|
||||
"driver_handles_share_servers": expected_bool,
|
||||
"snapshot_support": True,
|
||||
@ -618,7 +618,7 @@ class ShellTest(test_utils.TestCase):
|
||||
expected = {
|
||||
"share_type": {
|
||||
"name": "test",
|
||||
"os-share-type-access:is_public": True,
|
||||
"share_type_access:is_public": True,
|
||||
"extra_specs": {
|
||||
"driver_handles_share_servers": False,
|
||||
"snapshot_support": expected_bool,
|
||||
@ -743,32 +743,32 @@ class ShellTest(test_utils.TestCase):
|
||||
|
||||
def test_extend(self):
|
||||
self.run_command('extend 1234 77')
|
||||
expected = {'os-extend': {'new_size': 77}}
|
||||
expected = {'extend': {'new_size': 77}}
|
||||
self.assert_called('POST', '/shares/1234/action', body=expected)
|
||||
|
||||
def test_reset_state(self):
|
||||
self.run_command('reset-state 1234')
|
||||
expected = {'os-reset_status': {'status': 'available'}}
|
||||
expected = {'reset_status': {'status': 'available'}}
|
||||
self.assert_called('POST', '/shares/1234/action', body=expected)
|
||||
|
||||
def test_shrink(self):
|
||||
self.run_command('shrink 1234 77')
|
||||
expected = {'os-shrink': {'new_size': 77}}
|
||||
expected = {'shrink': {'new_size': 77}}
|
||||
self.assert_called('POST', '/shares/1234/action', body=expected)
|
||||
|
||||
def test_reset_state_with_flag(self):
|
||||
self.run_command('reset-state --state error 1234')
|
||||
expected = {'os-reset_status': {'status': 'error'}}
|
||||
expected = {'reset_status': {'status': 'error'}}
|
||||
self.assert_called('POST', '/shares/1234/action', body=expected)
|
||||
|
||||
def test_snapshot_reset_state(self):
|
||||
self.run_command('snapshot-reset-state 1234')
|
||||
expected = {'os-reset_status': {'status': 'available'}}
|
||||
expected = {'reset_status': {'status': 'available'}}
|
||||
self.assert_called('POST', '/snapshots/1234/action', body=expected)
|
||||
|
||||
def test_snapshot_reset_state_with_flag(self):
|
||||
self.run_command('snapshot-reset-state --state error 1234')
|
||||
expected = {'os-reset_status': {'status': 'error'}}
|
||||
expected = {'reset_status': {'status': 'error'}}
|
||||
self.assert_called('POST', '/snapshots/1234/action', body=expected)
|
||||
|
||||
@ddt.data(
|
||||
@ -1088,7 +1088,7 @@ class ShellTest(test_utils.TestCase):
|
||||
self.run_command("access-allow 1234 cert client.example.com")
|
||||
|
||||
expected = {
|
||||
"os-allow_access": {
|
||||
"allow_access": {
|
||||
"access_type": "cert",
|
||||
"access_to": "client.example.com",
|
||||
}
|
||||
@ -1121,7 +1121,7 @@ class ShellTest(test_utils.TestCase):
|
||||
def test_allow_access_with_access_level(self):
|
||||
aliases = ['--access_level', '--access-level']
|
||||
expected = {
|
||||
"os-allow_access": {
|
||||
"allow_access": {
|
||||
"access_type": "ip",
|
||||
"access_to": "10.0.0.6",
|
||||
"access_level": "ro",
|
||||
@ -1137,14 +1137,14 @@ class ShellTest(test_utils.TestCase):
|
||||
|
||||
def test_allow_access_with_valid_access_levels(self):
|
||||
expected = {
|
||||
"os-allow_access": {
|
||||
"allow_access": {
|
||||
"access_type": "ip",
|
||||
"access_to": "10.0.0.6",
|
||||
}
|
||||
}
|
||||
|
||||
for level in ['rw', 'ro']:
|
||||
expected["os-allow_access"]['access_level'] = level
|
||||
expected["allow_access"]['access_level'] = level
|
||||
self.run_command(
|
||||
"access-allow --access-level " + level + " 1111 ip 10.0.0.6")
|
||||
self.assert_called("POST", "/shares/1111/action",
|
||||
@ -1359,7 +1359,7 @@ class ShellTest(test_utils.TestCase):
|
||||
|
||||
self.run_command('cg-delete --force fake-cg')
|
||||
self.assert_called('POST', '/consistency-groups/1234/action',
|
||||
{'os-force_delete': None})
|
||||
{'force_delete': None})
|
||||
|
||||
@mock.patch.object(shell_v2, '_find_consistency_group', mock.Mock())
|
||||
def test_cg_reset_state_with_flag(self):
|
||||
@ -1368,7 +1368,7 @@ class ShellTest(test_utils.TestCase):
|
||||
|
||||
self.run_command('cg-reset-state --state error 1234')
|
||||
self.assert_called('POST', '/consistency-groups/1234/action',
|
||||
{'os-reset_status': {'status': 'error'}})
|
||||
{'reset_status': {'status': 'error'}})
|
||||
|
||||
@mock.patch.object(shell_v2, '_find_cg_snapshot', mock.Mock())
|
||||
def test_cg_snapshot_reset_state(self):
|
||||
@ -1377,7 +1377,7 @@ class ShellTest(test_utils.TestCase):
|
||||
|
||||
self.run_command('cg-snapshot-reset-state 1234')
|
||||
self.assert_called('POST', '/cgsnapshots/1234/action',
|
||||
{'os-reset_status': {'status': 'available'}})
|
||||
{'reset_status': {'status': 'available'}})
|
||||
|
||||
@mock.patch.object(shell_v2, '_find_cg_snapshot', mock.Mock())
|
||||
def test_cg_snapshot_reset_state_with_flag(self):
|
||||
@ -1386,7 +1386,7 @@ class ShellTest(test_utils.TestCase):
|
||||
|
||||
self.run_command('cg-snapshot-reset-state --state creating 1234')
|
||||
self.assert_called('POST', '/cgsnapshots/1234/action',
|
||||
{'os-reset_status': {'status': 'creating'}})
|
||||
{'reset_status': {'status': 'creating'}})
|
||||
|
||||
@mock.patch.object(cliutils, 'print_list', mock.Mock())
|
||||
def test_cg_snapshot_list(self):
|
||||
@ -1456,7 +1456,7 @@ class ShellTest(test_utils.TestCase):
|
||||
|
||||
self.run_command('cg-snapshot-delete --force fake-cg')
|
||||
self.assert_called('POST', '/cgsnapshots/1234/action',
|
||||
{'os-force_delete': None})
|
||||
{'force_delete': None})
|
||||
|
||||
@ddt.data(
|
||||
{'--shares': 5},
|
||||
@ -1481,4 +1481,4 @@ class ShellTest(test_utils.TestCase):
|
||||
expected = dict(quota_class_set=expected)
|
||||
|
||||
self.run_command(cmd)
|
||||
self.assert_called('PUT', '/os-quota-class-sets/test', body=expected)
|
||||
self.assert_called('PUT', '/quota-class-sets/test', body=expected)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Copyright (c) 2013 OpenStack Foundation
|
||||
#
|
||||
# Copyright (c) 2015 Mirantis, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -14,41 +14,81 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient.tests.unit import utils
|
||||
from manilaclient.tests.unit.v2 import fakes
|
||||
from manilaclient.v2 import share_type_access
|
||||
|
||||
cs = fakes.FakeClient()
|
||||
|
||||
PROJECT_UUID = '11111111-1111-1111-111111111111'
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TypeAccessTest(utils.TestCase):
|
||||
|
||||
def test_list(self):
|
||||
def _get_share_type_access_manager(self, microversion):
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
return share_type_access.ShareTypeAccessManager(
|
||||
api=mock_microversion)
|
||||
|
||||
@ddt.data(
|
||||
("1.0", "os-share-type-access"),
|
||||
("2.0", "os-share-type-access"),
|
||||
("2.6", "os-share-type-access"),
|
||||
("2.7", "share_type_access"),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_list(self, microversion, action_name):
|
||||
fake_access_list = ['foo', 'bar']
|
||||
share_type = mock.Mock()
|
||||
share_type.uuid = '3'
|
||||
share_type.is_public = False
|
||||
access = cs.share_type_access.list(share_type=share_type)
|
||||
cs.assert_called('GET', '/types/3/os-share-type-access')
|
||||
for a in access:
|
||||
self.assertTrue(isinstance(a, share_type_access.ShareTypeAccess))
|
||||
manager = self._get_share_type_access_manager(microversion)
|
||||
|
||||
def test_list_public(self):
|
||||
with mock.patch.object(manager, '_list',
|
||||
mock.Mock(return_value=fake_access_list)):
|
||||
access = manager.list(share_type=share_type)
|
||||
|
||||
manager._list.assert_called_once_with(
|
||||
"/types/3/%s" % action_name, "share_type_access")
|
||||
self.assertEqual(fake_access_list, access)
|
||||
|
||||
@ddt.data("1.0", "2.0", "2.6", "2.7")
|
||||
def test_list_public(self, microversion):
|
||||
share_type = mock.Mock()
|
||||
share_type.uuid = '4'
|
||||
share_type.is_public = True
|
||||
actual_result = cs.share_type_access.list(share_type=share_type)
|
||||
self.assertEqual(None, actual_result)
|
||||
manager = self._get_share_type_access_manager(microversion)
|
||||
|
||||
def test_add_project_access(self):
|
||||
cs.share_type_access.add_project_access('3', PROJECT_UUID)
|
||||
cs.assert_called('POST', '/types/3/action',
|
||||
{'addProjectAccess': {'project': PROJECT_UUID}})
|
||||
with mock.patch.object(manager, '_list',
|
||||
mock.Mock(return_value='fake')):
|
||||
access = manager.list(share_type=share_type)
|
||||
|
||||
def test_remove_project_access(self):
|
||||
cs.share_type_access.remove_project_access('3', PROJECT_UUID)
|
||||
cs.assert_called('POST', '/types/3/action',
|
||||
{'removeProjectAccess': {'project': PROJECT_UUID}})
|
||||
self.assertFalse(manager._list.called)
|
||||
self.assertEqual(None, access)
|
||||
|
||||
@ddt.data("1.0", "2.0", "2.6", "2.7")
|
||||
def test_add_project_access(self, microversion):
|
||||
share_type = mock.Mock()
|
||||
manager = self._get_share_type_access_manager(microversion)
|
||||
|
||||
with mock.patch.object(manager, '_action',
|
||||
mock.Mock(return_value='fake_action')):
|
||||
manager.add_project_access(share_type, PROJECT_UUID)
|
||||
|
||||
manager._action.assert_called_once_with(
|
||||
'addProjectAccess', share_type, {'project': PROJECT_UUID})
|
||||
|
||||
@ddt.data("1.0", "2.0", "2.6", "2.7")
|
||||
def test_remove_project_access(self, microversion):
|
||||
share_type = mock.Mock()
|
||||
manager = self._get_share_type_access_manager(microversion)
|
||||
|
||||
with mock.patch.object(manager, '_action',
|
||||
mock.Mock(return_value='fake_action')):
|
||||
manager.remove_project_access(share_type, PROJECT_UUID)
|
||||
|
||||
manager._action.assert_called_once_with(
|
||||
'removeProjectAccess', share_type, {'project': PROJECT_UUID})
|
||||
|
@ -14,6 +14,7 @@
|
||||
import ddt
|
||||
import mock
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient.tests.unit import utils
|
||||
from manilaclient.tests.unit.v2 import fakes
|
||||
from manilaclient.v2 import share_types
|
||||
@ -24,6 +25,11 @@ cs = fakes.FakeClient()
|
||||
@ddt.ddt
|
||||
class TypesTest(utils.TestCase):
|
||||
|
||||
def _get_share_types_manager(self, microversion):
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
return share_types.ShareTypeManager(api=mock_microversion)
|
||||
|
||||
@ddt.data(
|
||||
{'snapshot_support': 'False'},
|
||||
{'snapshot_support': 'False', 'foo': 'bar'},
|
||||
@ -67,10 +73,11 @@ class TypesTest(utils.TestCase):
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_create(self, is_public, dhss, snapshot_support):
|
||||
manager = self._get_share_types_manager("2.7")
|
||||
expected_body = {
|
||||
"share_type": {
|
||||
"name": 'test-type-3',
|
||||
'os-share-type-access:is_public': is_public,
|
||||
'share_type_access:is_public': is_public,
|
||||
"extra_specs": {
|
||||
"driver_handles_share_servers": dhss,
|
||||
"snapshot_support": snapshot_support,
|
||||
@ -78,17 +85,32 @@ class TypesTest(utils.TestCase):
|
||||
}
|
||||
}
|
||||
|
||||
result = cs.share_types.create(
|
||||
'test-type-3', dhss, snapshot_support, is_public=is_public)
|
||||
cs.assert_called('POST', '/types', expected_body)
|
||||
self.assertIsInstance(result, share_types.ShareType)
|
||||
with mock.patch.object(manager, '_create',
|
||||
mock.Mock(return_value="fake")):
|
||||
result = manager.create(
|
||||
'test-type-3', dhss, snapshot_support, is_public=is_public)
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_create_with_default_values(self, dhss):
|
||||
manager._create.assert_called_once_with(
|
||||
"/types", expected_body, "share_type")
|
||||
self.assertEqual("fake", result)
|
||||
|
||||
@ddt.data(
|
||||
("2.6", True),
|
||||
("2.7", True),
|
||||
("2.6", False),
|
||||
("2.7", False),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_create_with_default_values(self, microversion, dhss):
|
||||
manager = self._get_share_types_manager(microversion)
|
||||
if float(microversion) > 2.6:
|
||||
is_public_keyname = "share_type_access:is_public"
|
||||
else:
|
||||
is_public_keyname = "os-share-type-access:is_public"
|
||||
expected_body = {
|
||||
"share_type": {
|
||||
"name": 'test-type-3',
|
||||
'os-share-type-access:is_public': True,
|
||||
is_public_keyname: True,
|
||||
"extra_specs": {
|
||||
"driver_handles_share_servers": dhss,
|
||||
"snapshot_support": True,
|
||||
@ -96,9 +118,13 @@ class TypesTest(utils.TestCase):
|
||||
}
|
||||
}
|
||||
|
||||
result = cs.share_types.create('test-type-3', dhss)
|
||||
cs.assert_called('POST', '/types', expected_body)
|
||||
self.assertIsInstance(result, share_types.ShareType)
|
||||
with mock.patch.object(manager, '_create',
|
||||
mock.Mock(return_value="fake")):
|
||||
result = manager.create('test-type-3', dhss)
|
||||
|
||||
manager._create.assert_called_once_with(
|
||||
"/types", expected_body, "share_type")
|
||||
self.assertEqual("fake", result)
|
||||
|
||||
def test_set_key(self):
|
||||
t = cs.share_types.get(1)
|
||||
|
@ -123,8 +123,7 @@ class ConsistencyGroupSnapshotManager(base.ManagerWithFind):
|
||||
|
||||
return self._list(path, RESOURCES_NAME)
|
||||
|
||||
@api_versions.wraps("2.4")
|
||||
def delete(self, cg_snapshot, force=False):
|
||||
def _do_delete(self, cg_snapshot, force=False, action_name='force_delete'):
|
||||
"""Delete a consistency group snapshot.
|
||||
|
||||
:param cg_snapshot: either a cg snapshot object or text wit its ID.
|
||||
@ -133,13 +132,21 @@ class ConsistencyGroupSnapshotManager(base.ManagerWithFind):
|
||||
body = None
|
||||
|
||||
if force:
|
||||
body = {'os-force_delete': None}
|
||||
body = {action_name: None}
|
||||
|
||||
if body:
|
||||
self.api.client.post(RESOURCE_PATH_ACTION % cg_id, body=body)
|
||||
else:
|
||||
self._delete(RESOURCE_PATH % cg_id)
|
||||
|
||||
@api_versions.wraps("2.4", "2.6")
|
||||
def delete(self, cg_snapshot, force=False):
|
||||
return self._do_delete(cg_snapshot, force, 'os-force_delete')
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def delete(self, cg_snapshot, force=False):
|
||||
return self._do_delete(cg_snapshot, force, 'force_delete')
|
||||
|
||||
@api_versions.wraps("2.4")
|
||||
def members(self, cg_snapshot, search_opts=None):
|
||||
"""Get a list of consistency group snapshot members.
|
||||
@ -161,14 +168,21 @@ class ConsistencyGroupSnapshotManager(base.ManagerWithFind):
|
||||
|
||||
return self._list(path, MEMBERS_RESOURCE_NAME)
|
||||
|
||||
@api_versions.wraps("2.4")
|
||||
def reset_state(self, cg_snapshot, state):
|
||||
def _do_reset_state(self, cg_snapshot, state, action_name):
|
||||
"""Update the specified consistency group with the provided state."""
|
||||
body = {'os-reset_status': {'status': state}}
|
||||
body = {action_name: {'status': state}}
|
||||
cg_id = common_base.getid(cg_snapshot)
|
||||
url = RESOURCE_PATH_ACTION % cg_id
|
||||
return self.api.client.post(url, body=body)
|
||||
|
||||
@api_versions.wraps("2.4", "2.6")
|
||||
def reset_state(self, cg_snapshot, state):
|
||||
return self._do_reset_state(cg_snapshot, state, 'os-reset_status')
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def reset_state(self, cg_snapshot, state):
|
||||
return self._do_reset_state(cg_snapshot, state, 'reset_status')
|
||||
|
||||
def _query_string_helper(self, search_opts):
|
||||
q_string = parse.urlencode(
|
||||
sorted([(k, v) for (k, v) in list(search_opts.items()) if v]))
|
||||
|
@ -139,8 +139,8 @@ class ConsistencyGroupManager(base.ManagerWithFind):
|
||||
|
||||
return self._list(path, RESOURCES_NAME)
|
||||
|
||||
@api_versions.wraps("2.4")
|
||||
def delete(self, consistency_group, force=False):
|
||||
def _do_delete(self, consistency_group, force=False,
|
||||
action_name='force_delete'):
|
||||
"""Delete a consistency group.
|
||||
|
||||
:param consistency_group: either consistency group object or text with
|
||||
@ -151,20 +151,36 @@ class ConsistencyGroupManager(base.ManagerWithFind):
|
||||
body = None
|
||||
|
||||
if force:
|
||||
body = {'os-force_delete': None}
|
||||
body = {action_name: None}
|
||||
|
||||
if body:
|
||||
self.api.client.post(url + '/action', body=body)
|
||||
else:
|
||||
self._delete(url)
|
||||
|
||||
@api_versions.wraps("2.4")
|
||||
def reset_state(self, consistency_group, state):
|
||||
@api_versions.wraps("2.4", "2.6")
|
||||
def delete(self, consistency_group, force=False):
|
||||
return self._do_delete(consistency_group, force, 'os-force_delete')
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def delete(self, consistency_group, force=False):
|
||||
return self._do_delete(consistency_group, force, 'force_delete')
|
||||
|
||||
def _do_reset_state(self, consistency_group, state, action_name):
|
||||
"""Update the specified consistency group with the provided state."""
|
||||
body = {'os-reset_status': {'status': state}}
|
||||
body = {action_name: {'status': state}}
|
||||
url = RESOURCE_PATH_ACTION % common_base.getid(consistency_group)
|
||||
return self.api.client.post(url, body=body)
|
||||
|
||||
@api_versions.wraps("2.4", "2.6")
|
||||
def reset_state(self, cg, state):
|
||||
return self._do_reset_state(
|
||||
consistency_group, state, 'os-reset_status')
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def reset_state(self, consistency_group, state):
|
||||
return self._do_reset_state(consistency_group, state, 'reset_status')
|
||||
|
||||
def _query_string_helper(self, search_opts):
|
||||
q_string = parse.urlencode(
|
||||
sorted([(k, v) for (k, v) in list(search_opts.items()) if v]))
|
||||
|
@ -13,9 +13,13 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import base
|
||||
from manilaclient.openstack.common.apiclient import base as common_base
|
||||
|
||||
RESOURCE_PATH_LEGACY = '/os-quota-class-sets'
|
||||
RESOURCE_PATH = '/quota-class-sets'
|
||||
|
||||
|
||||
class QuotaClassSet(common_base.Resource):
|
||||
|
||||
@ -31,18 +35,24 @@ class QuotaClassSet(common_base.Resource):
|
||||
class QuotaClassSetManager(base.ManagerWithFind):
|
||||
resource_class = QuotaClassSet
|
||||
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def get(self, class_name):
|
||||
return self._get("/os-quota-class-sets/%s" % class_name,
|
||||
"quota_class_set")
|
||||
return self._get(
|
||||
"%(resource_path)s/%(class_name)s" % {
|
||||
"resource_path": RESOURCE_PATH_LEGACY,
|
||||
"class_name": class_name},
|
||||
"quota_class_set")
|
||||
|
||||
def update(self,
|
||||
class_name,
|
||||
shares=None,
|
||||
gigabytes=None,
|
||||
snapshots=None,
|
||||
snapshot_gigabytes=None,
|
||||
share_networks=None):
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def get(self, class_name):
|
||||
return self._get(
|
||||
"%(resource_path)s/%(class_name)s" % {
|
||||
"resource_path": RESOURCE_PATH, "class_name": class_name},
|
||||
"quota_class_set")
|
||||
|
||||
def _do_update(self, class_name, shares=None, gigabytes=None,
|
||||
snapshots=None, snapshot_gigabytes=None,
|
||||
share_networks=None, resource_path=RESOURCE_PATH):
|
||||
body = {
|
||||
'quota_class_set': {
|
||||
'class_name': class_name,
|
||||
@ -58,4 +68,22 @@ class QuotaClassSetManager(base.ManagerWithFind):
|
||||
if body['quota_class_set'][key] is None:
|
||||
body['quota_class_set'].pop(key)
|
||||
|
||||
self._update('/os-quota-class-sets/%s' % class_name, body)
|
||||
self._update(
|
||||
"%(resource_path)s/%(class_name)s" % {
|
||||
"resource_path": resource_path,
|
||||
"class_name": class_name},
|
||||
body)
|
||||
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def update(self, class_name, shares=None, gigabytes=None,
|
||||
snapshots=None, snapshot_gigabytes=None, share_networks=None):
|
||||
return self._do_update(
|
||||
class_name, shares, gigabytes, snapshots, snapshot_gigabytes,
|
||||
share_networks, RESOURCE_PATH_LEGACY)
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def update(self, class_name, shares=None, gigabytes=None,
|
||||
snapshots=None, snapshot_gigabytes=None, share_networks=None):
|
||||
return self._do_update(
|
||||
class_name, shares, gigabytes, snapshots, snapshot_gigabytes,
|
||||
share_networks, RESOURCE_PATH)
|
||||
|
@ -13,9 +13,13 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import base
|
||||
from manilaclient.openstack.common.apiclient import base as common_base
|
||||
|
||||
RESOURCE_PATH_LEGACY = '/os-quota-sets'
|
||||
RESOURCE_PATH = '/quota-sets'
|
||||
|
||||
|
||||
class QuotaSet(common_base.Resource):
|
||||
|
||||
@ -31,18 +35,32 @@ class QuotaSet(common_base.Resource):
|
||||
class QuotaSetManager(base.ManagerWithFind):
|
||||
resource_class = QuotaSet
|
||||
|
||||
def get(self, tenant_id, user_id=None):
|
||||
def _do_get(self, tenant_id, user_id=None, resource_path=RESOURCE_PATH):
|
||||
if hasattr(tenant_id, 'tenant_id'):
|
||||
tenant_id = tenant_id.tenant_id
|
||||
data = {
|
||||
"resource_path": resource_path,
|
||||
"tenant_id": tenant_id,
|
||||
"user_id": user_id,
|
||||
}
|
||||
if user_id:
|
||||
url = "/os-quota-sets/%s?user_id=%s" % (tenant_id, user_id)
|
||||
url = "%(resource_path)s/%(tenant_id)s?user_id=%(user_id)s" % data
|
||||
else:
|
||||
url = "/os-quota-sets/%s" % tenant_id
|
||||
url = "%(resource_path)s/%(tenant_id)s" % data
|
||||
return self._get(url, "quota_set")
|
||||
|
||||
def update(self, tenant_id, shares=None, snapshots=None,
|
||||
gigabytes=None, snapshot_gigabytes=None,
|
||||
share_networks=None, force=None, user_id=None):
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def get(self, tenant_id, user_id=None):
|
||||
return self._do_get(tenant_id, user_id, RESOURCE_PATH_LEGACY)
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def get(self, tenant_id, user_id=None):
|
||||
return self._do_get(tenant_id, user_id, RESOURCE_PATH)
|
||||
|
||||
def _do_update(self, tenant_id, shares=None, snapshots=None,
|
||||
gigabytes=None, snapshot_gigabytes=None,
|
||||
share_networks=None, force=None, user_id=None,
|
||||
resource_path=RESOURCE_PATH):
|
||||
|
||||
body = {
|
||||
'quota_set': {
|
||||
@ -59,20 +77,67 @@ class QuotaSetManager(base.ManagerWithFind):
|
||||
for key in list(body['quota_set']):
|
||||
if body['quota_set'][key] is None:
|
||||
body['quota_set'].pop(key)
|
||||
data = {
|
||||
"resource_path": resource_path,
|
||||
"tenant_id": tenant_id,
|
||||
"user_id": user_id,
|
||||
}
|
||||
if user_id:
|
||||
url = '/os-quota-sets/%s?user_id=%s' % (tenant_id, user_id)
|
||||
url = '%(resource_path)s/%(tenant_id)s?user_id=%(user_id)s' % data
|
||||
else:
|
||||
url = '/os-quota-sets/%s' % tenant_id
|
||||
url = "%(resource_path)s/%(tenant_id)s" % data
|
||||
|
||||
return self._update(url, body, 'quota_set')
|
||||
|
||||
def defaults(self, tenant_id):
|
||||
return self._get('/os-quota-sets/%s/defaults' % tenant_id,
|
||||
'quota_set')
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def update(self, tenant_id, shares=None, snapshots=None, gigabytes=None,
|
||||
snapshot_gigabytes=None, share_networks=None, force=None,
|
||||
user_id=None):
|
||||
return self._do_update(
|
||||
tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes,
|
||||
share_networks, force, user_id, RESOURCE_PATH_LEGACY,
|
||||
)
|
||||
|
||||
def delete(self, tenant_id, user_id=None):
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def update(self, tenant_id, shares=None, snapshots=None, gigabytes=None,
|
||||
snapshot_gigabytes=None, share_networks=None, force=None,
|
||||
user_id=None):
|
||||
return self._do_update(
|
||||
tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes,
|
||||
share_networks, force, user_id, RESOURCE_PATH,
|
||||
)
|
||||
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def defaults(self, tenant_id):
|
||||
return self._get(
|
||||
"%(resource_path)s/%(tenant_id)s/defaults" % {
|
||||
"resource_path": RESOURCE_PATH_LEGACY, "tenant_id": tenant_id},
|
||||
"quota_set")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def defaults(self, tenant_id):
|
||||
return self._get(
|
||||
"%(resource_path)s/%(tenant_id)s/defaults" % {
|
||||
"resource_path": RESOURCE_PATH, "tenant_id": tenant_id},
|
||||
"quota_set")
|
||||
|
||||
def _do_delete(self, tenant_id, user_id=None, resource_path=RESOURCE_PATH):
|
||||
data = {
|
||||
"resource_path": resource_path,
|
||||
"tenant_id": tenant_id,
|
||||
"user_id": user_id,
|
||||
}
|
||||
if user_id:
|
||||
url = '/os-quota-sets/%s?user_id=%s' % (tenant_id, user_id)
|
||||
url = '%(resource_path)s/%(tenant_id)s?user_id=%(user_id)s' % data
|
||||
else:
|
||||
url = '/os-quota-sets/%s' % tenant_id
|
||||
url = '%(resource_path)s/%(tenant_id)s' % data
|
||||
self._delete(url)
|
||||
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def delete(self, tenant_id, user_id=None):
|
||||
return self._do_delete(
|
||||
tenant_id, user_id, resource_path=RESOURCE_PATH_LEGACY)
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def delete(self, tenant_id, user_id=None):
|
||||
return self._do_delete(tenant_id, user_id, resource_path=RESOURCE_PATH)
|
||||
|
@ -19,11 +19,13 @@ try:
|
||||
except ImportError:
|
||||
from urllib.parse import urlencode # noqa
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import base
|
||||
from manilaclient.openstack.common.apiclient import base as common_base
|
||||
|
||||
RESOURCES_PATH = '/os-services'
|
||||
RESOURCES_NAME = 'services'
|
||||
RESOURCE_PATH_LEGACY = '/os-services'
|
||||
RESOURCE_PATH = '/services'
|
||||
RESOURCE_NAME = 'services'
|
||||
|
||||
|
||||
class Service(common_base.Resource):
|
||||
@ -40,7 +42,7 @@ class ServiceManager(base.Manager):
|
||||
"""Manage :class:`Service` resources."""
|
||||
resource_class = Service
|
||||
|
||||
def list(self, search_opts=None):
|
||||
def _do_list(self, search_opts=None, resource_path=RESOURCE_PATH):
|
||||
"""Get a list of all services.
|
||||
|
||||
:rtype: list of :class:`Service`
|
||||
@ -51,17 +53,43 @@ class ServiceManager(base.Manager):
|
||||
sorted([(k, v) for (k, v) in six.iteritems(search_opts) if v]))
|
||||
if query_string:
|
||||
query_string = "?%s" % query_string
|
||||
return self._list(RESOURCES_PATH + query_string, RESOURCES_NAME)
|
||||
return self._list(resource_path + query_string, RESOURCE_NAME)
|
||||
|
||||
def enable(self, host, binary):
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def list(self, search_opts=None):
|
||||
return self._do_list(
|
||||
search_opts=search_opts, resource_path=RESOURCE_PATH_LEGACY)
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def list(self, search_opts=None):
|
||||
return self._do_list(
|
||||
search_opts=search_opts, resource_path=RESOURCE_PATH)
|
||||
|
||||
def _do_enable(self, host, binary, resource_path=RESOURCE_PATH):
|
||||
"""Enable the service specified by hostname and binary."""
|
||||
body = {"host": host, "binary": binary}
|
||||
return self._update("/os-services/enable", body)
|
||||
return self._update("%s/enable" % resource_path, body)
|
||||
|
||||
def disable(self, host, binary):
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def enable(self, host, binary):
|
||||
return self._do_enable(host, binary, RESOURCE_PATH_LEGACY)
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def enable(self, host, binary):
|
||||
return self._do_enable(host, binary, RESOURCE_PATH)
|
||||
|
||||
def _do_disable(self, host, binary, resource_path=RESOURCE_PATH):
|
||||
"""Disable the service specified by hostname and binary."""
|
||||
body = {"host": host, "binary": binary}
|
||||
return self._update("/os-services/disable", body)
|
||||
return self._update("%s/disable" % resource_path, body)
|
||||
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def disable(self, host, binary):
|
||||
return self._do_disable(host, binary, RESOURCE_PATH_LEGACY)
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def disable(self, host, binary):
|
||||
return self._do_disable(host, binary, RESOURCE_PATH)
|
||||
|
||||
def server_api_version(self, url_append=""):
|
||||
"""Returns the API Version supported by the server.
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import base
|
||||
from manilaclient.openstack.common.apiclient import base as common_base
|
||||
|
||||
@ -35,6 +36,7 @@ class ShareInstanceManager(base.ManagerWithFind):
|
||||
"""Manage :class:`ShareInstances` resources."""
|
||||
resource_class = ShareInstance
|
||||
|
||||
@api_versions.wraps("2.3")
|
||||
def get(self, instance):
|
||||
"""Get a share instance.
|
||||
|
||||
@ -44,6 +46,7 @@ class ShareInstanceManager(base.ManagerWithFind):
|
||||
share_id = common_base.getid(instance)
|
||||
return self._get("/share_instances/%s" % share_id, "share_instance")
|
||||
|
||||
@api_versions.wraps("2.3")
|
||||
def list(self):
|
||||
"""List all share instances."""
|
||||
return self._list('/share_instances', 'share_instances')
|
||||
@ -61,17 +64,33 @@ class ShareInstanceManager(base.ManagerWithFind):
|
||||
url = '/share_instances/%s/action' % common_base.getid(instance)
|
||||
return self.api.client.post(url, body=body)
|
||||
|
||||
def force_delete(self, instance):
|
||||
def _do_force_delete(self, instance, action_name="force_delete"):
|
||||
"""Delete a share instance forcibly - share status will be avoided.
|
||||
|
||||
:param instance: either share instance object or text with its ID.
|
||||
"""
|
||||
return self._action('os-force_delete', common_base.getid(instance))
|
||||
return self._action(action_name, common_base.getid(instance))
|
||||
|
||||
def reset_state(self, instance, state):
|
||||
@api_versions.wraps("2.3", "2.6")
|
||||
def force_delete(self, instance):
|
||||
return self._do_force_delete(instance, "os-force_delete")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def force_delete(self, instance):
|
||||
return self._do_force_delete(instance, "force_delete")
|
||||
|
||||
def _do_reset_state(self, instance, state, action_name):
|
||||
"""Update the provided share instance with the provided state.
|
||||
|
||||
:param instance: either share object or text with its ID.
|
||||
:param state: text with new state to set for share.
|
||||
"""
|
||||
return self._action('os-reset_status', instance, {'status': state})
|
||||
return self._action(action_name, instance, {"status": state})
|
||||
|
||||
@api_versions.wraps("2.3", "2.6")
|
||||
def reset_state(self, instance, state):
|
||||
return self._do_reset_state(instance, state, "os-reset_status")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def reset_state(self, instance, state):
|
||||
return self._do_reset_state(instance, state, "reset_status")
|
||||
|
@ -19,6 +19,7 @@ try:
|
||||
except ImportError:
|
||||
from urllib.parse import urlencode # noqa
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import base
|
||||
from manilaclient.common import constants
|
||||
from manilaclient.openstack.common.apiclient import base as common_base
|
||||
@ -127,9 +128,17 @@ class ShareSnapshotManager(base.ManagerWithFind):
|
||||
"""
|
||||
self._delete("/snapshots/%s" % common_base.getid(snapshot))
|
||||
|
||||
def force_delete(self, snapshot):
|
||||
def _do_force_delete(self, snapshot, action_name="force_delete"):
|
||||
"""Delete the specified snapshot ignoring its current state."""
|
||||
return self._action('os-force_delete', common_base.getid(snapshot))
|
||||
return self._action(action_name, common_base.getid(snapshot))
|
||||
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def force_delete(self, snapshot):
|
||||
return self._do_force_delete(snapshot, "os-force_delete")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def force_delete(self, snapshot):
|
||||
return self._do_force_delete(snapshot, "force_delete")
|
||||
|
||||
def update(self, snapshot, **kwargs):
|
||||
"""Update a snapshot.
|
||||
@ -145,9 +154,17 @@ class ShareSnapshotManager(base.ManagerWithFind):
|
||||
snapshot_id = common_base.getid(snapshot)
|
||||
return self._update("/snapshots/%s" % snapshot_id, body)
|
||||
|
||||
def reset_state(self, snapshot, state):
|
||||
def _do_reset_state(self, snapshot, state, action_name="reset_status"):
|
||||
"""Update the specified share snapshot with the provided state."""
|
||||
return self._action('os-reset_status', snapshot, {'status': state})
|
||||
return self._action(action_name, snapshot, {"status": state})
|
||||
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def reset_state(self, snapshot, state):
|
||||
return self._do_reset_state(snapshot, state, "os-reset_status")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def reset_state(self, snapshot, state):
|
||||
return self._do_reset_state(snapshot, state, "reset_status")
|
||||
|
||||
def _action(self, action, snapshot, info=None, **kwargs):
|
||||
"""Perform a snapshot 'action'."""
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
"""Share type access interface."""
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import base
|
||||
from manilaclient.openstack.common.apiclient import base as common_base
|
||||
|
||||
@ -28,13 +29,23 @@ class ShareTypeAccessManager(base.ManagerWithFind):
|
||||
|
||||
resource_class = ShareTypeAccess
|
||||
|
||||
def list(self, share_type):
|
||||
def _do_list(self, share_type, action_name="share_type_access"):
|
||||
if share_type.is_public:
|
||||
return None
|
||||
|
||||
return self._list(
|
||||
'/types/%s/os-share-type-access' % common_base.getid(share_type),
|
||||
'share_type_access')
|
||||
"/types/%(st_id)s/%(action_name)s" % {
|
||||
"st_id": common_base.getid(share_type),
|
||||
"action_name": action_name},
|
||||
"share_type_access")
|
||||
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def list(self, share_type):
|
||||
return self._do_list(share_type, "os-share-type-access")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def list(self, share_type):
|
||||
return self._do_list(share_type, "share_type_access")
|
||||
|
||||
def add_project_access(self, share_type, project):
|
||||
"""Add a project to the given share type access list."""
|
||||
|
@ -18,6 +18,7 @@
|
||||
Share Type interface.
|
||||
"""
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import base
|
||||
from manilaclient.openstack.common.apiclient import base as common_base
|
||||
|
||||
@ -38,8 +39,10 @@ class ShareType(common_base.Resource):
|
||||
|
||||
@property
|
||||
def is_public(self):
|
||||
"""Provide a user-friendly accessor to os-share-type-access."""
|
||||
return self._info.get("os-share-type-access:is_public", 'N/A')
|
||||
"""Provide a user-friendly accessor to [os-]share-type-access."""
|
||||
return self._info.get(
|
||||
"share_type_access:is_public",
|
||||
self._info.get("os-share-type-access:is_public", "N/A"))
|
||||
|
||||
def get_keys(self, prefer_resource_data=True):
|
||||
"""Get extra specs from a share type.
|
||||
@ -130,8 +133,9 @@ class ShareTypeManager(base.ManagerWithFind):
|
||||
"""
|
||||
self._delete("/types/%s" % common_base.getid(share_type))
|
||||
|
||||
def create(self, name, spec_driver_handles_share_servers,
|
||||
spec_snapshot_support=True, is_public=True):
|
||||
def _do_create(self, name, spec_driver_handles_share_servers,
|
||||
spec_snapshot_support=True, is_public=True,
|
||||
is_public_keyname="os-share-type-access:is_public"):
|
||||
"""Create a share type.
|
||||
|
||||
:param name: Descriptive name of the share type
|
||||
@ -141,7 +145,7 @@ class ShareTypeManager(base.ManagerWithFind):
|
||||
body = {
|
||||
"share_type": {
|
||||
"name": name,
|
||||
"os-share-type-access:is_public": is_public,
|
||||
is_public_keyname: is_public,
|
||||
"extra_specs": {
|
||||
"driver_handles_share_servers":
|
||||
spec_driver_handles_share_servers,
|
||||
@ -151,3 +155,23 @@ class ShareTypeManager(base.ManagerWithFind):
|
||||
}
|
||||
|
||||
return self._create("/types", body, "share_type")
|
||||
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def create(self, name, spec_driver_handles_share_servers,
|
||||
spec_snapshot_support=True, is_public=True):
|
||||
return self._do_create(
|
||||
name,
|
||||
spec_driver_handles_share_servers,
|
||||
spec_snapshot_support,
|
||||
is_public,
|
||||
"os-share-type-access:is_public")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def create(self, name, spec_driver_handles_share_servers,
|
||||
spec_snapshot_support=True, is_public=True):
|
||||
return self._do_create(
|
||||
name,
|
||||
spec_driver_handles_share_servers,
|
||||
spec_snapshot_support,
|
||||
is_public,
|
||||
"share_type_access:is_public")
|
||||
|
@ -21,6 +21,7 @@ try:
|
||||
except ImportError:
|
||||
from urllib.parse import urlencode # noqa
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import base
|
||||
from manilaclient.common import constants
|
||||
from manilaclient import exceptions
|
||||
@ -185,7 +186,7 @@ class ShareManager(base.ManagerWithFind):
|
||||
}
|
||||
return self._create('/shares', {'share': body}, 'share')
|
||||
|
||||
def migrate_share(self, share, host, force_host_copy):
|
||||
def _do_migrate_share(self, share, host, force_host_copy, action_name):
|
||||
"""Migrate share to new host and pool.
|
||||
|
||||
:param share: The :class:'share' to migrate
|
||||
@ -193,13 +194,24 @@ class ShareManager(base.ManagerWithFind):
|
||||
:param force_host_copy: Skip driver optimizations
|
||||
"""
|
||||
|
||||
return self._action('os-migrate_share',
|
||||
share, {'host': host,
|
||||
'force_host_copy': force_host_copy})
|
||||
return self._action(
|
||||
action_name, share,
|
||||
{"host": host, "force_host_copy": force_host_copy})
|
||||
|
||||
def manage(self, service_host, protocol, export_path,
|
||||
driver_options=None, share_type=None,
|
||||
name=None, description=None):
|
||||
@api_versions.wraps("2.5", "2.6")
|
||||
def migrate_share(self, share, host, force_host_copy):
|
||||
return self._do_migrate_share(
|
||||
share, host, force_host_copy, "os-migrate_share")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def migrate_share(self, share, host, force_host_copy):
|
||||
return self._do_migrate_share(
|
||||
share, host, force_host_copy, "migrate_share")
|
||||
|
||||
def _do_manage(self, service_host, protocol, export_path,
|
||||
driver_options=None, share_type=None,
|
||||
name=None, description=None,
|
||||
resource_path="/shares/manage"):
|
||||
"""Manage some existing share.
|
||||
|
||||
:param service_host: text - host of share service where share is runing
|
||||
@ -220,8 +232,23 @@ class ShareManager(base.ManagerWithFind):
|
||||
'name': name,
|
||||
'description': description
|
||||
}
|
||||
return self._create('/os-share-manage', {'share': body}, 'share')
|
||||
return self._create(resource_path, {'share': body}, 'share')
|
||||
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def manage(self, service_host, protocol, export_path, driver_options=None,
|
||||
share_type=None, name=None, description=None):
|
||||
return self._do_manage(
|
||||
service_host, protocol, export_path, driver_options, share_type,
|
||||
name, description, "/os-share-manage")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def manage(self, service_host, protocol, export_path, driver_options=None,
|
||||
share_type=None, name=None, description=None):
|
||||
return self._do_manage(
|
||||
service_host, protocol, export_path, driver_options, share_type,
|
||||
name, description, "/shares/manage")
|
||||
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def unmanage(self, share):
|
||||
"""Unmanage a share.
|
||||
|
||||
@ -230,6 +257,14 @@ class ShareManager(base.ManagerWithFind):
|
||||
return self.api.client.post(
|
||||
"/os-share-unmanage/%s/unmanage" % common_base.getid(share))
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def unmanage(self, share):
|
||||
"""Unmanage a share.
|
||||
|
||||
:param share: either share object or text with its ID.
|
||||
"""
|
||||
return self._action("unmanage", share)
|
||||
|
||||
def get(self, share):
|
||||
"""Get a share.
|
||||
|
||||
@ -334,14 +369,22 @@ class ShareManager(base.ManagerWithFind):
|
||||
url += "?consistency_group_id=%s" % consistency_group_id
|
||||
self._delete(url)
|
||||
|
||||
def force_delete(self, share):
|
||||
def _do_force_delete(self, share, action_name):
|
||||
"""Delete a share forcibly - share status will be avoided.
|
||||
|
||||
:param share: either share object or text with its ID.
|
||||
"""
|
||||
return self._action('os-force_delete', common_base.getid(share))
|
||||
return self._action(action_name, share)
|
||||
|
||||
def allow(self, share, access_type, access, access_level):
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def force_delete(self, share):
|
||||
return self._do_force_delete(share, "os-force_delete")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def force_delete(self, share):
|
||||
return self._do_force_delete(share, "force_delete")
|
||||
|
||||
def _do_allow(self, share, access_type, access, access_level, action_name):
|
||||
"""Allow access to a share.
|
||||
|
||||
:param share: either share object or text with its ID.
|
||||
@ -355,31 +398,57 @@ class ShareManager(base.ManagerWithFind):
|
||||
}
|
||||
if access_level:
|
||||
access_params['access_level'] = access_level
|
||||
access = self._action('os-allow_access', share,
|
||||
access = self._action(action_name, share,
|
||||
access_params)[1]["access"]
|
||||
|
||||
return access
|
||||
|
||||
def deny(self, share, access_id):
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def allow(self, share, access_type, access, access_level):
|
||||
return self._do_allow(
|
||||
share, access_type, access, access_level, "os-allow_access")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def allow(self, share, access_type, access, access_level):
|
||||
return self._do_allow(
|
||||
share, access_type, access, access_level, "allow_access")
|
||||
|
||||
def _do_deny(self, share, access_id, action_name):
|
||||
"""Deny access to a share.
|
||||
|
||||
:param share: either share object or text with its ID.
|
||||
:param access_id: ID of share access rule
|
||||
"""
|
||||
return self._action('os-deny_access', share, {'access_id': access_id})
|
||||
return self._action(action_name, share, {"access_id": access_id})
|
||||
|
||||
def access_list(self, share):
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def deny(self, share, access_id):
|
||||
return self._do_deny(share, access_id, "os-deny_access")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def deny(self, share, access_id):
|
||||
return self._do_deny(share, access_id, "deny_access")
|
||||
|
||||
def _do_access_list(self, share, action_name):
|
||||
"""Get access list to a share.
|
||||
|
||||
:param share: either share object or text with its ID.
|
||||
"""
|
||||
access_list = self._action("os-access_list", share)[1]["access_list"]
|
||||
access_list = self._action(action_name, share)[1]["access_list"]
|
||||
if access_list:
|
||||
t = collections.namedtuple('Access', list(access_list[0]))
|
||||
return [t(*value.values()) for value in access_list]
|
||||
else:
|
||||
return []
|
||||
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def access_list(self, share):
|
||||
return self._do_access_list(share, "os-access_list")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def access_list(self, share):
|
||||
return self._do_access_list(share, "access_list")
|
||||
|
||||
def get_metadata(self, share):
|
||||
"""Get metadata of a share.
|
||||
|
||||
@ -432,29 +501,53 @@ class ShareManager(base.ManagerWithFind):
|
||||
url = '/shares/%s/action' % common_base.getid(share)
|
||||
return self.api.client.post(url, body=body)
|
||||
|
||||
def reset_state(self, share, state):
|
||||
def _do_reset_state(self, share, state, action_name):
|
||||
"""Update the provided share with the provided state.
|
||||
|
||||
:param share: either share object or text with its ID.
|
||||
:param state: text with new state to set for share.
|
||||
"""
|
||||
return self._action('os-reset_status', share, {'status': state})
|
||||
return self._action(action_name, share, {"status": state})
|
||||
|
||||
def extend(self, share, new_size):
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def reset_state(self, share, state):
|
||||
return self._do_reset_state(share, state, "os-reset_status")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def reset_state(self, share, state):
|
||||
return self._do_reset_state(share, state, "reset_status")
|
||||
|
||||
def _do_extend(self, share, new_size, action_name):
|
||||
"""Extend the size of the specified share.
|
||||
|
||||
:param share: either share object or text with its ID.
|
||||
:param new_size: The desired size to extend share to.
|
||||
"""
|
||||
return self._action('os-extend', share, {'new_size': new_size})
|
||||
return self._action(action_name, share, {"new_size": new_size})
|
||||
|
||||
def shrink(self, share, new_size):
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def extend(self, share, new_size):
|
||||
return self._do_extend(share, new_size, "os-extend")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def extend(self, share, new_size):
|
||||
return self._do_extend(share, new_size, "extend")
|
||||
|
||||
def _do_shrink(self, share, new_size, action_name):
|
||||
"""Shrink the size of the specified share.
|
||||
|
||||
:param share: either share object or text with its ID.
|
||||
:param new_size: The desired size to shrink share to.
|
||||
"""
|
||||
return self._action('os-shrink', share, {'new_size': new_size})
|
||||
return self._action(action_name, share, {'new_size': new_size})
|
||||
|
||||
@api_versions.wraps("1.0", "2.6")
|
||||
def shrink(self, share, new_size):
|
||||
return self._do_shrink(share, new_size, "os-shrink")
|
||||
|
||||
@api_versions.wraps("2.7") # noqa
|
||||
def shrink(self, share, new_size):
|
||||
return self._do_shrink(share, new_size, "shrink")
|
||||
|
||||
def list_instances(self, share):
|
||||
"""List instances of the specified share.
|
||||
|
Loading…
x
Reference in New Issue
Block a user