diff --git a/net/haproxy/Makefile b/net/haproxy/Makefile index 5bbe66377..36875ce93 100644 --- a/net/haproxy/Makefile +++ b/net/haproxy/Makefile @@ -1,6 +1,5 @@ PLUGIN_NAME= haproxy -PLUGIN_VERSION= 3.6 -PLUGIN_REVISION= 1 +PLUGIN_VERSION= 3.7 PLUGIN_COMMENT= Reliable, high performance TCP/HTTP load balancer PLUGIN_DEPENDS= haproxy22 PLUGIN_MAINTAINER= opnsense@moov.de diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr index 5cba9c35d..0609ea6f3 100644 --- a/net/haproxy/pkg-descr +++ b/net/haproxy/pkg-descr @@ -6,6 +6,23 @@ very high loads while needing persistence or Layer7 processing. Plugin Changelog ================ +3.7 + +Added: +* add options "preload" and "filename scheme" to Lua scripts (#2265) +* add syslog-ng socket for logging (#2620) +* show hint to apply changes after every config change (#2590) +* show warning for pending configuration changes (#2590) + +Fixed: +* unable to use the "require" function in Lua scripts (#2265) +* request logging not working (#2587) +* fix syntax error in template (#2619) + +Changed: +* set "lua-prepend-path" so that Lua scripts can be found (#2265) +* show "apply" and "test syntax" buttons on introduction pages + 3.6 Added: diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogLua.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogLua.xml index 72a791e42..23ef5b030 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogLua.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogLua.xml @@ -17,6 +17,18 @@ text Description for this Lua script. + + lua.preload + + checkbox + Whether HAProxy should load and execute this Lua script on startup. This is the default behaviour. However, if this Lua script is included by other Lua scripts using the "require" function, then preloading should be disabled to avoid HAProxy errors. + + + lua.filename_scheme + + dropdown + + lua.content diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml index 7eaa7c3dd..89cfe9e0f 100644 --- a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml +++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml @@ -1,6 +1,6 @@ //OPNsense/HAProxy - 3.2.0 + 3.3.0 the HAProxy load balancer @@ -2364,6 +2364,18 @@ Should be a string between 1 and 255 characters. N + + 1 + Y + + + Y + id + + Use a random ID for the filename [default] + Use the specified name as filename + + Y diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/Migrations/M3_3_0.php b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/Migrations/M3_3_0.php new file mode 100644 index 000000000..5714a405b --- /dev/null +++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/Migrations/M3_3_0.php @@ -0,0 +1,45 @@ +getNodeByReference('luas.lua')->iterateItems() as $lua) { + $lua->filename_scheme = 'id'; + $lua->preload = '1'; + } + } +} diff --git a/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt b/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt index 51f40d96a..ba0cf32f0 100644 --- a/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt +++ b/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt @@ -300,7 +300,6 @@ POSSIBILITY OF SUCH DAMAGE. $("#healthcheck\\.type").change(function(){ var service_id = 'table_' + $(this).val(); $(".type_table").hide(); - // $(".table_"+$(this).val()).show(); $("."+service_id).show(); }); $("#healthcheck\\.type").change(); @@ -323,89 +322,92 @@ POSSIBILITY OF SUCH DAMAGE. // reconfigure haproxy to activate changes $('[id*="reconfigureAct"]').each(function(){ $(this).click(function(){ - - // set progress animation - $('[id*="reconfigureAct_progress"]').each(function(){ - $(this).addClass("fa fa-spinner fa-pulse"); - }); - // first run syntax check to catch critical errors - ajaxCall(url="/api/haproxy/service/configtest", sendData={}, callback=function(data,status) { - // show warning in case of critical errors - if (data['result'].indexOf('ALERT') > -1) { - BootstrapDialog.show({ - type: BootstrapDialog.TYPE_DANGER, - title: "{{ lang._('HAProxy configtest found critical errors') }}", - message: "{{ lang._('The HAProxy service may not be able to start due to critical errors. Run syntax check for further details or review the changes in the %sConfiguration Diff%s.')|format('','') }}", - buttons: [{ - icon: 'fa fa-trash-o', - label: '{{ lang._('Abort') }}', - action: function(dlg){ - // when done, disable progress animation - $('[id*="reconfigureAct_progress"]').each(function(){ - $(this).removeClass("fa fa-spinner fa-pulse"); - }); - dlg.close(); - } - }] - }); - } else { - ajaxCall(url="/api/haproxy/service/reconfigure", sendData={}, callback=function(data,status) { - if (status != "success" || data['status'] != 'ok') { - BootstrapDialog.show({ - type: BootstrapDialog.TYPE_WARNING, - title: "{{ lang._('Error reconfiguring HAProxy') }}", - message: data['status'], - draggable: true - }); - } - // when done, disable progress animation - $('[id*="reconfigureAct_progress"]').each(function(){ - $(this).removeClass("fa fa-spinner fa-pulse"); + // set progress animation + $('[id*="reconfigureAct_progress"]').each(function(){ + $(this).addClass("fa fa-spinner fa-pulse"); + }); + // first run syntax check to catch critical errors + ajaxCall(url="/api/haproxy/service/configtest", sendData={}, callback=function(data,status) { + // show warning in case of critical errors + if (data['result'].indexOf('ALERT') > -1) { + BootstrapDialog.show({ + type: BootstrapDialog.TYPE_DANGER, + title: "{{ lang._('HAProxy configtest found critical errors') }}", + message: "{{ lang._('The HAProxy service may not be able to start due to critical errors. Run syntax check for further details or review the changes in the %sConfiguration Diff%s.')|format('','') }}", + buttons: [{ + icon: 'fa fa-trash-o', + label: '{{ lang._('Abort') }}', + action: function(dlg){ + // when done, disable progress animation + $('[id*="reconfigureAct_progress"]').each(function(){ + $(this).removeClass("fa fa-spinner fa-pulse"); + }); + dlg.close(); + } + }] }); - }); - } - }); + } else { + ajaxCall(url="/api/haproxy/service/reconfigure", sendData={}, callback=function(data,status) { + if (status != "success" || data['status'] != 'ok') { + BootstrapDialog.show({ + type: BootstrapDialog.TYPE_WARNING, + title: "{{ lang._('Error reconfiguring HAProxy') }}", + message: data['status'], + draggable: true + }); + } else { + // reload page to hide pending changes reminder + setTimeout(function () { + window.location.reload(true) + }, 300); + } + // when done, disable progress animation + $('[id*="reconfigureAct_progress"]').each(function(){ + $(this).removeClass("fa fa-spinner fa-pulse"); + }); + }); + } + }); }); }); // test configuration file $('[id*="configtestAct"]').each(function(){ $(this).click(function(){ - - // set progress animation - $('[id*="configtestAct_progress"]').each(function(){ - $(this).addClass("fa fa-spinner fa-pulse"); - }); - - ajaxCall(url="/api/haproxy/service/configtest", sendData={}, callback=function(data,status) { - // when done, disable progress animation + // set progress animation $('[id*="configtestAct_progress"]').each(function(){ - $(this).removeClass("fa fa-spinner fa-pulse"); + $(this).addClass("fa fa-spinner fa-pulse"); }); - if (data['result'].indexOf('ALERT') > -1) { - BootstrapDialog.show({ - type: BootstrapDialog.TYPE_DANGER, - title: "{{ lang._('HAProxy configtest found critical errors') }}", - message: data['result'], - draggable: true + ajaxCall(url="/api/haproxy/service/configtest", sendData={}, callback=function(data,status) { + // when done, disable progress animation + $('[id*="configtestAct_progress"]').each(function(){ + $(this).removeClass("fa fa-spinner fa-pulse"); }); - } else if (data['result'].indexOf('WARNING') > -1) { - BootstrapDialog.show({ - type: BootstrapDialog.TYPE_WARNING, - title: "{{ lang._('HAProxy configtest found minor errors') }}", - message: data['result'], - draggable: true - }); - } else { - BootstrapDialog.show({ - type: BootstrapDialog.TYPE_WARNING, - title: "{{ lang._('HAProxy configtest result') }}", - message: "{{ lang._('Your HAProxy config contains no errors.') }}", - draggable: true - }); - } - }); + + if (data['result'].indexOf('ALERT') > -1) { + BootstrapDialog.show({ + type: BootstrapDialog.TYPE_DANGER, + title: "{{ lang._('HAProxy configtest found critical errors') }}", + message: data['result'], + draggable: true + }); + } else if (data['result'].indexOf('WARNING') > -1) { + BootstrapDialog.show({ + type: BootstrapDialog.TYPE_WARNING, + title: "{{ lang._('HAProxy configtest found minor errors') }}", + message: data['result'], + draggable: true + }); + } else { + BootstrapDialog.show({ + type: BootstrapDialog.TYPE_WARNING, + title: "{{ lang._('HAProxy configtest result') }}", + message: "{{ lang._('Your HAProxy config contains no errors.') }}", + draggable: true + }); + } + }); }); }); @@ -427,18 +429,26 @@ POSSIBILITY OF SUCH DAMAGE. if (data['result'].indexOf('ALERT') > -1) { BootstrapDialog.show({ type: BootstrapDialog.TYPE_DANGER, - title: "{{ lang._('HAProxy config contains critical errors') }}", + title: "{{ lang._('HAProxy configtest found critical errors') }}", message: data['result'], draggable: true }); } else if (data['result'].indexOf('WARNING') > -1) { BootstrapDialog.show({ type: BootstrapDialog.TYPE_WARNING, - title: "{{ lang._('HAProxy config contains minor errors') }}", + title: "{{ lang._('HAProxy configtest found minor errors') }}", message: data['result'], draggable: true }); + } else { + BootstrapDialog.show({ + type: BootstrapDialog.TYPE_WARNING, + title: "{{ lang._('HAProxy configtest result') }}", + message: "{{ lang._('Your HAProxy config contains no errors.') }}", + draggable: true + }); } + // when done, disable progress animation $('[id*="saveAndTestAct_progress"]').each(function(){ $(this).removeClass("fa fa-spinner fa-pulse"); @@ -510,6 +520,11 @@ POSSIBILITY OF SUCH DAMAGE. message: data['status'], draggable: true }); + } else { + // reload page to hide pending changes reminder + setTimeout(function () { + window.location.reload(true) + }, 300); } // when done, disable progress animation $('[id*="saveAndReconfigureAct_progress"]').each(function(){ @@ -517,15 +532,51 @@ POSSIBILITY OF SUCH DAMAGE. }); }); } - //}); }); }); }); }); + /*********************************************************************** + * UI tricks + **********************************************************************/ + + // show reminder when config has pending changes + function pending_changes_reminder() { + ajaxCall(url="/api/haproxy/export/diff/", sendData={}, callback=function(data,status) { + if (data['response'] && data['response'].trim()) { + $("#haproxyPendingReminder").show(); + } else { + $("#haproxyPendingReminder").hide(); + } + }); + } + pending_changes_reminder(); + + // show hint after every config change + function add_apply_reminder() { + hint_msg = "{{ lang._('After changing settings, please remember to test and apply them with the buttons below.') }}" + $('[id*="haproxyChangeMessage"]').each(function(){ + $(this).append(hint_msg); + }); + + }; + add_apply_reminder(); + + // show or hide the correct buttons depending on which tab is shown + // NOTE: This does not work on already shown tabs, so this event must + // fire first. + $('.nav-tabs a').on('show.bs.tab', function (e) { + if (/^\#general/.test(e.target.hash)) { + $("#haproxyCommonButtons").hide(); + } else { + $("#haproxyCommonButtons").show(); + } + }); + // update history on tab state and implement navigation - if(window.location.hash != "") { + if (window.location.hash != "") { $('a[href="' + window.location.hash + '"]').click() } $('.nav-tabs a').on('shown.bs.tab', function (e) { @@ -745,7 +796,7 @@ POSSIBILITY OF SUCH DAMAGE.
- +
@@ -768,17 +819,10 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Enabled') }}
-
-
- - -
-
-
- +
@@ -801,17 +845,10 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Enabled') }}
-
-
- - -
-
-
- +
@@ -837,17 +874,10 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Enabled') }}
-
-
- - -
-
-
- +
@@ -869,17 +899,10 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Health Monitor ID') }}
-
-
- - -
-
-
- +
@@ -901,17 +924,10 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Rule ID') }}
-
-
- - -
-
-
- +
@@ -933,17 +949,10 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Condition ID') }}
-
-
- - -
-
-
- +
@@ -966,17 +975,10 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Enabled') }}
-
-
- - -
-
-
- +
@@ -999,17 +1001,10 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Enabled') }}
-
-
- - -
-
-
- +
@@ -1032,17 +1027,10 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Enabled') }}
-
-
- - -
-
-
- +
@@ -1064,17 +1052,10 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Error Message ID') }}
-
-
- - -
-
-
- +
@@ -1096,17 +1077,10 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Map File ID') }}
-
-
- - -
-
-
- +
@@ -1131,17 +1105,10 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('CPU Rule ID') }}
-
-
- - -
-
-
- +
@@ -1164,17 +1131,10 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Resolver ID') }}
-
-
- - -
-
-
- +
@@ -1198,13 +1158,6 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Mailer ID') }}
-
-
- - -
-
-
@@ -1284,6 +1237,20 @@ POSSIBILITY OF SUCH DAMAGE. + + + + {# include dialogs #} diff --git a/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/maintenance.volt b/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/maintenance.volt index ae75d8a20..50eb00511 100644 --- a/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/maintenance.volt +++ b/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/maintenance.volt @@ -548,7 +548,7 @@ POSSIBILITY OF SUCH DAMAGE.
-

{{ lang._("%sChoose a command to change a server's state in runtime:%s") | format('', '') }}

+

{{ lang._("%sThe following commands are available to change a server's state in runtime:%s") | format('', '') }}

  • {{ lang._('%sSet state to ready:%s This puts the server in normal mode.') | format('', '') }}
  • {{ lang._('%sSet state to drain:%s This removes the server from load balancing. Health checks will continue to run and it still accepts new persistent connections.') | format('', '') }}
  • diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportLuaScripts.php b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportLuaScripts.php index d0da858af..82243d95f 100755 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportLuaScripts.php +++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportLuaScripts.php @@ -2,7 +2,7 @@ OPNsense->HAProxy->luas)) { } $lua_name = (string)$lua->name; $lua_id = (string)$lua->id; - if ($lua_id != "") { - $lua_content = htmlspecialchars_decode(str_replace("\r", "", (string)$lua->content)); - $lua_filename = $export_path . $lua_id . ".lua"; - file_put_contents($lua_filename, $lua_content); - chmod($lua_filename, 0600); - echo "lua script exported to " . $lua_filename . "\n"; + $lua_filename_scheme = (string)$lua->filename_scheme; + if ($lua_filename_scheme != '' and $lua_filename_scheme === 'name') { + $_name_alnum = preg_replace("/[^A-Za-z0-9]/", '', $lua_name); + $lua_filename = $export_path . $_name_alnum . '.lua'; + } else { + $lua_filename = $export_path . $lua_id . '.lua'; } + $lua_content = htmlspecialchars_decode(str_replace("\r", "", (string)$lua->content)); + file_put_contents($lua_filename, $lua_content); + chmod($lua_filename, 0600); + chown($lua_filename, 'www'); + echo "lua script exported to " . $lua_filename . "\n"; } } 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 d6e0624ef..4ce226be3 100644 --- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf +++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf @@ -994,13 +994,20 @@ global {% do logging.append('len ' ~ OPNsense.HAProxy.general.logging.length) if OPNsense.HAProxy.general.logging.length|default("") != "" %} {% do logging.append(OPNsense.HAProxy.general.logging.facility) %} {% do logging.append(OPNsense.HAProxy.general.logging.level) if OPNsense.HAProxy.general.logging.level|default("") != "" %} - log {{logging|join(' ')}} + log {{logging|join(' ')}} +{# # lua scripts #} + lua-prepend-path /tmp/haproxy/lua/?.lua {% if helpers.exists('OPNsense.HAProxy.luas.lua') %} - # lua scripts {% for lua in helpers.toList('OPNsense.HAProxy.luas.lua') %} -{% if lua.enabled == '1' %} +{% if lua.enabled == '1' and lua.preload|default('') == '1' %} +{# # select the filename scheme for lua scripts #} +{% if lua.filename_scheme|default('id') == 'name' %} +{% set lua_filename = lua.name | regex_replace ("[^A-Za-z0-9]","") %} +{% else %} +{% set lua_filename = lua.id %} +{% endif %} # lua script: {{lua.name}} - lua-load /tmp/haproxy/lua/{{lua.id}}.lua + lua-load /tmp/haproxy/lua/{{lua_filename}}.lua {% endif %} {% endfor %} {% endif %}