ntopng/scripts/lua/modules/conf_handlers/netplan.lua
2021-01-02 12:08:23 +01:00

189 lines
5.4 KiB
Lua

--
-- (C) 2013-21 - ntop.org
--
local sys_utils = require("sys_utils")
local ipv4_utils = require("ipv4_utils")
local config = {}
-- ################################################################
local NEDGE_NETPLAN_CONF = "20-nedge.yaml"
local CLOUD_DIRECTORY = "/etc/cloud/cloud.cfg.d"
local CLOUD_DISABLED_FNAME = "99-disable-network-config.cfg"
local start_ethernet_section = true
function config.writeNetworkInterfaceConfig(f, iface, network_conf, dns_config, bridge_ifaces)
if iface == "lo" then
-- nothing to do for loopback interface
return
end
local vlan_raw_iface = nil
local vlan_id = nil
if string.contains(iface, "%.") then
local parts = string.split(iface, "%.")
vlan_raw_iface = parts[1]
vlan_id = parts[2]
end
if bridge_ifaces ~= nil then
f:write(" bridges:\n")
elseif string.find(iface, ":") then
-- This is an alias
local base_iface = split(iface, ":")[1]
if starts(iface, "br") then
-- bridge iface
f:write(" bridges:\n")
else
f:write(" ethernets:\n")
end
iface = base_iface
elseif start_ethernet_section then
f:write(" ethernets:\n")
start_ethernet_section = false
end
if vlan_raw_iface then
-- inside ethernet section, write the raw device
f:write(" ".. vlan_raw_iface ..":\n")
f:write(" addresses: []\n")
-- start a vlan section
f:write(" vlans:\n")
end
f:write(" ".. iface ..":\n")
if network_conf.mode == "static" then
cidr = ipv4_utils.netmask(network_conf.netmask)
f:write(" addresses: [" .. network_conf.ip .."/".. cidr .."]\n")
if not isEmptyString(network_conf.gateway) then
f:write(" gateway4: " .. network_conf.gateway .. "\n")
f:write(" nameservers:\n")
f:write(" addresses: [" .. table.concat({dns_config.global, dns_config.secondary}, ", ") .. "]\n")
end
elseif (network_conf.mode == "dhcp") then
f:write(" addresses: []\n")
f:write(" dhcp4: true\n")
else
-- e.g. vlan-trunk
f:write(" addresses: []\n")
end
if vlan_raw_iface then
f:write(" accept-ra: no\n")
f:write(" id: " .. vlan_id .. "\n")
f:write(" link: " .. vlan_raw_iface .. "\n")
-- end VLAN section and start again the ethernet section
start_ethernet_section = true
elseif bridge_ifaces ~= nil then
f:write(" interfaces: [".. table.concat(bridge_ifaces, ", ") .."]\n")
f:write(" parameters:\n")
f:write(" stp: false\n")
f:write(" forward-delay: 0\n")
end
end
-- ################################################################
function config.openNetworkInterfacesConfigFile()
local f = sys_utils.openFile("/etc/netplan/" .. NEDGE_NETPLAN_CONF, "w")
f:write("network:\n version: 2\n")
start_ethernet_section = true
return f
end
-- ################################################################
function config.closeNetworkInterfacesConfigFile(f)
f:close()
sys_utils.execShellCmd("netplan generate")
end
-- ################################################################
function config.backupNetworkInterfacesFiles(to_backup)
for fname in pairs(to_backup) do
local source = fname
local destination = source .. ".old"
os.rename(source, destination)
traceError(TRACE_WARNING, TRACE_CONSOLE, source .. " has been moved to " .. destination)
end
local cloud_disabled_path = CLOUD_DIRECTORY .. "/" .. CLOUD_DISABLED_FNAME
if ntop.isdir(CLOUD_DIRECTORY) and not ntop.exists(cloud_disabled_path) then
-- disable cloud to prevent future modifications
local f = sys_utils.openFile(cloud_disabled_path, "w")
if f ~= nil then
f:write("network: {config: disabled}\n")
f:close()
end
end
end
-- ################################################################
-- returns true if the interface is already configured in a file which is not managed by nedge
-- In such case, it also returns the list of files which use the interface
function config.isConfiguredInterface(iface)
local files_to_rename = {}
for fname in pairs(ntop.readdir("/etc/netplan")) do
if fname ~= NEDGE_NETPLAN_CONF then
local fpath = "/etc/netplan/".. fname
-- e.g.: "renderer: NetworkManager", "iface: enp1s0"
local res = sys_utils.execCmd("grep \"^\\s*[^#]*\\(" .. iface .. "\\|renderer\\):\" ".. fpath .." >/dev/null 2>/dev/null")
if not isEmptyString(res) then
files_to_rename[fpath] = 1
end
end
end
return not table.empty(files_to_rename), files_to_rename
end
-- ################################################################
function config.dhcpInterfaceGetGateway(iface)
-- it says "do not parse", but there is no script to get this info
local dirs = ntop.readdir("/var/run/systemd/netif/leases/") or {}
for ifid in pairs(dirs) do
local name_line = sys_utils.execShellCmd('grep "NETWORK_FILE=" /run/systemd/netif/links/'.. ifid)
if not isEmptyString(name_line) then
local parts = split(name_line, "-")
local name = split(parts[#parts], ".network")[1]
if name == iface then
local gw = sys_utils.execShellCmd('grep "ROUTER=" /var/run/systemd/netif/leases/' .. ifid .. ' | cut -f2 -d=')
if not isEmptyString(gw) then
gw = split(gw, "\n")[1]
if isIPv4(gw) then
return gw
end
end
end
end
end
return nil
end
-- ################################################################
return config