Added WebDAV auto-backup support

This commit is contained in:
Ylian Saint-Hilaire 2020-09-10 12:43:48 -07:00
parent 45fe8e30dd
commit 4a3e56e0c2
5 changed files with 172 additions and 67 deletions

73
db.js
View File

@ -1412,7 +1412,77 @@ module.exports.CreateDB = function (parent, func) {
// Perform cloud backup
obj.performCloudBackup = function (filename, func) {
if (typeof parent.config.settings.autobackup.googledrive != 'object') return;
// WebDAV Backup
if ((typeof parent.config.settings.autobackup == 'object') && (typeof parent.config.settings.autobackup.webdav == 'object')) {
const xdateTimeSort = function (a, b) { if (a.xdate > b.xdate) return 1; if (a.xdate < b.xdate) return -1; return 0; }
// Fetch the folder name
var webdavfolderName = 'MeshCentral-Backups';
if (typeof parent.config.settings.autobackup.webdav.foldername == 'string') { webdavfolderName = parent.config.settings.autobackup.webdav.foldername; }
// Clean up our WebDAV folder
function performWebDavCleanup(client) {
if ((typeof parent.config.settings.autobackup.webdav.maxfiles == 'number') && (parent.config.settings.autobackup.webdav.maxfiles > 1)) {
var directoryItems = client.getDirectoryContents(webdavfolderName);
directoryItems.then(
function (files) {
for (var i in files) { files[i].xdate = new Date(files[i].lastmod); }
files.sort(xdateTimeSort);
while (files.length >= parent.config.settings.autobackup.webdav.maxfiles) {
client.deleteFile(files.shift().filename).then(function (state) {
if (func) { func('WebDAV file deleted.'); }
}).catch(function (err) {
if (func) { func('WebDAV (deleteFile) error: ' + err); }
});
}
}
).catch(function (err) {
if (func) { func('WebDAV (getDirectoryContents) error: ' + err); }
});
}
}
// Upload to the WebDAV folder
function performWebDavUpload(client, filepath) {
var fileStream = require('fs').createReadStream(filepath);
fileStream.on('close', function () { if (func) { func('WebDAV upload completed'); } })
fileStream.on('error', function (err) { if (func) { func('WebDAV (fileUpload) error: ' + err); } })
fileStream.pipe(client.createWriteStream('/' + webdavfolderName + '/' + require('path').basename(filepath)));
if (func) { func('Uploading using WebDAV...'); }
}
if (func) { func('Attempting WebDAV upload...'); }
const { createClient } = require('webdav');
const client = createClient(parent.config.settings.autobackup.webdav.url, { username: parent.config.settings.autobackup.webdav.username, password: parent.config.settings.autobackup.webdav.password });
var directoryItems = client.getDirectoryContents('/');
directoryItems.then(
function (files) {
var folderFound = false;
for (var i in files) { if ((files[i].basename == webdavfolderName) && (files[i].type == 'directory')) { folderFound = true; } }
if (folderFound == false) {
client.createDirectory(webdavfolderName).then(function (a) {
if (a.statusText == 'Created') {
if (func) { func('WebDAV folder created'); }
performWebDavUpload(client, filename);
} else {
if (func) { func('WebDAV (createDirectory) status: ' + a.statusText); }
}
}).catch(function (err) {
if (func) { func('WebDAV (createDirectory) error: ' + err); }
});
} else {
performWebDavCleanup(client);
performWebDavUpload(client, filename);
}
}
).catch(function (err) {
if (func) { func('WebDAV (getDirectoryContents) error: ' + err); }
});
}
// Google Drive Backup
if ((typeof parent.config.settings.autobackup == 'object') && (typeof parent.config.settings.autobackup.googledrive == 'object')) {
obj.Get('GoogleDriveBackup', function (err, docs) {
if ((err != null) || (docs.length != 1) || (docs[0].state != 3)) return;
if (func) { func('Attempting Google Drive upload...'); }
@ -1488,6 +1558,7 @@ module.exports.CreateDB = function (parent, func) {
});
});
}
}
function padNumber(number, digits) { return Array(Math.max(digits - String(number).length + 1, 0)).join(0) + number; }

View File

@ -115,6 +115,17 @@
"folderName": { "type": "integer", "default": "MeshCentral-Backups", "description": "The name of the folder to create in the Google Drive account." },
"maxFiles": { "type": "string", "default": null, "description": "The maximum number of files to keep in the Google Drive folder, older files will be removed if needed." }
}
},
"webDAV": {
"type": "object",
"description": "Enabled automated upload of the server backups to a WebDAV account.",
"properties": {
"url": { "type": "string", "description": "WebDAV account URL." },
"username": { "type": "string", "description": "WebDAV account username." },
"password": { "type": "string", "description": "WebDAV account password." },
"folderName": { "type": "integer", "default": "MeshCentral-Backups", "description": "The name of the folder to create in the WebDAV account." },
"maxFiles": { "type": "string", "default": null, "description": "The maximum number of files to keep in the WebDAV folder, older files will be removed if needed." }
}
}
}
},

View File

@ -2725,7 +2725,24 @@ function mainStart() {
// Setup encrypted zip support if needed
if (config.settings.autobackup && config.settings.autobackup.zippassword) {
modules.push('archiver-zip-encrypted');
if (typeof config.settings.autobackup.googledrive == 'object') { if (nodeVersion >= 8) { modules.push('googleapis'); } else { delete config.settings.autobackup.googledrive; } } // Enable Google Drive Support
// Enable Google Drive Support
if (typeof config.settings.autobackup.googledrive == 'object') {
if (nodeVersion >= 8) {
modules.push('googleapis');
} else {
addServerWarning("Google Drive requires Node v8.x or higher.", !args.launch);
delete config.settings.autobackup.googledrive;
}
}
// Enable WebDAV Support
if (typeof config.settings.autobackup.webdav == 'object') {
if (nodeVersion >= 10) {
if ((typeof config.settings.autobackup.webdav.url != 'string') || (typeof config.settings.autobackup.webdav.username != 'string') || (typeof config.settings.autobackup.webdav.password != 'string')) { addServerWarning("Missing WebDAV parameters.", !args.launch); } else { modules.push('webdav'); }
} else {
addServerWarning("WebDAV requires Node v10.x or higher.", !args.launch);
delete config.settings.autobackup.webdav;
}
}
}
// Setup common password blocking

View File

@ -36,7 +36,6 @@
"sample-config-advanced.json"
],
"dependencies": {
"archiver": "^4.0.2",
"body-parser": "^1.19.0",
"cbor": "^4.1.5",
"compression": "^1.7.4",

View File

@ -92,6 +92,13 @@
"_googleDrive": {
"folderName": "MeshCentral-Backups",
"maxFiles": 10
},
"webdav": {
"url": "https://server/remote.php/dav/files/xxxxx@server.com/",
"username": "user",
"password": "pass",
"folderName": "MeshCentral-Backups",
"maxFiles": 10
}
},
"_redirects": {