Enable rate-limiting for the API.

This commit is contained in:
Christopher Glass 2015-10-02 14:05:06 +02:00
parent 0af9078ed0
commit ca94f0699d
6 changed files with 51 additions and 1 deletions

View File

@ -411,3 +411,12 @@ options:
description: |
List of filter class names to use for filtering hosts when not specified in
the request.
api-rate-limit-rules:
type: string
default:
description: |
The API rate-limit rules to use for the deployed nova API, if any.
Contents of this config options will be inserted in the api-paste.ini file
under the "filter:ratelimit" section as "limits". The syntax for these
rules is documented at
http://docs.openstack.org/kilo/config-reference/content/configuring-compute-API.html

View File

@ -409,3 +409,11 @@ class ConsoleSSLContext(context.OSContextGenerator):
ctxt['html5proxy_base_url'] = url
return ctxt
class APIRateLimitingContext(context.OSContextGenerator):
def __call__(self):
ctxt = {}
rate_rules = config('api-rate-limit-rules')
if rate_rules:
ctxt['api_rate_limit_rules'] = rate_rules
return ctxt

View File

@ -199,7 +199,8 @@ BASE_RESOURCE_MAP = OrderedDict([
}),
(NOVA_API_PASTE, {
'services': [s for s in BASE_SERVICES if 'api' in s],
'contexts': [nova_cc_context.IdentityServiceContext()],
'contexts': [nova_cc_context.IdentityServiceContext(),
nova_cc_context.APIRateLimitingContext()],
}),
(QUANTUM_CONF, {
'services': ['quantum-server'],

View File

@ -85,6 +85,9 @@ paste.filter_factory = nova.api.openstack.auth:NoAuthMiddlewareV3.factory
[filter:ratelimit]
paste.filter_factory = nova.api.openstack.compute.limits:RateLimitingMiddleware.factory
{% if api_rate_limit_rules -%}
limits = {{ api_rate_limit_rules }}
{% endif -%}
[filter:sizelimit]
paste.filter_factory = nova.api.sizelimit:RequestBodySizeLimiter.factory

View File

@ -104,6 +104,9 @@ paste.filter_factory = nova.api.openstack.auth:NoAuthMiddlewareV3.factory
[filter:ratelimit]
paste.filter_factory = nova.api.openstack.compute.limits:RateLimitingMiddleware.factory
{% if api_rate_limit_rules -%}
limits = {{ api_rate_limit_rules }}
{% endif -%}
[filter:sizelimit]
paste.filter_factory = oslo.middleware:RequestBodySizeLimiter.factory

View File

@ -98,6 +98,10 @@ class NovaCCBasicDeployment(OpenStackAmuletDeployment):
}
nova_cc_config['openstack-origin-git'] = yaml.dump(openstack_origin_git)
nova_config['openstack-origin-git'] = yaml.dump(openstack_origin_git)
# Add some rate-limiting options to the charm. These will noop before
# icehouse.
nova_cc_config['api-rate-limit-rules'] = "( POST, '*', .*, 9999, MINUTE )"
keystone_config = {'admin-password': 'openstack',
'admin-token': 'ubuntutesting'}
configs = {'nova-cloud-controller': nova_cc_config,
@ -647,3 +651,25 @@ class NovaCCBasicDeployment(OpenStackAmuletDeployment):
u.delete_image(self.glance, image)
u.delete_instance(self.nova_demo, instance)
def test_api_rate_limiting_is_enabled_for_icehouse_or_more(self):
"""
The API rate limiting is enabled for icehouse or more. Otherwise the
api-paste.ini file is left untouched.
"""
unit = self.nova_cc_sentry
conf = '/etc/nova/api-paste.ini'
section = "filter:ratelimit"
factory = ("nova.api.openstack.compute.limits:RateLimitingMiddleware"
".factory")
if self._get_openstack_release() >= self.precise_icehouse:
expected = {"paste.filter_factory": factory,
"limits": "( POST, *, .*, 9999, MINUTE );"}
else:
expected = {"paste.filter_factory": factory}
ret = u.validate_config_data(unit, conf, section, expected)
if ret:
message = "api paste config error: {}".format(ret)
amulet.raise_status(amulet.FAIL, msg=message)