Add ngx_http_limit_conn_module functionality
Add posibility to limit the number of connections per the defined key
Change-Id: Ic05f9c4a4904ea4293889bc3d88d0122525df1b0
Related-Prod: PROD-24400
diff --git a/README.rst b/README.rst
index 0e04cf8..6e28916 100644
--- a/README.rst
+++ b/README.rst
@@ -415,6 +415,42 @@
enabled: true
+Use `ngx_http_limit_conn_module` module that is used to set the shared memory
+zone and the maximum allowed number of connections for a given key value.
+The `limit_conn_module` might be configured globally or applied to specific
+nginx site.
+
+.. code-block:: yaml
+
+ nginx:
+ server:
+ limit_conn_module:
+ limit_conn_zone:
+ global_limit_conn_zone:
+ key: 'binary_remote_addr'
+ size: 10m
+ limit_conn_status: 503
+ limit_conn:
+ global_limit_conn_zone:
+ connection: 50
+ enabled: true
+
+
+To apply connection limiting to particular site only `limit_conn` should be
+applied on site level, for example:
+
+.. code-block:: yaml
+
+ nginx:
+ server:
+ site:
+ nginx_proxy_openstack_web:
+ limit_conn_module:
+ limit_conn:
+ global_limit_conn_zone:
+ connections: 25
+ enabled: true
+
Gitlab server with user for basic auth:
.. code-block:: yaml
diff --git a/nginx/files/_limit_conn_module.conf b/nginx/files/_limit_conn_module.conf
new file mode 100644
index 0000000..4250415
--- /dev/null
+++ b/nginx/files/_limit_conn_module.conf
@@ -0,0 +1,19 @@
+{%- for _item,_value in _data.get('limit_conn_zone', {}).iteritems() %}
+ {%- if _value.get('enabled', 'True') %}
+limit_conn_zone ${{ _value.key }} zone={{ _value.get('name', _item) }}:{{ _value.size}};
+ {%- endif %}
+{%- endfor %}
+
+{%- for _item,_value in _data.get('limit_conn', {}).iteritems() %}
+ {%- if _value.get('enabled', 'True') %}
+limit_conn {{ _value.get('name', _item) }} {{ _value.get('connections', '50') }};
+ {%- endif %}
+{%- endfor %}
+
+{%- if _data.limit_conn_status is defined %}
+limit_conn_status {{ _data.limit_conn_status }};
+{%- endif %}
+
+{%- if _data.limit_conn_log_level is defined %}
+limit_conn_log_level {{ _data.limit_conn_log_level }};
+{% endif %}
diff --git a/nginx/files/nginx.conf b/nginx/files/nginx.conf
index 5a15b4a..9429740 100644
--- a/nginx/files/nginx.conf
+++ b/nginx/files/nginx.conf
@@ -84,6 +84,11 @@
{%- include "nginx/files/_limit_req_module.conf" %}
{%- endif %}
+{%- if server.limit_conn_module is defined %}
+ {%- set _data = server.limit_conn_module %}
+ {%- include "nginx/files/_limit_conn_module.conf" %}
+{%- endif %}
+
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*.conf;
diff --git a/nginx/files/proxy.conf b/nginx/files/proxy.conf
index 2353c93..ca69367 100644
--- a/nginx/files/proxy.conf
+++ b/nginx/files/proxy.conf
@@ -133,8 +133,14 @@
{%- include "nginx/files/_limit_req_module.conf" %}
{%- endif %}
+ {%- if site.limit_conn_module is defined %}
+ {%- set _data = site.limit_conn_module %}
+ {%- include "nginx/files/_limit_conn_module.conf" %}
+ {%- endif %}
+
{# The approach below is deprecated, as it was limited funtionality #}
{# compare to flexibility that nginx provide. site:limit_req_module:limit_req shall be used instead. #}
+
{%- if site.get('limit', {}).get('enabled', False) %}
limit_req zone={{ site_name }}{% if site.limit.get('burst', False) %} burst={{ site.limit.burst }}{% endif %}{% if site.limit.get('nodelay', False) %} nodelay{% endif %};
{%- for subfilter_name, subfilter in site.limit.get('subfilters', {}).items() %}
diff --git a/tests/pillar/proxy_rate_limit.sls b/tests/pillar/proxy_rate_limit.sls
index 7dc7156..7cebd59 100644
--- a/tests/pillar/proxy_rate_limit.sls
+++ b/tests/pillar/proxy_rate_limit.sls
@@ -42,6 +42,21 @@
size: 10m
rate: '1r/s'
limit_req_status: 503
+ limit_conn_module:
+ limit_conn_zone:
+ global_limit_conn_zone:
+ key: 'binary_remote_addr'
+ size: 20m
+ enabled: true
+ openstack_web_conn_zone:
+ key: 'binary_remote_addr'
+ size: 10m
+ enabled: true
+ limit_conn:
+ global_limit_conn_zone:
+ connections: 100
+ enabled: true
+ limit_conn_status: 503
site:
nginx_proxy_site01:
enabled: true
@@ -59,3 +74,9 @@
global_limit_zone:
burst: 5
enabled: true
+ limit_conn_module:
+ limit_conn:
+ openstack_web_conn_zone:
+ connections: 50
+ enabled: true
+ limit_conn_status: 503