Filter network related limits from limits API

As all the network related proxy APIs were deprecated, the related limits
should be filtered out of limits API also.

This patch doesn't bump the max api version, due to the patch separation.
The max api version will bump in the last patch.

Partially implements blueprint deprecate-api-proxies

Change-Id: I00bad055847adbbe26fe2f9225a4adde18f546b8
This commit is contained in:
He Jie Xu 2016-07-20 23:11:11 +08:00
parent 603859eb45
commit 62d57e57e3
3 changed files with 83 additions and 8 deletions

View File

@ -13,6 +13,9 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova.api.openstack import api_version_request
from nova.api.openstack.api_version_request \
import MAX_PROXY_API_SUPPORT_VERSION
from nova.api.openstack.compute.views import limits as limits_views
from nova.api.openstack import extensions
from nova.api.openstack import wsgi
@ -24,11 +27,32 @@ QUOTAS = quota.QUOTAS
ALIAS = 'limits'
def _get_filter_result_version():
"""Calculate the start API version which needs to filter the network
related limits. MAX_PROXY_API_SUPPORT_VERSION is the end API version
of supporting those network related limits. So we return
MAX_PROXY_API_SUPPORT_VERSION +1 in this method.
"""
filter_result_version = api_version_request.APIVersionRequest(
MAX_PROXY_API_SUPPORT_VERSION)
filter_result_version.ver_minor = filter_result_version.ver_minor + 1
return filter_result_version.get_string()
class LimitsController(wsgi.Controller):
"""Controller for accessing limits in the OpenStack API."""
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@extensions.expected_errors(())
def index(self, req):
return self._index(req)
@wsgi.Controller.api_version(_get_filter_result_version()) # noqa
@extensions.expected_errors(())
def index(self, req):
return self._index(req, filter_result=True)
def _index(self, req, filter_result=False):
"""Return all global limit information."""
context = req.environ['nova.context']
context.can(limits_policies.BASE_POLICY_NAME)
@ -38,8 +62,7 @@ class LimitsController(wsgi.Controller):
abs_limits = {k: v['limit'] for k, v in quotas.items()}
builder = self._get_view_builder(req)
return builder.build(abs_limits)
return builder.build(abs_limits, filter_result=filter_result)
def _get_view_builder(self, req):
return limits_views.ViewBuilderV21()

View File

@ -16,6 +16,12 @@
import six
# This is a list of limits which needs to filter out from the API response.
# This is due to the deprecation of network related proxy APIs, the related
# limit should be removed from the API also.
FILTERED_LIMITS = ['floating_ips', 'security_groups', 'security_group_rules']
class ViewBuilder(object):
"""OpenStack API base limits view builder."""
@ -35,8 +41,9 @@ class ViewBuilder(object):
"security_group_rules": ["maxSecurityGroupRules"],
}
def build(self, absolute_limits):
absolute_limits = self._build_absolute_limits(absolute_limits)
def build(self, absolute_limits, filter_result=False):
absolute_limits = self._build_absolute_limits(
absolute_limits, filter_result=filter_result)
output = {
"limits": {
@ -47,16 +54,20 @@ class ViewBuilder(object):
return output
def _build_absolute_limits(self, absolute_limits):
def _build_absolute_limits(self, absolute_limits, filter_result=False):
"""Builder for absolute limits
absolute_limits should be given as a dict of limits.
For example: {"ram": 512, "gigabytes": 1024}.
"""
filtered_limits = []
if filter_result:
filtered_limits = FILTERED_LIMITS
limits = {}
for name, value in six.iteritems(absolute_limits):
if name in self.limit_names and value is not None:
if (name in self.limit_names and
value is not None and name not in filtered_limits):
for limit_name in self.limit_names[name]:
limits[limit_name] = value
return limits

View File

@ -67,9 +67,10 @@ class LimitsControllerTestV21(BaseLimitTestSuite):
def _get_index_request(self, accept_header="application/json",
tenant_id=None):
"""Helper to set routing arguments."""
request = webob.Request.blank("/")
request = fakes.HTTPRequest.blank('', version='2.1')
if tenant_id:
request = webob.Request.blank("/?tenant_id=%s" % tenant_id)
request = fakes.HTTPRequest.blank('/?tenant_id=%s' % tenant_id,
version='2.1')
request.accept = accept_header
request.environ["wsgiorg.routing_args"] = (None, {
@ -235,3 +236,43 @@ class LimitsPolicyEnforcementV21(test.NoDBTestCase):
self.assertEqual(
"Policy doesn't allow %s to be performed." % rule_name,
exc.format_message())
class LimitsControllerTestV236(BaseLimitTestSuite):
def setUp(self):
super(LimitsControllerTestV236, self).setUp()
self.controller = limits_v21.LimitsController()
self.req = fakes.HTTPRequest.blank("/?tenant_id=faketenant",
version='2.36')
def test_index_filtered(self):
absolute_limits = {
'ram': 512,
'instances': 5,
'cores': 21,
'key_pairs': 10,
'floating_ips': 10,
'security_groups': 10,
'security_group_rules': 20,
}
def _get_project_quotas(context, project_id, usages=True):
return {k: dict(limit=v) for k, v in absolute_limits.items()}
with mock.patch('nova.quota.QUOTAS.get_project_quotas') as \
get_project_quotas:
get_project_quotas.side_effect = _get_project_quotas
response = self.controller.index(self.req)
expected_response = {
"limits": {
"rate": [],
"absolute": {
"maxTotalRAMSize": 512,
"maxTotalInstances": 5,
"maxTotalCores": 21,
"maxTotalKeypairs": 10,
},
},
}
self.assertEqual(expected_response, response)