| {%- from "haproxy/map.jinja" import proxy, invalid_section_options with context -%} |
| |
| {% macro checktimeout(value) -%} |
| {% if value is number -%}{{ value }}ms{% else -%}{{ value }}{% endif %} |
| {%- endmacro -%} |
| |
| global |
| {%- for param_name, param in proxy.global.items()|sort %} {# Iterate through all global parameters #} |
| {%- if param is iterable and param is not string and param|length > 0 %} {# Param is a list of values #} |
| {%- for value in param %} {# Iterate through list #} |
| {{ param_name|replace('_', '.') }} {{ value }} {# Add each value from list #} |
| {%- endfor %} |
| {%- elif param == true or param|lower == 'true' %} {# Param is boolean and true #} |
| {{ param_name|replace('_', '.') }} {# Add param name if value is true #} |
| {%- elif (param is string and param != '' and param|lower != 'false') or (param is number and param != false) %} {# Param is a string and is not empty or is a number #} |
| {{ param_name|replace('_', '.') }} {{ param }} {# Add a string value #} |
| {%- endif %} |
| {%- endfor %} |
| |
| {%- if salt['pkg.version']('haproxy')[:3] >= '1.6' %} |
| # SSL options |
| ca-base /etc/haproxy/ssl |
| crt-base /etc/haproxy/ssl |
| tune.ssl.default-dh-param 2048 |
| ssl-default-bind-ciphers {{ proxy.ssl_defaults.bind_ciphers }} |
| ssl-default-bind-options {{ proxy.ssl_defaults.bind_options }} |
| ssl-default-server-ciphers {{ proxy.ssl_defaults.server_ciphers }} |
| ssl-default-server-options {{ proxy.ssl_defaults.server_options }} |
| {%- endif %} |
| |
| defaults |
| log global |
| mode http |
| |
| maxconn {{ proxy.maxconn|default(8000) }} |
| {%- if proxy.get('forwardfor', {}).enabled|default(False) %} |
| option forwardfor{% if proxy.forwardfor.get('except', False) %} except {{proxy.forwardfor.except}}{% endif %}{% if proxy.forwardfor.get('header', False) %} header {{proxy.forwardfor.header}}{% endif %}{% if proxy.forwardfor.get('if-none') %} if-none{% endif %} |
| {%- endif %} |
| option redispatch |
| retries {{ proxy.retries|default(3) }} |
| stats enable |
| |
| timeout http-request {{ checktimeout(proxy.get('timeout', {}).get('http-request','10s')) }} |
| timeout queue {{ checktimeout(proxy.get('timeout', {}).get('queue', '1m')) }} |
| timeout connect {{ checktimeout(proxy.get('timeout', {}).get('connect', '10s')) }} |
| timeout client {{ checktimeout(proxy.get('timeout', {}).get('client', '1m')) }} |
| timeout server {{ checktimeout(proxy.get('timeout', {}).get('server', '1m')) }} |
| timeout check {{ checktimeout(proxy.get('timeout', {}).get('check', '10s')) }} |
| |
| {%- if proxy.get('listen') is mapping and proxy.listen.admin_page is defined and proxy.listen.admin_page.user is defined %} |
| |
| userlist STATSUSERS |
| group admin users admin |
| user {{ proxy.listen.admin_page.user }} insecure-password {{ proxy.listen.admin_page.password }} |
| user stats insecure-password {{ proxy.listen.admin_page.password }} |
| {# |
| {%- for listen_name, listen in proxy.get('listen', {}).iteritems() %} |
| {%- if listen.user is defined %} |
| user {{ listen.user }} insecure-password {{ listen.password }} |
| {%- endif %} |
| {%- endfor %} |
| #} |
| {%- endif %} |
| |
| {% if proxy.get('userlist') is defined %} |
| {%- for userlist_name, userlist in proxy.get('userlist', {}).iteritems() %} |
| userlist {{ userlist.name|default(userlist_name) }} |
| {%- if userlist.groups is defined %} |
| {%- set groupNames = [] %} |
| {%- for group in userlist.groups %} |
| {%- do groupNames.append(group.name) %} |
| group {{ group.name }} {% if group.users is defined %} users {{ group.users|join(',') }} {% endif %} |
| {%- endfor %} |
| {% endif %} |
| {%- for user in userlist.users %} |
| {%- if user.get('insecure_password', False) %} |
| {%- set userPasswordField = 'insecure-password ' + user.password %} |
| {%- elif user.get('shadow_password', False) %} |
| {%- set userPasswordField = 'password ' + salt['shadow.gen_password'](user.password) %} |
| {%- else %} |
| {%- set userPasswordField = 'password ' + user.password %} |
| {%- endif %} |
| {%- if user.groups is defined %} |
| {%- set userGroupsField = 'groups ' + user.groups|join(',') %} |
| {%- elif userlist.groups is defined %} |
| {%- set userGroupsField = 'groups ' + groupNames|join(',') %} |
| {%- endif %} |
| user {{ user.name }} {{ userPasswordField }} {{ userGroupsField }} |
| {%- endfor %} |
| {%- endfor %} |
| {%- endif %} |
| |
| {%- for listen_name, listen in proxy.get('listen', {}).iteritems() %} |
| {%- if listen.get('enabled', True) %} |
| {%- if listen.get('format', 'listen') == 'listen' %} |
| |
| listen {{ listen_name }} |
| {%- for bind in listen.binds %} |
| bind {{ bind.address }}:{{ bind.port }} {% if bind.get('ssl', {}).enabled|default(False) %}{% if bind.ssl.pem_file is defined %}ssl crt {{ bind.ssl.pem_file }}{% else %}ssl crt /etc/haproxy/ssl/{{ listen_name }}{% endif %}{% endif %} |
| {%- endfor %} |
| {%- if listen.bind_process is defined %} |
| bind-process {{ listen.bind_process }} |
| {%- endif %} |
| {%- if listen.get('type', None) == 'http' %} |
| mode http |
| balance {{ listen.get('balance', 'roundrobin') }} |
| option httplog |
| {%- elif listen.get('type', None) == 'rabbitmq' %} |
| balance {{ listen.get('balance', 'roundrobin') }} |
| mode tcp |
| option tcpka |
| timeout client 300s |
| timeout server 300s |
| {%- elif listen.get('type', None) == 'mysql' %} |
| balance {{ listen.get('balance', 'leastconn') }} |
| mode tcp |
| option httpchk |
| option tcplog |
| option clitcpka |
| option srvtcpka |
| timeout client 300s |
| timeout server 300s |
| {%- if listen.get('health-check', {}).get('mysql', {}).get('enabled', True) %} |
| # option conflict's with port check of clustercheck script, if enabled haproxy reports invalid reponse |
| option mysql-check user haproxy |
| {%- endif %} |
| {%- elif listen.get('type', None) == 'pgsql' %} |
| balance {{ listen.get('balance', 'leastconn') }} |
| mode tcp |
| option httpchk |
| option tcplog |
| option clitcpka |
| option srvtcpka |
| timeout client 28801s |
| timeout server 28801s |
| {%- if listen.get('health-check', {}).get('pgsql', {}).get('enabled', True) %} |
| option pgsql-check user postgres |
| {%- endif %} |
| {%- elif listen.get('type', None) == 'horizon' %} |
| balance {{ listen.get('balance', 'source') }} |
| capture cookie vgnvisitor= len 32 |
| cookie SERVERID insert indirect nocache |
| mode http |
| option forwardfor |
| option httpchk |
| option httpclose |
| option httplog |
| rspidel ^Set-cookie:\ IP= |
| {%- elif listen.get('type', None) == 'general-service' %} |
| mode http |
| balance {{ listen.get('balance', 'roundrobin') }} |
| option httplog |
| {%- elif listen.get('type', None) == 'openstack-service' %} |
| # NOTE(vsaienko): by default haproxy uses OPTIONS method when doing check |
| # This is not guaranteed by openstack APIs, change it to GET instead |
| option httpchk GET / |
| option httplog |
| option httpclose |
| {%- elif listen.get('type', None) == 'heat' %} |
| balance source |
| option tcpka |
| option httpchk |
| option tcplog |
| {%- elif listen.get('type', None) == 'contrail-config' %} |
| mode http |
| stats enable |
| stats uri / |
| stats auth {{ listen.user }}:{{ listen.password }} |
| {%- elif listen.get('type', None) == 'contrail-api' %} |
| {%- for option in listen.get('options', []) %} |
| option {{ option }} |
| {%- endfor %} |
| balance {{ listen.get('balance', 'leastconn') }} |
| {%- elif listen.get('type', None) == 'contrail-analytics' %} |
| {%- for option in listen.get('options', []) %} |
| option {{ option }} |
| {%- endfor %} |
| balance {{ listen.get('balance', 'roundrobin') }} |
| option tcp-check |
| tcp-check connect port 6379 |
| default-server error-limit 1 on-error mark-down |
| {%- elif listen.get('type', None) == 'stats' %} |
| mode http |
| stats enable |
| stats uri / |
| {%- if listen.user is defined %} |
| stats auth {{ listen.user }}:{{ listen.password }} |
| {%- endif %} |
| {%- elif listen.get('type', None) == 'admin' %} |
| mode http |
| acl AuthOkay_ReadOnly http_auth(STATSUSERS) |
| acl AuthOkay_Admin http_auth_group(STATSUSERS) {{ listen.user }} |
| stats enable |
| stats refresh 60s |
| stats uri / |
| stats http-request auth realm admin_page unless AuthOkay_ReadOnly |
| stats admin if AuthOkay_Admin |
| {%- else %} |
| {# no type specified #} |
| mode {{ listen.mode|default('tcp') }} |
| balance {{ listen.balance|default('roundrobin') }} |
| {%- for ttype, timeout in listen.get('timeout', {}).iteritems() %} |
| timeout {{ ttype }} {{ checktimeout(timeout) }} |
| {%- endfor %} |
| {%- for aclname, acl in listen.get('acl', {}).iteritems() %} |
| acl {{ aclname }} {{ acl }} |
| {%- endfor %} |
| {%- for capture in listen.get('capture', []) %} |
| capture {{ capture }} |
| {%- endfor %} |
| {%- for compression in listen.get('compression', []) %} |
| compression {{ compression }} |
| {%- endfor %} |
| {%- if listen.declare_capture is defined %} |
| declare capture {{ listen.declare_capture }} |
| {%- endif %} |
| {%- for email_alert in listen.get('email_alert', []) %} |
| email-alert {{ email_alert }} |
| {%- endfor %} |
| {%- if listen.errorfile is defined %} |
| {%- for errorfile_name, errorfile in listen.get('errorfile', {}).iteritems() %} |
| errorfile {{ errorfile.code }} {{ errorfile.file }} |
| {%- endfor %} |
| {%- endif %} |
| {%- if listen.max_keep_alive_queue is defined %} |
| max-keep-alive-queue {{ listen.max_keep_alive_queue }} |
| {%- endif %} |
| {%- if listen.maxconn is defined %} |
| maxconn {{ listen.maxconn }} |
| {%- endif %} |
| {%- for http_request in listen.get('http_request', []) %} |
| http-request {{ http_request.action }}{% if http_request.condition is defined %} {{ http_request.condition }}{% endif %} |
| {%- endfor %} |
| {%- for http_response in listen.get('http_response', []) %} |
| http-response {{ http_response.action }}{% if http_response.condition is defined %} {{ http_response.condition }}{% endif %} |
| {%- endfor %} |
| {%- for http_check in listen.get('http_check', []) %} |
| http-check {{ http_check.action }} |
| {%- endfor %} |
| {%- for option in listen.get('options', []) %} |
| option {{ option }} |
| {%- endfor %} |
| {%- for type, checks in listen.get('health-check', {}).iteritems() %} |
| {%- if checks.get('enabled', True) %} |
| {%- if type == 'http' and 'httpchk' not in listen.get('options', [])|join('|') %} |
| option httpchk |
| {%- endif %} |
| {%- if type == 'tcp' and 'tcp-check' not in listen.get('options', [])|join('|') %} |
| option tcp-check |
| {%- endif %} |
| {%- for option in checks.get('options', []) %} |
| {{ type }}-check {{ option }} |
| {%- endfor %} |
| {%- endif %} |
| {%- endfor %} |
| {%- for stick in listen.get('sticks', []) %} |
| {{ stick }} |
| {%- endfor %} |
| {%- for reqadd in listen.get('reqadd', []) %} |
| reqadd {{ reqadd }} |
| {%- endfor %} |
| {%- for reqirep in listen.get('reqirep', []) %} |
| reqirep {{ reqirep }} |
| {%- endfor %} |
| {%- for modify_header in listen.get('modify_headers', []) %} |
| {{ modify_header }} |
| {%- endfor %} |
| {%- if listen.retries is defined %} |
| retries {{ listen.retries }} |
| {%- endif %} |
| {%- for stat in listen.get('stats', []) %} |
| stats {{ stat }} |
| {%- endfor %} |
| {%- if listen.rate_limit_sessions is defined %} |
| rate-limit sessions {{ listen.rate_limit_sessions }} |
| {%- endif %} |
| {%- endif %} |
| {%- if listen.rate_limit is defined and listen.rate_limit.get('enabled', False) %} |
| {%- include "haproxy/files/_rate_limit.cfg" %} |
| {%- endif %} |
| {%- if listen.redirects is defined %} |
| {%- for redirect in listen.redirects %} |
| http-request redirect {% if redirect.code is defined %} code {{ redirect.code }} {% endif %} location {{ redirect.location }} {%- if redirect.condition_raw is defined %} {{ redirect.condition_raw }} {%- endif %} |
| {%- endfor %} |
| {%- else %} |
| {%- for server in listen.get('servers', []) %} |
| {%- set port_range_length=server.get('port_range_length', 1) %} |
| {%- set port_range_start_offset=server.get('port_range_start_offset', 0) %} |
| {%- for worker_port in range(port_range_start_offset, port_range_length) %} |
| server {{ server.name }}{% if worker_port > 0 %}p{{ worker_port }}{% endif %} {{ server.host }}:{{ server.port + worker_port }} {{ server.get('params', '') }} |
| {%- endfor %} |
| {%- endfor %} |
| {%- endif %} |
| {%- if listen.rate_limit is defined and listen.rate_limit.get('enabled', False) %} |
| backend {{ listen_name }}-rate_limit |
| {%- set stick_table_found = { 'val': false } %} |
| {%- for item in listen.get('sticks', []) if item.startswith('stick-table ') %} |
| {%- do stick_table_found.update({'val': true}) %} |
| {%- endfor %} |
| {%- if stick_table_found.val %} |
| stick-table type {{ listen.rate_limit.get('type', 'string') }} {%- if listen.rate_limit.len is defined and listen.rate_limit.type in ['string', 'binary'] %} len {{ listen.rate_limit.len }}{%- endif %} size {{ listen.rate_limit.get('size', '100k') }} store gpc0_rate({{ listen.rate_limit.get('duration', '60s') }}) |
| {%- endif %} |
| timeout tarpit {{ checktimeout(listen.rate_limit.get('tarpit_timeout', '2s')) }} |
| errorfile 500 /etc/haproxy/errors/429.http11 |
| http-request tarpit |
| {%- endif %} |
| {%- endif %} |
| {%- endif %} |
| {%- endfor %} |
| |
| {%- for listen_name, listen in proxy.get('listen', {}).iteritems() %} |
| {%- if listen.get('format', 'listen') == 'end' %} |
| |
| frontend {{ listen_name }} |
| {%- for bind in listen.binds %} |
| bind {{ bind.address }}:{{ bind.port }} {% if bind.get('ssl', {}).enabled|default(False) %} {% if bind.ssl.pem_file is defined %}ssl crt {{ bind.ssl.pem_file }}{% else %}ssl crt /etc/haproxy/ssl/{{ listen_name }}{% endif %} {% endif %} |
| {% endfor %} |
| {% if listen.get('force_ssl') == true %} |
| redirect scheme https code 301 if !{ ssl_fc } |
| {% endif %} |
| {%- for redirect in listen.get('redirects', []) %} |
| {%- for condition in redirect.get('conditions', []) %} |
| redirect {% if redirect.code is defined %} code {{ redirect.code }} {% endif %} location {{ redirect.location }} if { {{ condition.type }} {{ condition.condition }} } |
| {%- endfor %} |
| {%- endfor %} |
| |
| {#- Add options in the frontend section that make sense. #} |
| {%- for option in listen.get('options', []) %} |
| {%- if option not in invalid_section_options.frontend %} |
| option {{ option }} |
| {%- endif %} |
| {%- endfor %} |
| |
| {%- for acl in listen.get('acls', []) %} |
| {%- for condition in acl.get('conditions', []) %} |
| acl {{ acl.name }} {{ condition.type }} {{ condition.condition }} |
| {%- endfor %} |
| |
| {%- if listen_name == 'service_proxy' %} |
| use_backend {{ acl.backend|default(acl.name, true) }} if {{ acl.name }} |
| {% else %} |
| use_backend {{ acl.name }}-backend if {{ acl.name }} |
| {% endif %} |
| {%- endfor %} |
| |
| {%- if listen.rate_limit is defined and listen.rate_limit.get('enabled', False) %} |
| {%- include "haproxy/files/_rate_limit.cfg" %} |
| {%- endif %} |
| |
| default_backend {{ listen_name }}-backend |
| |
| backend {{ listen_name }}-backend |
| {%- if listen.get('type', None) == 'http' %} |
| balance {{ listen.get('balance', 'roundrobin') }} |
| {%- endif %} |
| |
| {#- Add options in the backend section that make sense. #} |
| {%- for option in listen.get('options', []) %} |
| {%- if option not in invalid_section_options.backend %} |
| option {{ option }} |
| {%- endif %} |
| {%- endfor %} |
| |
| {%- for server in listen.get('servers', []) %} |
| server {{ server.get('name', server.host) }} {{ server.host }}:{{ server.port }} {{ server.get('params', '') }} |
| {%- endfor %} |
| {%- if listen_name != 'service_proxy' %} |
| {%- for acl in listen.get('acls', []) %} |
| |
| backend {{ acl.name }}-backend |
| balance {{ acl.get('balance', 'roundrobin') }} |
| {%- for option in acl.get('options', []) %} |
| option {{ option }} |
| {%- endfor %} |
| {%- for server in acl.get('servers', []) %} |
| server {{ server.get('name', server.host) }} {{ server.host }}:{{ server.port }} {{ server.get('params', '') }} |
| {%- endfor %} |
| {%- endfor %} |
| {%- endif %} |
| |
| {%- if listen.rate_limit is defined and listen.rate_limit.get('enabled', False) %} |
| |
| backend {{ listen_name }}-rate_limit |
| timeout tarpit {{ checktimeout(listen.rate_limit.get('tarpit_timeout', '2s')) }} |
| errorfile 500 /etc/haproxy/errors/429.http11 |
| http-request tarpit |
| {%- endif %} |
| {%- endif %} |
| {%- endfor %} |