net/haproxy: improve handling of Lua scripts, fixes #2265

This commit is contained in:
Frank Wall
2021-10-31 23:35:44 +01:00
parent 1b7802f362
commit 719b4b00be
6 changed files with 103 additions and 11 deletions
+11
View File
@@ -6,6 +6,17 @@ very high loads while needing persistence or Layer7 processing.
Plugin Changelog
================
3.7
Added:
* add options "preload" and "filename scheme" to Lua scripts (#2265)
Fixed:
* unable to use the "require" function in Lua scripts (#2265)
Changed:
* set "lua-prepend-path" so that Lua scripts can be found (#2265)
3.6
Added:
@@ -17,6 +17,18 @@
<type>text</type>
<help>Description for this Lua script.</help>
</field>
<field>
<id>lua.preload</id>
<label>Preload on startup</label>
<type>checkbox</type>
<help>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.</help>
</field>
<field>
<id>lua.filename_scheme</id>
<label>Filename Scheme</label>
<type>dropdown</type>
<help><![CDATA[Specify the filename scheme for this Lua script. Usually using the ID is sufficient and the most fail-safe apparoach. However, when using Lua's "require" function this apparoach will not work and it becomes necessary to use the specified name as filename. In this case all non-alphanumeric characters are removed from the filename. Note that this may cause issues when creating multiple Lua scripts with the same name.]]></help>
</field>
<field>
<id>lua.content</id>
<label>Content</label>
@@ -1,6 +1,6 @@
<model>
<mount>//OPNsense/HAProxy</mount>
<version>3.2.0</version>
<version>3.3.0</version>
<description>the HAProxy load balancer</description>
<items>
<general>
@@ -2364,6 +2364,18 @@
<ValidationMessage>Should be a string between 1 and 255 characters.</ValidationMessage>
<Required>N</Required>
</description>
<preload type="BooleanField">
<default>1</default>
<Required>Y</Required>
</preload>
<filename_scheme type="OptionField">
<Required>Y</Required>
<default>id</default>
<OptionValues>
<id>Use a random ID for the filename [default]</id>
<name>Use the specified name as filename</name>
</OptionValues>
</filename_scheme>
<content type="TextField">
<Required>Y</Required>
</content>
@@ -0,0 +1,45 @@
<?php
/**
* Copyright (C) 2021 Frank Wall
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
namespace OPNsense\HAProxy\Migrations;
use OPNsense\Base\BaseModelMigration;
class M3_3_0 extends BaseModelMigration
{
public function run($model)
{
// Lua scripts have a 'filename_scheme' and 'preload' field now
foreach ($model->getNodeByReference('luas.lua')->iterateItems() as $lua) {
$lua->filename_scheme = 'id';
$lua->preload = '1';
}
}
}
@@ -2,7 +2,7 @@
<?php
/*
* Copyright (C) 2016 Frank Wall
* Copyright (C) 2016-2021 Frank Wall
* Copyright (C) 2015 Deciso B.V.
* All rights reserved.
*
@@ -46,12 +46,17 @@ if (isset($configObj->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";
}
}
@@ -995,12 +995,19 @@ global
{% 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(' ')}}
{# # 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 %}