diff --git a/nova/api/openstack/compute/__init__.py b/nova/api/openstack/compute/__init__.py index eee14b4bb3cc..cc9d11ef381d 100644 --- a/nova/api/openstack/compute/__init__.py +++ b/nova/api/openstack/compute/__init__.py @@ -21,17 +21,20 @@ WSGI middleware for OpenStack Compute API. from oslo_config import cfg import nova.api.openstack -from nova.api.openstack.compute import consoles -from nova.api.openstack.compute import extensions -from nova.api.openstack.compute import flavors -from nova.api.openstack.compute import image_metadata -from nova.api.openstack.compute import images -from nova.api.openstack.compute import ips -from nova.api.openstack.compute import limits +from nova.api.openstack.compute.legacy_v2 import consoles as v2_consoles +from nova.api.openstack.compute.legacy_v2 import extensions as v2_extensions +from nova.api.openstack.compute.legacy_v2 import flavors as v2_flavors +from nova.api.openstack.compute.legacy_v2 import image_metadata \ + as v2_image_metadata +from nova.api.openstack.compute.legacy_v2 import images as v2_images +from nova.api.openstack.compute.legacy_v2 import ips as v2_ips +from nova.api.openstack.compute.legacy_v2 import limits as v2_limits +from nova.api.openstack.compute.legacy_v2 import server_metadata \ + as v2_server_metadata +from nova.api.openstack.compute.legacy_v2 import servers as v2_servers +from nova.api.openstack.compute.legacy_v2 import versions as \ + legacy_v2_versions from nova.api.openstack.compute import plugins -from nova.api.openstack.compute import server_metadata -from nova.api.openstack.compute import servers -from nova.api.openstack.compute import versions allow_instance_snapshots_opt = cfg.BoolOpt('allow_instance_snapshots', default=True, @@ -45,11 +48,11 @@ class APIRouter(nova.api.openstack.APIRouter): """Routes requests on the OpenStack API to the appropriate controller and method. """ - ExtensionManager = extensions.ExtensionManager + ExtensionManager = v2_extensions.ExtensionManager def _setup_routes(self, mapper, ext_mgr, init_only): if init_only is None or 'versions' in init_only: - self.resources['versions'] = versions.create_resource() + self.resources['versions'] = legacy_v2_versions.create_resource() mapper.connect("versions", "/", controller=self.resources['versions'], action='show', @@ -58,7 +61,7 @@ class APIRouter(nova.api.openstack.APIRouter): mapper.redirect("", "/") if init_only is None or 'consoles' in init_only: - self.resources['consoles'] = consoles.create_resource() + self.resources['consoles'] = v2_consoles.create_resource() mapper.resource("console", "consoles", controller=self.resources['consoles'], parent_resource=dict(member_name='server', @@ -66,38 +69,39 @@ class APIRouter(nova.api.openstack.APIRouter): if init_only is None or 'consoles' in init_only or \ 'servers' in init_only or 'ips' in init_only: - self.resources['servers'] = servers.create_resource(ext_mgr) + self.resources['servers'] = v2_servers.create_resource(ext_mgr) mapper.resource("server", "servers", controller=self.resources['servers'], collection={'detail': 'GET'}, member={'action': 'POST'}) if init_only is None or 'ips' in init_only: - self.resources['ips'] = ips.create_resource() + self.resources['ips'] = v2_ips.create_resource() mapper.resource("ip", "ips", controller=self.resources['ips'], parent_resource=dict(member_name='server', collection_name='servers')) if init_only is None or 'images' in init_only: - self.resources['images'] = images.create_resource() + self.resources['images'] = v2_images.create_resource() mapper.resource("image", "images", controller=self.resources['images'], collection={'detail': 'GET'}) if init_only is None or 'limits' in init_only: - self.resources['limits'] = limits.create_resource() + self.resources['limits'] = v2_limits.create_resource() mapper.resource("limit", "limits", controller=self.resources['limits']) if init_only is None or 'flavors' in init_only: - self.resources['flavors'] = flavors.create_resource() + self.resources['flavors'] = v2_flavors.create_resource() mapper.resource("flavor", "flavors", controller=self.resources['flavors'], collection={'detail': 'GET'}, member={'action': 'POST'}) if init_only is None or 'image_metadata' in init_only: - self.resources['image_metadata'] = image_metadata.create_resource() + v2immeta = v2_image_metadata + self.resources['image_metadata'] = v2immeta.create_resource() image_metadata_controller = self.resources['image_metadata'] mapper.resource("image_meta", "metadata", @@ -113,7 +117,7 @@ class APIRouter(nova.api.openstack.APIRouter): if init_only is None or 'server_metadata' in init_only: self.resources['server_metadata'] = \ - server_metadata.create_resource() + v2_server_metadata.create_resource() server_metadata_controller = self.resources['server_metadata'] mapper.resource("server_meta", "metadata", diff --git a/nova/api/openstack/compute/contrib/config_drive.py b/nova/api/openstack/compute/contrib/config_drive.py index fefdecc937d7..bd7ff41915f5 100644 --- a/nova/api/openstack/compute/contrib/config_drive.py +++ b/nova/api/openstack/compute/contrib/config_drive.py @@ -15,7 +15,7 @@ """Config Drive extension.""" -from nova.api.openstack.compute import servers +from nova.api.openstack.compute.legacy_v2 import servers from nova.api.openstack import extensions from nova.api.openstack import wsgi diff --git a/nova/api/openstack/compute/contrib/keypairs.py b/nova/api/openstack/compute/contrib/keypairs.py index 5b89ba4ba3f2..d4a34d035e0a 100644 --- a/nova/api/openstack/compute/contrib/keypairs.py +++ b/nova/api/openstack/compute/contrib/keypairs.py @@ -18,7 +18,7 @@ import webob import webob.exc -from nova.api.openstack.compute import servers +from nova.api.openstack.compute.legacy_v2 import servers from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova.compute import api as compute_api diff --git a/nova/api/openstack/compute/legacy_v2/__init__.py b/nova/api/openstack/compute/legacy_v2/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/nova/api/openstack/compute/consoles.py b/nova/api/openstack/compute/legacy_v2/consoles.py similarity index 100% rename from nova/api/openstack/compute/consoles.py rename to nova/api/openstack/compute/legacy_v2/consoles.py diff --git a/nova/api/openstack/compute/extensions.py b/nova/api/openstack/compute/legacy_v2/extensions.py similarity index 100% rename from nova/api/openstack/compute/extensions.py rename to nova/api/openstack/compute/legacy_v2/extensions.py diff --git a/nova/api/openstack/compute/flavors.py b/nova/api/openstack/compute/legacy_v2/flavors.py similarity index 100% rename from nova/api/openstack/compute/flavors.py rename to nova/api/openstack/compute/legacy_v2/flavors.py diff --git a/nova/api/openstack/compute/image_metadata.py b/nova/api/openstack/compute/legacy_v2/image_metadata.py similarity index 100% rename from nova/api/openstack/compute/image_metadata.py rename to nova/api/openstack/compute/legacy_v2/image_metadata.py diff --git a/nova/api/openstack/compute/images.py b/nova/api/openstack/compute/legacy_v2/images.py similarity index 100% rename from nova/api/openstack/compute/images.py rename to nova/api/openstack/compute/legacy_v2/images.py diff --git a/nova/api/openstack/compute/ips.py b/nova/api/openstack/compute/legacy_v2/ips.py similarity index 100% rename from nova/api/openstack/compute/ips.py rename to nova/api/openstack/compute/legacy_v2/ips.py diff --git a/nova/api/openstack/compute/legacy_v2/limits.py b/nova/api/openstack/compute/legacy_v2/limits.py new file mode 100644 index 000000000000..8487d08e8fbe --- /dev/null +++ b/nova/api/openstack/compute/legacy_v2/limits.py @@ -0,0 +1,457 @@ +# Copyright 2011 OpenStack Foundation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" +Module dedicated functions/classes dealing with rate limiting requests. + +This module handles rate liming at a per-user level, so it should not be used +to prevent intentional Denial of Service attacks, as we can assume a DOS can +easily come through multiple user accounts. DOS protection should be done at a +different layer. Instead this module should be used to protect against +unintentional user actions. With that in mind the limits set here should be +high enough as to not rate-limit any intentional actions. + +To find good rate-limit values, check how long requests are taking (see logs) +in your environment to assess your capabilities and multiply out to get +figures. + +NOTE: As the rate-limiting here is done in memory, this only works per +process (each process will have its own rate limiting counter). +""" + +import collections +import copy +import math +import re +import time + +from oslo_serialization import jsonutils +from oslo_utils import importutils +from six.moves import http_client as httplib +import webob.dec +import webob.exc + +from nova.api.openstack.compute.views import limits as limits_views +from nova.api.openstack import wsgi +from nova.i18n import _ +from nova import quota +from nova import utils +from nova import wsgi as base_wsgi + + +QUOTAS = quota.QUOTAS +LIMITS_PREFIX = "limits." + + +class LimitsController(object): + """Controller for accessing limits in the OpenStack API.""" + + def index(self, req): + """Return all global and rate limit information.""" + context = req.environ['nova.context'] + project_id = req.params.get('tenant_id', context.project_id) + quotas = QUOTAS.get_project_quotas(context, project_id, + usages=False) + abs_limits = {k: v['limit'] for k, v in quotas.items()} + rate_limits = req.environ.get("nova.limits", []) + + builder = self._get_view_builder(req) + return builder.build(rate_limits, abs_limits) + + def create(self, req, body): + """Create a new limit.""" + raise webob.exc.HTTPNotImplemented() + + def delete(self, req, id): + """Delete the limit.""" + raise webob.exc.HTTPNotImplemented() + + def show(self, req, id): + """Show limit information.""" + raise webob.exc.HTTPNotImplemented() + + def update(self, req, id, body): + """Update existing limit.""" + raise webob.exc.HTTPNotImplemented() + + def _get_view_builder(self, req): + return limits_views.ViewBuilder() + + +def create_resource(): + return wsgi.Resource(LimitsController()) + + +class Limit(object): + """Stores information about a limit for HTTP requests.""" + + UNITS = {v: k for k, v in utils.TIME_UNITS.items()} + + def __init__(self, verb, uri, regex, value, unit): + """Initialize a new `Limit`. + + @param verb: HTTP verb (POST, PUT, etc.) + @param uri: Human-readable URI + @param regex: Regular expression format for this limit + @param value: Integer number of requests which can be made + @param unit: Unit of measure for the value parameter + """ + self.verb = verb + self.uri = uri + self.regex = regex + self.value = int(value) + self.unit = unit + self.unit_string = self.display_unit().lower() + self.remaining = int(value) + + if value <= 0: + raise ValueError("Limit value must be > 0") + + self.last_request = None + self.next_request = None + + self.water_level = 0 + self.capacity = self.unit + self.request_value = float(self.capacity) / float(self.value) + msg = (_("Only %(value)s %(verb)s request(s) can be " + "made to %(uri)s every %(unit_string)s.") % + {'value': self.value, 'verb': self.verb, 'uri': self.uri, + 'unit_string': self.unit_string}) + self.error_message = msg + + def __call__(self, verb, url): + """Represents a call to this limit from a relevant request. + + @param verb: string http verb (POST, GET, etc.) + @param url: string URL + """ + if self.verb != verb or not re.match(self.regex, url): + return + + now = self._get_time() + + if self.last_request is None: + self.last_request = now + + leak_value = now - self.last_request + + self.water_level -= leak_value + self.water_level = max(self.water_level, 0) + self.water_level += self.request_value + + difference = self.water_level - self.capacity + + self.last_request = now + + if difference > 0: + self.water_level -= self.request_value + self.next_request = now + difference + return difference + + cap = self.capacity + water = self.water_level + val = self.value + + self.remaining = math.floor(((cap - water) / cap) * val) + self.next_request = now + + def _get_time(self): + """Retrieve the current time. Broken out for testability.""" + return time.time() + + def display_unit(self): + """Display the string name of the unit.""" + return self.UNITS.get(self.unit, "UNKNOWN") + + def display(self): + """Return a useful representation of this class.""" + return { + "verb": self.verb, + "URI": self.uri, + "regex": self.regex, + "value": self.value, + "remaining": int(self.remaining), + "unit": self.display_unit(), + "resetTime": int(self.next_request or self._get_time()), + } + +# "Limit" format is a dictionary with the HTTP verb, human-readable URI, +# a regular-expression to match, value and unit of measure (PER_DAY, etc.) + +DEFAULT_LIMITS = [ + Limit("POST", "*", ".*", 120, utils.TIME_UNITS['MINUTE']), + Limit("POST", "*/servers", "^/servers", 120, utils.TIME_UNITS['MINUTE']), + Limit("PUT", "*", ".*", 120, utils.TIME_UNITS['MINUTE']), + Limit("GET", "*changes-since*", ".*changes-since.*", 120, + utils.TIME_UNITS['MINUTE']), + Limit("DELETE", "*", ".*", 120, utils.TIME_UNITS['MINUTE']), + Limit("GET", "*/os-fping", "^/os-fping", 12, utils.TIME_UNITS['MINUTE']), +] + + +class RateLimitingMiddleware(base_wsgi.Middleware): + """Rate-limits requests passing through this middleware. All limit + information is stored in memory for this implementation. + """ + + def __init__(self, application, limits=None, limiter=None, **kwargs): + """Initialize new `RateLimitingMiddleware`. + + It wraps the given WSGI application and sets up the given limits. + + @param application: WSGI application to wrap + @param limits: String describing limits + @param limiter: String identifying class for representing limits + + Other parameters are passed to the constructor for the limiter. + """ + base_wsgi.Middleware.__init__(self, application) + + # Select the limiter class + if limiter is None: + limiter = Limiter + else: + limiter = importutils.import_class(limiter) + + # Parse the limits, if any are provided + if limits is not None: + limits = limiter.parse_limits(limits) + + self._limiter = limiter(limits or DEFAULT_LIMITS, **kwargs) + + @webob.dec.wsgify(RequestClass=wsgi.Request) + def __call__(self, req): + """Represents a single call through this middleware. + + We should record the request if we have a limit relevant to it. + If no limit is relevant to the request, ignore it. + + If the request should be rate limited, return a fault telling the user + they are over the limit and need to retry later. + """ + verb = req.method + url = req.url + context = req.environ.get("nova.context") + + if context: + username = context.user_id + else: + username = None + + delay, error = self._limiter.check_for_delay(verb, url, username) + + if delay: + msg = _("This request was rate-limited.") + retry = time.time() + delay + return wsgi.RateLimitFault(msg, error, retry) + + req.environ["nova.limits"] = self._limiter.get_limits(username) + + return self.application + + +class Limiter(object): + """Rate-limit checking class which handles limits in memory.""" + + def __init__(self, limits, **kwargs): + """Initialize the new `Limiter`. + + @param limits: List of `Limit` objects + """ + self.limits = copy.deepcopy(limits) + self.levels = collections.defaultdict(lambda: copy.deepcopy(limits)) + + # Pick up any per-user limit information + for key, value in kwargs.items(): + if key.startswith(LIMITS_PREFIX): + username = key[len(LIMITS_PREFIX):] + self.levels[username] = self.parse_limits(value) + + def get_limits(self, username=None): + """Return the limits for a given user.""" + return [limit.display() for limit in self.levels[username]] + + def check_for_delay(self, verb, url, username=None): + """Check the given verb/user/user triplet for limit. + + @return: Tuple of delay (in seconds) and error message (or None, None) + """ + delays = [] + + for limit in self.levels[username]: + delay = limit(verb, url) + if delay: + delays.append((delay, limit.error_message)) + + if delays: + delays.sort() + return delays[0] + + return None, None + + # Note: This method gets called before the class is instantiated, + # so this must be either a static method or a class method. It is + # used to develop a list of limits to feed to the constructor. We + # put this in the class so that subclasses can override the + # default limit parsing. + @staticmethod + def parse_limits(limits): + """Convert a string into a list of Limit instances. This + implementation expects a semicolon-separated sequence of + parenthesized groups, where each group contains a + comma-separated sequence consisting of HTTP method, + user-readable URI, a URI reg-exp, an integer number of + requests which can be made, and a unit of measure. Valid + values for the latter are "SECOND", "MINUTE", "HOUR", and + "DAY". + + @return: List of Limit instances. + """ + + # Handle empty limit strings + limits = limits.strip() + if not limits: + return [] + + # Split up the limits by semicolon + result = [] + for group in limits.split(';'): + group = group.strip() + if group[:1] != '(' or group[-1:] != ')': + raise ValueError("Limit rules must be surrounded by " + "parentheses") + group = group[1:-1] + + # Extract the Limit arguments + args = [a.strip() for a in group.split(',')] + if len(args) != 5: + raise ValueError("Limit rules must contain the following " + "arguments: verb, uri, regex, value, unit") + + # Pull out the arguments + verb, uri, regex, value, unit = args + + # Upper-case the verb + verb = verb.upper() + + # Convert value--raises ValueError if it's not integer + value = int(value) + + # Convert unit + unit = unit.upper() + if unit not in utils.TIME_UNITS: + raise ValueError("Invalid units specified") + unit = utils.TIME_UNITS[unit] + + # Build a limit + result.append(Limit(verb, uri, regex, value, unit)) + + return result + + +class WsgiLimiter(object): + """Rate-limit checking from a WSGI application. Uses an in-memory + `Limiter`. + + To use, POST ``/`` with JSON data such as:: + + { + "verb" : GET, + "path" : "/servers" + } + + and receive a 204 No Content, or a 403 Forbidden with an X-Wait-Seconds + header containing the number of seconds to wait before the action would + succeed. + """ + + def __init__(self, limits=None): + """Initialize the new `WsgiLimiter`. + + @param limits: List of `Limit` objects + """ + self._limiter = Limiter(limits or DEFAULT_LIMITS) + + @webob.dec.wsgify(RequestClass=wsgi.Request) + def __call__(self, request): + """Handles a call to this application. + + Returns 204 if the request is acceptable to the limiter, else a 403 + is returned with a relevant header indicating when the request *will* + succeed. + """ + if request.method != "POST": + raise webob.exc.HTTPMethodNotAllowed() + + try: + info = dict(jsonutils.loads(request.body)) + except ValueError: + raise webob.exc.HTTPBadRequest() + + username = request.path_info_pop() + verb = info.get("verb") + path = info.get("path") + + delay, error = self._limiter.check_for_delay(verb, path, username) + + if delay: + headers = {"X-Wait-Seconds": "%.2f" % delay} + return webob.exc.HTTPForbidden(headers=headers, explanation=error) + else: + return webob.exc.HTTPNoContent() + + +class WsgiLimiterProxy(object): + """Rate-limit requests based on answers from a remote source.""" + + def __init__(self, limiter_address): + """Initialize the new `WsgiLimiterProxy`. + + @param limiter_address: IP/port combination of where to request limit + """ + self.limiter_address = limiter_address + + def check_for_delay(self, verb, path, username=None): + body = jsonutils.dumps({"verb": verb, "path": path}) + headers = {"Content-Type": "application/json"} + + conn = httplib.HTTPConnection(self.limiter_address) + + if username: + conn.request("POST", "/%s" % (username), body, headers) + else: + conn.request("POST", "/", body, headers) + + resp = conn.getresponse() + + if 200 >= resp.status < 300: + return None, None + + return resp.getheader("X-Wait-Seconds"), resp.read() or None + + # Note: This method gets called before the class is instantiated, + # so this must be either a static method or a class method. It is + # used to develop a list of limits to feed to the constructor. + # This implementation returns an empty list, since all limit + # decisions are made by a remote server. + @staticmethod + def parse_limits(limits): + """Ignore a limits string--simply doesn't apply for the limit + proxy. + + @return: Empty list. + """ + + return [] diff --git a/nova/api/openstack/compute/server_metadata.py b/nova/api/openstack/compute/legacy_v2/server_metadata.py similarity index 100% rename from nova/api/openstack/compute/server_metadata.py rename to nova/api/openstack/compute/legacy_v2/server_metadata.py diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/legacy_v2/servers.py similarity index 100% rename from nova/api/openstack/compute/servers.py rename to nova/api/openstack/compute/legacy_v2/servers.py diff --git a/nova/api/openstack/compute/legacy_v2/versions.py b/nova/api/openstack/compute/legacy_v2/versions.py new file mode 100644 index 000000000000..6c36ea03764e --- /dev/null +++ b/nova/api/openstack/compute/legacy_v2/versions.py @@ -0,0 +1,28 @@ +# Copyright 2011 OpenStack Foundation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from nova.api.openstack.compute import versions +from nova.api.openstack.compute.views import versions as views_versions +from nova.api.openstack import wsgi + + +class VersionV2(object): + def show(self, req): + builder = views_versions.get_view_builder(req) + return builder.build_version(versions.VERSIONS['v2.0']) + + +def create_resource(): + return wsgi.Resource(VersionV2()) diff --git a/nova/api/openstack/compute/limits.py b/nova/api/openstack/compute/limits.py index 8487d08e8fbe..6ffa79aa4456 100644 --- a/nova/api/openstack/compute/limits.py +++ b/nova/api/openstack/compute/limits.py @@ -13,445 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. -""" -Module dedicated functions/classes dealing with rate limiting requests. +from nova.api.openstack.compute.legacy_v2 import limits -This module handles rate liming at a per-user level, so it should not be used -to prevent intentional Denial of Service attacks, as we can assume a DOS can -easily come through multiple user accounts. DOS protection should be done at a -different layer. Instead this module should be used to protect against -unintentional user actions. With that in mind the limits set here should be -high enough as to not rate-limit any intentional actions. -To find good rate-limit values, check how long requests are taking (see logs) -in your environment to assess your capabilities and multiply out to get -figures. - -NOTE: As the rate-limiting here is done in memory, this only works per -process (each process will have its own rate limiting counter). -""" - -import collections -import copy -import math -import re -import time - -from oslo_serialization import jsonutils -from oslo_utils import importutils -from six.moves import http_client as httplib -import webob.dec -import webob.exc - -from nova.api.openstack.compute.views import limits as limits_views -from nova.api.openstack import wsgi -from nova.i18n import _ -from nova import quota -from nova import utils -from nova import wsgi as base_wsgi - - -QUOTAS = quota.QUOTAS -LIMITS_PREFIX = "limits." - - -class LimitsController(object): - """Controller for accessing limits in the OpenStack API.""" - - def index(self, req): - """Return all global and rate limit information.""" - context = req.environ['nova.context'] - project_id = req.params.get('tenant_id', context.project_id) - quotas = QUOTAS.get_project_quotas(context, project_id, - usages=False) - abs_limits = {k: v['limit'] for k, v in quotas.items()} - rate_limits = req.environ.get("nova.limits", []) - - builder = self._get_view_builder(req) - return builder.build(rate_limits, abs_limits) - - def create(self, req, body): - """Create a new limit.""" - raise webob.exc.HTTPNotImplemented() - - def delete(self, req, id): - """Delete the limit.""" - raise webob.exc.HTTPNotImplemented() - - def show(self, req, id): - """Show limit information.""" - raise webob.exc.HTTPNotImplemented() - - def update(self, req, id, body): - """Update existing limit.""" - raise webob.exc.HTTPNotImplemented() - - def _get_view_builder(self, req): - return limits_views.ViewBuilder() - - -def create_resource(): - return wsgi.Resource(LimitsController()) - - -class Limit(object): - """Stores information about a limit for HTTP requests.""" - - UNITS = {v: k for k, v in utils.TIME_UNITS.items()} - - def __init__(self, verb, uri, regex, value, unit): - """Initialize a new `Limit`. - - @param verb: HTTP verb (POST, PUT, etc.) - @param uri: Human-readable URI - @param regex: Regular expression format for this limit - @param value: Integer number of requests which can be made - @param unit: Unit of measure for the value parameter - """ - self.verb = verb - self.uri = uri - self.regex = regex - self.value = int(value) - self.unit = unit - self.unit_string = self.display_unit().lower() - self.remaining = int(value) - - if value <= 0: - raise ValueError("Limit value must be > 0") - - self.last_request = None - self.next_request = None - - self.water_level = 0 - self.capacity = self.unit - self.request_value = float(self.capacity) / float(self.value) - msg = (_("Only %(value)s %(verb)s request(s) can be " - "made to %(uri)s every %(unit_string)s.") % - {'value': self.value, 'verb': self.verb, 'uri': self.uri, - 'unit_string': self.unit_string}) - self.error_message = msg - - def __call__(self, verb, url): - """Represents a call to this limit from a relevant request. - - @param verb: string http verb (POST, GET, etc.) - @param url: string URL - """ - if self.verb != verb or not re.match(self.regex, url): - return - - now = self._get_time() - - if self.last_request is None: - self.last_request = now - - leak_value = now - self.last_request - - self.water_level -= leak_value - self.water_level = max(self.water_level, 0) - self.water_level += self.request_value - - difference = self.water_level - self.capacity - - self.last_request = now - - if difference > 0: - self.water_level -= self.request_value - self.next_request = now + difference - return difference - - cap = self.capacity - water = self.water_level - val = self.value - - self.remaining = math.floor(((cap - water) / cap) * val) - self.next_request = now - - def _get_time(self): - """Retrieve the current time. Broken out for testability.""" - return time.time() - - def display_unit(self): - """Display the string name of the unit.""" - return self.UNITS.get(self.unit, "UNKNOWN") - - def display(self): - """Return a useful representation of this class.""" - return { - "verb": self.verb, - "URI": self.uri, - "regex": self.regex, - "value": self.value, - "remaining": int(self.remaining), - "unit": self.display_unit(), - "resetTime": int(self.next_request or self._get_time()), - } - -# "Limit" format is a dictionary with the HTTP verb, human-readable URI, -# a regular-expression to match, value and unit of measure (PER_DAY, etc.) - -DEFAULT_LIMITS = [ - Limit("POST", "*", ".*", 120, utils.TIME_UNITS['MINUTE']), - Limit("POST", "*/servers", "^/servers", 120, utils.TIME_UNITS['MINUTE']), - Limit("PUT", "*", ".*", 120, utils.TIME_UNITS['MINUTE']), - Limit("GET", "*changes-since*", ".*changes-since.*", 120, - utils.TIME_UNITS['MINUTE']), - Limit("DELETE", "*", ".*", 120, utils.TIME_UNITS['MINUTE']), - Limit("GET", "*/os-fping", "^/os-fping", 12, utils.TIME_UNITS['MINUTE']), -] - - -class RateLimitingMiddleware(base_wsgi.Middleware): - """Rate-limits requests passing through this middleware. All limit - information is stored in memory for this implementation. - """ - - def __init__(self, application, limits=None, limiter=None, **kwargs): - """Initialize new `RateLimitingMiddleware`. - - It wraps the given WSGI application and sets up the given limits. - - @param application: WSGI application to wrap - @param limits: String describing limits - @param limiter: String identifying class for representing limits - - Other parameters are passed to the constructor for the limiter. - """ - base_wsgi.Middleware.__init__(self, application) - - # Select the limiter class - if limiter is None: - limiter = Limiter - else: - limiter = importutils.import_class(limiter) - - # Parse the limits, if any are provided - if limits is not None: - limits = limiter.parse_limits(limits) - - self._limiter = limiter(limits or DEFAULT_LIMITS, **kwargs) - - @webob.dec.wsgify(RequestClass=wsgi.Request) - def __call__(self, req): - """Represents a single call through this middleware. - - We should record the request if we have a limit relevant to it. - If no limit is relevant to the request, ignore it. - - If the request should be rate limited, return a fault telling the user - they are over the limit and need to retry later. - """ - verb = req.method - url = req.url - context = req.environ.get("nova.context") - - if context: - username = context.user_id - else: - username = None - - delay, error = self._limiter.check_for_delay(verb, url, username) - - if delay: - msg = _("This request was rate-limited.") - retry = time.time() + delay - return wsgi.RateLimitFault(msg, error, retry) - - req.environ["nova.limits"] = self._limiter.get_limits(username) - - return self.application - - -class Limiter(object): - """Rate-limit checking class which handles limits in memory.""" - - def __init__(self, limits, **kwargs): - """Initialize the new `Limiter`. - - @param limits: List of `Limit` objects - """ - self.limits = copy.deepcopy(limits) - self.levels = collections.defaultdict(lambda: copy.deepcopy(limits)) - - # Pick up any per-user limit information - for key, value in kwargs.items(): - if key.startswith(LIMITS_PREFIX): - username = key[len(LIMITS_PREFIX):] - self.levels[username] = self.parse_limits(value) - - def get_limits(self, username=None): - """Return the limits for a given user.""" - return [limit.display() for limit in self.levels[username]] - - def check_for_delay(self, verb, url, username=None): - """Check the given verb/user/user triplet for limit. - - @return: Tuple of delay (in seconds) and error message (or None, None) - """ - delays = [] - - for limit in self.levels[username]: - delay = limit(verb, url) - if delay: - delays.append((delay, limit.error_message)) - - if delays: - delays.sort() - return delays[0] - - return None, None - - # Note: This method gets called before the class is instantiated, - # so this must be either a static method or a class method. It is - # used to develop a list of limits to feed to the constructor. We - # put this in the class so that subclasses can override the - # default limit parsing. - @staticmethod - def parse_limits(limits): - """Convert a string into a list of Limit instances. This - implementation expects a semicolon-separated sequence of - parenthesized groups, where each group contains a - comma-separated sequence consisting of HTTP method, - user-readable URI, a URI reg-exp, an integer number of - requests which can be made, and a unit of measure. Valid - values for the latter are "SECOND", "MINUTE", "HOUR", and - "DAY". - - @return: List of Limit instances. - """ - - # Handle empty limit strings - limits = limits.strip() - if not limits: - return [] - - # Split up the limits by semicolon - result = [] - for group in limits.split(';'): - group = group.strip() - if group[:1] != '(' or group[-1:] != ')': - raise ValueError("Limit rules must be surrounded by " - "parentheses") - group = group[1:-1] - - # Extract the Limit arguments - args = [a.strip() for a in group.split(',')] - if len(args) != 5: - raise ValueError("Limit rules must contain the following " - "arguments: verb, uri, regex, value, unit") - - # Pull out the arguments - verb, uri, regex, value, unit = args - - # Upper-case the verb - verb = verb.upper() - - # Convert value--raises ValueError if it's not integer - value = int(value) - - # Convert unit - unit = unit.upper() - if unit not in utils.TIME_UNITS: - raise ValueError("Invalid units specified") - unit = utils.TIME_UNITS[unit] - - # Build a limit - result.append(Limit(verb, uri, regex, value, unit)) - - return result - - -class WsgiLimiter(object): - """Rate-limit checking from a WSGI application. Uses an in-memory - `Limiter`. - - To use, POST ``/`` with JSON data such as:: - - { - "verb" : GET, - "path" : "/servers" - } - - and receive a 204 No Content, or a 403 Forbidden with an X-Wait-Seconds - header containing the number of seconds to wait before the action would - succeed. - """ - - def __init__(self, limits=None): - """Initialize the new `WsgiLimiter`. - - @param limits: List of `Limit` objects - """ - self._limiter = Limiter(limits or DEFAULT_LIMITS) - - @webob.dec.wsgify(RequestClass=wsgi.Request) - def __call__(self, request): - """Handles a call to this application. - - Returns 204 if the request is acceptable to the limiter, else a 403 - is returned with a relevant header indicating when the request *will* - succeed. - """ - if request.method != "POST": - raise webob.exc.HTTPMethodNotAllowed() - - try: - info = dict(jsonutils.loads(request.body)) - except ValueError: - raise webob.exc.HTTPBadRequest() - - username = request.path_info_pop() - verb = info.get("verb") - path = info.get("path") - - delay, error = self._limiter.check_for_delay(verb, path, username) - - if delay: - headers = {"X-Wait-Seconds": "%.2f" % delay} - return webob.exc.HTTPForbidden(headers=headers, explanation=error) - else: - return webob.exc.HTTPNoContent() - - -class WsgiLimiterProxy(object): - """Rate-limit requests based on answers from a remote source.""" - - def __init__(self, limiter_address): - """Initialize the new `WsgiLimiterProxy`. - - @param limiter_address: IP/port combination of where to request limit - """ - self.limiter_address = limiter_address - - def check_for_delay(self, verb, path, username=None): - body = jsonutils.dumps({"verb": verb, "path": path}) - headers = {"Content-Type": "application/json"} - - conn = httplib.HTTPConnection(self.limiter_address) - - if username: - conn.request("POST", "/%s" % (username), body, headers) - else: - conn.request("POST", "/", body, headers) - - resp = conn.getresponse() - - if 200 >= resp.status < 300: - return None, None - - return resp.getheader("X-Wait-Seconds"), resp.read() or None - - # Note: This method gets called before the class is instantiated, - # so this must be either a static method or a class method. It is - # used to develop a list of limits to feed to the constructor. - # This implementation returns an empty list, since all limit - # decisions are made by a remote server. - @staticmethod - def parse_limits(limits): - """Ignore a limits string--simply doesn't apply for the limit - proxy. - - @return: Empty list. - """ - - return [] +# NOTE(alex_xu): This is just for keeping backward compatible with v2 endpoint +# in api-paste.ini. This will be removed after v2 API code deprecated in the +# future. +RateLimitingMiddleware = limits.RateLimitingMiddleware diff --git a/nova/api/openstack/compute/plugins/v3/evacuate.py b/nova/api/openstack/compute/plugins/v3/evacuate.py index aaed73dd3546..bd05081ccb86 100644 --- a/nova/api/openstack/compute/plugins/v3/evacuate.py +++ b/nova/api/openstack/compute/plugins/v3/evacuate.py @@ -29,7 +29,7 @@ from nova import utils CONF = cfg.CONF CONF.import_opt('enable_instance_password', - 'nova.api.openstack.compute.servers') + 'nova.api.openstack.compute.legacy_v2.servers') ALIAS = "os-evacuate" authorize = extensions.os_compute_authorizer(ALIAS) diff --git a/nova/api/openstack/compute/plugins/v3/rescue.py b/nova/api/openstack/compute/plugins/v3/rescue.py index bf974875db32..3ab3f498cec6 100644 --- a/nova/api/openstack/compute/plugins/v3/rescue.py +++ b/nova/api/openstack/compute/plugins/v3/rescue.py @@ -30,7 +30,7 @@ from nova import utils ALIAS = "os-rescue" CONF = cfg.CONF CONF.import_opt('enable_instance_password', - 'nova.api.openstack.compute.servers') + 'nova.api.openstack.compute.legacy_v2.servers') authorize = extensions.os_compute_authorizer(ALIAS) diff --git a/nova/api/openstack/compute/plugins/v3/servers.py b/nova/api/openstack/compute/plugins/v3/servers.py index 0fba3c860034..6487e9840449 100644 --- a/nova/api/openstack/compute/plugins/v3/servers.py +++ b/nova/api/openstack/compute/plugins/v3/servers.py @@ -48,7 +48,7 @@ ALIAS = 'servers' CONF = cfg.CONF CONF.import_opt('enable_instance_password', - 'nova.api.openstack.compute.servers') + 'nova.api.openstack.compute.legacy_v2.servers') CONF.import_opt('network_api_class', 'nova.network') CONF.import_opt('reclaim_instance_interval', 'nova.compute.manager') CONF.import_opt('extensions_blacklist', 'nova.api.openstack', group='osapi_v3') diff --git a/nova/api/openstack/compute/versions.py b/nova/api/openstack/compute/versions.py index 4b727de32061..e1611725c3bb 100644 --- a/nova/api/openstack/compute/versions.py +++ b/nova/api/openstack/compute/versions.py @@ -103,13 +103,3 @@ class Versions(wsgi.Resource): args['action'] = 'multi' return args - - -class VersionV2(object): - def show(self, req): - builder = views_versions.get_view_builder(req) - return builder.build_version(VERSIONS['v2.0']) - - -def create_resource(): - return wsgi.Resource(VersionV2()) diff --git a/nova/api/opts.py b/nova/api/opts.py index 7b4ed05b8f87..2af8e3e1bb6a 100644 --- a/nova/api/opts.py +++ b/nova/api/opts.py @@ -24,9 +24,9 @@ import nova.api.openstack.compute import nova.api.openstack.compute.contrib import nova.api.openstack.compute.contrib.fping import nova.api.openstack.compute.contrib.os_tenant_networks -import nova.api.openstack.compute.extensions +import nova.api.openstack.compute.legacy_v2.extensions +import nova.api.openstack.compute.legacy_v2.servers import nova.api.openstack.compute.plugins.v3.hide_server_addresses -import nova.api.openstack.compute.servers import nova.availability_zones import nova.baserpc import nova.cells.manager @@ -138,9 +138,9 @@ def list_opts(): nova.api.openstack.compute.contrib.fping.fping_opts, nova.api.openstack.compute.contrib.os_tenant_networks. os_network_opts, - nova.api.openstack.compute.extensions.ext_opts, + nova.api.openstack.compute.legacy_v2.extensions.ext_opts, nova.api.openstack.compute.plugins.v3.hide_server_addresses.opts, - nova.api.openstack.compute.servers.server_opts, + nova.api.openstack.compute.legacy_v2.servers.server_opts, )), ('neutron', nova.api.metadata.handler.metadata_proxy_opts), ('osapi_v3', nova.api.openstack.api_opts), diff --git a/nova/tests/functional/test_api_samples.py b/nova/tests/functional/test_api_samples.py index c78be6f35b12..ee84cf473bf5 100644 --- a/nova/tests/functional/test_api_samples.py +++ b/nova/tests/functional/test_api_samples.py @@ -41,7 +41,7 @@ CONF.import_opt('shelved_offload_time', 'nova.compute.manager') CONF.import_opt('enable_network_quota', 'nova.api.openstack.compute.contrib.os_tenant_networks') CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') CONF.import_opt('osapi_compute_link_prefix', 'nova.api.openstack.common') CONF.import_opt('osapi_glance_link_prefix', 'nova.api.openstack.common') CONF.import_opt('enable', 'nova.cells.opts', group='cells') diff --git a/nova/tests/functional/v3/test_access_ips.py b/nova/tests/functional/v3/test_access_ips.py index 8c2c258f110b..7a835d3bce82 100644 --- a/nova/tests/functional/v3/test_access_ips.py +++ b/nova/tests/functional/v3/test_access_ips.py @@ -20,7 +20,7 @@ from nova.tests.unit.image import fake CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class AccessIPsSampleJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_admin_actions.py b/nova/tests/functional/v3/test_admin_actions.py index 85f90915dba3..10b067743abf 100644 --- a/nova/tests/functional/v3/test_admin_actions.py +++ b/nova/tests/functional/v3/test_admin_actions.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class AdminActionsSamplesJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_admin_password.py b/nova/tests/functional/v3/test_admin_password.py index fbf3f874798a..1465a6fbe2d0 100644 --- a/nova/tests/functional/v3/test_admin_password.py +++ b/nova/tests/functional/v3/test_admin_password.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class AdminPasswordJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_agents.py b/nova/tests/functional/v3/test_agents.py index 33336ec973dc..daaef53819e8 100644 --- a/nova/tests/functional/v3/test_agents.py +++ b/nova/tests/functional/v3/test_agents.py @@ -21,7 +21,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class AgentsJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_aggregates.py b/nova/tests/functional/v3/test_aggregates.py index 2089c451b4f4..dc102c7e0248 100644 --- a/nova/tests/functional/v3/test_aggregates.py +++ b/nova/tests/functional/v3/test_aggregates.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class AggregatesSampleJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_assisted_volume_snapshots.py b/nova/tests/functional/v3/test_assisted_volume_snapshots.py index ad7dd37c2528..6cdbae7963d8 100644 --- a/nova/tests/functional/v3/test_assisted_volume_snapshots.py +++ b/nova/tests/functional/v3/test_assisted_volume_snapshots.py @@ -20,7 +20,7 @@ from nova.tests.unit.api.openstack import fakes CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class AssistedVolumeSnapshotsJsonTests(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_attach_interfaces.py b/nova/tests/functional/v3/test_attach_interfaces.py index 15a00bd4d671..eccc2c0f0543 100644 --- a/nova/tests/functional/v3/test_attach_interfaces.py +++ b/nova/tests/functional/v3/test_attach_interfaces.py @@ -23,7 +23,7 @@ from nova.tests.unit import fake_network_cache_model CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class AttachInterfacesSampleJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_availability_zone.py b/nova/tests/functional/v3/test_availability_zone.py index e0caecfcc7c7..9ae59aa35910 100644 --- a/nova/tests/functional/v3/test_availability_zone.py +++ b/nova/tests/functional/v3/test_availability_zone.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('manager', 'nova.cells.opts', group='cells') CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class AvailabilityZoneJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_baremetal_nodes.py b/nova/tests/functional/v3/test_baremetal_nodes.py index 3b7131629106..a4c6bcae113b 100644 --- a/nova/tests/functional/v3/test_baremetal_nodes.py +++ b/nova/tests/functional/v3/test_baremetal_nodes.py @@ -20,7 +20,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class FakeNode(object): diff --git a/nova/tests/functional/v3/test_cells.py b/nova/tests/functional/v3/test_cells.py index d27829f33731..4ac7db85a023 100644 --- a/nova/tests/functional/v3/test_cells.py +++ b/nova/tests/functional/v3/test_cells.py @@ -25,7 +25,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class CellsSampleJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_certificates.py b/nova/tests/functional/v3/test_certificates.py index 74e448bc25fd..9709337b95ab 100644 --- a/nova/tests/functional/v3/test_certificates.py +++ b/nova/tests/functional/v3/test_certificates.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class CertificatesSamplesJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_cloudpipe.py b/nova/tests/functional/v3/test_cloudpipe.py index 31b378b392a5..149c0954777b 100644 --- a/nova/tests/functional/v3/test_cloudpipe.py +++ b/nova/tests/functional/v3/test_cloudpipe.py @@ -25,7 +25,7 @@ from nova.tests.unit.image import fake CONF = cfg.CONF CONF.import_opt('vpn_image_id', 'nova.cloudpipe.pipelib') CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class CloudPipeSampleTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_config_drive.py b/nova/tests/functional/v3/test_config_drive.py index b542ab54dbe7..fcb5d1e339a9 100644 --- a/nova/tests/functional/v3/test_config_drive.py +++ b/nova/tests/functional/v3/test_config_drive.py @@ -21,7 +21,7 @@ from nova.tests.unit.image import fake CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ConfigDriveSampleJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_console_auth_tokens.py b/nova/tests/functional/v3/test_console_auth_tokens.py index e6d49051234d..ba4d9914e8d1 100644 --- a/nova/tests/functional/v3/test_console_auth_tokens.py +++ b/nova/tests/functional/v3/test_console_auth_tokens.py @@ -21,7 +21,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ConsoleAuthTokensSampleJsonTests(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_console_output.py b/nova/tests/functional/v3/test_console_output.py index 02dc51721223..c9e41a4d5ef7 100644 --- a/nova/tests/functional/v3/test_console_output.py +++ b/nova/tests/functional/v3/test_console_output.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ConsoleOutputSampleJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_create_backup.py b/nova/tests/functional/v3/test_create_backup.py index 39e423122f7d..2a4e8f8afc45 100644 --- a/nova/tests/functional/v3/test_create_backup.py +++ b/nova/tests/functional/v3/test_create_backup.py @@ -22,7 +22,7 @@ from nova.tests.unit.image import fake CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class CreateBackupSamplesJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_deferred_delete.py b/nova/tests/functional/v3/test_deferred_delete.py index e1e717753358..d68cbd1ff995 100644 --- a/nova/tests/functional/v3/test_deferred_delete.py +++ b/nova/tests/functional/v3/test_deferred_delete.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class DeferredDeleteSampleJsonTests(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_disk_config.py b/nova/tests/functional/v3/test_disk_config.py index a96504ad18e2..f07c95824ecb 100644 --- a/nova/tests/functional/v3/test_disk_config.py +++ b/nova/tests/functional/v3/test_disk_config.py @@ -20,7 +20,7 @@ from nova.tests.unit.image import fake CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class DiskConfigJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_evacuate.py b/nova/tests/functional/v3/test_evacuate.py index d2d4ff84c3eb..5dd7b404816a 100644 --- a/nova/tests/functional/v3/test_evacuate.py +++ b/nova/tests/functional/v3/test_evacuate.py @@ -23,7 +23,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class EvacuateJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_extended_availability_zone.py b/nova/tests/functional/v3/test_extended_availability_zone.py index 8b97a8845507..fa00d7fe8a35 100644 --- a/nova/tests/functional/v3/test_extended_availability_zone.py +++ b/nova/tests/functional/v3/test_extended_availability_zone.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ExtendedAvailabilityZoneJsonTests(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_extended_server_attributes.py b/nova/tests/functional/v3/test_extended_server_attributes.py index 3105dd72ecfe..536e1813bd60 100644 --- a/nova/tests/functional/v3/test_extended_server_attributes.py +++ b/nova/tests/functional/v3/test_extended_server_attributes.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ExtendedServerAttributesJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_extended_status.py b/nova/tests/functional/v3/test_extended_status.py index 6b3200b33148..09d48051bb5a 100644 --- a/nova/tests/functional/v3/test_extended_status.py +++ b/nova/tests/functional/v3/test_extended_status.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ExtendedStatusSampleJsonTests(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_extended_volumes.py b/nova/tests/functional/v3/test_extended_volumes.py index 8db84c009192..7a49ef677460 100644 --- a/nova/tests/functional/v3/test_extended_volumes.py +++ b/nova/tests/functional/v3/test_extended_volumes.py @@ -24,7 +24,7 @@ from nova.tests.unit import fake_instance CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ExtendedVolumesSampleJsonTests(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_extension_info.py b/nova/tests/functional/v3/test_extension_info.py index 699133b33832..3c6ced06f057 100644 --- a/nova/tests/functional/v3/test_extension_info.py +++ b/nova/tests/functional/v3/test_extension_info.py @@ -21,7 +21,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') def fake_soft_extension_authorizer(extension_name, core=False): diff --git a/nova/tests/functional/v3/test_fixed_ips.py b/nova/tests/functional/v3/test_fixed_ips.py index 470ce266daa5..5aaa1927afd0 100644 --- a/nova/tests/functional/v3/test_fixed_ips.py +++ b/nova/tests/functional/v3/test_fixed_ips.py @@ -22,7 +22,7 @@ from nova.tests.unit import utils as test_utils CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class FixedIpTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_flavor_access.py b/nova/tests/functional/v3/test_flavor_access.py index 741609d71552..0a23a3c8ca10 100644 --- a/nova/tests/functional/v3/test_flavor_access.py +++ b/nova/tests/functional/v3/test_flavor_access.py @@ -18,7 +18,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class FlavorAccessSampleJsonTests(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_flavor_extraspecs.py b/nova/tests/functional/v3/test_flavor_extraspecs.py index 5475b8338777..e6368d1999d3 100644 --- a/nova/tests/functional/v3/test_flavor_extraspecs.py +++ b/nova/tests/functional/v3/test_flavor_extraspecs.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class FlavorExtraSpecsSampleJsonTests(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_flavor_manage.py b/nova/tests/functional/v3/test_flavor_manage.py index 298ee420a9a5..5cf06c49d1b0 100644 --- a/nova/tests/functional/v3/test_flavor_manage.py +++ b/nova/tests/functional/v3/test_flavor_manage.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class FlavorManageSampleJsonTests(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_flavor_rxtx.py b/nova/tests/functional/v3/test_flavor_rxtx.py index 646503518745..3cc755109735 100644 --- a/nova/tests/functional/v3/test_flavor_rxtx.py +++ b/nova/tests/functional/v3/test_flavor_rxtx.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class FlavorRxtxJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_flavors.py b/nova/tests/functional/v3/test_flavors.py index 900ba3d04c43..26fb1c29fb1d 100644 --- a/nova/tests/functional/v3/test_flavors.py +++ b/nova/tests/functional/v3/test_flavors.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class FlavorsSampleJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_floating_ip_dns.py b/nova/tests/functional/v3/test_floating_ip_dns.py index 0b62331f58e3..2bb952abca0c 100644 --- a/nova/tests/functional/v3/test_floating_ip_dns.py +++ b/nova/tests/functional/v3/test_floating_ip_dns.py @@ -18,7 +18,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class FloatingIpDNSTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_floating_ip_pools.py b/nova/tests/functional/v3/test_floating_ip_pools.py index b5ed49b989e5..d714353d62c3 100644 --- a/nova/tests/functional/v3/test_floating_ip_pools.py +++ b/nova/tests/functional/v3/test_floating_ip_pools.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class FloatingIPPoolsSampleTests(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_floating_ips.py b/nova/tests/functional/v3/test_floating_ips.py index 68aa7f3aab76..ac726f208499 100644 --- a/nova/tests/functional/v3/test_floating_ips.py +++ b/nova/tests/functional/v3/test_floating_ips.py @@ -22,7 +22,7 @@ CONF = cfg.CONF CONF.import_opt('default_floating_pool', 'nova.network.floating_ips') CONF.import_opt('public_interface', 'nova.network.linux_net') CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class FloatingIpsTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_floating_ips_bulk.py b/nova/tests/functional/v3/test_floating_ips_bulk.py index c5b43d12f2ad..52ac6ef75a94 100644 --- a/nova/tests/functional/v3/test_floating_ips_bulk.py +++ b/nova/tests/functional/v3/test_floating_ips_bulk.py @@ -22,7 +22,7 @@ CONF = cfg.CONF CONF.import_opt('default_floating_pool', 'nova.network.floating_ips') CONF.import_opt('public_interface', 'nova.network.linux_net') CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class FloatingIpsBulkTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_fping.py b/nova/tests/functional/v3/test_fping.py index fffd8b6cefa0..21a9a3d26f4d 100644 --- a/nova/tests/functional/v3/test_fping.py +++ b/nova/tests/functional/v3/test_fping.py @@ -23,7 +23,7 @@ from nova import utils CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class FpingSampleJsonTests(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_hide_server_addresses.py b/nova/tests/functional/v3/test_hide_server_addresses.py index ed1dabb602db..d9b355e042c1 100644 --- a/nova/tests/functional/v3/test_hide_server_addresses.py +++ b/nova/tests/functional/v3/test_hide_server_addresses.py @@ -22,7 +22,7 @@ CONF = cfg.CONF CONF.import_opt('osapi_hide_server_address_states', 'nova.api.openstack.compute.plugins.v3.hide_server_addresses') CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ServersSampleHideAddressesJsonTest(test_servers.ServersSampleJsonTest): diff --git a/nova/tests/functional/v3/test_hosts.py b/nova/tests/functional/v3/test_hosts.py index 2cbfeae5f401..89d5d27efdd8 100644 --- a/nova/tests/functional/v3/test_hosts.py +++ b/nova/tests/functional/v3/test_hosts.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class HostsSampleJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_hypervisors.py b/nova/tests/functional/v3/test_hypervisors.py index 22448ddb79ea..b1102a9353e4 100644 --- a/nova/tests/functional/v3/test_hypervisors.py +++ b/nova/tests/functional/v3/test_hypervisors.py @@ -24,7 +24,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class HypervisorsSampleJsonTests(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_image_size.py b/nova/tests/functional/v3/test_image_size.py index ca6e0fa2044c..563ef452ce84 100644 --- a/nova/tests/functional/v3/test_image_size.py +++ b/nova/tests/functional/v3/test_image_size.py @@ -20,7 +20,7 @@ from nova.tests.unit.image import fake CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ImageSizeSampleJsonTests(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_images.py b/nova/tests/functional/v3/test_images.py index 830b89953d61..b764b7c50d13 100644 --- a/nova/tests/functional/v3/test_images.py +++ b/nova/tests/functional/v3/test_images.py @@ -20,7 +20,7 @@ from nova.tests.unit.image import fake CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ImagesSampleJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_instance_actions.py b/nova/tests/functional/v3/test_instance_actions.py index 005edaab0adf..e561368683a4 100644 --- a/nova/tests/functional/v3/test_instance_actions.py +++ b/nova/tests/functional/v3/test_instance_actions.py @@ -27,7 +27,7 @@ from nova.tests.unit import utils as test_utils CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_instance_usage_audit_log.py b/nova/tests/functional/v3/test_instance_usage_audit_log.py index 93197d32d2a0..08ccf0eb3455 100644 --- a/nova/tests/functional/v3/test_instance_usage_audit_log.py +++ b/nova/tests/functional/v3/test_instance_usage_audit_log.py @@ -21,7 +21,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class InstanceUsageAuditLogJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_keypairs.py b/nova/tests/functional/v3/test_keypairs.py index 838b6738de44..c4f38523d0f8 100644 --- a/nova/tests/functional/v3/test_keypairs.py +++ b/nova/tests/functional/v3/test_keypairs.py @@ -23,7 +23,7 @@ from nova.tests.unit import fake_crypto CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class KeyPairsSampleJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_lock_server.py b/nova/tests/functional/v3/test_lock_server.py index bbd72f8a83ac..6d803047039a 100644 --- a/nova/tests/functional/v3/test_lock_server.py +++ b/nova/tests/functional/v3/test_lock_server.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class LockServerSamplesJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_migrate_server.py b/nova/tests/functional/v3/test_migrate_server.py index ee4b1b78a8d0..e425590abb3d 100644 --- a/nova/tests/functional/v3/test_migrate_server.py +++ b/nova/tests/functional/v3/test_migrate_server.py @@ -23,7 +23,7 @@ from nova import utils CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class MigrateServerSamplesJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_migrations.py b/nova/tests/functional/v3/test_migrations.py index 67f08390f5c5..54c24add30d8 100644 --- a/nova/tests/functional/v3/test_migrations.py +++ b/nova/tests/functional/v3/test_migrations.py @@ -22,7 +22,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class MigrationsSamplesJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_multinic.py b/nova/tests/functional/v3/test_multinic.py index 8bc8d82faaba..bfac61e01c82 100644 --- a/nova/tests/functional/v3/test_multinic.py +++ b/nova/tests/functional/v3/test_multinic.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class MultinicSampleJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_multiple_create.py b/nova/tests/functional/v3/test_multiple_create.py index 809025d2f081..bf7ca3e6d0ce 100644 --- a/nova/tests/functional/v3/test_multiple_create.py +++ b/nova/tests/functional/v3/test_multiple_create.py @@ -20,7 +20,7 @@ from nova.tests.unit.image import fake CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class MultipleCreateJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_networks.py b/nova/tests/functional/v3/test_networks.py index a9345246726a..60fd202248dc 100644 --- a/nova/tests/functional/v3/test_networks.py +++ b/nova/tests/functional/v3/test_networks.py @@ -21,7 +21,7 @@ from nova.tests.unit.api.openstack.compute.contrib import test_networks CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class NetworksJsonTests(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_networks_associate.py b/nova/tests/functional/v3/test_networks_associate.py index 1012a21894d2..77899b8d1594 100644 --- a/nova/tests/functional/v3/test_networks_associate.py +++ b/nova/tests/functional/v3/test_networks_associate.py @@ -20,7 +20,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class NetworksAssociateJsonTests(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_pause_server.py b/nova/tests/functional/v3/test_pause_server.py index f0aad8fa0443..c7b1d5f1159e 100644 --- a/nova/tests/functional/v3/test_pause_server.py +++ b/nova/tests/functional/v3/test_pause_server.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class PauseServerSamplesJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_preserve_ephemeral_rebuild.py b/nova/tests/functional/v3/test_preserve_ephemeral_rebuild.py index 235ff6bdaa70..acdc03acdf98 100644 --- a/nova/tests/functional/v3/test_preserve_ephemeral_rebuild.py +++ b/nova/tests/functional/v3/test_preserve_ephemeral_rebuild.py @@ -20,7 +20,7 @@ from nova.tests.unit.image import fake CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class PreserveEphemeralOnRebuildJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_quota_classes.py b/nova/tests/functional/v3/test_quota_classes.py index 187c69b0e03c..89adfb0d3dce 100644 --- a/nova/tests/functional/v3/test_quota_classes.py +++ b/nova/tests/functional/v3/test_quota_classes.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class QuotaClassesSampleJsonTests(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_quota_sets.py b/nova/tests/functional/v3/test_quota_sets.py index 2d99ac7b9421..dcfc82926f97 100644 --- a/nova/tests/functional/v3/test_quota_sets.py +++ b/nova/tests/functional/v3/test_quota_sets.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class QuotaSetsSampleJsonTests(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_remote_consoles.py b/nova/tests/functional/v3/test_remote_consoles.py index 8df3801dc89f..4da22667fefa 100644 --- a/nova/tests/functional/v3/test_remote_consoles.py +++ b/nova/tests/functional/v3/test_remote_consoles.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ConsolesSampleJsonTests(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_rescue.py b/nova/tests/functional/v3/test_rescue.py index c950431a6940..c91542b3691f 100644 --- a/nova/tests/functional/v3/test_rescue.py +++ b/nova/tests/functional/v3/test_rescue.py @@ -20,7 +20,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class RescueJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_scheduler_hints.py b/nova/tests/functional/v3/test_scheduler_hints.py index d8dae69e8705..5dbd972cd286 100644 --- a/nova/tests/functional/v3/test_scheduler_hints.py +++ b/nova/tests/functional/v3/test_scheduler_hints.py @@ -22,7 +22,7 @@ from nova.tests.unit.image import fake CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class SchedulerHintsJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_security_group_default_rules.py b/nova/tests/functional/v3/test_security_group_default_rules.py index 0b1a8c1a467c..a84caa445443 100644 --- a/nova/tests/functional/v3/test_security_group_default_rules.py +++ b/nova/tests/functional/v3/test_security_group_default_rules.py @@ -18,7 +18,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class SecurityGroupDefaultRulesSampleJsonTest( diff --git a/nova/tests/functional/v3/test_security_groups.py b/nova/tests/functional/v3/test_security_groups.py index 8dd1c381a2aa..7f54aaceb9b4 100644 --- a/nova/tests/functional/v3/test_security_groups.py +++ b/nova/tests/functional/v3/test_security_groups.py @@ -20,7 +20,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') def fake_get(*args, **kwargs): diff --git a/nova/tests/functional/v3/test_server_diagnostics.py b/nova/tests/functional/v3/test_server_diagnostics.py index b3d09edc2ad6..3eb4f54c44d4 100644 --- a/nova/tests/functional/v3/test_server_diagnostics.py +++ b/nova/tests/functional/v3/test_server_diagnostics.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ServerDiagnosticsSamplesJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_server_external_events.py b/nova/tests/functional/v3/test_server_external_events.py index b9a586b44c53..5c6659aea89d 100644 --- a/nova/tests/functional/v3/test_server_external_events.py +++ b/nova/tests/functional/v3/test_server_external_events.py @@ -18,7 +18,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ServerExternalEventsSamplesJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_server_groups.py b/nova/tests/functional/v3/test_server_groups.py index c330fa574a52..b84817896ca3 100644 --- a/nova/tests/functional/v3/test_server_groups.py +++ b/nova/tests/functional/v3/test_server_groups.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import api_sample_base CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ServerGroupsSampleJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_server_metadata.py b/nova/tests/functional/v3/test_server_metadata.py index dc961d2db95f..1197255a583e 100644 --- a/nova/tests/functional/v3/test_server_metadata.py +++ b/nova/tests/functional/v3/test_server_metadata.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ServersMetadataJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_server_password.py b/nova/tests/functional/v3/test_server_password.py index 9cef74250045..6e1798bdf0e7 100644 --- a/nova/tests/functional/v3/test_server_password.py +++ b/nova/tests/functional/v3/test_server_password.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ServerPasswordSampleJsonTests(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_server_usage.py b/nova/tests/functional/v3/test_server_usage.py index 56d0d9dffe12..fe036c4c99ff 100644 --- a/nova/tests/functional/v3/test_server_usage.py +++ b/nova/tests/functional/v3/test_server_usage.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ServerUsageSampleJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_servers.py b/nova/tests/functional/v3/test_servers.py index e427dece3cba..0bbcf0e3c157 100644 --- a/nova/tests/functional/v3/test_servers.py +++ b/nova/tests/functional/v3/test_servers.py @@ -20,7 +20,7 @@ from nova.tests.unit.image import fake CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ServersSampleBase(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_servers_ips.py b/nova/tests/functional/v3/test_servers_ips.py index 036feb489c8d..13d9f612ecf4 100644 --- a/nova/tests/functional/v3/test_servers_ips.py +++ b/nova/tests/functional/v3/test_servers_ips.py @@ -19,7 +19,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ServersIpsJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_services.py b/nova/tests/functional/v3/test_services.py index 5c983e9027c8..c770d9bba9b6 100644 --- a/nova/tests/functional/v3/test_services.py +++ b/nova/tests/functional/v3/test_services.py @@ -22,7 +22,7 @@ from nova.tests.unit.api.openstack.compute.contrib import test_services CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ServicesJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_shelve.py b/nova/tests/functional/v3/test_shelve.py index 06dd85481222..ca2db366d696 100644 --- a/nova/tests/functional/v3/test_shelve.py +++ b/nova/tests/functional/v3/test_shelve.py @@ -20,7 +20,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('shelved_offload_time', 'nova.compute.manager') CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class ShelveJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_simple_tenant_usage.py b/nova/tests/functional/v3/test_simple_tenant_usage.py index b83867e5b2f0..fe58d9521296 100644 --- a/nova/tests/functional/v3/test_simple_tenant_usage.py +++ b/nova/tests/functional/v3/test_simple_tenant_usage.py @@ -22,7 +22,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class SimpleTenantUsageSampleJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_suspend_server.py b/nova/tests/functional/v3/test_suspend_server.py index 97b2f05fd3c8..13f9d759d415 100644 --- a/nova/tests/functional/v3/test_suspend_server.py +++ b/nova/tests/functional/v3/test_suspend_server.py @@ -18,7 +18,7 @@ from nova.tests.functional.v3 import test_servers CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class SuspendServerSamplesJsonTest(test_servers.ServersSampleBase): diff --git a/nova/tests/functional/v3/test_tenant_networks.py b/nova/tests/functional/v3/test_tenant_networks.py index d9bad1852c83..b18c610acfd7 100644 --- a/nova/tests/functional/v3/test_tenant_networks.py +++ b/nova/tests/functional/v3/test_tenant_networks.py @@ -24,7 +24,7 @@ CONF = cfg.CONF CONF.import_opt('enable_network_quota', 'nova.api.openstack.compute.contrib.os_tenant_networks') CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class TenantNetworksJsonTests(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_user_data.py b/nova/tests/functional/v3/test_user_data.py index dfacf27fb2d5..c67fd6d4e4ae 100644 --- a/nova/tests/functional/v3/test_user_data.py +++ b/nova/tests/functional/v3/test_user_data.py @@ -21,7 +21,7 @@ from nova.tests.unit.image import fake CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class UserDataJsonTest(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/functional/v3/test_volumes.py b/nova/tests/functional/v3/test_volumes.py index 0f8183bbd6a3..bf12c405d3d4 100644 --- a/nova/tests/functional/v3/test_volumes.py +++ b/nova/tests/functional/v3/test_volumes.py @@ -31,7 +31,7 @@ from nova.volume import cinder CONF = cfg.CONF CONF.import_opt('osapi_compute_extension', - 'nova.api.openstack.compute.extensions') + 'nova.api.openstack.compute.legacy_v2.extensions') class SnapshotsSampleJsonTests(api_sample_base.ApiSampleTestBaseV3): diff --git a/nova/tests/unit/api/openstack/compute/contrib/test_access_ips.py b/nova/tests/unit/api/openstack/compute/contrib/test_access_ips.py index 85a8d6a61345..dfc80570cafd 100644 --- a/nova/tests/unit/api/openstack/compute/contrib/test_access_ips.py +++ b/nova/tests/unit/api/openstack/compute/contrib/test_access_ips.py @@ -14,10 +14,10 @@ import webob +from nova.api.openstack.compute.legacy_v2 import servers as servers_v20 from nova.api.openstack.compute import plugins from nova.api.openstack.compute.plugins.v3 import access_ips from nova.api.openstack.compute.plugins.v3 import servers as servers_v21 -from nova.api.openstack.compute import servers as servers_v20 from nova.api.openstack import extensions as extensions_v20 from nova.api.openstack import wsgi from nova.compute import api as compute_api diff --git a/nova/tests/unit/api/openstack/compute/contrib/test_admin_password.py b/nova/tests/unit/api/openstack/compute/contrib/test_admin_password.py index 1d36f0658cc5..7dde133eb19b 100644 --- a/nova/tests/unit/api/openstack/compute/contrib/test_admin_password.py +++ b/nova/tests/unit/api/openstack/compute/contrib/test_admin_password.py @@ -16,9 +16,9 @@ import mock import webob +from nova.api.openstack.compute.legacy_v2 import servers from nova.api.openstack.compute.plugins.v3 import admin_password \ - as admin_password_v21 -from nova.api.openstack.compute import servers + as admin_password_v21 from nova.compute import api as compute_api from nova import exception from nova import test diff --git a/nova/tests/unit/api/openstack/compute/contrib/test_availability_zone.py b/nova/tests/unit/api/openstack/compute/contrib/test_availability_zone.py index 5c8ede0f826c..1deda461d771 100644 --- a/nova/tests/unit/api/openstack/compute/contrib/test_availability_zone.py +++ b/nova/tests/unit/api/openstack/compute/contrib/test_availability_zone.py @@ -17,10 +17,10 @@ import datetime import iso8601 from nova.api.openstack.compute.contrib import availability_zone as az_v2 +from nova.api.openstack.compute.legacy_v2 import servers as servers_v2 from nova.api.openstack.compute import plugins from nova.api.openstack.compute.plugins.v3 import availability_zone as az_v21 from nova.api.openstack.compute.plugins.v3 import servers as servers_v21 -from nova.api.openstack.compute import servers as servers_v2 from nova.api.openstack import extensions from nova import availability_zones from nova.compute import api as compute_api diff --git a/nova/tests/unit/api/openstack/compute/contrib/test_block_device_mapping.py b/nova/tests/unit/api/openstack/compute/contrib/test_block_device_mapping.py index 9dd5b7cf26e1..2244e32c0515 100644 --- a/nova/tests/unit/api/openstack/compute/contrib/test_block_device_mapping.py +++ b/nova/tests/unit/api/openstack/compute/contrib/test_block_device_mapping.py @@ -20,11 +20,11 @@ from oslo_serialization import jsonutils from six.moves import range from webob import exc -from nova.api.openstack.compute import extensions +from nova.api.openstack.compute.legacy_v2 import extensions +from nova.api.openstack.compute.legacy_v2 import servers as servers_v2 from nova.api.openstack.compute import plugins from nova.api.openstack.compute.plugins.v3 import block_device_mapping from nova.api.openstack.compute.plugins.v3 import servers as servers_v21 -from nova.api.openstack.compute import servers as servers_v2 from nova import block_device from nova.compute import api as compute_api from nova import exception diff --git a/nova/tests/unit/api/openstack/compute/contrib/test_block_device_mapping_v1.py b/nova/tests/unit/api/openstack/compute/contrib/test_block_device_mapping_v1.py index d5b50ad0195f..d0c864c7cfe5 100644 --- a/nova/tests/unit/api/openstack/compute/contrib/test_block_device_mapping_v1.py +++ b/nova/tests/unit/api/openstack/compute/contrib/test_block_device_mapping_v1.py @@ -19,12 +19,12 @@ from oslo_config import cfg from oslo_serialization import jsonutils from webob import exc -from nova.api.openstack.compute import extensions +from nova.api.openstack.compute.legacy_v2 import extensions +from nova.api.openstack.compute.legacy_v2 import servers as servers_v2 from nova.api.openstack.compute import plugins from nova.api.openstack.compute.plugins.v3 import block_device_mapping_v1 as \ block_device_mapping from nova.api.openstack.compute.plugins.v3 import servers as servers_v21 -from nova.api.openstack.compute import servers as servers_v2 from nova.compute import api as compute_api from nova import exception from nova import test diff --git a/nova/tests/unit/api/openstack/compute/contrib/test_config_drive.py b/nova/tests/unit/api/openstack/compute/contrib/test_config_drive.py index 4f1af8ab7e5f..ef7080c18a58 100644 --- a/nova/tests/unit/api/openstack/compute/contrib/test_config_drive.py +++ b/nova/tests/unit/api/openstack/compute/contrib/test_config_drive.py @@ -19,9 +19,9 @@ from oslo_config import cfg from oslo_serialization import jsonutils import webob +from nova.api.openstack.compute.legacy_v2 import servers as servers_v2 from nova.api.openstack.compute import plugins from nova.api.openstack.compute.plugins.v3 import servers as servers_v21 -from nova.api.openstack.compute import servers as servers_v2 from nova.api.openstack import extensions from nova.compute import api as compute_api from nova.compute import flavors diff --git a/nova/tests/unit/api/openstack/compute/contrib/test_flavor_access.py b/nova/tests/unit/api/openstack/compute/contrib/test_flavor_access.py index 20b3ca655504..0dfa578ecc2d 100644 --- a/nova/tests/unit/api/openstack/compute/contrib/test_flavor_access.py +++ b/nova/tests/unit/api/openstack/compute/contrib/test_flavor_access.py @@ -22,7 +22,7 @@ from webob import exc from nova.api.openstack import api_version_request as api_version from nova.api.openstack.compute.contrib import flavor_access \ as flavor_access_v2 -from nova.api.openstack.compute import flavors as flavors_api +from nova.api.openstack.compute.legacy_v2 import flavors as flavors_api from nova.api.openstack.compute.plugins.v3 import flavor_access \ as flavor_access_v21 from nova import context diff --git a/nova/tests/unit/api/openstack/compute/contrib/test_multiple_create.py b/nova/tests/unit/api/openstack/compute/contrib/test_multiple_create.py index b6fad96fc0ff..606cb8a3a93d 100644 --- a/nova/tests/unit/api/openstack/compute/contrib/test_multiple_create.py +++ b/nova/tests/unit/api/openstack/compute/contrib/test_multiple_create.py @@ -19,13 +19,13 @@ import uuid from oslo_config import cfg import webob +from nova.api.openstack.compute.legacy_v2 import servers as servers_v20 from nova.api.openstack.compute import plugins from nova.api.openstack.compute.plugins.v3 import block_device_mapping as \ block_device_mapping_v21 from nova.api.openstack.compute.plugins.v3 import multiple_create as \ multiple_create_v21 from nova.api.openstack.compute.plugins.v3 import servers as servers_v21 -from nova.api.openstack.compute import servers as servers_v20 from nova.api.openstack import extensions as extensions_v20 from nova.compute import api as compute_api from nova.compute import flavors diff --git a/nova/tests/unit/api/openstack/compute/contrib/test_scheduler_hints.py b/nova/tests/unit/api/openstack/compute/contrib/test_scheduler_hints.py index 7b0d77c9209b..733f6dfee4ba 100644 --- a/nova/tests/unit/api/openstack/compute/contrib/test_scheduler_hints.py +++ b/nova/tests/unit/api/openstack/compute/contrib/test_scheduler_hints.py @@ -19,9 +19,9 @@ from oslo_config import cfg from oslo_serialization import jsonutils from nova.api.openstack import compute +from nova.api.openstack.compute.legacy_v2 import servers as servers_v2 from nova.api.openstack.compute import plugins from nova.api.openstack.compute.plugins.v3 import servers as servers_v21 -from nova.api.openstack.compute import servers as servers_v2 from nova.api.openstack import extensions import nova.compute.api from nova.compute import flavors diff --git a/nova/tests/unit/api/openstack/compute/test_consoles.py b/nova/tests/unit/api/openstack/compute/test_consoles.py index 57c9aade9749..9a01df415049 100644 --- a/nova/tests/unit/api/openstack/compute/test_consoles.py +++ b/nova/tests/unit/api/openstack/compute/test_consoles.py @@ -20,7 +20,7 @@ import uuid as stdlib_uuid from oslo_utils import timeutils import webob -from nova.api.openstack.compute import consoles as consoles_v2 +from nova.api.openstack.compute.legacy_v2 import consoles as consoles_v2 from nova.api.openstack.compute.plugins.v3 import consoles as consoles_v21 from nova.compute import vm_states from nova import console diff --git a/nova/tests/unit/api/openstack/compute/test_extensions.py b/nova/tests/unit/api/openstack/compute/test_extensions.py index 4fbb6e9009fb..195261ac98b2 100644 --- a/nova/tests/unit/api/openstack/compute/test_extensions.py +++ b/nova/tests/unit/api/openstack/compute/test_extensions.py @@ -20,7 +20,8 @@ from oslo_serialization import jsonutils import webob from nova.api.openstack import compute -from nova.api.openstack.compute import extensions as compute_extensions +from nova.api.openstack.compute.legacy_v2 import extensions \ + as compute_extensions from nova.api.openstack import extensions as base_extensions from nova.api.openstack import wsgi from nova import exception diff --git a/nova/tests/unit/api/openstack/compute/test_flavors.py b/nova/tests/unit/api/openstack/compute/test_flavors.py index 926d9c22e406..b6926b6bc24c 100644 --- a/nova/tests/unit/api/openstack/compute/test_flavors.py +++ b/nova/tests/unit/api/openstack/compute/test_flavors.py @@ -18,7 +18,7 @@ import six.moves.urllib.parse as urlparse import webob from nova.api.openstack import common -from nova.api.openstack.compute import flavors as flavors_v2 +from nova.api.openstack.compute.legacy_v2 import flavors as flavors_v2 from nova.api.openstack.compute.plugins.v3 import flavors as flavors_v21 import nova.compute.flavors from nova import context diff --git a/nova/tests/unit/api/openstack/compute/test_image_metadata.py b/nova/tests/unit/api/openstack/compute/test_image_metadata.py index 6eb75f085096..317f1d6c31ef 100644 --- a/nova/tests/unit/api/openstack/compute/test_image_metadata.py +++ b/nova/tests/unit/api/openstack/compute/test_image_metadata.py @@ -19,7 +19,7 @@ import mock from oslo_serialization import jsonutils import webob -from nova.api.openstack.compute import image_metadata +from nova.api.openstack.compute.legacy_v2 import image_metadata from nova.api.openstack.compute.plugins.v3 import image_metadata \ as image_metadata_v21 from nova import exception diff --git a/nova/tests/unit/api/openstack/compute/test_images.py b/nova/tests/unit/api/openstack/compute/test_images.py index b34a9ad03155..6a139f072ee4 100644 --- a/nova/tests/unit/api/openstack/compute/test_images.py +++ b/nova/tests/unit/api/openstack/compute/test_images.py @@ -24,7 +24,7 @@ import mock import six.moves.urllib.parse as urlparse import webob -from nova.api.openstack.compute import images +from nova.api.openstack.compute.legacy_v2 import images from nova.api.openstack.compute.plugins.v3 import images as images_v21 from nova.api.openstack.compute.views import images as images_view from nova import exception diff --git a/nova/tests/unit/api/openstack/compute/test_limits.py b/nova/tests/unit/api/openstack/compute/test_limits.py index be10f34b01ef..edcdcd219cb1 100644 --- a/nova/tests/unit/api/openstack/compute/test_limits.py +++ b/nova/tests/unit/api/openstack/compute/test_limits.py @@ -26,7 +26,7 @@ import six from six.moves import range import webob -from nova.api.openstack.compute import limits +from nova.api.openstack.compute.legacy_v2 import limits from nova.api.openstack.compute.plugins.v3 import limits as limits_v21 from nova.api.openstack.compute import views from nova.api.openstack import wsgi diff --git a/nova/tests/unit/api/openstack/compute/test_server_actions.py b/nova/tests/unit/api/openstack/compute/test_server_actions.py index 797daffe47b0..09ff1aaa0c23 100644 --- a/nova/tests/unit/api/openstack/compute/test_server_actions.py +++ b/nova/tests/unit/api/openstack/compute/test_server_actions.py @@ -22,9 +22,9 @@ from oslo_config import cfg from oslo_utils import uuidutils import webob +from nova.api.openstack.compute.legacy_v2 import servers as servers_v2 from nova.api.openstack.compute import plugins from nova.api.openstack.compute.plugins.v3 import servers as servers_v21 -from nova.api.openstack.compute import servers as servers_v2 from nova.compute import api as compute_api from nova.compute import task_states from nova.compute import vm_states diff --git a/nova/tests/unit/api/openstack/compute/test_server_metadata.py b/nova/tests/unit/api/openstack/compute/test_server_metadata.py index 93f2bffeeb22..dbca384eab18 100644 --- a/nova/tests/unit/api/openstack/compute/test_server_metadata.py +++ b/nova/tests/unit/api/openstack/compute/test_server_metadata.py @@ -22,9 +22,10 @@ from oslo_utils import timeutils import six import webob +from nova.api.openstack.compute.legacy_v2 import server_metadata \ + as server_metadata_v2 from nova.api.openstack.compute.plugins.v3 import server_metadata \ - as server_metadata_v21 -from nova.api.openstack.compute import server_metadata as server_metadata_v2 + as server_metadata_v21 from nova.compute import rpcapi as compute_rpcapi from nova.compute import vm_states import nova.db diff --git a/nova/tests/unit/api/openstack/compute/test_servers.py b/nova/tests/unit/api/openstack/compute/test_servers.py index d33813de4886..ff3e1cf55e53 100644 --- a/nova/tests/unit/api/openstack/compute/test_servers.py +++ b/nova/tests/unit/api/openstack/compute/test_servers.py @@ -32,8 +32,8 @@ import six.moves.urllib.parse as urlparse import testtools import webob -from nova.api.openstack.compute import ips -from nova.api.openstack.compute import servers +from nova.api.openstack.compute.legacy_v2 import ips +from nova.api.openstack.compute.legacy_v2 import servers from nova.api.openstack.compute import views from nova.api.openstack import extensions from nova.compute import api as compute_api diff --git a/nova/tests/unit/api/openstack/fakes.py b/nova/tests/unit/api/openstack/fakes.py index 5728e1e34cc8..d21e7a7ecd23 100644 --- a/nova/tests/unit/api/openstack/fakes.py +++ b/nova/tests/unit/api/openstack/fakes.py @@ -31,7 +31,7 @@ from nova.api import openstack as openstack_api from nova.api.openstack import api_version_request as api_version from nova.api.openstack import auth from nova.api.openstack import compute -from nova.api.openstack.compute import limits +from nova.api.openstack.compute.legacy_v2 import limits from nova.api.openstack.compute import versions from nova.api.openstack import urlmap from nova.api.openstack import wsgi as os_wsgi @@ -157,11 +157,9 @@ def stub_out_rate_limiting(stubs): super(limits.RateLimitingMiddleware, self).__init__(app) self.application = app - stubs.Set(nova.api.openstack.compute.limits.RateLimitingMiddleware, - '__init__', fake_rate_init) - - stubs.Set(nova.api.openstack.compute.limits.RateLimitingMiddleware, - '__call__', fake_wsgi) + v2_limits = nova.api.openstack.compute.legacy_v2.limits + stubs.Set(v2_limits.RateLimitingMiddleware, '__init__', fake_rate_init) + stubs.Set(v2_limits.RateLimitingMiddleware, '__call__', fake_wsgi) def stub_out_instance_quota(stubs, allowed, quota, resource='instances'):