This package provides the keystone_limits
Python module, which
contains the keystone_preprocess()
preprocessor, the
KeystoneClassLimit
limit class, and the KeystoneTurnstileMiddleware
replacement middleware class, all for use with Turnstile. These
pieces work together to provide class-based rate limiting integration
with keystone. To use, you must configure the Turnstile middleware with
the following configuration:
[filter:turnstile] paste.filter_factory = turnstile.middleware:turnstile_filter turnstile = keystone_limits:KeystoneTurnstileMiddleware preprocess = keystone_limits:keystone_preprocess redis.host = <your Redis database host>
Then you must add the turnstile filter to your pipelines:
[pipeline:public_api] pipeline = turnstile token_auth admin_token_auth xml_body json_body debug ec2_extension public_service [pipeline:admin_api] pipeline = turnstile token_auth admin_token_auth xml_body json_body debug ec2_extension crud_extension admin_service
In order to read and write limits, you need to use the turnstile
setup_limits
and load_limits
commands. Sample configuration and
limit files are provided in the etc/ directory:
setup_limits etc/keystone_limits.conf etc/default_limits.xml dump_limits etc/keystone_limits.conf loaded_limits.xml cat loaded_limits.xml <?xml version='1.0' encoding='UTF-8'?> <limits> <limit class="keystone_limits:KeystoneClassLimit"> <attr name="rate_class">tokens</attr> <attr name="queries"/> <attr name="unit">minute</attr> <attr name="uri">/tokens</attr> <attr name="use"/> <attr name="uuid">d8b13e95-4a15-4816-aefd-cb5cef1e78da</attr> <attr name="value">2</attr> <attr name="verbs"> <value>POST</value> </attr> </limit> </limits>
These values are configurable in the XML. After you've changed them,
they need to be reloaded into the redis database using the
setup_limits
command.
With the above configuration, the middleware will limit requests to the
/tokens
URL to 2 POSTs per minute.
You can set up additional rules using the Routes syntax.
For example, keeping the example above, in case you wanted to limit all
the other requests using a different rule, you could add another limit
to the configuration file (and then reload using setup_limits
)
<?xml version='1.0' encoding='UTF-8'?> <limits> <limit class="keystone_limits:KeystoneClassLimit"> <attr name="rate_class">tokens</default> <attr name="unit">minute</attr> <attr name="uri">{everything:.*}</attr> <attr name="value">10</attr> </limit> </limits>
Requests are limited based on incoming IP address.