mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-15 09:46:11 +01:00
oc backups
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from django.db import models
|
||||
from websiteFunctions.models import Websites
|
||||
from loginSystem.models import Administrator
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
@@ -27,3 +28,19 @@ class BackupJob(models.Model):
|
||||
class JobSites(models.Model):
|
||||
job = models.ForeignKey(BackupJob, on_delete=models.CASCADE)
|
||||
website = models.CharField(max_length=300)
|
||||
|
||||
|
||||
class OneClickBackups(models.Model):
|
||||
owner = models.ForeignKey(Administrator, on_delete=models.PROTECT)
|
||||
planName = models.CharField(max_length=100)
|
||||
months = models.CharField(max_length=100)
|
||||
price = models.CharField(max_length=100)
|
||||
customer = models.CharField(max_length=300)
|
||||
subscription = models.CharField(max_length=300, unique=True)
|
||||
sftpUser = models.CharField(max_length=100)
|
||||
config = models.TextField(default='{}')
|
||||
date = models.DateTimeField(default=datetime.now, blank=True)
|
||||
state = models.IntegerField(default=0)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,12 @@
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
import django
|
||||
from io import StringIO
|
||||
|
||||
import django
|
||||
import paramiko
|
||||
|
||||
from plogical.applicationInstaller import ApplicationInstaller
|
||||
from plogical.httpProc import httpProc
|
||||
|
||||
sys.path.append('/usr/local/CyberCP')
|
||||
@@ -1912,4 +1916,405 @@ class BackupManager:
|
||||
except BaseException as msg:
|
||||
data_ret = {'abort': 0, 'installStatus': 0, 'installationProgress': "0", 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def OneClickBackups(self, request=None, userID=None, data=None):
|
||||
user = Administrator.objects.get(pk=userID)
|
||||
|
||||
data = {}
|
||||
|
||||
import requests
|
||||
try:
|
||||
if request.GET.get('status', 'none') == 'success':
|
||||
plan_name = request.GET.get('planName')
|
||||
months = request.GET.get('months')
|
||||
monthly_price = request.GET.get('monthlyPrice')
|
||||
yearly_price = request.GET.get('yearlyPrice')
|
||||
customer = request.GET.get('customer')
|
||||
subscription = request.GET.get('subscription')
|
||||
|
||||
from IncBackups.models import OneClickBackups
|
||||
|
||||
if months == '1':
|
||||
price = monthly_price
|
||||
else:
|
||||
price = yearly_price
|
||||
|
||||
try:
|
||||
|
||||
backup_plan = OneClickBackups(
|
||||
owner=user,
|
||||
planName=plan_name,
|
||||
months=months,
|
||||
price=price,
|
||||
customer=customer,
|
||||
subscription=subscription,
|
||||
sftpUser=f'{user.userName}{str(randint(1000, 9999))}',
|
||||
)
|
||||
backup_plan.save()
|
||||
|
||||
####
|
||||
|
||||
import requests
|
||||
import json
|
||||
|
||||
|
||||
# Define the URL of the endpoint
|
||||
url = 'http://platform.cyberpersons.com/Billing/CreateSFTPAccount' # Replace with your actual endpoint URL
|
||||
|
||||
# Define the payload to send in the POST request
|
||||
payload = {
|
||||
'sub': subscription,
|
||||
'key': ProcessUtilities.outputExecutioner(f'cat /root/.ssh/cyberpanel.pub'), # Replace with the actual SSH public key
|
||||
'sftpUser': backup_plan.sftpUser,
|
||||
'serverIP': ACLManager.fetchIP(), # Replace with the actual server IP,
|
||||
'planName': plan_name
|
||||
}
|
||||
|
||||
# Convert the payload to JSON format
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
dataRet = json.dumps(payload)
|
||||
|
||||
# Make the POST request
|
||||
response = requests.post(url, headers=headers, data=dataRet)
|
||||
|
||||
# Handle the response
|
||||
if response.status_code == 200:
|
||||
response_data = response.json()
|
||||
if response_data.get('status') == 1:
|
||||
|
||||
ocbkup = OneClickBackups.objects.get(owner=user,subscription=subscription)
|
||||
ocbkup.state = 1
|
||||
ocbkup.save()
|
||||
|
||||
finalDic = {}
|
||||
|
||||
finalDic['IPAddress'] = response_data.get('ipAddress')
|
||||
finalDic['password'] = 'NOT-NEEDED'
|
||||
finalDic['backupSSHPort'] = '22'
|
||||
finalDic['userName'] = backup_plan.sftpUser
|
||||
finalDic['type'] = 'SFTP'
|
||||
finalDic['path'] = 'cpbackups'
|
||||
finalDic['name'] = backup_plan.sftpUser
|
||||
|
||||
wm = BackupManager()
|
||||
response_inner = wm.submitDestinationCreation(userID, finalDic)
|
||||
|
||||
response_data_inner = json.loads(response_inner.content.decode('utf-8'))
|
||||
|
||||
# Extract the value of 'status'
|
||||
if response_data_inner.get('status') == 0:
|
||||
data['status'] = 0
|
||||
data[
|
||||
'message'] = f"[2109] Failed to create sftp account {response_data_inner.get('error_message')}"
|
||||
print("Failed to create SFTP account:", response_data_inner.get('error_message'))
|
||||
else:
|
||||
data['status'] = 1
|
||||
|
||||
else:
|
||||
data['status'] = 0
|
||||
data['message'] = f"[1985] Failed to create sftp account {response_data.get('error_message')}"
|
||||
print("Failed to create SFTP account:", response_data.get('error_message'))
|
||||
else:
|
||||
print("Failed to connect to the server. Status code:", response.status_code)
|
||||
print("Response:", response.text)
|
||||
data['status'] = 0
|
||||
data['message'] = f"[1991] Failed to create sftp account {response.text}"
|
||||
|
||||
####
|
||||
|
||||
except BaseException as msg:
|
||||
data['status'] = 4
|
||||
data['message'] = str(msg)
|
||||
|
||||
elif request.GET.get('status', 'none') == 'cancelled':
|
||||
data['status'] = 0
|
||||
else:
|
||||
data['status'] = 2
|
||||
except BaseException as msg:
|
||||
data['status'] = 0
|
||||
data['message'] = f"[2038] Unkown error occured in purchase process. Error message: {str(msg)}"
|
||||
|
||||
|
||||
url = 'https://platform.cyberpersons.com/Billing/FetchBackupPlans'
|
||||
|
||||
try:
|
||||
response = requests.get(url)
|
||||
response.raise_for_status() # Check if the request was successful
|
||||
data['plans'] = response.json() # Convert the response to a Python dictionary
|
||||
except requests.exceptions.HTTPError as http_err:
|
||||
print(f'HTTP error occurred: {http_err}')
|
||||
except Exception as err:
|
||||
print(f'Other error occurred: {err}')
|
||||
|
||||
data['bPlans'] = user.oneclickbackups_set.all()
|
||||
|
||||
proc = httpProc(request, 'backup/oneClickBackups.html', data, 'addDeleteDestinations')
|
||||
return proc.render()
|
||||
|
||||
def ManageOCBackups(self, request=None, userID=None, data=None):
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
from IncBackups.models import OneClickBackups
|
||||
ocb = OneClickBackups.objects.get(pk = request.GET.get('id'), owner=admin)
|
||||
destinations = [NormalBackupDests.objects.get(name=ocb.sftpUser)]
|
||||
dests = []
|
||||
for dest in destinations:
|
||||
dests.append(dest.name)
|
||||
|
||||
websitesName = ACLManager.findAllSites(currentACL, userID)
|
||||
|
||||
proc = httpProc(request, 'backup/OneClickBackupSchedule.html', {'destination': NormalBackupDests.objects.get(name=ocb.sftpUser).name, 'websites': websitesName},
|
||||
'scheduleBackups')
|
||||
return proc.render()
|
||||
|
||||
def RestoreOCBackups(self, request=None, userID=None, data=None):
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
from IncBackups.models import OneClickBackups
|
||||
ocb = OneClickBackups.objects.get(pk = request.GET.get('id'), owner=admin)
|
||||
|
||||
# Load the private key
|
||||
|
||||
nbd = NormalBackupDests.objects.get(name=ocb.sftpUser)
|
||||
ip = json.loads(nbd.config)['ip']
|
||||
|
||||
# Connect to the remote server using the private key
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
# Read the private key content
|
||||
private_key_path = '/root/.ssh/cyberpanel'
|
||||
key_content = ProcessUtilities.outputExecutioner(f'cat {private_key_path}').rstrip('\n')
|
||||
|
||||
# Load the private key from the content
|
||||
key_file = StringIO(key_content)
|
||||
key = paramiko.RSAKey.from_private_key(key_file)
|
||||
# Connect to the server using the private key
|
||||
ssh.connect(ip, username=ocb.sftpUser, pkey=key)
|
||||
# Command to list directories under the specified path
|
||||
command = f"ls -d cpbackups/*/"
|
||||
|
||||
# Execute the command
|
||||
stdin, stdout, stderr = ssh.exec_command(command)
|
||||
|
||||
# Read the results
|
||||
directories = stdout.read().decode().splitlines()
|
||||
|
||||
finalDirs = []
|
||||
|
||||
# Print directories
|
||||
for directory in directories:
|
||||
finalDirs.append(directory.split('/')[1])
|
||||
|
||||
proc = httpProc(request, 'backup/restoreOCBackups.html', {'directories': finalDirs},
|
||||
'scheduleBackups')
|
||||
return proc.render()
|
||||
|
||||
def fetchOCSites(self, request=None, userID=None, data=None):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
data = json.loads(request.body)
|
||||
id = data['idValue']
|
||||
folder = data['folder']
|
||||
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
from IncBackups.models import OneClickBackups
|
||||
ocb = OneClickBackups.objects.get(pk = id, owner=admin)
|
||||
|
||||
# Load the private key
|
||||
|
||||
nbd = NormalBackupDests.objects.get(name=ocb.sftpUser)
|
||||
ip = json.loads(nbd.config)['ip']
|
||||
|
||||
# Connect to the remote server using the private key
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
# Read the private key content
|
||||
private_key_path = '/root/.ssh/cyberpanel'
|
||||
key_content = ProcessUtilities.outputExecutioner(f'cat {private_key_path}').rstrip('\n')
|
||||
|
||||
# Load the private key from the content
|
||||
key_file = StringIO(key_content)
|
||||
key = paramiko.RSAKey.from_private_key(key_file)
|
||||
# Connect to the server using the private key
|
||||
ssh.connect(ip, username=ocb.sftpUser, pkey=key)
|
||||
# Command to list directories under the specified path
|
||||
command = f"ls -d cpbackups/{folder}/*"
|
||||
|
||||
# Execute the command
|
||||
stdin, stdout, stderr = ssh.exec_command(command)
|
||||
|
||||
# Read the results
|
||||
directories = stdout.read().decode().splitlines()
|
||||
|
||||
finalDirs = []
|
||||
|
||||
# Print directories
|
||||
for directory in directories:
|
||||
finalDirs.append(directory.split('/')[2])
|
||||
|
||||
data_ret = {'status': 1, 'finalDirs': finalDirs}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
except BaseException as msg:
|
||||
data_ret = {'status': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def StartOCRestore(self, request=None, userID=None, data=None):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
data = json.loads(request.body)
|
||||
id = data['idValue']
|
||||
folder = data['folder']
|
||||
backupfile = data['backupfile']
|
||||
|
||||
|
||||
extraArgs = {}
|
||||
extraArgs['id'] = id
|
||||
extraArgs['folder'] = folder
|
||||
extraArgs['backupfile'] = backupfile
|
||||
extraArgs['userID'] = userID
|
||||
extraArgs['tempStatusPath'] = "/home/cyberpanel/" + str(randint(1000, 9999))
|
||||
|
||||
statusFile = open(extraArgs['tempStatusPath'], 'w')
|
||||
statusFile.writelines("Restore started..")
|
||||
statusFile.close()
|
||||
|
||||
background = ApplicationInstaller('StartOCRestore', extraArgs)
|
||||
background.start()
|
||||
|
||||
data_ret = {'status': 1, 'installStatus': 1, 'error_message': 'None',
|
||||
'tempStatusPath': extraArgs['tempStatusPath']}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
except BaseException as msg:
|
||||
data_ret = {'status': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def DeployAccount(self, request=None, userID=None, data=None):
|
||||
user = Administrator.objects.get(pk=userID)
|
||||
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
import json
|
||||
|
||||
data = json.loads(request.body)
|
||||
id = data['id']
|
||||
|
||||
from IncBackups.models import OneClickBackups
|
||||
ocb = OneClickBackups.objects.get(pk=id, owner=user)
|
||||
|
||||
data = {}
|
||||
|
||||
####
|
||||
|
||||
import requests
|
||||
import json
|
||||
|
||||
# Define the URL of the endpoint
|
||||
url = 'http://platform.cyberpersons.com/Billing/CreateSFTPAccount' # Replace with your actual endpoint URL
|
||||
|
||||
# Define the payload to send in the POST request
|
||||
payload = {
|
||||
'sub': ocb.subscription,
|
||||
'key': ProcessUtilities.outputExecutioner(f'cat /root/.ssh/cyberpanel.pub'),
|
||||
# Replace with the actual SSH public key
|
||||
'sftpUser': ocb.sftpUser,
|
||||
'serverIP': ACLManager.fetchIP(), # Replace with the actual server IP
|
||||
'planName': ocb.planName
|
||||
}
|
||||
|
||||
# Convert the payload to JSON format
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
dataRet = json.dumps(payload)
|
||||
|
||||
# Make the POST request
|
||||
response = requests.post(url, headers=headers, data=dataRet)
|
||||
|
||||
# Handle the response
|
||||
# Handle the response
|
||||
if response.status_code == 200:
|
||||
response_data = response.json()
|
||||
if response_data.get('status') == 1:
|
||||
|
||||
ocb.state = 1
|
||||
ocb.save()
|
||||
|
||||
print("SFTP account created successfully.")
|
||||
|
||||
finalDic = {}
|
||||
|
||||
finalDic['IPAddress'] = response_data.get('ipAddress')
|
||||
finalDic['password'] = 'NOT-NEEDED'
|
||||
finalDic['backupSSHPort'] = '22'
|
||||
finalDic['userName'] = ocb.sftpUser
|
||||
finalDic['type'] = 'SFTP'
|
||||
finalDic['path'] = 'cpbackups'
|
||||
finalDic['name'] = ocb.sftpUser
|
||||
|
||||
wm = BackupManager()
|
||||
response_inner = wm.submitDestinationCreation(userID, finalDic)
|
||||
|
||||
response_data_inner = json.loads(response_inner.content.decode('utf-8'))
|
||||
|
||||
# Extract the value of 'status'
|
||||
if response_data_inner.get('status') == 0:
|
||||
data_ret = {'status': 1, 'error_message': response_data_inner.get('error_message')}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
else:
|
||||
data_ret = {'status': 1,}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
else:
|
||||
|
||||
if response_data.get('error_message') == "Already deployed.":
|
||||
ocb.state = 1
|
||||
ocb.save()
|
||||
|
||||
print("SFTP account created successfully.")
|
||||
|
||||
finalDic = {}
|
||||
|
||||
finalDic['IPAddress'] = response_data.get('ipAddress')
|
||||
finalDic['password'] = 'NOT-NEEDED'
|
||||
finalDic['backupSSHPort'] = '22'
|
||||
finalDic['userName'] = ocb.sftpUser
|
||||
finalDic['type'] = 'SFTP'
|
||||
finalDic['path'] = 'cpbackups'
|
||||
finalDic['name'] = ocb.sftpUser
|
||||
|
||||
wm = BackupManager()
|
||||
response_inner = wm.submitDestinationCreation(userID, finalDic)
|
||||
|
||||
response_data_inner = json.loads(response_inner.content.decode('utf-8'))
|
||||
|
||||
# Extract the value of 'status'
|
||||
if response_data_inner.get('status') == 0:
|
||||
data_ret = {'status': 1, 'error_message': response_data_inner.get('error_message')}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
else:
|
||||
data_ret = {'status': 1, }
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
data_ret = {'status': 0, 'error_message': response_data.get('error_message')}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
else:
|
||||
data['message'] = f"[1991] Failed to create sftp account {response.text}"
|
||||
data_ret = {'status': 0, 'error_message': response.text}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
|
||||
|
||||
@@ -97,8 +97,7 @@ app.controller('backupWebsiteControl', function ($scope, $http, $timeout) {
|
||||
$scope.status = response.data.status;
|
||||
populateCurrentRecords();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$scope.destination = true;
|
||||
$scope.backupButton = true;
|
||||
$scope.runningBackup = false;
|
||||
@@ -109,8 +108,7 @@ app.controller('backupWebsiteControl', function ($scope, $http, $timeout) {
|
||||
$timeout(getBackupStatus, 2000);
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$timeout.cancel();
|
||||
$scope.backupLoadingBottom = true;
|
||||
$scope.backupLoading = true;
|
||||
@@ -230,8 +228,7 @@ app.controller('backupWebsiteControl', function ($scope, $http, $timeout) {
|
||||
populateCurrentRecords();
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
@@ -308,8 +305,7 @@ app.controller('restoreWebsiteControl', function ($scope, $http, $timeout) {
|
||||
$scope.restoreFinished = true;
|
||||
$timeout.cancel();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$scope.running = response.data.running;
|
||||
$scope.fileName = $scope.backupFile;
|
||||
$scope.restoreLoading = false;
|
||||
@@ -364,18 +360,17 @@ app.controller('restoreWebsiteControl', function ($scope, $http, $timeout) {
|
||||
|
||||
getRestoreStatus();
|
||||
restoreBackupButton.disabled = false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$scope.backupError = false;
|
||||
$scope.errorMessage = response.data.error_message;
|
||||
restoreBackupButton.disabled = false;
|
||||
restoreBackupButton.disabled = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.couldNotConnect = false;
|
||||
restoreBackupButton.disabled = false;
|
||||
restoreBackupButton.disabled = false;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -404,14 +399,12 @@ app.controller('restoreWebsiteControl', function ($scope, $http, $timeout) {
|
||||
|
||||
if (response.data.createWebSiteStatus == 1) {
|
||||
getRestoreStatus();
|
||||
}
|
||||
else if (response.data.existsStatus == 1) {
|
||||
} else if (response.data.existsStatus == 1) {
|
||||
$scope.backupError = false;
|
||||
$scope.errorMessage = response.data.error_message;
|
||||
$scope.restoreButton = true;
|
||||
$scope.runningRestore = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$scope.websiteDomain = domainName;
|
||||
$scope.backupError = false;
|
||||
$scope.errorMessage = response.data.error_message;
|
||||
@@ -484,8 +477,7 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) {
|
||||
websitesToBeBacked.push(website);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
var tempArray = [];
|
||||
|
||||
@@ -504,8 +496,7 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) {
|
||||
|
||||
websitesToBeBacked = websitesToBeBackedTemp;
|
||||
$scope.webSiteStatus = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
websitesToBeBacked = [];
|
||||
$scope.webSiteStatus = false;
|
||||
}
|
||||
@@ -568,8 +559,7 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) {
|
||||
$scope.backupCancelled = true;
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$scope.error_message = response.data.error_message;
|
||||
$scope.backupLoading = true;
|
||||
|
||||
@@ -667,8 +657,7 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) {
|
||||
getBackupStatus();
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
$scope.error_message = response.data.error_message;
|
||||
$scope.backupLoading = true;
|
||||
@@ -730,8 +719,7 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) {
|
||||
$scope.backupStatus = false;
|
||||
$scope.requestData = response.data.status;
|
||||
$timeout(getBackupStatus, 2000);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$scope.requestData = response.data.status;
|
||||
$timeout.cancel();
|
||||
|
||||
@@ -739,8 +727,7 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) {
|
||||
|
||||
remoteBackupRestore();
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
$scope.error_message = response.data.error_message;
|
||||
$scope.backupLoading = true;
|
||||
@@ -832,15 +819,13 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) {
|
||||
$scope.backupStatus = false;
|
||||
$scope.restoreData = response.data.status;
|
||||
$timeout(localRestoreStatus, 2000);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$scope.restoreData = response.data.status;
|
||||
$timeout.cancel();
|
||||
$scope.backupLoading = true;
|
||||
$scope.startTransferbtn = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
$scope.error_message = response.data.error_message;
|
||||
$scope.backupLoading = true;
|
||||
@@ -895,8 +880,7 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) {
|
||||
$scope.backupStatus = false;
|
||||
$scope.requestData = response.data.status;
|
||||
$timeout(getBackupStatus, 2000);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$timeout.cancel();
|
||||
}
|
||||
}
|
||||
@@ -980,8 +964,7 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) {
|
||||
$scope.fetchAccountsBtn = false;
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
$scope.error_message = response.data.error_message;
|
||||
$scope.backupLoading = true;
|
||||
@@ -1067,6 +1050,7 @@ app.controller('backupLogsScheduled', function ($scope, $http, $timeout) {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function cantLoadInitialData(response) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
new PNotify({
|
||||
@@ -1085,15 +1069,12 @@ app.controller('backupLogsScheduled', function ($scope, $http, $timeout) {
|
||||
///** Backup site ends **///
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
app.controller('googleDrive', function ($scope, $http) {
|
||||
|
||||
$scope.cyberPanelLoading = true;
|
||||
$scope.driveHidden = true;
|
||||
|
||||
$scope.setupAccount = function(){
|
||||
$scope.setupAccount = function () {
|
||||
window.open("https://platform.cyberpersons.com/gDrive?name=" + $scope.accountName + '&server=' + window.location.href + 'Setup');
|
||||
};
|
||||
|
||||
@@ -1252,7 +1233,7 @@ app.controller('googleDrive', function ($scope, $http) {
|
||||
|
||||
$scope.changeRetention = function () {
|
||||
$scope.cyberPanelLoading = false;
|
||||
var config = {
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
@@ -1268,24 +1249,25 @@ app.controller('googleDrive', function ($scope, $http) {
|
||||
|
||||
$http.post(dataurl, data, config).then(fileretention, cantLoadInitialData);
|
||||
|
||||
function fileretention(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
text: 'Changes successfully applied',
|
||||
type: 'success'
|
||||
});
|
||||
$scope.fetchWebsites();
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
function fileretention(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
text: 'Changes successfully applied',
|
||||
type: 'success'
|
||||
});
|
||||
$scope.fetchWebsites();
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
function cantLoadInitialData(response) {
|
||||
}
|
||||
|
||||
function cantLoadInitialData(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
@@ -2062,3 +2044,654 @@ app.controller('scheduleBackup', function ($scope, $http, $window) {
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
app.controller('backupPlanNowOneClick', function ($scope, $http, $window) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
$scope.sftpHide = true;
|
||||
$scope.localHide = true;
|
||||
|
||||
$scope.BuyNowBackupP = function (planName, monthlyPrice, yearlyPrice, months) {
|
||||
|
||||
const baseURL = 'https://platform.cyberpersons.com/Billing/CreateOrderforBackupPlans';
|
||||
// Get the current URL
|
||||
var currentURL = window.location.href;
|
||||
|
||||
// Find the position of the question mark
|
||||
const queryStringIndex = currentURL.indexOf('?');
|
||||
|
||||
// Check if there is a query string
|
||||
currentURL = queryStringIndex !== -1 ? currentURL.substring(0, queryStringIndex) : currentURL;
|
||||
|
||||
|
||||
// Encode parameters to make them URL-safe
|
||||
const params = new URLSearchParams({
|
||||
planName: planName,
|
||||
monthlyPrice: monthlyPrice,
|
||||
yearlyPrice: yearlyPrice,
|
||||
returnURL: currentURL, // Add the current URL as a query parameter
|
||||
months: months
|
||||
});
|
||||
|
||||
|
||||
// Build the complete URL with query string
|
||||
const fullURL = `${baseURL}?${params.toString()}`;
|
||||
|
||||
// Redirect to the constructed URL
|
||||
|
||||
window.location.href = fullURL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
$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,
|
||||
name: $scope.name
|
||||
};
|
||||
}
|
||||
|
||||
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'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.DeployAccount = function (id) {
|
||||
$scope.cyberpanelLoading = false;
|
||||
|
||||
url = "/backup/DeployAccount";
|
||||
|
||||
var data = {
|
||||
id:id
|
||||
|
||||
};
|
||||
|
||||
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) {
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
text: 'Successfully deployed.',
|
||||
type: 'success'
|
||||
});
|
||||
$window.location.reload();
|
||||
|
||||
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.couldNotConnect = false;
|
||||
restoreBackupButton.disabled = false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
app.controller('OneClickrestoreWebsiteControl', function ($scope, $http, $timeout) {
|
||||
|
||||
$scope.restoreLoading = true;
|
||||
$scope.runningRestore = true;
|
||||
$scope.restoreButton = true;
|
||||
$scope.restoreFinished = false;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.backupError = true;
|
||||
$scope.siteExists = true;
|
||||
$scope.installationProgress = true;
|
||||
|
||||
// check to start time of status function
|
||||
|
||||
var check = 1;
|
||||
|
||||
|
||||
$scope.fetchDetails = function () {
|
||||
$scope.restoreLoading = false;
|
||||
getRestoreStatus();
|
||||
};
|
||||
|
||||
|
||||
function getRestoreStatus() {
|
||||
|
||||
var backupFile = $scope.backupFile;
|
||||
|
||||
url = "/backup/restoreStatus";
|
||||
|
||||
var data = {
|
||||
backupFile: backupFile,
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
|
||||
|
||||
if (response.data.restoreStatus === 1) {
|
||||
|
||||
if (response.data.abort === 1) {
|
||||
$scope.running = response.data.running;
|
||||
$scope.fileName = $scope.backupFile;
|
||||
$scope.restoreLoading = true;
|
||||
$scope.status = response.data.status;
|
||||
$scope.runningRestore = false;
|
||||
$scope.restoreButton = false;
|
||||
$scope.restoreFinished = true;
|
||||
$timeout.cancel();
|
||||
return;
|
||||
} else {
|
||||
$scope.running = response.data.running;
|
||||
$scope.fileName = $scope.backupFile;
|
||||
$scope.restoreLoading = false;
|
||||
$scope.status = response.data.status;
|
||||
$scope.runningRestore = false;
|
||||
$scope.restoreButton = true;
|
||||
$timeout(getRestoreStatus, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.couldNotConnect = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
$scope.restoreBackup = function () {
|
||||
var restoreBackupButton = document.getElementById("restoreBackup");
|
||||
restoreBackupButton.disabled = true;
|
||||
var backupFile = $scope.backupFile;
|
||||
$scope.running = "Lets start.."
|
||||
|
||||
url = "/backup/submitRestore";
|
||||
|
||||
var data = {
|
||||
backupFile: backupFile,
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
|
||||
$scope.restoreLoading = true;
|
||||
if (response.data.restoreStatus == 1) {
|
||||
$scope.runningRestore = false;
|
||||
$scope.running = "Running";
|
||||
$scope.fileName = $scope.backupFile;
|
||||
$scope.status = "Just Started..";
|
||||
|
||||
getRestoreStatus();
|
||||
restoreBackupButton.disabled = false;
|
||||
} else {
|
||||
$scope.backupError = false;
|
||||
$scope.errorMessage = response.data.error_message;
|
||||
restoreBackupButton.disabled = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.couldNotConnect = false;
|
||||
restoreBackupButton.disabled = false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function createWebsite() {
|
||||
|
||||
var backupFile = $scope.backupFile;
|
||||
|
||||
url = "/websites/CreateWebsiteFromBackup";
|
||||
|
||||
var data = {
|
||||
backupFile: backupFile,
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
|
||||
if (response.data.createWebSiteStatus == 1) {
|
||||
getRestoreStatus();
|
||||
} else if (response.data.existsStatus == 1) {
|
||||
$scope.backupError = false;
|
||||
$scope.errorMessage = response.data.error_message;
|
||||
$scope.restoreButton = true;
|
||||
$scope.runningRestore = true;
|
||||
} else {
|
||||
$scope.websiteDomain = domainName;
|
||||
$scope.backupError = false;
|
||||
$scope.errorMessage = response.data.error_message;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.couldNotConnect = false;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
$scope.FetchOCSites = function () {
|
||||
$scope.restoreLoading = false;
|
||||
|
||||
// Current URL
|
||||
const currentURL = window.location.href;
|
||||
|
||||
// Create a URL object
|
||||
const urlN = new URL(currentURL);
|
||||
|
||||
// Get the value of the 'id' parameter
|
||||
const idValue = urlN.searchParams.get('id');
|
||||
|
||||
|
||||
url = "/backup/fetchOCSites";
|
||||
|
||||
var data = {
|
||||
idValue: idValue,
|
||||
folder: $scope.ocFolder
|
||||
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
|
||||
$scope.restoreLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
|
||||
$scope.backups = response.data.finalDirs;
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.couldNotConnect = false;
|
||||
restoreBackupButton.disabled = false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.StartOCRestore = function () {
|
||||
|
||||
$scope.restoreLoading = false;
|
||||
$scope.installationDetailsForm = true;
|
||||
$scope.installationProgress = false;
|
||||
$scope.errorMessageBox = true;
|
||||
$scope.success = true;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.goBackDisable = true;
|
||||
$scope.restoreLoading = false;
|
||||
|
||||
|
||||
$scope.currentStatus = "Starting creation..";
|
||||
|
||||
|
||||
// Current URL
|
||||
const currentURL = window.location.href;
|
||||
|
||||
// Create a URL object
|
||||
const urlN = new URL(currentURL);
|
||||
|
||||
// Get the value of the 'id' parameter
|
||||
const idValue = urlN.searchParams.get('id');
|
||||
|
||||
|
||||
//alert(domainNameCreate);
|
||||
var data = {
|
||||
|
||||
idValue: idValue,
|
||||
folder: $scope.ocFolder,
|
||||
backupfile: $scope.ocFile
|
||||
}
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
var url = "/backup/StartOCRestore";
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.restoreLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
statusFile = response.data.tempStatusPath;
|
||||
getCreationStatus();
|
||||
|
||||
} else {
|
||||
$scope.goBackDisable = false;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
|
||||
alert("Error..." + response)
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
$scope.goBack = function () {
|
||||
$scope.webSiteCreationLoading = true;
|
||||
$scope.installationDetailsForm = false;
|
||||
$scope.installationProgress = true;
|
||||
$scope.errorMessageBox = true;
|
||||
$scope.success = true;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.goBackDisable = true;
|
||||
$("#installProgress").css("width", "0%");
|
||||
};
|
||||
|
||||
function getCreationStatus() {
|
||||
|
||||
url = "/websites/installWordpressStatus";
|
||||
|
||||
var data = {
|
||||
statusFile: statusFile
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
|
||||
if (response.data.abort === 1) {
|
||||
|
||||
if (response.data.installStatus === 1) {
|
||||
|
||||
$scope.restoreLoading = true;
|
||||
$scope.installationDetailsForm = true;
|
||||
$scope.installationProgress = false;
|
||||
$scope.errorMessageBox = true;
|
||||
$scope.success = false;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.goBackDisable = false;
|
||||
|
||||
$("#installProgress").css("width", "100%");
|
||||
$scope.installPercentage = "100";
|
||||
$scope.currentStatus = response.data.currentStatus ;
|
||||
$timeout.cancel();
|
||||
|
||||
} else {
|
||||
|
||||
$scope.restoreLoading = true;
|
||||
$scope.installationDetailsForm = true;
|
||||
$scope.installationProgress = false;
|
||||
$scope.errorMessageBox = false;
|
||||
$scope.success = true;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.goBackDisable = false;
|
||||
|
||||
$scope.errorMessage = response.data.error_message;
|
||||
|
||||
$("#installProgress").css("width", "0%");
|
||||
$scope.installPercentage = "0";
|
||||
$scope.goBackDisable = false;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
$scope.restoreLoading = false;
|
||||
$("#installProgress").css("width", response.data.installationProgress + "%");
|
||||
$scope.installPercentage = response.data.installationProgress;
|
||||
$scope.currentStatus = response.data.currentStatus;
|
||||
$timeout(getCreationStatus, 1000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
|
||||
$scope.restoreLoading = true;
|
||||
$scope.installationDetailsForm = true;
|
||||
$scope.installationProgress = false;
|
||||
$scope.errorMessageBox = true;
|
||||
$scope.success = true;
|
||||
$scope.couldNotConnect = false;
|
||||
$scope.goBackDisable = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
309
backup/templates/backup/OneClickBackupSchedule.html
Executable file
309
backup/templates/backup/OneClickBackupSchedule.html
Executable file
@@ -0,0 +1,309 @@
|
||||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Schedule Backup - CyberPanel" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
<div ng-controller="scheduleBackup" class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Schedule Backup" %} - <a target="_blank"
|
||||
href="https://cyberpanel.net/KnowledgeBase/home/schedule-backups-local-or-sftp/"
|
||||
style="height: 23px;line-height: 21px; text-decoration: underline"
|
||||
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 schedule Backups to localhost or remote server (If you have added one)" %}</p>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Create New Backup Schedule" %} <img ng-hide="cyberPanelLoading"
|
||||
src="{% static 'images/loading.gif' %}"
|
||||
alt="cyberPanelLoading">
|
||||
</h3>
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
|
||||
<form action="/" class="form-horizontal bordered-row">
|
||||
|
||||
<div class="form-group" style="display: none">
|
||||
<label class="col-sm-3 control-label">{% trans "Name" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="selectedAccountAdd"
|
||||
ng-init="selectedAccountAdd='{{ destination }}'" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div 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 class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Select Backup Frequency" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-model="backupFrequency" class="form-control">
|
||||
<option>Never</option>
|
||||
<option>Daily</option>
|
||||
<option>Weekly</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Select Backup Retention. Leave 0 for no limit" %}</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="number">
|
||||
<label>
|
||||
<input ng-model="backupRetention" type="number" value="0">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-click="addSchedule()"
|
||||
class="btn btn-primary btn-lg btn-block">{% trans "Add Schedule" %}</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Manage Existing Backup Schedules" %} <img ng-hide="cyberPanelLoading"
|
||||
src="{% static 'images/loading.gif' %}"
|
||||
alt="cyberPanelLoading">
|
||||
</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 Destination" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="fetchJobs()" ng-model="selectedAccount" class="form-control">
|
||||
<option>{{ destination }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="jobsHidden" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Select Job" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="fetchWebsites()" ng-model="selectedJob" class="form-control">
|
||||
<option ng-repeat="job in jobs track by $index">{$ job $}</option>
|
||||
</select>
|
||||
</div>
|
||||
<button ng-hide="driveHidden" type="button" ng-click="deleteAccount()"
|
||||
class="btn btn-danger">{% trans "Delete" %}</button>
|
||||
</div>
|
||||
|
||||
<div ng-hide="driveHidden" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Add Sites for Backup" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-model="selectedWebsite" class="form-control">
|
||||
{% for items in websites %}
|
||||
<option>{{ items }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<button type="button" ng-click="addSite('one')"
|
||||
class="btn btn-primary">{% trans "Add Site" %}</button>
|
||||
<button type="button" ng-click="addSite('all')"
|
||||
class="btn btn-primary">{% trans "Add All" %}</button>
|
||||
</div>
|
||||
|
||||
<div ng-hide="driveHidden" class="form-group">
|
||||
<div style="border: 1px solid green;" class="col-sm-12">
|
||||
<table style="margin-top: 2%" class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Last Run</th>
|
||||
<th>All Sites</th>
|
||||
<th>Frequency ({$ currently $})</th>
|
||||
<th>Retention ({$ currently $})</th>
|
||||
<th>Current Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{$ lastRun $}</td>
|
||||
<td>{$ allSites $}</td>
|
||||
<td>
|
||||
<select ng-change="changeFrequency()" ng-model="backupFrequency"
|
||||
class="form-control">
|
||||
<option>Never</option>
|
||||
<option>Daily</option>
|
||||
<option>Weekly</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>{$ currentStatus $}</td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="border: 1px solid green;" ng-hide="driveHidden" class="form-group">
|
||||
<div class="row">
|
||||
<div style="margin-left: 2%" class="col-sm-3">
|
||||
<button data-toggle="modal" data-target="#backupLogs" ng-hide="driveHidden"
|
||||
type="button" ng-click="fetchLogs()"
|
||||
class="btn btn-gray">{% trans "View Logs" %}</button>
|
||||
<div id="backupLogs" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<!-- Modal content-->
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×
|
||||
</button>
|
||||
<h4 class="modal-title">{% trans "Backup logs" %} <img
|
||||
ng-hide="cyberPanelLoading"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-9">
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="form-group">
|
||||
<select ng-model="recordsToShowLogs"
|
||||
ng-change="fetchLogs()"
|
||||
class="form-control" id="example-select">
|
||||
<option>10</option>
|
||||
<option>50</option>
|
||||
<option>100</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table style="margin: 0px; padding-bottom: 2%" class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<th>Message</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="log in logs track by $index">
|
||||
<td ng-bind="log.type"></td>
|
||||
<td ng-bind="log.message"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="margin-top: 2%" class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<select ng-model="currentPageLogs"
|
||||
class="form-control"
|
||||
ng-change="fetchLogs()">
|
||||
<option ng-repeat="page in paginationLogs">
|
||||
{$
|
||||
$index + 1
|
||||
$}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end row -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="form-group">
|
||||
<select ng-model="recordsToShow"
|
||||
ng-change="fetchWebsites()"
|
||||
class="form-control" id="example-select">
|
||||
<option>10</option>
|
||||
<option>50</option>
|
||||
<option>100</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table style="margin-top: 2%" class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Sites</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="website in websites track by $index">
|
||||
<td ng-bind="website.name"></td>
|
||||
<td>
|
||||
<button type="button" ng-click="deleteSite(website.name)"
|
||||
class="btn btn-danger">{% trans "Delete" %}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="margin-top: 2%" class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<select ng-model="currentPage" class="form-control"
|
||||
ng-change="fetchWebsites()">
|
||||
<option ng-repeat="page in pagination">{$ $index + 1
|
||||
$}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end row -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -1,155 +1,167 @@
|
||||
|
||||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Backup Website" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Backup Website" %} - <a target="_blank" href="http://go.cyberpanel.net/backup" style="height: 23px;line-height: 21px;" class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>{% trans "Backup Docs" %}</span></a></h2>
|
||||
<p>{% trans "This page can be used to Backup your websites" %}</p>
|
||||
</div>
|
||||
|
||||
<div ng-controller="backupWebsiteControl" class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Backup Website" %} <img ng-hide="backupLoading" 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 Website" %} </label>
|
||||
<div class="col-sm-6">
|
||||
<select id="create-backup-select" ng-model="websiteToBeBacked" class="form-control">
|
||||
{% for items in websiteList %}
|
||||
<option>{{ items }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group destinationHide">
|
||||
<label class="col-sm-3 control-label">{% trans "Destination" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="destinationSelection()" ng-model="backupDestinations" class="form-control">
|
||||
<option>{% trans "Home" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!---- if Backup is running ----->
|
||||
|
||||
<div ng-hide="runningBackup" class="form-group">
|
||||
|
||||
<div class="col-sm-12">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>{% trans "File Name" %}</th>
|
||||
<th>{% trans "Status" %} <img ng-hide="backupLoadingBottom" src="{% static 'images/loading.gif' %}"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{% trans "Running" %}</td>
|
||||
<td>{$ fileName $}</td>
|
||||
<td style="color: red"><strong>{$ status $}</strong></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!---- if Backup is running------>
|
||||
|
||||
<div class="form-group destinationHide">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-click="createBackup()" id="createBackup" class="btn btn-primary btn-lg btn-block">{% trans "Create Backup" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="cancelButton" class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-click="cancelBackup()" class="btn btn-primary btn-lg btn-block">{% trans "Cancel Backup" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!------ List of records --------------->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<div class="col-sm-12">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "ID" %}</th>
|
||||
<th>{% trans "File" %}</th>
|
||||
<th>{% trans "Date" %}</th>
|
||||
<th>{% trans "Size" %}</th>
|
||||
<th>{% trans "Status" %}</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.file"></td>
|
||||
<td ng-bind="record.date"></td>
|
||||
<td ng-bind="record.size"></td>
|
||||
<td ng-bind="record.status"></td>
|
||||
<a href=""><td ng-click="deleteBackup(record.id)"><img src="{% static 'images/delete.png' %}"></td></a>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!------ List of records --------------->
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<div id="websiteDeleteFailure" class="alert alert-danger">
|
||||
<p>{% trans "Cannot delete website, Error message: " %}{$ errorMessage $}</p>
|
||||
</div>
|
||||
|
||||
<div id="websiteDeleteSuccess" class="alert alert-success">
|
||||
<p>Website <strong>{$ deletedWebsite $}</strong> {% trans "Successfully Deleted" %}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
{% load static %}
|
||||
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Backup Website" %} - <a target="_blank" href="http://go.cyberpanel.net/backup"
|
||||
style="height: 23px;line-height: 21px;"
|
||||
class="btn btn-border btn-alt border-red btn-link font-red"
|
||||
title=""><span>{% trans "Backup Docs" %}</span></a></h2>
|
||||
<p>{% trans "This page can be used to Backup your websites" %}</p>
|
||||
</div>
|
||||
|
||||
<div ng-controller="backupWebsiteControl" class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Backup Website" %} <img ng-hide="backupLoading" src="{% static 'images/loading.gif' %}">
|
||||
</h3>
|
||||
<div class="alert alert-warning">
|
||||
<p>Configure automatic backups to our secure servers in 60 seconds. <a
|
||||
href="/backup/OneClickBackups">Set-up now.</a></p>
|
||||
</div>
|
||||
<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 Website" %} </label>
|
||||
<div class="col-sm-6">
|
||||
<select id="create-backup-select" ng-model="websiteToBeBacked" class="form-control">
|
||||
{% for items in websiteList %}
|
||||
<option>{{ items }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group destinationHide">
|
||||
<label class="col-sm-3 control-label">{% trans "Destination" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="destinationSelection()" ng-model="backupDestinations"
|
||||
class="form-control">
|
||||
<option>{% trans "Home" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!---- if Backup is running ----->
|
||||
|
||||
<div ng-hide="runningBackup" class="form-group">
|
||||
|
||||
<div class="col-sm-12">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>{% trans "File Name" %}</th>
|
||||
<th>{% trans "Status" %} <img ng-hide="backupLoadingBottom"
|
||||
src="{% static 'images/loading.gif' %}"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{% trans "Running" %}</td>
|
||||
<td>{$ fileName $}</td>
|
||||
<td style="color: red"><strong>{$ status $}</strong></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!---- if Backup is running------>
|
||||
|
||||
<div class="form-group destinationHide">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-click="createBackup()" id="createBackup"
|
||||
class="btn btn-primary btn-lg btn-block">{% trans "Create Backup" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="cancelButton" class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-click="cancelBackup()"
|
||||
class="btn btn-primary btn-lg btn-block">{% trans "Cancel Backup" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!------ List of records --------------->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<div class="col-sm-12">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "ID" %}</th>
|
||||
<th>{% trans "File" %}</th>
|
||||
<th>{% trans "Date" %}</th>
|
||||
<th>{% trans "Size" %}</th>
|
||||
<th>{% trans "Status" %}</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.file"></td>
|
||||
<td ng-bind="record.date"></td>
|
||||
<td ng-bind="record.size"></td>
|
||||
<td ng-bind="record.status"></td>
|
||||
<a href="">
|
||||
<td ng-click="deleteBackup(record.id)"><img
|
||||
src="{% static 'images/delete.png' %}"></td>
|
||||
</a>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!------ List of records --------------->
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<div id="websiteDeleteFailure" class="alert alert-danger">
|
||||
<p>{% trans "Cannot delete website, Error message: " %}{$ errorMessage $}</p>
|
||||
</div>
|
||||
|
||||
<div id="websiteDeleteSuccess" class="alert alert-success">
|
||||
<p>Website <strong>{$ deletedWebsite $}</strong> {% trans "Successfully Deleted" %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -12,10 +12,10 @@
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Set up Backup Destinations" %} - <a target="_blank"
|
||||
href="https://cyberpanel.net/KnowledgeBase/home/add-destination-scheduled-local-sftp-remote-backups/"
|
||||
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>
|
||||
href="https://cyberpanel.net/KnowledgeBase/home/add-destination-scheduled-local-sftp-remote-backups/"
|
||||
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 Backup destinations. (SFTP)" %}</p>
|
||||
</div>
|
||||
@@ -24,8 +24,12 @@
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Set up Backup Destinations." %} <img ng-hide="cyberpanelLoading"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
</h3>
|
||||
<div class="alert alert-warning">
|
||||
<p>Configure automatic backups to our secure servers in 60 seconds. <a
|
||||
href="/backup/OneClickBackups">Set-up now.</a></p>
|
||||
</div>
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
|
||||
@@ -82,7 +86,8 @@
|
||||
<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>
|
||||
<input placeholder="Path on remote server to store backups." type="text"
|
||||
class="form-control" ng-model="path" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -122,7 +127,8 @@
|
||||
<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 ng-click="removeDestination('SFTP', record.name)"><img
|
||||
src="{% static 'images/delete.png' %}">
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
@@ -164,8 +170,6 @@
|
||||
<!--- SFTP --->
|
||||
|
||||
|
||||
|
||||
|
||||
<!------ List of Destinations --------------->
|
||||
|
||||
<div ng-hide="localHide" class="form-group">
|
||||
@@ -184,7 +188,8 @@
|
||||
<tr ng-repeat="record in records track by $index">
|
||||
<td ng-bind="record.name"></td>
|
||||
<td ng-bind="record.path"></td>
|
||||
<td ng-click="removeDestination('local', record.name)"><img src="{% static 'images/delete.png' %}">
|
||||
<td ng-click="removeDestination('local', record.name)"><img
|
||||
src="{% static 'images/delete.png' %}">
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
172
backup/templates/backup/oneClickBackups.html
Executable file
172
backup/templates/backup/oneClickBackups.html
Executable file
@@ -0,0 +1,172 @@
|
||||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "One-click Backups" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "One-click Backups" %} - <a target="_blank"
|
||||
href="https://cyberpanel.net/KnowledgeBase/home/add-destination-scheduled-local-sftp-remote-backups/"
|
||||
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 purchase and manage one-click backups." %}</p>
|
||||
</div>
|
||||
|
||||
<div ng-controller="backupPlanNowOneClick" class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Set up Backup Destinations." %} <img ng-hide="cyberpanelLoading"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
</h3>
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
{% if status == 1 %}
|
||||
<div class="alert alert-info">
|
||||
<p>You have successfully purchased a backup plan.</p>
|
||||
</div>
|
||||
{% elif status == 0 %}
|
||||
|
||||
<div class="alert alert-danger">
|
||||
<p>Your purchase was not successful.</p> {{ message }}
|
||||
</div>
|
||||
{% elif status == 4 %}
|
||||
|
||||
<div class="alert alert-danger">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form action="/" class="form-horizontal bordered-row">
|
||||
|
||||
<p style="font-size: 15px;margin: 1%;">With CyberPanel's one-click backups, you can easily back up your website to our secure
|
||||
servers in just 60 seconds. It's simple, fast, and reliable.</p>
|
||||
|
||||
|
||||
<!------ List of Purchased backup plans --------------->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<div class="col-sm-12">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Account" %}</th>
|
||||
<th>{% trans "Plan Name" %}</th>
|
||||
<th>{% trans "Subscription" %}</th>
|
||||
<th>{% trans "Billing Cycle" %}</th>
|
||||
<th>{% trans "Purchase Date" %}</th>
|
||||
<th>{% trans "Actions" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for plan in bPlans %}
|
||||
<tr>
|
||||
<td>{{ plan.sftpUser }}</td>
|
||||
<td>{{ plan.planName }}</td>
|
||||
<td>{{ plan.subscription }}</td>
|
||||
{% if plan.months == '1' %}
|
||||
<td>${{ plan.price }}/month</td>
|
||||
{% else %}
|
||||
<td>${{ plan.price }}/year</td>
|
||||
{% endif %}
|
||||
<td>{{ plan.date }}</td>
|
||||
<td>
|
||||
{% if plan.state == 1 %}
|
||||
<a
|
||||
href="{% url 'ManageOCBackups' %}?id={{ plan.id }}">
|
||||
<button style="margin-bottom: 1%" type="button"
|
||||
class="btn btn-primary btn-lg btn-block">{% trans "Schedule Backups" %}</button>
|
||||
</a>
|
||||
<a href="{% url 'RestoreOCBackups' %}?id={{ plan.id }}">
|
||||
<button type="button"
|
||||
class="btn btn-primary btn-lg btn-block">{% trans "Restore Backups" %}</button>
|
||||
</a>
|
||||
{% else %}
|
||||
<button type="button"
|
||||
ng-click="DeployAccount('{{ plan.id }}')"
|
||||
class="btn btn-primary btn-lg btn-block">{% trans "Deploy Account" %}</button>
|
||||
{% endif %}
|
||||
|
||||
</td>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!------ List of Purchased backup plans --------------->
|
||||
|
||||
|
||||
<!------ List of Backup plans --------------->
|
||||
|
||||
<h3 class="title-hero">
|
||||
{% trans "Subscribe to one-click backup plans." %} <img ng-hide="cyberpanelLoading"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
</h3>
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<div class="col-sm-12">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Plan Name" %}</th>
|
||||
<th>{% trans "Monthly Price" %}</th>
|
||||
<th>{% trans "Yearly Price" %}</th>
|
||||
<th>{% trans "Actions" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for plan in plans %}
|
||||
<tr>
|
||||
<td>{{ plan.name }}</td>
|
||||
<td>${{ plan.monthlyPrice }}</td>
|
||||
<td>${{ plan.yearlyPrice }}</td>
|
||||
<td>
|
||||
<button type="button"
|
||||
ng-click="BuyNowBackupP('{{ plan.name }}', '{{ plan.monthlyPrice }}', '{{ plan.yearlyPrice }}', 1)"
|
||||
class="btn btn-primary btn-lg btn-block">{% trans "Buy Monthly" %}</button>
|
||||
<button type="button"
|
||||
ng-click="BuyNowBackupP('{{ plan.name }}', '{{ plan.monthlyPrice }}', '{{ plan.yearlyPrice }}', 12)"
|
||||
class="btn btn-primary btn-lg btn-block">{% trans "Buy Yearly" %}</button>
|
||||
</td>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!------ List of backup plans --------------->
|
||||
|
||||
|
||||
<!--- AWS End --->
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
114
backup/templates/backup/restoreOCBackups.html
Executable file
114
backup/templates/backup/restoreOCBackups.html
Executable file
@@ -0,0 +1,114 @@
|
||||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Restore Website - CyberPanel" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Restore Website" %} - <a target="_blank" href="http://go.cyberpanel.net/backup"
|
||||
style="height: 23px;line-height: 21px;"
|
||||
class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>{% trans "Backup Docs" %}</span></a>
|
||||
</h2>
|
||||
<p>{% trans "This page can be used to restore your websites, Backup should be generated from CyberPanel Backup generation tool, it will detect all Backups under <strong>/home/backup</strong>." %}</p>
|
||||
</div>
|
||||
|
||||
<div ng-controller="OneClickrestoreWebsiteControl" class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Restore Website" %} <img ng-hide="restoreLoading" 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 Folder" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="FetchOCSites()" ng-model="ocFolder" class="form-control">
|
||||
{% for items in directories %}
|
||||
<option>{{ items }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Select Backup" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-model="ocFile" class="form-control">
|
||||
<option ng-repeat="item in backups">{$ item $}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-click="StartOCRestore()"
|
||||
class="btn btn-primary btn-lg">{% trans "Restore Backup" %}</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="installationProgress" class="form-group">
|
||||
<label class="col-sm-2 control-label"></label>
|
||||
<div class="col-sm-7">
|
||||
|
||||
<div class="alert alert-success text-center">
|
||||
<h2>{$ currentStatus $}</h2>
|
||||
</div>
|
||||
|
||||
<div class="progress">
|
||||
<div id="installProgress" class="progress-bar" role="progressbar" aria-valuenow="70"
|
||||
aria-valuemin="0" aria-valuemax="100" style="width:0%">
|
||||
<span class="sr-only">70% Complete</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="errorMessageBox" class="alert alert-danger">
|
||||
<p>{% trans "Error message:" %} {$ errorMessage $}</p>
|
||||
</div>
|
||||
|
||||
<div ng-hide="success" class="alert alert-success">
|
||||
<p>{% trans "Backup restored successfully." %}</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 ng-hide="installationProgress" class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-disabled="goBackDisable" ng-click="goBack()"
|
||||
class="btn btn-primary btn-lg">{% trans "Go Back" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -4,6 +4,13 @@ from . import views
|
||||
urlpatterns = [
|
||||
url(r'^$', views.loadBackupHome, name='loadBackupHome'),
|
||||
url(r'^getCurrentBackups', views.getCurrentBackups, name='getCurrentBackups'),
|
||||
url(r'^OneClickBackups', views.OneClickBackups, name='OneClickBackups'),
|
||||
url(r'^ManageOCBackups', views.ManageOCBackups, name='ManageOCBackups'),
|
||||
url(r'^RestoreOCBackups', views.RestoreOCBackups, name='RestoreOCBackups'),
|
||||
url(r'^fetchOCSites', views.fetchOCSites, name='fetchOCSites'),
|
||||
url(r'^StartOCRestore', views.StartOCRestore, name='StartOCRestore'),
|
||||
url(r'^DeployAccount', views.DeployAccount, name='DeployAccount'),
|
||||
|
||||
url(r'^backupSite', views.backupSite, name='backupSite'),
|
||||
url(r'^restoreSite', views.restoreSite, name='restoreSite'),
|
||||
url(r'^gDrive$', views.gDrive, name='gDrive'),
|
||||
@@ -16,7 +23,6 @@ urlpatterns = [
|
||||
url(r'^deleteSitegDrive$', views.deleteSitegDrive, name='deleteSitegDrive'),
|
||||
url(r'^fetchDriveLogs$', views.fetchDriveLogs, name='fetchDriveLogs'),
|
||||
|
||||
|
||||
url(r'^submitBackupCreation', views.submitBackupCreation, name='submitBackupCreation'),
|
||||
url(r'^cancelBackupCreation', views.cancelBackupCreation, name='cancelBackupCreation'),
|
||||
url(r'^backupStatus', views.backupStatus, name='backupStatus'),
|
||||
@@ -42,10 +48,8 @@ urlpatterns = [
|
||||
|
||||
url(r'^submitBackupSchedule', views.submitBackupSchedule, name='submitBackupSchedule'),
|
||||
|
||||
|
||||
url(r'^scheduleDelete', views.scheduleDelete, name='scheduleDelete'),
|
||||
|
||||
|
||||
url(r'^remoteBackups', views.remoteBackups, name='remoteBackups'),
|
||||
url(r'^submitRemoteBackups', views.submitRemoteBackups, name='submitRemoteBackups'),
|
||||
url(r'^getRemoteTransferStatus', views.getRemoteTransferStatus, name='getRemoteTransferStatus'),
|
||||
@@ -67,4 +71,4 @@ urlpatterns = [
|
||||
url(r'^deleteAccountNormal$', views.deleteAccountNormal, name='deleteAccountNormal'),
|
||||
url(r'^fetchNormalLogs$', views.fetchNormalLogs, name='fetchNormalLogs'),
|
||||
|
||||
]
|
||||
]
|
||||
|
||||
@@ -481,5 +481,56 @@ def fetchNormalLogs(request):
|
||||
userID = request.session['userID']
|
||||
wm = BackupManager()
|
||||
return wm.fetchNormalLogs(request, userID)
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
|
||||
def OneClickBackups(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
bm = BackupManager()
|
||||
return bm.OneClickBackups(request, userID)
|
||||
except KeyError:
|
||||
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def ManageOCBackups(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
bm = BackupManager()
|
||||
return bm.ManageOCBackups(request, userID)
|
||||
except KeyError:
|
||||
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def RestoreOCBackups(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
bm = BackupManager()
|
||||
return bm.RestoreOCBackups(request, userID)
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def fetchOCSites(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
bm = BackupManager()
|
||||
return bm.fetchOCSites(request, userID)
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def StartOCRestore(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
bm = BackupManager()
|
||||
return bm.StartOCRestore(request, userID)
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def DeployAccount(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
bm = BackupManager()
|
||||
return bm.DeployAccount(request, userID)
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
@@ -77,7 +77,7 @@
|
||||
|
||||
<!-- HELPERS -->
|
||||
|
||||
{% with version="2.3.5.4" %}
|
||||
{% with version="2.3.5.6" %}
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'baseTemplate/assets/finalBase/finalBase.css' %}">
|
||||
|
||||
@@ -690,6 +690,11 @@
|
||||
<div class="sidebar-submenu">
|
||||
|
||||
<ul>
|
||||
{% if admin or createBackup %}
|
||||
<li><a href="{% url 'OneClickBackups' %}"
|
||||
title="{% trans 'One-Click Backups' %}"><span>{% trans "One-Click Backups" %}</span></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if admin or createBackup %}
|
||||
<li><a href="{% url 'backupSite' %}"
|
||||
title="{% trans 'Create Backup' %}"><span>{% trans "Create Backup" %}</span></a>
|
||||
@@ -947,9 +952,9 @@
|
||||
<li><a href="{% url 'packageManager' %}"
|
||||
title="{% trans 'Package Manager' %}"><span>{% trans "Package Manager" %}</span></a>
|
||||
</li>
|
||||
{# <li><a href="{% url 'Switchoffsecurity' %}"#}
|
||||
{# title="{% trans 'Switch off security' %}"><span>{% trans "Switch off security" %}</span></a>#}
|
||||
{# </li>#}
|
||||
{# <li><a href="{% url 'Switchoffsecurity' %}"#}
|
||||
{# title="{% trans 'Switch off security' %}"><span>{% trans "Switch off security" %}</span></a>#}
|
||||
{# </li>#}
|
||||
</ul>
|
||||
|
||||
</div><!-- .sidebar-submenu -->
|
||||
@@ -1149,6 +1154,12 @@
|
||||
href="/base/onboarding">Setup Wizard.</a></p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if backupDisplay == 1 %}
|
||||
<div class="alert alert-warning">
|
||||
<p>Looks like your websites are not secured with automatic backups. <a
|
||||
href="/backup/OneClickBackups">Configure now.</a></p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@@ -652,8 +652,18 @@ Automatic backup failed for %s on %s.
|
||||
except BaseException as msg:
|
||||
NormalBackupJobLogs(owner=backupjob, status=backupSchedule.INFO,
|
||||
message=f'Failed to make sftp connection {str(msg)}').save()
|
||||
|
||||
print(str(msg))
|
||||
continue
|
||||
|
||||
try:
|
||||
|
||||
command = f'find cpbackups -type f -mtime +{destinationConfig["retention"]} -exec rm -f {{}} \\;'
|
||||
ssh.exec_command(command)
|
||||
logging.writeToFile(command)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Execute the command to create the remote directory
|
||||
command = f'mkdir -p {finalPath}'
|
||||
stdin, stdout, stderr = ssh.exec_command(command)
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
#!/usr/local/CyberCP/bin/python
|
||||
import argparse
|
||||
import json
|
||||
import os, sys
|
||||
import shutil
|
||||
import time
|
||||
from io import StringIO
|
||||
|
||||
import paramiko
|
||||
|
||||
from ApachController.ApacheVhosts import ApacheVhost
|
||||
from loginSystem.models import Administrator
|
||||
@@ -18,7 +22,7 @@ import threading as multi
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
import subprocess
|
||||
from websiteFunctions.models import ChildDomains, Websites, WPSites, WPStaging, wpplugins, WPSitesBackup, \
|
||||
RemoteBackupConfig
|
||||
RemoteBackupConfig, NormalBackupDests
|
||||
from plogical import randomPassword
|
||||
from plogical.mysqlUtilities import mysqlUtilities
|
||||
from databases.models import Databases
|
||||
@@ -86,6 +90,8 @@ class ApplicationInstaller(multi.Thread):
|
||||
self.RestoreWPbackupNow()
|
||||
elif self.installApp == 'UpgradeCP':
|
||||
self.UpgradeCP()
|
||||
elif self.installApp == 'StartOCRestore':
|
||||
self.StartOCRestore()
|
||||
|
||||
except BaseException as msg:
|
||||
logging.writeToFile(str(msg) + ' [ApplicationInstaller.run]')
|
||||
@@ -6358,6 +6364,99 @@ class ApplicationInstaller(multi.Thread):
|
||||
logging.statusWriter(self.tempStatusPath, str(msg))
|
||||
return 0, str(msg)
|
||||
|
||||
def StartOCRestore(self):
|
||||
try:
|
||||
|
||||
id = self.extraArgs['id']
|
||||
folder = self.extraArgs['folder']
|
||||
backupfile = self.extraArgs['backupfile']
|
||||
tempStatusPath = self.extraArgs['tempStatusPath']
|
||||
userID = self.extraArgs['userID']
|
||||
self.tempStatusPath = tempStatusPath
|
||||
|
||||
statusFile = open(tempStatusPath, 'w')
|
||||
statusFile.writelines("Download started..,30")
|
||||
statusFile.close()
|
||||
|
||||
from IncBackups.models import OneClickBackups
|
||||
ocb = OneClickBackups.objects.get(pk=id)
|
||||
|
||||
# Load the private key
|
||||
|
||||
nbd = NormalBackupDests.objects.get(name=ocb.sftpUser)
|
||||
ip = json.loads(nbd.config)['ip']
|
||||
|
||||
# Connect to the remote server using the private key
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
# Read the private key content
|
||||
private_key_path = '/root/.ssh/cyberpanel'
|
||||
key_content = ProcessUtilities.outputExecutioner(f'cat {private_key_path}').rstrip('\n')
|
||||
|
||||
# Load the private key from the content
|
||||
key_file = StringIO(key_content)
|
||||
key = paramiko.RSAKey.from_private_key(key_file)
|
||||
# Connect to the server using the private key
|
||||
ssh.connect(ip, username=ocb.sftpUser, pkey=key)
|
||||
sftp = ssh.open_sftp()
|
||||
|
||||
sftp.get(f'cpbackups/{folder}/{backupfile}', f'/home/cyberpanel/{backupfile}')
|
||||
|
||||
if not os.path.exists('/home/backup'):
|
||||
command = 'mkdir /home/backup'
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
command = f'mv /home/cyberpanel/{backupfile} /home/backup/{backupfile}'
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
from backup.backupManager import BackupManager
|
||||
wm = BackupManager()
|
||||
resp = wm.submitRestore({'backupFile': backupfile}, userID)
|
||||
|
||||
if json.loads(resp.content)['restoreStatus'] == 0:
|
||||
statusFile = open(tempStatusPath, 'w')
|
||||
statusFile.writelines(f"Failed to restore backup. Error {json.loads(resp.content)['error_message']}. [404]")
|
||||
statusFile.close()
|
||||
|
||||
command = f'rm -f /home/backup/{backupfile}'
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
return 0
|
||||
|
||||
while True:
|
||||
resp = wm.restoreStatus({'backupFile': backupfile})
|
||||
resp = json.loads(resp.content)
|
||||
|
||||
if resp['abort'] == 1 and resp['running'] == 'Completed':
|
||||
statusFile = open(tempStatusPath, 'w')
|
||||
statusFile.writelines("Successfully Installed. [200]")
|
||||
statusFile.close()
|
||||
command = f'rm -f /home/backup/{backupfile}'
|
||||
ProcessUtilities.executioner(command)
|
||||
return 0
|
||||
elif resp['abort'] == 1 and resp['running'] == 'Error':
|
||||
statusFile = open(tempStatusPath, 'w')
|
||||
statusFile.writelines(
|
||||
f"Failed to restore backup. Error {resp['status']}. [404]")
|
||||
statusFile.close()
|
||||
command = f'rm -f /home/backup/{backupfile}'
|
||||
ProcessUtilities.executioner(command)
|
||||
break
|
||||
else:
|
||||
statusFile = open(tempStatusPath, 'w')
|
||||
statusFile.writelines(f"{resp['status']},60")
|
||||
statusFile.close()
|
||||
command = f'rm -f /home/backup/{backupfile}'
|
||||
ProcessUtilities.executioner(command)
|
||||
time.sleep(3)
|
||||
|
||||
except BaseException as msg:
|
||||
|
||||
statusFile = open(self.tempStatusPath, 'w')
|
||||
statusFile.writelines(str(msg) + " [404]")
|
||||
statusFile.close()
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='CyberPanel Application Installer')
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
@@ -41,7 +42,7 @@ from random import randint
|
||||
from plogical.processUtilities import ProcessUtilities
|
||||
|
||||
try:
|
||||
from websiteFunctions.models import Websites, ChildDomains, Backups
|
||||
from websiteFunctions.models import Websites, ChildDomains, Backups, NormalBackupDests
|
||||
from databases.models import Databases
|
||||
from loginSystem.models import Administrator
|
||||
from plogical.dnsUtilities import DNS
|
||||
@@ -1329,35 +1330,48 @@ class backupUtilities:
|
||||
try:
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(IPAddress, port=int(port), username=user, password=password)
|
||||
if password != 'NOT-NEEDED':
|
||||
|
||||
commands = [
|
||||
"mkdir -p .ssh",
|
||||
"rm -f .ssh/temp",
|
||||
"rm -f .ssh/authorized_temp",
|
||||
"cp .ssh/authorized_keys .ssh/temp",
|
||||
"chmod 700 .ssh",
|
||||
"chmod g-w ~",
|
||||
]
|
||||
ssh.connect(IPAddress, port=int(port), username=user, password=password)
|
||||
commands = [
|
||||
"mkdir -p .ssh",
|
||||
"rm -f .ssh/temp",
|
||||
"rm -f .ssh/authorized_temp",
|
||||
"cp .ssh/authorized_keys .ssh/temp",
|
||||
"chmod 700 .ssh",
|
||||
"chmod g-w ~",
|
||||
]
|
||||
|
||||
for command in commands:
|
||||
try:
|
||||
ssh.exec_command(command)
|
||||
except BaseException as msg:
|
||||
logging.CyberCPLogFileWriter.writeToFile(f'Error executing remote command {command}. Error {str(msg)}')
|
||||
for command in commands:
|
||||
try:
|
||||
ssh.exec_command(command)
|
||||
except BaseException as msg:
|
||||
logging.CyberCPLogFileWriter.writeToFile(
|
||||
f'Error executing remote command {command}. Error {str(msg)}')
|
||||
|
||||
ssh.close()
|
||||
ssh.close()
|
||||
|
||||
sendKey = backupUtilities.sendKey(IPAddress, password, port, user)
|
||||
sendKey = backupUtilities.sendKey(IPAddress, password, port, user)
|
||||
|
||||
if sendKey[0] == 1:
|
||||
command = 'chmod 644 %s' % ('/root/.ssh/cyberpanel.pub')
|
||||
ProcessUtilities.executioner(command)
|
||||
return [1, "None"]
|
||||
if sendKey[0] == 1:
|
||||
command = 'chmod 644 %s' % ('/root/.ssh/cyberpanel.pub')
|
||||
ProcessUtilities.executioner(command)
|
||||
return [1, "None"]
|
||||
else:
|
||||
command = 'chmod 644 %s' % ('/root/.ssh/cyberpanel.pub')
|
||||
ProcessUtilities.executioner(command)
|
||||
return [0, sendKey[1]]
|
||||
else:
|
||||
command = 'chmod 644 %s' % ('/root/.ssh/cyberpanel.pub')
|
||||
ProcessUtilities.executioner(command)
|
||||
return [0, sendKey[1]]
|
||||
# Load the private key
|
||||
private_key_path = '/root/.ssh/cyberpanel'
|
||||
keyPrivate = paramiko.RSAKey(filename=private_key_path)
|
||||
|
||||
# Connect to the remote server using the private key
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(IPAddress, username=user, pkey=keyPrivate)
|
||||
|
||||
return [1, "None"]
|
||||
|
||||
except paramiko.AuthenticationException:
|
||||
return [0, 'Authentication failed. [setupSSHKeys]']
|
||||
@@ -2345,6 +2359,37 @@ def getConnectionStatus(ipAddress):
|
||||
except BaseException as msg:
|
||||
print(str(msg))
|
||||
|
||||
def FetchOCBackupsFolders(id, owner):
|
||||
# Load the private key
|
||||
private_key_path = '/root/.ssh/cyberpanel'
|
||||
keyPrivate = paramiko.RSAKey(filename=private_key_path)
|
||||
|
||||
from IncBackups.models import OneClickBackups
|
||||
admin = Administrator.objects.get(userName=owner)
|
||||
ocb = OneClickBackups.objects.get(pk=id, owner=admin)
|
||||
|
||||
nbd = NormalBackupDests.objects.get(name=ocb.sftpUser)
|
||||
ip = json.loads(nbd.config)['ip']
|
||||
|
||||
# Connect to the remote server using the private key
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(ip, username=ocb.sftpUser, pkey=keyPrivate)
|
||||
|
||||
# Command to list directories under the specified path
|
||||
command = f"ls -d cpbackups/*/"
|
||||
|
||||
# Execute the command
|
||||
stdin, stdout, stderr = ssh.exec_command(command)
|
||||
|
||||
# Read the results
|
||||
directories = stdout.read().decode().splitlines()
|
||||
|
||||
# Print directories
|
||||
for directory in directories:
|
||||
print(directory)
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='CyberPanel Backup Generator')
|
||||
@@ -2391,6 +2436,10 @@ def main():
|
||||
|
||||
parser.add_argument('--CPHomeStorage', help='')
|
||||
|
||||
### id
|
||||
|
||||
parser.add_argument('--id', help='')
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -2439,5 +2488,8 @@ def main():
|
||||
bu = backupUtilities(extraArgs)
|
||||
bu.SubmitS3BackupRestore()
|
||||
|
||||
elif args.function == 'FetchOCBackupsFolders':
|
||||
FetchOCBackupsFolders(args.id, args.user)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -77,6 +77,13 @@ Please launch the <a href="/base/onboarding">set-up wizard</a> to get maximum ou
|
||||
except:
|
||||
pass
|
||||
|
||||
from IncBackups.models import OneClickBackups
|
||||
if OneClickBackups.objects.filter(owner=admin).count() == 0:
|
||||
self.data['backupDisplay'] = 1
|
||||
else:
|
||||
self.data['backupDisplay'] = 0
|
||||
|
||||
|
||||
ACLManager.GetServiceStatus(self.data)
|
||||
|
||||
self.data.update(currentACL)
|
||||
|
||||
Reference in New Issue
Block a user