2023-02-12 22:31:41 +05:00
|
|
|
import argparse
|
2023-02-11 21:27:06 +05:00
|
|
|
import json
|
2023-02-11 11:27:09 +05:00
|
|
|
import os
|
|
|
|
|
import sys
|
2023-02-12 13:15:41 +05:00
|
|
|
import time
|
2023-02-11 11:27:09 +05:00
|
|
|
|
|
|
|
|
sys.path.append('/usr/local/CyberCP')
|
|
|
|
|
import django
|
|
|
|
|
|
|
|
|
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
|
|
|
|
|
try:
|
|
|
|
|
django.setup()
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
|
2023-02-12 22:31:41 +05:00
|
|
|
from plogical.processUtilities import ProcessUtilities
|
|
|
|
|
|
2023-02-11 11:27:09 +05:00
|
|
|
|
|
|
|
|
class CPBackupsV2:
|
2023-02-12 13:15:41 +05:00
|
|
|
PENDING_START = 0
|
|
|
|
|
RUNNING = 1
|
|
|
|
|
COMPLETED = 2
|
|
|
|
|
FAILED = 3
|
|
|
|
|
|
2023-02-11 11:27:09 +05:00
|
|
|
def __init__(self, data):
|
|
|
|
|
self.data = data
|
|
|
|
|
pass
|
|
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
@staticmethod
|
|
|
|
|
def FetchCurrentTimeStamp():
|
|
|
|
|
import time
|
|
|
|
|
return str(time.time())
|
|
|
|
|
|
|
|
|
|
def UpdateStatus(self, message, status):
|
2023-02-12 22:31:41 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
from websiteFunctions.models import Backupsv2, BackupsLogsv2
|
|
|
|
|
self.buv2 = Backupsv2.objects.get(fileName=self.buv2.fileName)
|
|
|
|
|
self.buv2.status = status
|
|
|
|
|
self.buv2.save()
|
|
|
|
|
|
2023-02-12 22:31:41 +05:00
|
|
|
BackupsLogsv2(message=message, owner=self.buv2).save()
|
2023-02-12 13:15:41 +05:00
|
|
|
|
|
|
|
|
if status == CPBackupsV2.FAILED:
|
|
|
|
|
self.buv2.website.BackupLock = 0
|
|
|
|
|
self.buv2.website.save()
|
|
|
|
|
elif status == CPBackupsV2.COMPLETED:
|
|
|
|
|
self.buv2.website.BackupLock = 0
|
|
|
|
|
self.buv2.website.save()
|
|
|
|
|
|
2023-02-11 11:27:09 +05:00
|
|
|
def InitiateBackup(self):
|
2023-02-11 21:27:06 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
from websiteFunctions.models import Websites, Backupsv2
|
2023-02-11 11:27:09 +05:00
|
|
|
from django.forms.models import model_to_dict
|
|
|
|
|
from plogical.mysqlUtilities import mysqlUtilities
|
2023-02-13 15:11:05 +05:00
|
|
|
self.website = Websites.objects.get(domain=self.data['domain'])
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-12 22:31:41 +05:00
|
|
|
if not os.path.exists(self.data['BasePath']):
|
|
|
|
|
command = f"mkdir -p {self.data['BasePath']}"
|
|
|
|
|
ProcessUtilities.executioner(command)
|
|
|
|
|
|
|
|
|
|
command = f"chmod 711 {self.data['BasePath']}"
|
|
|
|
|
ProcessUtilities.executioner(command)
|
|
|
|
|
|
2023-02-14 10:06:09 +05:00
|
|
|
self.StartingTimeStamp = CPBackupsV2.FetchCurrentTimeStamp()
|
2023-02-12 22:31:41 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
while(1):
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-14 10:12:29 +05:00
|
|
|
self.website = Websites.objects.get(domain=self.data['domain'])
|
|
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
if self.website.BackupLock == 0:
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
self.website.BackupLock = 1
|
|
|
|
|
self.website.save()
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
self.buv2 = Backupsv2(website=self.website, fileName='backup-' + self.data['domain'] + "-" + time.strftime("%m.%d.%Y_%H-%M-%S"), status=CPBackupsV2.RUNNING, BasePath=self.data['BasePath'])
|
2023-02-12 13:15:41 +05:00
|
|
|
self.buv2.save()
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
self.FinalPath = f"{self.data['BasePath']}/{self.buv2.fileName}"
|
2023-02-12 22:31:41 +05:00
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
command = f"mkdir -p {self.FinalPath}"
|
2023-02-12 22:31:41 +05:00
|
|
|
ProcessUtilities.executioner(command)
|
|
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
#command = f"chown {website.externalApp}:{website.externalApp} {self.FinalPath}"
|
|
|
|
|
#ProcessUtilities.executioner(command)
|
|
|
|
|
|
|
|
|
|
command = f'chown cyberpanel:cyberpanel {self.FinalPath}'
|
2023-02-12 22:31:41 +05:00
|
|
|
ProcessUtilities.executioner(command)
|
|
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
command = f"chmod 711 {self.FinalPath}"
|
|
|
|
|
ProcessUtilities.executioner(command, self.website.externalApp)
|
2023-02-12 22:31:41 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
try:
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-12 22:31:41 +05:00
|
|
|
self.UpdateStatus('Creating backup config,0', CPBackupsV2.RUNNING)
|
|
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
Config = {'MainWebsite': model_to_dict(self.website, fields=['domain', 'adminEmail', 'phpSelection', 'state', 'config'])}
|
|
|
|
|
Config['admin'] = model_to_dict(self.website.admin, fields=['userName', 'password', 'firstName', 'lastName',
|
2023-02-12 13:15:41 +05:00
|
|
|
'email', 'type', 'owner', 'token', 'api', 'securityLevel',
|
2023-02-13 15:11:05 +05:00
|
|
|
'state', 'initself.websitesLimit', 'twoFA', 'secretKey', 'config'])
|
|
|
|
|
Config['acl'] = model_to_dict(self.website.admin.acl)
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
### Child domains to config
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
ChildsList = []
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
for childDomains in self.website.childdomains_set.all():
|
2023-02-12 13:15:41 +05:00
|
|
|
print(childDomains.domain)
|
|
|
|
|
ChildsList.append(model_to_dict(childDomains))
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
Config['ChildDomains'] = ChildsList
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
#print(str(Config))
|
2023-02-11 21:27:06 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
### Databases
|
2023-02-11 21:27:06 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
connection, cursor = mysqlUtilities.setupConnection()
|
2023-02-11 21:27:06 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
if connection == 0:
|
|
|
|
|
return 0
|
2023-02-11 21:27:06 +05:00
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
dataBases = self.website.databases_set.all()
|
2023-02-12 13:15:41 +05:00
|
|
|
DBSList = []
|
2023-02-11 21:27:06 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
for db in dataBases:
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
query = f"SELECT host,user FROM mysql.db WHERE db='{db.dbName}';"
|
|
|
|
|
cursor.execute(query)
|
|
|
|
|
DBUsers = cursor.fetchall()
|
2023-02-11 21:27:06 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
UserList = []
|
2023-02-11 21:27:06 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
for databaseUser in DBUsers:
|
|
|
|
|
query = f"SELECT password FROM `mysql`.`user` WHERE `Host`='{databaseUser[0]}' AND `User`='{databaseUser[1]}';"
|
|
|
|
|
cursor.execute(query)
|
|
|
|
|
resp = cursor.fetchall()
|
|
|
|
|
print(resp)
|
|
|
|
|
UserList.append({'user': databaseUser[1], 'host': databaseUser[0], 'password': resp[0][0]})
|
2023-02-11 21:27:06 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
DBSList.append({db.dbName: UserList})
|
2023-02-11 21:27:06 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
Config['databases'] = DBSList
|
2023-02-11 21:27:06 +05:00
|
|
|
|
2023-02-12 13:15:41 +05:00
|
|
|
WPSitesList = []
|
|
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
for wpsite in self.website.wpsites_set.all():
|
2023-02-12 13:15:41 +05:00
|
|
|
WPSitesList.append(model_to_dict(wpsite,fields=['title', 'path', 'FinalURL', 'AutoUpdates', 'PluginUpdates', 'ThemeUpdates', 'WPLockState']))
|
|
|
|
|
|
|
|
|
|
Config['WPSites'] = WPSitesList
|
2023-02-13 15:11:05 +05:00
|
|
|
self.config = Config
|
|
|
|
|
|
|
|
|
|
#command = f"echo '{json.dumps(Config)}' > {self.FinalPath}/config.json"
|
|
|
|
|
#ProcessUtilities.executioner(command, self.website.externalApp, True)
|
2023-02-12 22:31:41 +05:00
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
WriteToFile = open(f'{self.FinalPath}/config.json', 'w')
|
|
|
|
|
WriteToFile.write(json.dumps(Config))
|
|
|
|
|
WriteToFile.close()
|
|
|
|
|
|
|
|
|
|
command = f"chmod 600 {self.FinalPath}/config.json"
|
|
|
|
|
ProcessUtilities.executioner(command)
|
2023-02-12 22:31:41 +05:00
|
|
|
|
|
|
|
|
self.UpdateStatus('Backup config created,5', CPBackupsV2.RUNNING)
|
2023-02-12 13:15:41 +05:00
|
|
|
except BaseException as msg:
|
2023-02-14 10:06:09 +05:00
|
|
|
self.UpdateStatus(f'Failed during config generation, Error: {str(msg)}', CPBackupsV2.FAILED)
|
2023-02-12 13:15:41 +05:00
|
|
|
return 0
|
|
|
|
|
|
2023-02-14 10:06:09 +05:00
|
|
|
try:
|
2023-02-13 15:11:05 +05:00
|
|
|
|
2023-02-14 10:06:09 +05:00
|
|
|
if self.data['BackupDatabase']:
|
|
|
|
|
self.UpdateStatus('Backing up databases..,10', CPBackupsV2.RUNNING)
|
|
|
|
|
if self.BackupDataBases() == 0:
|
|
|
|
|
self.UpdateStatus(f'Failed to create backup for databases.', CPBackupsV2.FAILED)
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
self.UpdateStatus('Database backups completed successfully..,25', CPBackupsV2.RUNNING)
|
2023-02-13 15:11:05 +05:00
|
|
|
|
2023-02-14 10:06:09 +05:00
|
|
|
if self.data['BackupData']:
|
|
|
|
|
self.UpdateStatus('Backing up website data..,30', CPBackupsV2.RUNNING)
|
|
|
|
|
if self.BackupData() == 0:
|
|
|
|
|
return 0
|
|
|
|
|
self.UpdateStatus('Website data backup completed successfully..,70', CPBackupsV2.RUNNING)
|
2023-02-12 22:31:41 +05:00
|
|
|
|
2023-02-14 10:06:09 +05:00
|
|
|
##command = f'/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/Backupsv2.py BackupDataBases --path {self.FinalPath}'
|
|
|
|
|
##ProcessUtilities.executioner(command)
|
2023-02-12 22:31:41 +05:00
|
|
|
|
|
|
|
|
|
2023-02-14 10:06:09 +05:00
|
|
|
self.UpdateStatus('Completed', CPBackupsV2.COMPLETED)
|
|
|
|
|
|
|
|
|
|
print(self.FinalPath)
|
|
|
|
|
|
|
|
|
|
break
|
|
|
|
|
except BaseException as msg:
|
|
|
|
|
self.UpdateStatus(f'Failed after config generation, Error: {str(msg)}', CPBackupsV2.FAILED)
|
|
|
|
|
return 0
|
2023-02-12 13:15:41 +05:00
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
time.sleep(5)
|
2023-02-14 10:12:29 +05:00
|
|
|
### If website lock is there for more then 20 minutes it means old backup is stucked or backup job failed, thus continue backup
|
|
|
|
|
if float(CPBackupsV2.FetchCurrentTimeStamp()) > (float(self.StartingTimeStamp) + 1200):
|
|
|
|
|
self.website = Websites.objects.get(domain=self.data['domain'])
|
|
|
|
|
self.website.BackupLock = 0
|
|
|
|
|
self.website.save()
|
|
|
|
|
|
2023-02-11 21:27:06 +05:00
|
|
|
|
2023-02-11 22:52:38 +05:00
|
|
|
def BackupDataBases(self):
|
2023-02-11 21:27:06 +05:00
|
|
|
|
|
|
|
|
### This function will backup databases of the website, also need to take care of database that we need to exclude
|
|
|
|
|
### excluded databases are in a list self.data['ExcludedDatabases'] only backup databases if backupdatabase check is on
|
|
|
|
|
## For example if self.data['BackupDatabase'] is one then only run this function otherwise not
|
|
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
from plogical.mysqlUtilities import mysqlUtilities
|
|
|
|
|
|
|
|
|
|
for dbs in self.config['databases']:
|
|
|
|
|
|
|
|
|
|
### Pending: Need to only backup database present in the list of databases that need backing up
|
|
|
|
|
|
|
|
|
|
for key, value in dbs.items():
|
|
|
|
|
print(f'DB {key}')
|
|
|
|
|
|
|
|
|
|
if mysqlUtilities.createDatabaseBackup(key, self.FinalPath) == 0:
|
2023-02-14 10:06:09 +05:00
|
|
|
self.UpdateStatus(f'Failed to create backup for database {key}.', CPBackupsV2.RUNNING)
|
2023-02-13 15:11:05 +05:00
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
for dbUsers in value:
|
|
|
|
|
print(f'User: {dbUsers["user"]}, Host: {dbUsers["host"]}, Pass: {dbUsers["password"]}')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 1
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-11 22:52:38 +05:00
|
|
|
def BackupData(self):
|
2023-02-12 10:04:58 +05:00
|
|
|
|
2023-02-11 21:27:06 +05:00
|
|
|
### This function will backup data of the website, also need to take care of directories that we need to exclude
|
|
|
|
|
### excluded directories are in a list self.data['ExcludedDirectories'] only backup data if backupdata check is on
|
|
|
|
|
## For example if self.data['BackupData'] is one then only run this function otherwise not
|
2023-02-11 11:27:09 +05:00
|
|
|
|
2023-02-13 15:11:05 +05:00
|
|
|
destination = f'{self.FinalPath}/data'
|
|
|
|
|
source = f'/home/{self.website.domain}'
|
|
|
|
|
|
|
|
|
|
## Pending add user provided folders in the exclude list
|
|
|
|
|
|
|
|
|
|
exclude = f'--exclude=.cache --exclude=.cache --exclude=.cache --exclude=.wp-cli ' \
|
|
|
|
|
f'--exclude=backup --exclude=incbackup --exclude=incbackup --exclude=logs --exclude=lscache'
|
|
|
|
|
|
|
|
|
|
command = f'mkdir -p {destination}'
|
|
|
|
|
ProcessUtilities.executioner(command, 'cyberpanel')
|
|
|
|
|
|
|
|
|
|
command = f'chown {self.website.externalApp}:{self.website.externalApp} {destination}'
|
|
|
|
|
ProcessUtilities.executioner(command)
|
|
|
|
|
|
|
|
|
|
command = f'rsync -av {exclude} {source}/ {destination}/'
|
|
|
|
|
ProcessUtilities.executioner(command, self.website.externalApp)
|
|
|
|
|
|
|
|
|
|
return 1
|
2023-02-11 11:27:09 +05:00
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2023-02-12 22:31:41 +05:00
|
|
|
try:
|
|
|
|
|
parser = argparse.ArgumentParser(description='CyberPanel Backup Generator')
|
|
|
|
|
parser.add_argument('function', help='Specify a function to call!')
|
|
|
|
|
parser.add_argument('--path', help='')
|
|
|
|
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
|
|
if args.function == "BackupDataBases":
|
|
|
|
|
cpbuv2 = CPBackupsV2({'finalPath': args.path})
|
|
|
|
|
cpbuv2.BackupDataBases()
|
|
|
|
|
|
|
|
|
|
except:
|
|
|
|
|
cpbuv2 = CPBackupsV2({'domain': 'cyberpanel.net', 'BasePath': '/home/backup', 'BackupDatabase': 1, 'BackupData': 1} )
|
|
|
|
|
cpbuv2.InitiateBackup()
|