Advertise v2 API routes without project_id
Manila APIs have had the requirement to include project_id in the URLs since the very beginning. This comes from an old assumption that our APIs would be differentiated per-tenant on the cloud, and we would allow different kinds of API endpoints (public, admin, internal, etc). While it is possible to set up different endpoints against the API service, the same and complete API is exposed at each of these endpoints. We don't _need_ the project_id information that we receive in the URL for any of our APIs to function. We rather authorize tenants by gathering information from the Identity service (Keystone) and wrapping that into a RequestContext object that we then rely on to ensure namespace isolation. Removing the requirement for "project_id" simplifies our API endpoint structure in the service catalog as well as provides a way for system scoped users to interact with manila without having to declare their project. In order to make project_id optional in urls, the possible values of project_id have to be constrained. This change introduces a new configuration option so deployers may control that. This configuration option defaults to accepting UUIDs with and without dashes. Since manila can be used in standalone deployments without the need for Keystone, this change introduces a noauth middleware that can work without project_id in the URL paths. The API version has been incremented to signal this change to end users. When 2.60 is available, deployments may drop "project_id" in the service catalog endpoint for Manila and end users applications can stop needing it as well (if they don't already rely on the service catalog for this data). APIImpact Implements: bp remove-project-id-from-urls Change-Id: I5127e150e8a71e621890f30dba6720b3932cf583 Signed-off-by: Goutham Pacha Ravi <gouthampravi@gmail.com>
This commit is contained in:
parent
f855abd374
commit
263d5438f0
@ -17,6 +17,7 @@ keystone_nolimit = cors faultwrap http_proxy_to_wsgi sizelimit authtoken keyston
|
||||
[composite:openstack_share_api_v2]
|
||||
use = call:manila.api.middleware.auth:pipeline_factory
|
||||
noauth = cors faultwrap http_proxy_to_wsgi sizelimit noauth apiv2
|
||||
noauthv2 = cors faultwrap http_proxy_to_wsgi sizelimit noauthv2 apiv2
|
||||
keystone = cors faultwrap http_proxy_to_wsgi sizelimit authtoken keystonecontext apiv2
|
||||
keystone_nolimit = cors faultwrap http_proxy_to_wsgi sizelimit authtoken keystonecontext apiv2
|
||||
|
||||
@ -26,6 +27,9 @@ paste.filter_factory = manila.api.middleware.fault:FaultWrapper.factory
|
||||
[filter:noauth]
|
||||
paste.filter_factory = manila.api.middleware.auth:NoAuthMiddleware.factory
|
||||
|
||||
[filter:noauthv2]
|
||||
paste.filter_factory = manila.api.middleware.auth:NoAuthMiddlewarev2_60.factory
|
||||
|
||||
[filter:sizelimit]
|
||||
paste.filter_factory = oslo_middleware.sizelimit:RequestBodySizeLimiter.factory
|
||||
|
||||
|
@ -260,6 +260,17 @@ class ViewBuilder(object):
|
||||
_collection_name = None
|
||||
_detail_version_modifiers = []
|
||||
|
||||
def _get_project_id(self, request):
|
||||
project_id = request.environ["manila.context"].project_id
|
||||
if '/v1/' in request.url:
|
||||
# project_ids are mandatory in v1 URLs
|
||||
return project_id
|
||||
elif project_id and ("/v2/%s" % project_id in request.url):
|
||||
# project_ids are not mandatory within v2 URLs, but links need
|
||||
# to include them if the request does.
|
||||
return project_id
|
||||
return ''
|
||||
|
||||
def _get_links(self, request, identifier):
|
||||
return [{"rel": "self",
|
||||
"href": self._get_href_link(request, identifier), },
|
||||
@ -273,7 +284,7 @@ class ViewBuilder(object):
|
||||
prefix = self._update_link_prefix(request.application_url,
|
||||
CONF.osapi_share_base_URL)
|
||||
url = os.path.join(prefix,
|
||||
request.environ["manila.context"].project_id,
|
||||
self._get_project_id(request),
|
||||
self._collection_name)
|
||||
return "%s?%s" % (url, dict_to_query_str(params))
|
||||
|
||||
@ -282,7 +293,7 @@ class ViewBuilder(object):
|
||||
prefix = self._update_link_prefix(request.application_url,
|
||||
CONF.osapi_share_base_URL)
|
||||
return os.path.join(prefix,
|
||||
request.environ["manila.context"].project_id,
|
||||
self._get_project_id(request),
|
||||
self._collection_name,
|
||||
str(identifier))
|
||||
|
||||
@ -292,7 +303,7 @@ class ViewBuilder(object):
|
||||
base_url = self._update_link_prefix(base_url,
|
||||
CONF.osapi_share_base_URL)
|
||||
return os.path.join(base_url,
|
||||
request.environ["manila.context"].project_id,
|
||||
self._get_project_id(request),
|
||||
self._collection_name,
|
||||
str(identifier))
|
||||
|
||||
|
@ -116,15 +116,17 @@ class ManilaKeystoneContext(base_wsgi.Middleware):
|
||||
return self.application
|
||||
|
||||
|
||||
class NoAuthMiddleware(base_wsgi.Middleware):
|
||||
class NoAuthMiddlewareBase(base_wsgi.Middleware):
|
||||
"""Return a fake token if one isn't specified."""
|
||||
|
||||
@webob.dec.wsgify(RequestClass=wsgi.Request)
|
||||
def __call__(self, req):
|
||||
def base_call(self, req, project_id_in_path=False):
|
||||
if 'X-Auth-Token' not in req.headers:
|
||||
user_id = req.headers.get('X-Auth-User', 'admin')
|
||||
project_id = req.headers.get('X-Auth-Project-Id', 'admin')
|
||||
os_url = os.path.join(req.url, project_id)
|
||||
if project_id_in_path:
|
||||
os_url = os.path.join(req.url.rstrip('/'), project_id)
|
||||
else:
|
||||
os_url = req.url.rstrip('/')
|
||||
res = webob.Response()
|
||||
# NOTE(vish): This is expecting and returning Auth(1.1), whereas
|
||||
# keystone uses 2.0 auth. We should probably allow
|
||||
@ -148,3 +150,24 @@ class NoAuthMiddleware(base_wsgi.Middleware):
|
||||
|
||||
req.environ['manila.context'] = ctx
|
||||
return self.application
|
||||
|
||||
|
||||
class NoAuthMiddleware(NoAuthMiddlewareBase):
|
||||
"""Return a fake token if one isn't specified.
|
||||
|
||||
Sets project_id in URLs.
|
||||
"""
|
||||
|
||||
@webob.dec.wsgify(RequestClass=wsgi.Request)
|
||||
def __call__(self, req):
|
||||
return self.base_call(req, project_id_in_path=True)
|
||||
|
||||
|
||||
class NoAuthMiddlewarev2_60(NoAuthMiddlewareBase):
|
||||
"""Return a fake token if one isn't specified.
|
||||
|
||||
Does not set project_id in URLs.
|
||||
"""
|
||||
@webob.dec.wsgify(RequestClass=wsgi.Request)
|
||||
def __call__(self, req):
|
||||
return self.base_call(req)
|
||||
|
@ -18,6 +18,7 @@
|
||||
WSGI middleware for OpenStack API controllers.
|
||||
"""
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
from oslo_service import wsgi as base_wsgi
|
||||
import routes
|
||||
@ -25,6 +26,16 @@ import routes
|
||||
from manila.api.openstack import wsgi
|
||||
from manila.i18n import _
|
||||
|
||||
openstack_api_opts = [
|
||||
cfg.StrOpt('project_id_regex',
|
||||
default=r"[0-9a-f\-]+",
|
||||
help=r'The validation regex for project_ids used in urls. '
|
||||
r'This defaults to [0-9a-f\\-]+ if not set, '
|
||||
r'which matches normal uuids created by keystone.'),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(openstack_api_opts)
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
@ -47,13 +58,42 @@ class APIMapper(routes.Mapper):
|
||||
|
||||
class ProjectMapper(APIMapper):
|
||||
def resource(self, member_name, collection_name, **kwargs):
|
||||
"""Base resource path handler
|
||||
|
||||
This method is compatible with resource paths that include a
|
||||
project_id and those that don't. Including project_id in the URLs
|
||||
was a legacy API requirement; and making API requests against
|
||||
such endpoints won't work for users that don't belong to a
|
||||
particular project.
|
||||
"""
|
||||
# NOTE(gouthamr): project_id parameter is only valid if its hex
|
||||
# or hex + dashes (note, integers are a subset of this). This
|
||||
# is required to handle our overlapping routes issues.
|
||||
project_id_regex = CONF.project_id_regex
|
||||
project_id_token = '{project_id:%s}' % project_id_regex
|
||||
if 'parent_resource' not in kwargs:
|
||||
kwargs['path_prefix'] = '{project_id}/'
|
||||
kwargs['path_prefix'] = '%s/' % project_id_token
|
||||
else:
|
||||
parent_resource = kwargs['parent_resource']
|
||||
p_collection = parent_resource['collection_name']
|
||||
p_member = parent_resource['member_name']
|
||||
kwargs['path_prefix'] = '{project_id}/%s/:%s_id' % (p_collection,
|
||||
kwargs['path_prefix'] = '%s/%s/:%s_id' % (project_id_token,
|
||||
p_collection,
|
||||
p_member)
|
||||
routes.Mapper.resource(self,
|
||||
member_name,
|
||||
collection_name,
|
||||
**kwargs)
|
||||
|
||||
# NOTE(gouthamr): while we are in transition mode to not needing
|
||||
# project_ids in URLs, we'll need additional routes without project_id.
|
||||
if 'parent_resource' not in kwargs:
|
||||
del kwargs['path_prefix']
|
||||
else:
|
||||
parent_resource = kwargs['parent_resource']
|
||||
p_collection = parent_resource['collection_name']
|
||||
p_member = parent_resource['member_name']
|
||||
kwargs['path_prefix'] = '%s/:%s_id' % (p_collection,
|
||||
p_member)
|
||||
routes.Mapper.resource(self,
|
||||
member_name,
|
||||
|
@ -159,13 +159,14 @@ REST_API_VERSION_HISTORY = """
|
||||
* 2.58 - Added 'share_groups' and 'share_group_snapshots' to the limits
|
||||
view.
|
||||
* 2.59 - Add driver ``details`` field to migration get progress.
|
||||
* 2.60 - API URLs no longer need to include a project_id parameter.
|
||||
"""
|
||||
|
||||
# The minimum and maximum versions of the API supported
|
||||
# The default api version request is defined to be the
|
||||
# minimum version of the API supported.
|
||||
_MIN_API_VERSION = "2.0"
|
||||
_MAX_API_VERSION = "2.59"
|
||||
_MAX_API_VERSION = "2.60"
|
||||
DEFAULT_API_VERSION = _MIN_API_VERSION
|
||||
|
||||
|
||||
|
@ -323,3 +323,11 @@ user documentation.
|
||||
----
|
||||
Added 'details' field to migration get progress api, which optionally may hold
|
||||
additional driver data related to the progress of share migration.
|
||||
|
||||
2.60
|
||||
----
|
||||
API URLs no longer need a "project_id" argument in them. For example, the
|
||||
API route: https://$(controller)s/share/v2/$(project_id)s/shares is
|
||||
equivalent to https://$(controller)s/share/v2/shares. When interacting
|
||||
with the manila service as system or domain scoped users, project_id should
|
||||
not be specified in the API path.
|
||||
|
@ -155,8 +155,10 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
collection={"detail": "GET"},
|
||||
member={"action": "POST"})
|
||||
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
mapper.connect("shares",
|
||||
"/{project_id}/shares/manage",
|
||||
"%s/shares/manage" % path_prefix,
|
||||
controller=self.resources["shares"],
|
||||
action="manage",
|
||||
conditions={"method": ["POST"]})
|
||||
@ -169,23 +171,28 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
|
||||
self.resources["share_instance_export_locations"] = (
|
||||
share_instance_export_locations.create_resource())
|
||||
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
mapper.connect("share_instances",
|
||||
("/{project_id}/share_instances/{share_instance_id}/"
|
||||
"export_locations"),
|
||||
("%s/share_instances/{share_instance_id}"
|
||||
"/export_locations" % path_prefix),
|
||||
controller=self.resources[
|
||||
"share_instance_export_locations"],
|
||||
action="index",
|
||||
conditions={"method": ["GET"]})
|
||||
|
||||
mapper.connect("share_instances",
|
||||
("/{project_id}/share_instances/{share_instance_id}/"
|
||||
"export_locations/{export_location_uuid}"),
|
||||
("%s/share_instances/{share_instance_id}"
|
||||
"/export_locations"
|
||||
"/{export_location_uuid}" % path_prefix),
|
||||
controller=self.resources[
|
||||
"share_instance_export_locations"],
|
||||
action="show",
|
||||
conditions={"method": ["GET"]})
|
||||
|
||||
mapper.connect("share_instance",
|
||||
"/{project_id}/shares/{share_id}/instances",
|
||||
"%s/shares/{share_id}/instances" % path_prefix,
|
||||
controller=self.resources["share_instances"],
|
||||
action="get_share_instances",
|
||||
conditions={"method": ["GET"]})
|
||||
@ -193,13 +200,14 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
self.resources["share_export_locations"] = (
|
||||
share_export_locations.create_resource())
|
||||
mapper.connect("shares",
|
||||
"/{project_id}/shares/{share_id}/export_locations",
|
||||
"%s/shares/{share_id}"
|
||||
"/export_locations" % path_prefix,
|
||||
controller=self.resources["share_export_locations"],
|
||||
action="index",
|
||||
conditions={"method": ["GET"]})
|
||||
mapper.connect("shares",
|
||||
("/{project_id}/shares/{share_id}/"
|
||||
"export_locations/{export_location_uuid}"),
|
||||
("%s/shares/{share_id}/export_locations"
|
||||
"/{export_location_uuid}" % path_prefix),
|
||||
controller=self.resources["share_export_locations"],
|
||||
action="show",
|
||||
conditions={"method": ["GET"]})
|
||||
@ -210,14 +218,17 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
collection={"detail": "GET"},
|
||||
member={"action": "POST"})
|
||||
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
mapper.connect("snapshots",
|
||||
"/{project_id}/snapshots/manage",
|
||||
"%s/snapshots/manage" % path_prefix,
|
||||
controller=self.resources["snapshots"],
|
||||
action="manage",
|
||||
conditions={"method": ["POST"]})
|
||||
|
||||
mapper.connect("snapshots",
|
||||
"/{project_id}/snapshots/{snapshot_id}/access-list",
|
||||
"%s/snapshots/{snapshot_id}"
|
||||
"/access-list" % path_prefix,
|
||||
controller=self.resources["snapshots"],
|
||||
action="access_list",
|
||||
conditions={"method": ["GET"]})
|
||||
@ -225,16 +236,16 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
self.resources["share_snapshot_export_locations"] = (
|
||||
share_snapshot_export_locations.create_resource())
|
||||
mapper.connect("snapshots",
|
||||
"/{project_id}/snapshots/{snapshot_id}/"
|
||||
"export-locations",
|
||||
"%s/snapshots/{snapshot_id}"
|
||||
"/export-locations" % path_prefix,
|
||||
controller=self.resources[
|
||||
"share_snapshot_export_locations"],
|
||||
action="index",
|
||||
conditions={"method": ["GET"]})
|
||||
|
||||
mapper.connect("snapshots",
|
||||
"/{project_id}/snapshots/{snapshot_id}/"
|
||||
"export-locations/{export_location_id}",
|
||||
"%s/snapshots/{snapshot_id}/export-locations"
|
||||
"/{export_location_id}" % path_prefix,
|
||||
controller=self.resources[
|
||||
"share_snapshot_export_locations"],
|
||||
action="show",
|
||||
@ -249,18 +260,21 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
|
||||
self.resources["share_snapshot_instance_export_locations"] = (
|
||||
share_snapshot_instance_export_locations.create_resource())
|
||||
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
mapper.connect("snapshot-instance",
|
||||
"/{project_id}/snapshot-instances/"
|
||||
"{snapshot_instance_id}/export-locations",
|
||||
"%s/snapshot-instances/{snapshot_instance_id}"
|
||||
"/export-locations" % path_prefix,
|
||||
controller=self.resources[
|
||||
"share_snapshot_instance_export_locations"],
|
||||
action="index",
|
||||
conditions={"method": ["GET"]})
|
||||
|
||||
mapper.connect("snapshot-instance",
|
||||
"/{project_id}/snapshot-instances/"
|
||||
"{snapshot_instance_id}/export-locations/"
|
||||
"{export_location_id}",
|
||||
"%s/snapshot-instances/{snapshot_instance_id}"
|
||||
"/export-locations"
|
||||
"/{export_location_id}" % path_prefix,
|
||||
controller=self.resources[
|
||||
"share_snapshot_instance_export_locations"],
|
||||
action="show",
|
||||
@ -274,8 +288,10 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
parent_resource=dict(member_name="share",
|
||||
collection_name="shares"))
|
||||
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
mapper.connect("metadata",
|
||||
"/{project_id}/shares/{share_id}/metadata",
|
||||
"%s/shares/{share_id}/metadata" % path_prefix,
|
||||
controller=share_metadata_controller,
|
||||
action="update_all",
|
||||
conditions={"method": ["PUT"]})
|
||||
@ -297,29 +313,31 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
collection={"detail": "GET"},
|
||||
member={"action": "POST"})
|
||||
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
self.resources["share_network_subnets"] = (
|
||||
share_network_subnets.create_resource())
|
||||
mapper.connect("share-networks",
|
||||
"/{project_id}/share-networks/{share_network_id}/"
|
||||
"subnets",
|
||||
"%s/share-networks/{share_network_id}"
|
||||
"/subnets" % path_prefix,
|
||||
controller=self.resources["share_network_subnets"],
|
||||
action="create",
|
||||
conditions={"method": ["POST"]})
|
||||
mapper.connect("share-networks",
|
||||
"/{project_id}/share-networks/{share_network_id}/"
|
||||
"subnets/{share_network_subnet_id}",
|
||||
"%s/share-networks/{share_network_id}"
|
||||
"/subnets/{share_network_subnet_id}" % path_prefix,
|
||||
controller=self.resources["share_network_subnets"],
|
||||
action="delete",
|
||||
conditions={"method": ["DELETE"]})
|
||||
mapper.connect("share-networks",
|
||||
"/{project_id}/share-networks/{share_network_id}/"
|
||||
"subnets/{share_network_subnet_id}",
|
||||
"%s/share-networks/{share_network_id}"
|
||||
"/subnets/{share_network_subnet_id}" % path_prefix,
|
||||
controller=self.resources["share_network_subnets"],
|
||||
action="show",
|
||||
conditions={"method": ["GET"]})
|
||||
mapper.connect("share-networks",
|
||||
"/{project_id}/share-networks/{share_network_id}/"
|
||||
"subnets",
|
||||
"%s/share-networks/{share_network_id}"
|
||||
"/subnets" % path_prefix,
|
||||
controller=self.resources["share_network_subnets"],
|
||||
action="index",
|
||||
conditions={"method": ["GET"]})
|
||||
@ -329,13 +347,16 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
"share-servers",
|
||||
controller=self.resources["share_servers"],
|
||||
member={"action": "POST"})
|
||||
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
mapper.connect("details",
|
||||
"/{project_id}/share-servers/{id}/details",
|
||||
"%s/share-servers/{id}/details" % path_prefix,
|
||||
controller=self.resources["share_servers"],
|
||||
action="details",
|
||||
conditions={"method": ["GET"]})
|
||||
mapper.connect("share_servers",
|
||||
"/{project_id}/share-servers/manage",
|
||||
"%s/share-servers/manage" % path_prefix,
|
||||
controller=self.resources["share_servers"],
|
||||
action="manage",
|
||||
conditions={"method": ["POST"]})
|
||||
@ -356,11 +377,15 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
collection_name="types"))
|
||||
|
||||
self.resources["scheduler_stats"] = scheduler_stats.create_resource()
|
||||
mapper.connect("pools", "/{project_id}/scheduler-stats/pools",
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
mapper.connect("pools",
|
||||
"%s/scheduler-stats/pools" % path_prefix,
|
||||
controller=self.resources["scheduler_stats"],
|
||||
action="pools_index",
|
||||
conditions={"method": ["GET"]})
|
||||
mapper.connect("pools", "/{project_id}/scheduler-stats/pools/detail",
|
||||
mapper.connect("pools",
|
||||
"%s/scheduler-stats/pools/detail" % path_prefix,
|
||||
controller=self.resources["scheduler_stats"],
|
||||
action="pools_detail",
|
||||
conditions={"method": ["GET"]})
|
||||
@ -371,9 +396,11 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
"share-groups",
|
||||
controller=self.resources["share-groups"],
|
||||
collection={"detail": "GET"})
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
mapper.connect(
|
||||
"share-groups",
|
||||
"/{project_id}/share-groups/{id}/action",
|
||||
"%s/share-groups/{id}/action" % path_prefix,
|
||||
controller=self.resources["share-groups"],
|
||||
action="action",
|
||||
conditions={"method": ["POST"]})
|
||||
@ -386,9 +413,11 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
controller=self.resources["share-group-types"],
|
||||
collection={"detail": "GET", "default": "GET"},
|
||||
member={"action": "POST"})
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
mapper.connect(
|
||||
"share-group-types",
|
||||
"/{project_id}/share-group-types/{id}/access",
|
||||
"%s/share-group-types/{id}/access" % path_prefix,
|
||||
controller=self.resources["share-group-types"],
|
||||
action="share_group_type_access",
|
||||
conditions={"method": ["GET"]})
|
||||
@ -397,33 +426,36 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
# issue is fixed: https://github.com/bbangert/routes/issues/68
|
||||
self.resources["group-specs"] = (
|
||||
share_group_type_specs.create_resource())
|
||||
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
mapper.connect(
|
||||
"share-group-types",
|
||||
"/{project_id}/share-group-types/{id}/group-specs",
|
||||
"%s/share-group-types/{id}/group-specs" % path_prefix,
|
||||
controller=self.resources["group-specs"],
|
||||
action="index",
|
||||
conditions={"method": ["GET"]})
|
||||
mapper.connect(
|
||||
"share-group-types",
|
||||
"/{project_id}/share-group-types/{id}/group-specs",
|
||||
"%s/share-group-types/{id}/group-specs" % path_prefix,
|
||||
controller=self.resources["group-specs"],
|
||||
action="create",
|
||||
conditions={"method": ["POST"]})
|
||||
mapper.connect(
|
||||
"share-group-types",
|
||||
"/{project_id}/share-group-types/{id}/group-specs/{key}",
|
||||
"%s/share-group-types/{id}/group-specs/{key}" % path_prefix,
|
||||
controller=self.resources["group-specs"],
|
||||
action="show",
|
||||
conditions={"method": ["GET"]})
|
||||
mapper.connect(
|
||||
"share-group-types",
|
||||
"/{project_id}/share-group-types/{id}/group-specs/{key}",
|
||||
"%s/share-group-types/{id}/group-specs/{key}" % path_prefix,
|
||||
controller=self.resources["group-specs"],
|
||||
action="delete",
|
||||
conditions={"method": ["DELETE"]})
|
||||
mapper.connect(
|
||||
"share-group-types",
|
||||
"/{project_id}/share-group-types/{id}/group-specs/{key}",
|
||||
"%s/share-group-types/{id}/group-specs/{key}" % path_prefix,
|
||||
controller=self.resources["group-specs"],
|
||||
action="update",
|
||||
conditions={"method": ["PUT"]})
|
||||
@ -436,9 +468,12 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
controller=self.resources["share-group-snapshots"],
|
||||
collection={"detail": "GET"},
|
||||
member={"members": "GET", "action": "POST"})
|
||||
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
mapper.connect(
|
||||
"share-group-snapshots",
|
||||
"/{project_id}/share-group-snapshots/{id}/action",
|
||||
"%s/share-group-snapshots/{id}/action" % path_prefix,
|
||||
controller=self.resources["share-group-snapshots"],
|
||||
action="action",
|
||||
conditions={"method": ["POST"]})
|
||||
@ -448,18 +483,22 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
controller=self.resources['share-replicas'],
|
||||
collection={'detail': 'GET'},
|
||||
member={'action': 'POST'})
|
||||
|
||||
self.resources["share-replica-export-locations"] = (
|
||||
share_replica_export_locations.create_resource())
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
mapper.connect("share-replicas",
|
||||
("/{project_id}/share-replicas/{share_replica_id}/"
|
||||
"export-locations"),
|
||||
("%s/share-replicas/{share_replica_id}"
|
||||
"/export-locations" % path_prefix),
|
||||
controller=self.resources[
|
||||
"share-replica-export-locations"],
|
||||
action="index",
|
||||
conditions={"method": ["GET"]})
|
||||
mapper.connect("share-replicas",
|
||||
("/{project_id}/share-replicas/{share_replica_id}/"
|
||||
"export-locations/{export_location_uuid}"),
|
||||
("%s/share-replicas/{share_replica_id}"
|
||||
"/export-locations"
|
||||
"/{export_location_uuid}" % path_prefix),
|
||||
controller=self.resources[
|
||||
"share-replica-export-locations"],
|
||||
action="show",
|
||||
@ -476,18 +515,21 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
controller=self.resources["share-access-rules"],
|
||||
collection={"detail": "GET"})
|
||||
|
||||
for path_prefix in ['/{project_id}', '']:
|
||||
# project_id is optional
|
||||
self.resources["access-metadata"] = (
|
||||
share_access_metadata.create_resource())
|
||||
access_metadata_controller = self.resources["access-metadata"]
|
||||
mapper.connect("share-access-rules",
|
||||
"/{project_id}/share-access-rules/{access_id}/metadata",
|
||||
"%s/share-access-rules"
|
||||
"/{access_id}/metadata" % path_prefix,
|
||||
controller=access_metadata_controller,
|
||||
action="update",
|
||||
conditions={"method": ["PUT"]})
|
||||
|
||||
mapper.connect("share-access-rules",
|
||||
"/{project_id}/share-access-rules/"
|
||||
"{access_id}/metadata/{key}",
|
||||
"%s/share-access-rules"
|
||||
"/{access_id}/metadata/{key}" % path_prefix,
|
||||
controller=access_metadata_controller,
|
||||
action="delete",
|
||||
conditions={"method": ["DELETE"]})
|
||||
|
@ -128,7 +128,7 @@ global_opts = [
|
||||
cfg.StrOpt('auth_strategy',
|
||||
default='keystone',
|
||||
help='The strategy to use for auth. Supports noauth, keystone, '
|
||||
'and deprecated.'),
|
||||
'and noauthv2.'),
|
||||
cfg.ListOpt('enabled_share_backends',
|
||||
help='A list of share backend names to use. These backend '
|
||||
'names should be backed by a unique [CONFIG] group '
|
||||
|
@ -86,7 +86,11 @@ class HTTPRequest(os_wsgi.Request):
|
||||
@classmethod
|
||||
def blank(cls, *args, **kwargs):
|
||||
if not kwargs.get('base_url'):
|
||||
kwargs['base_url'] = 'http://localhost/v1'
|
||||
method_url = args[0]
|
||||
if method_url.startswith('/v2'):
|
||||
kwargs['base_url'] = 'http://localhost/share/v2'
|
||||
else:
|
||||
kwargs['base_url'] = 'http://localhost/share/v1'
|
||||
use_admin_context = kwargs.pop('use_admin_context', False)
|
||||
version = kwargs.pop('version', api_version.DEFAULT_API_VERSION)
|
||||
experimental = kwargs.pop('experimental', False)
|
||||
|
@ -65,7 +65,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
}
|
||||
self.mock_object(share_api.API, 'get_snapshot',
|
||||
mock.Mock(return_value=return_snapshot))
|
||||
req = fakes.HTTPRequest.blank('/snapshots/200')
|
||||
req = fakes.HTTPRequest.blank('/fake/snapshots/200')
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.show,
|
||||
req, '200')
|
||||
@ -82,7 +82,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
'description': 'displaysnapdesc',
|
||||
}
|
||||
}
|
||||
req = fakes.HTTPRequest.blank('/snapshots')
|
||||
req = fakes.HTTPRequest.blank('/fake/snapshots')
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -105,7 +105,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
'description': 'fake_share_description',
|
||||
}
|
||||
}
|
||||
req = fakes.HTTPRequest.blank('/snapshots')
|
||||
req = fakes.HTTPRequest.blank('/fake/snapshots')
|
||||
|
||||
self.assertRaises(
|
||||
webob.exc.HTTPUnprocessableEntity,
|
||||
@ -115,7 +115,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
|
||||
def test_snapshot_create_no_body(self):
|
||||
body = {}
|
||||
req = fakes.HTTPRequest.blank('/snapshots')
|
||||
req = fakes.HTTPRequest.blank('/fake/snapshots')
|
||||
self.assertRaises(webob.exc.HTTPUnprocessableEntity,
|
||||
self.controller.create,
|
||||
req,
|
||||
@ -124,21 +124,21 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
def test_snapshot_delete(self):
|
||||
self.mock_object(share_api.API, 'delete_snapshot',
|
||||
stubs.stub_snapshot_delete)
|
||||
req = fakes.HTTPRequest.blank('/snapshots/200')
|
||||
req = fakes.HTTPRequest.blank('/fake/snapshots/200')
|
||||
resp = self.controller.delete(req, 200)
|
||||
self.assertEqual(202, resp.status_int)
|
||||
|
||||
def test_snapshot_delete_nofound(self):
|
||||
self.mock_object(share_api.API, 'get_snapshot',
|
||||
stubs.stub_snapshot_get_notfound)
|
||||
req = fakes.HTTPRequest.blank('/snapshots/200')
|
||||
req = fakes.HTTPRequest.blank('/fake/snapshots/200')
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.delete,
|
||||
req,
|
||||
200)
|
||||
|
||||
def test_snapshot_show(self):
|
||||
req = fakes.HTTPRequest.blank('/snapshots/200')
|
||||
req = fakes.HTTPRequest.blank('/fake/snapshots/200')
|
||||
res_dict = self.controller.show(req, 200)
|
||||
expected = fake_share.expected_snapshot(id=200)
|
||||
self.assertEqual(expected, res_dict)
|
||||
@ -146,7 +146,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
def test_snapshot_show_nofound(self):
|
||||
self.mock_object(share_api.API, 'get_snapshot',
|
||||
stubs.stub_snapshot_get_notfound)
|
||||
req = fakes.HTTPRequest.blank('/snapshots/200')
|
||||
req = fakes.HTTPRequest.blank('/fake/snapshots/200')
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.show,
|
||||
req, '200')
|
||||
@ -154,7 +154,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
def test_snapshot_list_summary(self):
|
||||
self.mock_object(share_api.API, 'get_all_snapshots',
|
||||
stubs.stub_snapshot_get_all_by_project)
|
||||
req = fakes.HTTPRequest.blank('/snapshots')
|
||||
req = fakes.HTTPRequest.blank('/fake/snapshots')
|
||||
res_dict = self.controller.index(req)
|
||||
expected = {
|
||||
'snapshots': [
|
||||
@ -163,12 +163,12 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
'id': 2,
|
||||
'links': [
|
||||
{
|
||||
'href': 'http://localhost/v1/fake/'
|
||||
'href': 'http://localhost/share/v1/fake/'
|
||||
'snapshots/2',
|
||||
'rel': 'self'
|
||||
},
|
||||
{
|
||||
'href': 'http://localhost/fake/snapshots/2',
|
||||
'href': 'http://localhost/share/fake/snapshots/2',
|
||||
'rel': 'bookmark'
|
||||
}
|
||||
],
|
||||
@ -180,7 +180,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
def _snapshot_list_summary_with_search_opts(self, use_admin_context):
|
||||
search_opts = fake_share.search_opts()
|
||||
# fake_key should be filtered for non-admin
|
||||
url = '/snapshots?fake_key=fake_value'
|
||||
url = '/fake/snapshots?fake_key=fake_value'
|
||||
for k, v in search_opts.items():
|
||||
url = url + '&' + k + '=' + v
|
||||
req = fakes.HTTPRequest.blank(url, use_admin_context=use_admin_context)
|
||||
@ -225,7 +225,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
def _snapshot_list_detail_with_search_opts(self, use_admin_context):
|
||||
search_opts = fake_share.search_opts()
|
||||
# fake_key should be filtered for non-admin
|
||||
url = '/shares/detail?fake_key=fake_value'
|
||||
url = '/fake/shares/detail?fake_key=fake_value'
|
||||
for k, v in search_opts.items():
|
||||
url = url + '&' + k + '=' + v
|
||||
req = fakes.HTTPRequest.blank(url, use_admin_context=use_admin_context)
|
||||
@ -289,7 +289,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
|
||||
def test_snapshot_list_detail(self):
|
||||
env = {'QUERY_STRING': 'name=Share+Test+Name'}
|
||||
req = fakes.HTTPRequest.blank('/shares/detail', environ=env)
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/detail', environ=env)
|
||||
res_dict = self.controller.detail(req)
|
||||
expected_s = fake_share.expected_snapshot(id=2)
|
||||
expected = {'snapshots': [expected_s['snapshot']]}
|
||||
@ -316,7 +316,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
]
|
||||
self.mock_object(share_api.API, 'get_all_snapshots',
|
||||
mock.Mock(return_value=snapshots))
|
||||
req = fakes.HTTPRequest.blank('/snapshots')
|
||||
req = fakes.HTTPRequest.blank('/fake/snapshots')
|
||||
result = self.controller.index(req)
|
||||
self.assertEqual(1, len(result['snapshots']))
|
||||
self.assertEqual(snapshots[0]['id'], result['snapshots'][0]['id'])
|
||||
@ -325,7 +325,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
snp = self.snp_example
|
||||
body = {"snapshot": snp}
|
||||
|
||||
req = fakes.HTTPRequest.blank('/snapshot/1')
|
||||
req = fakes.HTTPRequest.blank('/fake/snapshot/1')
|
||||
res_dict = self.controller.update(req, 1, body)
|
||||
self.assertEqual(snp["display_name"], res_dict['snapshot']["name"])
|
||||
|
||||
@ -333,7 +333,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
snp = self.snp_example
|
||||
body = {"snapshot": snp}
|
||||
|
||||
req = fakes.HTTPRequest.blank('/snapshot/1')
|
||||
req = fakes.HTTPRequest.blank('/fake/snapshot/1')
|
||||
res_dict = self.controller.update(req, 1, body)
|
||||
|
||||
self.assertEqual(snp["display_description"],
|
||||
@ -343,7 +343,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
snp = self.snp_example
|
||||
body = {"snapshot": snp}
|
||||
|
||||
req = fakes.HTTPRequest.blank('/snapshot/1')
|
||||
req = fakes.HTTPRequest.blank('/fake/snapshot/1')
|
||||
res_dict = self.controller.update(req, 1, body)
|
||||
|
||||
self.assertNotEqual(snp["size"], res_dict['snapshot']["size"])
|
||||
|
@ -117,11 +117,11 @@ class ShareAPITest(test.TestCase):
|
||||
'is_public': False,
|
||||
'links': [
|
||||
{
|
||||
'href': 'http://localhost/v1/fake/shares/1',
|
||||
'href': 'http://localhost/share/v1/fake/shares/1',
|
||||
'rel': 'self'
|
||||
},
|
||||
{
|
||||
'href': 'http://localhost/fake/shares/1',
|
||||
'href': 'http://localhost/share/fake/shares/1',
|
||||
'rel': 'bookmark'
|
||||
}
|
||||
],
|
||||
@ -143,7 +143,7 @@ class ShareAPITest(test.TestCase):
|
||||
def test_share_create_original(self, microversion):
|
||||
self.mock_object(share_api.API, 'create', self.create_mock)
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version=microversion)
|
||||
req = fakes.HTTPRequest.blank('/fake/shares', version=microversion)
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -157,7 +157,7 @@ class ShareAPITest(test.TestCase):
|
||||
def test_share_create_with_snapshot_support_without_cg(self, microversion):
|
||||
self.mock_object(share_api.API, 'create', self.create_mock)
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version=microversion)
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/shares', version=microversion)
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -173,7 +173,7 @@ class ShareAPITest(test.TestCase):
|
||||
self.mock_object(share_api.API, 'create', self.create_mock)
|
||||
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/shares')
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
self.mock_policy_check.assert_called_once_with(
|
||||
@ -191,7 +191,7 @@ class ShareAPITest(test.TestCase):
|
||||
self.vt['name'])),
|
||||
)
|
||||
CONF.set_default("default_share_type", self.vt['name'])
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/shares')
|
||||
|
||||
self.assertRaises(exception.ShareTypeNotFoundByName,
|
||||
self.controller.create, req, {'share': self.share})
|
||||
@ -212,7 +212,7 @@ class ShareAPITest(test.TestCase):
|
||||
mock.Mock(return_value=fake_share_type),
|
||||
)
|
||||
CONF.set_default("default_share_type", fake_share_type['name'])
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/shares')
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.create, req, {'share': self.share})
|
||||
@ -244,7 +244,7 @@ class ShareAPITest(test.TestCase):
|
||||
mock.Mock(return_value={'id': 'fakesubnetid'}))
|
||||
|
||||
body = {"share": copy.deepcopy(shr)}
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/shares')
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
self.mock_policy_check.assert_called_once_with(
|
||||
@ -276,7 +276,7 @@ class ShareAPITest(test.TestCase):
|
||||
share_network_id=shr['share_network_id']))
|
||||
self.mock_object(share_api.API, 'create', create_mock)
|
||||
body = {"share": copy.deepcopy(shr)}
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/shares')
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -320,7 +320,7 @@ class ShareAPITest(test.TestCase):
|
||||
db, 'share_network_subnet_get_by_availability_zone_id')
|
||||
|
||||
body = {"share": copy.deepcopy(shr)}
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/shares')
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -367,7 +367,7 @@ class ShareAPITest(test.TestCase):
|
||||
db, 'share_network_subnet_get_by_availability_zone_id')
|
||||
|
||||
body = {"share": copy.deepcopy(shr)}
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/shares')
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -392,7 +392,7 @@ class ShareAPITest(test.TestCase):
|
||||
"share_network_id": 1234
|
||||
}
|
||||
body = {"share": shr}
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/shares')
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.create,
|
||||
@ -439,7 +439,7 @@ class ShareAPITest(test.TestCase):
|
||||
db, 'share_network_subnet_get_by_availability_zone_id')
|
||||
|
||||
body = {"share": copy.deepcopy(shr)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version=microversion)
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/shares', version=microversion)
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -459,7 +459,7 @@ class ShareAPITest(test.TestCase):
|
||||
"share_proto": "fakeproto",
|
||||
"availability_zone": "zone1:host1"}
|
||||
body = {"share": shr}
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/fake/shares')
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.controller.create,
|
||||
req,
|
||||
@ -469,7 +469,7 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_share_create_no_body(self):
|
||||
body = {}
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/fake/shares')
|
||||
self.assertRaises(webob.exc.HTTPUnprocessableEntity,
|
||||
self.controller.create,
|
||||
req,
|
||||
@ -485,7 +485,7 @@ class ShareAPITest(test.TestCase):
|
||||
)
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/fake/shares')
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.create,
|
||||
req,
|
||||
@ -507,14 +507,14 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
body = {"share": fake_share_with_sn}
|
||||
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/fake/shares')
|
||||
self.assertRaises(exception_to_raise,
|
||||
self.controller.create,
|
||||
req,
|
||||
body)
|
||||
|
||||
def test_share_show(self):
|
||||
req = fakes.HTTPRequest.blank('/shares/1')
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/1')
|
||||
expected = self._get_expected_share_detailed_response()
|
||||
expected['share'].pop('snapshot_support')
|
||||
|
||||
@ -523,7 +523,7 @@ class ShareAPITest(test.TestCase):
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
def test_share_show_with_share_type_name(self):
|
||||
req = fakes.HTTPRequest.blank('/shares/1', version='2.6')
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/1', version='2.6')
|
||||
res_dict = self.controller.show(req, '1')
|
||||
expected = self._get_expected_share_detailed_response()
|
||||
expected['share']['share_type_name'] = None
|
||||
@ -531,7 +531,7 @@ class ShareAPITest(test.TestCase):
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
def test_share_show_admin(self):
|
||||
req = fakes.HTTPRequest.blank('/shares/1', use_admin_context=True)
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/1', use_admin_context=True)
|
||||
expected = self._get_expected_share_detailed_response(admin=True)
|
||||
expected['share'].pop('snapshot_support')
|
||||
|
||||
@ -542,13 +542,13 @@ class ShareAPITest(test.TestCase):
|
||||
def test_share_show_no_share(self):
|
||||
self.mock_object(share_api.API, 'get',
|
||||
stubs.stub_share_get_notfound)
|
||||
req = fakes.HTTPRequest.blank('/shares/1')
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/1')
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.show,
|
||||
req, '1')
|
||||
|
||||
def test_share_delete(self):
|
||||
req = fakes.HTTPRequest.blank('/shares/1')
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/1')
|
||||
resp = self.controller.delete(req, 1)
|
||||
self.assertEqual(202, resp.status_int)
|
||||
|
||||
@ -580,7 +580,7 @@ class ShareAPITest(test.TestCase):
|
||||
def test_share_delete_no_share(self):
|
||||
self.mock_object(share_api.API, 'get',
|
||||
stubs.stub_share_get_notfound)
|
||||
req = fakes.HTTPRequest.blank('/shares/1')
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/1')
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.delete,
|
||||
req,
|
||||
@ -605,7 +605,7 @@ class ShareAPITest(test.TestCase):
|
||||
if use_admin_context:
|
||||
search_opts['host'] = 'fake_host'
|
||||
# fake_key should be filtered for non-admin
|
||||
url = '/shares?fake_key=fake_value'
|
||||
url = '/fake/shares?fake_key=fake_value'
|
||||
for k, v in search_opts.items():
|
||||
url = url + '&' + k + '=' + v
|
||||
req = fakes.HTTPRequest.blank(url, use_admin_context=use_admin_context)
|
||||
@ -657,7 +657,7 @@ class ShareAPITest(test.TestCase):
|
||||
def test_share_list_summary(self):
|
||||
self.mock_object(share_api.API, 'get_all',
|
||||
stubs.stub_share_get_all_by_project)
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/fake/shares')
|
||||
res_dict = self.controller.index(req)
|
||||
expected = {
|
||||
'shares': [
|
||||
@ -666,11 +666,11 @@ class ShareAPITest(test.TestCase):
|
||||
'id': '1',
|
||||
'links': [
|
||||
{
|
||||
'href': 'http://localhost/v1/fake/shares/1',
|
||||
'href': 'http://localhost/share/v1/fake/shares/1',
|
||||
'rel': 'self'
|
||||
},
|
||||
{
|
||||
'href': 'http://localhost/fake/shares/1',
|
||||
'href': 'http://localhost/share/fake/shares/1',
|
||||
'rel': 'bookmark'
|
||||
}
|
||||
],
|
||||
@ -698,7 +698,7 @@ class ShareAPITest(test.TestCase):
|
||||
if use_admin_context:
|
||||
search_opts['host'] = 'fake_host'
|
||||
# fake_key should be filtered for non-admin
|
||||
url = '/shares/detail?fake_key=fake_value'
|
||||
url = '/fake/shares/detail?fake_key=fake_value'
|
||||
for k, v in search_opts.items():
|
||||
url = url + '&' + k + '=' + v
|
||||
req = fakes.HTTPRequest.blank(url, use_admin_context=use_admin_context)
|
||||
@ -792,11 +792,11 @@ class ShareAPITest(test.TestCase):
|
||||
'is_public': False,
|
||||
'links': [
|
||||
{
|
||||
'href': 'http://localhost/v1/fake/shares/1',
|
||||
'href': 'http://localhost/share/v1/fake/shares/1',
|
||||
'rel': 'self'
|
||||
},
|
||||
{
|
||||
'href': 'http://localhost/fake/shares/1',
|
||||
'href': 'http://localhost/share/fake/shares/1',
|
||||
'rel': 'bookmark'
|
||||
}
|
||||
],
|
||||
@ -815,14 +815,14 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_share_list_detail(self):
|
||||
env = {'QUERY_STRING': 'name=Share+Test+Name'}
|
||||
req = fakes.HTTPRequest.blank('/shares/detail', environ=env)
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/detail', environ=env)
|
||||
expected = self._list_detail_common_expected()
|
||||
expected['shares'][0].pop('snapshot_support')
|
||||
self._list_detail_test_common(req, expected)
|
||||
|
||||
def test_share_list_detail_with_task_state(self):
|
||||
env = {'QUERY_STRING': 'name=Share+Test+Name'}
|
||||
req = fakes.HTTPRequest.blank('/shares/detail', environ=env,
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/detail', environ=env,
|
||||
version="2.5")
|
||||
expected = self._list_detail_common_expected()
|
||||
expected['shares'][0]['task_state'] = None
|
||||
@ -896,7 +896,7 @@ class ShareActionsTest(test.TestCase):
|
||||
id = 'fake_share_id'
|
||||
body = {'os-allow_access': access}
|
||||
expected = {'access': {'fake': 'fake'}}
|
||||
req = fakes.HTTPRequest.blank('/v1/tenant1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/tenant1/shares/%s/action' % id)
|
||||
|
||||
res = self.controller._allow_access(req, id, body)
|
||||
|
||||
@ -924,7 +924,7 @@ class ShareActionsTest(test.TestCase):
|
||||
def test_allow_access_error(self, access):
|
||||
id = 'fake_share_id'
|
||||
body = {'os-allow_access': access}
|
||||
req = fakes.HTTPRequest.blank('/v1/tenant1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/tenant1/shares/%s/action' % id)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller._allow_access, req, id, body)
|
||||
@ -940,7 +940,7 @@ class ShareActionsTest(test.TestCase):
|
||||
|
||||
id = 'fake_share_id'
|
||||
body = {"os-deny_access": {"access_id": 'fake_acces_id'}}
|
||||
req = fakes.HTTPRequest.blank('/v1/tenant1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/tenant1/shares/%s/action' % id)
|
||||
|
||||
res = self.controller._deny_access(req, id, body)
|
||||
|
||||
@ -957,7 +957,7 @@ class ShareActionsTest(test.TestCase):
|
||||
|
||||
id = 'super_fake_share_id'
|
||||
body = {"os-deny_access": {"access_id": 'fake_acces_id'}}
|
||||
req = fakes.HTTPRequest.blank('/v1/tenant1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/tenant1/shares/%s/action' % id)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller._deny_access,
|
||||
@ -969,7 +969,7 @@ class ShareActionsTest(test.TestCase):
|
||||
|
||||
@ddt.data('_allow_access', '_deny_access')
|
||||
def test_allow_access_deny_access_policy_not_authorized(self, method):
|
||||
req = fakes.HTTPRequest.blank('/v1/tenant1/shares/someuuid/action')
|
||||
req = fakes.HTTPRequest.blank('/tenant1/shares/someuuid/action')
|
||||
action = method[1:]
|
||||
body = {action: None}
|
||||
noauthexc = exception.PolicyNotAuthorized(action=action)
|
||||
@ -996,7 +996,7 @@ class ShareActionsTest(test.TestCase):
|
||||
fake_access_list}))
|
||||
id = 'fake_share_id'
|
||||
body = {"os-access_list": None}
|
||||
req = fakes.HTTPRequest.blank('/v1/tenant1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/tenant1/shares/%s/action' % id)
|
||||
|
||||
res_dict = self.controller._access_list(req, id, body)
|
||||
self.assertEqual({'access_list': fake_access_list}, res_dict)
|
||||
@ -1009,7 +1009,7 @@ class ShareActionsTest(test.TestCase):
|
||||
|
||||
size = '123'
|
||||
body = {"os-extend": {'new_size': size}}
|
||||
req = fakes.HTTPRequest.blank('/v1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/%s/action' % id)
|
||||
|
||||
actual_response = self.controller._extend(req, id, body)
|
||||
|
||||
@ -1023,7 +1023,7 @@ class ShareActionsTest(test.TestCase):
|
||||
{"os-extend": {"new_size": {'foo': 'bar'}}})
|
||||
def test_extend_invalid_body(self, body):
|
||||
id = 'fake_share_id'
|
||||
req = fakes.HTTPRequest.blank('/v1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/%s/action' % id)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller._extend, req, id, body)
|
||||
@ -1037,7 +1037,7 @@ class ShareActionsTest(test.TestCase):
|
||||
@ddt.unpack
|
||||
def test_extend_exception(self, source, target):
|
||||
id = 'fake_share_id'
|
||||
req = fakes.HTTPRequest.blank('/v1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/%s/action' % id)
|
||||
body = {"os-extend": {'new_size': '123'}}
|
||||
self.mock_object(share_api.API, "extend",
|
||||
mock.Mock(side_effect=source('fake')))
|
||||
@ -1052,7 +1052,7 @@ class ShareActionsTest(test.TestCase):
|
||||
|
||||
size = '123'
|
||||
body = {"os-shrink": {'new_size': size}}
|
||||
req = fakes.HTTPRequest.blank('/v1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/%s/action' % id)
|
||||
|
||||
actual_response = self.controller._shrink(req, id, body)
|
||||
|
||||
@ -1066,7 +1066,7 @@ class ShareActionsTest(test.TestCase):
|
||||
{"os-shrink": {"new_size": {'foo': 'bar'}}})
|
||||
def test_shrink_invalid_body(self, body):
|
||||
id = 'fake_share_id'
|
||||
req = fakes.HTTPRequest.blank('/v1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/%s/action' % id)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller._shrink, req, id, body)
|
||||
@ -1078,7 +1078,7 @@ class ShareActionsTest(test.TestCase):
|
||||
@ddt.unpack
|
||||
def test_shrink_exception(self, source, target):
|
||||
id = 'fake_share_id'
|
||||
req = fakes.HTTPRequest.blank('/v1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/fake/shares/%s/action' % id)
|
||||
body = {"os-shrink": {'new_size': '123'}}
|
||||
self.mock_object(share_api.API, "shrink",
|
||||
mock.Mock(side_effect=source('fake')))
|
||||
@ -1162,7 +1162,7 @@ class ShareAdminActionsAPITest(test.TestCase):
|
||||
|
||||
def test_share_reset_status_for_missing(self):
|
||||
fake_share = {'id': 'missing-share-id'}
|
||||
req = webob.Request.blank('/v1/fake/shares/%s/action' %
|
||||
req = webob.Request.blank('/fake/shares/%s/action' %
|
||||
fake_share['id'])
|
||||
|
||||
self._reset_status(self.admin_context, fake_share, req,
|
||||
|
@ -43,9 +43,9 @@ class MessageApiTest(test.TestCase):
|
||||
def _expected_message_from_controller(self, id, **kwargs):
|
||||
message = stubs.stub_message(id, **kwargs)
|
||||
links = [
|
||||
{'href': 'http://localhost/v2/fake/messages/%s' % id,
|
||||
{'href': 'http://localhost/share/v2/fake/messages/%s' % id,
|
||||
'rel': 'self'},
|
||||
{'href': 'http://localhost/fake/messages/%s' % id,
|
||||
{'href': 'http://localhost/share/fake/messages/%s' % id,
|
||||
'rel': 'bookmark'},
|
||||
]
|
||||
return {
|
||||
@ -71,9 +71,8 @@ class MessageApiTest(test.TestCase):
|
||||
self.mock_object(message_api.API, 'get', stubs.stub_message_get)
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/messages/%s' % fakes.FAKE_UUID,
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION,
|
||||
base_url='http://localhost/v2')
|
||||
'/v2/fake/messages/%s' % fakes.FAKE_UUID,
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION)
|
||||
req.environ['manila.context'] = self.ctxt
|
||||
|
||||
res_dict = self.controller.show(req, fakes.FAKE_UUID)
|
||||
@ -91,9 +90,9 @@ class MessageApiTest(test.TestCase):
|
||||
self.mock_object(message_api.API, 'get', mock_get)
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/messages/%s' % fakes.FAKE_UUID,
|
||||
'/v2/fake/messages/%s' % fakes.FAKE_UUID,
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION,
|
||||
base_url='http://localhost/v2')
|
||||
base_url='http://localhost/share/v2')
|
||||
req.environ['manila.context'] = self.ctxt
|
||||
|
||||
res_dict = self.controller.show(req, fakes.FAKE_UUID)
|
||||
@ -109,9 +108,9 @@ class MessageApiTest(test.TestCase):
|
||||
mock.Mock(side_effect=fake_not_found))
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/messages/%s' % fakes.FAKE_UUID,
|
||||
'/v2/fake/messages/%s' % fakes.FAKE_UUID,
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION,
|
||||
base_url='http://localhost/v2')
|
||||
base_url='http://localhost/share/v2')
|
||||
req.environ['manila.context'] = self.ctxt
|
||||
|
||||
self.assertRaises(webob.exc.HTTPNotFound, self.controller.show,
|
||||
@ -120,9 +119,9 @@ class MessageApiTest(test.TestCase):
|
||||
def test_show_pre_microversion(self):
|
||||
self.mock_object(message_api.API, 'get', stubs.stub_message_get)
|
||||
|
||||
req = fakes.HTTPRequest.blank('/messages/%s' % fakes.FAKE_UUID,
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/messages/%s' % fakes.FAKE_UUID,
|
||||
version='2.35',
|
||||
base_url='http://localhost/v2')
|
||||
base_url='http://localhost/share/v2')
|
||||
req.environ['manila.context'] = self.ctxt
|
||||
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
@ -133,7 +132,7 @@ class MessageApiTest(test.TestCase):
|
||||
self.mock_object(message_api.API, 'delete')
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/messages/%s' % fakes.FAKE_UUID,
|
||||
'/v2/fake/messages/%s' % fakes.FAKE_UUID,
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION)
|
||||
req.environ['manila.context'] = self.ctxt
|
||||
|
||||
@ -148,7 +147,7 @@ class MessageApiTest(test.TestCase):
|
||||
mock.Mock(side_effect=fake_not_found))
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/messages/%s' % fakes.FAKE_UUID,
|
||||
'/v2/fake/messages/%s' % fakes.FAKE_UUID,
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete,
|
||||
@ -160,9 +159,9 @@ class MessageApiTest(test.TestCase):
|
||||
self.mock_object(message_api.API, 'get_all', mock.Mock(
|
||||
return_value=[msg1, msg2]))
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/messages',
|
||||
'/v2/fake/messages',
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION,
|
||||
base_url='http://localhost/v2')
|
||||
base_url='http://localhost/share/v2')
|
||||
req.environ['manila.context'] = self.ctxt
|
||||
|
||||
res_dict = self.controller.index(req)
|
||||
@ -177,9 +176,8 @@ class MessageApiTest(test.TestCase):
|
||||
self.mock_object(message_api.API, 'get_all', mock.Mock(
|
||||
return_value=[msg2]))
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/messages?limit=1&offset=1',
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION,
|
||||
base_url='http://localhost/v2')
|
||||
'/v2/fake/messages?limit=1&offset=1',
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION)
|
||||
req.environ['manila.context'] = self.ctxt
|
||||
|
||||
res_dict = self.controller.index(req)
|
||||
@ -195,10 +193,10 @@ class MessageApiTest(test.TestCase):
|
||||
self.mock_object(message_api.API, 'get_all', mock.Mock(
|
||||
return_value=[msg]))
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/messages?created_since=1900-01-01T01:01:01&'
|
||||
'/fake/messages?created_since=1900-01-01T01:01:01&'
|
||||
'created_before=1900-03-01T01:01:01',
|
||||
version=messages.MESSAGES_QUERY_BY_TIMESTAMP,
|
||||
base_url='http://localhost/v2')
|
||||
base_url='http://localhost/share/v2')
|
||||
req.environ['manila.context'] = self.ctxt
|
||||
|
||||
res_dict = self.controller.index(req)
|
||||
@ -213,7 +211,7 @@ class MessageApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/messages?created_since=invalid_time_str',
|
||||
version=messages.MESSAGES_QUERY_BY_TIMESTAMP,
|
||||
base_url='http://localhost/v2')
|
||||
base_url='http://localhost/share/v2')
|
||||
req.environ['manila.context'] = self.ctxt
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.index, req)
|
||||
|
@ -97,7 +97,7 @@ class ShareInstancesAPITest(test.TestCase):
|
||||
req_context, self.resource_name, 'index')
|
||||
|
||||
def test_index_with_limit(self):
|
||||
req = self._get_request('/share_instances')
|
||||
req = self._get_request('/v2/fake/share_instances')
|
||||
req_context = req.environ['manila.context']
|
||||
share_instances_count = 3
|
||||
test_instances = [
|
||||
@ -107,13 +107,13 @@ class ShareInstancesAPITest(test.TestCase):
|
||||
expect_links = [
|
||||
{
|
||||
'href': (
|
||||
'http://localhost/v1/fake/share_instances?'
|
||||
'http://localhost/share/v2/fake/share_instances?'
|
||||
'limit=3&marker=%s' % test_instances[2]['id']),
|
||||
'rel': 'next',
|
||||
}
|
||||
]
|
||||
|
||||
url = 'share_instances?limit=3'
|
||||
url = '/v2/fake/share_instances?limit=3'
|
||||
req = self._get_request(url)
|
||||
actual_result = self.controller.index(req)
|
||||
|
||||
|
@ -32,7 +32,7 @@ class ShareSnapshotExportLocationsAPITest(test.TestCase):
|
||||
|
||||
def _get_request(self, version="2.32", use_admin_context=True):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/snapshots/%s/export-locations' % self.snapshot['id'],
|
||||
'/v2/fake/snapshots/%s/export-locations' % self.snapshot['id'],
|
||||
version=version, use_admin_context=use_admin_context)
|
||||
return req
|
||||
|
||||
@ -75,12 +75,12 @@ class ShareSnapshotExportLocationsAPITest(test.TestCase):
|
||||
'is_admin_only': True,
|
||||
'id': self.exp_loc['id'],
|
||||
'links': [{
|
||||
'href': 'http://localhost/v1/fake/'
|
||||
'href': 'http://localhost/share/v2/fake/'
|
||||
'share_snapshot_export_locations/' +
|
||||
self.exp_loc['id'],
|
||||
'rel': 'self'
|
||||
}, {
|
||||
'href': 'http://localhost/fake/'
|
||||
'href': 'http://localhost/share/fake/'
|
||||
'share_snapshot_export_locations/' +
|
||||
self.exp_loc['id'],
|
||||
'rel': 'bookmark'
|
||||
|
@ -32,7 +32,7 @@ class ShareSnapshotInstanceExportLocationsAPITest(test.TestCase):
|
||||
|
||||
def _get_request(self, version="2.32", use_admin_context=True):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/snapshot-instances/%s/export-locations' %
|
||||
'/v2/fake/snapshot-instances/%s/export-locations' %
|
||||
self.snapshot_instance['id'],
|
||||
version=version, use_admin_context=use_admin_context)
|
||||
return req
|
||||
@ -74,11 +74,11 @@ class ShareSnapshotInstanceExportLocationsAPITest(test.TestCase):
|
||||
'is_admin_only': True,
|
||||
'id': self.el['id'],
|
||||
'links': [{
|
||||
'href': 'http://localhost/v1/fake/'
|
||||
'href': 'http://localhost/share/v2/fake/'
|
||||
'share_snapshot_export_locations/' + self.el['id'],
|
||||
'rel': 'self'
|
||||
}, {
|
||||
'href': 'http://localhost/fake/'
|
||||
'href': 'http://localhost/share/fake/'
|
||||
'share_snapshot_export_locations/' + self.el['id'],
|
||||
'rel': 'bookmark'
|
||||
}],
|
||||
|
@ -87,7 +87,10 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
'description': 'displaysnapdesc',
|
||||
}
|
||||
}
|
||||
req = fakes.HTTPRequest.blank('/snapshots', version=version)
|
||||
url = ('/v2/fake/snapshots'
|
||||
if version.startswith('2.')
|
||||
else '/v1/fake/snapshots')
|
||||
req = fakes.HTTPRequest.blank(url, version=version)
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -110,7 +113,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
'description': 'fake_share_description',
|
||||
}
|
||||
}
|
||||
req = fakes.HTTPRequest.blank('/snapshots')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/snapshots')
|
||||
|
||||
self.assertRaises(
|
||||
webob.exc.HTTPUnprocessableEntity,
|
||||
@ -120,7 +123,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
|
||||
def test_snapshot_create_no_body(self):
|
||||
body = {}
|
||||
req = fakes.HTTPRequest.blank('/snapshots')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/snapshots')
|
||||
self.assertRaises(webob.exc.HTTPUnprocessableEntity,
|
||||
self.controller.create,
|
||||
req,
|
||||
@ -129,14 +132,14 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
def test_snapshot_delete(self):
|
||||
self.mock_object(share_api.API, 'delete_snapshot',
|
||||
stubs.stub_snapshot_delete)
|
||||
req = fakes.HTTPRequest.blank('/snapshots/200')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/snapshots/200')
|
||||
resp = self.controller.delete(req, 200)
|
||||
self.assertEqual(202, resp.status_int)
|
||||
|
||||
def test_snapshot_delete_nofound(self):
|
||||
self.mock_object(share_api.API, 'get_snapshot',
|
||||
stubs.stub_snapshot_get_notfound)
|
||||
req = fakes.HTTPRequest.blank('/snapshots/200')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/snapshots/200')
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.delete,
|
||||
req,
|
||||
@ -144,7 +147,8 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
|
||||
@ddt.data('2.0', '2.16', '2.17')
|
||||
def test_snapshot_show(self, version):
|
||||
req = fakes.HTTPRequest.blank('/snapshots/200', version=version)
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/snapshots/200',
|
||||
version=version)
|
||||
expected = fake_share.expected_snapshot(version=version, id=200)
|
||||
|
||||
res_dict = self.controller.show(req, 200)
|
||||
@ -154,7 +158,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
def test_snapshot_show_nofound(self):
|
||||
self.mock_object(share_api.API, 'get_snapshot',
|
||||
stubs.stub_snapshot_get_notfound)
|
||||
req = fakes.HTTPRequest.blank('/snapshots/200')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/snapshots/200')
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.show,
|
||||
req, '200')
|
||||
@ -162,7 +166,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
def test_snapshot_list_summary(self):
|
||||
self.mock_object(share_api.API, 'get_all_snapshots',
|
||||
stubs.stub_snapshot_get_all_by_project)
|
||||
req = fakes.HTTPRequest.blank('/snapshots')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/snapshots')
|
||||
res_dict = self.controller.index(req)
|
||||
expected = {
|
||||
'snapshots': [
|
||||
@ -171,12 +175,12 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
'id': 2,
|
||||
'links': [
|
||||
{
|
||||
'href': 'http://localhost/v1/fake/'
|
||||
'href': 'http://localhost/share/v2/fake/'
|
||||
'snapshots/2',
|
||||
'rel': 'self'
|
||||
},
|
||||
{
|
||||
'href': 'http://localhost/fake/snapshots/2',
|
||||
'href': 'http://localhost/share/fake/snapshots/2',
|
||||
'rel': 'bookmark'
|
||||
}
|
||||
],
|
||||
@ -193,7 +197,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
search_opts.pop('name')
|
||||
search_opts['display_name~'] = 'fake_name'
|
||||
# fake_key should be filtered for non-admin
|
||||
url = '/snapshots?fake_key=fake_value'
|
||||
url = '/v2/fake/snapshots?fake_key=fake_value'
|
||||
for k, v in search_opts.items():
|
||||
url = url + '&' + k + '=' + v
|
||||
req = fakes.HTTPRequest.blank(
|
||||
@ -244,7 +248,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
def _snapshot_list_detail_with_search_opts(self, use_admin_context):
|
||||
search_opts = fake_share.search_opts()
|
||||
# fake_key should be filtered for non-admin
|
||||
url = '/shares/detail?fake_key=fake_value'
|
||||
url = '/v2/fake/shares/detail?fake_key=fake_value'
|
||||
for k, v in search_opts.items():
|
||||
url = url + '&' + k + '=' + v
|
||||
req = fakes.HTTPRequest.blank(url, use_admin_context=use_admin_context)
|
||||
@ -307,7 +311,8 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
@ddt.data('2.0', '2.16', '2.17')
|
||||
def test_snapshot_list_detail(self, version):
|
||||
env = {'QUERY_STRING': 'name=Share+Test+Name'}
|
||||
req = fakes.HTTPRequest.blank('/snapshots/detail', environ=env,
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/snapshots/detail',
|
||||
environ=env,
|
||||
version=version)
|
||||
expected_s = fake_share.expected_snapshot(version=version, id=2)
|
||||
expected = {'snapshots': [expected_s['snapshot']]}
|
||||
@ -320,7 +325,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
def test_snapshot_updates_display_name_and_description(self, version):
|
||||
snp = self.snp_example
|
||||
body = {"snapshot": snp}
|
||||
req = fakes.HTTPRequest.blank('/snapshot/1', version=version)
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/snapshot/1', version=version)
|
||||
|
||||
res_dict = self.controller.update(req, 1, body)
|
||||
|
||||
@ -338,7 +343,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
snp = self.snp_example
|
||||
body = {"snapshot": snp}
|
||||
|
||||
req = fakes.HTTPRequest.blank('/snapshot/1')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/snapshot/1')
|
||||
res_dict = self.controller.update(req, 1, body)
|
||||
|
||||
self.assertNotEqual(snp["size"], res_dict['snapshot']["size"])
|
||||
@ -358,7 +363,7 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
mock.Mock(return_value=expected))
|
||||
|
||||
id = 'fake_snap_id'
|
||||
req = fakes.HTTPRequest.blank('/snapshots/%s/action' % id,
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/snapshots/%s/action' % id,
|
||||
version='2.32')
|
||||
|
||||
actual = self.controller.access_list(req, id)
|
||||
@ -388,8 +393,8 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
allow_access = self.mock_object(share_api.API, 'snapshot_allow_access',
|
||||
mock.Mock(return_value=access))
|
||||
body = {'allow_access': access}
|
||||
req = fakes.HTTPRequest.blank('/snapshots/%s/action' % snapshot['id'],
|
||||
version=version)
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/snapshots/%s/action' % snapshot['id'], version=version)
|
||||
|
||||
actual = self.controller.allow_access(req, snapshot['id'], body)
|
||||
|
||||
@ -406,8 +411,8 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
share = db_utils.create_share(mount_snapshot_support=True)
|
||||
snapshot = db_utils.create_snapshot(
|
||||
status=constants.STATUS_AVAILABLE, share_id=share['id'])
|
||||
req = fakes.HTTPRequest.blank('/snapshots/%s/action' % snapshot['id'],
|
||||
version='2.32')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/snapshots/%s/action' % snapshot['id'], version='2.32')
|
||||
body = {}
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
@ -418,8 +423,8 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
share = db_utils.create_share(mount_snapshot_support=True)
|
||||
snapshot = db_utils.create_snapshot(
|
||||
status=constants.STATUS_AVAILABLE, share_id=share['id'])
|
||||
req = fakes.HTTPRequest.blank('/snapshots/%s/action' % snapshot['id'],
|
||||
version='2.32')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/snapshots/%s/action' % snapshot['id'], version='2.32')
|
||||
access = {
|
||||
'id': 'fake_id',
|
||||
'access_type': 'ip',
|
||||
@ -468,8 +473,8 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
mock.Mock(return_value=share))
|
||||
|
||||
body = {'allow_access': access}
|
||||
req = fakes.HTTPRequest.blank('/snapshots/%s/action' % snapshot['id'],
|
||||
version='2.32')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/snapshots/%s/action' % snapshot['id'], version='2.32')
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.allow_access, req,
|
||||
@ -490,8 +495,8 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
'access_to': ''}
|
||||
|
||||
body = {'allow_access': access}
|
||||
req = fakes.HTTPRequest.blank('/snapshots/%s/action' % snapshot['id'],
|
||||
version='2.32')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/snapshots/%s/action' % snapshot['id'], version='2.32')
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.allow_access, req,
|
||||
@ -513,8 +518,8 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
deny_access = self.mock_object(share_api.API, 'snapshot_deny_access')
|
||||
|
||||
body = {'deny_access': {'access_id': access.id}}
|
||||
req = fakes.HTTPRequest.blank('/snapshots/%s/action' % snapshot['id'],
|
||||
version='2.32')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/snapshots/%s/action' % snapshot['id'], version='2.32')
|
||||
|
||||
resp = self.controller.deny_access(req, snapshot['id'], body)
|
||||
|
||||
@ -533,8 +538,8 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
share = db_utils.create_share(mount_snapshot_support=True)
|
||||
snapshot = db_utils.create_snapshot(
|
||||
status=constants.STATUS_AVAILABLE, share_id=share['id'])
|
||||
req = fakes.HTTPRequest.blank('/snapshots/%s/action' % snapshot['id'],
|
||||
version='2.32')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/snapshots/%s/action' % snapshot['id'], version='2.32')
|
||||
body = {}
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
@ -561,8 +566,8 @@ class ShareSnapshotAPITest(test.TestCase):
|
||||
mock.Mock(return_value=wrong_access))
|
||||
|
||||
body = {'deny_access': {'access_id': access.id}}
|
||||
req = fakes.HTTPRequest.blank('/snapshots/%s/action' % snapshot['id'],
|
||||
version='2.32')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/snapshots/%s/action' % snapshot['id'], version='2.32')
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.deny_access, req, snapshot['id'],
|
||||
@ -588,11 +593,11 @@ class ShareSnapshotAdminActionsAPITest(test.TestCase):
|
||||
|
||||
self.resource_name = self.controller.resource_name
|
||||
self.manage_request = fakes.HTTPRequest.blank(
|
||||
'/snapshots/manage', use_admin_context=True,
|
||||
'/v2/fake/snapshots/manage', use_admin_context=True,
|
||||
version=MIN_MANAGE_SNAPSHOT_API_VERSION)
|
||||
self.snapshot_id = 'fake'
|
||||
self.unmanage_request = fakes.HTTPRequest.blank(
|
||||
'/snapshots/%s/unmanage' % self.snapshot_id,
|
||||
'/v2/fake/snapshots/%s/unmanage' % self.snapshot_id,
|
||||
use_admin_context=True,
|
||||
version=MIN_MANAGE_SNAPSHOT_API_VERSION)
|
||||
|
||||
@ -734,8 +739,9 @@ class ShareSnapshotAdminActionsAPITest(test.TestCase):
|
||||
'display_description': 'bar',
|
||||
}
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/snapshots/manage', use_admin_context=True, version=version)
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/snapshots/manage',
|
||||
use_admin_context=True,
|
||||
version=version)
|
||||
|
||||
actual_result = self.controller.manage(req, data)
|
||||
|
||||
@ -793,7 +799,7 @@ class ShareSnapshotAdminActionsAPITest(test.TestCase):
|
||||
share_id='fake', provider_location='fake_volume_snapshot_id',
|
||||
driver_options={})
|
||||
fake_req = fakes.HTTPRequest.blank(
|
||||
'/snapshots/manage', use_admin_context=True,
|
||||
'/v2/fake/snapshots/manage', use_admin_context=True,
|
||||
version=version)
|
||||
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
@ -804,8 +810,7 @@ class ShareSnapshotAdminActionsAPITest(test.TestCase):
|
||||
body = {}
|
||||
snapshot = {'status': constants.STATUS_AVAILABLE, 'id': 'bar_id',
|
||||
'share_id': 'bar_id'}
|
||||
fake_req = fakes.HTTPRequest.blank(
|
||||
'/snapshots/unmanage',
|
||||
fake_req = fakes.HTTPRequest.blank('/v2/fake/snapshots/unmanage',
|
||||
use_admin_context=True,
|
||||
version='2.49')
|
||||
mock_unmanage = self.mock_object(self.controller, '_unmanage')
|
||||
@ -948,7 +953,7 @@ class ShareSnapshotAdminActionsAPITest(test.TestCase):
|
||||
def test_unmanage_version_not_found(self, version):
|
||||
snapshot_id = 'fake'
|
||||
fake_req = fakes.HTTPRequest.blank(
|
||||
'/snapshots/%s/unmanage' % snapshot_id,
|
||||
'/v2/fake/snapshots/%s/unmanage' % snapshot_id,
|
||||
use_admin_context=True,
|
||||
version=version)
|
||||
|
||||
|
@ -165,11 +165,11 @@ class ShareAPITest(test.TestCase):
|
||||
'share_type_name': None,
|
||||
'links': [
|
||||
{
|
||||
'href': 'http://localhost/v1/fake/shares/1',
|
||||
'href': 'http://localhost/share/v2/fake/shares/1',
|
||||
'rel': 'self'
|
||||
},
|
||||
{
|
||||
'href': 'http://localhost/fake/shares/1',
|
||||
'href': 'http://localhost/share/fake/shares/1',
|
||||
'rel': 'bookmark'
|
||||
}
|
||||
],
|
||||
@ -205,8 +205,9 @@ class ShareAPITest(test.TestCase):
|
||||
snapshot = copy.deepcopy(self.snapshot)
|
||||
snapshot['status'] = constants.STATUS_AVAILABLE
|
||||
body = {'revert': {'snapshot_id': '2'}}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1/action', use_admin_context=False, version='2.27')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1/action',
|
||||
use_admin_context=False,
|
||||
version='2.27')
|
||||
mock_validate_revert_parameters = self.mock_object(
|
||||
self.controller, '_validate_revert_parameters',
|
||||
mock.Mock(return_value=body['revert']))
|
||||
@ -243,8 +244,9 @@ class ShareAPITest(test.TestCase):
|
||||
snapshot['status'] = constants.STATUS_AVAILABLE
|
||||
snapshot['share_id'] = 'wrong_id'
|
||||
body = {'revert': {'snapshot_id': '2'}}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1/action', use_admin_context=False, version='2.27')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1/action',
|
||||
use_admin_context=False,
|
||||
version='2.27')
|
||||
self.mock_object(
|
||||
self.controller, '_validate_revert_parameters',
|
||||
mock.Mock(return_value=body['revert']))
|
||||
@ -268,8 +270,9 @@ class ShareAPITest(test.TestCase):
|
||||
snapshot['status'] = constants.STATUS_AVAILABLE
|
||||
snapshot['share_id'] = 'wrong_id'
|
||||
body = {'revert': {'snapshot_id': '2'}}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1/action', use_admin_context=False, version='2.27')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1/action',
|
||||
use_admin_context=False,
|
||||
version='2.27')
|
||||
self.mock_object(
|
||||
self.controller, '_validate_revert_parameters',
|
||||
mock.Mock(return_value=body['revert']))
|
||||
@ -309,8 +312,9 @@ class ShareAPITest(test.TestCase):
|
||||
snapshot = copy.deepcopy(self.snapshot)
|
||||
snapshot['status'] = snapshot_status
|
||||
body = {'revert': {'snapshot_id': '2'}}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1/action', use_admin_context=False, version='2.27')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1/action',
|
||||
use_admin_context=False,
|
||||
version='2.27')
|
||||
self.mock_object(
|
||||
self.controller, '_validate_revert_parameters',
|
||||
mock.Mock(return_value=body['revert']))
|
||||
@ -333,8 +337,9 @@ class ShareAPITest(test.TestCase):
|
||||
snapshot = copy.deepcopy(self.snapshot)
|
||||
snapshot['status'] = constants.STATUS_AVAILABLE
|
||||
body = {'revert': {'snapshot_id': '2'}}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1/action', use_admin_context=False, version='2.27')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1/action',
|
||||
use_admin_context=False,
|
||||
version='2.27')
|
||||
self.mock_object(
|
||||
self.controller, '_validate_revert_parameters',
|
||||
mock.Mock(return_value=body['revert']))
|
||||
@ -366,8 +371,9 @@ class ShareAPITest(test.TestCase):
|
||||
snapshot = copy.deepcopy(self.snapshot)
|
||||
snapshot['status'] = constants.STATUS_AVAILABLE
|
||||
body = {'revert': {'snapshot_id': '2'}}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1/action', use_admin_context=False, version='2.27')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1/action',
|
||||
use_admin_context=False,
|
||||
version='2.27')
|
||||
self.mock_object(
|
||||
self.controller, '_validate_revert_parameters',
|
||||
mock.Mock(return_value=body['revert']))
|
||||
@ -396,8 +402,9 @@ class ShareAPITest(test.TestCase):
|
||||
latest_snapshot['status'] = constants.STATUS_AVAILABLE
|
||||
latest_snapshot['id'] = '3'
|
||||
body = {'revert': {'snapshot_id': '2'}}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1/action', use_admin_context=False, version='2.27')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1/action',
|
||||
use_admin_context=False,
|
||||
version='2.27')
|
||||
self.mock_object(
|
||||
self.controller, '_validate_revert_parameters',
|
||||
mock.Mock(return_value=body['revert']))
|
||||
@ -442,8 +449,9 @@ class ShareAPITest(test.TestCase):
|
||||
def test__revert_exception(self, caught, exc_args, thrown):
|
||||
|
||||
body = {'revert': {'snapshot_id': '2'}}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1/action', use_admin_context=False, version='2.27')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1/action',
|
||||
use_admin_context=False,
|
||||
version='2.27')
|
||||
self.mock_object(
|
||||
self.controller, '_validate_revert_parameters',
|
||||
mock.Mock(return_value=body['revert']))
|
||||
@ -483,7 +491,7 @@ class ShareAPITest(test.TestCase):
|
||||
def test_share_create_original(self, microversion):
|
||||
self.mock_object(share_api.API, 'create', self.create_mock)
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version=microversion)
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares', version=microversion)
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -495,7 +503,7 @@ class ShareAPITest(test.TestCase):
|
||||
def test_share_create_with_snapshot_support_without_cg(self, microversion):
|
||||
self.mock_object(share_api.API, 'create', self.create_mock)
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version=microversion)
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares', version=microversion)
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -506,7 +514,7 @@ class ShareAPITest(test.TestCase):
|
||||
def test_share_create_with_share_group(self):
|
||||
self.mock_object(share_api.API, 'create', self.create_mock)
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version="2.31",
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares', version="2.31",
|
||||
experimental=True)
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
@ -532,7 +540,7 @@ class ShareAPITest(test.TestCase):
|
||||
"share_group_id": sg_id,
|
||||
}}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares', version="2.31", experimental=True)
|
||||
'/v2/fake/shares', version="2.31", experimental=True)
|
||||
|
||||
self.controller.create(req, body)
|
||||
|
||||
@ -570,7 +578,7 @@ class ShareAPITest(test.TestCase):
|
||||
"share_group_id": sg_id,
|
||||
}}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares', version="2.31", experimental=True)
|
||||
'/v2/fake/shares', version="2.31", experimental=True)
|
||||
|
||||
self.assertRaises(
|
||||
exception.InvalidInput, self.controller.create, req, body)
|
||||
@ -595,7 +603,7 @@ class ShareAPITest(test.TestCase):
|
||||
"share_group_id": sg_id,
|
||||
}}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares', version="2.31", experimental=True)
|
||||
'/v2/fake/shares', version="2.31", experimental=True)
|
||||
|
||||
self.assertRaises(
|
||||
webob.exc.HTTPNotFound, self.controller.create, req, body)
|
||||
@ -612,7 +620,7 @@ class ShareAPITest(test.TestCase):
|
||||
self.mock_object(share_api.API, 'create', self.create_mock)
|
||||
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version='2.7')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares', version='2.7')
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
expected = self._get_expected_share_detailed_response(self.share,
|
||||
@ -628,7 +636,7 @@ class ShareAPITest(test.TestCase):
|
||||
self.vt['name'])),
|
||||
)
|
||||
CONF.set_default("default_share_type", self.vt['name'])
|
||||
req = fakes.HTTPRequest.blank('/shares', version='2.7')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares', version='2.7')
|
||||
self.assertRaises(exception.ShareTypeNotFoundByName,
|
||||
self.controller.create, req, {'share': self.share})
|
||||
share_types.get_default_share_type.assert_called_once_with()
|
||||
@ -638,7 +646,8 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares', version=share_replicas.MIN_SUPPORTED_API_VERSION)
|
||||
'/v2/fake/shares',
|
||||
version=share_replicas.MIN_SUPPORTED_API_VERSION)
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -670,7 +679,7 @@ class ShareAPITest(test.TestCase):
|
||||
db, 'share_network_subnet_get_by_availability_zone_id')
|
||||
|
||||
body = {"share": copy.deepcopy(shr)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version='2.7')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares', version='2.7')
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
expected = self._get_expected_share_detailed_response(
|
||||
@ -684,7 +693,7 @@ class ShareAPITest(test.TestCase):
|
||||
def test_share_create_original_with_user_id(self, microversion):
|
||||
self.mock_object(share_api.API, 'create', self.create_mock)
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version=microversion)
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares', version=microversion)
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -693,10 +702,10 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
@ddt.data(test_utils.annotated('v2.0_az_unsupported', ('2.0', False)),
|
||||
test_utils.annotated('v2.0_az_supported', ('2.0', True)),
|
||||
test_utils.annotated('v2.47_az_unsupported', ('2.47', False)),
|
||||
test_utils.annotated('v2.47_az_supported', ('2.47', True)))
|
||||
@ddt.data(test_utils.annotated('/v2.0_az_unsupported', ('2.0', False)),
|
||||
test_utils.annotated('/v2.0_az_supported', ('2.0', True)),
|
||||
test_utils.annotated('/v2.47_az_unsupported', ('2.47', False)),
|
||||
test_utils.annotated('/v2.47_az_supported', ('2.47', True)))
|
||||
@ddt.unpack
|
||||
def test_share_create_with_share_type_azs(self, version, az_supported):
|
||||
"""For API version<2.48, AZ validation should not be performed."""
|
||||
@ -709,7 +718,7 @@ class ShareAPITest(test.TestCase):
|
||||
self.mock_object(share_types, 'get_share_type', mock.Mock(
|
||||
return_value=stype_with_azs))
|
||||
|
||||
req = fakes.HTTPRequest.blank('/shares', version=version)
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares', version=version)
|
||||
|
||||
res_dict = self.controller.create(req, {'share': create_args})
|
||||
|
||||
@ -742,7 +751,7 @@ class ShareAPITest(test.TestCase):
|
||||
self.mock_object(share_api.API, 'get_snapshot',
|
||||
stubs.stub_snapshot_get)
|
||||
|
||||
req = fakes.HTTPRequest.blank('/shares', version=version)
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares', version=version)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.create,
|
||||
@ -753,8 +762,10 @@ class ShareAPITest(test.TestCase):
|
||||
share = db_utils.create_share()
|
||||
share_network = db_utils.create_share_network()
|
||||
share_type = {'share_type_id': 'fake_type_id'}
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.29')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.29')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request.experimental = True
|
||||
@ -797,8 +808,8 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_migration_start_conflict(self):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True)
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'], use_admin_context=True)
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request = api_version.APIVersionRequest('2.29')
|
||||
@ -825,7 +836,8 @@ class ShareAPITest(test.TestCase):
|
||||
'preserve_snapshots', 'host', 'body')
|
||||
def test_migration_start_missing_mandatory(self, param):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.29')
|
||||
req.method = 'POST'
|
||||
@ -861,7 +873,8 @@ class ShareAPITest(test.TestCase):
|
||||
'preserve_snapshots', 'force_host_assisted_migration')
|
||||
def test_migration_start_non_boolean(self, param):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.29')
|
||||
req.method = 'POST'
|
||||
@ -891,7 +904,7 @@ class ShareAPITest(test.TestCase):
|
||||
req, 'fake_id', body)
|
||||
|
||||
def test_migration_start_no_share_id(self):
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % 'fake_id',
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/%s/action' % 'fake_id',
|
||||
use_admin_context=True, version='2.29')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
@ -908,8 +921,10 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_migration_start_new_share_network_not_found(self):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.29')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.29')
|
||||
context = req.environ['manila.context']
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
@ -933,8 +948,10 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_migration_start_new_share_type_not_found(self):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.29')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.29')
|
||||
context = req.environ['manila.context']
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
@ -958,8 +975,10 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_migration_start_invalid_force_host_assisted_migration(self):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.29')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.29')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request.experimental = True
|
||||
@ -976,8 +995,10 @@ class ShareAPITest(test.TestCase):
|
||||
def test_migration_start_invalid_writable_preserve_metadata(
|
||||
self, parameter):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.29')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.29')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request.experimental = True
|
||||
@ -992,8 +1013,10 @@ class ShareAPITest(test.TestCase):
|
||||
@ddt.data(constants.TASK_STATE_MIGRATION_ERROR, None)
|
||||
def test_reset_task_state(self, task_state):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.22')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.22')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request.experimental = True
|
||||
@ -1012,8 +1035,10 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_reset_task_state_error_body(self):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.22')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.22')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request.experimental = True
|
||||
@ -1027,8 +1052,10 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_reset_task_state_error_invalid(self):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.22')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.22')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request.experimental = True
|
||||
@ -1042,8 +1069,10 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_reset_task_state_not_found(self):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.22')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.22')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request.experimental = True
|
||||
@ -1063,8 +1092,10 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_migration_complete(self):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.22')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.22')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request.experimental = True
|
||||
@ -1085,8 +1116,10 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_migration_complete_not_found(self):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.22')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.22')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request.experimental = True
|
||||
@ -1103,8 +1136,10 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_migration_cancel(self):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.22')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.22')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request.experimental = True
|
||||
@ -1125,8 +1160,10 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_migration_cancel_not_found(self):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.22')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.22')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request.experimental = True
|
||||
@ -1144,8 +1181,10 @@ class ShareAPITest(test.TestCase):
|
||||
def test_migration_get_progress(self):
|
||||
share = db_utils.create_share(
|
||||
task_state=constants.TASK_STATE_MIGRATION_SUCCESS)
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.22')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.22')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request.experimental = True
|
||||
@ -1172,8 +1211,10 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_migration_get_progress_not_found(self):
|
||||
share = db_utils.create_share()
|
||||
req = fakes.HTTPRequest.blank('/shares/%s/action' % share['id'],
|
||||
use_admin_context=True, version='2.22')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/shares/%s/action' % share['id'],
|
||||
use_admin_context=True,
|
||||
version='2.22')
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
req.api_version_request.experimental = True
|
||||
@ -1209,7 +1250,7 @@ class ShareAPITest(test.TestCase):
|
||||
share_network_id=shr['share_network_id'])))
|
||||
self.mock_object(share_api.API, 'create', create_mock)
|
||||
body = {"share": copy.deepcopy(shr)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version='2.7')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares', version='2.7')
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -1251,7 +1292,7 @@ class ShareAPITest(test.TestCase):
|
||||
db, 'share_network_subnet_get_by_availability_zone_id')
|
||||
|
||||
body = {"share": copy.deepcopy(shr)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version='2.7')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares', version='2.7')
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
@ -1296,7 +1337,7 @@ class ShareAPITest(test.TestCase):
|
||||
db, 'share_network_subnet_get_by_availability_zone_id')
|
||||
|
||||
body = {"share": copy.deepcopy(shr)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version='2.7')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares', version='2.7')
|
||||
res_dict = self.controller.create(req, body)
|
||||
expected = self._get_expected_share_detailed_response(
|
||||
shr, version='2.7')
|
||||
@ -1317,7 +1358,7 @@ class ShareAPITest(test.TestCase):
|
||||
"share_network_id": 1234,
|
||||
}
|
||||
body = {"share": shr}
|
||||
req = fakes.HTTPRequest.blank('/shares', version='2.7')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares', version='2.7')
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.create, req, body)
|
||||
|
||||
@ -1370,14 +1411,14 @@ class ShareAPITest(test.TestCase):
|
||||
)
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
|
||||
req = fakes.HTTPRequest.blank('/shares', version='2.7')
|
||||
req = fakes.HTTPRequest.blank('/v2/shares', version='2.7')
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.create,
|
||||
req,
|
||||
body)
|
||||
|
||||
def test_share_show(self):
|
||||
req = fakes.HTTPRequest.blank('/shares/1')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1')
|
||||
expected = self._get_expected_share_detailed_response()
|
||||
|
||||
res_dict = self.controller.show(req, '1')
|
||||
@ -1386,7 +1427,7 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_share_show_with_share_group(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1', version='2.31', experimental=True)
|
||||
'/v2/fake/shares/1', version='2.31', experimental=True)
|
||||
expected = self._get_expected_share_detailed_response(version='2.31')
|
||||
|
||||
res_dict = self.controller.show(req, '1')
|
||||
@ -1395,7 +1436,7 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_share_show_with_share_group_earlier_version(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1', version='2.23', experimental=True)
|
||||
'/v2/fake/shares/1', version='2.23', experimental=True)
|
||||
expected = self._get_expected_share_detailed_response(version='2.23')
|
||||
|
||||
res_dict = self.controller.show(req, '1')
|
||||
@ -1403,7 +1444,7 @@ class ShareAPITest(test.TestCase):
|
||||
self.assertDictMatch(expected, res_dict)
|
||||
|
||||
def test_share_show_with_share_type_name(self):
|
||||
req = fakes.HTTPRequest.blank('/shares/1', version='2.6')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1', version='2.6')
|
||||
|
||||
res_dict = self.controller.show(req, '1')
|
||||
|
||||
@ -1412,7 +1453,8 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
@ddt.data("2.15", "2.16")
|
||||
def test_share_show_with_user_id(self, microversion):
|
||||
req = fakes.HTTPRequest.blank('/shares/1', version=microversion)
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1',
|
||||
version=microversion)
|
||||
|
||||
res_dict = self.controller.show(req, '1')
|
||||
|
||||
@ -1422,7 +1464,8 @@ class ShareAPITest(test.TestCase):
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
def test_share_show_admin(self):
|
||||
req = fakes.HTTPRequest.blank('/shares/1', use_admin_context=True)
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1',
|
||||
use_admin_context=True)
|
||||
expected = self._get_expected_share_detailed_response(admin=True)
|
||||
|
||||
res_dict = self.controller.show(req, '1')
|
||||
@ -1432,18 +1475,17 @@ class ShareAPITest(test.TestCase):
|
||||
def test_share_show_no_share(self):
|
||||
self.mock_object(share_api.API, 'get',
|
||||
stubs.stub_share_get_notfound)
|
||||
req = fakes.HTTPRequest.blank('/shares/1')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1')
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.show,
|
||||
req, '1')
|
||||
|
||||
def test_share_show_with_replication_type(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1', version=share_replicas.MIN_SUPPORTED_API_VERSION)
|
||||
api_vers = share_replicas.MIN_SUPPORTED_API_VERSION
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1', version=api_vers)
|
||||
res_dict = self.controller.show(req, '1')
|
||||
|
||||
expected = self._get_expected_share_detailed_response(
|
||||
version=share_replicas.MIN_SUPPORTED_API_VERSION)
|
||||
expected = self._get_expected_share_detailed_response(version=api_vers)
|
||||
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
@ -1456,7 +1498,7 @@ class ShareAPITest(test.TestCase):
|
||||
status=constants.STATUS_AVAILABLE)
|
||||
self.mock_object(share_api.API, 'get', mock.Mock(return_value=share))
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/%s' % share['id'], version=version)
|
||||
'/v2/fake/shares/%s' % share['id'], version=version)
|
||||
|
||||
res_dict = self.controller.show(req, share['id'])
|
||||
|
||||
@ -1466,12 +1508,12 @@ class ShareAPITest(test.TestCase):
|
||||
self.assertEqual(expected, res_dict['share']['access_rules_status'])
|
||||
|
||||
def test_share_delete(self):
|
||||
req = fakes.HTTPRequest.blank('/shares/1')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1')
|
||||
resp = self.controller.delete(req, 1)
|
||||
self.assertEqual(202, resp.status_int)
|
||||
|
||||
def test_share_delete_has_replicas(self):
|
||||
req = fakes.HTTPRequest.blank('/shares/1')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1')
|
||||
self.mock_object(share_api.API, 'get',
|
||||
mock.Mock(return_value=self.share))
|
||||
self.mock_object(share_api.API, 'delete',
|
||||
@ -1485,7 +1527,7 @@ class ShareAPITest(test.TestCase):
|
||||
share_group_id='fake_group_id')
|
||||
self.mock_object(share_api.API, 'get',
|
||||
mock.Mock(return_value=fake_share))
|
||||
req = fakes.HTTPRequest.blank('/shares/1')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1')
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.delete, req, 1)
|
||||
|
||||
@ -1495,7 +1537,7 @@ class ShareAPITest(test.TestCase):
|
||||
self.mock_object(share_api.API, 'get',
|
||||
mock.Mock(return_value=fake_share))
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1?share_group_id=fake_group_id')
|
||||
'/v2/fake/shares/1?share_group_id=fake_group_id')
|
||||
resp = self.controller.delete(req, 1)
|
||||
self.assertEqual(202, resp.status_int)
|
||||
|
||||
@ -1505,7 +1547,7 @@ class ShareAPITest(test.TestCase):
|
||||
self.mock_object(share_api.API, 'get',
|
||||
mock.Mock(return_value=fake_share))
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1?share_group_id=not_fake_group_id')
|
||||
'/v2/fake/shares/1?share_group_id=not_fake_group_id')
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.delete, req, 1)
|
||||
|
||||
@ -1513,7 +1555,7 @@ class ShareAPITest(test.TestCase):
|
||||
shr = self.share
|
||||
body = {"share": shr}
|
||||
|
||||
req = fakes.HTTPRequest.blank('/share/1')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/share/1')
|
||||
res_dict = self.controller.update(req, 1, body)
|
||||
self.assertEqual(shr["display_name"], res_dict['share']["name"])
|
||||
self.assertEqual(shr["display_description"],
|
||||
@ -1526,7 +1568,7 @@ class ShareAPITest(test.TestCase):
|
||||
body = {"share": shr}
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/share/1', version="2.31", experimental=True)
|
||||
'/v2/fake/share/1', version="2.31", experimental=True)
|
||||
|
||||
res_dict = self.controller.update(req, 1, body)
|
||||
|
||||
@ -1535,14 +1577,14 @@ class ShareAPITest(test.TestCase):
|
||||
res_dict['share']["source_share_group_snapshot_member_id"])
|
||||
|
||||
def test_share_not_updates_size(self):
|
||||
req = fakes.HTTPRequest.blank('/share/1')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/share/1')
|
||||
res_dict = self.controller.update(req, 1, {"share": self.share})
|
||||
self.assertNotEqual(res_dict['share']["size"], self.share["size"])
|
||||
|
||||
def test_share_delete_no_share(self):
|
||||
self.mock_object(share_api.API, 'get',
|
||||
stubs.stub_share_get_notfound)
|
||||
req = fakes.HTTPRequest.blank('/shares/1')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1')
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.delete,
|
||||
req,
|
||||
@ -1587,7 +1629,7 @@ class ShareAPITest(test.TestCase):
|
||||
if use_admin_context:
|
||||
search_opts['host'] = 'fake_host'
|
||||
# fake_key should be filtered for non-admin
|
||||
url = '/shares?fake_key=fake_value'
|
||||
url = '/v2/fake/shares?fake_key=fake_value'
|
||||
for k, v in search_opts.items():
|
||||
url = url + '&' + k + '=' + v
|
||||
req = fakes.HTTPRequest.blank(url, version=version,
|
||||
@ -1659,7 +1701,7 @@ class ShareAPITest(test.TestCase):
|
||||
if use_admin_context:
|
||||
search_opts['host'] = 'fake_host'
|
||||
# fake_key should be filtered
|
||||
url = '/shares?fake_key=fake_value'
|
||||
url = '/v2/fake/shares?fake_key=fake_value'
|
||||
for k, v in search_opts.items():
|
||||
url = url + '&' + k + '=' + v
|
||||
req = fakes.HTTPRequest.blank(url, version=version,
|
||||
@ -1687,7 +1729,7 @@ class ShareAPITest(test.TestCase):
|
||||
def test_share_list_summary(self):
|
||||
self.mock_object(share_api.API, 'get_all',
|
||||
stubs.stub_share_get_all_by_project)
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares')
|
||||
res_dict = self.controller.index(req)
|
||||
expected = {
|
||||
'shares': [
|
||||
@ -1696,11 +1738,11 @@ class ShareAPITest(test.TestCase):
|
||||
'id': '1',
|
||||
'links': [
|
||||
{
|
||||
'href': 'http://localhost/v1/fake/shares/1',
|
||||
'href': 'http://localhost/share/v2/fake/shares/1',
|
||||
'rel': 'self'
|
||||
},
|
||||
{
|
||||
'href': 'http://localhost/fake/shares/1',
|
||||
'href': 'http://localhost/share/fake/shares/1',
|
||||
'rel': 'bookmark'
|
||||
}
|
||||
],
|
||||
@ -1741,7 +1783,7 @@ class ShareAPITest(test.TestCase):
|
||||
if use_admin_context:
|
||||
search_opts['host'] = 'fake_host'
|
||||
# fake_key should be filtered for non-admin
|
||||
url = '/shares/detail?fake_key=fake_value'
|
||||
url = '/v2/fake/shares/detail?fake_key=fake_value'
|
||||
for k, v in search_opts.items():
|
||||
url = url + '&' + k + '=' + v
|
||||
req = fakes.HTTPRequest.blank(url, version=version,
|
||||
@ -1844,11 +1886,11 @@ class ShareAPITest(test.TestCase):
|
||||
'is_public': False,
|
||||
'links': [
|
||||
{
|
||||
'href': 'http://localhost/v1/fake/shares/1',
|
||||
'href': 'http://localhost/share/v2/fake/shares/1',
|
||||
'rel': 'self'
|
||||
},
|
||||
{
|
||||
'href': 'http://localhost/fake/shares/1',
|
||||
'href': 'http://localhost/share/fake/shares/1',
|
||||
'rel': 'bookmark'
|
||||
}
|
||||
],
|
||||
@ -1867,15 +1909,17 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_share_list_detail(self):
|
||||
env = {'QUERY_STRING': 'name=Share+Test+Name'}
|
||||
req = fakes.HTTPRequest.blank('/shares/detail', environ=env)
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/detail', environ=env)
|
||||
expected = self._list_detail_common_expected()
|
||||
expected['shares'][0].pop('snapshot_support')
|
||||
self._list_detail_test_common(req, expected)
|
||||
|
||||
def test_share_list_detail_with_share_group(self):
|
||||
env = {'QUERY_STRING': 'name=Share+Test+Name'}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/detail', environ=env, version="2.31", experimental=True)
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/detail',
|
||||
environ=env,
|
||||
version="2.31",
|
||||
experimental=True)
|
||||
expected = self._list_detail_common_expected()
|
||||
expected['shares'][0]['task_state'] = None
|
||||
expected['shares'][0]['share_type_name'] = None
|
||||
@ -1893,7 +1937,7 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_share_list_detail_with_task_state(self):
|
||||
env = {'QUERY_STRING': 'name=Share+Test+Name'}
|
||||
req = fakes.HTTPRequest.blank('/shares/detail', environ=env,
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/detail', environ=env,
|
||||
version="2.5")
|
||||
expected = self._list_detail_common_expected()
|
||||
expected['shares'][0]['task_state'] = None
|
||||
@ -1901,7 +1945,7 @@ class ShareAPITest(test.TestCase):
|
||||
|
||||
def test_share_list_detail_without_export_locations(self):
|
||||
env = {'QUERY_STRING': 'name=Share+Test+Name'}
|
||||
req = fakes.HTTPRequest.blank('/shares/detail', environ=env,
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/detail', environ=env,
|
||||
version="2.9")
|
||||
expected = self._list_detail_common_expected()
|
||||
expected['shares'][0]['task_state'] = None
|
||||
@ -1915,7 +1959,7 @@ class ShareAPITest(test.TestCase):
|
||||
stubs.stub_share_get_all_by_project)
|
||||
env = {'QUERY_STRING': 'name=Share+Test+Name'}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/detail', environ=env,
|
||||
'/v2/fake/shares/detail', environ=env,
|
||||
version=share_replicas.MIN_SUPPORTED_API_VERSION)
|
||||
res_dict = self.controller.detail(req)
|
||||
expected = {
|
||||
@ -1944,11 +1988,11 @@ class ShareAPITest(test.TestCase):
|
||||
'task_state': None,
|
||||
'links': [
|
||||
{
|
||||
'href': 'http://localhost/v1/fake/shares/1',
|
||||
'href': 'http://localhost/share/v2/fake/shares/1',
|
||||
'rel': 'self'
|
||||
},
|
||||
{
|
||||
'href': 'http://localhost/fake/shares/1',
|
||||
'href': 'http://localhost/share/fake/shares/1',
|
||||
'rel': 'bookmark'
|
||||
}
|
||||
],
|
||||
@ -2292,7 +2336,7 @@ class ShareActionsTest(test.TestCase):
|
||||
|
||||
id = 'fake_share_id'
|
||||
body = {"os-deny_access": {"access_id": 'fake_acces_id'}}
|
||||
req = fakes.HTTPRequest.blank('/v1/tenant1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/v2/tenant1/shares/%s/action' % id)
|
||||
res = self.controller._deny_access(req, id, body)
|
||||
self.assertEqual(202, res.status_int)
|
||||
|
||||
@ -2305,7 +2349,7 @@ class ShareActionsTest(test.TestCase):
|
||||
|
||||
id = 'super_fake_share_id'
|
||||
body = {"os-deny_access": {"access_id": 'fake_acces_id'}}
|
||||
req = fakes.HTTPRequest.blank('/v1/tenant1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/v2/tenant1/shares/%s/action' % id)
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller._deny_access,
|
||||
req,
|
||||
@ -2357,7 +2401,7 @@ class ShareActionsTest(test.TestCase):
|
||||
{"os-extend": {"new_size": {'foo': 'bar'}}})
|
||||
def test_extend_invalid_body(self, body):
|
||||
id = 'fake_share_id'
|
||||
req = fakes.HTTPRequest.blank('/v1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/v2/shares/%s/action' % id)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller._extend, req, id, body)
|
||||
@ -2371,7 +2415,7 @@ class ShareActionsTest(test.TestCase):
|
||||
@ddt.unpack
|
||||
def test_extend_exception(self, source, target):
|
||||
id = 'fake_share_id'
|
||||
req = fakes.HTTPRequest.blank('/v1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/v2/shares/%s/action' % id)
|
||||
body = {"os-extend": {'new_size': '123'}}
|
||||
self.mock_object(share_api.API, "extend",
|
||||
mock.Mock(side_effect=source('fake')))
|
||||
@ -2404,7 +2448,7 @@ class ShareActionsTest(test.TestCase):
|
||||
{"os-shrink": {"new_size": {'foo': 'bar'}}})
|
||||
def test_shrink_invalid_body(self, body):
|
||||
id = 'fake_share_id'
|
||||
req = fakes.HTTPRequest.blank('/v1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/v2/shares/%s/action' % id)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller._shrink, req, id, body)
|
||||
@ -2416,7 +2460,7 @@ class ShareActionsTest(test.TestCase):
|
||||
@ddt.unpack
|
||||
def test_shrink_exception(self, source, target):
|
||||
id = 'fake_share_id'
|
||||
req = fakes.HTTPRequest.blank('/v1/shares/%s/action' % id)
|
||||
req = fakes.HTTPRequest.blank('/v2/shares/%s/action' % id)
|
||||
body = {"os-shrink": {'new_size': '123'}}
|
||||
self.mock_object(share_api.API, "shrink",
|
||||
mock.Mock(side_effect=source('fake')))
|
||||
@ -2561,7 +2605,7 @@ class ShareUnmanageTest(test.TestCase):
|
||||
stubs.stub_snapshot_get)
|
||||
self.share_id = 'fake'
|
||||
self.request = fakes.HTTPRequest.blank(
|
||||
'/share/%s/unmanage' % self.share_id,
|
||||
'/v2/fake/share/%s/unmanage' % self.share_id,
|
||||
use_admin_context=True, version='2.7',
|
||||
)
|
||||
|
||||
@ -2587,8 +2631,9 @@ class ShareUnmanageTest(test.TestCase):
|
||||
|
||||
def test__unmanage(self):
|
||||
body = {}
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/1/action', use_admin_context=False, version='2.49')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/1/action',
|
||||
use_admin_context=False,
|
||||
version='2.49')
|
||||
share = dict(status=constants.STATUS_AVAILABLE, id='foo_id',
|
||||
instance={})
|
||||
mock_unmanage = self.mock_object(self.controller, '_unmanage')
|
||||
@ -2673,7 +2718,7 @@ class ShareUnmanageTest(test.TestCase):
|
||||
|
||||
def test_wrong_permissions(self):
|
||||
share_id = 'fake'
|
||||
req = fakes.HTTPRequest.blank('/share/%s/unmanage' % share_id,
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/share/%s/unmanage' % share_id,
|
||||
use_admin_context=False, version='2.7')
|
||||
|
||||
self.assertRaises(webob.exc.HTTPForbidden,
|
||||
@ -2683,7 +2728,7 @@ class ShareUnmanageTest(test.TestCase):
|
||||
|
||||
def test_unsupported_version(self):
|
||||
share_id = 'fake'
|
||||
req = fakes.HTTPRequest.blank('/share/%s/unmanage' % share_id,
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/share/%s/unmanage' % share_id,
|
||||
use_admin_context=False, version='2.6')
|
||||
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
@ -2867,11 +2912,11 @@ class ShareManageTest(test.TestCase):
|
||||
'task_state': None,
|
||||
'links': [
|
||||
{
|
||||
'href': 'http://localhost/v1/fake/shares/fake',
|
||||
'href': 'http://localhost/share/v2/fake/shares/fake',
|
||||
'rel': 'self'
|
||||
},
|
||||
{
|
||||
'href': 'http://localhost/fake/shares/fake',
|
||||
'href': 'http://localhost/share/fake/shares/fake',
|
||||
'rel': 'bookmark'
|
||||
}
|
||||
],
|
||||
@ -2923,7 +2968,8 @@ class ShareManageTest(test.TestCase):
|
||||
api_version.APIVersionRequest('2.8')):
|
||||
share['is_public'] = data['share']['is_public']
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v2/shares/manage', version=version,
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/manage',
|
||||
version=version,
|
||||
use_admin_context=True)
|
||||
|
||||
actual_result = self.controller.manage(req, data)
|
||||
@ -2942,15 +2988,16 @@ class ShareManageTest(test.TestCase):
|
||||
self.assertRaises(
|
||||
webob.exc.HTTPForbidden,
|
||||
self.controller.manage,
|
||||
fakes.HTTPRequest.blank(
|
||||
'/share/manage', use_admin_context=False, version='2.7'),
|
||||
fakes.HTTPRequest.blank('/v2/fake/share/manage',
|
||||
use_admin_context=False,
|
||||
version='2.7'),
|
||||
body,
|
||||
)
|
||||
|
||||
def test_unsupported_version(self):
|
||||
share_id = 'fake'
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/share/manage', use_admin_context=False, version='2.6')
|
||||
'/v2/fake/share/manage', use_admin_context=False, version='2.6')
|
||||
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
self.controller.manage,
|
||||
@ -2962,8 +3009,9 @@ class ShareManageTest(test.TestCase):
|
||||
mock_revert = self.mock_object(
|
||||
self.controller, '_revert',
|
||||
mock.Mock(return_value='fake_response'))
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/fake_id/action', use_admin_context=False, version='2.27')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/shares/fake_id/action',
|
||||
use_admin_context=False,
|
||||
version='2.27')
|
||||
|
||||
result = self.controller.revert(req, 'fake_id', 'fake_body')
|
||||
|
||||
@ -2973,8 +3021,9 @@ class ShareManageTest(test.TestCase):
|
||||
|
||||
def test_revert_unsupported(self):
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/shares/fake_id/action', use_admin_context=False, version='2.24')
|
||||
req = fakes.HTTPRequest.blank('/v2/shares/fake_id/action',
|
||||
use_admin_context=False,
|
||||
version='2.24')
|
||||
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
self.controller.revert,
|
||||
|
@ -41,6 +41,8 @@ def set_defaults(conf):
|
||||
'etc/manila/api-paste.ini'))
|
||||
wsgi.register_opts(conf)
|
||||
_safe_set_of_opts(conf, 'api_paste_config', _API_PASTE_PATH)
|
||||
# we use "fake" and "openstack" as project ID in a number of tests
|
||||
_safe_set_of_opts(conf, 'project_id_regex', r"[0-9a-fopnstk\-]+")
|
||||
_safe_set_of_opts(conf, 'share_driver',
|
||||
'manila.tests.fake_driver.FakeShareDriver')
|
||||
_safe_set_of_opts(conf, 'auth_strategy', 'noauth')
|
||||
|
@ -175,8 +175,10 @@ def fake_snapshot_instance(base_snapshot=None, as_primitive=False, **kwargs):
|
||||
|
||||
|
||||
def expected_snapshot(version=None, id='fake_snapshot_id', **kwargs):
|
||||
self_link = 'http://localhost/v1/fake/snapshots/%s' % id
|
||||
bookmark_link = 'http://localhost/fake/snapshots/%s' % id
|
||||
api_major_version = 'v2' if version and version.startswith('2.') else 'v1'
|
||||
self_link = 'http://localhost/share/%s/fake/snapshots/%s' % (
|
||||
api_major_version, id)
|
||||
bookmark_link = 'http://localhost/share/fake/snapshots/%s' % id
|
||||
snapshot = {
|
||||
'id': id,
|
||||
'share_id': 'fakeshareid',
|
||||
|
@ -71,12 +71,12 @@ class TestOpenStackClient(object):
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, auth_user, auth_key, www_authenticate_uri):
|
||||
def __init__(self, auth_user, auth_key, endpoint):
|
||||
super(TestOpenStackClient, self).__init__()
|
||||
self.auth_result = None
|
||||
self.auth_user = auth_user
|
||||
self.auth_key = auth_key
|
||||
self.www_authenticate_uri = www_authenticate_uri
|
||||
self.endpoint = endpoint
|
||||
# default project_id
|
||||
self.project_id = 'openstack'
|
||||
|
||||
@ -114,16 +114,15 @@ class TestOpenStackClient(object):
|
||||
if self.auth_result:
|
||||
return self.auth_result
|
||||
|
||||
www_authenticate_uri = self.www_authenticate_uri
|
||||
headers = {'X-Auth-User': self.auth_user,
|
||||
'X-Auth-Key': self.auth_key,
|
||||
'X-Auth-Project-Id': self.project_id}
|
||||
response = self.request(www_authenticate_uri,
|
||||
response = self.request(self.endpoint,
|
||||
headers=headers)
|
||||
|
||||
http_status = response.status
|
||||
LOG.debug("%(www_authenticate_uri)s => code %(http_status)s.",
|
||||
{"www_authenticate_uri": www_authenticate_uri,
|
||||
LOG.debug("%(endpoint)s => code %(http_status)s.",
|
||||
{"endpoint": self.endpoint,
|
||||
"http_status": http_status})
|
||||
|
||||
if http_status == 401:
|
||||
|
@ -65,12 +65,12 @@ class _IntegratedTestBase(test.TestCase):
|
||||
self.flags(**f)
|
||||
|
||||
# set up services
|
||||
self.volume = self.start_service('share')
|
||||
self.share = self.start_service('share')
|
||||
self.scheduler = self.start_service('scheduler')
|
||||
|
||||
self._start_api_service()
|
||||
|
||||
self.api = client.TestOpenStackClient('fake', 'fake', self.auth_url)
|
||||
self.api = client.TestOpenStackClient('fake', 'fake', self.endpoint)
|
||||
|
||||
def tearDown(self):
|
||||
self.osapi.stop()
|
||||
@ -79,10 +79,9 @@ class _IntegratedTestBase(test.TestCase):
|
||||
def _start_api_service(self):
|
||||
self.osapi = service.WSGIService("osapi_share")
|
||||
self.osapi.start()
|
||||
# FIXME(ja): this is not the auth url - this is the service url
|
||||
# FIXME(ja): this needs fixed in nova as well
|
||||
self.auth_url = 'http://%s:%s/v1' % (self.osapi.host, self.osapi.port)
|
||||
LOG.warning(self.auth_url)
|
||||
self.endpoint = 'http://%s:%s/v2' % (self.osapi.host,
|
||||
self.osapi.port)
|
||||
LOG.info("Manila API started at %s", self.endpoint)
|
||||
|
||||
def _get_flags(self):
|
||||
"""An opportunity to setup flags, before the services are started."""
|
||||
|
@ -0,0 +1,26 @@
|
||||
---
|
||||
prelude: >
|
||||
Manila v2 API URLs no longer require a project_id to be specified.
|
||||
features:
|
||||
- |
|
||||
It is now possible to omit the %{project_id}s from the API endpoints for
|
||||
the v2 API. While the behavior of the APIs have not been altered, the
|
||||
service recognizes URLs with and without project ids in the path. It is
|
||||
recommended that you adjust the service catalog in your cloud to remove
|
||||
the project_id substitution, especially if you would like to enable
|
||||
users operating at system scope.
|
||||
- |
|
||||
A new "noauth" auth strategy is available, and is named "noauthv2".
|
||||
It can be enabled by setting the configuration option
|
||||
``[DEFAULT]/auth_strategy`` to ``noauthv2``. This auth strategy can be
|
||||
used when project_id substitution is removed from the manila endpoint URL.
|
||||
upgrade:
|
||||
- |
|
||||
In order to make project_id optional in urls, the possible values of
|
||||
project_id had to be constrained. A new configuration option called
|
||||
``project_id_regex`` has been added in the ``[DEFAULT]`` section. The
|
||||
default value for this option is ``[0-9a-f\-]+`` and it matches hex
|
||||
UUIDs with and without dashes, therefore covering the formats supported
|
||||
by the OpenStack Identity service. If your cloud uses other formats, set
|
||||
this configuration option accordingly, or remove project_id from the
|
||||
manila endpoint URL in your service catalog.
|
Loading…
Reference in New Issue
Block a user