{# Copyright (c) 2015 Rackspace # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # #} {% macro peers_macro(constants,listener) %} {% if listener.topology == constants.TOPOLOGY_ACTIVE_STANDBY %} peers {{ "%s_peers"|format(listener.id.replace("-", ""))|trim() }} {% for amp in listener.amphorae if ( amp.status == constants.AMPHORA_ALLOCATED) %} {# HAProxy has peer name limitations, thus the hash filter #} peer {{ amp.id|hash_amp_id|replace('=', '') }} {{ amp.vrrp_ip }}:{{ listener.peer_port }} {% endfor %} {% endif %} {% endmacro %} {% macro bind_macro(constants, listener, lb_vip_address) %} {% if listener.default_tls_path %} {% set def_crt_opt = ("ssl crt %s"|format( listener.default_tls_path)|trim()) %} {% else %} {% set def_crt_opt = "" %} {% endif %} {% if listener.crt_dir %} {% set crt_dir_opt = "crt %s"|format(listener.crt_dir)|trim() %} {% else %} {% set crt_dir_opt = "" %} {% endif %} bind {{ lb_vip_address }}:{{ listener.protocol_port }} {{ "%s %s"|format(def_crt_opt, crt_dir_opt)|trim() }} {% endmacro %} {% macro l7rule_compare_type_macro(constants, ctype) %} {% if ctype == constants.L7RULE_COMPARE_TYPE_REGEX %} {{- "-m reg" -}} {% elif ctype == constants.L7RULE_COMPARE_TYPE_STARTS_WITH %} {{- "-m beg" -}} {% elif ctype == constants.L7RULE_COMPARE_TYPE_ENDS_WITH %} {{- "-m end" -}} {% elif ctype == constants.L7RULE_COMPARE_TYPE_CONTAINS %} {{- "-m sub" -}} {% elif ctype == constants.L7RULE_COMPARE_TYPE_EQUAL_TO %} {{- "-m str" -}} {% endif %} {% endmacro %} {% macro l7rule_macro(constants, l7rule) %} {% if l7rule.type == constants.L7RULE_TYPE_HOST_NAME %} acl {{ l7rule.id }} req.hdr(host) -i {{ l7rule_compare_type_macro( constants, l7rule.compare_type) }} {{ l7rule.value }} {% elif l7rule.type == constants.L7RULE_TYPE_PATH %} acl {{ l7rule.id }} path {{ l7rule_compare_type_macro( constants, l7rule.compare_type) }} {{ l7rule.value }} {% elif l7rule.type == constants.L7RULE_TYPE_FILE_TYPE %} acl {{ l7rule.id }} path_end {{ l7rule_compare_type_macro( constants, l7rule.compare_type) }} {{ l7rule.value }} {% elif l7rule.type == constants.L7RULE_TYPE_HEADER %} acl {{ l7rule.id }} req.hdr({{ l7rule.key }}) {{ l7rule_compare_type_macro( constants, l7rule.compare_type) }} {{ l7rule.value }} {% elif l7rule.type == constants.L7RULE_TYPE_COOKIE %} acl {{ l7rule.id }} req.cook({{ l7rule.key }}) {{ l7rule_compare_type_macro( constants, l7rule.compare_type) }} {{ l7rule.value }} {% endif %} {% endmacro %} {% macro l7rule_invert_macro(invert) %} {% if invert %} {{- "!" -}} {% endif %} {% endmacro %} {% macro l7rule_list_macro(l7policy) %} {% for l7rule in l7policy.l7rules %} {{- " " -}}{{- l7rule_invert_macro(l7rule.invert) -}}{{- l7rule.id -}} {% endfor %} {% endmacro %} {% macro l7policy_macro(constants, l7policy) %} {% for l7rule in l7policy.l7rules %} {{- l7rule_macro(constants, l7rule) -}} {% endfor %} {% if l7policy.action == constants.L7POLICY_ACTION_REJECT %} http-request deny if{{ l7rule_list_macro(l7policy) }} {% elif l7policy.action == constants.L7POLICY_ACTION_REDIRECT_TO_URL %} redirect location {{ l7policy.redirect_url }} if{{ l7rule_list_macro( l7policy) }} {% elif l7policy.action == constants.L7POLICY_ACTION_REDIRECT_TO_POOL and l7policy.redirect_pool.enabled %} use_backend {{ l7policy.redirect_pool.id }} if{{ l7rule_list_macro( l7policy) }} {% endif %} {% endmacro %} {% macro frontend_macro(constants, listener, lb_vip_address) %} frontend {{ listener.id }} {% if (listener.protocol.lower() == constants.PROTOCOL_TERMINATED_HTTPS.lower() or listener.protocol.lower() == constants.PROTOCOL_HTTP.lower()) %} option httplog {% else %} option tcplog {% endif %} {% if listener.connection_limit is defined %} maxconn {{ listener.connection_limit }} {% endif %} {% if (listener.protocol.lower() == constants.PROTOCOL_TERMINATED_HTTPS.lower()) %} redirect scheme https if !{ ssl_fc } {% endif %} {{ bind_macro(constants, listener, lb_vip_address)|trim() }} mode {{ listener.protocol_mode }} {% for l7policy in listener.l7policies if (l7policy.enabled and l7policy.l7rules|length > 0) %} {{- l7policy_macro(constants, l7policy) -}} {% endfor %} {% if listener.default_pool and listener.default_pool.enabled %} default_backend {{ listener.default_pool.id }} {% endif %} timeout client {{ listener.timeout_client_data }} {% if listener.timeout_tcp_inspect %} tcp-request inspect-delay {{ listener.timeout_tcp_inspect }} {% endif %} {% endmacro %} {% macro member_macro(constants, pool, member) %} {% if pool.health_monitor and pool.health_monitor.enabled %} {% if member.monitor_address %} {% set monitor_addr_opt = " addr %s"|format(member.monitor_address) %} {% else %} {% set monitor_addr_opt = "" %} {% endif %} {% if member.monitor_port %} {% set monitor_port_opt = " port %s"|format(member.monitor_port) %} {% else %} {% set monitor_port_opt = "" %} {% endif %} {% if pool.health_monitor.type == constants.HEALTH_MONITOR_HTTPS %} {% set monitor_ssl_opt = " check-ssl verify none" %} {% else %} {% set monitor_ssl_opt = "" %} {% endif %} {% set hm_opt = " check%s inter %ds fall %d rise %d%s%s"|format( monitor_ssl_opt, pool.health_monitor.delay, pool.health_monitor.fall_threshold, pool.health_monitor.rise_threshold, monitor_addr_opt, monitor_port_opt) %} {% else %} {% set hm_opt = "" %} {% endif %} {% if (pool.session_persistence.type == constants.SESSION_PERSISTENCE_HTTP_COOKIE) %} {% set persistence_opt = " cookie %s"|format(member.id) %} {% else %} {% set persistence_opt = "" %} {% endif %} {% if pool.protocol.lower() == constants.PROTOCOL_PROXY.lower() %} {% set proxy_protocol_opt = " send-proxy" %} {% else %} {% set proxy_protocol_opt = "" %} {% endif %} {% if member.backup %} {% set member_backup_opt = " backup" %} {% else %} {% set member_backup_opt = "" %} {% endif %} {% if member.enabled %} {% set member_enabled_opt = "" %} {% else %} {% set member_enabled_opt = " disabled" %} {% endif %} {{ "server %s %s:%d weight %s%s%s%s%s%s"|e|format( member.id, member.address, member.protocol_port, member.weight, hm_opt, persistence_opt, proxy_protocol_opt, member_backup_opt, member_enabled_opt)|trim() }} {% endmacro %} {% macro backend_macro(constants, listener, pool) %} backend {{ pool.id }} {% if pool.protocol.lower() == constants.PROTOCOL_PROXY.lower() %} mode {{ listener.protocol_mode }} {% else %} mode {{ pool.protocol }} {% endif %} {% if (pool.protocol.lower() == constants.PROTOCOL_HTTP.lower() or (pool.protocol.lower() == constants.PROTOCOL_PROXY.lower() and listener.protocol_mode.lower() == constants.PROTOCOL_HTTP.lower()))%} http-reuse safe {% endif %} balance {{ pool.lb_algorithm }} {% if pool.session_persistence %} {% if (pool.session_persistence.type == constants.SESSION_PERSISTENCE_SOURCE_IP) %} {% if listener.topology == constants.TOPOLOGY_ACTIVE_STANDBY %} stick-table type ip size {{ pool.stick_size }} peers {{ "%s_peers"|format(listener.id.replace("-", ""))|trim() }} {% else %} stick-table type ip size {{ pool.stick_size }} {% endif %} stick on src {% elif (pool.session_persistence.type == constants.SESSION_PERSISTENCE_APP_COOKIE) %} {% if listener.topology == constants.TOPOLOGY_ACTIVE_STANDBY %} stick-table type string len 64 size {{ pool.stick_size }} peers {{ "%s_peers"|format(listener.id.replace("-", ""))|trim() }} {% else %} stick-table type string len 64 size {{ pool.stick_size }} {% endif %} stick store-response res.cook({{ pool.session_persistence.cookie_name }}) stick match req.cook({{ pool.session_persistence.cookie_name }}) {% elif (pool.session_persistence.type == constants.SESSION_PERSISTENCE_HTTP_COOKIE) %} cookie SRV insert indirect nocache {% endif %} {% endif %} {% if pool.health_monitor and pool.health_monitor.enabled %} timeout check {{ pool.health_monitor.timeout }}s {% if (pool.health_monitor.type == constants.HEALTH_MONITOR_HTTP or pool.health_monitor.type == constants.HEALTH_MONITOR_HTTPS) %} option httpchk {{ pool.health_monitor.http_method }} {{ pool.health_monitor.url_path }} http-check expect rstatus {{ pool.health_monitor.expected_codes }} {% endif %} {% if pool.health_monitor.type == constants.HEALTH_MONITOR_TLS_HELLO %} option ssl-hello-chk {% endif %} {% if pool.health_monitor.type == constants.HEALTH_MONITOR_PING %} option external-check external-check command /var/lib/octavia/ping-wrapper.sh {% endif %} {% endif %} {% if pool.protocol.lower() == constants.PROTOCOL_HTTP.lower() %} {% if listener.insert_headers.get('X-Forwarded-For', 'False').lower() == 'true' %} option forwardfor {% endif %} {% if listener.insert_headers.get('X-Forwarded-Port', 'False').lower() == 'true' %} http-request set-header X-Forwarded-Port %[dst_port] {% endif %} {% endif %} {% if listener.insert_headers.get('X-Forwarded-Proto', 'False').lower() == 'true' %} {% if listener.protocol.lower() == constants.PROTOCOL_HTTP.lower() %} http-request set-header X-Forwarded-Proto http {% elif listener.protocol.lower() == constants.PROTOCOL_TERMINATED_HTTPS.lower() %} http-request set-header X-Forwarded-Proto https {% endif %} {% endif %} {% if listener.connection_limit is defined %} fullconn {{ listener.connection_limit }} {% endif %} option allbackups timeout connect {{ listener.timeout_member_connect }} timeout server {{ listener.timeout_member_data }} {% for member in pool.members %} {{- member_macro(constants, pool, member) -}} {% endfor %} {% endmacro %}