mirror of
https://github.com/lucaspalomodevelop/opnsense-core.git
synced 2026-03-13 00:07:27 +00:00
Merge branch 'kulikov-a-lvtemplates'
This commit is contained in:
commit
361e336d3e
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2021 Deciso B.V.
|
||||
*
|
||||
* 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\Diagnostics\Api;
|
||||
|
||||
use OPNsense\Base\ApiMutableModelControllerBase;
|
||||
use OPNsense\Base\UserException;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\Config;
|
||||
|
||||
class LvtemplateController extends ApiMutableModelControllerBase
|
||||
{
|
||||
protected static $internalModelName = 'lvtemplate';
|
||||
protected static $internalModelClass = 'OPNsense\Diagnostics\Lvtemplate';
|
||||
|
||||
public function searchItemAction()
|
||||
{
|
||||
return $this->searchBase(
|
||||
"templates.template",
|
||||
array('name', 'filters', 'or'), "name", null, SORT_NATURAL|SORT_FLAG_CASE
|
||||
);
|
||||
}
|
||||
|
||||
public function setItemAction($uuid)
|
||||
{
|
||||
return $this->setBase("template", "templates.template", $uuid);
|
||||
}
|
||||
|
||||
public function addItemAction()
|
||||
{
|
||||
return $this->addBase("template", "templates.template");
|
||||
}
|
||||
|
||||
public function getItemAction($uuid = null)
|
||||
{
|
||||
return $this->getBase("template", "templates.template", $uuid);
|
||||
}
|
||||
|
||||
public function delItemAction($uuid)
|
||||
{
|
||||
return $this->delBase("templates.template", $uuid);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2021 Deciso B.V.
|
||||
*
|
||||
* 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\Diagnostics;
|
||||
|
||||
use OPNsense\Base\BaseModel;
|
||||
|
||||
class Lvtemplate extends BaseModel
|
||||
{
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
<model>
|
||||
<mount>//OPNsense/Firewall/Lvtemplate</mount>
|
||||
<version>0.0.1</version>
|
||||
<description>Firewall Live View filter templates</description>
|
||||
<items>
|
||||
<templates>
|
||||
<template type="ArrayField">
|
||||
<name type="TextField">
|
||||
<Required>Y</Required>
|
||||
<mask>/^.{1,255}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 255 characters.</ValidationMessage>
|
||||
</name>
|
||||
<or type="BooleanField">
|
||||
<default>0</default>
|
||||
<Required>Y</Required>
|
||||
</or>
|
||||
<filters type="CSVListField">
|
||||
<Required>Y</Required>
|
||||
</filters>
|
||||
</template>
|
||||
</templates>
|
||||
</items>
|
||||
</model>
|
||||
@ -1,6 +1,6 @@
|
||||
{#
|
||||
#
|
||||
# Copyright (c) 2014-2016 Deciso B.V.
|
||||
# Copyright (c) 2014-2021 Deciso B.V.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -37,7 +37,7 @@
|
||||
let hostnameMap = {};
|
||||
|
||||
/**
|
||||
* reverse lookup address fields (replace adres part for hostname if found)
|
||||
* reverse lookup address fields (replace address part for hostname if found)
|
||||
*/
|
||||
function reverse_lookup() {
|
||||
let to_fetch = [];
|
||||
@ -74,6 +74,139 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set new selection
|
||||
* @param items list of lexical expressions
|
||||
* @param operator enable or disable global OR operator
|
||||
*/
|
||||
function set_selection(items, operator)
|
||||
{
|
||||
// remove old selection
|
||||
$("#filters > span.badge").click();
|
||||
// collect valid condition types
|
||||
let conditions = [];
|
||||
$("#filter_condition > option").each(function(){
|
||||
conditions.push($(this).val());
|
||||
});
|
||||
items.forEach(function(value) {
|
||||
let parts = value.split(new RegExp("("+conditions.join("|")+")(.+)$"));
|
||||
if (parts.length >= 3 && $("#filter_tag").val(parts[0]).val() === parts[0] ) {
|
||||
$("#filter_tag").val(parts[0]);
|
||||
$("#filter_condition").val(parts[1]);
|
||||
$("#filter_value").val(parts[2]);
|
||||
$("#add_filter_condition").click();
|
||||
} else if (value.toLowerCase() == "or=1") {
|
||||
operator = "1";
|
||||
}
|
||||
});
|
||||
$("#filter_or_type").prop('checked', operator === "1" ? true : false);
|
||||
$(".selectpicker").selectpicker('refresh');
|
||||
$("#filter_tag").change();
|
||||
}
|
||||
|
||||
/**
|
||||
* add new filters template
|
||||
* @param t_data template's parameters
|
||||
*/
|
||||
function addTemplate(t_data) {
|
||||
ajaxCall('/api/diagnostics/lvtemplate/addItem/', t_data, function(data, status) {
|
||||
if (data.result == "saved") {
|
||||
fetchTemplates(data.uuid);
|
||||
} else {
|
||||
BootstrapDialog.show({
|
||||
type: BootstrapDialog.TYPE_DANGER,
|
||||
title: "{{ lang._('Add filters template') }}",
|
||||
message: "{{ lang._('Template save failed. Message: ') }}" + data.result,
|
||||
buttons: [{
|
||||
label: "{{ lang._('Close') }}",
|
||||
action: function (dialogRef) {
|
||||
dialogRef.close();
|
||||
}
|
||||
}]
|
||||
});
|
||||
fetchTemplates("00000");
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* set template new values
|
||||
* @param t_id template uuid
|
||||
* @param t_data template's parameters
|
||||
*/
|
||||
function editTemplate(t_id, t_data) {
|
||||
ajaxCall('/api/diagnostics/lvtemplate/setItem/' + t_id, t_data, function(data, status) {
|
||||
if (data.result == "saved") {
|
||||
fetchTemplates(t_id);
|
||||
} else {
|
||||
BootstrapDialog.show({
|
||||
type: BootstrapDialog.TYPE_DANGER,
|
||||
title: "{{ lang._('Filters template edit') }}",
|
||||
message: "{{ lang._('Template edit failed. Message: ') }}" + data.result,
|
||||
buttons: [{
|
||||
label: "{{ lang._('Close') }}",
|
||||
action: function (dialogRef) {
|
||||
dialogRef.close();
|
||||
}
|
||||
}]
|
||||
});
|
||||
fetchTemplates(t_id);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* delete filters template
|
||||
* @param t_id template uuid
|
||||
*/
|
||||
function delTemplate(t_id) {
|
||||
ajaxCall('/api/diagnostics/lvtemplate/delItem/' + t_id, {}, function(data, status) {
|
||||
if (data.result == "deleted") {
|
||||
//don't reset current filters so template can be restored right after delete
|
||||
$("#templates option[value=" + t_id + "]").remove();
|
||||
$("#templates").val("").selectpicker('refresh');
|
||||
} else {
|
||||
BootstrapDialog.show({
|
||||
type: BootstrapDialog.TYPE_DANGER,
|
||||
title: "{{ lang._('Filters template delete') }}",
|
||||
message: "{{ lang._('Template delete failed. Result: ') }}" + data.result,
|
||||
buttons: [{
|
||||
label: "{{ lang._('Close') }}",
|
||||
action: function (dialogRef) {
|
||||
dialogRef.close();
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* fetch templates from config
|
||||
* @param opt select value to make :selected and apply
|
||||
*/
|
||||
function fetchTemplates(opt) {
|
||||
opt = opt || "00000";
|
||||
//apply = apply || true;
|
||||
$('#templ_name').val("");
|
||||
$('#templates').empty();
|
||||
$('#templates').append($('<option/>', {value: "00000", text: "None"}).data('template', {'filters': "0", 'or': "0"}).addClass("disp_none_opt templates"));
|
||||
$('#templates').append($('<option/>', {value: "00001", text: "New"}).data('template', {'filters': "0", 'or': "0"}).data('icon','glyphicon-file').addClass("add_new_opt templ_save"));
|
||||
$('#templates').selectpicker('refresh');
|
||||
$('.templates').show();
|
||||
$('.templ_save').hide();
|
||||
ajaxGet('/api/diagnostics/lvtemplate/searchItem/', {}, function(data, status) {
|
||||
let templates = data.rows;
|
||||
$.each(templates, function(i, template) {
|
||||
$('#templates').append(template.uuid == opt ? $('<option/>', {value:template.uuid, text:template.name, selected: "selected" }).data('template', template) : $('<option/>', {value:template.uuid, text:template.name }).data('template', template));
|
||||
});
|
||||
$('#templates').selectpicker('refresh');
|
||||
$('.badge').click();
|
||||
$("#templates").change();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function fetch_log() {
|
||||
var record_spec = [];
|
||||
// read heading, contains field specs
|
||||
@ -354,6 +487,95 @@
|
||||
fetch_log();
|
||||
});
|
||||
|
||||
// templates actions
|
||||
$("#templates").change(function () {
|
||||
if ($('#templ_save_start').is(':visible')) {
|
||||
//apply chosen template
|
||||
let t_data = $(this).find('option:selected').data('template') ? $(this).find('option:selected').data('template') : {'filters': "0", 'or': "0"};
|
||||
set_selection(t_data.filters.split(','), t_data.or);
|
||||
} else {
|
||||
//choose template to modify or create new one. Show Name input if New option clicked
|
||||
if ($('#templates').val() === "00001") {
|
||||
$('#templates').selectpicker('hide');
|
||||
$('#templ_name').show().focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#templ_save_start').click(function () {
|
||||
if ($(".badge").text() == '') {
|
||||
BootstrapDialog.show({
|
||||
type: BootstrapDialog.TYPE_DANGER,
|
||||
title: "{{ lang._('Save filters template') }}",
|
||||
message: "{{ lang._('Filters not set') }}",
|
||||
buttons: [{
|
||||
label: "{{ lang._('Close') }}",
|
||||
action: function (dialogRef) {
|
||||
dialogRef.close();
|
||||
}
|
||||
}]
|
||||
});
|
||||
} else {
|
||||
$('.templates').hide();
|
||||
$('.templ_save').show();
|
||||
$('#templ_name').focus();
|
||||
if ($("#templates option").length == 3){
|
||||
//no stored templates. skip to new template name
|
||||
$('#templates').val("00001").selectpicker('refresh').change();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$("#templ_save_cancel").click(function () {
|
||||
$('#templ_name').val("").hide();
|
||||
$('.templ_save').hide();
|
||||
$('.templates').show();
|
||||
$('#templates').val('').selectpicker('refresh').selectpicker('show');
|
||||
});
|
||||
|
||||
$("#templ_name").on('keyup', function (e) {
|
||||
if (e.key === 'Enter' || e.keyCode === 13) {
|
||||
$('#templ_save_apply').click();
|
||||
} else if (e.keyCode === 27) {
|
||||
$('#templ_name').val("").hide();
|
||||
$('#templates').val('').selectpicker('refresh').selectpicker('show');
|
||||
}
|
||||
});
|
||||
|
||||
$("#templ_save_apply").click(function () {
|
||||
let fltrs = "";
|
||||
$('.badge').each(function () {
|
||||
fltrs += $(this).text() + ",";
|
||||
});
|
||||
fltrs = fltrs.slice(0, -1);
|
||||
let or = $('#filter_or_type').prop("checked") ? "1" : "0";
|
||||
let t_data = {
|
||||
'template': {
|
||||
'filters': fltrs,
|
||||
'or': or
|
||||
}
|
||||
};
|
||||
$('#templates').selectpicker('refresh').selectpicker('show');
|
||||
if ($("#templ_name").val().length >= 1 && $("#templ_name").is(':visible')) {
|
||||
//new template
|
||||
t_data.template.name = $("#templ_name").val();
|
||||
$('#templ_name').val("").hide();
|
||||
addTemplate(t_data);
|
||||
} else if ($("#templ_name").val().length == 0 && $("#templ_name").is(':hidden') && $("#templates").val().length == 36) {
|
||||
//edit template
|
||||
let t_id = $("#templates").val();
|
||||
t_data.template.name = $("#templates option:selected").text();
|
||||
editTemplate(t_id, t_data);
|
||||
}
|
||||
});
|
||||
|
||||
$("#template_delete").click(function () {
|
||||
let t_id = $('#templates').val();
|
||||
if (t_id.length == 36) {
|
||||
delTemplate(t_id);
|
||||
}
|
||||
});
|
||||
|
||||
// fetch interface mappings on load
|
||||
ajaxGet('/api/diagnostics/interface/getInterfaceNames', {}, function(data, status) {
|
||||
interface_descriptions = data;
|
||||
@ -389,36 +611,14 @@
|
||||
filter_value.show();
|
||||
}
|
||||
}).change();
|
||||
fetchTemplates("00000");
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* set new selection
|
||||
* @param items list of lexical expressions
|
||||
*/
|
||||
function set_selection(items)
|
||||
{
|
||||
// remove old selection
|
||||
$("#filters > span.badge").click();
|
||||
// collect valid condition types
|
||||
let conditions = [];
|
||||
$("#filter_condition > option").each(function(){
|
||||
conditions.push($(this).val());
|
||||
});
|
||||
items.forEach(function(value) {
|
||||
let parts = value.split(new RegExp("("+conditions.join("|")+")(.+)$"));
|
||||
if (parts.length >= 3 && $("#filter_tag").val(parts[0]).val() === parts[0] ) {
|
||||
$("#filter_tag").val(parts[0]);
|
||||
$("#filter_condition").val(parts[1]);
|
||||
$("#filter_value").val(parts[2]);
|
||||
$("#add_filter_condition").click();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// get and apply url params. ie11 compat
|
||||
set_selection(window.location.search.substring(1).split("&"));
|
||||
set_selection(window.location.search.substring(1).split("&"), "0");
|
||||
|
||||
// startup poller
|
||||
poller();
|
||||
@ -473,7 +673,7 @@
|
||||
</select>
|
||||
</td>
|
||||
<td style="width:125px;">
|
||||
<select id="filter_condition" class="condition" data-width="120px">
|
||||
<select id="filter_condition" class="selectpicker" data-width="120px">
|
||||
<option value="~" selected=selected>{{ lang._('contains') }}</option>
|
||||
<option value="=">{{ lang._('is') }}</option>
|
||||
<option value="!~">{{ lang._('does not contain') }}</option>
|
||||
@ -505,14 +705,34 @@
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<input id="filter_or_type" type="checkbox">
|
||||
{{ lang._('Select any of given criteria (or)') }}
|
||||
<label>
|
||||
<input id="filter_or_type" type="checkbox">
|
||||
{{ lang._('Select any of given criteria (or)') }}
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-lg-6 col-sm-12">
|
||||
<div class="col-lg-4 col-sm-12">
|
||||
<div class="pull-right">
|
||||
<button type="button" class="btn btn-default templates"
|
||||
title="Save the current set of filters" id="templ_save_start"><span
|
||||
class="fa fa-angle-double-right"></span></button>
|
||||
<button type="button" class="btn btn-default templ_save" title="Cancel" id="templ_save_cancel"><span
|
||||
class="fa fa-times"></span></button>
|
||||
<div style="display: inline-block;vertical-align: top;"><select id="templates" class="selectpicker" title="Choose template" data-width="200"></select>
|
||||
<input type="text" id="templ_name" placeholder="Template name" style="width:200px;vertical-align:middle;display:none;">
|
||||
</div>
|
||||
<button type="button" class="btn btn-default templ_save" title="Save template" id="templ_save_apply"><span class="fa fa-save"></span></button>
|
||||
<span class="templates">
|
||||
<button id="template_delete" type="button" class="btn btn-default" title="Deleted selected template" if="templ_del">
|
||||
<span class="fa fa-trash"></span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-2 col-sm-12">
|
||||
<div class="pull-right">
|
||||
<div class="checkbox-inline">
|
||||
<label>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user