diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Unbound/Api/OverviewController.php b/src/opnsense/mvc/app/controllers/OPNsense/Unbound/Api/OverviewController.php index 87b8c4c66..1b5caa844 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Unbound/Api/OverviewController.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/Unbound/Api/OverviewController.php @@ -43,11 +43,18 @@ class OverviewController extends ApiControllerBase ]; } + public function isBlockListEnabledAction() + { + return [ + 'enabled' => (new \OPNsense\Unbound\Unbound())->getNodes()['dnsbl']['enabled'] + ]; + } + public function RollingAction($timeperiod, $clients = false) { $this->sessionClose(); // Sanitize input - $interval = preg_replace("/^(?:(?!1|12|24).)*$/", "24", $timeperiod) == 1 ? 60 : 300; + $interval = preg_replace("/^(?:(?!1|12|24).)*$/", "24", $timeperiod) == 1 ? 60 : 600; $type = $clients ? 'clients' : 'rolling'; $response = (new Backend())->configdpRun('unbound qstats ' . $type, [$interval, $timeperiod]); return json_decode($response, true); diff --git a/src/opnsense/mvc/app/views/OPNsense/Unbound/overview.volt b/src/opnsense/mvc/app/views/OPNsense/Unbound/overview.volt index 2bc525cff..48217227b 100644 --- a/src/opnsense/mvc/app/views/OPNsense/Unbound/overview.volt +++ b/src/opnsense/mvc/app/views/OPNsense/Unbound/overview.volt @@ -253,7 +253,7 @@ /* Add a redundant data step to end the chart time axis properly */ if (formatted.length > 0) { let lastVal = formatted[formatted.length - 1]; - let interval = $("#timeperiod").val() == 1 ? 60 : 300; + let interval = $("#timeperiod").val() == 1 ? 60 : 600; let y_val = logarithmic ? 0.1 : 0 formatted.push({ x: lastVal.x + (interval * 1000), @@ -290,7 +290,7 @@ /* Add a redundant data step to end the chart time axis properly */ if (tmp.length > 0) { let lastVal = tmp[tmp.length - 1]; - let interval = $("#timeperiod-clients").val() == 1 ? 60 : 300; + let interval = $("#timeperiod-clients").val() == 1 ? 60 : 600; tmp.push({ x: lastVal.x + (interval * 1000), y: backup_val, @@ -354,23 +354,41 @@ } function createTopList(id, data, type) { - let idx = 1; - for (const [domain, statObj] of Object.entries(data)) { + ajaxGet('/api/unbound/overview/isBlockListEnabled', {}, function(bl_enabled, status) { let class_type = type == "pass" ? "block-domain" : "whitelist-domain"; let icon_type = type == "pass" ? "fa fa-ban text-danger" : "fa fa-pencil text-info"; - let bl = statObj.hasOwnProperty('blocklist') ? '(' + statObj.blocklist + ')' : ''; - $('#' + id).append( - '
  • ' + - idx + '. ' + domain + ' ' + bl + - ''+ statObj.total +' (' + statObj.pcnt +'%)' + - '' + - '
  • ' - ) - idx++; - } - $(".block-domain").tooltip().attr('title', "{{ lang._('Block Domain') }}"); - $(".whitelist-domain").tooltip().attr('title', "{{ lang._('Whitelist Domain') }}"); + for (let i = 0; i < 10; i++) { + let domain = Object.keys(data)[i]; + let statObj = Object.values(data)[i]; + if (typeof domain == 'undefined' || typeof statObj == 'undefined') { + $('#' + id).append( + '
  • ' + + (i + 1) + '. ' + + '0 (0.0%)' + + '
  • ' + ) + continue; + } + + let icon = '' + + if (bl_enabled.enabled == 0) { + icon = ''; + } + + let bl = statObj.hasOwnProperty('blocklist') ? '(' + statObj.blocklist + ')' : ''; + $('#' + id).append( + '
  • ' + + (i + 1) + '. ' + domain + ' ' + bl + + ''+ statObj.total +' (' + statObj.pcnt +'%)' + + icon + + '
  • ' + ) + } + $(".block-domain").tooltip().attr('title', "{{ lang._('Block Domain') }}"); + $(".whitelist-domain").tooltip().attr('title', "{{ lang._('Whitelist Domain') }}"); + }); } function create_or_update_totals() { @@ -478,62 +496,72 @@ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { if (e.target.id == 'query_details_tab') { $("#grid-queries").bootgrid('destroy'); - let grid_queries = $("#grid-queries").UIBootgrid({ - search:'/api/unbound/overview/searchQueries/', - options: { - rowSelect: false, - multiSelect: false, - selection: false, - formatters: { - "timeformatter": function (column, row) { - return moment.unix(row.time).local().format('YYYY-MM-DD HH:mm:ss'); + ajaxGet('/api/unbound/overview/isBlockListEnabled', {}, function(bl_enabled, status) { + let grid_queries = $("#grid-queries").UIBootgrid({ + search:'/api/unbound/overview/searchQueries/', + options: { + rowSelect: false, + multiSelect: false, + selection: false, + formatters: { + "timeformatter": function (column, row) { + return moment.unix(row.time).local().format('YYYY-MM-DD HH:mm:ss'); + }, + "resolveformatter": function (column, row) { + return row.resolve_time_ms + 'ms'; + }, + "commands": function (column, row) { + let btn = ''; + if (bl_enabled.enabled == 0) { + return btn; + } else if (row.action == 'Pass') { + btn = ' '; + } else if (row.action == 'Block') { + btn = ''; + } + return btn; + }, }, - "resolveformatter": function (column, row) { - return row.resolve_time_ms + 'ms'; - }, - "commands": function (column, row) { - let btn = ''; - if (row.action == 'Pass') { - btn = ' '; - } else if (row.action == 'Block') { - btn = ''; - } - return btn; - }, - }, - statusMapping: { - 0: "query-success", - 1: "info", - 2: "query-warning", - 3: "query-danger", - 4: "danger" + statusMapping: { + 0: "query-success", + 1: "info", + 2: "query-warning", + 3: "query-danger", + 4: "danger" + } } - } - }).on("loaded.rs.jquery.bootgrid", function (e) { - $(".block-domain").tooltip().attr('title', "{{ lang._('Block Domain') }}"); - $(".whitelist-domain").tooltip().attr('title', "{{ lang._('Whitelist Domain') }}"); - grid_queries.find(".block-domain").on("click", function(e) { - $(this).remove("i").html(''); - ajaxCall('/api/unbound/settings/updateBlocklist', { - 'domain': $(this).data('domain'), - 'type': 'blocklists', - }, function(data, status) { - let btn = grid_queries.find(".block-domain"); - btn.remove("i").html(''); - }); - }); + }).on("loaded.rs.jquery.bootgrid", function (e) { + if (bl_enabled.enabled == 0) { + $(".hide-col").css("display", "none"); + } else { + $(".hide-col").css('display', ''); + } + $(".block-domain").tooltip().attr('title', "{{ lang._('Block Domain') }}"); + $(".whitelist-domain").tooltip().attr('title', "{{ lang._('Whitelist Domain') }}"); + grid_queries.find(".block-domain").on("click", function(e) { + $(this).remove("i").html(''); + ajaxCall('/api/unbound/settings/updateBlocklist', { + 'domain': $(this).data('domain'), + 'type': 'blocklists', + }, function(data, status) { + let btn = grid_queries.find(".block-domain"); + btn.remove("i").html(''); + }); + }); + + grid_queries.find(".whitelist-domain").on("click", function(e) { + $(this).remove("i").html(''); + ajaxCall('/api/unbound/settings/updateBlocklist', { + 'domain': $(this).data('domain'), + 'type': 'whitelists', + }, function(data, status) { + let btn = grid_queries.find(".whitelist-domain"); + btn.remove("i").html(''); + }); + }); + }); + }) - grid_queries.find(".whitelist-domain").on("click", function(e) { - $(this).remove("i").html(''); - ajaxCall('/api/unbound/settings/updateBlocklist', { - 'domain': $(this).data('domain'), - 'type': 'whitelists', - }, function(data, status) { - let btn = grid_queries.find(".whitelist-domain"); - btn.remove("i").html(''); - }); - }); - }); } if (e.target.id == 'query_overview_tab') { create_or_update_totals(); @@ -714,7 +742,7 @@ {{ lang._('Resolve time') }} {{ lang._('TTL') }} {{ lang._('Blocklist') }} - {{ lang._('Command') }} + {{ lang._('Command') }} diff --git a/src/opnsense/scripts/unbound/logger.py b/src/opnsense/scripts/unbound/logger.py index 54ada8431..6ccfdcb92 100755 --- a/src/opnsense/scripts/unbound/logger.py +++ b/src/opnsense/scripts/unbound/logger.py @@ -68,7 +68,7 @@ class DNSReader: ) """) - for size in [300, 60]: + for size in [600, 300, 60]: db.connection.execute( """ CREATE OR REPLACE VIEW v_time_series_{min}min AS ( diff --git a/src/opnsense/scripts/unbound/stats.py b/src/opnsense/scripts/unbound/stats.py index be1aa8cfc..a7f8e6b85 100755 --- a/src/opnsense/scripts/unbound/stats.py +++ b/src/opnsense/scripts/unbound/stats.py @@ -45,7 +45,7 @@ def percent(val, total): def handle_rolling(args): # sanitize input - interval = int(re.sub("^(?:(?!300|60).)*$", "300", str(args.interval))) + interval = int(re.sub("^(?:(?!600|300|60).)*$", "600", str(args.interval))) tp = int(re.sub("^(?:(?!24|12|1).)*$", "24", str(args.timeperiod))) data = pandas.DataFrame() diff --git a/src/opnsense/www/css/dns-overview.css b/src/opnsense/www/css/dns-overview.css index ecdf17f0e..4283ad86f 100644 --- a/src/opnsense/www/css/dns-overview.css +++ b/src/opnsense/www/css/dns-overview.css @@ -65,6 +65,10 @@ padding-bottom: 10px; } +.list-group-item { + height: 2.5em; +} + .list-group-item-border { border: 1px solid #ddd; }