From 856291aa6708b134249dcdbed466241d675520ed Mon Sep 17 00:00:00 2001 From: Matteo Biscosi Date: Thu, 16 Apr 2026 07:57:41 +0000 Subject: [PATCH] Added looking glass page --- http_src/vue/ntop_vue.js | 2 + http_src/vue/page-looking-glass.vue | 118 +++ httpdocs/tables_config/looking_glass.json | 95 ++ scripts/locales/en.lua | 3 +- scripts/lua/flow_details.lua | 15 - scripts/lua/inc/menu.lua | 977 +++++++++--------- scripts/lua/looking_glass.lua | 36 + scripts/lua/modules/bgp_utils.lua | 120 +++ scripts/lua/modules/page_utils.lua | 6 + .../rest/v2/get/flow/bgp/general_stats.lua | 111 +- .../rest/v2/get/flow/bgp/looking_glass.lua | 37 + 11 files changed, 895 insertions(+), 625 deletions(-) create mode 100644 http_src/vue/page-looking-glass.vue create mode 100644 httpdocs/tables_config/looking_glass.json create mode 100644 scripts/lua/looking_glass.lua create mode 100644 scripts/lua/modules/bgp_utils.lua create mode 100644 scripts/lua/rest/v2/get/flow/bgp/looking_glass.lua diff --git a/http_src/vue/ntop_vue.js b/http_src/vue/ntop_vue.js index afea71e597..1883a11609 100644 --- a/http_src/vue/ntop_vue.js +++ b/http_src/vue/ntop_vue.js @@ -110,6 +110,7 @@ import { default as PageEditDeviceProtocols } from "./page-edit-device-protocols import { default as PageAiStats } from "./page-ai-stats.vue" import { default as PageAlertExclusions } from "./page-alert-exclusions.vue" import { default as PageInternals } from "./page-internals.vue" +import { default as PageLookingGlass } from "./page-looking-glass.vue" /* Testing page */ import { default as PageTest } from "./page-test.vue"; @@ -263,6 +264,7 @@ let ntopVue = { PageAiStats: PageAiStats, PageAlertExclusions: PageAlertExclusions, PageInternals: PageInternals, + PageLookingGlass: PageLookingGlass, PageExportersGraph: PageExportersGraph, PageAbout: PageAbout, diff --git a/http_src/vue/page-looking-glass.vue b/http_src/vue/page-looking-glass.vue new file mode 100644 index 0000000000..12e1506c92 --- /dev/null +++ b/http_src/vue/page-looking-glass.vue @@ -0,0 +1,118 @@ + + + + diff --git a/httpdocs/tables_config/looking_glass.json b/httpdocs/tables_config/looking_glass.json new file mode 100644 index 0000000000..594a9b1329 --- /dev/null +++ b/httpdocs/tables_config/looking_glass.json @@ -0,0 +1,95 @@ +{ + "id": "looking_glass", + "data_url": "lua/rest/v2/get/flow/bgp/looking_glass.lua", + "use_current_page": false, + "enable_search": true, + "paging": false, + "display_empty_rows": true, + "default_sort": { + "column_id": "prefix", + "sort": 0 + }, + "columns": [ + { + "title_i18n": "flow_details.bgp_prefix", + "data_field": "prefix", + "sortable": true, + "min-width" : "120px", + "class": [ + "text-nowrap" + ] + }, + { + "title_i18n": "flow_details.bgp_peer_id", + "data_field": "peer_id", + "sortable": true, + "min-width" : "120px", + "class": [ + "text-nowrap" + ] + }, + { + "title_i18n": "flow_details.bgp_peer_asn", + "data_field": "peer_asn", + "sortable": true, + "min-width" : "120px", + "class": [ + "text-nowrap" + ] + }, + { + "title_i18n": "flow_details.bgp_origin", + "data_field": "origin", + "sortable": true, + "min-width" : "120px", + "class": [ + "text-nowrap" + ] + }, + { + "title_i18n": "flow_details.bgp_next_hop", + "data_field": "next_hop", + "sortable": true, + "min-width" : "120px", + "class": [ + "text-nowrap" + ] + }, + { + "title_i18n": "flow_details.bgp_as_path", + "data_field": "as_path", + "sortable": true, + "min-width" : "120px", + "class": [ + "text-nowrap" + ] + }, + { + "title_i18n": "flow_details.bgp_med", + "data_field": "med", + "sortable": true, + "min-width" : "120px", + "class": [ + "text-nowrap" + ] + }, + { + "title_i18n": "flow_details.bgp_local_pref", + "data_field": "local_pref", + "sortable": true, + "min-width" : "120px", + "class": [ + "text-nowrap" + ] + }, + { + "title_i18n": "flow_details.bgp_communities", + "data_field": "communities", + "sortable": true, + "min-width" : "120px", + "class": [ + "text-nowrap" + ] + } + ] +} diff --git a/scripts/locales/en.lua b/scripts/locales/en.lua index 6473b9c90c..4982c241b6 100644 --- a/scripts/locales/en.lua +++ b/scripts/locales/en.lua @@ -615,6 +615,7 @@ local lang = { ["local_traffic"] = "Local Traffic", ["location"] = "Location", ["lower_value_upper"] = "(lower / value / upper)", + ["looking_glass"] = "Looking Glass", ["lua_c_api"] = "Lua/C API", ["mac_address"] = "MAC Address", ["mac_address_dev_type"] = "MAC Address / Device Type", @@ -827,7 +828,7 @@ local lang = { ["scripts"] = "Scripts", ["search"] = "Search", ["search_box"] = "Search an Host, Network, ...", - ["search_host"] = "Search", + ["search_host"] = "Search an Host", ["seen_since"] = "Seen Since", ["sent"] = "Sent", ["serial"] = "Serial", diff --git a/scripts/lua/flow_details.lua b/scripts/lua/flow_details.lua index 6580043a1e..b4458256e3 100644 --- a/scripts/lua/flow_details.lua +++ b/scripts/lua/flow_details.lua @@ -1960,21 +1960,6 @@ if isEmptyString(page) or page == "overview" then print("\n") end - - -- tprint(flow.bgp) - if flow.bgp and not isEmptyString(flow.bgp.src) then - print('' .. - i18n("flow_details.src_bgp_info") .. '') - print(format_utils.formatBgpBmpInfo(json.decode(flow.bgp.src))) - print('\n') - end - - if flow.bgp and not isEmptyString(flow.bgp.dst) then - print('' .. - i18n("flow_details.dst_bgp_info") .. '') - print(format_utils.formatBgpBmpInfo(json.decode(flow.bgp.dst))) - print('\n') - end if (flow.prev_adjacent_as or flow.next_adjacent_as) then print("") diff --git a/scripts/lua/inc/menu.lua b/scripts/lua/inc/menu.lua index f5fc327b7b..16acb8655b 100644 --- a/scripts/lua/inc/menu.lua +++ b/scripts/lua/inc/menu.lua @@ -2,15 +2,10 @@ -- (C) 2013-26 - ntop.org -- local dirs = ntop.getDirs() -package.path = - dirs.installdir .. "/pro/scripts/lua/enterprise/modules/?.lua;" .. - package.path +package.path = dirs.installdir .. "/pro/scripts/lua/enterprise/modules/?.lua;" .. package.path package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path -package.path = dirs.installdir .. "/scripts/lua/modules/toasts/?.lua;" .. - package.path -package.path = dirs.installdir .. - "/scripts/lua/modules/vulnerability_scan/?.lua;" .. - package.path +package.path = dirs.installdir .. "/scripts/lua/modules/toasts/?.lua;" .. package.path +package.path = dirs.installdir .. "/scripts/lua/modules/vulnerability_scan/?.lua;" .. package.path if ((dirs.scriptdir ~= nil) and (dirs.scriptdir ~= "")) then package.path = dirs.scriptdir .. "/lua/modules/?.lua;" .. package.path @@ -31,20 +26,17 @@ local checks = require "checks" local has_local_auth = (ntop.getPref("ntopng.prefs.local.auth_enabled") ~= '0') local has_help_enabled = (ntop.getPref("ntopng.prefs.menu_entries.help") ~= '0') -local has_developer_enabled = (ntop.getPref( - "ntopng.prefs.menu_entries.developer") ~= '0') +local has_developer_enabled = (ntop.getPref("ntopng.prefs.menu_entries.developer") ~= '0') -- ************************************ -prefs = ntop.getPrefs() +local prefs = ntop.getPrefs() local asset_inventory_enabled = assetsInventoryEnabled() -local is_influxdb_enabled = ntop.getPref("ntopng.prefs.timeseries_driver") == - "influxdb" +local is_influxdb_enabled = ntop.getPref("ntopng.prefs.timeseries_driver") == "influxdb" local has_ch_support = hasClickHouseSupport() - -- user data local is_admin = isAdministrator() local session_user = _SESSION['user'] @@ -56,7 +48,7 @@ local has_vlans = interface.hasVLANs() local is_allowed_sys_interface = isAllowedSystemInterface() local system_ifid = getSystemInterfaceId() local interface_id = ifid_stats.id -local random_csrf = ntop.getRandomCSRFValue() +local random_csrf = ntop.getRandomCSRFValue() local is_system_interface = toboolean(page_utils.is_system_view()) local is_pcap_dump = interface.isPcapDumpInterface() local is_packet_interface = interface.isPacketInterface() @@ -73,7 +65,9 @@ local current_ifid = interface.getId() -- compute number of interfaces num_ifaces = 0 -for k, v in pairs(iface_names) do num_ifaces = num_ifaces + 1 end +for k, v in pairs(iface_names) do + num_ifaces = num_ifaces + 1 +end -- nedge versions local is_nedge = ntop.isnEdge() @@ -82,13 +76,13 @@ local is_routing_mode = false if is_nededge then is_routing_mode = ntop.isRoutingMode() end -local is_nedge_enterprise = ntop.isnEdgeEnterprise() +local is_nedge_enterprise = ntop.isnEdgeEnterprise() -- ntopng info/version local info = ntop.getInfo() -local is_pro = ntop.isPro() -local is_enterprise_M = ntop.isEnterpriseM() -local is_enterprise = ntop.isEnterprise() +local is_pro = ntop.isPro() +local is_enterprise_M = ntop.isEnterpriseM() +local is_enterprise = ntop.isEnterprise() local is_enterprise_L = ntop.isEnterpriseL() local is_enterprise_XL = ntop.isEnterpriseXL() local is_appliance = ntop.isAppliance() @@ -111,7 +105,6 @@ local obsPointsInfo = interface.getObsPointsInfo() or {} local obs_points = obsPointsInfo["ObsPoints"] or {} local num_obs_points = obsPointsInfo.numObsPoints or 0 - local checks_config = checks.getConfigset()["config"] local interface_config = checks_config["interface"] local flow_config = checks_config["flow"] @@ -168,7 +161,11 @@ print [[", print(i18n("no_data_available")) print [[", "showing_x_to_y_rows": "]] -print(i18n("showing_x_to_y_rows", {x = "{0}", y = "{1}", tot = "{2}"})) +print(i18n("showing_x_to_y_rows", { + x = "{0}", + y = "{1}", + tot = "{2}" +})) print [[", "actions": "]] print(i18n("actions")) @@ -243,7 +240,9 @@ print [[", print(i18n("nation")) print [[", "and_x_more": "]] -print(i18n("and_x_more", {num = '$num'})) +print(i18n("and_x_more", { + num = '$num' +})) print [[", "invalid_input": "]] print(i18n("validation.invalid_input")) @@ -302,21 +301,18 @@ else page_utils.add_menubar_section({ section = page_utils.menu_sections.dashboard, hidden = is_pcap_dump or is_system_interface or is_db_view_interface, - entries = { - { - entry = page_utils.menu_entries.traffic_dashboard, - url = '/lua/index.lua' - }, { - entry = page_utils.menu_entries.assets_dashboard, - hidden = (not has_ch_support) or (not asset_inventory_enabled) or (not is_enterprise_L), - url = "/lua/pro/assets_dashboard.lua" - }, { - entry = page_utils.menu_entries.traffic_report, - hidden = not (is_enterprise and has_ch_support) or - infrastructure_view or is_viewed, -- disable if interface is viewed - url = "/lua/pro/report.lua" - } - } + entries = {{ + entry = page_utils.menu_entries.traffic_dashboard, + url = '/lua/index.lua' + }, { + entry = page_utils.menu_entries.assets_dashboard, + hidden = (not has_ch_support) or (not asset_inventory_enabled) or (not is_enterprise_L), + url = "/lua/pro/assets_dashboard.lua" + }, { + entry = page_utils.menu_entries.traffic_report, + hidden = not (is_enterprise and has_ch_support) or infrastructure_view or is_viewed, -- disable if interface is viewed + url = "/lua/pro/report.lua" + }} }) -- ############################################## @@ -329,34 +325,28 @@ else page_utils.add_menubar_section({ section = page_utils.menu_sections.monitoring, hidden = is_system_interface or not is_admin, - entries = { - { - entry = page_utils.menu_entries.active_monitoring, - hidden = is_windows, - url = "/lua/active_monitoring.lua" - }, { - entry = page_utils.menu_entries.network_discovery, - hidden = not is_discoverable_interface or is_windows or - is_loopback_interface or limit_resource_usage or - infrastructure_view, - url = "/lua/discover.lua" - }, { - entry = page_utils.menu_entries.infrastructure_dashboard, - hidden = (not is_enterprise_L and - not is_nedge_enterprise) or not is_admin, - url = '/lua/pro/enterprise/infrastructure_config.lua' - }, { - entry = page_utils.menu_entries.snmp_monitoring, - hidden = (not is_enterprise_M and - not is_nedge_enterprise), - url = "/lua/pro/enterprise/snmpdevices_stats.lua" - }, { - entry = page_utils.menu_entries.vulnerability_scan, - url = '/lua/vulnerability_scan.lua', - hidden = not is_vs_utils_available or - is_zmq_interface - } - } + entries = {{ + entry = page_utils.menu_entries.active_monitoring, + hidden = is_windows, + url = "/lua/active_monitoring.lua" + }, { + entry = page_utils.menu_entries.network_discovery, + hidden = not is_discoverable_interface or is_windows or is_loopback_interface or limit_resource_usage or + infrastructure_view, + url = "/lua/discover.lua" + }, { + entry = page_utils.menu_entries.infrastructure_dashboard, + hidden = (not is_enterprise_L and not is_nedge_enterprise) or not is_admin, + url = '/lua/pro/enterprise/infrastructure_config.lua' + }, { + entry = page_utils.menu_entries.snmp_monitoring, + hidden = (not is_enterprise_M and not is_nedge_enterprise), + url = "/lua/pro/enterprise/snmpdevices_stats.lua" + }, { + entry = page_utils.menu_entries.vulnerability_scan, + url = '/lua/vulnerability_scan.lua', + hidden = not is_vs_utils_available or is_zmq_interface + }} }) -- ############################################## @@ -364,35 +354,30 @@ else -- Alerts page_utils.add_menubar_section({ section = page_utils.menu_sections.alerts, - hidden = not prefs.are_alerts_enabled or - not auth.has_capability(auth.capabilities.alerts) or + hidden = not prefs.are_alerts_enabled or not auth.has_capability(auth.capabilities.alerts) or is_db_view_interface or infrastructure_view, - entries = { - { - entry = page_utils.menu_entries.alerts_list, - url = "/lua/alert_stats.lua" - }, { - entry = page_utils.menu_entries.alerts_graph, - url = "/lua/pro/alerts_graph.lua", - hidden = (not is_enterprise_L and not is_nedge_enterprise) or - (not has_ch_support) or - (is_pcap_dump) - }, { - entry = page_utils.menu_entries.alerts_geomap, - url = "/lua/pro/alerts_geomap.lua", - hidden = true or (not is_enterprise_XL) - }, { - entry = page_utils.menu_entries.alerts_analysis, - url = "/lua/pro/enterprise/alerts_analysis.lua", - hidden = (not is_enterprise) or is_pcap_dump - }, { - entry = page_utils.menu_entries.divider - }, { - entry = page_utils.menu_sections.notifications, - hidden = (not is_admin) or is_pcap_dump, - url = '/lua/admin/endpoint_notifications_list.lua' - } - } + entries = {{ + entry = page_utils.menu_entries.alerts_list, + url = "/lua/alert_stats.lua" + }, { + entry = page_utils.menu_entries.alerts_graph, + url = "/lua/pro/alerts_graph.lua", + hidden = (not is_enterprise_L and not is_nedge_enterprise) or (not has_ch_support) or (is_pcap_dump) + }, { + entry = page_utils.menu_entries.alerts_geomap, + url = "/lua/pro/alerts_geomap.lua", + hidden = true or (not is_enterprise_XL) + }, { + entry = page_utils.menu_entries.alerts_analysis, + url = "/lua/pro/enterprise/alerts_analysis.lua", + hidden = (not is_enterprise) or is_pcap_dump + }, { + entry = page_utils.menu_entries.divider + }, { + entry = page_utils.menu_sections.notifications, + hidden = (not is_admin) or is_pcap_dump, + url = '/lua/admin/endpoint_notifications_list.lua' + }} }) -- ############################################## @@ -400,26 +385,28 @@ else -- Flows page_utils.add_menubar_section({ section = page_utils.menu_sections.flows, - hidden = is_asn_mode_enabled or - (is_system_interface or infrastructure_view), - entries = { - { - entry = page_utils.menu_entries.active_flows, - url = "/lua/flows_stats.lua" - }, { - entry = page_utils.menu_entries.db_explorer, - hidden = (not is_enterprise and - not is_nedge_enterprise) or - not auth.has_capability(auth.capabilities.historical_flows) or - ifid_stats.isViewed or ifid_stats['type'] == 'db' or - not has_ch_support, - url = "/lua/pro/db_search.lua" - }, { - entry = page_utils.menu_entries.server_ports, - url = '/lua/server_ports.lua', - hidden = not is_enterprise_L - } - } + hidden = is_asn_mode_enabled or (is_system_interface or infrastructure_view), + entries = {{ + entry = page_utils.menu_entries.active_flows, + url = "/lua/flows_stats.lua" + }, { + entry = page_utils.menu_entries.db_explorer, + hidden = (not is_enterprise and not is_nedge_enterprise) or + not auth.has_capability(auth.capabilities.historical_flows) or ifid_stats.isViewed or ifid_stats['type'] == + 'db' or not has_ch_support, + url = "/lua/pro/db_search.lua" + }, { + entry = page_utils.menu_entries.server_ports, + url = '/lua/server_ports.lua', + hidden = not is_enterprise_L + }, { + entry = page_utils.menu_entries.divider + }, { + entry = page_utils.menu_entries.looking_glass, + url = '/lua/looking_glass.lua', + hidden = isEmptyString(ntop.getPref("ntopng.prefs.bgp_server.ip_address")) or + isEmptyString(ntop.getPref('ntopng.prefs.bgp_server.port')) + }} }) -- ############################################## @@ -440,51 +427,45 @@ else page_utils.add_menubar_section({ section = page_utils.menu_sections.views, - hidden = not is_asn_mode_enabled or - (is_system_interface or is_viewed or infrastructure_view), - entries = { - { - entry = page_utils.menu_entries.hosts_asn_mode, - url = '/lua/hosts_stats.lua' - }, { - entry = page_utils.menu_entries.active_flows_asn_mode, - url = "/lua/flows_stats.lua" - }, { - entry = page_utils.menu_entries.historical_flows_asn_mode, - hidden = (not is_enterprise and - not is_nedge_enterprise) or - not auth.has_capability(auth.capabilities.historical_flows) or - ifid_stats.isViewed or ifid_stats['type'] == 'db' or - not has_ch_support, - url = "/lua/pro/db_search.lua" - }, { - entry = page_utils.menu_entries.server_ports_asn_mode, - url = '/lua/server_ports.lua', - hidden = not is_enterprise_L - } - } + hidden = not is_asn_mode_enabled or (is_system_interface or is_viewed or infrastructure_view), + entries = {{ + entry = page_utils.menu_entries.hosts_asn_mode, + url = '/lua/hosts_stats.lua' + }, { + entry = page_utils.menu_entries.active_flows_asn_mode, + url = "/lua/flows_stats.lua" + }, { + entry = page_utils.menu_entries.historical_flows_asn_mode, + hidden = (not is_enterprise and not is_nedge_enterprise) or + not auth.has_capability(auth.capabilities.historical_flows) or ifid_stats.isViewed or ifid_stats['type'] == + 'db' or not has_ch_support, + url = "/lua/pro/db_search.lua" + }, { + entry = page_utils.menu_entries.server_ports_asn_mode, + url = '/lua/server_ports.lua', + hidden = not is_enterprise_L + }} }) -- ############################################## -- Hosts page_utils.add_menubar_section({ section = page_utils.menu_sections.hosts, - hidden = is_system_interface or is_viewed or infrastructure_view or - is_asn_mode_enabled, - entries = { - { - entry = page_utils.menu_entries.hosts, - url = '/lua/hosts_stats.lua' - }, { - entry = page_utils.menu_entries.devices, - hidden = (not ifid_stats.has_macs), - url = '/lua/macs_stats.lua' - }, {entry = page_utils.menu_entries.divider}, { - hidden = not (is_enterprise_M and not is_windows) or not asset_inventory_enabled, - entry = page_utils.menu_entries.assets, - url = '/lua/pro/assets.lua' - } - } + hidden = is_system_interface or is_viewed or infrastructure_view or is_asn_mode_enabled, + entries = {{ + entry = page_utils.menu_entries.hosts, + url = '/lua/hosts_stats.lua' + }, { + entry = page_utils.menu_entries.devices, + hidden = (not ifid_stats.has_macs), + url = '/lua/macs_stats.lua' + }, { + entry = page_utils.menu_entries.divider + }, { + hidden = not (is_enterprise_M and not is_windows) or not asset_inventory_enabled, + entry = page_utils.menu_entries.assets, + url = '/lua/pro/assets.lua' + }} }) -- ############################################## @@ -492,34 +473,30 @@ else -- Exporters local has_exporters = (ifid_stats.type == "zmq") or (ifid_stats.type == "custom") or - (is_pro and - (table.len(flowDevices) > 0)) + (is_pro and (table.len(flowDevices) > 0)) page_utils.add_menubar_section({ section = page_utils.menu_sections.collection, - hidden = not has_exporters or not is_enterprise_M or - is_system_interface or infrastructure_view, - entries = { - { - entry = page_utils.menu_entries.sflow_exporters, - hidden = table.len(sFlowDevices) == 0, - url = '/lua/pro/enterprise/sflowdevices_stats.lua' - }, { - entry = page_utils.menu_entries.nprobe, - url = '/lua/pro/enterprise/nprobe.lua' - }, { - entry = page_utils.menu_entries.exporters_interfaces_stats, - url = '/lua/pro/exporters_interfaces_stats.lua' - }, { - entry = page_utils.menu_entries.observation_points, - hidden = (num_obs_points) == 0, - url = '/lua/pro/enterprise/observation_points.lua' - }, { - entry = page_utils.menu_entries.exporter_sites, - hidden = not is_pro, - url = '/lua/pro/enterprise/exporter_sites.lua' - } - } + hidden = not has_exporters or not is_enterprise_M or is_system_interface or infrastructure_view, + entries = {{ + entry = page_utils.menu_entries.sflow_exporters, + hidden = table.len(sFlowDevices) == 0, + url = '/lua/pro/enterprise/sflowdevices_stats.lua' + }, { + entry = page_utils.menu_entries.nprobe, + url = '/lua/pro/enterprise/nprobe.lua' + }, { + entry = page_utils.menu_entries.exporters_interfaces_stats, + url = '/lua/pro/exporters_interfaces_stats.lua' + }, { + entry = page_utils.menu_entries.observation_points, + hidden = (num_obs_points) == 0, + url = '/lua/pro/enterprise/observation_points.lua' + }, { + entry = page_utils.menu_entries.exporter_sites, + hidden = not is_pro, + url = '/lua/pro/enterprise/exporter_sites.lua' + }} }) end @@ -535,21 +512,19 @@ service_map_available, _ = behavior_utils.mapsAvailable() page_utils.add_menubar_section({ section = page_utils.menu_sections.maps, hidden = is_system_interface or is_viewed or infrastructure_view, - entries = { - { - entry = page_utils.menu_entries.analysis_map, - hidden = not service_map_available, - url = '/lua/pro/enterprise/network_maps.lua?map=service_map' - }, { - entry = page_utils.menu_entries.geo_map, - hidden = is_loopback_interface or not is_geoip_enabled, - url = '/lua/hosts_geomap.lua' - }, { - entry = page_utils.menu_entries.hosts_map, - hidden = not is_enterprise or is_asn_mode_enabled, - url = '/lua/pro/enterprise/hosts_map.lua' - } - } + entries = {{ + entry = page_utils.menu_entries.analysis_map, + hidden = not service_map_available, + url = '/lua/pro/enterprise/network_maps.lua?map=service_map' + }, { + entry = page_utils.menu_entries.geo_map, + hidden = is_loopback_interface or not is_geoip_enabled, + url = '/lua/hosts_geomap.lua' + }, { + entry = page_utils.menu_entries.hosts_map, + hidden = not is_enterprise or is_asn_mode_enabled, + url = '/lua/pro/enterprise/hosts_map.lua' + }} }) -- ############################################## @@ -558,65 +533,65 @@ page_utils.add_menubar_section({ page_utils.add_menubar_section({ hidden = is_system_interface or infrastructure_view, section = page_utils.menu_sections.if_stats, - entries = { - {entry = page_utils.menu_entries.interface, url = "/lua/if_stats.lua"}, - {entry = page_utils.menu_entries.divider}, { - entry = page_utils.menu_entries.networks, - hidden = is_viewed_interface, - url = '/lua/network_stats.lua' - }, { - entry = page_utils.menu_entries.host_pools, - hidden = is_nedge, - url = '/lua/pool_stats.lua' - }, { - entry = page_utils.menu_entries.autonomous_systems, - hidden = (not is_geoip_enabled) or is_viewed_interface, - url = '/lua/as_stats.lua' - }, { - entry = page_utils.menu_entries.countries, - hidden = not is_geoip_enabled or is_viewed_interface, - url = '/lua/country_stats.lua' - }, { - entry = page_utils.menu_entries.vlans, - hidden = not has_vlans or is_viewed_interface, - url = '/lua/vlan_stats.lua' - }, { - entry = page_utils.menu_entries.pods, - hidden = not ifid_stats.has_seen_pods, - url = '/lua/pods_stats.lua' - }, { - entry = page_utils.menu_entries.containers, - hidden = not ifid_stats.has_seen_containers, - url = '/lua/containers_stats.lua' - } - } + entries = {{ + entry = page_utils.menu_entries.interface, + url = "/lua/if_stats.lua" + }, { + entry = page_utils.menu_entries.divider + }, { + entry = page_utils.menu_entries.networks, + hidden = is_viewed_interface, + url = '/lua/network_stats.lua' + }, { + entry = page_utils.menu_entries.host_pools, + hidden = is_nedge, + url = '/lua/pool_stats.lua' + }, { + entry = page_utils.menu_entries.autonomous_systems, + hidden = (not is_geoip_enabled) or is_viewed_interface, + url = '/lua/as_stats.lua' + }, { + entry = page_utils.menu_entries.countries, + hidden = not is_geoip_enabled or is_viewed_interface, + url = '/lua/country_stats.lua' + }, { + entry = page_utils.menu_entries.vlans, + hidden = not has_vlans or is_viewed_interface, + url = '/lua/vlan_stats.lua' + }, { + entry = page_utils.menu_entries.pods, + hidden = not ifid_stats.has_seen_pods, + url = '/lua/pods_stats.lua' + }, { + entry = page_utils.menu_entries.containers, + hidden = not ifid_stats.has_seen_containers, + url = '/lua/containers_stats.lua' + }} }) -- ############################################## -- System Health -local health_entries = { - { - entry = page_utils.menu_entries.system_status, - url = '/lua/system_stats.lua' - }, { - entry = page_utils.menu_entries.interfaces_status, - url = '/lua/system_interfaces_stats.lua' - }, { - entry = page_utils.menu_entries.influxdb_status, - url = '/lua/monitor/influxdb_monitor.lua', - hidden = not is_influxdb_enabled - }, { - entry = page_utils.menu_entries.redis_status, - url = '/lua/monitor/redis_monitor.lua', - hidden = false -- TODO: add a check for redis monitoring status - }, { - entry = page_utils.menu_entries.clickhouse_status, - url = '/lua/pro/enterprise/monitor/clickhouse_monitor.lua', - hidden = not has_ch_support - } -} +local health_entries = {{ + entry = page_utils.menu_entries.system_status, + url = '/lua/system_stats.lua' +}, { + entry = page_utils.menu_entries.interfaces_status, + url = '/lua/system_interfaces_stats.lua' +}, { + entry = page_utils.menu_entries.influxdb_status, + url = '/lua/monitor/influxdb_monitor.lua', + hidden = not is_influxdb_enabled +}, { + entry = page_utils.menu_entries.redis_status, + url = '/lua/monitor/redis_monitor.lua', + hidden = false -- TODO: add a check for redis monitoring status +}, { + entry = page_utils.menu_entries.clickhouse_status, + url = '/lua/pro/enterprise/monitor/clickhouse_monitor.lua', + hidden = not has_ch_support +}} -- Add script entries relative to system health (e.g., redis) ... for k, entry in pairsByField(page_utils.scripts_menu, "sort_order", rev) do @@ -640,27 +615,25 @@ page_utils.add_menubar_section({ -- Pollers (e.g., SNMP, active monitoring) -- System interface menu -local poller_entries = { - {entry = page_utils.menu_entries.divider}, { - hidden = not asset_inventory_enabled, - entry = page_utils.menu_entries.assets_snmp, - url = '/lua/pro/assets.lua' - }, { - entry = page_utils.menu_entries.snmp, - hidden = not is_system_interface or - (not is_enterprise_M and not is_nedge_enterprise), - url = "/lua/pro/enterprise/snmpdevices_stats.lua" - }, { - entry = page_utils.menu_entries.active_monitoring, - hidden = not is_system_interface, - url = "/lua/active_monitoring.lua" - }, { - entry = page_utils.menu_entries.infrastructure_dashboard, - hidden = (not is_enterprise_L and not is_nedge_enterprise) or - not is_admin, - url = '/lua/pro/enterprise/infrastructure_config.lua' - } -} +local poller_entries = {{ + entry = page_utils.menu_entries.divider +}, { + hidden = not asset_inventory_enabled, + entry = page_utils.menu_entries.assets_snmp, + url = '/lua/pro/assets.lua' +}, { + entry = page_utils.menu_entries.snmp, + hidden = not is_system_interface or (not is_enterprise_M and not is_nedge_enterprise), + url = "/lua/pro/enterprise/snmpdevices_stats.lua" +}, { + entry = page_utils.menu_entries.active_monitoring, + hidden = not is_system_interface, + url = "/lua/active_monitoring.lua" +}, { + entry = page_utils.menu_entries.infrastructure_dashboard, + hidden = (not is_enterprise_L and not is_nedge_enterprise) or not is_admin, + url = '/lua/pro/enterprise/infrastructure_config.lua' +}} -- Add script entries relative to pollers (e.g., active monitoring) ... for k, entry in pairsByField(page_utils.scripts_menu, "sort_order", rev) do @@ -707,43 +680,43 @@ if is_nedge or is_appliance then end if is_nedge then - for _, entry in ipairs({ - { - entry = page_utils.menu_entries.system_setup, - hidden = not is_admin, - url = '/lua/system_setup_ui/interfaces.lua' - }, { - entry = page_utils.menu_entries.dhcp_static_leases, - hidden = not is_admin or not is_routing_mode, - url = '/lua/pro/nedge/admin/dhcp_leases.lua' - }, { - entry = page_utils.menu_entries.dhcp_active_leases, - hidden = not is_admin or not is_routing_mode, - url = '/lua/pro/nedge/admin/dhcp_active_leases.lua' - }, { - entry = page_utils.menu_entries.port_forwarding, - hidden = not is_admin or not is_routing_mode, - url = '/lua/pro/nedge/admin/port_forwarding.lua' - }, { - entry = page_utils.menu_entries.rules_config, - hidden = not is_admin or not is_routing_mode, - url = '/lua/pro/nedge/admin/rules_config.lua' - }, { - entry = page_utils.menu_entries.forwarders_config, - hidden = not is_admin or not is_routing_mode, - url = '/lua/pro/nedge/admin/forwarders_config.lua' - } - }) do system_entries[#system_entries + 1] = entry end + for _, entry in ipairs({{ + entry = page_utils.menu_entries.system_setup, + hidden = not is_admin, + url = '/lua/system_setup_ui/interfaces.lua' + }, { + entry = page_utils.menu_entries.dhcp_static_leases, + hidden = not is_admin or not is_routing_mode, + url = '/lua/pro/nedge/admin/dhcp_leases.lua' + }, { + entry = page_utils.menu_entries.dhcp_active_leases, + hidden = not is_admin or not is_routing_mode, + url = '/lua/pro/nedge/admin/dhcp_active_leases.lua' + }, { + entry = page_utils.menu_entries.port_forwarding, + hidden = not is_admin or not is_routing_mode, + url = '/lua/pro/nedge/admin/port_forwarding.lua' + }, { + entry = page_utils.menu_entries.rules_config, + hidden = not is_admin or not is_routing_mode, + url = '/lua/pro/nedge/admin/rules_config.lua' + }, { + entry = page_utils.menu_entries.forwarders_config, + hidden = not is_admin or not is_routing_mode, + url = '/lua/pro/nedge/admin/forwarders_config.lua' + }}) do + system_entries[#system_entries + 1] = entry + end end if is_appliance then - for _, entry in ipairs({ - { - entry = page_utils.menu_entries.system_setup, - hidden = not is_admin, - url = '/lua/system_setup_ui/mode.lua' - } - }) do system_entries[#system_entries + 1] = entry end + for _, entry in ipairs({{ + entry = page_utils.menu_entries.system_setup, + hidden = not is_admin, + url = '/lua/system_setup_ui/mode.lua' + }}) do + system_entries[#system_entries + 1] = entry + end end if #system_entries > 0 then @@ -761,17 +734,15 @@ end page_utils.add_menubar_section({ hidden = true, -- Always add the pools menu (moved to the Hosts submenu) section = page_utils.menu_sections.pools, - entries = { - { - entry = page_utils.menu_entries.manage_pools, - hidden = not is_admin, - url = '/lua/admin/manage_pools.lua' - }, { - entry = page_utils.menu_entries.host_members, - hidden = not is_admin, - url = '/lua/admin/manage_host_members.lua' - } - } + entries = {{ + entry = page_utils.menu_entries.manage_pools, + hidden = not is_admin, + url = '/lua/admin/manage_pools.lua' + }, { + entry = page_utils.menu_entries.host_members, + hidden = not is_admin, + url = '/lua/admin/manage_host_members.lua' + }} }) -- ############################################## @@ -789,94 +760,90 @@ page_utils.add_menubar_section({ page_utils.add_menubar_section({ section = page_utils.menu_sections.policies, hidden = infrastructure_view or not is_admin, - entries = { - { - entry = page_utils.menu_entries.access_control_list, - hidden = not is_admin or not is_enterprise_L or - is_asn_mode_enabled, - url = '/lua/pro/admin/access_control_list.lua' - }, { - entry = page_utils.menu_entries.device_protocols, - hidden = not is_admin or is_asn_mode_enabled, - url = '/lua/admin/edit_device_protocols.lua' - }, { - entry = page_utils.menu_entries.device_exclusions, - section = page_utils.menu_sections.hosts, - hidden = not is_admin or - not auth.has_capability(auth.capabilities.checks) or - not is_enterprise_M or not devices_exclusion_enabled, - url = '/lua/pro/admin/edit_device_exclusions.lua' - }, { - entry = page_utils.menu_entries.network_config, - section = page_utils.menu_sections.admin, - hidden = not is_admin or - not auth.has_capability(auth.capabilities.checks), - url = '/lua/admin/network_configuration.lua' - }, { - entry = page_utils.menu_entries.traffic_rules, - url = '/lua/pro/traffic_rules.lua', - hidden = not is_enterprise or not is_admin - }, {entry = page_utils.menu_entries.divider}, { - entry = page_utils.menu_entries.scripts_config, - section = page_utils.menu_sections.checks, - hidden = not is_admin or - not auth.has_capability(auth.capabilities.checks) or - (tonumber(system_ifid) == tonumber(current_ifid)), -- disable checks for the system interface - url = '/lua/admin/edit_configset.lua?subdir=all' - }, { - entry = page_utils.menu_entries.alert_exclusions, - section = page_utils.menu_sections.admin, - hidden = not is_admin or - not auth.has_capability(auth.capabilities.checks) or - not is_enterprise_M or - (tonumber(system_ifid) == tonumber(current_ifid)), - url = '/lua/pro/admin/edit_alert_exclusions.lua?subdir=host' - }, {entry = page_utils.menu_entries.divider}, { - entry = page_utils.menu_entries.profiles, - hidden = not is_admin or not is_pro or is_nedge or - is_asn_mode_enabled, - url = '/lua/pro/admin/edit_profiles.lua' - } - } + entries = {{ + entry = page_utils.menu_entries.access_control_list, + hidden = not is_admin or not is_enterprise_L or is_asn_mode_enabled, + url = '/lua/pro/admin/access_control_list.lua' + }, { + entry = page_utils.menu_entries.device_protocols, + hidden = not is_admin or is_asn_mode_enabled, + url = '/lua/admin/edit_device_protocols.lua' + }, { + entry = page_utils.menu_entries.device_exclusions, + section = page_utils.menu_sections.hosts, + hidden = not is_admin or not auth.has_capability(auth.capabilities.checks) or not is_enterprise_M or + not devices_exclusion_enabled, + url = '/lua/pro/admin/edit_device_exclusions.lua' + }, { + entry = page_utils.menu_entries.network_config, + section = page_utils.menu_sections.admin, + hidden = not is_admin or not auth.has_capability(auth.capabilities.checks), + url = '/lua/admin/network_configuration.lua' + }, { + entry = page_utils.menu_entries.traffic_rules, + url = '/lua/pro/traffic_rules.lua', + hidden = not is_enterprise or not is_admin + }, { + entry = page_utils.menu_entries.divider + }, { + entry = page_utils.menu_entries.scripts_config, + section = page_utils.menu_sections.checks, + hidden = not is_admin or not auth.has_capability(auth.capabilities.checks) or + (tonumber(system_ifid) == tonumber(current_ifid)), -- disable checks for the system interface + url = '/lua/admin/edit_configset.lua?subdir=all' + }, { + entry = page_utils.menu_entries.alert_exclusions, + section = page_utils.menu_sections.admin, + hidden = not is_admin or not auth.has_capability(auth.capabilities.checks) or not is_enterprise_M or + (tonumber(system_ifid) == tonumber(current_ifid)), + url = '/lua/pro/admin/edit_alert_exclusions.lua?subdir=host' + }, { + entry = page_utils.menu_entries.divider + }, { + entry = page_utils.menu_entries.profiles, + hidden = not is_admin or not is_pro or is_nedge or is_asn_mode_enabled, + url = '/lua/pro/admin/edit_profiles.lua' + }} }) page_utils.add_menubar_section({ section = page_utils.menu_sections.admin, hidden = not is_admin, - entries = { - { - entry = page_utils.menu_entries.nedge_users, - hidden = not is_admin or not is_nedge, - url = '/lua/pro/nedge/admin/nf_list_users.lua' - }, { - entry = page_utils.menu_entries.manage_users, - -- Note: 'not _SESSION["localuser"]' indicates that this is an external - -- user (e.g. LDAP), in that case allow users management if fallback is enabled. - hidden = not is_admin or - (not _SESSION["localuser"] and not has_local_auth), - url = '/lua/admin/users.lua' - }, { - entry = page_utils.menu_entries.preferences, - hidden = not is_admin, - url = '/lua/admin/prefs.lua' - }, { - hidden = not is_admin, - entry = page_utils.menu_entries.labels, - url = '/lua/labels.lua' - }, {entry = page_utils.menu_entries.divider}, { - entry = page_utils.menu_entries.category_lists, - hidden = not is_admin, - url = '/lua/admin/blacklists.lua?enabled_status=enabled' - }, { - entry = page_utils.menu_entries.manage_configurations, - hidden = not is_admin or not has_dump_cache, - url = '/lua/admin/manage_configurations.lua' - }, {entry = page_utils.menu_entries.divider}, { - entry = page_utils.menu_entries.categories, - hidden = not is_admin, - url = '/lua/admin/edit_categories.lua' - } - } + entries = {{ + entry = page_utils.menu_entries.nedge_users, + hidden = not is_admin or not is_nedge, + url = '/lua/pro/nedge/admin/nf_list_users.lua' + }, { + entry = page_utils.menu_entries.manage_users, + -- Note: 'not _SESSION["localuser"]' indicates that this is an external + -- user (e.g. LDAP), in that case allow users management if fallback is enabled. + hidden = not is_admin or (not _SESSION["localuser"] and not has_local_auth), + url = '/lua/admin/users.lua' + }, { + entry = page_utils.menu_entries.preferences, + hidden = not is_admin, + url = '/lua/admin/prefs.lua' + }, { + hidden = not is_admin, + entry = page_utils.menu_entries.labels, + url = '/lua/labels.lua' + }, { + entry = page_utils.menu_entries.divider + }, { + entry = page_utils.menu_entries.category_lists, + hidden = not is_admin, + url = '/lua/admin/blacklists.lua?enabled_status=enabled' + }, { + entry = page_utils.menu_entries.manage_configurations, + hidden = not is_admin or not has_dump_cache, + url = '/lua/admin/manage_configurations.lua' + }, { + entry = page_utils.menu_entries.divider + }, { + entry = page_utils.menu_entries.categories, + hidden = not is_admin, + url = '/lua/admin/edit_categories.lua' + }} }) -- ############################################## @@ -888,38 +855,32 @@ if not info.oem and auth.has_capability(auth.capabilities.developer) then if not is_enterprise_M or (has_developer_enabled) then page_utils.add_menubar_section({ section = page_utils.menu_sections.dev, - entries = { - { - entry = page_utils.menu_entries.rest_api, - url = '/lua/swagger.lua' - }, - { - entry = page_utils.menu_entries.analyze_pcap, - url = '/lua/upload_pcap.lua' - }, { - entry = page_utils.menu_entries.manage_data, - hidden = not is_admin, - url = '/lua/manage_data.lua' - }, - { - entry = page_utils.menu_entries.checks_dev, - url = '/lua/checks_overview.lua' - }, { - entry = page_utils.menu_entries.alert_definitions, - url = '/lua/defs_overview.lua' - }, - { - entry = page_utils.menu_entries.ts_definitions, - url = '/lua/ts_overview.lua' - }, - { - entry = page_utils.menu_entries.directories, - url = '/lua/directories.lua' - }, { - entry = page_utils.menu_entries.api, - url = 'https://www.ntop.org/guides/ntopng/api/' - } - } + entries = {{ + entry = page_utils.menu_entries.rest_api, + url = '/lua/swagger.lua' + }, { + entry = page_utils.menu_entries.analyze_pcap, + url = '/lua/upload_pcap.lua' + }, { + entry = page_utils.menu_entries.manage_data, + hidden = not is_admin, + url = '/lua/manage_data.lua' + }, { + entry = page_utils.menu_entries.checks_dev, + url = '/lua/checks_overview.lua' + }, { + entry = page_utils.menu_entries.alert_definitions, + url = '/lua/defs_overview.lua' + }, { + entry = page_utils.menu_entries.ts_definitions, + url = '/lua/ts_overview.lua' + }, { + entry = page_utils.menu_entries.directories, + url = '/lua/directories.lua' + }, { + entry = page_utils.menu_entries.api, + url = 'https://www.ntop.org/guides/ntopng/api/' + }} }) end end @@ -931,35 +892,35 @@ if not is_enterprise_M or has_help_enabled then page_utils.add_menubar_section({ section = page_utils.menu_sections.about, hidden = info.oem, - entries = { - {entry = page_utils.menu_entries.about, url = '/lua/about.lua'}, { - entry = page_utils.menu_entries.license, - hidden = info["pro.forced_community"] or (not is_admin), - url = '/lua/license.lua' - }, - { - entry = page_utils.menu_entries.limits, - hidden = (not is_admin), - url = '/lua/limits.lua' - }, - { - entry = page_utils.menu_entries.blog, - url = 'http://blog.ntop.org/' - }, - { - entry = page_utils.menu_entries.telegram, - url = 'https://t.me/ntop_community' - }, { - entry = page_utils.menu_entries.manual, - url = 'https://www.ntop.org/guides/ntopng/' - }, {entry = page_utils.menu_entries.divider}, { - entry = page_utils.menu_entries.report_issue, - url = 'https://github.com/ntop/ntopng/issues' - }, { - entry = page_utils.menu_entries.suggest_feature, - url = 'https://www.ntop.org/support/need-help-2/contact-us/' - } - } + entries = {{ + entry = page_utils.menu_entries.about, + url = '/lua/about.lua' + }, { + entry = page_utils.menu_entries.license, + hidden = info["pro.forced_community"] or (not is_admin), + url = '/lua/license.lua' + }, { + entry = page_utils.menu_entries.limits, + hidden = (not is_admin), + url = '/lua/limits.lua' + }, { + entry = page_utils.menu_entries.blog, + url = 'http://blog.ntop.org/' + }, { + entry = page_utils.menu_entries.telegram, + url = 'https://t.me/ntop_community' + }, { + entry = page_utils.menu_entries.manual, + url = 'https://www.ntop.org/guides/ntopng/' + }, { + entry = page_utils.menu_entries.divider + }, { + entry = page_utils.menu_entries.report_issue, + url = 'https://github.com/ntop/ntopng/issues' + }, { + entry = page_utils.menu_entries.suggest_feature, + url = 'https://www.ntop.org/support/need-help-2/contact-us/' + }} }) end @@ -1000,7 +961,7 @@ local action_urls = {} for v, k in pairs(iface_names) do interface.select(k) - + local ifid_stats = interface.getStats() local is_pcap_dump = interface.isPcapDumpInterface() local is_sub_interface = interface.isSubInterface() @@ -1008,23 +969,30 @@ for v, k in pairs(iface_names) do local is_zmq_interface = interface.isZMQInterface() ifnames[ifid_stats.id] = k - action_urls[ifid_stats.id] = page_utils.switch_interface_form_action_url(ifId, - ifid_stats.id, - ifid_stats.type) + action_urls[ifid_stats.id] = page_utils.switch_interface_form_action_url(ifId, ifid_stats.id, ifid_stats.type) - if is_pcap_dump then pcapdump[ifid_stats.id] = true end - if (ifid_stats.isView == true) then views[ifid_stats.id] = true end - if (is_sub_interface) then dynamic[ifid_stats.id] = true end + if is_pcap_dump then + pcapdump[ifid_stats.id] = true + end + if (ifid_stats.isView == true) then + views[ifid_stats.id] = true + end + if (is_sub_interface) then + dynamic[ifid_stats.id] = true + end if (recording_utils.isEnabled(ifid_stats.id)) then recording[ifid_stats.id] = true end if (is_packet_interface) then packetinterfaces[ifid_stats.id] = true end - if (is_zmq_interface) then zmqinterfaces[ifid_stats.id] = true end - - if (ifid_stats.stats_since_reset.drops * 100 > - ifid_stats.stats_since_reset.packets) then drops[ifid_stats.id] = true end + if (is_zmq_interface) then + zmqinterfaces[ifid_stats.id] = true + end + + if (ifid_stats.stats_since_reset.drops * 100 > ifid_stats.stats_since_reset.packets) then + drops[ifid_stats.id] = true + end ifCustom[ifid_stats.id] = ifid_stats.customIftype @@ -1032,15 +1000,13 @@ for v, k in pairs(iface_names) do -- Note: Ensure is_windows and is_enterprise_M are defined globally -- or check them here using ntop.isWindows(), etc. - if ntop.isWindows() and string.contains(descr, "{") then + if ntop.isWindows() and string.contains(descr, "{") then descr = ifid_stats.description - elseif ntop.isEnterpriseM() and is_sub_interface and - ifid_stats.dynamic_interface_probe_ip then + elseif ntop.isEnterpriseM() and is_sub_interface and ifid_stats.dynamic_interface_probe_ip then -- Attempt at printing SNMP information rather than plain disaggregated IPs local snmp_utils = require "snmp_utils" local snmp_cached_dev = require "snmp_cached_dev" - local cached_device = snmp_cached_dev:create( - ifid_stats.dynamic_interface_probe_ip) + local cached_device = snmp_cached_dev:create(ifid_stats.dynamic_interface_probe_ip) local snmp_name, snmp_if_name if cached_device then @@ -1051,12 +1017,9 @@ for v, k in pairs(iface_names) do -- Now check for the existance of the interface name if ifid_stats.dynamic_interface_inifidx then if cached_device.interfaces and - cached_device.interfaces[tostring( - ifid_stats.dynamic_interface_inifidx)] then + cached_device.interfaces[tostring(ifid_stats.dynamic_interface_inifidx)] then snmp_if_name = snmp_utils.get_snmp_interface_label( - cached_device.interfaces[tostring( - ifid_stats.dynamic_interface_inifidx)], - true) + cached_device.interfaces[tostring(ifid_stats.dynamic_interface_inifidx)], true) else snmp_if_name = ifid_stats.dynamic_interface_inifidx end @@ -1105,10 +1068,8 @@ end -- The observationPoint menu is displayed only for the flow page if (table.len(observationPoints) > 0) and - ((page_utils.get_active_section() == "flows" and - page_utils.get_active_entry() == "active_flows") or - ((page_utils.get_active_section() == "hosts") and - (string.contains(_SERVER.QUERY_STRING, "page=flows")))) then + ((page_utils.get_active_section() == "flows" and page_utils.get_active_entry() == "active_flows") or + ((page_utils.get_active_section() == "hosts") and (string.contains(_SERVER.QUERY_STRING, "page=flows")))) then observationPointId = ntop.getUserObservationPointId() if ((observationPointId == 0) and (_GET["observationPointId"] ~= 0)) then observationPointId = _GET["observationPointId"] @@ -1158,8 +1119,7 @@ end -- License Badge local info = ntop.getInfo(true) -if (_POST["ntopng_license"] == nil) and - (info["pro.systemid"] and (info["pro.systemid"] ~= "")) then +if (_POST["ntopng_license"] == nil) and (info["pro.systemid"] and (info["pro.systemid"] ~= "")) then if (info["pro.release"]) then @@ -1168,11 +1128,10 @@ if (_POST["ntopng_license"] == nil) and local rest = info["pro.demo_ends_at"] - os.time() if (rest > 0) then - print( - '') end end @@ -1181,8 +1140,7 @@ if (_POST["ntopng_license"] == nil) and if (not (info["pro.forced_community"])) then print( '') end end @@ -1217,7 +1175,10 @@ if not infrastructure_view then ifid = current_ifid }) print("") end @@ -1228,7 +1189,9 @@ end if (not info.oem) then local username = _SESSION["user"] or '' - if (is_no_login_user) then username = 'no_login' end + if (is_no_login_user) then + username = 'no_login' + end local posts, new_posts_counter = blog_utils.readPostsFromRedis(username) template_utils.render("pages/components/blog-dropdown.template", { @@ -1238,7 +1201,6 @@ if (not info.oem) then }) end - print([[
  • + ]] - print(i18n("manage_users.manage_user_x", {user = _SESSION["user"]})) + print(i18n("manage_users.manage_user_x", { + user = _SESSION["user"] + })) print [[
  • @@ -1259,10 +1225,8 @@ if (not _SESSION["localuser"] or not is_admin) and (not is_no_login_user) then else if (not is_no_login_user) then - print([[
  • ]] .. session_user .. + print([[
  • ]] .. session_user .. [[
  • ]]) else print([[ - +
  • ]] .. i18n("nedge.power_off") .. [[ @@ -1295,8 +1260,7 @@ end if hasSoftwareUpdatesSupport() then print([[
  • - +
  • ]] .. (i18n("updates.check")) .. [[
  • ]]) @@ -1307,13 +1271,14 @@ end local theme_selector = ntop.getPref("ntopng.user." .. session_user .. ".theme") local theme_selected = i18n("toggle_dark_theme") -if (theme_selector == 'dark') then theme_selected = i18n("toggle_white_theme") end +if (theme_selector == 'dark') then + theme_selected = i18n("toggle_white_theme") +end print([[
  • - ]] .. - theme_selected .. [[ + ]] .. theme_selected .. [[
  • ]]) diff --git a/scripts/lua/looking_glass.lua b/scripts/lua/looking_glass.lua new file mode 100644 index 0000000000..42942cf72e --- /dev/null +++ b/scripts/lua/looking_glass.lua @@ -0,0 +1,36 @@ +-- +-- (C) 2013-26 - ntop.org +-- +local dirs = ntop.getDirs() +package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path + +require "lua_utils" + +local page_utils = require "page_utils" +local json = require "dkjson" +local template_utils = require "template_utils" + +local info = ntop.getInfo() + +sendHTTPContentTypeHeader('text/html') + +page_utils.print_header_and_set_active_menu_entry(page_utils.menu_entries.looking_glass) + +dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua") + +page_utils.print_navbar(i18n('looking_glass'), ntop.getHttpPrefix() .. "/lua/looking_glass.lua", {{ + hidden = false, + active = true, + page_name = "overview", + label = "" +}}) + +local context = {} +local json_context = json.encode(context) + +template_utils.render("pages/vue_page.template", { + vue_page_name = "PageLookingGlass", + page_context = json_context +}) + +dofile(dirs.installdir .. "/scripts/lua/inc/footer.lua") diff --git a/scripts/lua/modules/bgp_utils.lua b/scripts/lua/modules/bgp_utils.lua new file mode 100644 index 0000000000..a225bb7afc --- /dev/null +++ b/scripts/lua/modules/bgp_utils.lua @@ -0,0 +1,120 @@ +-- +-- (C) 2013-26 - ntop.org +-- +local dirs = ntop.getDirs() +package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path + +require "ntop_utils" +require "lua_utils_gui" + +-- ###################################### + +local bgp_utils = {} + +-- ###################################### + +function bgp_utils.formatBgpBmpInfo(bgp_info) + local rsp = {} + for prefix, peers in pairs(bgp_info or {}) do + local peer_list = {} + local peer_id = {} + local asn_list = {} + local bgp_origin = {} + local bgp_next_hop = {} + local as_path = {} + local communities = {} + local med_list = {} + local local_pref_list = {} + for bgp_id, info in pairs(peers) do + peer_list[#peer_list + 1] = { + id = bgp_id, + info = info + } + end + local max_len = (#peer_list > 2) and 8 or 32 + for _, peer in ipairs(peer_list) do + peer_id[#peer_id + 1] = { + name = formatNextHop(peer.id) + } + asn_list[#asn_list + 1] = { + name = string.format("%s (%s)", peer.info.asn, ntop.getASNameFromASN(tonumber(peer.info.asn))), + url = string.format("%s/lua/hosts_stats.lua?asn=%s", ntop.getHttpPrefix(), peer.info.asn) + } + bgp_origin[#bgp_origin + 1] = { + name = string.upper(peer.info["origin"] or "") + } + bgp_next_hop[#bgp_next_hop + 1] = { + name = peer.info["next_hop"] or "" + } + med_list[#med_list + 1] = { + name = ((peer.info["med"] ~= nil) and tostring(peer.info["med"]) or "") + } + local_pref_list[#local_pref_list + 1] = { + name = ((peer.info["local_pref"] ~= nil) and tostring(peer.info["local_pref"]) or "") + } + + -- Formatting AS Path list + if peer.info["as_path"] and #peer.info["as_path"] > 0 then + local parts = {} + for _, asn in ipairs(peer.info["as_path"]) do + as_path[#as_path + 1] = { + name = string.format("%d (%s)", tonumber(asn), ntop.getASNameFromASN(tonumber(asn))), + url = string.format("%s/lua/hosts_stats.lua?asn=%s", ntop.getHttpPrefix(), asn) + } + end + end + + -- Formatting Communities list + if peer.info["communities"] and #peer.info["communities"] > 0 then + for _, c in ipairs(peer.info["communities"]) do + communities[#communities + 1] = { + name = c + } + end + end + end + rsp[#rsp + 1] = { + name = "bgp_prefix", + value = prefix + } + rsp[#rsp + 1] = { + name = "bgp_peer_id", + value = peer_id + } + rsp[#rsp + 1] = { + name = "bgp_peer_asn", + value = asn_list + } + rsp[#rsp + 1] = { + name = "bgp_origin", + value = bgp_origin + } + rsp[#rsp + 1] = { + name = "bgp_next_hop", + value = bgp_next_hop + } + rsp[#rsp + 1] = { + name = "bgp_as_path", + value = as_path + } + if not ((#bgp_info == 1) and (#peer_list > 0)) then + rsp[#rsp + 1] = { + name = "bgp_med", + value = med_list + } + rsp[#rsp + 1] = { + name = "bgp_local_pref", + value = local_pref_list + } + rsp[#rsp + 1] = { + name = "bgp_communities", + value = communities + } + end + end + return rsp +end + +-- ###################################### + +return bgp_utils diff --git a/scripts/lua/modules/page_utils.lua b/scripts/lua/modules/page_utils.lua index f2a1b76431..5584fd6255 100644 --- a/scripts/lua/modules/page_utils.lua +++ b/scripts/lua/modules/page_utils.lua @@ -282,6 +282,12 @@ page_utils.menu_entries = { section = "flows", help_link = "https://www.ntop.org/guides/ntopng/user_interface/network_interface/flows/server_ports.html" }, + looking_glass = { + key = "looking_glass", + i18n_title = "looking_glass", + section = "flows", + help_link = "https://www.ntop.org/guides/ntopng/user_interface/network_interface/flows/server_ports.html" + }, -- Hosts hosts = { diff --git a/scripts/lua/rest/v2/get/flow/bgp/general_stats.lua b/scripts/lua/rest/v2/get/flow/bgp/general_stats.lua index 2316b087e9..e43500aad2 100644 --- a/scripts/lua/rest/v2/get/flow/bgp/general_stats.lua +++ b/scripts/lua/rest/v2/get/flow/bgp/general_stats.lua @@ -7,6 +7,7 @@ package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path require "http_lint" require "lua_utils_gui" local json = require "dkjson" +local bgp_utils = require "bgp_utils" local rest_utils = require "rest_utils" -- ################################################ @@ -24,6 +25,8 @@ if not isEmptyString(ifid) then interface.select(ifid) end +-- ################################################ + local flow = nil if flow_hash_id and flow_key then @@ -37,118 +40,18 @@ elseif row_id and instance_name and tstamp and ntop.isEnterpriseL() --[[ Require flow = historical_flow_utils.convertToLiveFlowFormat(flow) end -local function formatBgpBmpInfo(bgp_info) - local rsp = {} - for prefix, peers in pairs(bgp_info or {}) do - local peer_list = {} - local peer_id = {} - local asn_list = {} - local bgp_origin = {} - local bgp_next_hop = {} - local as_path = {} - local communities = {} - local med_list = {} - local local_pref_list = {} - for bgp_id, info in pairs(peers) do - peer_list[#peer_list + 1] = { - id = bgp_id, - info = info - } - end - local max_len = (#peer_list > 2) and 8 or 32 - for _, peer in ipairs(peer_list) do - peer_id[#peer_id + 1] = { - name = formatNextHop(peer.id) - } - asn_list[#asn_list + 1] = { - name = string.format("%s (%s)", peer.info.asn, ntop.getASNameFromASN(tonumber(peer.info.asn))), - url = string.format("%s/lua/hosts_stats.lua?asn=%s", ntop.getHttpPrefix(), peer.info.asn) - } - bgp_origin[#bgp_origin + 1] = { - name = string.upper(peer.info["origin"] or "") - } - bgp_next_hop[#bgp_next_hop + 1] = { - name = peer.info["next_hop"] or "" - } - med_list[#med_list + 1] = { - name = ((peer.info["med"] ~= nil) and tostring(peer.info["med"]) or "") - } - local_pref_list[#local_pref_list + 1] = { - name = ((peer.info["local_pref"] ~= nil) and tostring(peer.info["local_pref"]) or "") - } - - -- Formatting AS Path list - if peer.info["as_path"] and #peer.info["as_path"] > 0 then - local parts = {} - for _, asn in ipairs(peer.info["as_path"]) do - as_path[#as_path + 1] = { - name = string.format("%d (%s)", tonumber(asn), ntop.getASNameFromASN(tonumber(asn))), - url = string.format("%s/lua/hosts_stats.lua?asn=%s", ntop.getHttpPrefix(), asn) - } - end - end - - -- Formatting Communities list - if peer.info["communities"] and #peer.info["communities"] > 0 then - for _, c in ipairs(peer.info["communities"]) do - communities[#communities + 1] = { - name = c - } - end - end - end - rsp[#rsp + 1] = { - name = "bgp_prefix", - value = prefix - } - rsp[#rsp + 1] = { - name = "bgp_peer_id", - value = peer_id - } - rsp[#rsp + 1] = { - name = "bgp_peer_asn", - value = asn_list - } - rsp[#rsp + 1] = { - name = "bgp_origin", - value = bgp_origin - } - rsp[#rsp + 1] = { - name = "bgp_next_hop", - value = bgp_next_hop - } - rsp[#rsp + 1] = { - name = "bgp_as_path", - value = as_path - } - if not ((#bgp_info == 1) and (#peer_list > 0)) then - rsp[#rsp + 1] = { - name = "bgp_med", - value = med_list - } - rsp[#rsp + 1] = { - name = "bgp_local_pref", - value = local_pref_list - } - rsp[#rsp + 1] = { - name = "bgp_communities", - value = communities - } - end - end - return rsp -end +-- ################################################ if (flow) and (flow.bgp) then local client_info = {} local server_info = {} if (flow.bgp.src) then local bgp_info = json.decode(flow.bgp.src) - client_info = formatBgpBmpInfo(bgp_info) + client_info = bgp_utils.formatBgpBmpInfo(bgp_info) end if (flow.bgp.dst) then local bgp_info = json.decode(flow.bgp.dst) - server_info = formatBgpBmpInfo(bgp_info) + server_info = bgp_utils.formatBgpBmpInfo(bgp_info) end rsp = { client_info = client_info, @@ -156,4 +59,6 @@ if (flow) and (flow.bgp) then } end +-- ################################################ + rest_utils.answer(rest_utils.consts.success.ok, rsp) diff --git a/scripts/lua/rest/v2/get/flow/bgp/looking_glass.lua b/scripts/lua/rest/v2/get/flow/bgp/looking_glass.lua new file mode 100644 index 0000000000..3eae8222b4 --- /dev/null +++ b/scripts/lua/rest/v2/get/flow/bgp/looking_glass.lua @@ -0,0 +1,37 @@ +-- +-- (C) 2013-26 - ntop.org +-- +local dirs = ntop.getDirs() +package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path + +require "http_lint" +local json = require "dkjson" +local bgp_utils = require "bgp_utils" +local rest_utils = require "rest_utils" + +-- ################################################ + +local rsp = {} +local host_to_find = _GET["host"] + +--[[ +if isEmptyString(host_to_find) then + rest_utils.answer(rest_utils.consts.err.bad_format) + return +end +]] +-- ################################################ + +--local rib = ntop.ribFind(host_to_find) +-- DEBUG +local rib = '{"1.1.1.0\\24": {"212.74.82.15": {"asn":8220,"origin":"igp","as_path": [8220,13335],"next_hop":"87.241.16.133","med":0,"local_pref":200,"communities": ["8220:65000","8220:65060","8220:65401"]},"185.54.80.4": {"asn":202032,"origin":"igp","as_path": [13335],"next_hop":"185.54.80.4","local_pref":305,"communities": ["20203:2004"]},"185.54.80.3": {"asn":202032,"origin":"igp","as_path": [13335],"next_hop":"185.54.80.3","local_pref":305,"communities": ["20203:2003"]},"38.28.1.11": {"asn":174,"origin":"igp","as_path": [174,13335],"next_hop":"149.11.89.168","med":0,"local_pref":200,"communities": ["174:21101","174:22004"]},"193.221.216.30": {"asn":5398,"origin":"igp","as_path": [5398,13335],"next_hop":"77.220.74.109","local_pref":200,"communities": ["5398:12051"]}}}' +--rib = json.encode(rib) +if not isEmptyString(rib) then + rib = json.decode(rib) + tprint(rib) + rsp = bgp_utils.formatBgpBmpInfo(rib) +end + +-- ################################################ + +rest_utils.answer(rest_utils.consts.success.ok, rsp) \ No newline at end of file