{{ lang._("%sError Messages:%s Return a custom message instead of errors generated by HAProxy. Useful to overwrite HAProxy's internal error messages. The message must represent the full HTTP response and include required HTTP headers.") | format('', '') }}
{{ lang._("%sLua scripts:%s Include your own Lua code/scripts to extend HAProxy's functionality. The Lua code can be used in certain %sRules%s, for example.") | format('', '', '', '') }}
+
{{ lang._("%sMap Files:%s A map allows to map a data in input to an other one on output. For example, this makes it possible to map a large number of domains to backend pools without using the GUI. Map files need to be used in %sRules%s, otherwise they are ignored.") | format('', '', '', '') }}
-
{{ lang._("For more details visit HAProxy's official documentation regarding the %sError Messages%s and the %sLua Script%s features.") | format('', '', '', '') }}
+
{{ lang._("For more details visit HAProxy's official documentation regarding the %sError Messages%s, %sLua Script%s and the %sMap Files%s features.") | format('', '', '', '', '', '') }}
@@ -833,6 +848,40 @@ POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
{{ lang._('Map File ID') }}
+
{{ lang._('Map File Name') }}
+
{{ lang._('Description') }}
+
{{ lang._('Commands') }}
+
{{ lang._('ID') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{# include dialogs #}
@@ -844,3 +893,4 @@ POSSIBILITY OF SUCH DAMAGE.
{{ partial("layout_partials/base_dialog",['fields':formDialogAcl,'id':'DialogAcl','label':lang._('Edit Condition')])}}
{{ partial("layout_partials/base_dialog",['fields':formDialogLua,'id':'DialogLua','label':lang._('Edit Lua Script')])}}
{{ partial("layout_partials/base_dialog",['fields':formDialogErrorfile,'id':'DialogErrorfile','label':lang._('Edit Error Message')])}}
+{{ partial("layout_partials/base_dialog",['fields':formDialogMapfile,'id':'DialogMapfile','label':lang._('Edit Map File')])}}
diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportMapFiles.php b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportMapFiles.php
new file mode 100755
index 000000000..e0836d7f0
--- /dev/null
+++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportMapFiles.php
@@ -0,0 +1,55 @@
+#!/usr/local/bin/php
+object();
+if (isset($configObj->OPNsense->HAProxy->mapfiles)) {
+ foreach ($configObj->OPNsense->HAProxy->mapfiles->children() as $mapfile) {
+ $mf_name = (string)$mapfile->name;
+ $mf_id = (string)$mapfile->id;
+ if ($mf_id != "") {
+ $mf_content = htmlspecialchars_decode(str_replace("\r", "", (string)$mapfile->content));
+ $mf_filename = "/var/etc/haproxy/mapfiles/" . $mf_id . ".txt";
+ file_put_contents($mf_filename, $mf_content);
+ chmod($mf_filename, 0600);
+ echo "map file exported to " . $mf_filename . "\n";
+ }
+ }
+}
diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh
index 28de9c9f8..3ade2075d 100755
--- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh
+++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh
@@ -7,11 +7,18 @@ fi
rcprefix=
case "$1" in
-stop|restart)
+stop)
if [ "${haproxy_hardstop}" == "YES" ]; then
rcprefix="hard"
fi
;;
+reload)
+ if [ "${haproxy_softreload}" == "YES" ]; then
+ rcprefix="soft"
+ elif [ "${haproxy_hardstop}" == "YES" ]; then
+ rcprefix="hard"
+ fi
+ ;;
esac
/usr/local/etc/rc.d/haproxy ${rcprefix}${1}
diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh
index dd501d10d..8af5efe23 100755
--- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh
+++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# NOTE: Keep /var/haproxy on this list, see GH issue opnsense/plugins #39.
-HAPROXY_DIRS="/var/haproxy /var/haproxy/var/run /var/etc/haproxy/ssl /var/etc/haproxy/lua /var/etc/haproxy/errorfiles"
+HAPROXY_DIRS="/var/haproxy /var/haproxy/var/run /var/etc/haproxy/ssl /var/etc/haproxy/lua /var/etc/haproxy/errorfiles /var/etc/haproxy/mapfiles"
for directory in ${HAPROXY_DIRS}; do
mkdir -p ${directory}
@@ -16,5 +16,6 @@ find /var/haproxy -type d -exec chmod 550 {} \;
/usr/local/opnsense/scripts/OPNsense/HAProxy/exportCerts.php > /dev/null 2>&1
/usr/local/opnsense/scripts/OPNsense/HAProxy/exportLuaScripts.php > /dev/null 2>&1
/usr/local/opnsense/scripts/OPNsense/HAProxy/exportErrorFiles.php > /dev/null 2>&1
+/usr/local/opnsense/scripts/OPNsense/HAProxy/exportMapFiles.php > /dev/null 2>&1
exit 0
diff --git a/net/haproxy/src/opnsense/service/conf/actions.d/actions_haproxy.conf b/net/haproxy/src/opnsense/service/conf/actions.d/actions_haproxy.conf
index 4560414ee..02896ebe0 100644
--- a/net/haproxy/src/opnsense/service/conf/actions.d/actions_haproxy.conf
+++ b/net/haproxy/src/opnsense/service/conf/actions.d/actions_haproxy.conf
@@ -22,6 +22,12 @@ parameters:
type:script
message:restarting haproxy
+[reload]
+command:/usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh; /usr/local/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh reload || /usr/local/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh restart
+parameters:
+type:script
+message:reloading haproxy
+
[configtest]
command:/usr/local/etc/rc.d/haproxy configtest 2>&1 || exit 0
parameters:
diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf
index a921a54bd..b1452d789 100644
--- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf
+++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf
@@ -306,6 +306,24 @@
{% set action_enabled = '0' %}
# ERROR: missing parameters
{% endif %}
+{% elif action_data.type == 'map_use_backend' %}
+{# # First get the map file path #}
+{% if action_data.map_use_backend_file|default("") != "" %}
+{% set mapfile_data = helpers.getUUID(action_data.map_use_backend_file) %}
+{% set mapfile_path = '/var/etc/haproxy/mapfiles/' ~ mapfile_data.id ~ '.txt' %}
+{# # Check if a default backend is specified #}
+{% if action_data.map_use_backend_default|default("") != "" %}
+{% set defaultbackend_data = helpers.getUUID(action_data.map_use_backend_default) %}
+{% set defaultbackend_option = ',' ~ defaultbackend_data.name %}
+{% else %}
+{% set defaultbackend_option = '' %}
+{% endif %}
+{# # Finally add map file to config #}
+{% do action_options.append('use_backend %[req.hdr(host),lower,map_dom(' ~ mapfile_path ~ defaultbackend_option ~ ')]') %}
+{% else %}
+{% set action_enabled = '0' %}
+ # ERROR: missing parameters
+{% endif %}
{% elif action_data.type == 'http-request_allow' %}
{% do action_options.append('http-request allow') %}
{% elif action_data.type == 'http-request_deny' %}
@@ -623,7 +641,11 @@ global
gid 80
chroot /var/haproxy
daemon
+{% if helpers.exists('OPNsense.HAProxy.general.seamlessReload') and OPNsense.HAProxy.general.seamlessReload|default("0") == "1" %}
+ stats socket /var/run/haproxy.socket level admin expose-fd listeners
+{% else %}
stats socket /var/run/haproxy.socket level admin
+{% endif %}
nbproc {{OPNsense.HAProxy.general.tuning.nbproc}}
{% if helpers.exists('OPNsense.HAProxy.general.tuning.maxConnections') %}
maxconn {{OPNsense.HAProxy.general.tuning.maxConnections}}
diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/rc.conf.d b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/rc.conf.d
index fab73298e..50cee173c 100644
--- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/rc.conf.d
+++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/rc.conf.d
@@ -8,6 +8,12 @@ haproxy_hardstop=NO
{% else %}
haproxy_hardstop=YES
{% endif %}
+{% if helpers.exists('OPNsense.HAProxy.general.seamlessReload') and OPNsense.HAProxy.general.seamlessReload|default("0") == "1" %}
+haproxy_socket="/var/run/haproxy.socket"
+haproxy_softreload=YES
+{% else %}
+haproxy_softreload=NO
+{% endif %}
{% else %}
haproxy_enable=NO
{% endif %}