diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr
index 122f67789..902dc499e 100644
--- a/net/haproxy/pkg-descr
+++ b/net/haproxy/pkg-descr
@@ -14,9 +14,12 @@ Added:
* add global option to enable old buggy behaviour for PROXY v2 connections
* add support for HTTP/2 in health checks
* add config export (#2035)
+* add config diff
+* guard against broken config by using a staging config file
Fixed:
* fix maintenance page (python error: 'list' object has no attribute 'strip')
+* prevent service outage by aborting "Apply" when configtest fails
Changed:
* change default SSL version to TLSv1.2 (ssl-min-ver)
@@ -26,6 +29,7 @@ Changed:
* change default for tune.ssl.default-dh-param from 1024 to 2048
* use new "http-check send" command for HTTP health checks
* change default for spreadChecks from 0 to 2
+* no longer overwrite live config file when running a syntax check
2.26
diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/Api/ExportController.php b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/Api/ExportController.php
index 89f9df4ca..5a3cd58f9 100644
--- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/Api/ExportController.php
+++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/Api/ExportController.php
@@ -52,6 +52,17 @@ class ExportController extends ApiControllerBase
return array("response" => $response);
}
+ /**
+ * get config diff
+ * @return string
+ */
+ public function diffAction()
+ {
+ $backend = new Backend();
+ $response = $backend->configdRun("haproxy configdiff");
+ return array("response" => $response);
+ }
+
/**
* download config file or config archive
* @return array|mixed
diff --git a/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/export.volt b/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/export.volt
index e9134da57..ccfbb5f95 100644
--- a/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/export.volt
+++ b/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/export.volt
@@ -39,6 +39,35 @@ POSSIBILITY OF SUCH DAMAGE.
}
update_showconf();
+ /**
+ * show HAProxy config diff
+ */
+ function update_showdiff() {
+ ajaxCall(url="/api/haproxy/export/diff/", sendData={}, callback=function(data,status) {
+ diff = '';
+ var lines = data['response'].split("\n");
+ $.each(lines, function(n, line) {
+ switch(line.substring(0,1)) {
+ case '+':
+ color = '#3bbb33';
+ break;
+ case '-':
+ color = '#c13928';
+ break;
+ case '@':
+ color = '#3bb9c3';
+ break;
+ default:
+ color = '#000000';
+ }
+ diff += '' + line + '
';
+
+ });
+ $("#showdiff").append(diff);
+ });
+ }
+ update_showdiff();
+
/**
* download HAProxy config
*/
@@ -66,6 +95,7 @@ POSSIBILITY OF SUCH DAMAGE.
@@ -81,6 +111,12 @@ POSSIBILITY OF SUCH DAMAGE.
+
+
{{ partial("layout_partials/base_dialog_processing") }}
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 45d6749ef..fe86bf89c 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
@@ -313,29 +313,9 @@ POSSIBILITY OF SUCH DAMAGE.
if (data['result'].indexOf('ALERT') > -1) {
BootstrapDialog.show({
type: BootstrapDialog.TYPE_DANGER,
- title: "{{ lang._('HAProxy config contains critical errors') }}",
- message: "{{ lang._('The HAProxy service may not be able to start due to critical errors. Try anyway?') }}",
+ 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.') }}",
buttons: [{
- label: '{{ lang._('Continue') }}',
- cssClass: 'btn-primary',
- action: function(dlg){
- 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");
- });
- dlg.close();
- }
- }, {
icon: 'fa fa-trash-o',
label: '{{ lang._('Abort') }}',
action: function(dlg){
@@ -385,21 +365,21 @@ 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 config test result') }}",
+ title: "{{ lang._('HAProxy configtest result') }}",
message: "{{ lang._('Your HAProxy config contains no errors.') }}",
draggable: true
});
diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh
index cb88ee64d..ca8cd48dc 100755
--- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh
+++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh
@@ -18,4 +18,14 @@ find /var/haproxy -type d -exec chmod 550 {} \;
/usr/local/opnsense/scripts/OPNsense/HAProxy/exportErrorFiles.php > /dev/null 2>&1
/usr/local/opnsense/scripts/OPNsense/HAProxy/exportMapFiles.php > /dev/null 2>&1
+# deploy new config
+case "$1" in
+deploy)
+ # run syntax check against newly generated config
+ if /usr/local/sbin/haproxy -c -f /usr/local/etc/haproxy.conf.staging > /dev/null 2>&1; then
+ cp /usr/local/etc/haproxy.conf.staging /usr/local/etc/haproxy.conf
+ fi
+ ;;
+esac
+
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 e23f091f6..07341474e 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
@@ -5,7 +5,7 @@ type:script_output
message:setup haproxy service requirements
[start]
-command:/usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh; /usr/local/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh start
+command:/usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh deploy; /usr/local/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh start
parameters:
type:script
message:starting haproxy
@@ -17,19 +17,19 @@ type:script
message:stopping haproxy
[restart]
-command:/usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh; /usr/local/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh restart
+command:/usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh deploy; /usr/local/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh restart
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
+command:/usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh deploy; /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
+command:/usr/local/sbin/haproxy -c -f /usr/local/etc/haproxy.conf.staging 2>&1 || exit 0
parameters:
type:script_output
message:testing haproxy configuration
@@ -102,14 +102,20 @@ message:Sync ssl certificates into HAProxy memory for all frontends
description:Sync ssl certificates changes into HAProxy memory
[showconf]
-command:test -f /usr/local/etc/haproxy.conf && cat /usr/local/etc/haproxy.conf
+command:test -f /usr/local/etc/haproxy.conf.staging && cat /usr/local/etc/haproxy.conf.staging
parameters:
type:script_output
message:show haproxy config
[exportall]
-command:/usr/local/bin/zip -r /tmp/haproxy_config_export.zip /tmp/haproxy /usr/local/etc/haproxy.conf
+command:/usr/local/bin/zip -r /tmp/haproxy_config_export.zip /tmp/haproxy /usr/local/etc/haproxy.conf.staging
parameters:
type:script_output
message:show haproxy config
+[configdiff]
+command:/usr/bin/diff -Naur /usr/local/etc/haproxy.conf /usr/local/etc/haproxy.conf.staging; exit 0
+parameters:
+type:script_output
+message:diff haproxy config
+
diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/+TARGETS b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/+TARGETS
index a8fa7728c..389191f4d 100644
--- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/+TARGETS
+++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/+TARGETS
@@ -1,3 +1,3 @@
-haproxy.conf:/usr/local/etc/haproxy.conf
+haproxy.conf:/usr/local/etc/haproxy.conf.staging
rc.conf.d:/etc/rc.conf.d/haproxy
sslCerts.yaml:/usr/local/etc/haproxy/sslCerts.yaml
\ No newline at end of file