-- -- (C) 2019-21 - ntop.org -- local dirs = ntop.getDirs() package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path require "lua_utils" local host_pools_utils = require "host_pools_utils" local discover = require "discover_utils" local template = require "template_utils" local graph_utils = require "graph_utils" local page_utils = require "page_utils" sendHTTPContentTypeHeader('text/html') if not isAdministratorOrPrintErr() then return end page_utils.set_active_menu_entry(page_utils.menu_entries.pools_host) -- append the menu above the page dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua") page_utils.print_page_title(i18n("host_pools.host_pools")) -- ************************************* ------ local pool_add_warnings = {} if _POST["edit_pools"] ~= nil then local config = paramsPairsDecode(_POST, true) for pool_id, pool_name in pairs(config) do -- Filter pool ids only if tonumber(pool_id) ~= nil then host_pools_utils.createPool(pool_id, pool_name, nil --[[ children_safe ]], nil --[[ enforce_quotas_per_pool_member ]], nil --[[ enforce_shapers_per_pool_member ]], true --[[ create or rename ]]) end end -- Reload is required here to load the new metadata ntop.reloadHostPools() elseif _POST["pool_to_delete"] ~= nil then local pool_id = _POST["pool_to_delete"] host_pools_utils.deletePool(pool_id) -- Note: this will also reload the shaping rules ntop.reloadHostPools() elseif (_POST["edit_members"] ~= nil) then local pool_to_edit = _POST["pool"] local config = paramsPairsDecode(_POST, true) local sanitized = {} -- Sanitize parameters for new_member, value in pairs(config) do if not isValidPoolMember(new_member) then http_lint.validationError(_POST, "new_member", new_member, "Invalid pool member") end local parts = split(value, "|") if #parts ~= 3 then http_lint.validationError(_POST, "member_values", parts, "Invalid member values") end local assembled = { old_member = parts[1], alias = parts[2], icon = parts[3], } -- Convention: use uppercase letters for mac, lowercase for ip if isMacAddress(new_member) then new_member = string.upper(new_member) else new_member = string.lower(new_member) end if (not isEmptyString(old_member)) and (not isValidPoolMember(assembled.old_member)) then http_lint.validationError(_POST, "old_member", new_member, "Invalid pool member") end if not http_lint.validateUnchecked(assembled.alias) then http_lint.validationError(_POST, "alias", assembled.alias, "Invalid member alias") end if not http_lint.validateSingleWord(assembled.icon) then http_lint.validationError(_POST, "icon", assembled.icon, "Invalid member icon") end local hostinfo = hostkey2hostinfo(new_member) local network, prefix = splitNetworkPrefix(hostinfo.host) local already_added = false if prefix ~= nil then local masked = ntop.networkPrefix(network, prefix) if masked ~= network then -- Normalize new networks (extract their prefix) local new_key = host2member(masked, hostinfo.vlan, prefix) pool_add_warnings[#pool_add_warnings + 1] = i18n("host_pools.network_normalized", { network = hostinfo2hostkey(hostkey2hostinfo(new_member)), network_normalized = hostinfo2hostkey(hostkey2hostinfo(new_key)) }) sanitized[new_key] = assembled already_added = true end end if not already_added then sanitized[new_member] = assembled end end config = sanitized -- This code handles member address changes -- delete old addresses for k,value in pairs(table.clone(config) --[[ Work on a copy to modify the original while iterating ]]) do local old_member = value.old_member if((not isEmptyString(old_member)) and (k ~= old_member)) then if config[old_member] then -- Do not delete and re-add members which have only changed their list key config[old_member].old_member = old_member else host_pools_utils.deletePoolMember(pool_to_edit, old_member) end end end -- add new addresses for new_member,value in pairs(config) do local k = value.old_member local is_new_member = (k ~= new_member) if is_new_member then local res, info = host_pools_utils.addPoolMember(pool_to_edit, new_member) if (res == false) and (info.existing_member_pool ~= nil) then -- remove @0 local member_to_print = hostinfo2hostkey(hostkey2hostinfo(new_member)) pool_add_warnings[#pool_add_warnings + 1] = i18n("host_pools.member_exists", { member_name = member_to_print, member_pool = host_pools_utils.getPoolName(info.existing_member_pool) }) end end local host_key, is_network = host_pools_utils.getMemberKey(new_member) if not is_network then local alias = value.alias local skip_alias = false if isMacAddress(new_member) then local manuf = ntop.getMacManufacturer(new_member) if (manuf ~= nil) and (manuf.extended == alias) then -- this is not the alias, it is the manufacturer skip_alias = true end end if(((not is_new_member) or (not isEmptyString(alias))) and (not skip_alias)) then setHostAltName(host_key, alias) end local icon = tonumber(value.icon) if (not isEmptyString(icon)) and ((not is_new_member) or (icon ~= 0)) and isMacAddress(new_member) and new_member ~= "00:00:00:00:00:00" then setCustomDeviceType(new_member, icon) ntop.setMacDeviceType(new_member, icon, true --[[ overwrite ]]) end end end ntop.reloadHostPools() elseif _POST["member_to_delete"] ~= nil then local pool_to_edit = _POST["pool"] host_pools_utils.deletePoolMember(pool_to_edit, _POST["member_to_delete"]) ntop.reloadHostPools() elseif _POST["empty_pool"] ~= nil then host_pools_utils.emptyPool(_POST["empty_pool"]) ntop.reloadHostPools() elseif (_POST["member"] ~= nil) and (_POST["pool"] ~= nil) then -- change member pool host_pools_utils.changeMemberPool(_POST["member"], _POST["pool"], nil, true --[[do not consider host MAC]]) ntop.reloadHostPools() end function printPoolNameField(pool_id_str) print[[