refactor how the schedule backup works

This commit is contained in:
Usman Nasir
2020-09-20 19:52:02 +05:00
parent 5c00fa909c
commit 9ed61ffb59
4 changed files with 451 additions and 463 deletions

View File

@@ -10,7 +10,7 @@ django.setup()
import json
from plogical.acl import ACLManager
import plogical.CyberCPLogFileWriter as logging
from websiteFunctions.models import Websites, Backups, dest, backupSchedules, BackupJob, BackupJobLogs, GDrive, GDriveSites, GDriveJobLogs
from websiteFunctions.models import Websites, Backups, dest, backupSchedules, BackupJob, GDrive, GDriveSites
from plogical.virtualHostUtilities import virtualHostUtilities
import subprocess
import shlex
@@ -26,6 +26,7 @@ import requests
import google.oauth2.credentials
import googleapiclient.discovery
from googleapiclient.discovery import build
from websiteFunctions.models import NormalBackupDests
class BackupManager:
@@ -710,10 +711,10 @@ class BackupManager:
if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
return ACLManager.loadErrorJson('destStatus', 0)
destinations = backupUtil.backupUtilities.destinationsPath
finalDic = {}
if data['type'] == 'SFTP':
finalDic['ipAddress'] = data['IPAddress']
finalDic['password'] = data['password']
@@ -727,18 +728,6 @@ class BackupManager:
except:
finalDic['user'] = "root"
if dest.objects.all().count() == 2:
final_dic = {'destStatus': 0,
'error_message': "Currently only one remote destination is allowed."}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
try:
d = dest.objects.get(destLoc=finalDic['password'])
final_dic = {'destStatus': 0, 'error_message': "This destination already exists."}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
except:
execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/plogical/backupUtilities.py"
execPath = execPath + " submitDestinationCreation --ipAddress " + finalDic['ipAddress'] + " --password " \
@@ -753,55 +742,62 @@ class BackupManager:
logging.CyberCPLogFileWriter.writeToFile(output)
if output.find('1,') > -1:
try:
writeToFile = open(destinations, "w")
writeToFile.write(json.dumps(finalDic))
writeToFile.close()
newDest = dest(destLoc=finalDic['ipAddress'])
newDest.save()
final_dic = {'destStatus': 1, 'error_message': "None"}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
except:
writeToFile = open(destinations, "w")
writeToFile.write(json.dumps(finalDic))
writeToFile.close()
config = {'type': data['type'], 'ip': data['IPAddress'], 'username': data['userName'], 'port': data['backupSSHPort'], 'path': data['path']}
nd = NormalBackupDests(name=data['name'], config = json.dumps(config))
nd.save()
newDest = dest(destLoc=finalDic['ipAddress'])
newDest.save()
final_dic = {'destStatus': 1, 'error_message': "None"}
final_dic = {'status' : 1, 'destStatus': 1, 'error_message': "None"}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
else:
final_dic = {'destStatus': 0, 'error_message': output}
final_dic = {'status' : 0, 'destStatus': 0, 'error_message': output}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
else:
config = {'type': data['type'], 'path': data['path']}
nd = NormalBackupDests(name='local', config=json.dumps(config))
nd.save()
final_dic = {'status' : 1, 'destStatus': 1, 'error_message': "None"}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
except BaseException as msg:
final_dic = {'destStatus': 0, 'error_message': str(msg)}
final_dic = {'status' : 0, 'destStatus': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def getCurrentBackupDestinations(self, userID=None, data=None):
try:
currentACL = ACLManager.loadedACL(userID)
if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
return ACLManager.loadErrorJson('fetchStatus', 0)
records = dest.objects.all()
destinations = NormalBackupDests.objects.all()
json_data = "["
checker = 0
for items in records:
if items.destLoc == "Home":
continue
dic = {'id': items.id,
'ip': items.destLoc,
for items in destinations:
config = json.loads(items.config)
if config['type'] == data['type'] and data['type'] == 'SFTP':
dic = {
'name': items.name,
'ip': config['ip'],
'username': config['username'],
'path': config['path'],
'port': config['port'],
}
else:
dic = {
'name': items.name,
'path': config['path'],
}
if checker == 0:
@@ -811,11 +807,11 @@ class BackupManager:
json_data = json_data + ',' + json.dumps(dic)
json_data = json_data + ']'
final_json = json.dumps({'fetchStatus': 1, 'error_message': "None", "data": json_data})
final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data})
return HttpResponse(final_json)
except BaseException as msg:
final_dic = {'fetchStatus': 0, 'error_message': str(msg)}
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
@@ -855,48 +851,25 @@ class BackupManager:
if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
return ACLManager.loadErrorJson('delStatus', 0)
ipAddress = data['IPAddress']
nameOrPath = data['nameOrPath']
type = data['type']
delDest = dest.objects.get(destLoc=ipAddress)
delDest.delete()
path = "/usr/local/CyberCP/backup/"
destinations = path + "destinations"
data = open(destinations, 'r').readlines()
writeToFile = open(destinations, 'r')
for items in data:
if items.find(ipAddress) > -1:
continue
if type == 'SFTP':
NormalBackupDests.objects.get(name=nameOrPath).delete()
else:
writeToFile.writelines(items)
dests = NormalBackupDests.objects.filter(name='local')
for items in dests:
config = json.loads(items.config)
if config['path'] == nameOrPath:
items.delete()
break
writeToFile.close()
## Deleting Cron Tab Entries for this destination
path = "/etc/crontab"
data = open(path, 'r').readlines()
writeToFile = open(path, 'w')
for items in data:
if items.find("backupSchedule.py") > -1:
continue
else:
writeToFile.writelines(items)
writeToFile.close()
final_dic = {'delStatus': 1, 'error_message': "None"}
final_dic = {'status': 1, 'delStatus': 1, 'error_message': "None"}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
except BaseException as msg:
final_dic = {'delStatus': 1, 'error_message': str(msg)}
final_dic = {'status': 0, 'delStatus': 1, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)

View File

@@ -415,254 +415,6 @@ app.controller('restoreWebsiteControl', function ($scope, $http, $timeout) {
//*** Restore site ends here ***///
///** Backup Destination ***//
app.controller('backupDestinations', function ($scope, $http, $timeout) {
$scope.destinationLoading = true;
$scope.connectionFailed = true;
$scope.connectionSuccess = true;
$scope.canNotAddDestination = true;
$scope.destinationAdded = true;
$scope.couldNotConnect = true;
populateCurrentRecords();
$scope.addDestination = function () {
$scope.destinationLoading = false;
$scope.connectionFailed = true;
$scope.connectionSuccess = true;
$scope.canNotAddDestination = true;
$scope.destinationAdded = true;
$scope.couldNotConnect = true;
url = "/backup/submitDestinationCreation";
var data = {
IPAddress: $scope.IPAddress,
password: $scope.password,
user: $scope.user,
backupSSHPort: $scope.backupSSHPort,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.destStatus == 1) {
$scope.destinationLoading = true;
$scope.connectionFailed = true;
$scope.connectionSuccess = true;
$scope.canNotAddDestination = true;
$scope.destinationAdded = false;
$scope.couldNotConnect = true;
populateCurrentRecords();
}
else {
$scope.destinationLoading = true;
$scope.connectionFailed = true;
$scope.connectionSuccess = true;
$scope.canNotAddDestination = false;
$scope.destinationAdded = true;
$scope.couldNotConnect = true;
$scope.errorMessage = response.data.error_message;
}
}
function cantLoadInitialDatas(response) {
$scope.destinationLoading = true;
$scope.connectionFailed = true;
$scope.connectionSuccess = true;
$scope.canNotAddDestination = true;
$scope.destinationAdded = true;
$scope.couldNotConnect = false;
}
};
$scope.checkConn = function (ip) {
$scope.destinationLoading = false;
$scope.connectionFailed = true;
$scope.connectionSuccess = true;
$scope.canNotAddDestination = true;
$scope.destinationAdded = true;
$scope.couldNotConnect = true;
url = "/backup/getConnectionStatus";
var data = {
IPAddress: ip,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.connStatus == 1) {
$scope.destinationLoading = true;
$scope.connectionFailed = true;
$scope.connectionSuccess = false;
$scope.canNotAddDestination = true;
$scope.destinationAdded = true;
$scope.couldNotConnect = true;
$scope.IPAddress = ip;
}
else {
$scope.destinationLoading = true;
$scope.connectionFailed = false;
$scope.connectionSuccess = true;
$scope.canNotAddDestination = true;
$scope.destinationAdded = true;
$scope.couldNotConnect = true;
$scope.errorMessage = response.data.error_message;
$scope.IPAddress = ip;
}
}
function cantLoadInitialDatas(response) {
$scope.destinationLoading = true;
$scope.connectionFailed = true;
$scope.connectionSuccess = true;
$scope.canNotAddDestination = true;
$scope.destinationAdded = true;
$scope.couldNotConnect = false;
}
};
$scope.delDest = function (ip) {
$scope.destinationLoading = false;
$scope.connectionFailed = true;
$scope.connectionSuccess = true;
$scope.canNotAddDestination = true;
$scope.destinationAdded = true;
$scope.couldNotConnect = true;
url = "/backup/deleteDestination";
var data = {
IPAddress: ip,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.delStatus == 1) {
$scope.destinationLoading = true;
$scope.connectionFailed = true;
$scope.connectionSuccess = true;
$scope.canNotAddDestination = true;
$scope.destinationAdded = true;
$scope.couldNotConnect = true;
populateCurrentRecords();
$scope.IPAddress = ip;
}
else {
$scope.destinationLoading = true;
$scope.connectionFailed = true;
$scope.connectionSuccess = true;
$scope.canNotAddDestination = true;
$scope.destinationAdded = true;
$scope.couldNotConnect = true;
$scope.errorMessage = response.data.error_message;
$scope.IPAddress = ip;
}
}
function cantLoadInitialDatas(response) {
$scope.destinationLoading = true;
$scope.connectionFailed = true;
$scope.connectionSuccess = true;
$scope.canNotAddDestination = true;
$scope.destinationAdded = true;
$scope.couldNotConnect = false;
}
};
function populateCurrentRecords() {
url = "/backup/getCurrentBackupDestinations";
var data = {};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.fetchStatus == 1) {
$scope.records = JSON.parse(response.data.data);
}
}
function cantLoadInitialDatas(response) {
$scope.couldNotConnect = false;
}
};
});
//*** Backup destination ***///
///** Schedule Backup ***//
app.controller('scheduleBackup', function ($scope, $http, $timeout) {
@@ -1911,3 +1663,191 @@ app.controller('googleDrive', function ($scope, $http) {
};
});
///
app.controller('backupDestinations', function ($scope, $http) {
$scope.cyberpanelLoading = true;
$scope.sftpHide = true;
$scope.localHide = true;
$scope.fetchDetails = function () {
if ($scope.destinationType === 'SFTP') {
$scope.sftpHide = false;
$scope.localHide = true;
$scope.populateCurrentRecords();
} else {
$scope.sftpHide = true;
$scope.localHide = false;
$scope.populateCurrentRecords();
}
};
$scope.populateCurrentRecords = function () {
$scope.cyberpanelLoading = false;
url = "/backup/getCurrentBackupDestinations";
var type = 'SFTP';
if ($scope.destinationType === 'SFTP') {
type = 'SFTP';
} else {
type = 'local';
}
var data = {
type: type
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.cyberpanelLoading = true;
if (response.data.status === 1) {
$scope.records = JSON.parse(response.data.data);
} else {
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.cyberpanelLoading = true;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
};
$scope.addDestination = function (type) {
$scope.cyberpanelLoading = false;
url = "/backup/submitDestinationCreation";
if (type === 'SFTP') {
var data = {
type: type,
name: $scope.name,
IPAddress: $scope.IPAddress,
userName: $scope.userName,
password: $scope.password,
backupSSHPort: $scope.backupSSHPort,
path: $scope.path
};
} else {
var data = {
type: type,
path: $scope.localPath,
};
}
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.cyberpanelLoading = true;
$scope.populateCurrentRecords();
if (response.data.status === 1) {
new PNotify({
title: 'Success!',
text: 'Destination successfully added.',
type: 'success'
});
} else {
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.cyberpanelLoading = true;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
};
$scope.removeDestination = function (type, nameOrPath) {
$scope.cyberpanelLoading = false;
url = "/backup/deleteDestination";
var data = {
type: type,
nameOrPath: nameOrPath,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.cyberpanelLoading = true;
$scope.populateCurrentRecords();
if (response.data.status === 1) {
new PNotify({
title: 'Success!',
text: 'Destination successfully removed.',
type: 'success'
});
} else {
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.cyberpanelLoading = true;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
};
});

View File

@@ -3,114 +3,127 @@
{% block title %}{% trans "Set up Back up Destinations" %}{% endblock %}
{% block content %}
{% load static %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2>{% trans "Set up Back up Destinations" %} - <a target="_blank" href="http://go.cyberpanel.net/remote-backup" style="height: 23px;line-height: 21px;" class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>{% trans "Remote Backups" %}</span></a></h2>
<div class="container">
<div id="page-title">
<h2>{% trans "Set up Back up Destinations" %} - <a target="_blank"
href="https://go.cyberpanel.net/remote-backup"
style="height: 23px;line-height: 21px;"
class="btn btn-border btn-alt border-red btn-link font-red"
title=""><span>{% trans "Remote Backups" %}</span></a>
</h2>
<p>{% trans "On this page you can set up your Back up destinations. (SFTP)" %}</p>
</div>
</div>
<div ng-controller="backupDestinations" class="panel">
<div ng-controller="backupDestinations" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Set up Back up Destinations (SSH port should be 22 on backup server)" %} <img ng-hide="destinationLoading" src="{% static 'images/loading.gif' %}">
{% trans "Set up Back up Destinations." %} <img ng-hide="cyberpanelLoading"
src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
<form action="/" class="form-horizontal bordered-row">
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Select Type" %} </label>
<div class="col-sm-6">
<select ng-change="fetchDetails()" ng-model="destinationType" class="form-control">
<option>local</option>
<option>SFTP</option>
</select>
</div>
</div>
<!--- SFTP --->
<div ng-hide="sftpHide" class="form-group">
<label class="col-sm-3 control-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="name" required>
</div>
</div>
<div ng-hide="sftpHide" class="form-group">
<label class="col-sm-3 control-label">{% trans "IP Address" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="IPAddress" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "User" %}</label>
<div ng-hide="sftpHide" class="form-group">
<label class="col-sm-3 control-label">{% trans "Username" %}</label>
<div class="col-sm-6">
<input placeholder="{% trans "Backup server SSH User, leave empty for root." %}" type="text" class="form-control" ng-model="user" required>
<input type="text" class="form-control" ng-model="userName" required>
</div>
</div>
<div class="form-group">
<div ng-hide="sftpHide" class="form-group">
<label class="col-sm-3 control-label">{% trans "Password" %}</label>
<div class="col-sm-6">
<input placeholder="" type="password" class="form-control" ng-model="password" required>
</div>
</div>
<div class="form-group">
<div ng-hide="sftpHide" class="form-group">
<label class="col-sm-3 control-label">{% trans "Port" %}</label>
<div class="col-sm-6">
<input placeholder="{% trans "Backup server SSH Port, leave empty for 22." %}" type="text" class="form-control" ng-model="backupSSHPort" required>
<input placeholder="{% trans "Backup server SSH Port, leave empty for 22." %}"
type="text" class="form-control" ng-model="backupSSHPort" required>
</div>
</div>
<div class="form-group">
<div ng-hide="sftpHide" class="form-group">
<label class="col-sm-3 control-label">{% trans "Path" %}</label>
<div class="col-sm-6">
<input placeholder="Path on remote server to store backups." type="text" class="form-control" ng-model="path" required>
</div>
</div>
<div ng-hide="sftpHide" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="addDestination()" class="btn btn-primary btn-lg btn-block">{% trans "Add Destination" %}</button>
<button type="button" ng-click="addDestination('SFTP')"
class="btn btn-primary btn-lg btn-block">{% trans "Add Destination" %}</button>
</div>
</div>
<!--- SFTP --->
<!------ List of Destinations --------------->
<div class="form-group">
<div class="col-sm-12">
<div ng-hide="connectionFailed" class="alert alert-danger">
<p>{% trans "Connection to" %} {$ IPAddress $} {% trans "failed. Please delete and re-add. " %} {$ errorMessage $} </p>
</div>
<div ng-hide="connectionSuccess" class="alert alert-success">
<p>{% trans "Connection to" %} {$ IPAddress $} {% trans "successful." %}</p>
</div>
<div ng-hide="canNotAddDestination" class="alert alert-danger">
<p>{% trans "Cannot add destination. Error message:" %} {$ errorMessage $} </p>
</div>
<div ng-hide="destinationAdded" class="alert alert-success">
<p>{% trans "Destination Added." %}</p>
</div>
<div ng-hide="couldNotConnect" class="alert alert-danger">
<p>{% trans "Could not connect to server. Please refresh this page." %}</p>
</div>
</div>
</div>
<div class="form-group">
<div ng-hide="sftpHide" class="form-group">
<div class="col-sm-12">
<table class="table">
<thead>
<tr>
<th>{% trans "ID" %}</th>
<th>{% trans "Name" %}</th>
<th>{% trans "IP" %}</th>
<th>{% trans "Check Connection" %}</th>
<th>{% trans "Username" %}</th>
<th>{% trans "Path" %}</th>
<th>{% trans "Port" %}</th>
<th>{% trans "Delete" %}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="record in records track by $index">
<td ng-bind="record.id"></td>
<td ng-bind="record.name"></td>
<td ng-bind="record.ip"></td>
<td><button type="button" ng-click="checkConn(record.ip)" class="btn ra-100 btn-purple">{% trans "Check Connection" %}</button></td>
<td ng-click="delDest(record.ip)"><img src="{% static 'images/delete.png' %}"></td>
<td ng-bind="record.username"></td>
<td ng-bind="record.path"></td>
<td ng-bind="record.port"></td>
<td ng-click="removeDestination('SFTP', record.name)"><img src="{% static 'images/delete.png' %}">
</td>
</tr>
</tbody>
@@ -121,16 +134,71 @@
<!------ List of records --------------->
<!--- SFTP End --->
<!--- AWS Start --->
<div ng-hide="localHide" class="form-group">
<label class="col-sm-3 control-label">{% trans "Local Path" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="localPath" required>
</div>
</div>
<div ng-hide="localHide" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="addDestination('local')"
class="btn btn-primary btn-lg btn-block">{% trans "Add Destination" %}</button>
</div>
</div>
<!--- SFTP --->
<!------ List of Destinations --------------->
<div ng-hide="localHide" class="form-group">
<div class="col-sm-12">
<table class="table">
<thead>
<tr>
<th>{% trans "Path" %}</th>
<th>{% trans "Delete" %}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="record in records track by $index">
<td ng-bind="record.path"></td>
<td ng-click="removeDestination('local', record.path)"><img src="{% static 'images/delete.png' %}">
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!------ List of records --------------->
<!--- AWS End --->
</form>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -76,3 +76,10 @@ class GDriveJobLogs(models.Model):
owner = models.ForeignKey(GDrive, on_delete=models.CASCADE)
status = models.IntegerField()
message = models.TextField()
### Normal backup models
class NormalBackupDests(models.Model):
name = models.CharField(max_length=25)
config = models.TextField()