Merge branch 'main' into new-admin

This commit is contained in:
baldo 2022-08-25 23:08:58 +02:00
commit 8cf692b523
2 changed files with 126 additions and 102 deletions

View file

@ -8,7 +8,6 @@ import {
hasOwnProperty, hasOwnProperty,
isLayerConfig, isLayerConfig,
isPlainObject, isPlainObject,
isString,
Url, Url,
Version, Version,
} from "./types"; } from "./types";

View file

@ -32,20 +32,16 @@ import {
isUndefined, isUndefined,
JSONValue, JSONValue,
MAC, MAC,
MailId,
MailType, MailType,
MapId,
mapIdFromMAC, mapIdFromMAC,
MonitoringSortField, MonitoringSortField,
MonitoringState, MonitoringState,
MonitoringToken, MonitoringToken,
NodeId,
NodeMonitoringStateResponse, NodeMonitoringStateResponse,
NodeStateData, NodeStateData,
NodeStateId, NodeStateId,
OnlineState, OnlineState,
parseJSON, parseJSON,
RunResult,
Site, Site,
StoredNode, StoredNode,
toCreateOrUpdateNode, toCreateOrUpdateNode,
@ -144,7 +140,7 @@ async function insertNodeInformation(
async function updateNodeInformation( async function updateNodeInformation(
nodeData: ParsedNode, nodeData: ParsedNode,
node: StoredNode, node: StoredNode,
row: any row: NodeStateRow
): Promise<void> { ): Promise<void> {
Logger.tag("monitoring", "informacallbacktion-retrieval").debug( Logger.tag("monitoring", "informacallbacktion-retrieval").debug(
"Node is known in monitoring: %s", "Node is known in monitoring: %s",
@ -201,9 +197,10 @@ async function storeNodeInformation(
nodeData.mac nodeData.mac
); );
const row = await db.get("SELECT * FROM node_state WHERE mac = ?", [ const row = await db.get<NodeStateRow>(
node.mac, "SELECT * FROM node_state WHERE mac = ?",
]); [node.mac]
);
if (isUndefined(row)) { if (isUndefined(row)) {
return await insertNodeInformation(nodeData, node); return await insertNodeInformation(nodeData, node);
@ -365,8 +362,8 @@ export function parseNodesJson(body: string): NodesParsingResult {
async function updateSkippedNode( async function updateSkippedNode(
id: NodeStateId, id: NodeStateId,
node?: StoredNode node?: StoredNode
): Promise<RunResult> { ): Promise<void> {
return await db.run( await db.run(
"UPDATE node_state " + "UPDATE node_state " +
"SET hostname = ?, monitoring_state = ?, modified_at = ?" + "SET hostname = ?, monitoring_state = ?, modified_at = ?" +
"WHERE id = ?", "WHERE id = ?",
@ -384,98 +381,126 @@ async function sendMonitoringMailsBatched(
name name
); );
while (true) { let nodeStates = await findBatchFun();
Logger.tag("monitoring", "mail-sending").debug("Sending next batch..."); while (nodeStates.length > 0) {
await sendMonitoringMailsBatch(name, mailType, nodeStates);
const nodeStates = await findBatchFun(); nodeStates = await findBatchFun();
if (_.isEmpty(nodeStates)) {
Logger.tag("monitoring", "mail-sending").debug(
'Done sending "%s" mails.',
name
);
return;
}
for (const nodeState of nodeStates) {
const mac = nodeState.mac;
Logger.tag("monitoring", "mail-sending").debug(
"Loading node data for: %s",
mac
);
const result = await NodeService.findNodeDataWithSecretsByMac(mac);
if (!result) {
Logger.tag("monitoring", "mail-sending").debug(
'Node not found. Skipping sending of "' +
name +
'" mail: ' +
mac
);
await updateSkippedNode(nodeState.id);
continue;
}
const { node, nodeSecrets } = result;
if (node.monitoringState !== MonitoringState.ACTIVE) {
Logger.tag("monitoring", "mail-sending").debug(
'Monitoring disabled, skipping "%s" mail for: %s',
name,
mac
);
await updateSkippedNode(nodeState.id, node);
continue;
}
const monitoringToken = nodeSecrets.monitoringToken;
if (!monitoringToken) {
Logger.tag("monitoring", "mail-sending").error(
'Node has no monitoring token. Cannot send mail "%s" for: %s',
name,
mac
);
await updateSkippedNode(nodeState.id, node);
continue;
}
Logger.tag("monitoring", "mail-sending").info(
'Sending "%s" mail for: %s',
name,
mac
);
await MailService.enqueue(
config.server.email.from,
node.nickname + " <" + node.email + ">",
mailType,
{
node: filterUndefinedFromJSON(node),
lastSeen: nodeState.last_seen,
disableUrl: monitoringDisableUrl(monitoringToken),
}
);
Logger.tag("monitoring", "mail-sending").debug(
"Updating node state: ",
mac
);
const timestamp = now();
await db.run(
"UPDATE node_state " +
"SET hostname = ?, monitoring_state = ?, modified_at = ?, last_status_mail_sent = ?, last_status_mail_type = ?" +
"WHERE id = ?",
[
node.hostname,
node.monitoringState,
timestamp,
timestamp,
mailType,
nodeState.id,
]
);
}
} }
Logger.tag("monitoring", "mail-sending").debug(
'Done sending "%s" mails.',
name
);
}
async function sendMonitoringMailsBatch(
name: string,
mailType: MailType,
nodeStates: NodeStateRow[]
) {
Logger.tag("monitoring", "mail-sending").debug("Sending next batch...");
for (const nodeState of nodeStates) {
await sendMonitoringMail(name, mailType, nodeState);
}
}
async function sendMonitoringMail(
name: string,
mailType: MailType,
nodeState: NodeStateRow
) {
const mac = nodeState.mac;
Logger.tag("monitoring", "mail-sending").debug(
"Loading node data for: %s",
mac
);
const result = await NodeService.findNodeDataWithSecretsByMac(mac);
if (!result) {
Logger.tag("monitoring", "mail-sending").debug(
`Node not found. Skipping sending of "${name}" mail: ${mac}`
);
await updateSkippedNode(nodeState.id);
return;
}
const { node, nodeSecrets } = result;
if (node.monitoringState !== MonitoringState.ACTIVE) {
Logger.tag("monitoring", "mail-sending").debug(
'Monitoring disabled, skipping "%s" mail for: %s',
name,
mac
);
await updateSkippedNode(nodeState.id, node);
return;
}
const monitoringToken = nodeSecrets.monitoringToken;
if (!monitoringToken) {
Logger.tag("monitoring", "mail-sending").error(
'Node has no monitoring token. Cannot send mail "%s" for: %s',
name,
mac
);
await updateSkippedNode(nodeState.id, node);
return;
}
await enqueMail(name, mailType, node, nodeState, monitoringToken);
await updateNodeForSentEmail(mailType, node, nodeState);
}
async function enqueMail(
name: string,
mailType: MailType,
node: StoredNode,
nodeState: NodeStateRow,
monitoringToken: MonitoringToken
) {
Logger.tag("monitoring", "mail-sending").info(
'Sending "%s" mail for: %s',
name,
node.mac
);
await MailService.enqueue(
config.server.email.from,
node.nickname + " <" + node.email + ">",
mailType,
{
node: filterUndefinedFromJSON(node),
lastSeen: nodeState.last_seen,
disableUrl: monitoringDisableUrl(monitoringToken),
}
);
}
async function updateNodeForSentEmail(
mailType: MailType,
node: StoredNode,
nodeState: NodeStateRow
) {
Logger.tag("monitoring", "mail-sending").debug(
"Updating node state: ",
node.mac
);
const timestamp = now();
await db.run(
"UPDATE node_state " +
"SET hostname = ?, monitoring_state = ?, modified_at = ?, last_status_mail_sent = ?, last_status_mail_type = ?" +
"WHERE id = ?",
[
node.hostname,
node.monitoringState,
timestamp,
timestamp,
mailType,
nodeState.id,
]
);
} }
async function sendOnlineAgainMails( async function sendOnlineAgainMails(