Skip to content

Commit

Permalink
Merge branch 'dev' of https://github.com/ntop/ntopng into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
MatteoBiscosi committed Sep 4, 2024
2 parents 3fbc7e5 + 658887a commit d3da78e
Show file tree
Hide file tree
Showing 8 changed files with 280 additions and 5 deletions.
2 changes: 2 additions & 0 deletions http_src/vue/ntop_vue.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import { default as PageProbes } from "./page-probes.vue"
import { default as PageExporters } from "./page-exporters.vue"
import { default as PageExportersDetails } from "./page-exporters-details.vue"
import { default as PageExportersInterfaces } from "./page-exporters-interfaces.vue"
import { default as PageNetworkConfiguration } from "./page-network-configuration.vue"

/* Config pages */
import { default as PageSNMPConfig } from "./page-snmp-config.vue"
Expand Down Expand Up @@ -190,6 +191,7 @@ let ntopVue = {
PageFlowDeviceInterfaceDetails: PageFlowDeviceInterfaceDetails,
PageHistoricalFlow: PageHistoricalFlow,
PageExportersInterfaces: PageExportersInterfaces,
PageNetworkConfiguration: PageNetworkConfiguration,
//PageSankeyTest: PageSankeyTest,

// components
Expand Down
153 changes: 153 additions & 0 deletions http_src/vue/page-network-configuration.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<template>
<div class="container mt-4">
<div v-for="(value, key) in check_name" :key="key" class="mb-4">
<div class="mb-2">
<strong>{{ _i18n(value.i18n_title) }}</strong>
</div>
<div>
<textarea v-model="ipAddresses[key]" class="form-control rounded"
:placeholder="`Enter ${value.device_type} IPs (Comma Separated)`" @input="markAsModified(key)"
rows="3"></textarea>
<div v-if="validationErrors[key]" class="text-danger mt-1">
{{ validationErrors[key] }}
</div>
</div>
</div>
<div class="d-flex justify-content-end mt-4">
<button @click="saveConfig" :class="saveButtonClass" :disabled="isSaving"> {{ saveButtonText }}
</button>
</div>
</div>
</template>

<script setup>
import { ref, reactive, onMounted, computed } from 'vue'
import { ntopng_utility } from "../services/context/ntopng_globals_services.js";
import regexValidation from "../utilities/regex-validation.js";
const _i18n = (t) => i18n(t);
const props = defineProps({
context: Object
});
const ipAddresses = reactive({});
const validationErrors = reactive({});
const set_config_url = `${http_prefix}/lua/rest/v2/set/network/config.lua`
const get_config_url = `${http_prefix}/lua/rest/v2/get/network/config.lua?ifid=${props.context.ifid}`
const modifiedInputs = ref([]);
const isSaving = ref(false);
const saveSuccess = ref(false);
const saveButtonText = computed(() => {
if (isSaving.value) return 'Saving...';
if (saveSuccess.value) return 'Saved!';
return _i18n("flow_checks.save_configuration");
});
const saveButtonClass = computed(() => {
if (saveSuccess.value) return 'btn btn-success';
return 'btn btn-primary';
});
const check_name = {
"dns_list": { "i18n_title": "flow_checks.dns_servers_title", "device_type": "DNS Server", "reques_param": "dns_list" },
"ntp_list": { "i18n_title": "flow_checks.ntp_servers_title", "device_type": "NTP Server", "reques_param": "ntp_list" },
"dhcp_list": { "i18n_title": "flow_checks.dhcp_servers_title", "device_type": "DHCP Server", "reques_param": "dhcp_list" },
"smtp_list": { "i18n_title": "flow_checks.smtp_servers_title", "device_type": "SMTP Server", "reques_param": "smtp_list" },
"gateway": { "i18n_title": "flow_checks.gateway", "device_type": "Gateway", "reques_param": "gateway" },
}
Object.keys(check_name).forEach(key => {
ipAddresses[key] = '';
});
onMounted(() => {
getConfig();
});
// Function used to populate text area with data received from the backend at page initialization
const getConfig = async () => {
const data = await ntopng_utility.http_request(get_config_url)
data.forEach(item => {
const key = Object.keys(check_name).find(k => k === item.key);
if (key && item.is_enabled === true) {
ipAddresses[key] = Array.isArray(item.value_description)
? item.value_description.join(', ')
: item.value_description;
}
})
};
// Used to mark a text area as modified so that only modified text areas are sent to the backend to be stored in redis
const markAsModified = (key) => {
if (!modifiedInputs.value.includes(key)) {
modifiedInputs.value.push(key);
}
};
// Function to validate IP addresses inserted in text area
const validateIpAddresses = () => {
let isValid = true;
Object.keys(ipAddresses).forEach(key => {
const ips = ipAddresses[key].split(',').map(ip => ip.trim()).filter(ip => ip !== '');
if (ips.length === 0) {
validationErrors[key] = '';
} else if (!ips.every(regexValidation.validateIP)) {
validationErrors[key] = 'Invalid IP address format';
isValid = false;
} else {
validationErrors[key] = '';
}
});
return isValid;
};
// Function used to post data to the backend and save the values in
const saveConfig = async () => {
if (validateIpAddresses()) {
isSaving.value = true;
let data = { csrf: props.context.csrf, config: []};
let headers = {
'Content-Type': 'application/json'
};
try {
for (const key of modifiedInputs.value) {
const value = ipAddresses[key];
const ips = value.split(',').map(ip => ip.trim());
let requestData = {
asset_key: check_name[key].reques_param,
item: ips
};
data.config.push(requestData)
}
console.log(data)
//await ntopng_utility.http_post_request(set_config_url, data);
await ntopng_utility.http_request(set_config_url, { method: 'post', headers, body: JSON.stringify(data) })
modifiedInputs.value = [];
// Show success when saved
saveSuccess.value = true;
setTimeout(() => {
saveSuccess.value = false;
}, 1500);
} catch (error) {
console.error('Save failed:', error);
} finally {
isSaving.value = false;
}
}
};
</script>
7 changes: 7 additions & 0 deletions scripts/locales/en.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1653,6 +1653,7 @@ local lang = {
},
},
["checks"] = {
["network_configuration"] = "Network Configuration",
["categories"] = "Categories",
["category"] = "Category",
["category_active_monitoring"] = "Active Monitoring",
Expand Down Expand Up @@ -2850,6 +2851,12 @@ local lang = {
["visual_explorer"] = "Visual Explorer",
},
["flow_checks"] = {
["dns_servers_title"] = "DNS Servers List",
["ntp_servers_title"] = "NTP Servers List",
["smtp_servers_title"] = "SMTP Servers List",
["dhcp_servers_title"] = "DHCP Servers List",
["save_configuration"] = "Save Configuration",
["gateway"] = "Gateway",
["allowed_server_names_description"] = "Comma separated values of allowed server IPs. Example: 173.194.76.109,my.example.com",
["allowed_servers_description"] = "Comma separated values of allowed server IPs. Example: 173.194.76.109,52.97.232.242",
["allowed_servers_title"] = "Allowed Servers",
Expand Down
44 changes: 44 additions & 0 deletions scripts/lua/admin/network_configuration.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
--
-- (C) 2020 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path

require "lua_utils"
require "ntop_utils"

local page_utils = require "page_utils"
local json = require "dkjson"
local template_utils = require("template_utils")
local ifid = interface.getId()

sendHTTPContentTypeHeader('text/html')

page_utils.print_header_and_set_active_menu_entry(page_utils.menu_entries.network_config)

dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua")

local ifstats = interface.getStats()
local probes = ifstats.probes

page_utils.print_navbar(i18n("checks.network_configuration"), ntop.getHttpPrefix() .. "/lua/admin/network_configuration.lua", {{
url = ntop.getHttpPrefix() .. "/lua/admin/network_configuration.lua",
active = true,
page_name = "assets_inventory",
label = "<i class=\"fas fa-lg fa-home\" data-bs-toggle=\"tooltip\" data-bs-placement=\"top\" title=\"" ..
i18n("checks.network_configuration") .. "\"></i>"
}})

local context = {
ifid = interface.getId(),
csrf = ntop.getRandomCSRFValue()
}

local json_context = json.encode(context)

template_utils.render("pages/vue_page.template", {
vue_page_name = "PageNetworkConfiguration",
page_context = json_context
})

dofile(dirs.installdir .. "/scripts/lua/inc/footer.lua")
10 changes: 5 additions & 5 deletions scripts/lua/modules/http_lint.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1968,14 +1968,17 @@ local known_parameters = {
["flow_hash_id"] = validateNumber, -- The ID uniquely identifying the flow in the hash table
["user"] = validateSingleWord, -- The user ID
["snapshot_name"] = validateSingleWord, -- The user ID
["command"] = validateSingleWord, -- The user ID
["report_name"] = validateSingleWord, -- The report name
["report_template"] = validateSingleWord, -- The report template
["report_title"] = validateSingleWord, -- The report title (used in vs reports)
["pool"] = validateNumber, -- A pool ID
["pool_id"] = validateNumber, -- A pool ID
["direction"] = validateDirection, -- Sent or Received direction
["download"] = validateBool,
["item"] = validateSingleWord, -- Used by the Import/Export page to select the item to import/export
["item"] = validateJSON, -- Used by the Import/Export page to select the item to import/export
["config"] = validateUnquoted, -- Used by the Import/Export page to select the item to import/export
["asset_key"] = validateSingleWord, -- Used by network configuration
["stats_type"] = validateStatsType, -- A mode for historical stats queries
["alertstats_type"] = validateAlertStatsType, -- A mode for alerts stats queries
["flowhosts_type"] = validateFlowHostsTypeOrIpVersionOrIp, -- A filter for local/remote hosts in each of the two directions
Expand Down Expand Up @@ -2826,7 +2829,6 @@ local function validateParameter(k, v)
if (type(v) == "table") then
for table_key, table_value in pairs(v) do
local success, message, purified = validateParameter(table_key, table_value)

-- Stop, if any of the table value fails the validation against
-- the expected table key
if not success then
Expand Down Expand Up @@ -2924,10 +2926,9 @@ local function lintParams()

-- Extend the parameters with validators from the scripts
local additional_params = script_manager.extendLintParams(http_lint, known_parameters)

for _, id in pairs(params_to_validate) do
for k, v in pairs(id) do
if (debug) then
if (false) then
io.write("[LINT] Validating [" .. k .. "]\n")
end

Expand All @@ -2938,7 +2939,6 @@ local function lintParams()
end
else
local success, message, purified = validateSpecialParameter(k, v)

if success then
id[k] = purified
else
Expand Down
1 change: 1 addition & 0 deletions scripts/lua/modules/page_utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ page_utils.menu_entries = {
nedge_users = {key = "nedge_users", i18n_title = "manage_users.manage_users", section = "admin", help_link = "https://www.ntop.org/guides/nedge/users.html#"},
manage_users = {key = "manage_users", i18n_title = ternary(is_nedge, "nedge.system_users", "manage_users.manage_users"), section = "admin", help_link = "https://www.ntop.org/guides/ntopng/web_gui/settings.html#manage-users"},
preferences = {key = "preferences", i18n_title = "prefs.preferences", section = "admin", help_link = "https://www.ntop.org/guides/ntopng/web_gui/settings.html#preferences"},
network_config = {key = "network_config", i18n_title = "checks.network_configuration", section = "admin"},
scripts_config = {key = "scripts_config", i18n_title = "about.checks", section = "admin", help_link = "https://www.ntop.org/guides/ntopng/web_gui/checks.html"},
scripts_config_all = {key = "scripts_config", subkey="all", i18n_title = "all", section = "admin", help_link = "https://www.ntop.org/guides/ntopng/web_gui/checks.html"},
scripts_config_hosts = {key = "scripts_config", subkey="hosts", i18n_title = alert_entities.host.i18n_label, section = "admin", help_link = "https://www.ntop.org/guides/ntopng/web_gui/checks.html"},
Expand Down
27 changes: 27 additions & 0 deletions scripts/lua/rest/v2/get/network/config.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

--
-- (C) 2021 - ntop.org
--

local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path

require "lua_utils"
local rest_utils = require "rest_utils"
local json = require "dkjson"

local ifid = tonumber(_GET["ifid"])


local res = {}

-- Get data from redis: expected format, array of objects with keys:
res = {{key= "unexpected_dhcp", value_description="192.168.2.85, 192.168.2.45" or "", is_enabled=true or false}}


if isEmptyString(ifid) then
rest_utils.answer(rest_utils.consts.err.invalid_interface)
return
end

rest_utils.answer(rest_utils.consts.success.ok, res)
41 changes: 41 additions & 0 deletions scripts/lua/rest/v2/set/network/config.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

--
-- (C) 2021 - ntop.org
--

local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path

require "lua_utils"
local rest_utils = require "rest_utils"
local json = require "dkjson"

local action = _GET["action"]
local post_data = _POST["payload"]

local res = {}

local config = _POST["config"]
tprint(_POST)

local data = json.decode(config)

-- data is:
--[[
asset_key = [ "gateway", "unexpected_dhcp", "unexpected_dns", "unexpected_ntp", "unexpected_smtp"]
{ "csrf":..., "config": [ {"asset_key": asset_key, "item": [ip1, ip2, ip3...]}, {"asset_key": asset_key_1, "item": [ip1, ip2, ip3...]}]}
]]

-- local script_key = post_data["asset_key"] -- asset_key
-- local redis_key = "ntopng.prefs." .. script_key .. "_ip_list"

-- for each element in respone: ntop.getCache(redis_key)

if isEmptyString(ifid) then
rest_utils.answer(rest_utils.consts.err.invalid_interface)
return
end


rest_utils.answer(rest_utils.consts.success.ok, res)

0 comments on commit d3da78e

Please sign in to comment.