rate_limit package

Submodules

rate_limit.backend module

class rate_limit.backend.Backend(host, port, rate_limit_response, logger=<rate_limit.log.Logger object>, **kwargs)

Bases: object

Backend for storing rate limits.

is_available()

Check whether the backend is available and the version supported.

Returns:bool whether it’s available, string describing the error (if any)
rate_limit(scope, action, target_type_uri, max_rate_string)

Handle the rate limit for the given scope, action, target_type_uri and max_rate_string. If scope is not given (scope=None) the global (non-project specific) rate limit is checked.

Parameters:
  • scope – the scope (project uuid, host ip, etc., ..) or None for global rate limits
  • action – the CADF action
  • target_type_uri – the CADF target type URI
  • max_rate_string – the max. rate limit per sliding window
Returns:

the configured RateLimitResponse or None

class rate_limit.backend.RedisBackend(host, port, rate_limit_response, max_sleep_time_seconds, log_sleep_time_seconds, logger=<rate_limit.log.Logger object>, **kwargs)

Bases: rate_limit.backend.Backend

Stable Redis backend for storing rate limits.

is_available()

Check whether the redis is available and supported.

rate_limit(scope, action, target_type_uri, max_rate_string)

Handle the rate limit for the given scope, action, target_type_uri and max_rate_string. If scope is not given (scope=None) the global (non-project specific) rate limit is checked.

Parameters:
  • scope – the scope (project uuid, host ip, etc., ..) or None for global rate limits
  • action – the CADF action
  • target_type_uri – the CADF target type URI
  • max_rate_string – the max. rate limit per sliding window
Returns:

the configured RateLimitResponse or None

rate_limit.common module

class rate_limit.common.Constants

Bases: object

Common constants used in various places.

blacklist_response = 'blacklist_response'
content_type_html = 'text/html'
content_type_json = 'application/json'
header_ratelimit_limit = 'X-RateLimit-Limit'
header_ratelimit_remaining = 'X-RateLimit-Remaining'
header_ratelimit_reset = 'X-RateLimit-Retry-After'
header_ratelimit_retry_after = 'X-Retry-After'
initiator_host_address = 'initiator_host_address'
initiator_project_id = 'initiator_project_id'
limes_api_uri = 'limes_api_uri'
limes_refresh_interval_seconds = 'limes_refresh_interval_seconds'
limes_service_type = 'limes'
log_sleep_time_seconds = 'log_sleep_time_seoncds'
max_sleep_time_seconds = 'max_sleep_time_seconds'
metric_errors_total = 'errors_total'
metric_prefix = 'openstack_ratelimit'
metric_requests_blacklisted_total = 'requests_blacklisted_total'
metric_requests_ratelimit_total = 'requests_ratelimit_total'
metric_requests_unknown_classification = 'requests_unknown_classification_total'
metric_requests_whitelisted_total = 'requests_whitelisted_total'
ratelimit_response = 'ratelimit_response'
target_project_id = 'target_project_id'
unknown = 'unknown'
rate_limit.common.build_uri(base, path)

Build the URI using base and path.

Parameters:
  • base
  • path
Returns:

rate_limit.common.find_item_by_key_in_list(item, key, list_to_search, empty_item={})

Find an item in a list by its key.

Parameters:
  • item – the item we’re looking for
  • key – the key by which the item can be identified
  • list_to_search – list of items
  • empty_item – is returned when the item could not be found
Returns:

rate_limit.common.is_none_or_unknown(thing)

Check if a thing is None or unknown.

Parameters:thing – the cadf action, cadf target_type_uri, ..
Returns:bool whether thing is None or unknown
rate_limit.common.is_ratelimit_by_project_id(ratelimit_by)

Check whether the scope is the initiator or target project id.

Parameters:ratelimit_by – the configurable scope by which is rate limited
Returns:bool whether the scope is initiator|target project id
rate_limit.common.is_unlimited(rate_limit)

Check whether a rate limit is None or unlimited (indicated by ‘-1’).

Parameters:rate_limit – the rate limit to check
Returns:bool
rate_limit.common.key_func(scope, action, target_type_uri)

Create the key based on scope, action, target_type_uri: ‘<scope>_<action>_<target_type_uri>’. If no scope is given (scope=None), the scope is global (global, non-project specific rate limits).

Parameters:
  • scope – the identifier of the scope (project uid, user uid, ip addr, ..) or ‘global’
  • action – the cadf action
  • target_type_uri – the target type uri of the request
Returns:

the key ‘<scope>_<action>_<target_type_uri>’

rate_limit.common.listitem_to_int(listthing, idx, default=0)

Safely get an item by index from a list.

Parameters:
  • listthing – the list
  • idx – the index of the item
  • default – the default value if item not found
Returns:

the item as int or the default value

rate_limit.common.load_config(cfg_file)

Load a yaml configuration as a dictionary.

Parameters:cfg_file – path to the yaml configuration file
Returns:the configuration as dictionary
rate_limit.common.load_lua_script(filename, foldername='lua')

Load the specified LUA script.

Parameters:
  • filename – the filename of the script
  • foldername – the name of the folder containing the script
Returns:

the content or None

rate_limit.common.printable_timestamp(timestamp)
rate_limit.common.to_int(raw_value, default=0)

Safely parse a raw value and convert to an integer. If that fails return the default value.

Parameters:
  • raw_value – the raw value
  • default – the fallback value if conversion fails
Returns:

the value as int or None

rate_limit.errors module

exception rate_limit.errors.ConfigError

Bases: exceptions.Exception

Raised when configuration could not be loaded or interpreted.

exception rate_limit.errors.LimesError

Bases: exceptions.Exception

Raised when rate limits cannot be fetched from limes.

exception rate_limit.errors.UnitConversionError

Bases: exceptions.Exception

Raised when a unit is invalid and cannot be converted.

rate_limit.log module

class rate_limit.log.Logger(name, product_name='rate_limit')

Bases: object

Logger that attempts to log and ignores any error.

debug(msg)
error(msg)
info(msg)
warning(msg)

rate_limit.provider module

class rate_limit.provider.ConfigurationRateLimitProvider(service_type, logger=<rate_limit.log.Logger object>, **kwargs)

Bases: rate_limit.provider.RateLimitProvider

The provider to obtain rate limits from a configuration file.

get_global_rate_limits(action, target_type_uri, **kwargs)

Get the global rate limit per action and target type URI. Returns -1 if unlimited.

Parameters:
  • action – the CADF action for the request
  • target_type_uri – the target type URI of the request
  • kwargs – optional, additional parameters
Returns:

the global rate limit or -1 (unlimited) if not set

get_local_rate_limits(scope, action, target_type_uri, **kwargs)

Get the local (project/domain/ip, ..) rate limit per scope, action, target type URI.

Parameters:
  • scope – the UUID of the project, domain or the IP
  • action – the CADF action of the request
  • target_type_uri – the target type URI of the request
  • kwargs – optional, additional parameters
Returns:

the local rate limit or -1 if not set

read_rate_limits_from_config(config_path)

Read rate limits from configuration file.

Parameters:config_path – path to the configuration file
class rate_limit.provider.LimesRateLimitProvider(service_type, logger=<rate_limit.log.Logger object>, **kwargs)

Bases: rate_limit.provider.RateLimitProvider

The provider to obtain rate limits from limes.

get_global_rate_limits(action, target_type_uri, **kwargs)

Get the global rate limit per action and target type URI. Returns -1 if unlimited.

Parameters:
  • action – the cadf action for the request
  • target_type_uri – the target type URI of the request
  • kwargs – optional, additional parameters
Returns:

the global rate limit or -1 if not set

get_local_rate_limits(scope, action, target_type_uri, **kwargs)

Get the local (project/domain/ip, ..) rate limit per scope, action, target type URI.

Parameters:
  • scope – the UUID of the project, domain or the IP
  • action – the cadf action of the request
  • target_type_uri – the target type URI of the request
  • kwargs – optional, additional parameters. should contain the domain id
Returns:

the local rate limit or -1 if not set

list_ratelimits_for_projects_in_domain(project_id, domain_id=None)

Query limes for rate limits for projects in a domain.

Parameters:
  • domain_id – the domain uid
  • project_id – optional project uid
Returns:

dictionary of projects and their rates in the given domain

class rate_limit.provider.RateLimitProvider(service_type, logger=<rate_limit.log.Logger object>, **kwargs)

Bases: object

Interface to obtain rate limits from different sources.

get_global_rate_limits(action, target_type_uri, **kwargs)

Get the global rate limit per action and target type URI. Returns -1 if unlimited.

Parameters:
  • action – the CADF action for the request
  • target_type_uri – the target type URI of the request
  • kwargs – optional, additional parameters
Returns:

the global rate limit or -1 if not set

get_local_rate_limits(scope, action, target_type_uri, **kwargs)

Get the local (project/domain/ip, ..) rate limit per scope, action, target type URI.

Parameters:
  • scope – the UUID of the project, domain or the IP
  • action – the CADF action of the request
  • target_type_uri – the target type URI of the request
  • kwargs – optional, additional parameters
Returns:

the local rate limit or -1 if not set

rate_limit.rate_limit module

class rate_limit.rate_limit.OpenStackRateLimitMiddleware(app, **conf)

Bases: object

OpenStack Rate Limit Middleware enforces configurable rate limits.

Per combination of:
service ( compute, identity, object-store, .. ) scope ( initiator|target project uid, initiator host address ) target_type_uri ( service/compute/servers, service/storage/block/volumes,.. ) action ( create, read, update, delete, authenticate, .. )
classmethod factory(global_config, **local_config)
get_action_from_rate_limit_groups(action)

Multiple CADF actions can be grouped and accounted as one entity.

Parameters:action – the original CADF action
Returns:the original action or action as per grouping
get_scope_action_target_type_uri_from_environ(environ)

Get the scope, action, target type URI from the request environ.

Parameters:environ – the request environ
Returns:tuple of scope, action, target type URI
is_scope_blacklisted(key_to_check)

Check whether a scope (user_id, project_id or client ip) is blacklisted.

Parameters:key_to_check – the user, project uid or client ip
Returns:bool whether the key is blacklisted
is_scope_whitelisted(key_to_check)

Check whether a scope (user_id, project_id or client ip) is whitelisted.

Parameters:key_to_check – the user, project uid or client ip
Returns:bool whether the key is whitelisted
is_user_blacklisted(user_to_check)

Check whether a user is blacklisted.

Parameters:user_to_check – the name of the user to check
Returns:bool whether user is blacklisted
is_user_whitelisted(user_to_check)

Check whether a user is whitelisted.

Parameters:user_to_check – the name of the user to check
Returns:bool whether user is whitelisted

rate_limit.response module

class rate_limit.response.BlacklistResponse(status='497 Blacklisted', status_code=497, headerlist=None, body=None, json_body=None, environ=None)

Bases: webob.response.Response

The blacklist response and defaults, which can be overwritten via configuration.

set_environ(environ)

Set the environ of the request triggering this response.

class rate_limit.response.RateLimitExceededResponse(status='429 Too Many Requests', status_code=429, headerlist=None, body=None, json_body=None, environ=None)

Bases: webob.response.Response

The rate limit response and defaults, which can be overwritten via configuration.

set_environ(environ)

Set the environ of the request triggering this response.

set_headers(ratelimit, remaining, retry_after)

Set response headers.

Parameters:
  • ratelimit – the limit for the current request in the format <n>r/<m><t>
  • remaining – the number of remaining requests within the current window
  • retry_after – the remaining window before the rate limit resets in seconds
rate_limit.response.response_parameters_from_config(response_config)

Get custom response from configuration.

Parameters:response_config – the configuration of the response
Returns:code, headers, content_type, body, json_body

rate_limit.units module

class rate_limit.units.Units

Bases: enum.Enum

Defines the units that can be used to rate limit requests.

DAY = 'd'
HOUR = 'h'
MILLISECOND = 'ms'
MINUTE = 'm'
NANOSECOND = 'ns'
SECOND = 's'
get_conversion_factor = <function get_conversion_factor>
parse = <function parse>
parse_and_convert_to_per_seconds = <function parse_and_convert_to_per_seconds>
parse_sliding_window_rate_limit = <function parse_sliding_window_rate_limit>

Module contents

rate_limit.main(global_config, **settings)