From 5e8aa45d56c73096b4b3583c88194ac84438610e Mon Sep 17 00:00:00 2001 From: onefang Date: Wed, 6 Nov 2019 01:37:56 +1000 Subject: Add the email report. --- apt-panopticon-report-email.lua | 186 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100755 apt-panopticon-report-email.lua diff --git a/apt-panopticon-report-email.lua b/apt-panopticon-report-email.lua new file mode 100755 index 0000000..2f7c8d1 --- /dev/null +++ b/apt-panopticon-report-email.lua @@ -0,0 +1,186 @@ +#!/usr/bin/env luajit + +local args = {...} + +verbosity = -1 +local logFile + + +--[[ Ordered table iterator, allow to iterate on the natural order of the keys of a table. + From http://lua-users.org/wiki/SortedIteration + ]] +function __genOrderedIndex( t ) + local orderedIndex = {} + for key in pairs(t) do + table.insert( orderedIndex, key ) + end + table.sort( orderedIndex ) + return orderedIndex +end +function orderedNext(t, state) + -- Equivalent of the next function, but returns the keys in the alphabetic + -- order. We use a temporary ordered key table that is stored in the + -- table being iterated. + + local key = nil + --print("orderedNext: state = "..tostring(state) ) + if state == nil then + -- the first time, generate the index + t.__orderedIndex = __genOrderedIndex( t ) + key = t.__orderedIndex[1] + else + -- fetch the next value + for i = 1,table.getn(t.__orderedIndex) do + if t.__orderedIndex[i] == state then + key = t.__orderedIndex[i+1] + end + end + end + + if key then + return key, t[key] + end + + -- no more value to return, cleanup + t.__orderedIndex = nil + return +end +function orderedPairs(t) + -- Equivalent of the pairs() function on tables. Allows to iterate + -- in order + return orderedNext, t, nil +end + + +local results = {} + +local log = function(v, t, s, prot, test, host) + local x = "" + if nil == prot then prot = "" end + if nil ~= test then x = x .. test else test = "" end + if nil ~= host then + if #x > 0 then x = x .. " " end + x = x .. host + end + if #x > 0 then + t = t .. "(" .. x .. ")" + end + if v <= verbosity then + if 3 <= verbosity then t = os.date() .. " " .. t end + print(t .. ": " .. s) + end + if nil ~= logFile then + logFile:write(os.date() .. " " .. t .. ": " .. s .. "\n") + logFile:flush() + end +end +local D = function(s) log(3, "DEBUG ", s) end +local I = function(s) log(2, "INFO ", s) end +local W = function(s, p, t, h) log(1, "WARNING ", s, p, t, h) end +local E = function(s, p, t, h) log(0, "ERROR ", s, p, t, h) end +local C = function(s) log(-1, "CRITICAL", s) end + +local faulty = "" +local status = function(host, results, typ) + local result = "" + local e = results[typ].errors + local w = results[typ].warnings + for i, u in pairs(results[typ]) do + if "table" == type(u) then + e = e + u.errors + w = w + u.warnings + end + end + + if 0 < e then result = e .. " errors" end + if 1 == e then result = e .. " error" end + if 0 < w then + if 0 < e then result = result .. ", " end + if 1 == w then + result = result .. w .. " warning" + else + result = result .. w .. " warnings" + end + end + if "[OK]" ~= result then + if 0 < e then + result = "[FAILED] (" .. result .. ")" + faulty = faulty .. host .. " (" .. typ .. ")\n" + elseif 0 < w then + result = "[OK] (" .. result .. ")" + else + result = "[OK]" + end + end + return result +end + +local collate = function(host, ip, results) + local f = "results/" .. host .. "_" .. ip .. ".lua" + local rfile, e = io.open(f, "r") + if nil == rfile then C("opening " .. f .. " file - " .. e) else + rfile:close() + local rs = loadfile(f)() + for k, v in pairs(rs) do + if "table" == type(v) then + for i, u in pairs(v) do + if "table" == type(u) then + for h, t in pairs(u) do + local a = results[k][h] + if nil == a then a = 0 end + results[k][h] = a + t + end + else + local a = results[k][i] + if nil == a then a = 0 end + results[k][i] = a + u + end + end + else + local a = results[k] + if nil == a then a = 0 end + results[k] = a + v + end + end + end + return results +end + + +local mirrors = loadfile("results/mirrors.lua")() + +local file, e = io.open("results/Report-email.txt", "w+") +if nil == file then C("opening mirrors file - " .. e) else + file:write( "Dear Mirror Admins,\n\n" .. + "The full list of Devuan package mirrors is available at the URL:\n\n" .. + " https://pkgmaster.devuan.org/mirror_list.txt\n\n" .. + 'Please contact "mirrors@devuan.org" if any of the information \nin the file above needs to be amended. \n\n' .. + "Please see below the current status of the Devuan Package Mirror \nnetwork:\n\n" .. + "---- BEGIN MIRROR-STATUS ----\n") + for k, v in orderedPairs(mirrors) do + local results = loadfile("results/" .. k .. ".lua")() + file:write(k .. "....\n") + local IPs = v.IPs + for i, u in pairs(IPs) do + if "table" == type(u) then + for h, t in pairs(u) do + results = collate(k, h, results) + end + else + results = collate(k, i, results) + end + end + local http = status(k, results, "http") + local https = status(k, results, "https") + local dns = "[skip]" + local updated = "[skip]" + local integrity = "[skip]" + file:write(" http: " .. http .. " https: " .. https .. " DNS-RR: " .. dns .. " Updated: " .. updated .. " Integrity: " .. integrity .. "\n") + end + file:write( "==== faulty mirrors: ====\n\n" .. faulty) + file:write( "---- END MIRROR-STATUS ----\n\n" .. + "Thanks for your precious help in ensuring that Devuan GNU+Linux \nremains a universal, stable, dependable, free operating system.\n\n" .. + "Love\n\n" .. + "The Dev1Devs\n\n") + file:close() +end -- cgit v1.1