mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
net/haproxy: add support for e-mail alerts and mailers, closes #1669
This commit is contained in:
@@ -17,6 +17,7 @@ Added:
|
||||
* add config diff
|
||||
* guard against broken config by using a staging config file
|
||||
* add basic OCSP stapling support (#1430)
|
||||
* add support for e-mail alerts and mailers (#1669)
|
||||
|
||||
Fixed:
|
||||
* fix maintenance page (python error: 'list' object has no attribute 'strip')
|
||||
|
||||
+30
@@ -409,4 +409,34 @@ class SettingsController extends ApiMutableModelControllerBase
|
||||
{
|
||||
return $this->searchBase('resolvers.resolver', array('enabled', 'name', 'nameservers'), 'name');
|
||||
}
|
||||
|
||||
public function getmailerAction($uuid = null)
|
||||
{
|
||||
return $this->getBase('mailer', 'mailers.mailer', $uuid);
|
||||
}
|
||||
|
||||
public function setmailerAction($uuid)
|
||||
{
|
||||
return $this->setBase('mailer', 'mailers.mailer', $uuid);
|
||||
}
|
||||
|
||||
public function addmailerAction()
|
||||
{
|
||||
return $this->addBase('mailer', 'mailers.mailer');
|
||||
}
|
||||
|
||||
public function delmailerAction($uuid)
|
||||
{
|
||||
return $this->delBase('mailers.mailer', $uuid);
|
||||
}
|
||||
|
||||
public function togglemailerAction($uuid, $enabled = null)
|
||||
{
|
||||
return $this->toggleBase('mailers.mailer', $uuid);
|
||||
}
|
||||
|
||||
public function searchmailersAction()
|
||||
{
|
||||
return $this->searchBase('mailers.mailer', array('enabled', 'name', 'mailservers', 'sender', 'recipient'), 'name');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ class IndexController extends \OPNsense\Base\IndexController
|
||||
$this->view->formDialogGroup = $this->getForm("dialogGroup");
|
||||
$this->view->formDialogHealthcheck = $this->getForm("dialogHealthcheck");
|
||||
$this->view->formDialogLua = $this->getForm("dialogLua");
|
||||
$this->view->formDialogMailer = $this->getForm("dialogMailer");
|
||||
$this->view->formDialogMapfile = $this->getForm("dialogMapfile");
|
||||
$this->view->formDialogResolver = $this->getForm("dialogResolver");
|
||||
$this->view->formDialogServer = $this->getForm("dialogServer");
|
||||
|
||||
@@ -119,6 +119,12 @@
|
||||
<help><![CDATA[The number of consecutive successful health checks before a server is considered as available.]]></help>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>backend.linkedMailer</id>
|
||||
<label>E-Mail Alert</label>
|
||||
<type>dropdown</type>
|
||||
<help><![CDATA[Select an e-mail alert configuration. An e-mail is sent when the state of a server changes.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<label>HTTP(S) settings</label>
|
||||
<type>header</type>
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>mailer.enabled</id>
|
||||
<label>Enabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable this mailer configuration.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>mailer.name</id>
|
||||
<label>Name</label>
|
||||
<type>text</type>
|
||||
<help>Choose a name for this mailer configuration.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>mailer.description</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
<help>Choose a optional description for this mailer configuration.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>mailer.mailservers</id>
|
||||
<label>Mail Servers</label>
|
||||
<type>select_multiple</type>
|
||||
<style>tokenize</style>
|
||||
<allownew>true</allownew>
|
||||
<sortable>true</sortable>
|
||||
<help><![CDATA[Add mailservers to this mailer configuration, i.e. 192.168.1.1:25. Use TAB key to complete typing.]]></help>
|
||||
<hint>Enter ip:port here. Finish with TAB.</hint>
|
||||
</field>
|
||||
<field>
|
||||
<id>mailer.sender</id>
|
||||
<label>Mail Sender</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[Declare the from email address to be used in both the envelope and header of email alerts.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>mailer.recipient</id>
|
||||
<label>Mail Recipient</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[Declare both the recipient address in the envelope and to address in the header of email alerts.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>mailer.loglevel</id>
|
||||
<label>Alert Log Level</label>
|
||||
<type>dropdown</type>
|
||||
<help><![CDATA[Declare the maximum log level of messages for which email alerts will be sent. This acts as a filter on the sending of email alerts.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>mailer.timeout</id>
|
||||
<label>Timeout</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[Defines the time (in seconds) available for a mail/connection to be made and send to the mail server.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>mailer.hostname</id>
|
||||
<label>Hostname</label>
|
||||
<type>text</type>
|
||||
<help><![CDATA[Declare the to hostname address to be used when communicating with mailers.]]></help>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
</form>
|
||||
@@ -928,6 +928,18 @@
|
||||
<ValidationMessage>Please specify a value between 1 and 100.</ValidationMessage>
|
||||
<Required>N</Required>
|
||||
</healthCheckRise>
|
||||
<linkedMailer type="ModelRelationField">
|
||||
<Model>
|
||||
<template>
|
||||
<source>OPNsense.HAProxy.HAProxy</source>
|
||||
<items>mailers.mailer</items>
|
||||
<display>name</display>
|
||||
</template>
|
||||
</Model>
|
||||
<ValidationMessage>Related mailer not found</ValidationMessage>
|
||||
<multiple>N</multiple>
|
||||
<Required>N</Required>
|
||||
</linkedMailer>
|
||||
<http2Enabled type="BooleanField">
|
||||
<default>0</default>
|
||||
<Required>N</Required>
|
||||
@@ -2623,5 +2635,64 @@
|
||||
</timeout_retry>
|
||||
</resolver>
|
||||
</resolvers>
|
||||
<mailers>
|
||||
<mailer type="ArrayField">
|
||||
<id type="UniqueIdField">
|
||||
<Required>Y</Required>
|
||||
</id>
|
||||
<enabled type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
<name type="TextField">
|
||||
<mask>/^[^\t^,^;^\.^\[^\]^\{^\}]{1,255}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 255 characters.</ValidationMessage>
|
||||
<Required>Y</Required>
|
||||
</name>
|
||||
<description type="TextField">
|
||||
<Required>N</Required>
|
||||
<mask>/^.{1,255}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 255 characters.</ValidationMessage>
|
||||
</description>
|
||||
<mailservers type="CSVListField">
|
||||
<Required>Y</Required>
|
||||
<Sorted>Y</Sorted>
|
||||
<multiple>Y</multiple>
|
||||
<mask>/^((([0-9a-zA-Z._\-\*:\[\]]+:[0-9]+(-[0-9]+)?)([,]){0,1}))*/u</mask>
|
||||
<ChangeCase>lower</ChangeCase>
|
||||
<ValidationMessage>Please provide mailserver addresses, i.e. 192.168.1.1:25.</ValidationMessage>
|
||||
</mailservers>
|
||||
<sender type="EmailField">
|
||||
<Required>Y</Required>
|
||||
</sender>
|
||||
<recipient type="EmailField">
|
||||
<Required>Y</Required>
|
||||
</recipient>
|
||||
<loglevel type="OptionField">
|
||||
<Required>Y</Required>
|
||||
<default>alert</default>
|
||||
<OptionValues>
|
||||
<emerg>emerg</emerg>
|
||||
<alert>alert</alert>
|
||||
<crit>crit</crit>
|
||||
<err>err</err>
|
||||
<warning>warning</warning>
|
||||
<notice>notice</notice>
|
||||
<info>info</info>
|
||||
<debug>debug</debug>
|
||||
</OptionValues>
|
||||
</loglevel>
|
||||
<timeout type="TextField">
|
||||
<default>30</default>
|
||||
<MinimumValue>4</MinimumValue>
|
||||
<MaximumValue>10000</MaximumValue>
|
||||
<ValidationMessage>Please specify a value between 4 and 10000 seconds.</ValidationMessage>
|
||||
<Required>Y</Required>
|
||||
</timeout>
|
||||
<hostname type="HostnameField">
|
||||
<Required>N</Required>
|
||||
</hostname>
|
||||
</mailer>
|
||||
</mailers>
|
||||
</items>
|
||||
</model>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<Errorfiles VisibleName="Error Files" url="/ui/haproxy#errorfiles"/>
|
||||
<Mapfiles VisibleName="Map Files" url="/ui/haproxy#mapfiles"/>
|
||||
<Resolvers VisibleName="Resolvers" url="/ui/haproxy#resolvers"/>
|
||||
<Mailers VisibleName="E-Mail Alerts" url="/ui/haproxy#mailers"/>
|
||||
</Settings>
|
||||
<Statistics order="20" url="/ui/haproxy/statistics">
|
||||
<Overview VisibleName="Overview" url="/ui/haproxy/statistics#info"/>
|
||||
|
||||
@@ -212,6 +212,19 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
}
|
||||
);
|
||||
|
||||
$("#grid-mailers").UIBootgrid(
|
||||
{ search:'/api/haproxy/settings/searchMailers',
|
||||
get:'/api/haproxy/settings/getMailer/',
|
||||
set:'/api/haproxy/settings/setMailer/',
|
||||
add:'/api/haproxy/settings/addMailer/',
|
||||
del:'/api/haproxy/settings/delMailer/',
|
||||
toggle:'/api/haproxy/settings/toggleMailer/',
|
||||
options: {
|
||||
rowCount:[10,25,50,100,500,1000]
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// hook into on-show event for dialog to extend layout.
|
||||
$('#DialogAcl').on('shown.bs.modal', function (e) {
|
||||
$("#acl\\.expression").change(function(){
|
||||
@@ -608,6 +621,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
<li><a data-toggle="tab" href="#mapfiles">{{ lang._('Map Files') }}</a></li>
|
||||
<li><a data-toggle="tab" href="#cpus">{{ lang._('CPU Affinity Rules') }}</a></li>
|
||||
<li><a data-toggle="tab" href="#resolvers">{{ lang._('Resolvers') }}</a></li>
|
||||
<li><a data-toggle="tab" href="#mailers">{{ lang._('E-Mail Alerts') }}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -715,6 +729,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
<li>{{ 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('<b>', '</b>', '<b>', '</b>') }}</li>
|
||||
<li>{{ lang._("%sCPU Affinity Rules:%s This feature makes it possible to bind HAProxy's processes/threads to a specific CPU (or a CPU set). Furthermore it is possible to select CPU Affinity Rules in %sPublic Services%s to restrict them to a certain set of processes/threads/CPUs.") | format('<b>', '</b>', '<b>', '</b>') }}</li>
|
||||
<li>{{ lang._("%sResolvers:%s This feature allows in-depth configuration of how HAProxy handles name resolution and interacts with name resolvers (DNS). Each resolver configuration can be used in %sBackend Pools%s to apply individual name resolution configurations.") | format('<b>', '</b>', '<b>', '</b>') }}</li>
|
||||
<li>{{ lang._("%sE-Mail Alerts:%s It is possible to send email alerts when the state of servers changes. Each configuration can be used in %sBackend Pools%s to send e-mail alerts to the configured recipient.") | format('<b>', '</b>', '<b>', '</b>') }}</li>
|
||||
</ul>
|
||||
<p>{{ lang._("For more details visit HAProxy's official documentation regarding the %sError Messages%s, %sLua Script%s and the %sMap Files%s features. More information on HAProxy's CPU Affinity is also available %shere%s, %shere%s and %shere%s. A detailed explanation of the resolvers feature can be found %shere%s.") | format('<a href="http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#4-errorfile" target="_blank">', '</a>', '<a href="http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#lua-load" target="_blank">', '</a>', '<a href="http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#map" target="_blank">', '</a>' ,'<a href="http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#cpu-map" target="_blank">', '</a>' ,'<a href="http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#bind-process" target="_blank">', '</a>' ,'<a href="http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#process" target="_blank">', '</a>','<a href="http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#5.3.2" target="_blank">', '</a>') }}</p>
|
||||
<br/>
|
||||
@@ -1149,6 +1164,40 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="mailers" class="tab-pane fade">
|
||||
<table id="grid-mailers" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="DialogMailer">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="mailerid" data-type="number" data-visible="false">{{ lang._('Mailer ID') }}</th>
|
||||
<th data-column-id="enabled" data-width="6em" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>
|
||||
<th data-column-id="name" data-type="string">{{ lang._('Name') }}</th>
|
||||
<th data-column-id="Sender" data-type="string">{{ lang._('Sender') }}</th>
|
||||
<th data-column-id="Recipient" data-type="string">{{ lang._('Recipient') }}</th>
|
||||
<th data-column-id="commands" data-width="7em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
|
||||
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<div class="col-md-12">
|
||||
<hr/>
|
||||
<button class="btn btn-primary" id="reconfigureAct-mailers" type="button"><b>{{ lang._('Apply') }}</b><i id="reconfigureAct_progress" class=""></i></button>
|
||||
<button class="btn btn-primary" id="configtestAct-mailers" type="button"><b>{{ lang._('Test syntax') }}</b><i id="configtestAct_progress" class=""></i></button>
|
||||
<br/>
|
||||
<br/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- subtabs for general "Settings" tab below -->
|
||||
<div id="general-settings" class="tab-pane fade">
|
||||
<div class="content-box" style="padding-bottom: 1.5em;">
|
||||
@@ -1242,3 +1291,4 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogMapfile,'id':'DialogMapfile','label':lang._('Edit Map File')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogCpu,'id':'DialogCpu','label':lang._('Edit CPU Affinity Rule')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogResolver,'id':'DialogResolver','label':lang._('Edit Resolver')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogMailer,'id':'DialogMailer','label':lang._('Edit E-Mail Alert')])}}
|
||||
|
||||
@@ -1049,6 +1049,29 @@ resolvers {{resolver.id}}
|
||||
{% endfor %}
|
||||
{%- endif -%}
|
||||
|
||||
{# ############################### #}
|
||||
{# MAILERS #}
|
||||
{# ############################### #}
|
||||
|
||||
{% if helpers.exists('OPNsense.HAProxy.mailers') %}
|
||||
{% for mailer in helpers.toList('OPNsense.HAProxy.mailers.mailer') %}
|
||||
{% if mailer.enabled == '1' %}
|
||||
# Mailer: {{mailer.name}}
|
||||
mailers {{mailer.id}}
|
||||
timeout mail {{mailer.timeout}}s
|
||||
{% if mailer.mailservers|default("") != "" %}
|
||||
{% for mailserver in mailer.mailservers.split(",") %}
|
||||
mailer {{mailserver}} {{mailserver}}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
# Mailer (DISABLED): {{mailer.name}}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{%- endif -%}
|
||||
|
||||
{# ############################### #}
|
||||
{# FRONTENDS #}
|
||||
{# ############################### #}
|
||||
@@ -1353,6 +1376,23 @@ backend {{backend.name}}
|
||||
# health checking is DISABLED
|
||||
{% set healthcheck_enabled = '0' %}
|
||||
{% endif %}
|
||||
{# # mailer #}
|
||||
{% if backend.linkedMailer|default("") != "" %}
|
||||
{% set mailer_data = helpers.getUUID(backend.linkedMailer) %}
|
||||
{% if mailer_data == {} %}
|
||||
# ERROR: mailer data not found ({{backend.linkedMailer}})
|
||||
{% elif mailer_data.enabled == '0' %}
|
||||
# NOTE: specified mailer is disabled ({{mailer_data.name}})
|
||||
{% else %}
|
||||
email-alert mailers {{mailer_data.id}}
|
||||
email-alert from {{mailer_data.sender}}
|
||||
email-alert to {{mailer_data.recipient}}
|
||||
email-alert level {{mailer_data.loglevel}}
|
||||
{% if mailer_data.hostname|default("") != "" %}
|
||||
email-alert myhostname {{mailer_data.hostname}}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{# # NOTE: Usually the frontend and the backend are in the same mode, #}
|
||||
{# # but we have no way to know what frontend uses this backend. #}
|
||||
{# # Hence we can't automatically set the mode and thus need a #}
|
||||
|
||||
Reference in New Issue
Block a user