Generate detailed mail configuration error notification
This commit is contained in:
@@ -29,6 +29,8 @@ exports = module.exports = {
|
||||
injectPrivateFields: injectPrivateFields,
|
||||
removePrivateFields: removePrivateFields,
|
||||
|
||||
checkConfiguration: checkConfiguration,
|
||||
|
||||
SECRET_PLACEHOLDER: String.fromCharCode(0x25CF).repeat(8),
|
||||
|
||||
// for testing
|
||||
@@ -1256,3 +1258,20 @@ function startCleanupTask(auditSource, callback) {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function checkConfiguration(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
settings.getBackupConfig(function (error, backupConfig) {
|
||||
if (error) return callback(error);
|
||||
|
||||
let message = '';
|
||||
if (backupConfig.provider === 'noop') {
|
||||
message = 'Cloudron backups are disabled. Please ensure this server is backed up using alternate means. See https://cloudron.io/documentation/backups/#storage-providers for more information.';
|
||||
} else if (backupConfig.provider === 'filesystem' && !backupConfig.externalDisk) {
|
||||
message = 'Cloudron backups are currently on the same disk as the Cloudron server instance. This is dangerous and can lead to complete data loss if the disk fails. See https://cloudron.io/documentation/backups/#storage-providers for storing backups in an external location.';
|
||||
}
|
||||
|
||||
callback(null, message);
|
||||
});
|
||||
}
|
||||
|
||||
+7
-29
@@ -27,6 +27,7 @@ exports = module.exports = {
|
||||
|
||||
var assert = require('assert'),
|
||||
async = require('async'),
|
||||
backups = require('./backups.js'),
|
||||
clients = require('./clients.js'),
|
||||
config = require('./config.js'),
|
||||
constants = require('./constants.js'),
|
||||
@@ -194,8 +195,8 @@ function runSystemChecks() {
|
||||
checkDiskSpace,
|
||||
checkMailStatus,
|
||||
checkRebootRequired
|
||||
], function () {
|
||||
debug('runSystemChecks: done');
|
||||
], function (error) {
|
||||
debug('runSystemChecks: done', error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -204,15 +205,8 @@ function checkBackupConfiguration(callback) {
|
||||
|
||||
debug('Checking backup configuration');
|
||||
|
||||
settings.getBackupConfig(function (error, backupConfig) {
|
||||
if (error) return console.error(error);
|
||||
|
||||
let message = '';
|
||||
if (backupConfig.provider === 'noop') {
|
||||
message = 'Cloudron backups are disabled. Please ensure this server is backed up using alternate means. See https://cloudron.io/documentation/backups/#storage-providers for more information.';
|
||||
} else if (backupConfig.provider === 'filesystem' && !backupConfig.externalDisk) {
|
||||
message = 'Cloudron backups are currently on the same disk as the Cloudron server instance. This is dangerous and can lead to complete data loss if the disk fails. See https://cloudron.io/documentation/backups/#storage-providers for storing backups in an external location.';
|
||||
}
|
||||
backups.checkConfiguration(function (error, message) {
|
||||
if (error) return callback(error);
|
||||
|
||||
notifications.alert(notifications.ALERT_BACKUP_CONFIG, message, callback);
|
||||
});
|
||||
@@ -262,26 +256,10 @@ function checkMailStatus(callback) {
|
||||
|
||||
debug('checking mail status');
|
||||
|
||||
domains.getAll(function (error, allDomains) {
|
||||
mail.checkConfiguration(function (error, message) {
|
||||
if (error) return callback(error);
|
||||
|
||||
async.filterSeries(allDomains, function (domainObject, iteratorCallback) {
|
||||
mail.getStatus(config.adminDomain(), function (error, result) {
|
||||
if (error) return iteratorCallback(null, true);
|
||||
|
||||
let mailError = Object.keys(result.dns).some((record) => !result.dns[record].status);
|
||||
if (result.relay && !result.relay.status) mailError = true;
|
||||
if (result.rbl && result.rbl.status === false) mailError = true; // rbl is an optional check
|
||||
|
||||
iteratorCallback(null, mailError);
|
||||
});
|
||||
}, function (error, erroredDomainObjects) {
|
||||
if (error || erroredDomainObjects.length === 0) return callback(error);
|
||||
|
||||
const erroredDomains = erroredDomainObjects.map((d) => d.domain);
|
||||
debug(`checkMailStatus: ${erroredDomains.join(',')} failed status checks`);
|
||||
notifications.alert(notifications.ALERT_MAIL_STATUS, erroredDomains.length ? `Email status check of the following domain(s) failed - ${erroredDomains.join(',')}. See the Status tab in the [Email view](/#/email/) for more information.` : '', callback);
|
||||
});
|
||||
notifications.alert(notifications.ALERT_MAIL_STATUS, message, callback);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+48
-3
@@ -2,6 +2,7 @@
|
||||
|
||||
exports = module.exports = {
|
||||
getStatus: getStatus,
|
||||
checkConfiguration: checkConfiguration,
|
||||
|
||||
getDomains: getDomains,
|
||||
|
||||
@@ -455,9 +456,9 @@ function getStatus(domain, callback) {
|
||||
|
||||
// ensure we always have a valid toplevel properties for the api
|
||||
var results = {
|
||||
dns: {},
|
||||
rbl: {},
|
||||
relay: {}
|
||||
dns: {}, // { mx: { expected, value }, dmarc: { expected, value }, dkim: { expected, value }, spf: { expected, value }, ptr: { expected, value } }
|
||||
rbl: {}, // { status, ip, servers: [{name,site,dns}]}
|
||||
relay: {} // { status, value }
|
||||
};
|
||||
|
||||
function recordResult(what, func) {
|
||||
@@ -504,6 +505,50 @@ function getStatus(domain, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function checkConfiguration(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
let messages = {};
|
||||
|
||||
domains.getAll(function (error, allDomains) {
|
||||
if (error) return callback(error);
|
||||
|
||||
async.eachSeries(allDomains, function (domainObject, iteratorCallback) {
|
||||
getStatus(domainObject.domain, function (error, result) {
|
||||
if (error) return iteratorCallback(error);
|
||||
|
||||
let message = [];
|
||||
|
||||
Object.keys(result.dns).forEach((type) => {
|
||||
const record = result.dns[type];
|
||||
if (!record.status) message.push(`${type.toUpperCase()} DNS record did not match. Expected: \`${record.expected}\`. Actual: \`${record.value}\``);
|
||||
});
|
||||
if (result.relay && !result.relay.status) message.push(`Relay error: ${result.relay.value}`);
|
||||
if (result.rbl && result.rbl.status === false) { // rbl field contents is optional
|
||||
const servers = result.rbl.servers.map((bs) => `[${bs.name}](${bs.site})`); // in markdown
|
||||
message.push(`This server's IP \`${result.rbl.ip}\` is blacklisted in the following servers - ${servers.join(', ')}`);
|
||||
}
|
||||
|
||||
if (message.length) messages[domainObject.domain] = message;
|
||||
|
||||
iteratorCallback(null);
|
||||
});
|
||||
}, function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
// create bulleted list for each domain
|
||||
let markdownMessage = '';
|
||||
Object.keys(messages).forEach((domain) => {
|
||||
markdownMessage += `**${domain}**\n`;
|
||||
markdownMessage += messages[domain].map((m) => `* ${m}\n`).join('');
|
||||
markdownMessage += '\n\n';
|
||||
});
|
||||
|
||||
callback(null, markdownMessage);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function createMailConfig(mailFqdn, callback) {
|
||||
assert.strictEqual(typeof mailFqdn, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
Reference in New Issue
Block a user