mirror of
				https://github.com/usmannasir/cyberpanel.git
				synced 2025-10-27 00:06:35 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			4657 lines
		
	
	
		
			196 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			4657 lines
		
	
	
		
			196 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import sys
 | |
| import socket
 | |
| import random
 | |
| import os
 | |
| import json
 | |
| import userManagment.views as um
 | |
| from backup.backupManager import BackupManager
 | |
| from databases.databaseManager import DatabaseManager
 | |
| from dns.dnsManager import DNSManager
 | |
| from firewall.firewallManager import FirewallManager
 | |
| from ftp.ftpManager import FTPManager
 | |
| from highAvailability.haManager import HAManager
 | |
| from loginSystem.models import Administrator
 | |
| from mailServer.mailserverManager import MailServerManager
 | |
| from manageSSL.views import issueSSL, obtainHostNameSSL, obtainMailServerSSL
 | |
| from packages.packagesManager import PackagesManager
 | |
| from plogical.mysqlUtilities import mysqlUtilities
 | |
| from plogical.virtualHostUtilities import virtualHostUtilities
 | |
| from websiteFunctions.website import WebsiteManager
 | |
| from s3Backups.s3Backups import S3Backups
 | |
| from serverLogs.views import getLogsFromFile
 | |
| from serverStatus.views import topProcessesStatus, killProcess, switchTOLSWSStatus
 | |
| from plogical import hashPassword
 | |
| from loginSystem.models import ACL
 | |
| from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
 | |
| from managePHP.phpManager import PHPManager
 | |
| from managePHP.views import submitExtensionRequest, getRequestStatusApache
 | |
| from containerization.views import *
 | |
| 
 | |
| sys.path.append('/usr/local/CyberCP')
 | |
| os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
 | |
| 
 | |
| 
 | |
| class CloudManager:
 | |
|     def __init__(self, data=None, admin=None):
 | |
|         self.data = data
 | |
|         self.admin = admin
 | |
| 
 | |
|     def ajaxPre(self, status, errorMessage):
 | |
|         final_dic = {'status': status, 'error_message': errorMessage}
 | |
|         final_json = json.dumps(final_dic)
 | |
|         return HttpResponse(final_json)
 | |
| 
 | |
|     def verifyLogin(self, request):
 | |
|         try:
 | |
|             if request.META['HTTP_AUTHORIZATION'] == self.admin.token:
 | |
|                 return 1, self.ajaxPre(1, None)
 | |
|             else:
 | |
|                 return 0, self.ajaxPre(0, 'Invalid login information.')
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchWebsites(self):
 | |
|         try:
 | |
|             wm = WebsiteManager()
 | |
|             return wm.getFurtherAccounts(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitWebsiteDeletion(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             wm = WebsiteManager()
 | |
|             return wm.submitWebsiteDeletion(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitWebsiteCreation(self):
 | |
|         try:
 | |
| 
 | |
|             try:
 | |
| 
 | |
|                 UserAccountName = self.data['UserAccountName']
 | |
|                 UserPassword = self.data['UserPassword']
 | |
|                 FullName = self.data['FullName']
 | |
|                 token = hashPassword.generateToken(UserAccountName, UserPassword)
 | |
|                 password = hashPassword.hash_password(UserPassword)
 | |
| 
 | |
|                 try:
 | |
|                     initWebsitesLimit = int(self.data['websitesLimit'])
 | |
|                 except:
 | |
|                     initWebsitesLimit = 10
 | |
| 
 | |
|                 try:
 | |
|                     acl = self.data['acl']
 | |
|                     selectedACL = ACL.objects.get(name=acl)
 | |
| 
 | |
|                 except:
 | |
|                     selectedACL = ACL.objects.get(name='user')
 | |
| 
 | |
|                 try:
 | |
|                     apiAccess = int(self.data['api'])
 | |
|                 except:
 | |
|                     apiAccess = 10
 | |
| 
 | |
|                 try:
 | |
|                     newAdmin = Administrator(firstName=FullName,
 | |
|                                              lastName="",
 | |
|                                              email=self.data['adminEmail'],
 | |
|                                              type=3,
 | |
|                                              userName=UserAccountName,
 | |
|                                              password=password,
 | |
|                                              initWebsitesLimit=initWebsitesLimit,
 | |
|                                              owner=1,
 | |
|                                              acl=selectedACL,
 | |
|                                              token=token,
 | |
|                                              api=apiAccess
 | |
|                                              )
 | |
|                     newAdmin.save()
 | |
|                 except BaseException as msg:
 | |
|                     logging.writeToFile(str(msg))
 | |
|                     admin = Administrator.objects.get(userName=UserAccountName)
 | |
|                     admin.token = token
 | |
|                     admin.password = password
 | |
|                     admin.save()
 | |
|             except BaseException as msg:
 | |
|                 logging.writeToFile(str(msg))
 | |
| 
 | |
|             wm = WebsiteManager()
 | |
|             return wm.submitWebsiteCreation(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchWebsiteDataJSON(self):
 | |
|         try:
 | |
|             wm = WebsiteManager()
 | |
|             return wm.fetchWebsiteDataJSON(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchWebsiteData(self):
 | |
|         try:
 | |
| 
 | |
|             currentACL = ACLManager.loadedACL(self.admin.pk)
 | |
|             website = Websites.objects.get(domain=self.data['domainName'])
 | |
|             admin = Administrator.objects.get(pk=self.admin.pk)
 | |
| 
 | |
|             if ACLManager.checkOwnership(self.data['domainName'], admin, currentACL) == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadErrorJson()
 | |
| 
 | |
|             Data = {}
 | |
| 
 | |
|             Data['ftpAllowed'] = website.package.ftpAccounts
 | |
|             Data['ftpUsed'] = website.users_set.all().count()
 | |
| 
 | |
|             Data['dbUsed'] = website.databases_set.all().count()
 | |
|             Data['dbAllowed'] = website.package.dataBases
 | |
| 
 | |
|             DiskUsage, DiskUsagePercentage, bwInMB, bwUsage = virtualHostUtilities.FindStats(website)
 | |
| 
 | |
|             ## bw usage calculations
 | |
| 
 | |
|             Data['bwInMBTotal'] = website.package.bandwidth
 | |
|             Data['bwInMB'] = bwInMB
 | |
|             Data['bwUsage'] = bwUsage
 | |
| 
 | |
|             if DiskUsagePercentage > 100:
 | |
|                 DiskUsagePercentage = 100
 | |
| 
 | |
|             Data['diskUsage'] = DiskUsagePercentage
 | |
|             Data['diskInMB'] = DiskUsage
 | |
|             Data['diskInMBTotal'] = website.package.diskSpace
 | |
| 
 | |
|             ##
 | |
| 
 | |
|             Data['status'] = 1
 | |
|             final_json = json.dumps(Data)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchModifyData(self):
 | |
|         try:
 | |
|             wm = WebsiteManager()
 | |
|             return wm.submitWebsiteModify(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def saveModifications(self):
 | |
|         try:
 | |
|             wm = WebsiteManager()
 | |
|             return wm.saveWebsiteChanges(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitDBCreation(self):
 | |
|         try:
 | |
|             dm = DatabaseManager()
 | |
|             return dm.submitDBCreation(self.admin.pk, self.data, 1)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchDatabases(self):
 | |
|         try:
 | |
|             dm = DatabaseManager()
 | |
|             return dm.fetchDatabases(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitDatabaseDeletion(self):
 | |
|         try:
 | |
|             dm = DatabaseManager()
 | |
|             return dm.submitDatabaseDeletion(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def changePassword(self):
 | |
|         try:
 | |
|             dm = DatabaseManager()
 | |
|             return dm.changePassword(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getCurrentRecordsForDomain(self):
 | |
|         try:
 | |
|             dm = DNSManager()
 | |
|             return dm.getCurrentRecordsForDomain(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def deleteDNSRecord(self):
 | |
|         try:
 | |
|             dm = DNSManager()
 | |
|             return dm.deleteDNSRecord(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def addDNSRecord(self):
 | |
|         try:
 | |
|             dm = DNSManager()
 | |
|             return dm.addDNSRecord(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitEmailCreation(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             msm = MailServerManager(request)
 | |
|             return msm.submitEmailCreation()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getEmailsForDomain(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             msm = MailServerManager(request)
 | |
|             return msm.getEmailsForDomain()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitEmailDeletion(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             msm = MailServerManager(request)
 | |
|             return msm.submitEmailDeletion()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitPasswordChange(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             msm = MailServerManager(request)
 | |
|             return msm.submitPasswordChange()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchCurrentForwardings(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             msm = MailServerManager(request)
 | |
|             return msm.fetchCurrentForwardings()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitForwardDeletion(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             msm = MailServerManager(request)
 | |
|             return msm.submitForwardDeletion()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitEmailForwardingCreation(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             msm = MailServerManager(request)
 | |
|             return msm.submitEmailForwardingCreation()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchDKIMKeys(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             msm = MailServerManager(request)
 | |
|             return msm.fetchDKIMKeys()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def generateDKIMKeys(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             msm = MailServerManager(request)
 | |
|             return msm.generateDKIMKeys()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitFTPCreation(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             fm = FTPManager(request)
 | |
|             return fm.submitFTPCreation()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getAllFTPAccounts(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             fm = FTPManager(request)
 | |
|             return fm.getAllFTPAccounts()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitFTPDelete(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             fm = FTPManager(request)
 | |
|             return fm.submitFTPDelete()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def changeFTPPassword(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             fm = FTPManager(request)
 | |
|             return fm.changePassword()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def issueSSL(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return issueSSL(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def statusFunc(self):
 | |
|         try:
 | |
|             statusFile = self.data['statusFile']
 | |
| 
 | |
|             if ACLManager.CheckStatusFilleLoc(statusFile):
 | |
|                 pass
 | |
|             else:
 | |
|                 data_ret = {'abort': 1, 'installStatus': 0, 'installationProgress': "100",
 | |
|                             'currentStatus': 'Invalid status file.'}
 | |
|                 json_data = json.dumps(data_ret)
 | |
|                 return HttpResponse(json_data)
 | |
| 
 | |
|             statusData = open(statusFile, 'r').readlines()
 | |
|             try:
 | |
|                 lastLine = statusData[-1]
 | |
|                 if lastLine.find('[200]') > -1:
 | |
|                     command = 'rm -f ' + statusFile
 | |
|                     ProcessUtilities.executioner(command)
 | |
|                     data_ret = {'status': 1, 'abort': 1, 'installationProgress': "100", 'currentStatus': lastLine}
 | |
|                     json_data = json.dumps(data_ret)
 | |
|                     return HttpResponse(json_data)
 | |
|                 elif lastLine.find('[404]') > -1:
 | |
|                     data_ret = {'status': 0, 'abort': 1, 'installationProgress': "0", 'error_message': lastLine}
 | |
|                     json_data = json.dumps(data_ret)
 | |
|                     return HttpResponse(json_data)
 | |
|                 else:
 | |
|                     progress = lastLine.split(',')
 | |
|                     currentStatus = progress[0]
 | |
|                     try:
 | |
|                         installationProgress = progress[1].rstrip('\n')
 | |
|                     except:
 | |
|                         installationProgress = 0
 | |
|                     data_ret = {'status': 1, 'abort': 0, 'installationProgress': installationProgress,
 | |
|                                 'currentStatus': currentStatus}
 | |
|                     json_data = json.dumps(data_ret)
 | |
|                     return HttpResponse(json_data)
 | |
|             except IndexError:
 | |
|                 data_ret = {'status': 1, 'abort': 0, 'installationProgress': 0,
 | |
|                             'currentStatus': 'Working..'}
 | |
|                 json_data = json.dumps(data_ret)
 | |
|                 return HttpResponse(json_data)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             data_ret = {'status': 0, 'abort': 0, 'installationProgress': "0", 'errorMessage': str(msg)}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
| 
 | |
|     def submitDomainCreation(self):
 | |
|         try:
 | |
|             wm = WebsiteManager()
 | |
|             return wm.submitDomainCreation(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchDomains(self):
 | |
|         try:
 | |
|             wm = WebsiteManager()
 | |
|             return wm.fetchDomains(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitDomainDeletion(self):
 | |
|         try:
 | |
|             wm = WebsiteManager()
 | |
|             return wm.submitDomainDeletion(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def changeOpenBasedir(self):
 | |
|         try:
 | |
|             wm = WebsiteManager()
 | |
|             return wm.changeOpenBasedir(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def changePHP(self):
 | |
|         try:
 | |
|             wm = WebsiteManager()
 | |
|             return wm.changePHP(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def backupStatusFunc(self):
 | |
|         try:
 | |
|             bm = BackupManager()
 | |
|             return bm.backupStatus(self.admin.pk, self.data)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             data_ret = {'status': 0, 'abort': 0, 'installationProgress': "0", 'errorMessage': str(msg)}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
| 
 | |
|     def submitBackupCreation(self):
 | |
|         try:
 | |
|             bm = BackupManager()
 | |
|             return bm.submitBackupCreation(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getCurrentBackups(self):
 | |
|         try:
 | |
|             bm = BackupManager()
 | |
|             return bm.getCurrentBackups(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def deleteBackup(self):
 | |
|         try:
 | |
|             bm = BackupManager()
 | |
|             return bm.deleteBackup(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchACLs(self):
 | |
|         try:
 | |
|             userID = self.admin.pk
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if currentACL['admin'] == 1:
 | |
|                 aclNames = ACLManager.unFileteredACLs()
 | |
|             elif currentACL['changeUserACL'] == 1:
 | |
|                 aclNames = ACLManager.unFileteredACLs()
 | |
|             elif currentACL['createNewUser'] == 1:
 | |
|                 aclNames = ['user']
 | |
|             else:
 | |
|                 return ACLManager.loadError()
 | |
| 
 | |
|             json_data = "["
 | |
|             checker = 0
 | |
| 
 | |
|             for items in aclNames:
 | |
|                 dic = {'acl': items}
 | |
| 
 | |
|                 if checker == 0:
 | |
|                     json_data = json_data + json.dumps(dic)
 | |
|                     checker = 1
 | |
|                 else:
 | |
|                     json_data = json_data + ',' + json.dumps(dic)
 | |
| 
 | |
|             json_data = json_data + ']'
 | |
|             final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitUserCreation(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return um.submitUserCreation(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchUsers(self):
 | |
|         try:
 | |
|             userID = self.admin.pk
 | |
|             allUsers = ACLManager.loadUserObjects(userID)
 | |
| 
 | |
|             json_data = "["
 | |
|             checker = 0
 | |
| 
 | |
|             for user in allUsers:
 | |
|                 dic = {
 | |
|                     "id": user.id,
 | |
|                     "userName": user.userName,
 | |
|                     "firstName": user.firstName,
 | |
|                     "lastName": user.lastName,
 | |
|                     "email": user.email,
 | |
|                     "acl": user.acl.name,
 | |
|                     "websitesLimit": user.initWebsitesLimit
 | |
|                 }
 | |
| 
 | |
|                 if checker == 0:
 | |
|                     json_data = json_data + json.dumps(dic)
 | |
|                     checker = 1
 | |
|                 else:
 | |
|                     json_data = json_data + ',' + json.dumps(dic)
 | |
| 
 | |
|             json_data = json_data + ']'
 | |
|             final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitUserDeletion(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return um.submitUserDeletion(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def saveModificationsUser(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return um.saveModifications(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def userWithResellerPriv(self):
 | |
|         try:
 | |
|             userID = self.admin.pk
 | |
|             allUsers = ACLManager.userWithResellerPriv(userID)
 | |
| 
 | |
|             json_data = "["
 | |
|             checker = 0
 | |
| 
 | |
|             for user in allUsers:
 | |
|                 dic = {
 | |
|                     "userName": user,
 | |
|                 }
 | |
| 
 | |
|                 if checker == 0:
 | |
|                     json_data = json_data + json.dumps(dic)
 | |
|                     checker = 1
 | |
|                 else:
 | |
|                     json_data = json_data + ',' + json.dumps(dic)
 | |
| 
 | |
|             json_data = json_data + ']'
 | |
|             final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data})
 | |
|             return HttpResponse(final_json)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def saveResellerChanges(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return um.saveResellerChanges(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def changeACLFunc(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return um.changeACLFunc(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def createACLFunc(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return um.createACLFunc(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def findAllACLs(self, request):
 | |
|         try:
 | |
|             userID = self.admin.pk
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if currentACL['admin'] == 1:
 | |
|                 aclNames = ACLManager.findAllACLs()
 | |
|             else:
 | |
|                 return ACLManager.loadErrorJson()
 | |
| 
 | |
|             json_data = "["
 | |
|             checker = 0
 | |
| 
 | |
|             for items in aclNames:
 | |
|                 dic = {'acl': items}
 | |
| 
 | |
|                 if checker == 0:
 | |
|                     json_data = json_data + json.dumps(dic)
 | |
|                     checker = 1
 | |
|                 else:
 | |
|                     json_data = json_data + ',' + json.dumps(dic)
 | |
| 
 | |
|             json_data = json_data + ']'
 | |
|             final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data})
 | |
|             return HttpResponse(final_json)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def deleteACLFunc(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return um.deleteACLFunc(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchACLDetails(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return um.fetchACLDetails(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitACLModifications(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return um.submitACLModifications(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitPackage(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             pm = PackagesManager(request)
 | |
|             return pm.submitPackage()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchPackages(self, request):
 | |
|         try:
 | |
|             userID = self.admin.pk
 | |
|             currentACL = ACLManager.loadedACL(userID)
 | |
| 
 | |
|             if ACLManager.currentContextPermission(currentACL, 'deletePackage') == 0:
 | |
|                 return ACLManager.loadError()
 | |
| 
 | |
|             packageList = ACLManager.loadPackageObjects(userID, currentACL)
 | |
| 
 | |
|             json_data = "["
 | |
|             checker = 0
 | |
| 
 | |
|             for items in packageList:
 | |
|                 dic = {
 | |
|                     'packageName': items.packageName,
 | |
|                     'allowedDomains': items.allowedDomains,
 | |
|                     'diskSpace': items.diskSpace,
 | |
|                     'bandwidth': items.bandwidth,
 | |
|                     'emailAccounts': items.emailAccounts,
 | |
|                     'dataBases': items.dataBases,
 | |
|                     'ftpAccounts': items.ftpAccounts,
 | |
|                 }
 | |
| 
 | |
|                 if checker == 0:
 | |
|                     json_data = json_data + json.dumps(dic)
 | |
|                     checker = 1
 | |
|                 else:
 | |
|                     json_data = json_data + ',' + json.dumps(dic)
 | |
| 
 | |
|             json_data = json_data + ']'
 | |
|             final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data})
 | |
|             return HttpResponse(final_json)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitPackageDelete(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             pm = PackagesManager(request)
 | |
|             return pm.submitDelete()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitPackageModify(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             pm = PackagesManager(request)
 | |
|             return pm.saveChanges()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getDataFromLogFile(self, request):
 | |
|         try:
 | |
|             wm = WebsiteManager()
 | |
|             return wm.getDataFromLogFile(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchErrorLogs(self, request):
 | |
|         try:
 | |
|             wm = WebsiteManager()
 | |
|             return wm.fetchErrorLogs(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitApplicationInstall(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             wm = WebsiteManager()
 | |
| 
 | |
|             if self.data['selectedApplication'] == 'WordPress with LSCache':
 | |
|                 return wm.installWordpress(self.admin.pk, self.data)
 | |
|             elif self.data['selectedApplication'] == 'Prestashop':
 | |
|                 return wm.prestaShopInstall(self.admin.pk, self.data)
 | |
|             elif self.data['selectedApplication'] == 'Joomla':
 | |
|                 return wm.installJoomla(self.admin.pk, self.data)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def obtainServer(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             data_ret = {'status': 1, 'serverStatus': ProcessUtilities.decideServer()}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getSSHConfigs(self):
 | |
|         try:
 | |
|             fm = FirewallManager()
 | |
|             return fm.getSSHConfigs(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def saveSSHConfigs(self):
 | |
|         try:
 | |
|             fm = FirewallManager()
 | |
|             return fm.saveSSHConfigs(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def deleteSSHKey(self):
 | |
|         try:
 | |
|             fm = FirewallManager()
 | |
|             return fm.deleteSSHKey(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def addSSHKey(self):
 | |
|         try:
 | |
|             fm = FirewallManager()
 | |
|             return fm.addSSHKey(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getCurrentRules(self):
 | |
|         try:
 | |
|             fm = FirewallManager()
 | |
|             return fm.getCurrentRules(self.admin.pk)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def addRule(self):
 | |
|         try:
 | |
|             fm = FirewallManager()
 | |
|             return fm.addRule(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def deleteRule(self):
 | |
|         try:
 | |
|             fm = FirewallManager()
 | |
|             return fm.deleteRule(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getLogsFromFile(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return getLogsFromFile(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def serverSSL(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             if self.data['type'] == 'hostname':
 | |
|                 return obtainHostNameSSL(request)
 | |
|             else:
 | |
|                 return obtainMailServerSSL(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def setupManager(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             tempStatusPath = "/home/cyberpanel/" + str(randint(1000, 9999))
 | |
|             self.data['tempStatusPath'] = tempStatusPath
 | |
| 
 | |
|             ham = HAManager(request, self.data, 'setupNode')
 | |
|             ham.start()
 | |
| 
 | |
|             data = {}
 | |
|             data['tempStatusPath'] = tempStatusPath
 | |
| 
 | |
|             proc = httpProc(request, None)
 | |
|             return proc.ajax(1, None, data)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchManagerTokens(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             ham = HAManager(request, self.data, 'fetchManagerTokens')
 | |
|             return ham.fetchManagerTokens()
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def addWorker(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             ham = HAManager(request, self.data, 'fetchManagerTokens')
 | |
|             return ham.addWorker()
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchSSHKey(self, request):
 | |
|         try:
 | |
|             pubKey = os.path.join("/root", ".ssh", 'cyberpanel.pub')
 | |
|             execPath = "sudo cat " + pubKey
 | |
|             data = ProcessUtilities.outputExecutioner(execPath)
 | |
| 
 | |
|             data_ret = {
 | |
|                 'status': 1,
 | |
|                 'error_message': "None",
 | |
|                 'pubKey': data
 | |
|             }
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def putSSHkeyFunc(self, request):
 | |
|         try:
 | |
|             fm = FirewallManager(request)
 | |
|             return fm.addSSHKey(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def leaveSwarm(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             ham = HAManager(request, self.data, 'leaveSwarm')
 | |
|             return ham.leaveSwarm()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def setUpDataNode(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             ham = HAManager(request, self.data, 'setUpDataNode')
 | |
|             return ham.setUpDataNode()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitEditCluster(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             ham = HAManager(request, self.data, 'submitEditCluster')
 | |
|             return ham.submitEditCluster()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def connectAccount(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'connectAccount')
 | |
|             return s3.connectAccount()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchBuckets(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'fetchBuckets')
 | |
|             return s3.fetchBuckets()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def createPlan(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'createPlan')
 | |
|             return s3.createPlan()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchBackupPlans(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'fetchBackupPlans')
 | |
|             return s3.fetchBackupPlans()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def deletePlan(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'deletePlan')
 | |
|             return s3.deletePlan()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchWebsitesInPlan(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'fetchWebsitesInPlan')
 | |
|             return s3.fetchWebsitesInPlan()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def deleteDomainFromPlan(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'deleteDomainFromPlan')
 | |
|             return s3.deleteDomainFromPlan()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def savePlanChanges(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'savePlanChanges')
 | |
|             return s3.savePlanChanges()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchBackupLogs(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'fetchBackupLogs')
 | |
|             return s3.fetchBackupLogs()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def forceRunAWSBackup(self, request):
 | |
|         try:
 | |
| 
 | |
|             request.session['userID'] = self.admin.pk
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/IncScheduler.py forceRunAWSBackup --planName %s" % (
 | |
|                 self.data['planName'])
 | |
|             ProcessUtilities.popenExecutioner(execPath)
 | |
| 
 | |
|             return self.ajaxPre(1, None)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def systemStatus(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return topProcessesStatus(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def killProcess(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return killProcess(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def connectAccountDO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'connectAccountDO')
 | |
|             return s3.connectAccountDO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchBucketsDO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'fetchBucketsDO')
 | |
|             return s3.fetchBucketsDO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def createPlanDO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'createPlanDO')
 | |
|             return s3.createPlanDO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchBackupPlansDO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'fetchBackupPlansDO')
 | |
|             return s3.fetchBackupPlansDO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def deletePlanDO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'deletePlanDO')
 | |
|             return s3.deletePlanDO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchWebsitesInPlanDO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'fetchWebsitesInPlanDO')
 | |
|             return s3.fetchWebsitesInPlanDO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchBackupLogsDO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'fetchBackupLogsDO')
 | |
|             return s3.fetchBackupLogsDO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def deleteDomainFromPlanDO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'deleteDomainFromPlanDO')
 | |
|             return s3.deleteDomainFromPlanDO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def savePlanChangesDO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'savePlanChangesDO')
 | |
|             return s3.savePlanChangesDO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def forceRunAWSBackupDO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'forceRunAWSBackupDO')
 | |
|             s3.start()
 | |
|             return self.ajaxPre(1, None)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def showStatus(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             currentACL = ACLManager.loadedACL(self.admin.pk)
 | |
| 
 | |
|             if currentACL['admin'] == 0:
 | |
|                 return self.ajaxPre(0, 'Only administrators can see MySQL status.')
 | |
| 
 | |
|             finalData = mysqlUtilities.showStatus()
 | |
| 
 | |
|             finalData = json.dumps(finalData)
 | |
|             return HttpResponse(finalData)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchRam(self, request):
 | |
|         try:
 | |
|             # request.session['userID'] = self.admin.pk
 | |
|             # currentACL = ACLManager.loadedACL(self.admin.pk)
 | |
|             #
 | |
|             # if currentACL['admin'] == 0:
 | |
|             #     return self.ajaxPre(0, 'Only administrators can see MySQL status.')
 | |
| 
 | |
|             # if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu:
 | |
|             #    return self.ajaxPre(0, 'This feature is currently only available on CentOS.')
 | |
| 
 | |
|             from psutil import virtual_memory
 | |
|             import math
 | |
| 
 | |
|             finalData = {}
 | |
|             mem = virtual_memory()
 | |
|             inGB = math.ceil(float(mem.total) / float(1024 * 1024 * 1024))
 | |
|             finalData['ramInGB'] = inGB
 | |
| 
 | |
|             if ProcessUtilities.decideDistro() == ProcessUtilities.centos or ProcessUtilities.decideDistro() == ProcessUtilities.cent8:
 | |
|                 finalData['conf'] = ProcessUtilities.outputExecutioner('sudo cat /etc/my.cnf')
 | |
|             else:
 | |
|                 finalData['conf'] = ProcessUtilities.outputExecutioner('sudo cat /etc/mysql/my.cnf')
 | |
| 
 | |
|             finalData['status'] = 1
 | |
| 
 | |
|             finalData = json.dumps(finalData)
 | |
|             return HttpResponse(finalData)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def applyMySQLChanges(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             currentACL = ACLManager.loadedACL(self.admin.pk)
 | |
| 
 | |
|             if currentACL['admin'] == 0:
 | |
|                 return self.ajaxPre(0, 'Only administrators can see MySQL status.')
 | |
| 
 | |
|             result = mysqlUtilities.applyMySQLChanges(self.data)
 | |
| 
 | |
|             if result[0] == 0:
 | |
|                 return self.ajaxPre(0, result[1])
 | |
|             else:
 | |
|                 return self.ajaxPre(1, None)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def restartMySQL(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             currentACL = ACLManager.loadedACL(self.admin.pk)
 | |
| 
 | |
|             if currentACL['admin'] == 0:
 | |
|                 return self.ajaxPre(0, 'Only administrators can see MySQL status.')
 | |
| 
 | |
|             finalData = mysqlUtilities.restartMySQL()
 | |
| 
 | |
|             finalData = json.dumps(finalData)
 | |
|             return HttpResponse(finalData)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchDatabasesMYSQL(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             currentACL = ACLManager.loadedACL(self.admin.pk)
 | |
| 
 | |
|             if currentACL['admin'] == 0:
 | |
|                 return self.ajaxPre(0, 'Only administrators can see MySQL status.')
 | |
| 
 | |
|             finalData = mysqlUtilities.fetchDatabases()
 | |
| 
 | |
|             finalData = json.dumps(finalData)
 | |
|             return HttpResponse(finalData)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchTables(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             currentACL = ACLManager.loadedACL(self.admin.pk)
 | |
| 
 | |
|             if currentACL['admin'] == 0:
 | |
|                 return self.ajaxPre(0, 'Only administrators can see MySQL status.')
 | |
| 
 | |
|             finalData = mysqlUtilities.fetchTables(self.data)
 | |
| 
 | |
|             finalData = json.dumps(finalData)
 | |
|             return HttpResponse(finalData)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def deleteTable(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             currentACL = ACLManager.loadedACL(self.admin.pk)
 | |
| 
 | |
|             if currentACL['admin'] == 0:
 | |
|                 return self.ajaxPre(0, 'Only administrators can see MySQL status.')
 | |
| 
 | |
|             finalData = mysqlUtilities.deleteTable(self.data)
 | |
| 
 | |
|             finalData = json.dumps(finalData)
 | |
|             return HttpResponse(finalData)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchTableData(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             currentACL = ACLManager.loadedACL(self.admin.pk)
 | |
| 
 | |
|             if currentACL['admin'] == 0:
 | |
|                 return self.ajaxPre(0, 'Only administrators can see MySQL status.')
 | |
| 
 | |
|             finalData = mysqlUtilities.fetchTableData(self.data)
 | |
| 
 | |
|             finalData = json.dumps(finalData)
 | |
|             return HttpResponse(finalData)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchStructure(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             currentACL = ACLManager.loadedACL(self.admin.pk)
 | |
| 
 | |
|             if currentACL['admin'] == 0:
 | |
|                 return self.ajaxPre(0, 'Only administrators can see MySQL status.')
 | |
| 
 | |
|             finalData = mysqlUtilities.fetchStructure(self.data)
 | |
| 
 | |
|             finalData = json.dumps(finalData)
 | |
|             return HttpResponse(finalData)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def addMINIONode(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'addMINIONode')
 | |
|             return s3.addMINIONode()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchMINIONodes(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'fetchMINIONodes')
 | |
|             return s3.fetchMINIONodes()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def deleteMINIONode(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'deleteMINIONode')
 | |
|             return s3.deleteMINIONode()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def createPlanMINIO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'createPlanMINIO')
 | |
|             return s3.createPlanMINIO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchBackupPlansMINIO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'fetchBackupPlansMINIO')
 | |
|             return s3.fetchBackupPlansMINIO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def deletePlanMINIO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'deletePlanMINIO')
 | |
|             return s3.deletePlanMINIO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def savePlanChangesMINIO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'savePlanChangesMINIO')
 | |
|             return s3.savePlanChangesMINIO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def forceRunAWSBackupMINIO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'forceRunAWSBackupMINIO')
 | |
|             s3.start()
 | |
|             return self.ajaxPre(1, None)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchWebsitesInPlanMINIO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'fetchWebsitesInPlanMINIO')
 | |
|             return s3.fetchWebsitesInPlanMINIO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchBackupLogsMINIO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'fetchBackupLogsMINIO')
 | |
|             return s3.fetchBackupLogsMINIO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def deleteDomainFromPlanMINIO(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             s3 = S3Backups(request, self.data, 'deleteDomainFromPlanMINIO')
 | |
|             return s3.deleteDomainFromPlanMINIO()
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitWebsiteStatus(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             wm = WebsiteManager()
 | |
|             return wm.submitWebsiteStatus(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitChangePHP(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             wm = WebsiteManager()
 | |
|             return wm.changePHP(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getSwitchStatus(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             wm = WebsiteManager()
 | |
|             return wm.getSwitchStatus(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def switchServer(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             wm = WebsiteManager()
 | |
|             return wm.switchServer(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def tuneSettings(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             wm = WebsiteManager()
 | |
|             return wm.tuneSettings(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getCurrentPHPConfig(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return PHPManager.getCurrentPHPConfig(self.data['phpSelection'])
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def savePHPConfigBasic(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return PHPManager.savePHPConfigBasic(self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchPHPSettingsAdvance(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return PHPManager.fetchPHPSettingsAdvance(self.data['phpSelection'])
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def savePHPConfigAdvance(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return PHPManager.savePHPConfigAdvance(self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchPHPExtensions(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return PHPManager.fetchPHPExtensions(self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitExtensionRequest(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             submitExtensionRequest(request)
 | |
|             return self.ajaxPre(1, 'None')
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getRequestStatus(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return getRequestStatusApache(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getContainerizationStatus(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
| 
 | |
|             finalData = {}
 | |
|             finalData['status'] = 1
 | |
| 
 | |
|             if not ProcessUtilities.containerCheck():
 | |
|                 finalData['notInstalled'] = 1
 | |
|             else:
 | |
|                 finalData['notInstalled'] = 0
 | |
| 
 | |
|             finalData = json.dumps(finalData)
 | |
|             return HttpResponse(finalData)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def submitContainerInstall(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             currentACL = ACLManager.loadedACL(self.admin.pk)
 | |
| 
 | |
|             if currentACL['admin'] == 1:
 | |
|                 pass
 | |
|             else:
 | |
|                 return ACLManager.loadErrorJson()
 | |
| 
 | |
|             c = ContainerManager(request, None, 'submitContainerInstall')
 | |
|             c.start()
 | |
| 
 | |
|             data_ret = {'status': 1, 'error_message': 'None'}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def switchTOLSWSStatus(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return switchTOLSWSStatus(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchWebsiteLimits(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return fetchWebsiteLimits(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def saveWebsiteLimits(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return saveWebsiteLimits(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getUsageData(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             return getUsageData(request)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def RunServerLevelEmailChecks(self):
 | |
|         try:
 | |
| 
 | |
|             tempStatusPath = "/home/cyberpanel/" + str(randint(1000, 9999))
 | |
|             reportFile = "/home/cyberpanel/" + str(randint(1000, 9999))
 | |
| 
 | |
|             extraArgs = {'tempStatusPath': tempStatusPath, 'reportFile': reportFile}
 | |
| 
 | |
|             background = MailServerManager(None, 'RunServerLevelEmailChecks', extraArgs)
 | |
|             background.start()
 | |
| 
 | |
|             final_dic = {'status': 1, 'tempStatusPath': tempStatusPath, 'reportFile': reportFile}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def ReadReport(self):
 | |
|         try:
 | |
|             reportFile = self.data['reportFile']
 | |
|             reportContent = open(reportFile, 'r').read()
 | |
| 
 | |
|             data_ret = {'status': 1, 'reportContent': reportContent}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             data_ret = {'status': 0, 'abort': 0, 'installationProgress': "0", 'errorMessage': str(msg)}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
| 
 | |
|     def ResetEmailConfigurations(self):
 | |
|         try:
 | |
| 
 | |
|             tempStatusPath = "/home/cyberpanel/" + str(randint(1000, 9999))
 | |
| 
 | |
|             writeToFile = open(tempStatusPath, 'w')
 | |
|             writeToFile.write('Starting..,0')
 | |
|             writeToFile.close()
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/plogical/mailUtilities.py"
 | |
|             execPath = execPath + ' ResetEmailConfigurations --tempStatusPath %s' % (tempStatusPath)
 | |
| 
 | |
|             ProcessUtilities.popenExecutioner(execPath)
 | |
| 
 | |
|             final_dic = {'status': 1, 'tempStatusPath': tempStatusPath}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchAllSites(self):
 | |
|         try:
 | |
|             currentACL = ACLManager.loadedACL(self.admin.pk)
 | |
|             websites = ACLManager.findAllWebsites(currentACL, self.admin.pk)
 | |
| 
 | |
|             final_dic = {'status': 1, 'websites': websites}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def debugEmailForSite(self):
 | |
|         try:
 | |
| 
 | |
|             websiteName = self.data['websiteName']
 | |
|             result = MailServerManager(None, 'debugEmailForSite', None).debugEmailForSite(websiteName)
 | |
| 
 | |
|             if result[0]:
 | |
|                 final_dic = {'error_message': result[1], 'status': 1}
 | |
|                 final_json = json.dumps(final_dic)
 | |
|                 return HttpResponse(final_json)
 | |
|             else:
 | |
|                 final_dic = {'error_message': result[1], 'status': 0}
 | |
|                 final_json = json.dumps(final_dic)
 | |
|                 return HttpResponse(final_json)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fixMailSSL(self, request):
 | |
|         try:
 | |
| 
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             msM = MailServerManager(request)
 | |
|             return msM.fixMailSSL(self.data)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def ReadReportFTP(self):
 | |
|         try:
 | |
|             command = 'ps aux'
 | |
|             result = ProcessUtilities.outputExecutioner(command)
 | |
| 
 | |
|             FTP = 1
 | |
|             if result.find('pure-ftpd') == -1:
 | |
|                 FTP = 0
 | |
| 
 | |
|             data_ret = {'status': 1, 'FTP': FTP}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             data_ret = {'status': 0, 'abort': 0, 'installationProgress': "0", 'errorMessage': str(msg)}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
| 
 | |
|     def ResetFTPConfigurations(self):
 | |
|         try:
 | |
| 
 | |
|             tempStatusPath = "/home/cyberpanel/" + str(randint(1000, 9999))
 | |
| 
 | |
|             writeToFile = open(tempStatusPath, 'w')
 | |
|             writeToFile.write('Starting..,0')
 | |
|             writeToFile.close()
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/ftp/ftpManager.py"
 | |
|             execPath = execPath + ' ResetFTPConfigurations --tempStatusPath %s' % (tempStatusPath)
 | |
| 
 | |
|             ProcessUtilities.popenExecutioner(execPath)
 | |
| 
 | |
|             final_dic = {'status': 1, 'tempStatusPath': tempStatusPath}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def ReadReportDNS(self):
 | |
|         try:
 | |
|             command = 'ps aux'
 | |
|             result = ProcessUtilities.outputExecutioner(command)
 | |
| 
 | |
|             DNS = 1
 | |
|             if result.find('pdns_server --guardian=no') == -1:
 | |
|                 DNS = 0
 | |
| 
 | |
|             data_ret = {'status': 1, 'DNS': DNS}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             data_ret = {'status': 0, 'abort': 0, 'installationProgress': "0", 'errorMessage': str(msg)}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
| 
 | |
|     def ResetDNSConfigurations(self):
 | |
|         try:
 | |
| 
 | |
|             tempStatusPath = "/home/cyberpanel/" + str(randint(1000, 9999))
 | |
| 
 | |
|             writeToFile = open(tempStatusPath, 'w')
 | |
|             writeToFile.write('Starting..,0')
 | |
|             writeToFile.close()
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/dns/dnsManager.py"
 | |
|             execPath = execPath + ' ResetDNSConfigurations --tempStatusPath %s' % (tempStatusPath)
 | |
| 
 | |
|             ProcessUtilities.popenExecutioner(execPath)
 | |
| 
 | |
|             final_dic = {'status': 1, 'tempStatusPath': tempStatusPath}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def SubmitCloudBackup(self):
 | |
|         try:
 | |
| 
 | |
|             tempStatusPath = "/home/cyberpanel/" + str(randint(1000, 9999))
 | |
| 
 | |
|             writeToFile = open(tempStatusPath, 'w')
 | |
|             writeToFile.write('Starting..,0')
 | |
|             writeToFile.close()
 | |
| 
 | |
|             try:
 | |
|                 data = str(int(self.data['data']))
 | |
|             except:
 | |
|                 data = '0'
 | |
| 
 | |
|             try:
 | |
|                 emails = str(int(self.data['emails']))
 | |
|             except:
 | |
|                 emails = '0'
 | |
| 
 | |
|             try:
 | |
|                 databases = str(int(self.data['databases']))
 | |
|             except:
 | |
|                 databases = '0'
 | |
| 
 | |
|             try:
 | |
|                 port = str(self.data['port'])
 | |
|             except:
 | |
|                 port = '0'
 | |
| 
 | |
|             try:
 | |
|                 ip = str(self.data['ip'])
 | |
|             except:
 | |
|                 ip = '0'
 | |
| 
 | |
|             try:
 | |
|                 destinationDomain = self.data['destinationDomain']
 | |
|             except:
 | |
|                 destinationDomain = 'None'
 | |
| 
 | |
|             import time
 | |
|             BackupPath = '/home/cyberpanel/backups/%s/backup-' % (self.data['domain']) + self.data[
 | |
|                 'domain'] + "-" + time.strftime("%m.%d.%Y_%H-%M-%S")
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/plogical/backupUtilities.py"
 | |
|             execPath = execPath + " CloudBackup --backupDomain %s --data %s --emails %s --databases %s --tempStoragePath %s " \
 | |
|                                   "--path %s --port %s --ip %s --destinationDomain %s" % (
 | |
|                            self.data['domain'], data, emails, databases, tempStatusPath, BackupPath, port, ip,
 | |
|                            destinationDomain)
 | |
|             ProcessUtilities.popenExecutioner(execPath)
 | |
| 
 | |
|             final_dic = {'status': 1, 'tempStatusPath': tempStatusPath, 'path': '%s.tar.gz' % (BackupPath)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def getCurrentCloudBackups(self):
 | |
|         try:
 | |
| 
 | |
|             backupDomain = self.data['domainName']
 | |
|             backupsPath = '/home/cyberpanel/backups/%s/' % (backupDomain)
 | |
|             try:
 | |
|                 backups = os.listdir(backupsPath)
 | |
|                 backups.reverse()
 | |
|             except:
 | |
|                 backups = []
 | |
| 
 | |
|             json_data = "["
 | |
|             checker = 0
 | |
| 
 | |
|             counter = 1
 | |
|             for items in backups:
 | |
| 
 | |
|                 size = str(int(int(os.path.getsize('%s/%s' % (backupsPath, items))) / int(1048576)))
 | |
| 
 | |
|                 dic = {'id': counter,
 | |
|                        'file': items,
 | |
|                        'size': '%s MBs' % (size),
 | |
|                        }
 | |
|                 counter = counter + 1
 | |
| 
 | |
|                 if checker == 0:
 | |
|                     json_data = json_data + json.dumps(dic)
 | |
|                     checker = 1
 | |
|                 else:
 | |
|                     json_data = json_data + ',' + json.dumps(dic)
 | |
| 
 | |
|             json_data = json_data + ']'
 | |
|             final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": json_data})
 | |
|             return HttpResponse(final_json)
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def fetchCloudBackupSettings(self):
 | |
|         try:
 | |
|             from plogical.backupUtilities import backupUtilities
 | |
|             if os.path.exists(backupUtilities.CloudBackupConfigPath):
 | |
|                 result = json.loads(open(backupUtilities.CloudBackupConfigPath, 'r').read())
 | |
|                 self.nice = result['nice']
 | |
|                 self.cpu = result['cpu']
 | |
|                 self.time = result['time']
 | |
|             else:
 | |
|                 self.nice = backupUtilities.NiceDefault
 | |
|                 self.cpu = backupUtilities.CPUDefault
 | |
|                 self.time = backupUtilities.time
 | |
| 
 | |
|             data_ret = {'status': 1, 'nice': self.nice, 'cpu': self.cpu, 'time': self.time}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             data_ret = {'status': 0, 'abort': 0, 'installationProgress': "0", 'errorMessage': str(msg)}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
| 
 | |
|     def saveCloudBackupSettings(self):
 | |
|         try:
 | |
|             from plogical.backupUtilities import backupUtilities
 | |
|             writeToFile = open(backupUtilities.CloudBackupConfigPath, 'w')
 | |
|             writeToFile.write(json.dumps(self.data))
 | |
|             writeToFile.close()
 | |
| 
 | |
|             data_ret = {'status': 1}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             data_ret = {'status': 0, 'abort': 0, 'installationProgress': "0", 'errorMessage': str(msg)}
 | |
|             json_data = json.dumps(data_ret)
 | |
|             return HttpResponse(json_data)
 | |
| 
 | |
|     def deleteCloudBackup(self):
 | |
|         try:
 | |
| 
 | |
|             backupDomain = self.data['domainName']
 | |
|             backupFile = self.data['backupFile']
 | |
|             backupsPathComplete = '/home/cyberpanel/backups/%s/%s' % (backupDomain, backupFile)
 | |
| 
 | |
|             command = 'rm -f %s' % (backupsPathComplete)
 | |
|             ProcessUtilities.executioner(command)
 | |
| 
 | |
|             final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None"})
 | |
|             return HttpResponse(final_json)
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def SubmitCloudBackupRestore(self):
 | |
|         try:
 | |
| 
 | |
|             tempStatusPath = "/home/cyberpanel/" + str(randint(1000, 9999))
 | |
| 
 | |
|             writeToFile = open(tempStatusPath, 'w')
 | |
|             writeToFile.write('Starting..,0')
 | |
|             writeToFile.close()
 | |
| 
 | |
|             try:
 | |
|                 sourceDomain = self.data['sourceDomain']
 | |
|             except:
 | |
|                 sourceDomain = 'None'
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/plogical/backupUtilities.py"
 | |
|             execPath = execPath + " SubmitCloudBackupRestore --backupDomain %s --backupFile %s --sourceDomain %s --tempStoragePath %s" % (
 | |
|                 self.data['domain'], self.data['backupFile'], sourceDomain, tempStatusPath)
 | |
|             ProcessUtilities.popenExecutioner(execPath)
 | |
| 
 | |
|             final_dic = {'status': 1, 'tempStatusPath': tempStatusPath}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def fetchAWSKeys(self):
 | |
|         path = '/home/cyberpanel/.aws'
 | |
|         credentials = path + '/credentials'
 | |
| 
 | |
|         data = open(credentials, 'r').readlines()
 | |
| 
 | |
|         aws_access_key_id = data[1].split(' ')[2].strip(' ').strip('\n')
 | |
|         aws_secret_access_key = data[2].split(' ')[2].strip(' ').strip('\n')
 | |
|         region = data[3].split(' ')[2].strip(' ').strip('\n')
 | |
| 
 | |
|         return aws_access_key_id, aws_secret_access_key, region
 | |
| 
 | |
|     def getCurrentS3Backups(self):
 | |
|         try:
 | |
| 
 | |
|             import boto3
 | |
|             from s3Backups.models import BackupPlan, BackupLogs
 | |
|             plan = BackupPlan.objects.get(name=self.data['planName'])
 | |
| 
 | |
|             aws_access_key_id, aws_secret_access_key, region = self.fetchAWSKeys()
 | |
| 
 | |
|             if region.find('http') > -1:
 | |
|                 s3 = boto3.resource(
 | |
|                     's3',
 | |
|                     aws_access_key_id=aws_access_key_id,
 | |
|                     aws_secret_access_key=aws_secret_access_key,
 | |
|                     endpoint_url=region
 | |
|                 )
 | |
|             else:
 | |
|                 s3 = boto3.resource(
 | |
|                     's3',
 | |
|                     aws_access_key_id=aws_access_key_id,
 | |
|                     aws_secret_access_key=aws_secret_access_key,
 | |
|                 )
 | |
|             bucket = s3.Bucket(plan.bucket)
 | |
|             key = '%s/%s/' % (plan.name, self.data['domainName'])
 | |
| 
 | |
|             backups = []
 | |
| 
 | |
|             for file in bucket.objects.filter(Prefix=key):
 | |
|                 backups.append({'key': file.key, 'size': file.size})
 | |
| 
 | |
|             json_data = "["
 | |
|             checker = 0
 | |
| 
 | |
|             counter = 1
 | |
|             for items in backups:
 | |
| 
 | |
|                 dic = {'id': counter,
 | |
|                        'file': items['key'],
 | |
|                        'size': items['size'],
 | |
|                        }
 | |
|                 counter = counter + 1
 | |
| 
 | |
|                 if checker == 0:
 | |
|                     json_data = json_data + json.dumps(dic)
 | |
|                     checker = 1
 | |
|                 else:
 | |
|                     json_data = json_data + ',' + json.dumps(dic)
 | |
| 
 | |
|             json_data = json_data + ']'
 | |
|             final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": json_data})
 | |
|             return HttpResponse(final_json)
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def deleteS3Backup(self):
 | |
|         try:
 | |
| 
 | |
|             import boto3
 | |
|             from s3Backups.models import BackupPlan, BackupLogs
 | |
|             plan = BackupPlan.objects.get(name=self.data['planName'])
 | |
| 
 | |
|             aws_access_key_id, aws_secret_access_key, region = self.fetchAWSKeys()
 | |
| 
 | |
|             if region.find('http') > -1:
 | |
|                 s3 = boto3.resource(
 | |
|                     's3',
 | |
|                     aws_access_key_id=aws_access_key_id,
 | |
|                     aws_secret_access_key=aws_secret_access_key,
 | |
|                     endpoint_url=region
 | |
|                 )
 | |
|             else:
 | |
|                 s3 = boto3.resource(
 | |
|                     's3',
 | |
|                     aws_access_key_id=aws_access_key_id,
 | |
|                     aws_secret_access_key=aws_secret_access_key,
 | |
|                 )
 | |
| 
 | |
|             s3.Object(plan.bucket, self.data['backupFile']).delete()
 | |
| 
 | |
|             final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None"})
 | |
|             return HttpResponse(final_json)
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def SubmitS3BackupRestore(self):
 | |
|         try:
 | |
| 
 | |
|             tempStatusPath = "/home/cyberpanel/" + str(randint(1000, 9999))
 | |
| 
 | |
|             writeToFile = open(tempStatusPath, 'w')
 | |
|             writeToFile.write('Starting..,0')
 | |
|             writeToFile.close()
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/plogical/backupUtilities.py"
 | |
|             execPath = execPath + " SubmitS3BackupRestore --backupDomain %s --backupFile '%s' --tempStoragePath %s --planName %s" % (
 | |
|                 self.data['domain'], self.data['backupFile'], tempStatusPath, self.data['planName'])
 | |
|             ProcessUtilities.popenExecutioner(execPath)
 | |
| 
 | |
|             final_dic = {'status': 1, 'tempStatusPath': tempStatusPath}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def DeployWordPress(self):
 | |
|         try:
 | |
| 
 | |
|             tempStatusPath = "/home/cyberpanel/" + str(randint(1000, 9999))
 | |
| 
 | |
|             writeToFile = open(tempStatusPath, 'w')
 | |
|             writeToFile.write('Starting..,0')
 | |
|             writeToFile.close()
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/plogical/applicationInstaller.py"
 | |
|             execPath = execPath + " DeployWordPress --tempStatusPath %s --appsSet '%s' --domain '%s' --email '%s' --password '%s' " \
 | |
|                                   "--pluginUpdates '%s' --themeUpdates '%s' --title '%s' --updates '%s' --userName '%s' " \
 | |
|                                   "--version '%s' --createSite %s" % (
 | |
|                            tempStatusPath, self.data['appsSet'], self.data['domain'], self.data['email'],
 | |
|                            self.data['passwordByPass'],
 | |
|                            self.data['pluginUpdates'], self.data['themeUpdates'], self.data['title'],
 | |
|                            self.data['updates'],
 | |
|                            self.data['userName'], self.data['version'], str(self.data['createSite']))
 | |
| 
 | |
|             try:
 | |
|                 execPath = '%s --path %s' % (execPath, self.data['path'])
 | |
|             except:
 | |
|                 pass
 | |
| 
 | |
|             ProcessUtilities.popenExecutioner(execPath)
 | |
| 
 | |
|             final_dic = {'status': 1, 'tempStatusPath': tempStatusPath}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def FetchWordPressDetails(self):
 | |
|         try:
 | |
| 
 | |
|             finalDic = {}
 | |
|             domain = self.data['domain']
 | |
|             finalDic['status'] = 1
 | |
|             finalDic['maintenanceMode'] = 1
 | |
|             finalDic['php'] = '7.4'
 | |
| 
 | |
|             ## Get versopm
 | |
| 
 | |
|             website = Websites.objects.get(domain=domain)
 | |
| 
 | |
|             try:
 | |
|                 from cloudAPI.models import WPDeployments
 | |
|                 wpd = WPDeployments.objects.get(owner=website)
 | |
|                 path = json.loads(wpd.config)['path']
 | |
|                 path = '/home/%s/public_html/%s' % (self.data['domain'], path)
 | |
| 
 | |
|             except:
 | |
|                 path = '/home/%s/public_html' % (self.data['domain'])
 | |
| 
 | |
|             command = 'wp core version --skip-plugins --skip-themes --path=%s 2>/dev/null' % (path)
 | |
|             finalDic['version'] = str(ProcessUtilities.outputExecutioner(command, website.externalApp, True))
 | |
| 
 | |
|             ## LSCache
 | |
| 
 | |
|             command = 'wp plugin status litespeed-cache --skip-plugins --skip-themes --path=%s' % (path)
 | |
|             result = str(ProcessUtilities.outputExecutioner(command, website.externalApp))
 | |
| 
 | |
|             if result.find('Status: Active') > -1:
 | |
|                 finalDic['lscache'] = 1
 | |
|             else:
 | |
|                 finalDic['lscache'] = 0
 | |
| 
 | |
|             ## Debug
 | |
| 
 | |
|             try:
 | |
|                 command = 'wp config list --skip-plugins --skip-themes --path=%s' % (path)
 | |
|                 result = ProcessUtilities.outputExecutioner(command, website.externalApp).split('\n')
 | |
|                 finalDic['debugging'] = 0
 | |
|                 for items in result:
 | |
|                     if items.find('WP_DEBUG') > -1 and items.find('1') > - 1:
 | |
|                         finalDic['debugging'] = 1
 | |
|                         break
 | |
|             except BaseException as msg:
 | |
|                 finalDic['debugging'] = 0
 | |
|                 logging.writeToFile('Error fetching WordPress debug mode for %s. [404]' % (website.domain))
 | |
| 
 | |
|             ## Search index
 | |
| 
 | |
|             try:
 | |
|                 command = 'wp option get blog_public --skip-plugins --skip-themes --path=%s' % (path)
 | |
|                 finalDic['searchIndex'] = int(
 | |
|                     ProcessUtilities.outputExecutioner(command, website.externalApp).splitlines()[-1])
 | |
|             except BaseException as msg:
 | |
|                 logging.writeToFile('Error fetching WordPress searchIndex mode for %s. [404]' % (website.domain))
 | |
|                 finalDic['searchIndex'] = 0
 | |
| 
 | |
|             ## Maintenece mode
 | |
| 
 | |
|             try:
 | |
| 
 | |
|                 command = 'wp maintenance-mode status --skip-plugins --skip-themes --path=%s' % (path)
 | |
|                 result = ProcessUtilities.outputExecutioner(command, website.externalApp).splitlines()[-1]
 | |
| 
 | |
|                 if result.find('not active') > -1:
 | |
|                     finalDic['maintenanceMode'] = 0
 | |
|                 else:
 | |
|                     finalDic['maintenanceMode'] = 1
 | |
|             except BaseException as msg:
 | |
|                 logging.writeToFile('Error fetching WordPress maintenanceMode mode for %s. [404]' % (website.domain))
 | |
|                 finalDic['maintenanceMode'] = 0
 | |
| 
 | |
|             ## Get title
 | |
| 
 | |
|             try:
 | |
|                 command = 'wp option get blogname --skip-plugins --skip-themes --path=%s' % (path)
 | |
|                 finalDic['title'] = ProcessUtilities.outputExecutioner(command, website.externalApp).splitlines()[-1]
 | |
|             except:
 | |
|                 logging.writeToFile('Error fetching WordPress Title for %s. [404]' % (website.domain))
 | |
|                 finalDic['title'] = 'CyberPanel'
 | |
| 
 | |
|             ##
 | |
| 
 | |
|             final_json = json.dumps(finalDic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def AutoLogin(self):
 | |
|         try:
 | |
| 
 | |
|             ## Get versopm
 | |
| 
 | |
|             website = Websites.objects.get(domain=self.data['domain'])
 | |
| 
 | |
|             try:
 | |
|                 from cloudAPI.models import WPDeployments
 | |
|                 wpd = WPDeployments.objects.get(owner=website)
 | |
|                 path = json.loads(wpd.config)['path']
 | |
|                 path = '/home/%s/public_html/%s' % (self.data['domain'], path)
 | |
| 
 | |
|             except:
 | |
|                 path = '/home/%s/public_html' % (self.data['domain'])
 | |
| 
 | |
|             ## Get title
 | |
| 
 | |
|             import plogical.randomPassword as randomPassword
 | |
|             password = randomPassword.generate_pass(32)
 | |
| 
 | |
|             command = 'wp user create cyberpanel support@cyberpanel.cloud --role=administrator --user_pass="%s" --path=%s --skip-plugins --skip-themes' % (
 | |
|                 password, path)
 | |
|             ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|             command = 'wp user update cyberpanel --user_pass="%s" --path=%s --skip-plugins --skip-themes' % (password,
 | |
|                                                                                                              path)
 | |
|             ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|             finalDic = {'status': 1, 'password': password}
 | |
|             final_json = json.dumps(finalDic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def UpdateWPSettings(self):
 | |
|         try:
 | |
| 
 | |
|             website = Websites.objects.get(domain=self.data['domain'])
 | |
|             domain = self.data['domain']
 | |
| 
 | |
|             try:
 | |
|                 from cloudAPI.models import WPDeployments
 | |
|                 wpd = WPDeployments.objects.get(owner=website)
 | |
|                 path = json.loads(wpd.config)['path']
 | |
|                 path = '/home/%s/public_html/%s' % (self.data['domain'], path)
 | |
| 
 | |
|             except:
 | |
|                 path = '/home/%s/public_html' % (self.data['domain'])
 | |
| 
 | |
|             if self.data['setting'] == 'lscache':
 | |
|                 if self.data['settingValue']:
 | |
| 
 | |
|                     command = "wp plugin install litespeed-cache --path=%s --skip-plugins --skip-themes" % (path)
 | |
|                     ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|                     command = "wp plugin activate litespeed-cache --path=%s --skip-plugins --skip-themes" % (path)
 | |
|                     ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|                     final_dic = {'status': 1, 'message': 'LSCache successfully installed and activated.'}
 | |
|                     final_json = json.dumps(final_dic)
 | |
|                     return HttpResponse(final_json)
 | |
|                 else:
 | |
|                     command = 'wp plugin deactivate litespeed-cache --path=%s --skip-plugins --skip-themes' % (path)
 | |
|                     ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|                     final_dic = {'status': 1, 'message': 'LSCache successfully deactivated.'}
 | |
|                     final_json = json.dumps(final_dic)
 | |
|                     return HttpResponse(final_json)
 | |
|             elif self.data['setting'] == 'debugging':
 | |
| 
 | |
|                 command = "wp litespeed-purge all --path=%s --skip-plugins --skip-themes" % (path)
 | |
|                 ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|                 if self.data['settingValue']:
 | |
|                     command = "wp config set WP_DEBUG true --path=%s --skip-plugins --skip-themes" % (path)
 | |
|                     ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|                     final_dic = {'status': 1, 'message': 'WordPress is now in debug mode.'}
 | |
|                     final_json = json.dumps(final_dic)
 | |
|                     return HttpResponse(final_json)
 | |
| 
 | |
|                 else:
 | |
|                     command = "wp config set WP_DEBUG false --path=%s --skip-plugins --skip-themes" % (path)
 | |
|                     ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|                     final_dic = {'status': 1, 'message': 'WordPress debug mode turned off.'}
 | |
|                     final_json = json.dumps(final_dic)
 | |
|                     return HttpResponse(final_json)
 | |
|             elif self.data['setting'] == 'searchIndex':
 | |
| 
 | |
|                 command = "wp litespeed-purge all --path=%s --skip-plugins --skip-themes" % (path)
 | |
|                 ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|                 if self.data['settingValue']:
 | |
|                     command = "wp option update blog_public 1 --path=%s --skip-plugins --skip-themes" % (path)
 | |
|                     ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|                     final_dic = {'status': 1, 'message': 'Search Engine Indexing enabled.'}
 | |
|                     final_json = json.dumps(final_dic)
 | |
|                     return HttpResponse(final_json)
 | |
| 
 | |
|                 else:
 | |
|                     command = "wp option update blog_public 0 --path=%s --skip-plugins --skip-themes" % (path)
 | |
|                     ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|                     final_dic = {'status': 1, 'message': 'Search Engine Indexing disabled.'}
 | |
|                     final_json = json.dumps(final_dic)
 | |
|                     return HttpResponse(final_json)
 | |
|             elif self.data['setting'] == 'maintenanceMode':
 | |
| 
 | |
|                 command = "wp litespeed-purge all --path=%s --skip-plugins --skip-themes" % (path)
 | |
|                 ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|                 if self.data['settingValue']:
 | |
| 
 | |
|                     command = "wp maintenance-mode activate --path=%s --skip-plugins --skip-themes" % (path)
 | |
|                     ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|                     final_dic = {'status': 1, 'message': 'WordPress Maintenance mode turned on.'}
 | |
|                     final_json = json.dumps(final_dic)
 | |
|                     return HttpResponse(final_json)
 | |
| 
 | |
|                 else:
 | |
|                     command = "wp maintenance-mode deactivate --path=%s --skip-plugins --skip-themes" % (path)
 | |
|                     ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|                     final_dic = {'status': 1, 'message': 'WordPress Maintenance mode turned off.'}
 | |
|                     final_json = json.dumps(final_dic)
 | |
|                     return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def GetCurrentPlugins(self):
 | |
|         try:
 | |
|             website = Websites.objects.get(domain=self.data['domain'])
 | |
| 
 | |
|             try:
 | |
|                 from cloudAPI.models import WPDeployments
 | |
|                 wpd = WPDeployments.objects.get(owner=website)
 | |
|                 path = json.loads(wpd.config)['path']
 | |
|                 path = '/home/%s/public_html/%s' % (self.data['domain'], path)
 | |
| 
 | |
|             except:
 | |
|                 path = '/home/%s/public_html' % (self.data['domain'])
 | |
| 
 | |
|             command = 'wp plugin list --skip-plugins --skip-themes --format=json --path=%s' % (path)
 | |
|             json_data = ProcessUtilities.outputExecutioner(command, website.externalApp).splitlines()[-1]
 | |
|             final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": json_data})
 | |
| 
 | |
|             return HttpResponse(final_json)
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def UpdatePlugins(self):
 | |
|         try:
 | |
|             website = Websites.objects.get(domain=self.data['domain'])
 | |
| 
 | |
|             try:
 | |
|                 from cloudAPI.models import WPDeployments
 | |
|                 wpd = WPDeployments.objects.get(owner=website)
 | |
|                 path = json.loads(wpd.config)['path']
 | |
|                 path = '/home/%s/public_html/%s' % (self.data['domain'], path)
 | |
| 
 | |
|             except:
 | |
|                 path = '/home/%s/public_html' % (self.data['domain'])
 | |
| 
 | |
|             if self.data['plugin'] == 'all':
 | |
|                 command = 'wp plugin update --all --skip-plugins --skip-themes --path=%s' % (path)
 | |
|                 ProcessUtilities.popenExecutioner(command, website.externalApp)
 | |
|                 final_json = json.dumps(
 | |
|                     {'status': 1, 'fetchStatus': 1, 'message': "Plugin updates started in the background."})
 | |
|                 return HttpResponse(final_json)
 | |
|             elif self.data['plugin'] == 'selected':
 | |
|                 if self.data['allPluginsChecked']:
 | |
|                     command = 'wp plugin update --all --skip-plugins --skip-themes --path=%s' % (path)
 | |
|                     ProcessUtilities.popenExecutioner(command, website.externalApp)
 | |
|                     final_json = json.dumps(
 | |
|                         {'status': 1, 'fetchStatus': 1, 'message': "Plugin updates started in the background."})
 | |
|                     return HttpResponse(final_json)
 | |
|                 else:
 | |
|                     pluginsList = ''
 | |
| 
 | |
|                     for plugin in self.data['plugins']:
 | |
|                         pluginsList = '%s %s' % (pluginsList, plugin)
 | |
| 
 | |
|                     command = 'wp plugin update %s --skip-plugins --skip-themes --path=%s' % (pluginsList, path)
 | |
|                     ProcessUtilities.popenExecutioner(command, website.externalApp)
 | |
|                     final_json = json.dumps(
 | |
|                         {'status': 1, 'fetchStatus': 1, 'message': "Plugin updates started in the background."})
 | |
|                     return HttpResponse(final_json)
 | |
|             else:
 | |
|                 command = 'wp plugin update %s --skip-plugins --skip-themes --path=%s' % (self.data['plugin'], path)
 | |
|                 ProcessUtilities.popenExecutioner(command, website.externalApp)
 | |
|                 final_json = json.dumps(
 | |
|                     {'status': 1, 'fetchStatus': 1, 'message': "Plugin updates started in the background."})
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def ChangeState(self):
 | |
|         try:
 | |
|             website = Websites.objects.get(domain=self.data['domain'])
 | |
| 
 | |
|             try:
 | |
|                 from cloudAPI.models import WPDeployments
 | |
|                 wpd = WPDeployments.objects.get(owner=website)
 | |
|                 path = json.loads(wpd.config)['path']
 | |
|                 path = '/home/%s/public_html/%s' % (self.data['domain'], path)
 | |
| 
 | |
|             except:
 | |
|                 path = '/home/%s/public_html' % (self.data['domain'])
 | |
| 
 | |
|             command = 'wp plugin status %s --skip-plugins --skip-themes --path=%s' % (self.data['plugin'], path)
 | |
|             result = ProcessUtilities.outputExecutioner(command, website.externalApp)
 | |
| 
 | |
|             if result.find('Status: Active') > -1:
 | |
|                 command = 'wp plugin deactivate %s --skip-plugins --skip-themes --path=%s' % (self.data['plugin'], path)
 | |
|                 ProcessUtilities.executioner(command, website.externalApp)
 | |
|                 final_json = json.dumps(
 | |
|                     {'status': 1, 'fetchStatus': 1, 'message': "Plugin successfully deactivated."})
 | |
|                 return HttpResponse(final_json)
 | |
|             else:
 | |
|                 command = 'wp plugin activate %s --skip-plugins --skip-themes --path=%s' % (
 | |
|                     self.data['plugin'], path)
 | |
|                 ProcessUtilities.executioner(command, website.externalApp)
 | |
|                 final_json = json.dumps(
 | |
|                     {'status': 1, 'fetchStatus': 1, 'message': "Plugin successfully activated."})
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def DeletePlugins(self):
 | |
|         try:
 | |
|             website = Websites.objects.get(domain=self.data['domain'])
 | |
| 
 | |
|             try:
 | |
|                 from cloudAPI.models import WPDeployments
 | |
|                 wpd = WPDeployments.objects.get(owner=website)
 | |
|                 path = json.loads(wpd.config)['path']
 | |
|                 path = '/home/%s/public_html/%s' % (self.data['domain'], path)
 | |
| 
 | |
|             except:
 | |
|                 path = '/home/%s/public_html' % (self.data['domain'])
 | |
| 
 | |
|             if self.data['plugin'] == 'selected':
 | |
|                 pluginsList = ''
 | |
| 
 | |
|                 for plugin in self.data['plugins']:
 | |
|                     pluginsList = '%s %s' % (pluginsList, plugin)
 | |
| 
 | |
|                 command = 'wp plugin delete %s --skip-plugins --skip-themes --path=%s' % (pluginsList, path)
 | |
|                 ProcessUtilities.popenExecutioner(command, website.externalApp)
 | |
|                 final_json = json.dumps(
 | |
|                     {'status': 1, 'fetchStatus': 1, 'message': "Plugin deletion started in the background."})
 | |
|                 return HttpResponse(final_json)
 | |
|             else:
 | |
|                 command = 'wp plugin delete %s --skip-plugins --skip-themes --path=%s' % (self.data['plugin'], path)
 | |
|                 ProcessUtilities.popenExecutioner(command, website.externalApp)
 | |
|                 final_json = json.dumps(
 | |
|                     {'status': 1, 'fetchStatus': 1, 'message': "Plugin deletion started in the background."})
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def GetCurrentThemes(self):
 | |
|         try:
 | |
| 
 | |
|             website = Websites.objects.get(domain=self.data['domain'])
 | |
| 
 | |
|             try:
 | |
|                 from cloudAPI.models import WPDeployments
 | |
|                 wpd = WPDeployments.objects.get(owner=website)
 | |
|                 path = json.loads(wpd.config)['path']
 | |
|                 path = '/home/%s/public_html/%s' % (self.data['domain'], path)
 | |
| 
 | |
|             except:
 | |
|                 path = '/home/%s/public_html' % (self.data['domain'])
 | |
| 
 | |
|             command = 'wp theme list --skip-plugins --skip-themes --format=json --path=%s' % (path)
 | |
|             json_data = ProcessUtilities.outputExecutioner(command, website.externalApp).splitlines()[-1]
 | |
|             final_json = json.dumps({'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": json_data})
 | |
|             return HttpResponse(final_json)
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def UpdateThemes(self):
 | |
|         try:
 | |
|             website = Websites.objects.get(domain=self.data['domain'])
 | |
| 
 | |
|             try:
 | |
|                 from cloudAPI.models import WPDeployments
 | |
|                 wpd = WPDeployments.objects.get(owner=website)
 | |
|                 path = json.loads(wpd.config)['path']
 | |
|                 path = '/home/%s/public_html/%s' % (self.data['domain'], path)
 | |
| 
 | |
|             except:
 | |
|                 path = '/home/%s/public_html' % (self.data['domain'])
 | |
| 
 | |
|             if self.data['plugin'] == 'all':
 | |
|                 command = 'wp theme update --all --skip-plugins --skip-themes --path=%s' % (path)
 | |
|                 ProcessUtilities.popenExecutioner(command, website.externalApp)
 | |
|                 final_json = json.dumps(
 | |
|                     {'status': 1, 'fetchStatus': 1, 'message': "Theme updates started in the background."})
 | |
|                 return HttpResponse(final_json)
 | |
|             elif self.data['plugin'] == 'selected':
 | |
|                 if self.data['allPluginsChecked']:
 | |
|                     command = 'wp theme update --all --skip-plugins --skip-themes --path=%s' % (path)
 | |
|                     ProcessUtilities.popenExecutioner(command, website.externalApp)
 | |
|                     final_json = json.dumps(
 | |
|                         {'status': 1, 'fetchStatus': 1, 'message': "Theme updates started in the background."})
 | |
|                     return HttpResponse(final_json)
 | |
|                 else:
 | |
|                     pluginsList = ''
 | |
| 
 | |
|                     for plugin in self.data['plugins']:
 | |
|                         pluginsList = '%s %s' % (pluginsList, plugin)
 | |
| 
 | |
|                     command = 'wp theme update %s --skip-plugins --skip-themes --path=%s' % (pluginsList, path)
 | |
|                     ProcessUtilities.popenExecutioner(command, website.externalApp)
 | |
|                     final_json = json.dumps(
 | |
|                         {'status': 1, 'fetchStatus': 1, 'message': "Theme updates started in the background."})
 | |
|                     return HttpResponse(final_json)
 | |
|             else:
 | |
|                 command = 'wp theme update %s --skip-plugins --skip-themes --path=%s' % (self.data['plugin'], path)
 | |
|                 ProcessUtilities.popenExecutioner(command, website.externalApp)
 | |
|                 final_json = json.dumps(
 | |
|                     {'status': 1, 'fetchStatus': 1, 'message': "Theme updates started in the background."})
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def ChangeStateThemes(self):
 | |
|         try:
 | |
|             website = Websites.objects.get(domain=self.data['domain'])
 | |
| 
 | |
|             try:
 | |
|                 from cloudAPI.models import WPDeployments
 | |
|                 wpd = WPDeployments.objects.get(owner=website)
 | |
|                 path = json.loads(wpd.config)['path']
 | |
|                 path = '/home/%s/public_html/%s' % (self.data['domain'], path)
 | |
| 
 | |
|             except:
 | |
|                 path = '/home/%s/public_html' % (self.data['domain'])
 | |
| 
 | |
|             command = 'wp theme status %s --skip-plugins --skip-themes --path=%s' % (self.data['plugin'], path)
 | |
|             result = ProcessUtilities.outputExecutioner(command, website.externalApp)
 | |
| 
 | |
|             if result.find('Status: Active') > -1:
 | |
|                 command = 'wp theme deactivate %s --skip-plugins --skip-themes --path=%s' % (
 | |
|                     self.data['plugin'], path)
 | |
|                 ProcessUtilities.executioner(command, website.externalApp)
 | |
|                 final_json = json.dumps(
 | |
|                     {'status': 1, 'fetchStatus': 1, 'message': "Theme successfully deactivated."})
 | |
|                 return HttpResponse(final_json)
 | |
|             else:
 | |
|                 command = 'wp theme activate %s --skip-plugins --skip-themes --path=%s' % (
 | |
|                     self.data['plugin'], path)
 | |
|                 ProcessUtilities.executioner(command, website.externalApp)
 | |
|                 final_json = json.dumps(
 | |
|                     {'status': 1, 'fetchStatus': 1, 'message': "Theme successfully activated."})
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def DeleteThemes(self):
 | |
|         try:
 | |
|             website = Websites.objects.get(domain=self.data['domain'])
 | |
| 
 | |
|             try:
 | |
|                 from cloudAPI.models import WPDeployments
 | |
|                 wpd = WPDeployments.objects.get(owner=website)
 | |
|                 path = json.loads(wpd.config)['path']
 | |
|                 path = '/home/%s/public_html/%s' % (self.data['domain'], path)
 | |
| 
 | |
|             except:
 | |
|                 path = '/home/%s/public_html' % (self.data['domain'])
 | |
| 
 | |
|             if self.data['plugin'] == 'selected':
 | |
|                 pluginsList = ''
 | |
| 
 | |
|                 for plugin in self.data['plugins']:
 | |
|                     pluginsList = '%s %s' % (pluginsList, plugin)
 | |
| 
 | |
|                 command = 'wp theme delete %s --skip-plugins --skip-themes --path=%s' % (pluginsList, path)
 | |
|                 ProcessUtilities.popenExecutioner(command, website.externalApp)
 | |
|                 final_json = json.dumps(
 | |
|                     {'status': 1, 'fetchStatus': 1, 'message': "Plugin Theme started in the background."})
 | |
|                 return HttpResponse(final_json)
 | |
|             else:
 | |
|                 command = 'wp theme delete %s --skip-plugins --skip-themes --path=%s' % (self.data['plugin'], path)
 | |
|                 ProcessUtilities.popenExecutioner(command, website.externalApp)
 | |
|                 final_json = json.dumps(
 | |
|                     {'status': 1, 'fetchStatus': 1, 'message': "Theme deletion started in the background."})
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def GetServerPublicSSHkey(self):
 | |
|         try:
 | |
| 
 | |
|             path = '/root/.ssh/cyberpanel.pub'
 | |
|             command = 'cat %s' % (path)
 | |
|             key = ProcessUtilities.outputExecutioner(command)
 | |
| 
 | |
|             final_dic = {'status': 1, 'key': key}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def SubmitPublicKey(self):
 | |
|         try:
 | |
| 
 | |
|             fm = FirewallManager()
 | |
|             fm.addSSHKey(self.admin.pk, self.data)
 | |
| 
 | |
|             ## Create backup path so that file can be sent here later. If just submitting the key, no need to create backup folder domain.
 | |
| 
 | |
|             try:
 | |
|                 BackupPath = '/home/cyberpanel/backups/%s' % (self.data['domain'])
 | |
|                 command = 'mkdir -p %s' % (BackupPath)
 | |
|                 ProcessUtilities.executioner(command, 'cyberpanel')
 | |
|             except:
 | |
|                 pass
 | |
| 
 | |
|             ###
 | |
| 
 | |
|             from WebTerminal.CPWebSocket import SSHServer
 | |
|             SSHServer.findSSHPort()
 | |
| 
 | |
|             final_dic = {'status': 1, 'port': SSHServer.DEFAULT_PORT}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def CreateStaging(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             wm = WebsiteManager()
 | |
|             return wm.startCloning(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def startSync(self, request):
 | |
|         try:
 | |
|             request.session['userID'] = self.admin.pk
 | |
|             wm = WebsiteManager()
 | |
|             return wm.startSync(self.admin.pk, self.data)
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def SaveAutoUpdateSettings(self):
 | |
|         try:
 | |
|             website = Websites.objects.get(domain=self.data['domainName'])
 | |
|             domainName = self.data['domainName']
 | |
|             from cloudAPI.models import WPDeployments
 | |
| 
 | |
|             try:
 | |
|                 wpd = WPDeployments.objects.get(owner=website)
 | |
|                 config = json.loads(wpd.config)
 | |
|             except:
 | |
|                 wpd = WPDeployments(owner=website)
 | |
|                 config = {}
 | |
| 
 | |
|             try:
 | |
|                 from cloudAPI.models import WPDeployments
 | |
|                 wpd = WPDeployments.objects.get(owner=website)
 | |
|                 path = json.loads(wpd.config)['path']
 | |
|                 path = '/home/%s/public_html/%s' % (self.data['domain'], path)
 | |
| 
 | |
|             except:
 | |
|                 path = '/home/%s/public_html' % (self.data['domain'])
 | |
| 
 | |
|             config['updates'] = self.data['wpCore']
 | |
|             config['pluginUpdates'] = self.data['plugins']
 | |
|             config['themeUpdates'] = self.data['themes']
 | |
|             wpd.config = json.dumps(config)
 | |
|             wpd.save()
 | |
| 
 | |
|             if self.data['wpCore'] == 'Disabled':
 | |
|                 command = "wp config set WP_AUTO_UPDATE_CORE false --skip-plugins --skip-themes --raw --path=%s" % (
 | |
|                     path)
 | |
|                 ProcessUtilities.executioner(command, website.externalApp)
 | |
|             elif self.data['wpCore'] == 'Minor and Security Updates':
 | |
|                 command = "wp config set WP_AUTO_UPDATE_CORE minor --skip-plugins --skip-themes --allow-root --path=%s" % (
 | |
|                     path)
 | |
|                 ProcessUtilities.executioner(command, website.externalApp)
 | |
|             else:
 | |
|                 command = "wp config set WP_AUTO_UPDATE_CORE true --raw --allow-root --path=%s" % (path)
 | |
|                 ProcessUtilities.executioner(command, website.externalApp)
 | |
| 
 | |
|             final_json = json.dumps(
 | |
|                 {'status': 1, 'message': "Autoupdates configured."})
 | |
|             return HttpResponse(final_json)
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def fetchWPSettings(self):
 | |
|         try:
 | |
| 
 | |
|             cliVersion = ProcessUtilities.outputExecutioner('wp --version --allow-root')
 | |
| 
 | |
|             if cliVersion.find('not found') > -1:
 | |
|                 cliVersion = 'WP CLI Not installed.'
 | |
| 
 | |
|             if ProcessUtilities.decideDistro() == ProcessUtilities.centos or ProcessUtilities.decideDistro() == ProcessUtilities.cent8:
 | |
|                 localCronPath = "/var/spool/cron/root"
 | |
|             else:
 | |
|                 localCronPath = "/var/spool/cron/crontabs/root"
 | |
| 
 | |
|             cronData = ProcessUtilities.outputExecutioner('cat %s' % (localCronPath)).split('\n')
 | |
| 
 | |
|             finalCron = ''
 | |
|             for cronLine in cronData:
 | |
|                 if cronLine.find('WPAutoUpdates.py') > -1:
 | |
|                     finalCron = cronLine
 | |
| 
 | |
|             if finalCron.find('WPAutoUpdates.py') == -1:
 | |
|                 finalCron = 'Not Set'
 | |
| 
 | |
|             final_json = json.dumps(
 | |
|                 {'status': 1, 'cliVersion': cliVersion, 'finalCron': finalCron})
 | |
|             return HttpResponse(final_json)
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def updateWPCLI(self):
 | |
|         try:
 | |
| 
 | |
|             command = 'wp cli update'
 | |
|             ProcessUtilities.executioner(command)
 | |
|             final_json = json.dumps({'status': 1})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def saveWPSettings(self):
 | |
|         try:
 | |
| 
 | |
|             command = 'wp cli update'
 | |
|             ProcessUtilities.executioner(command)
 | |
|             final_json = json.dumps({'status': 1})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def WPScan(self):
 | |
|         try:
 | |
| 
 | |
|             path = '/home/%s/public_html' % (self.data['domainName'])
 | |
| 
 | |
|             command = 'wp core version --allow-root --skip-plugins --skip-themes --path=%s 2>/dev/null' % (path)
 | |
|             result = ProcessUtilities.outputExecutioner(command, None, True)
 | |
| 
 | |
|             if result.find('Error:') > -1:
 | |
|                 final_dic = {'status': 0, 'fetchStatus': 0,
 | |
|                              'error_message': 'This does not seem to be a WordPress installation'}
 | |
|                 final_json = json.dumps(final_dic)
 | |
|                 return HttpResponse(final_json)
 | |
|             else:
 | |
|                 final_json = json.dumps({'status': 1})
 | |
|                 return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def SubmitCyberPanelUpgrade(self):
 | |
|         try:
 | |
|             try:
 | |
|                 mail = str(int(self.data['mail']))
 | |
|             except:
 | |
|                 mail = '0'
 | |
| 
 | |
|             try:
 | |
|                 dns = str(int(self.data['dns']))
 | |
|             except:
 | |
|                 dns = '0'
 | |
| 
 | |
|             try:
 | |
|                 ftp = str(int(self.data['ftp']))
 | |
|             except:
 | |
|                 ftp = '0'
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/CyberPanelUpgrade.py --branch %s --mail %s --dns %s --ftp %s" % (
 | |
|                 self.data['CyberPanelBranch'], mail, dns, ftp)
 | |
| 
 | |
|             ProcessUtilities.executioner(execPath)
 | |
|             final_json = json.dumps({'status': 1})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def DetachCluster(self):
 | |
|         try:
 | |
| 
 | |
|             type = self.data['type']
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/ClusterManager.py --function %s --type %s" % (
 | |
|                 'DetachCluster', type)
 | |
|             ProcessUtilities.executioner(execPath)
 | |
| 
 | |
|             final_json = json.dumps({'status': 1})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def SetupCluster(self):
 | |
|         try:
 | |
| 
 | |
|             ClusterConfigPath = '/home/cyberpanel/cluster'
 | |
|             writeToFile = open(ClusterConfigPath, 'w')
 | |
|             writeToFile.write(json.dumps(self.data))
 | |
|             writeToFile.close()
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/ClusterManager.py --function SetupCluster --type %s" % (
 | |
|             self.data['type'])
 | |
|             ProcessUtilities.executioner(execPath)
 | |
| 
 | |
|             final_json = json.dumps({'status': 1})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def FetchMasterBootStrapStatus(self):
 | |
|         try:
 | |
|             from CyberCP import settings
 | |
| 
 | |
|             data = {}
 | |
|             data['status'] = 1
 | |
| 
 | |
|             ## CyberPanel DB Creds
 | |
|             data['dbName'] = settings.DATABASES['default']['NAME']
 | |
|             data['dbUser'] = settings.DATABASES['default']['USER']
 | |
|             data['password'] = settings.DATABASES['default']['PASSWORD']
 | |
|             data['host'] = settings.DATABASES['default']['HOST']
 | |
|             data['port'] = settings.DATABASES['default']['PORT']
 | |
| 
 | |
|             ## Root DB Creds
 | |
| 
 | |
|             data['rootdbName'] = settings.DATABASES['rootdb']['NAME']
 | |
|             data['rootdbdbUser'] = settings.DATABASES['rootdb']['USER']
 | |
|             data['rootdbpassword'] = settings.DATABASES['rootdb']['PASSWORD']
 | |
| 
 | |
|             command = 'cat /var/lib/mysql/grastate.dat'
 | |
|             output = ProcessUtilities.outputExecutioner(command)
 | |
| 
 | |
|             if output.find('No such file or directory') > -1:
 | |
|                 data['safe'] = 1
 | |
|             elif output.find('safe_to_bootstrap: 1') > -1:
 | |
|                 data['safe'] = 1
 | |
|             else:
 | |
|                 data['safe'] = 0
 | |
| 
 | |
|             final_json = json.dumps(data)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def FetchChildBootStrapStatus(self):
 | |
|         try:
 | |
| 
 | |
|             data = {}
 | |
|             data['status'] = 1
 | |
| 
 | |
|             command = 'cat /var/lib/mysql/grastate.dat'
 | |
|             output = ProcessUtilities.outputExecutioner(command)
 | |
| 
 | |
|             if output.find('No such file or directory') > -1:
 | |
|                 data['safe'] = 1
 | |
|             elif output.find('safe_to_bootstrap: 0') > -1:
 | |
|                 data['safe'] = 1
 | |
|             else:
 | |
|                 data['safe'] = 0
 | |
| 
 | |
|             final_json = json.dumps(data)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def BootMaster(self):
 | |
|         try:
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/ClusterManager.py --function BootMaster --type Master"
 | |
|             ProcessUtilities.executioner(execPath)
 | |
| 
 | |
|             final_json = json.dumps({'status': 1})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def BootChild(self):
 | |
|         try:
 | |
| 
 | |
|             ChildData = '/home/cyberpanel/childaata'
 | |
|             writeToFile = open(ChildData, 'w')
 | |
|             writeToFile.write(json.dumps(self.data))
 | |
|             writeToFile.close()
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/ClusterManager.py --function BootChild --type Child"
 | |
|             ProcessUtilities.executioner(execPath)
 | |
| 
 | |
|             final_json = json.dumps({'status': 1})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def CreatePendingVirtualHosts(self):
 | |
|         try:
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/ClusterManager.py --function CreatePendingVirtualHosts --type Child"
 | |
|             ProcessUtilities.popenExecutioner(execPath)
 | |
| 
 | |
|             final_json = json.dumps({'status': 1})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def SwitchDNS(self):
 | |
|         try:
 | |
| 
 | |
|             command = 'chown -R cyberpanel:cyberpanel /usr/local/CyberCP/lib/python3.8/site-packages/tldextract/.suffix_cache/'
 | |
|             ProcessUtilities.executioner(command)
 | |
| 
 | |
|             command = 'chown cyberpanel:cyberpanel -R /usr/local/CyberCP/lib/python3.8/site-packages/tldextract/.suffix_cache'
 | |
|             ProcessUtilities.executioner(command)
 | |
| 
 | |
|             command = 'chown cyberpanel:cyberpanel -R /usr/local/CyberCP/lib/python*/site-packages/tldextract/.suffix_cache'
 | |
|             ProcessUtilities.executioner(command, None, True)
 | |
| 
 | |
|             ##
 | |
| 
 | |
|             ipFile = "/etc/cyberpanel/machineIP"
 | |
|             f = open(ipFile)
 | |
|             ipData = f.read()
 | |
|             ipAddress = ipData.split('\n', 1)[0]
 | |
| 
 | |
|             ##
 | |
| 
 | |
|             import CloudFlare
 | |
|             cf = CloudFlare.CloudFlare(email=self.data['cfemail'], token=self.data['apikey'])
 | |
| 
 | |
|             zones = cf.zones.get(params={'per_page': 100})
 | |
| 
 | |
|             for website in Websites.objects.all():
 | |
|                 import tldextract
 | |
|                 no_cache_extract = tldextract.TLDExtract(cache_dir=None)
 | |
|                 extractDomain = no_cache_extract(website.domain)
 | |
|                 topLevelDomain = extractDomain.domain + '.' + extractDomain.suffix
 | |
| 
 | |
|                 for zone in zones:
 | |
|                     if topLevelDomain == zone['name']:
 | |
|                         try:
 | |
|                             dns_records = cf.zones.dns_records.get(zone['id'], params={'name': website.domain})
 | |
| 
 | |
|                             for dns_record in dns_records:
 | |
|                                 r_zone_id = dns_record['zone_id']
 | |
|                                 r_id = dns_record['id']
 | |
|                                 r_name = dns_record['name']
 | |
|                                 r_type = dns_record['type']
 | |
|                                 r_ttl = dns_record['ttl']
 | |
|                                 r_proxied = dns_record['proxied']
 | |
| 
 | |
|                                 dns_record_id = dns_record['id']
 | |
| 
 | |
|                                 new_dns_record = {
 | |
|                                     'zone_id': r_zone_id,
 | |
|                                     'id': r_id,
 | |
|                                     'type': r_type,
 | |
|                                     'name': r_name,
 | |
|                                     'content': ipAddress,
 | |
|                                     'ttl': r_ttl,
 | |
|                                     'proxied': r_proxied
 | |
|                                 }
 | |
| 
 | |
|                                 cf.zones.dns_records.put(zone['id'], dns_record_id, data=new_dns_record)
 | |
| 
 | |
|                         except:
 | |
|                             pass
 | |
| 
 | |
|             ### For child domainsa
 | |
| 
 | |
|             command = 'chown cyberpanel:cyberpanel -R /usr/local/CyberCP/lib/python3.6/site-packages/tldextract/.suffix_cache'
 | |
|             ProcessUtilities.executioner(command)
 | |
| 
 | |
|             command = 'chown cyberpanel:cyberpanel -R /usr/local/CyberCP/lib/python3.8/site-packages/tldextract/.suffix_cache'
 | |
|             ProcessUtilities.executioner(command)
 | |
| 
 | |
|             command = 'chown cyberpanel:cyberpanel -R /usr/local/CyberCP/lib/python*/site-packages/tldextract/.suffix_cache'
 | |
|             ProcessUtilities.executioner(command, None, True)
 | |
| 
 | |
|             from websiteFunctions.models import ChildDomains
 | |
|             for website in ChildDomains.objects.all():
 | |
| 
 | |
|                 import tldextract
 | |
|                 no_cache_extract = tldextract.TLDExtract(cache_dir=None)
 | |
|                 extractDomain = no_cache_extract(website.domain)
 | |
|                 topLevelDomain = extractDomain.domain + '.' + extractDomain.suffix
 | |
| 
 | |
|                 for zone in zones:
 | |
|                     if topLevelDomain == zone['name']:
 | |
|                         try:
 | |
|                             dns_records = cf.zones.dns_records.get(zone['id'], params={'name': website.domain})
 | |
| 
 | |
|                             for dns_record in dns_records:
 | |
|                                 r_zone_id = dns_record['zone_id']
 | |
|                                 r_id = dns_record['id']
 | |
|                                 r_name = dns_record['name']
 | |
|                                 r_type = dns_record['type']
 | |
|                                 r_ttl = dns_record['ttl']
 | |
|                                 r_proxied = dns_record['proxied']
 | |
| 
 | |
|                                 dns_record_id = dns_record['id']
 | |
| 
 | |
|                                 new_dns_record = {
 | |
|                                     'zone_id': r_zone_id,
 | |
|                                     'id': r_id,
 | |
|                                     'type': r_type,
 | |
|                                     'name': r_name,
 | |
|                                     'content': ipAddress,
 | |
|                                     'ttl': r_ttl,
 | |
|                                     'proxied': r_proxied
 | |
|                                 }
 | |
| 
 | |
|                                 cf.zones.dns_records.put(zone['id'], dns_record_id, data=new_dns_record)
 | |
| 
 | |
|                         except:
 | |
|                             pass
 | |
| 
 | |
|             final_json = json.dumps({'status': 1})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             logging.writeToFile(str(msg))
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def DebugCluster(self):
 | |
|         try:
 | |
| 
 | |
|             type = self.data['type']
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/ClusterManager.py --function %s --type %s" % (
 | |
|                 'DebugCluster', type)
 | |
|             ProcessUtilities.executioner(execPath)
 | |
| 
 | |
|             final_json = json.dumps({'status': 1})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def UptimeMonitor(self):
 | |
|         try:
 | |
|             try:
 | |
|                 del self.data['controller']
 | |
|                 del self.data['serverUserName']
 | |
|                 del self.data['serverPassword']
 | |
|             except:
 | |
|                 pass
 | |
| 
 | |
|             CloudConfigPath = '/home/cyberpanel/cloud'
 | |
|             writeToFile = open(CloudConfigPath, 'w')
 | |
|             writeToFile.write(json.dumps(self.data))
 | |
|             writeToFile.close()
 | |
| 
 | |
|             execPath = "/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/ClusterManager.py --function UptimeMonitor --type All"
 | |
|             ProcessUtilities.executioner(execPath)
 | |
| 
 | |
|             final_json = json.dumps({'status': 1})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def CheckMasterNode(self):
 | |
|         try:
 | |
| 
 | |
|             command = 'systemctl status mysql'
 | |
|             result = ProcessUtilities.outputExecutioner(command)
 | |
| 
 | |
|             if result.find('active (running)') > -1:
 | |
|                 final_json = json.dumps({'status': 1})
 | |
|             else:
 | |
|                 final_json = json.dumps({'status': 0, 'error_message': 'MySQL on Main node is not running.'})
 | |
| 
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|     def SyncToMaster(self):
 | |
|         try:
 | |
| 
 | |
|             command = '/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/ClusterManager.py --function SyncToMaster --type Failover'
 | |
|             ProcessUtilities.executioner(command)
 | |
| 
 | |
|             final_json = json.dumps({'status': 1})
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)}
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
| 
 | |
|     def installN8N(self):
 | |
|         try:
 | |
|             import time
 | |
|             from websiteFunctions.models import Websites
 | |
|             from packages.models import Package
 | |
|             from random import randint
 | |
|             import re
 | |
|             import threading
 | |
|             from plogical.processUtilities import ProcessUtilities
 | |
|             from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
 | |
|             from plogical import randomPassword
 | |
| 
 | |
|             # Validate required parameters
 | |
|             domain_name = self.data.get('domainName')
 | |
|             if not domain_name:
 | |
|                 return self.ajaxPre(0, 'domainName is required')
 | |
| 
 | |
|             # Validate domain name format
 | |
|             if not re.match(r'^[a-zA-Z0-9][a-zA-Z0-9\-\.]*[a-zA-Z0-9]$', domain_name):
 | |
|                 return self.ajaxPre(0, 'Invalid domain name format')
 | |
| 
 | |
|             # Create status file path
 | |
|             tempStatusPath = "/home/cyberpanel/" + str(randint(1000, 9999))
 | |
| 
 | |
|             # Prepare website data
 | |
|             website_data = {
 | |
|                 'domainName': domain_name,
 | |
|                 'adminEmail': self.data.get('adminEmail', f'admin@{domain_name}'),
 | |
|                 'phpSelection': 'PHP 8.1',
 | |
|                 'websiteOwner': self.data.get('websiteOwner', self.data.get('Owner', 'admin')),
 | |
|                 'package': self.data.get('package', 'Default'),
 | |
|                 'ssl': 1,
 | |
|                 'dkimCheck': 0,
 | |
|                 'openBasedir': 0,
 | |
|                 'mailDomain': 0
 | |
|             }
 | |
| 
 | |
|             # Extract n8n parameters
 | |
|             n8n_username = self.data.get('n8nUsername', self.data.get('WPusername', 'admin'))
 | |
|             n8n_password = self.data.get('n8nPassword',
 | |
|                                          self.data.get('WPpasswd', 'changeme' + str(randint(1000, 9999))))
 | |
|             n8n_email = self.data.get('n8nEmail', self.data.get('WPemal', website_data['adminEmail']))
 | |
|             n8n_port = self.data.get('port', self._find_available_n8n_port())
 | |
| 
 | |
|             # Database parameters will be generated by native process
 | |
|             db_name = None  # Will be generated in thread
 | |
|             db_user = None  # Will be generated in thread
 | |
|             db_password = None  # Will be generated in thread
 | |
| 
 | |
|             # Create a new user for this n8n installation
 | |
|             n8n_system_user = domain_name.replace('.', '_').replace('-', '_')[:32]  # Max 32 chars for username
 | |
|             n8n_user_password = randomPassword.generate_pass()
 | |
|             
 | |
|             try:
 | |
|                 # Check if user already exists
 | |
|                 from loginSystem.models import Administrator, ACL
 | |
|                 existing_user = Administrator.objects.filter(userName=n8n_system_user).first()
 | |
|                 if not existing_user:
 | |
|                     user_acl = ACL.objects.get(name='user')
 | |
|                     
 | |
|                     new_user = Administrator(
 | |
|                         firstName=f"n8n_{domain_name}"[:50],  # Limit to 50 chars
 | |
|                         lastName="",
 | |
|                         email=website_data['adminEmail'],
 | |
|                         type=3,  # Normal user
 | |
|                         userName=n8n_system_user,
 | |
|                         password=n8n_user_password,
 | |
|                         initWebsitesLimit=1,
 | |
|                         owner=self.admin.pk,
 | |
|                         acl=user_acl,
 | |
|                         token="",
 | |
|                         api=0
 | |
|                     )
 | |
|                     new_user.save()
 | |
|                     logging.writeToFile(f"[installN8N] Created new user: {n8n_system_user}")
 | |
|                     website_data['websiteOwner'] = n8n_system_user
 | |
|                 else:
 | |
|                     n8n_system_user = existing_user.userName
 | |
|                     logging.writeToFile(f"[installN8N] Using existing user: {n8n_system_user}")
 | |
|                     website_data['websiteOwner'] = n8n_system_user
 | |
|             except Exception as e:
 | |
|                 logging.writeToFile(f"[installN8N] Failed to create user: {str(e)}")
 | |
|                 # Fall back to admin if user creation fails
 | |
|                 n8n_system_user = 'admin'
 | |
|                 website_data['websiteOwner'] = 'admin'
 | |
| 
 | |
|             # Create initial status file
 | |
|             try:
 | |
|                 writeToFile = open(tempStatusPath, 'w')
 | |
|                 writeToFile.write('Starting n8n installation...,0\n')
 | |
|                 writeToFile.close()
 | |
|                 logging.writeToFile(f"[installN8N] Created status file at: {tempStatusPath}")
 | |
|             except Exception as e:
 | |
|                 logging.writeToFile(f"[installN8N] Failed to create status file: {str(e)}")
 | |
|                 return self.ajaxPre(0, f"Failed to create status file: {str(e)}")
 | |
| 
 | |
|             # Start background installation including website creation
 | |
|             try:
 | |
|                 logging.writeToFile(f"[installN8N] Creating thread for domain: {domain_name}")
 | |
|                 logging.writeToFile(f"[installN8N] Admin object: {self.admin}, Admin PK: {self.admin.pk if self.admin else 'None'}")
 | |
|                 installation_thread = threading.Thread(
 | |
|                     target=self._install_n8n_with_website,
 | |
|                     args=(self.admin.pk, website_data, domain_name, n8n_username, n8n_password, n8n_email, n8n_port,
 | |
|                           db_name, db_user, db_password, tempStatusPath)
 | |
|                 )
 | |
|                 installation_thread.daemon = True
 | |
|                 installation_thread.start()
 | |
|                 logging.writeToFile(f"[installN8N] Thread started successfully for: {domain_name}")
 | |
|             except Exception as e:
 | |
|                 logging.writeToFile(f"[installN8N] Failed to start thread: {str(e)}")
 | |
|                 return self.ajaxPre(0, f"Failed to start installation thread: {str(e)}")
 | |
| 
 | |
|             # Return response immediately with domain identifier for status checking
 | |
|             final_dic = {
 | |
|                 'status': 1,
 | |
|                 'installStatus': 1,
 | |
|                 'error_message': 'None',
 | |
|                 'tempStatusPath': tempStatusPath,
 | |
|                 'domainIdentifier': domain_name.replace('.', '_'),
 | |
|                 'message': f'n8n installation started for {domain_name}',
 | |
|                 'n8nUsername': n8n_username,
 | |
|                 'n8nPort': n8n_port,
 | |
|                 'systemUser': n8n_system_user
 | |
|             }
 | |
| 
 | |
|             # Add password only if auto-generated
 | |
|             if 'n8nPassword' not in self.data and 'WPpasswd' not in self.data:
 | |
|                 final_dic['n8nPassword'] = n8n_password
 | |
|             
 | |
|             # Add system user password if new user was created
 | |
|             if n8n_system_user != 'admin' and 'n8n_user_password' in locals():
 | |
|                 final_dic['systemUserPassword'] = n8n_user_password
 | |
| 
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def _install_n8n_with_website(self, admin_pk, website_data, domain_name, n8n_username, n8n_password, n8n_email, n8n_port,
 | |
|                                   db_name, db_user, db_password, status_file_path):
 | |
|         """
 | |
|         Create website and install n8n in a single thread
 | |
|         """
 | |
|         # Import logging first to ensure we can log errors
 | |
|         from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
 | |
|         logging.writeToFile(f"[_install_n8n_with_website] Thread started for domain: {domain_name}")
 | |
|         logging.writeToFile(f"[_install_n8n_with_website] Status file path: {status_file_path}")
 | |
|         
 | |
|         # Initialize a simple status writer immediately
 | |
|         try:
 | |
|             with open(status_file_path, 'w') as f:
 | |
|                 f.write('Thread started...,1\n')
 | |
|         except Exception as e:
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] Failed to write initial status: {str(e)}")
 | |
|         
 | |
|         try:
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] Entering main try block")
 | |
|             
 | |
|             # Try a simpler approach - just import what we need
 | |
|             import os
 | |
|             import sys
 | |
|             import time
 | |
|             import json
 | |
|             
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] About to import modules")
 | |
|             
 | |
|             from plogical.processUtilities import ProcessUtilities
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] Imported ProcessUtilities")
 | |
|             
 | |
|             from websiteFunctions.models import Websites
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] Imported Websites")
 | |
|             
 | |
|             from websiteFunctions.website import WebsiteManager
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] Imported WebsiteManager")
 | |
|             
 | |
|             from databases.models import Databases
 | |
|             from plogical import randomPassword
 | |
|             from plogical.mysqlUtilities import mysqlUtilities
 | |
|             from loginSystem.models import Administrator
 | |
|             
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] All imports complete")
 | |
|             
 | |
|             # Initialize status writer - use file handle directly
 | |
|             class StatusWriter:
 | |
|                 def __init__(self, path):
 | |
|                     self.path = path
 | |
|                 
 | |
|                 def writeToFile(self, message):
 | |
|                     with open(self.path, 'a') as f:
 | |
|                         f.write(message + '\n')
 | |
|             
 | |
|             statusWriter = StatusWriter(status_file_path)
 | |
|             statusWriter.writeToFile('Starting website creation and n8n installation...,5')
 | |
|             
 | |
|             # Get administrator object
 | |
|             try:
 | |
|                 logging.writeToFile(f"[_install_n8n_with_website] Attempting to get admin with pk={admin_pk}")
 | |
|                 admin = Administrator.objects.get(pk=admin_pk)
 | |
|                 logging.writeToFile(f"[_install_n8n_with_website] Found admin: {admin.userName}")
 | |
|             except Administrator.DoesNotExist:
 | |
|                 logging.writeToFile(f"[_install_n8n_with_website] Administrator.DoesNotExist - pk={admin_pk}")
 | |
|                 statusWriter.writeToFile(f"Administrator with pk={admin_pk} not found [404]")
 | |
|                 return
 | |
|             except Exception as e:
 | |
|                 logging.writeToFile(f"[_install_n8n_with_website] Error getting admin: {str(e)}")
 | |
|                 statusWriter.writeToFile(f"Error getting administrator: {str(e)} [404]")
 | |
|                 return
 | |
|             
 | |
|             # Step 1: Create the website
 | |
|             statusWriter.writeToFile('Creating website...,10')
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] Creating website for {domain_name}")
 | |
|             wm = WebsiteManager()
 | |
|             result = wm.submitWebsiteCreation(admin.pk, website_data)
 | |
|             result_data = json.loads(result.content)
 | |
|             
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] Website creation result: {result_data}")
 | |
|             
 | |
|             if result_data.get('createWebSiteStatus', 0) != 1:
 | |
|                 statusWriter.writeToFile(f"Failed to create website: {result_data.get('error_message', 'Unknown error')} [404]")
 | |
|                 return
 | |
|             
 | |
|             # Wait for website creation to complete - no time limit
 | |
|             creation_status_path = result_data.get('tempStatusPath')
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] Website creation status path: {creation_status_path}")
 | |
|             
 | |
|             if creation_status_path:
 | |
|                 statusWriter.writeToFile('Waiting for website creation to complete (including SSL)...,15')
 | |
|                 check_count = 0
 | |
|                 while True:
 | |
|                     try:
 | |
|                         with open(creation_status_path, 'r') as f:
 | |
|                             status = f.read()
 | |
|                             if '[200]' in status:
 | |
|                                 logging.writeToFile(f"[_install_n8n_with_website] Website creation completed successfully")
 | |
|                                 break
 | |
|                             elif '[404]' in status:
 | |
|                                 logging.writeToFile(f"[_install_n8n_with_website] Website creation failed: {status}")
 | |
|                                 statusWriter.writeToFile(f"Website creation failed: {status} [404]")
 | |
|                                 return
 | |
|                     except Exception as e:
 | |
|                         if check_count % 10 == 0:  # Log every 10 checks
 | |
|                             logging.writeToFile(f"[_install_n8n_with_website] Still waiting for website creation... (check #{check_count})")
 | |
|                     
 | |
|                     check_count += 1
 | |
|                     time.sleep(1)
 | |
|             
 | |
|             # Get the created website object
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] Getting website object for {domain_name}")
 | |
|             try:
 | |
|                 website = Websites.objects.get(domain=domain_name)
 | |
|                 logging.writeToFile(f"[_install_n8n_with_website] Found website object: {website.domain}")
 | |
|             except Websites.DoesNotExist:
 | |
|                 logging.writeToFile(f"[_install_n8n_with_website] Website object not found for {domain_name}")
 | |
|                 statusWriter.writeToFile('Website creation succeeded but website object not found [404]')
 | |
|                 return
 | |
|             except Exception as e:
 | |
|                 logging.writeToFile(f"[_install_n8n_with_website] Error getting website object: {str(e)}")
 | |
|                 statusWriter.writeToFile(f'Error getting website object: {str(e)} [404]')
 | |
|                 return
 | |
|             
 | |
|             statusWriter.writeToFile('Website created successfully...,20')
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] Website creation phase complete")
 | |
|             
 | |
|             # Step 2: Create database using native CyberPanel process
 | |
|             statusWriter.writeToFile('Creating database using CyberPanel...,25')
 | |
|             db_result = self._createDatabaseForN8N(status_file_path, website)
 | |
|             
 | |
|             # Check if database creation failed
 | |
|             if db_result == 0:
 | |
|                 logging.writeToFile(f"[_install_n8n_with_website] Database creation failed")
 | |
|                 return
 | |
|             
 | |
|             # Database creation successful - unpack the tuple
 | |
|             db_name, db_user, db_password, db_type = db_result
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] Database created with type: {db_type}")
 | |
|             
 | |
|             statusWriter.writeToFile('Database created successfully...,30')
 | |
|             
 | |
|             # Step 3: Install n8n on the website
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] About to call _install_n8n_custom")
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] Parameters: domain={domain_name}")
 | |
|             
 | |
|             try:
 | |
|                 self._install_n8n_custom(website, domain_name, n8n_username, n8n_password, n8n_email, n8n_port,
 | |
|                                        db_name, db_user, db_password, db_type, status_file_path, statusWriter)
 | |
|                 logging.writeToFile(f"[_install_n8n_with_website] _install_n8n_custom completed")
 | |
|                 
 | |
|                 # Write final success status with [200]
 | |
|                 statusWriter.writeToFile('n8n installation completed successfully [200]')
 | |
|             except Exception as e:
 | |
|                 logging.writeToFile(f"[_install_n8n_with_website] Error calling _install_n8n_custom: {str(e)}")
 | |
|                 statusWriter.writeToFile(f"Error during n8n installation: {str(e)} [404]")
 | |
|                 raise
 | |
|             
 | |
|         except BaseException as msg:
 | |
|             error_msg = str(msg) if str(msg) else "Unknown error occurred"
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] BaseException caught: {error_msg}")
 | |
|             import traceback
 | |
|             tb = traceback.format_exc()
 | |
|             logging.writeToFile(f"[_install_n8n_with_website] Traceback: {tb}")
 | |
|             try:
 | |
|                 statusWriter.writeToFile(f'Error in installation: {error_msg} [404]')
 | |
|             except:
 | |
|                 # Try to write error directly to file
 | |
|                 try:
 | |
|                     with open(status_file_path, 'a') as f:
 | |
|                         f.write(f'Error in installation: {error_msg} [404]\n')
 | |
|                 except Exception as e:
 | |
|                     logging.writeToFile(f"[_install_n8n_with_website] Failed to write error to status file: {str(e)}")
 | |
|             return
 | |
|     
 | |
|     def _setupPostgreSQLForN8N(self):
 | |
|         """
 | |
|         Setup PostgreSQL for n8n if not already installed
 | |
|         Returns: (success, postgres_password, error_message)
 | |
|         """
 | |
|         try:
 | |
|             from plogical.processUtilities import ProcessUtilities
 | |
|             from plogical import randomPassword
 | |
|             import json
 | |
|             import os
 | |
|             
 | |
|             # Check if PostgreSQL is installed
 | |
|             check_postgres = ProcessUtilities.outputExecutioner("which psql", 'root')
 | |
|             logging.writeToFile(f"[_setupPostgreSQLForN8N] PostgreSQL check result: '{check_postgres}'")
 | |
|             
 | |
|             if not check_postgres or 'psql' not in check_postgres or 'not found' in check_postgres or check_postgres.strip() == '':
 | |
|                 logging.writeToFile("[_setupPostgreSQLForN8N] PostgreSQL not found, installing...")
 | |
|                 
 | |
|                 # Detect OS and use appropriate package manager
 | |
|                 distro = ProcessUtilities.decideDistro()
 | |
|                 logging.writeToFile(f"[_setupPostgreSQLForN8N] Detected distro: {distro}, centos={ProcessUtilities.centos}, cent8={ProcessUtilities.cent8}, cent9={ProcessUtilities.cent9}, ubuntu={ProcessUtilities.ubuntu}")
 | |
|                 
 | |
|                 if distro == ProcessUtilities.centos or distro == ProcessUtilities.cent8 or distro == ProcessUtilities.cent9:
 | |
|                     # CentOS/AlmaLinux/Rocky Linux
 | |
|                     install_commands = [
 | |
|                         "yum install -y epel-release",
 | |
|                         "yum install -y postgresql postgresql-server postgresql-contrib",
 | |
|                         "postgresql-setup initdb"
 | |
|                     ]
 | |
|                 else:
 | |
|                     # Ubuntu/Debian
 | |
|                     install_commands = [
 | |
|                         "DEBIAN_FRONTEND=noninteractive apt-get update",
 | |
|                         "DEBIAN_FRONTEND=noninteractive apt-get install -y postgresql postgresql-contrib"
 | |
|                     ]
 | |
|                 
 | |
|                 # Additional check - if apt-get exists, force Ubuntu commands
 | |
|                 apt_check = ProcessUtilities.outputExecutioner("which apt-get", 'root')
 | |
|                 if apt_check and 'apt-get' in apt_check:
 | |
|                     logging.writeToFile("[_setupPostgreSQLForN8N] Found apt-get, using Ubuntu/Debian commands")
 | |
|                     install_commands = [
 | |
|                         "DEBIAN_FRONTEND=noninteractive apt-get update",
 | |
|                         "DEBIAN_FRONTEND=noninteractive apt-get install -y postgresql postgresql-contrib"
 | |
|                     ]
 | |
| 
 | |
| 
 | |
|                 # Execute installation commands
 | |
|                 for cmd in install_commands:
 | |
|                     logging.writeToFile(f"[_setupPostgreSQLForN8N] Running: {cmd}")
 | |
|                     result, output = ProcessUtilities.outputExecutioner(cmd, 'root', shell=True, retRequired=True)
 | |
|                     if result != 1:
 | |
|                         logging.writeToFile(f"[_setupPostgreSQLForN8N] Command '{cmd}' failed with output: {output}")
 | |
|                         return False, None, f"Failed to install PostgreSQL: {output}"
 | |
|                     else:
 | |
|                         logging.writeToFile(f"[_setupPostgreSQLForN8N] Command '{cmd}' succeeded")
 | |
| 
 | |
|                 
 | |
|                 # Verify PostgreSQL installation
 | |
|                 verify_postgres = ProcessUtilities.outputExecutioner("which psql", 'root')
 | |
|                 logging.writeToFile(f"[_setupPostgreSQLForN8N] PostgreSQL verification result: '{verify_postgres}'")
 | |
|                 
 | |
|                 # Also try common PostgreSQL binary locations
 | |
|                 if not verify_postgres or 'psql' not in verify_postgres:
 | |
|                     # Check common locations
 | |
|                     common_paths = ["/usr/bin/psql", "/usr/local/bin/psql", "/usr/pgsql-*/bin/psql"]
 | |
|                     for path in common_paths:
 | |
|                         check_path = ProcessUtilities.outputExecutioner(f"ls {path} 2>/dev/null", 'root')
 | |
|                         if check_path and 'psql' in check_path:
 | |
|                             verify_postgres = check_path
 | |
|                             logging.writeToFile(f"[_setupPostgreSQLForN8N] Found psql at: {path}")
 | |
|                             break
 | |
|                 
 | |
|                 if not verify_postgres or ('psql' not in verify_postgres and 'No such' not in verify_postgres):
 | |
|                     # Try to find psql with find command
 | |
|                     find_psql = ProcessUtilities.outputExecutioner("find /usr -name psql -type f 2>/dev/null | head -1", 'root')
 | |
|                     if find_psql and 'psql' in find_psql:
 | |
|                         verify_postgres = find_psql
 | |
|                         logging.writeToFile(f"[_setupPostgreSQLForN8N] Found psql using find: {find_psql}")
 | |
|                     else:
 | |
|                         logging.writeToFile("[_setupPostgreSQLForN8N] PostgreSQL installation verification failed")
 | |
|                         return False, None, "PostgreSQL installation failed - psql not found"
 | |
|                 
 | |
|                 logging.writeToFile(f"[_setupPostgreSQLForN8N] PostgreSQL installed successfully, psql found at: {verify_postgres.strip()}")
 | |
|             
 | |
|             # Check/Load PostgreSQL password
 | |
|             postgres_pass_file = "/etc/cyberpanel/postgresqlPassword"
 | |
|             postgres_password = None
 | |
|             
 | |
|             if os.path.exists(postgres_pass_file):
 | |
|                 try:
 | |
|                     with open(postgres_pass_file, 'r') as f:
 | |
|                         postgres_data = json.loads(f.read())
 | |
|                         postgres_password = postgres_data.get('postgrespassword')
 | |
|                         logging.writeToFile("[_setupPostgreSQLForN8N] Loaded existing PostgreSQL credentials")
 | |
|                 except:
 | |
|                     pass
 | |
|             
 | |
|             if not postgres_password:
 | |
|                 # Generate new password
 | |
|                 postgres_password = randomPassword.generate_pass(32)
 | |
|                 
 | |
|                 # Save password to file
 | |
|                 postgres_data = {
 | |
|                     'postgrespassword': postgres_password,
 | |
|                     'postgresport': '5433',
 | |
|                     'postgreshost': 'localhost'
 | |
|                 }
 | |
|                 
 | |
|                 # Create directory if it doesn't exist
 | |
|                 ProcessUtilities.executioner("mkdir -p /etc/cyberpanel", 'root', True)
 | |
|                 
 | |
|                 # Write to temp file first, then move with proper permissions
 | |
|                 temp_file = f"/tmp/postgres_pass_{randomPassword.generate_pass()[:8]}.json"
 | |
|                 try:
 | |
|                     with open(temp_file, 'w') as f:
 | |
|                         json.dump(postgres_data, f, indent=2)
 | |
|                     
 | |
|                     # Move file with root permissions
 | |
|                     ProcessUtilities.executioner(f"mv {temp_file} {postgres_pass_file}", 'root', True)
 | |
|                     ProcessUtilities.executioner(f"chmod 600 {postgres_pass_file}", 'root', True)
 | |
|                     ProcessUtilities.executioner(f"chown root:root {postgres_pass_file}", 'root', True)
 | |
|                     
 | |
|                     logging.writeToFile("[_setupPostgreSQLForN8N] Generated new PostgreSQL credentials")
 | |
|                 except Exception as e:
 | |
|                     logging.writeToFile(f"[_setupPostgreSQLForN8N] Error saving credentials: {str(e)}")
 | |
|                     if os.path.exists(temp_file):
 | |
|                         os.remove(temp_file)
 | |
|                     raise
 | |
|             
 | |
|             # Find PostgreSQL config file location
 | |
|             pg_config_paths = [
 | |
|                 "/etc/postgresql/*/main/postgresql.conf",  # Ubuntu/Debian
 | |
|                 "/var/lib/pgsql/data/postgresql.conf",     # CentOS/RHEL old
 | |
|                 "/var/lib/pgsql/*/data/postgresql.conf"    # CentOS/RHEL new
 | |
|             ]
 | |
|             
 | |
|             postgres_config = None
 | |
|             for path in pg_config_paths:
 | |
|                 check_cmd = f"ls {path} 2>/dev/null | head -1"
 | |
|                 result = ProcessUtilities.outputExecutioner(check_cmd, 'root')
 | |
|                 if result and not result.find('No such') > -1:
 | |
|                     postgres_config = result.strip()
 | |
|                     break
 | |
|             
 | |
|             if postgres_config:
 | |
|                 logging.writeToFile(f"[_setupPostgreSQLForN8N] Found PostgreSQL config at: {postgres_config}")
 | |
|                 # Update port in PostgreSQL config
 | |
|                 update_port_cmd = f"sed -i 's/^#*port = .*/port = 5433/' {postgres_config}"
 | |
|                 ProcessUtilities.executioner(update_port_cmd, 'root', True)
 | |
|                 
 | |
|                 # Also update listen_addresses
 | |
|                 update_listen_cmd = f"sed -i \"s/^#*listen_addresses = .*/listen_addresses = 'localhost'/\" {postgres_config}"
 | |
|                 ProcessUtilities.executioner(update_listen_cmd, 'root', True)
 | |
|                 
 | |
|                 # Update pg_hba.conf for password authentication
 | |
|                 pg_hba_path = postgres_config.replace('postgresql.conf', 'pg_hba.conf')
 | |
|                 if os.path.exists(pg_hba_path):
 | |
|                     logging.writeToFile(f"[_setupPostgreSQLForN8N] Updating pg_hba.conf at: {pg_hba_path}")
 | |
|                     # Allow password authentication for local connections
 | |
|                     hba_cmd = f"""sed -i 's/local   all             all                                     peer/local   all             all                                     md5/g' {pg_hba_path}"""
 | |
|                     ProcessUtilities.executioner(hba_cmd, 'root', True)
 | |
|                     # Also for host connections
 | |
|                     hba_cmd2 = f"""sed -i 's/host    all             all             127.0.0.1\/32            ident/host    all             all             127.0.0.1\/32            md5/g' {pg_hba_path}"""
 | |
|                     ProcessUtilities.executioner(hba_cmd2, 'root', True)
 | |
|             else:
 | |
|                 logging.writeToFile("[_setupPostgreSQLForN8N] Warning: PostgreSQL config not found, using default settings")
 | |
|             
 | |
|             # Enable and restart PostgreSQL
 | |
|             # First check which PostgreSQL service name is correct
 | |
|             service_names = ["postgresql", "postgresql-12", "postgresql-13", "postgresql-14", "postgresql-15"]
 | |
|             postgres_service = None
 | |
|             
 | |
|             for service in service_names:
 | |
|                 check_service = ProcessUtilities.outputExecutioner(f"systemctl list-unit-files | grep {service}.service", 'root')
 | |
|                 if check_service and service in check_service:
 | |
|                     postgres_service = service
 | |
|                     logging.writeToFile(f"[_setupPostgreSQLForN8N] Found PostgreSQL service: {service}")
 | |
|                     break
 | |
|             
 | |
|             if not postgres_service:
 | |
|                 postgres_service = "postgresql"  # Default fallback
 | |
|                 logging.writeToFile("[_setupPostgreSQLForN8N] Using default PostgreSQL service name")
 | |
|             
 | |
|             # Enable and start the service
 | |
|             enable_result = ProcessUtilities.executioner(f"systemctl enable {postgres_service}", 'root', True)
 | |
|             start_result = ProcessUtilities.executioner(f"systemctl restart {postgres_service}", 'root', True)
 | |
|             
 | |
|             if start_result != 1:
 | |
|                 logging.writeToFile(f"[_setupPostgreSQLForN8N] Failed to start {postgres_service} service")
 | |
|                 return False, None, f"Failed to start PostgreSQL service {postgres_service}"
 | |
|             
 | |
|             # Wait for PostgreSQL to start
 | |
|             import time
 | |
|             time.sleep(5)
 | |
|             
 | |
|             # Verify PostgreSQL is running
 | |
|             status_check = ProcessUtilities.outputExecutioner(f"systemctl is-active {postgres_service}", 'root')
 | |
|             if 'active' not in status_check:
 | |
|                 logging.writeToFile(f"[_setupPostgreSQLForN8N] PostgreSQL service not active: {status_check}")
 | |
|                 return False, None, "PostgreSQL service failed to start"
 | |
|             
 | |
|             # Set postgres user password - first try default port, then custom port
 | |
|             set_pass_cmd = f"""sudo -u postgres psql -c "ALTER USER postgres PASSWORD '{postgres_password}';" """
 | |
|             pass_result, pass_output = ProcessUtilities.outputExecutioner(set_pass_cmd, 'root', shell=True, retRequired=True)
 | |
|             
 | |
|             if pass_result != 1:
 | |
|                 # Try with custom port
 | |
|                 logging.writeToFile("[_setupPostgreSQLForN8N] Configuring authentication on port 5433")
 | |
|                 set_pass_cmd = f"""sudo -u postgres psql -p 5433 -c "ALTER USER postgres PASSWORD '{postgres_password}';" """
 | |
|                 pass_result, pass_output = ProcessUtilities.outputExecutioner(set_pass_cmd, 'root', shell=True, retRequired=True)
 | |
|                 
 | |
|                 if pass_result != 1:
 | |
|                     logging.writeToFile(f"[_setupPostgreSQLForN8N] Warning: Could not configure postgres authentication")
 | |
|             else:
 | |
|                 logging.writeToFile("[_setupPostgreSQLForN8N] Successfully configured postgres authentication")
 | |
|             
 | |
|             logging.writeToFile("[_setupPostgreSQLForN8N] PostgreSQL setup completed")
 | |
|             return True, postgres_password, None
 | |
|             
 | |
|         except Exception as e:
 | |
|             error_msg = f"PostgreSQL setup error: {str(e)}"
 | |
|             logging.writeToFile(f"[_setupPostgreSQLForN8N] {error_msg}")
 | |
|             return False, None, error_msg
 | |
|     
 | |
|     def _createDatabaseForN8N(self, tempStatusPath, website):
 | |
|         """
 | |
|         Create PostgreSQL database for n8n
 | |
|         Always uses PostgreSQL for n8n installations
 | |
|         """
 | |
|         try:
 | |
|             from databases.models import Databases
 | |
|             from plogical import randomPassword
 | |
|             from plogical.processUtilities import ProcessUtilities
 | |
|             import json
 | |
|             
 | |
|             # Generate database credentials - use lowercase for PostgreSQL compatibility
 | |
|             dbName = f"n8n_{randomPassword.generate_pass()[:12]}".lower()  # PostgreSQL converts to lowercase
 | |
|             dbUser = dbName
 | |
|             dbPassword = randomPassword.generate_pass()
 | |
|             
 | |
|             # Always use PostgreSQL for n8n
 | |
|             logging.writeToFile("[_createDatabaseForN8N] Setting up PostgreSQL for n8n")
 | |
|             postgres_success, postgres_password, postgres_error = self._setupPostgreSQLForN8N()
 | |
|             
 | |
|             if not postgres_success:
 | |
|                 logging.writeToFile(f"[_createDatabaseForN8N] PostgreSQL setup failed: {postgres_error}")
 | |
|                 statusFile = open(tempStatusPath, 'a')
 | |
|                 statusFile.writelines(f"PostgreSQL setup failed: {postgres_error} [404]\n")
 | |
|                 statusFile.close()
 | |
|                 return 0
 | |
|             
 | |
|             # Check if database or user already exists
 | |
|             if Databases.objects.filter(dbName=dbName).exists() or Databases.objects.filter(dbUser=dbUser).exists():
 | |
|                 statusFile = open(tempStatusPath, 'a')
 | |
|                 statusFile.writelines("This database or user is already taken. [404]\n")
 | |
|                 statusFile.close()
 | |
|                 return 0
 | |
|             
 | |
|             try:
 | |
|                 # Create PostgreSQL database and user - use separate commands for reliability
 | |
|                 logging.writeToFile(f"[_createDatabaseForN8N] Creating database with user")
 | |
|                 
 | |
|                 # Create user - use psql directly as it needs to run as postgres user
 | |
|                 create_user_cmd = f"psql -p 5433 -c \"CREATE USER {dbUser} WITH PASSWORD '{dbPassword}';\""
 | |
|                 user_result, user_output = ProcessUtilities.outputExecutioner(create_user_cmd, 'postgres', shell=True, retRequired=True)
 | |
|                 
 | |
|                 if user_result != 1:
 | |
|                     logging.writeToFile(f"[_createDatabaseForN8N] Failed to create user. Output: {user_output}")
 | |
|                     statusFile = open(tempStatusPath, 'a')
 | |
|                     statusFile.writelines(f"Failed to create PostgreSQL user: {user_output} [404]\n")
 | |
|                     statusFile.close()
 | |
|                     return 0
 | |
|                 
 | |
|                 # Create database
 | |
|                 create_db_cmd = f"psql -p 5433 -c \"CREATE DATABASE {dbName} OWNER {dbUser};\""
 | |
|                 db_result, db_output = ProcessUtilities.outputExecutioner(create_db_cmd, 'postgres', shell=True, retRequired=True)
 | |
|                 
 | |
|                 if db_result != 1:
 | |
|                     logging.writeToFile(f"[_createDatabaseForN8N] Failed to create database. Output: {db_output}")
 | |
|                     statusFile = open(tempStatusPath, 'a')
 | |
|                     statusFile.writelines(f"Failed to create PostgreSQL database: {db_output} [404]\n")
 | |
|                     statusFile.close()
 | |
|                     return 0
 | |
|                 
 | |
|                 # Grant privileges
 | |
|                 grant_cmd = f"psql -p 5433 -c \"GRANT ALL PRIVILEGES ON DATABASE {dbName} TO {dbUser};\""
 | |
|                 grant_result, grant_output = ProcessUtilities.outputExecutioner(grant_cmd, 'postgres', shell=True, retRequired=True)
 | |
|                 
 | |
|                 result = grant_result
 | |
|                 
 | |
|                 if result == 1:
 | |
|                     logging.writeToFile(f"[_createDatabaseForN8N] PostgreSQL database creation command executed")
 | |
|                     
 | |
|                     # Verify the database was actually created
 | |
|                     verify_cmd = f"psql -p 5433 -c \"SELECT datname FROM pg_database WHERE datname = '{dbName}';\""
 | |
|                     verify_result, verify_output = ProcessUtilities.outputExecutioner(verify_cmd, 'postgres', shell=True, retRequired=True)
 | |
|                     
 | |
|                     if verify_result == 1 and dbName in verify_output:
 | |
|                         logging.writeToFile(f"[_createDatabaseForN8N] PostgreSQL database verified successfully")
 | |
|                         
 | |
|                         # Save database record
 | |
|                         db = Databases(website=website, dbName=dbName, dbUser=dbUser)
 | |
|                         db.save()
 | |
|                         
 | |
|                         # Always return PostgreSQL type
 | |
|                         return dbName, dbUser, dbPassword, 'postgresql'
 | |
|                     else:
 | |
|                         logging.writeToFile(f"[_createDatabaseForN8N] PostgreSQL database verification failed. Output: {verify_output}")
 | |
|                         statusFile = open(tempStatusPath, 'a')
 | |
|                         statusFile.writelines("Failed to verify PostgreSQL database creation [404]\n")
 | |
|                         statusFile.close()
 | |
|                         return 0
 | |
|                 else:
 | |
|                     logging.writeToFile(f"[_createDatabaseForN8N] PostgreSQL database creation failed. Grant output: {grant_output}")
 | |
|                     statusFile = open(tempStatusPath, 'a')
 | |
|                     statusFile.writelines("Failed to create PostgreSQL database [404]\n")
 | |
|                     statusFile.close()
 | |
|                     return 0
 | |
|             except Exception as e:
 | |
|                 logging.writeToFile(f"[_createDatabaseForN8N] PostgreSQL error: {str(e)}")
 | |
|                 statusFile = open(tempStatusPath, 'a')
 | |
|                 statusFile.writelines(f"PostgreSQL database error: {str(e)} [404]\n")
 | |
|                 statusFile.close()
 | |
|                 return 0
 | |
|             
 | |
|         except BaseException as msg:
 | |
|             logging.writeToFile(str(msg) + '[CloudManager.createDatabaseForN8N]')
 | |
|             return 0
 | |
|     
 | |
|     def _find_available_n8n_port(self):
 | |
|         """Find an available port for n8n installation between 8000-9999"""
 | |
|         port_range_start = 8000
 | |
|         port_range_end = 9999
 | |
|         max_attempts = 10
 | |
|         
 | |
|         for _ in range(max_attempts):
 | |
|             port = random.randint(port_range_start, port_range_end)
 | |
|             
 | |
|             # Check if port is available
 | |
|             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 | |
|             try:
 | |
|                 result = sock.bind(('127.0.0.1', port))
 | |
|                 sock.close()
 | |
|                 
 | |
|                 # Also check if port is not already used by another n8n instance
 | |
|                 # by checking OpenLiteSpeed vhost configurations
 | |
|                 vhost_config_path = f'/usr/local/lsws/conf/vhosts/n8n_port_{port}'
 | |
|                 if not os.path.exists(vhost_config_path):
 | |
|                     return str(port)
 | |
|             except OSError:
 | |
|                 # Port is already in use
 | |
|                 continue
 | |
|             finally:
 | |
|                 try:
 | |
|                     sock.close()
 | |
|                 except:
 | |
|                     pass
 | |
|         
 | |
|         # If no available port found after max attempts, return a random one
 | |
|         return str(random.randint(port_range_start, port_range_end))
 | |
|     
 | |
|     def _install_n8n_custom(self, website, domain_name, n8n_username, n8n_password, n8n_email, n8n_port,
 | |
|                             db_name, db_user, db_password, db_type, status_file_path, statusWriter=None):
 | |
|         """
 | |
|         Install n8n using native installation method with MySQL/MariaDB or PostgreSQL
 | |
|         """
 | |
|         try:
 | |
|             from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
 | |
|             logging.writeToFile(f"[_install_n8n_custom] Starting installation for {domain_name}")
 | |
|             
 | |
|             from plogical.processUtilities import ProcessUtilities
 | |
|             from plogical.mysqlUtilities import mysqlUtilities
 | |
|             from plogical import randomPassword
 | |
|             import os
 | |
| 
 | |
|             # Initialize status writer if not provided
 | |
|             if statusWriter is None:
 | |
|                 class StatusWriter:
 | |
|                     def __init__(self, path):
 | |
|                         self.path = path
 | |
| 
 | |
| 
 | |
|                     def writeToFile(self, message):
 | |
|                         with open(self.path, 'a') as f:
 | |
|                             f.write(message + '\n')
 | |
| 
 | |
|                 statusWriter = StatusWriter(status_file_path)
 | |
|                 statusWriter.writeToFile('Starting n8n installation...')
 | |
|             # Website paths
 | |
|             website_home = f"/home/{website.domain}"
 | |
|             public_html = f"{website_home}/public_html"
 | |
|             n8n_dir = f"{website_home}/n8n"
 | |
| 
 | |
| 
 | |
|             # Get website user
 | |
| 
 | |
|             website_user = website.externalApp
 | |
| 
 | |
|             try:
 | |
|                 # Step 1: Create directory structure
 | |
|                 statusWriter.writeToFile('Creating directory structure...,10')
 | |
| 
 | |
|                 directories = [
 | |
|                     f"{n8n_dir}/app",
 | |
|                     f"{n8n_dir}/data",
 | |
|                     f"{n8n_dir}/logs",
 | |
|                     f"{n8n_dir}/config",
 | |
|                     f"{n8n_dir}/backup"
 | |
|                 ]
 | |
| 
 | |
|                 for directory in directories:
 | |
|                     command = f"mkdir -p {directory}"
 | |
|                     ProcessUtilities.executioner(command, website_user)
 | |
| 
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Directories created successfully")
 | |
| 
 | |
|                 # Database creation is now handled in _install_n8n_with_website
 | |
|                 statusWriter.writeToFile('Database setup complete...,30')
 | |
| 
 | |
|                 # Step 2.5: Install Node.js via nvm for the website user
 | |
|                 statusWriter.writeToFile('Installing Node.js for user...,35')
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Installing nvm for user {website_user}")
 | |
|                 
 | |
|                 # Download and install nvm
 | |
|                 # First download the script, then execute it
 | |
|                 nvm_script = f"{website_home}/nvm_install.sh"
 | |
|                 download_cmd = f"curl -o {nvm_script} https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh"
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Downloading nvm install script")
 | |
|                 
 | |
|                 try:
 | |
|                     # Download the script first
 | |
|                     download_result = ProcessUtilities.outputExecutioner(download_cmd, website_user, shell=True)
 | |
|                     if isinstance(download_result, tuple):
 | |
|                         status, output = download_result
 | |
|                         logging.writeToFile(f"[_install_n8n_custom] nvm download status: {status}, output: {output[:200]}")
 | |
|                         if status != 1:
 | |
|                             statusWriter.writeToFile(f'Failed to download nvm script: {output} [404]')
 | |
|                             return
 | |
|                     else:
 | |
|                         logging.writeToFile(f"[_install_n8n_custom] nvm download output: {download_result[:200]}")
 | |
|                     
 | |
|                     # Check if script was downloaded
 | |
|                     if not os.path.exists(nvm_script):
 | |
|                         logging.writeToFile(f"[_install_n8n_custom] nvm script not found at {nvm_script}")
 | |
|                         statusWriter.writeToFile(f'Failed to download nvm install script [404]')
 | |
|                         return
 | |
|                     
 | |
|                     # Make it executable
 | |
|                     ProcessUtilities.executioner(f"chmod +x {nvm_script}", website_user)
 | |
|                     
 | |
|                     # Now run the script
 | |
|                     install_cmd = f"bash {nvm_script}"
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Running nvm install script")
 | |
|                     install_output = ProcessUtilities.outputExecutioner(install_cmd, website_user, shell=True)
 | |
|                     if isinstance(install_output, tuple):
 | |
|                         status, output = install_output
 | |
|                         logging.writeToFile(f"[_install_n8n_custom] nvm install status: {status}, output: {output[:500]}")
 | |
|                         if status != 1:
 | |
|                             statusWriter.writeToFile(f'Failed to install nvm: {output} [404]')
 | |
|                             return
 | |
|                     else:
 | |
|                         logging.writeToFile(f"[_install_n8n_custom] nvm install output: {install_output[:500]}")
 | |
|                     
 | |
|                     # Add nvm to bashrc if not already there
 | |
|                     bashrc_path = f"{website_home}/.bashrc"
 | |
|                     nvm_source_line = 'export NVM_DIR="$HOME/.nvm"\n[ -s "$NVM_DIR/nvm.sh" ] && \\. "$NVM_DIR/nvm.sh"\n'
 | |
|                     
 | |
|                     # Create .bashrc if it doesn't exist and add nvm source lines
 | |
|                     # Use bash commands to handle this properly with correct permissions
 | |
|                     check_bashrc_cmd = f"test -f {bashrc_path} && echo 'exists' || echo 'not exists'"
 | |
|                     bashrc_exists = ProcessUtilities.outputExecutioner(check_bashrc_cmd, website_user, shell=True)
 | |
|                     if isinstance(bashrc_exists, tuple):
 | |
|                         bashrc_exists = bashrc_exists[1] if len(bashrc_exists) == 2 else str(bashrc_exists)
 | |
|                     
 | |
|                     if 'not exists' in str(bashrc_exists):
 | |
|                         # Create .bashrc with nvm source lines
 | |
|                         create_bashrc_cmd = f'''echo 'export NVM_DIR="$HOME/.nvm"
 | |
| [ -s "$NVM_DIR/nvm.sh" ] && \\. "$NVM_DIR/nvm.sh"' > {bashrc_path}'''
 | |
|                         ProcessUtilities.executioner(create_bashrc_cmd, website_user, shell=True)
 | |
|                         logging.writeToFile(f"[_install_n8n_custom] Created .bashrc with nvm source lines")
 | |
|                     else:
 | |
|                         # Check if nvm is already in bashrc
 | |
|                         check_nvm_cmd = f"grep -q 'NVM_DIR' {bashrc_path} && echo 'found' || echo 'not found'"
 | |
|                         nvm_in_bashrc = ProcessUtilities.outputExecutioner(check_nvm_cmd, website_user, shell=True)
 | |
|                         if isinstance(nvm_in_bashrc, tuple):
 | |
|                             nvm_in_bashrc = nvm_in_bashrc[1] if len(nvm_in_bashrc) == 2 else str(nvm_in_bashrc)
 | |
|                         
 | |
|                         if 'not found' in str(nvm_in_bashrc):
 | |
|                             # Append nvm source lines
 | |
|                             append_cmd = f'''echo '
 | |
| export NVM_DIR="$HOME/.nvm"
 | |
| [ -s "$NVM_DIR/nvm.sh" ] && \\. "$NVM_DIR/nvm.sh"' >> {bashrc_path}'''
 | |
|                             ProcessUtilities.executioner(append_cmd, website_user, shell=True)
 | |
|                             logging.writeToFile(f"[_install_n8n_custom] Appended nvm source lines to .bashrc")
 | |
|                     
 | |
|                     # Clean up the install script
 | |
|                     ProcessUtilities.executioner(f"rm -f {nvm_script}", website_user)
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] nvm installation completed successfully")
 | |
|                     
 | |
|                 except Exception as e:
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Error installing nvm: {str(e)}")
 | |
|                     statusWriter.writeToFile(f'Failed to install nvm: {str(e)} [404]')
 | |
|                     return
 | |
|                 
 | |
|                 # Create a script to source nvm and install node
 | |
|                 node_setup_script = f"{website_home}/setup_node.sh"
 | |
|                 script_content = '''#!/bin/bash
 | |
| export NVM_DIR="$HOME/.nvm"
 | |
| [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
 | |
| nvm install 22
 | |
| nvm use 22
 | |
| nvm alias default 22
 | |
| '''
 | |
|                 # Write script to temp location first, then move it
 | |
|                 temp_script = f"/tmp/setup_node_{website_user}.sh"
 | |
|                 with open(temp_script, 'w') as f:
 | |
|                     f.write(script_content)
 | |
|                 
 | |
|                 # Move script to correct location with proper ownership
 | |
|                 ProcessUtilities.executioner(f"cp {temp_script} {node_setup_script}", website_user)
 | |
|                 os.remove(temp_script)
 | |
|                 
 | |
|                 # Make script executable and run it
 | |
|                 try:
 | |
|                     ProcessUtilities.executioner(f"chmod +x {node_setup_script}", website_user)
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Installing Node.js 22 via nvm")
 | |
|                     node_install_output = ProcessUtilities.outputExecutioner(f"bash {node_setup_script}", website_user, shell=True, dir=website_home)
 | |
|                     if isinstance(node_install_output, tuple):
 | |
|                         # outputExecutioner might return (status, output)
 | |
|                         if len(node_install_output) == 2:
 | |
|                             status_code, actual_output = node_install_output
 | |
|                             node_install_output = actual_output
 | |
|                             logging.writeToFile(f"[_install_n8n_custom] node install status code: {status_code}")
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Node install output: {str(node_install_output)[:500]}")
 | |
|                 except Exception as e:
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Error installing Node.js: {str(e)}")
 | |
|                     statusWriter.writeToFile(f'Failed to install Node.js: {str(e)} [404]')
 | |
|                     return
 | |
|                 
 | |
|                 # Clean up the script
 | |
|                 try:
 | |
|                     ProcessUtilities.executioner(f"rm -f {node_setup_script}", website_user)
 | |
|                 except:
 | |
|                     pass  # Ignore cleanup errors
 | |
|                 
 | |
|                 # Verify Node.js installation by checking version
 | |
|                 statusWriter.writeToFile('Verifying Node.js installation...,38')
 | |
|                 verify_node_cmd = 'bash -c "source ~/.nvm/nvm.sh && node --version"'
 | |
|                 verify_npm_cmd = 'bash -c "source ~/.nvm/nvm.sh && npm --version"'
 | |
|                 
 | |
|                 try:
 | |
|                     node_version = ProcessUtilities.outputExecutioner(verify_node_cmd, website_user, shell=True, dir=website_home)
 | |
|                     npm_version = ProcessUtilities.outputExecutioner(verify_npm_cmd, website_user, shell=True, dir=website_home)
 | |
|                     
 | |
|                     if isinstance(node_version, tuple):
 | |
|                         node_version = node_version[1] if len(node_version) == 2 else str(node_version)
 | |
|                     if isinstance(npm_version, tuple):
 | |
|                         npm_version = npm_version[1] if len(npm_version) == 2 else str(npm_version)
 | |
|                     
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Node version: {node_version}")
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] NPM version: {npm_version}")
 | |
|                     
 | |
|                     # Check if versions look valid
 | |
|                     if not node_version or 'v' not in str(node_version):
 | |
|                         logging.writeToFile(f"[_install_n8n_custom] Invalid node version output: {node_version}")
 | |
|                         statusWriter.writeToFile(f'Node.js installation verification failed [404]')
 | |
|                         return
 | |
|                     
 | |
|                     statusWriter.writeToFile(f'Node.js {node_version.strip()} installed successfully...,39')
 | |
|                     
 | |
|                 except Exception as e:
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Error verifying Node.js: {str(e)}")
 | |
|                     statusWriter.writeToFile(f'Failed to verify Node.js installation: {str(e)} [404]')
 | |
|                     return
 | |
|                 
 | |
|                 # Step 3: Install n8n via npm
 | |
|                 statusWriter.writeToFile('Installing n8n via npm...,40')
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] About to run npm commands")
 | |
| 
 | |
|                 # Check if npm/node is now available with nvm
 | |
|                 check_node_cmd = '''bash -c "source ~/.nvm/nvm.sh && which node"'''
 | |
|                 check_npm_cmd = '''bash -c "source ~/.nvm/nvm.sh && which npm"'''
 | |
|                 try:
 | |
|                     node_check = ProcessUtilities.outputExecutioner(check_node_cmd, website_user, shell=True, dir=website_home)
 | |
|                     npm_check = ProcessUtilities.outputExecutioner(check_npm_cmd, website_user, shell=True, dir=website_home)
 | |
|                     if isinstance(node_check, tuple):
 | |
|                         node_check = node_check[1] if len(node_check) == 2 else node_check
 | |
|                     if isinstance(npm_check, tuple):
 | |
|                         npm_check = npm_check[1] if len(npm_check) == 2 else npm_check
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] node path: {node_check}, npm path: {npm_check}")
 | |
|                     
 | |
|                     # Check if paths are valid
 | |
|                     if not node_check or 'not found' in str(node_check) or not npm_check or 'not found' in str(npm_check):
 | |
|                         logging.writeToFile(f"[_install_n8n_custom] Node/npm not found after installation")
 | |
|                         statusWriter.writeToFile('Node.js installation failed - node/npm not found [404]')
 | |
|                         return
 | |
|                 except Exception as e:
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Error checking node/npm: {str(e)}")
 | |
|                     statusWriter.writeToFile(f'Failed to verify Node.js installation: {str(e)} [404]')
 | |
|                     return
 | |
| 
 | |
|                 # Change to app directory and install n8n
 | |
|                 # First create package.json
 | |
|                 app_dir = f"{n8n_dir}/app"
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Running npm init in dir: {app_dir}")
 | |
|                 
 | |
|                 # Use bash -c to source nvm before running npm commands
 | |
|                 init_cmd = 'bash -c "source ~/.nvm/nvm.sh && npm init -y"'
 | |
|                 init_output = ProcessUtilities.outputExecutioner(init_cmd, website_user, shell=True, dir=app_dir)
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] npm init output: {init_output[:200]}")
 | |
|                 
 | |
|                 # Install n8n - this may take several minutes
 | |
|                 statusWriter.writeToFile('Installing n8n via npm (this may take 2-5 minutes)...,45')
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Starting npm install n8n in dir: {app_dir}")
 | |
| 
 | |
|                 
 | |
|                 # Use bash -c to source nvm before installing n8n
 | |
|                 install_cmd = 'bash -c "source ~/.nvm/nvm.sh && npm install n8n --production"'
 | |
|                 install_output = ProcessUtilities.outputExecutioner(install_cmd, website_user, shell=True, dir=app_dir)
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] npm install output: {install_output[:500]}")  # Log first 500 chars
 | |
|                 
 | |
|                 # Check if n8n was actually installed
 | |
|                 check_cmd = 'bash -c "source ~/.nvm/nvm.sh && ls node_modules/n8n"'
 | |
|                 check_output = ProcessUtilities.outputExecutioner(check_cmd, website_user, shell=True, dir=app_dir)
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Check n8n module output: {check_output}")
 | |
|                 
 | |
|                 if "No such file or directory" in check_output or "cannot access" in check_output:
 | |
|                     statusWriter.writeToFile(f'n8n installation failed - module not found [404]')
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] n8n module not found after install")
 | |
|                     return
 | |
| 
 | |
|                 statusWriter.writeToFile('n8n installed successfully...,50')
 | |
| 
 | |
|                 # Step 4: Create n8n configuration file
 | |
|                 statusWriter.writeToFile('Creating n8n configuration...,60')
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Creating n8n configuration file")
 | |
| 
 | |
|                 # Generate encryption key
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Generating encryption key")
 | |
|                 encryption_key = randomPassword.generate_pass(32)
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Encryption key generated")
 | |
|                 
 | |
|                 # Configure database settings based on type
 | |
|                 if db_type == 'postgresql':
 | |
|                     db_config = f'''# Database Configuration (PostgreSQL)
 | |
| DB_TYPE=postgresdb
 | |
| DB_POSTGRESDB_DATABASE={db_name}
 | |
| DB_POSTGRESDB_HOST=127.0.0.1
 | |
| DB_POSTGRESDB_PORT=5433
 | |
| DB_POSTGRESDB_USER={db_user}
 | |
| DB_POSTGRESDB_PASSWORD={db_password}'''
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Using PostgreSQL configuration")
 | |
|                 else:
 | |
|                     db_config = f'''# Database Configuration (MySQL/MariaDB)
 | |
| DB_TYPE=mysqldb
 | |
| DB_MYSQLDB_DATABASE={db_name}
 | |
| DB_MYSQLDB_HOST=127.0.0.1
 | |
| DB_MYSQLDB_PORT=3306
 | |
| DB_MYSQLDB_USER={db_user}
 | |
| DB_MYSQLDB_PASSWORD={db_password}
 | |
| DB_MYSQLDB_CHARSET=utf8mb4
 | |
| DB_MYSQLDB_COLLATION=utf8mb4_unicode_ci'''
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Using MySQL/MariaDB configuration")
 | |
| 
 | |
|                 config_content = f'''# n8n Configuration for {domain_name}
 | |
| 
 | |
| # Application Paths
 | |
| N8N_USER_FOLDER={n8n_dir}/data
 | |
| N8N_LOG_FILE_LOCATION={n8n_dir}/logs/n8n.log
 | |
| 
 | |
| {db_config}
 | |
| 
 | |
| # n8n Configuration
 | |
| N8N_HOST=127.0.0.1
 | |
| N8N_PORT={n8n_port}
 | |
| N8N_PROTOCOL=https
 | |
| WEBHOOK_URL=https://{domain_name}
 | |
| N8N_EDITOR_BASE_URL=https://{domain_name}
 | |
| 
 | |
| # Security
 | |
| N8N_BASIC_AUTH_ACTIVE=true
 | |
| N8N_BASIC_AUTH_USER={n8n_username}
 | |
| N8N_BASIC_AUTH_PASSWORD={n8n_password}
 | |
| N8N_ENCRYPTION_KEY={encryption_key}
 | |
| 
 | |
| # Execution Settings
 | |
| EXECUTIONS_DATA_SAVE_ON_ERROR=all
 | |
| EXECUTIONS_DATA_SAVE_ON_SUCCESS=all
 | |
| EXECUTIONS_DATA_MAX_AGE=336
 | |
| 
 | |
| # Performance
 | |
| NODE_OPTIONS=--max-old-space-size=2048
 | |
| 
 | |
| # Timezone
 | |
| GENERIC_TIMEZONE=UTC
 | |
| 
 | |
| # File Storage
 | |
| N8N_DEFAULT_BINARY_DATA_MODE=filesystem
 | |
| N8N_BINARY_DATA_STORAGE_PATH={n8n_dir}/data/files
 | |
| 
 | |
| # Log Settings
 | |
| N8N_LOG_LEVEL=info
 | |
| 
 | |
| # Push Backend Configuration (Use SSE for OpenLiteSpeed compatibility)
 | |
| N8N_PUSH_BACKEND=sse
 | |
| '''
 | |
| 
 | |
|                 config_file = f"{n8n_dir}/config/n8n.env"
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Writing config to {config_file}")
 | |
|                 
 | |
|                 # Write config to temp location first, then move it
 | |
|                 temp_config = f"/tmp/n8n_config_{website_user}_{n8n_port}.env"
 | |
|                 try:
 | |
|                     with open(temp_config, 'w') as f:
 | |
|                         f.write(config_content)
 | |
|                     
 | |
|                     # Copy to correct location with proper ownership
 | |
|                     ProcessUtilities.executioner(f"cp {temp_config} {config_file}", website_user)
 | |
|                     os.remove(temp_config)
 | |
|                     
 | |
|                     # Set permissions
 | |
|                     command = f"chmod 600 {config_file}"
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Setting config file permissions")
 | |
|                     ProcessUtilities.executioner(command, website_user)
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Config file written successfully")
 | |
|                 except Exception as e:
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Error writing config file: {str(e)}")
 | |
|                     if os.path.exists(temp_config):
 | |
|                         os.remove(temp_config)
 | |
|                     statusWriter.writeToFile(f'Failed to write n8n configuration: {str(e)} [404]')
 | |
|                     return
 | |
| 
 | |
|                 # Save encryption key
 | |
|                 encryption_file = f"{n8n_dir}/config/encryption.key"
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Saving encryption key to {encryption_file}")
 | |
|                 
 | |
|                 # Write encryption key to temp location first, then move it
 | |
|                 temp_encryption = f"/tmp/n8n_encryption_{website_user}_{n8n_port}.key"
 | |
|                 try:
 | |
|                     with open(temp_encryption, 'w') as f:
 | |
|                         f.write(f"N8N_ENCRYPTION_KEY={encryption_key}\n")
 | |
|                     
 | |
|                     # Copy to correct location with proper ownership
 | |
|                     ProcessUtilities.executioner(f"cp {temp_encryption} {encryption_file}", website_user)
 | |
|                     os.remove(temp_encryption)
 | |
|                     
 | |
|                     # Set permissions
 | |
|                     command = f"chmod 600 {encryption_file}"
 | |
|                     ProcessUtilities.executioner(command, website_user)
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Encryption key saved successfully")
 | |
|                 except Exception as e:
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Error saving encryption key: {str(e)}")
 | |
|                     if os.path.exists(temp_encryption):
 | |
|                         os.remove(temp_encryption)
 | |
|                     statusWriter.writeToFile(f'Failed to save encryption key: {str(e)} [404]')
 | |
|                     return
 | |
| 
 | |
|                 statusWriter.writeToFile('Configuration created...,70')
 | |
| 
 | |
|                 # Step 5: Create systemd service
 | |
|                 statusWriter.writeToFile('Creating systemd service...,80')
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Creating systemd service")
 | |
| 
 | |
|                 service_name = f"n8n-{domain_name.replace('.', '-')}"
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Service name: {service_name}")
 | |
|                 service_content = f'''[Unit]
 | |
| Description=n8n - Workflow Automation Tool for {domain_name}
 | |
| After=network.target mysql.service
 | |
| Requires=mysql.service
 | |
| 
 | |
| [Service]
 | |
| Type=simple
 | |
| User={website_user}
 | |
| Group={website_user}
 | |
| WorkingDirectory={n8n_dir}/app
 | |
| EnvironmentFile={n8n_dir}/config/n8n.env
 | |
| 
 | |
| # Create log directory if it doesn't exist
 | |
| ExecStartPre=/bin/bash -c 'mkdir -p {n8n_dir}/logs && chown {website_user}:{website_user} {n8n_dir}/logs'
 | |
| 
 | |
| # Start command - source nvm and environment file first, with detailed logging
 | |
| ExecStart=/bin/bash -c 'exec > >(tee -a {n8n_dir}/logs/n8n.log) 2> >(tee -a {n8n_dir}/logs/n8n-error.log >&2) && echo "[$(date)] Starting n8n service..." && source {website_home}/.nvm/nvm.sh && echo "[$(date)] NVM sourced successfully" && source {n8n_dir}/config/n8n.env && echo "[$(date)] Environment variables loaded:" && env | grep -E "^(N8N_|DB_)" | sort && echo "[$(date)] Starting n8n on port $N8N_PORT..." && {n8n_dir}/app/node_modules/.bin/n8n start'
 | |
| 
 | |
| # Restart configuration
 | |
| Restart=always
 | |
| RestartSec=10
 | |
| 
 | |
| # Logging
 | |
| StandardOutput=append:{n8n_dir}/logs/n8n.log
 | |
| StandardError=append:{n8n_dir}/logs/n8n-error.log
 | |
| SyslogIdentifier={service_name}
 | |
| 
 | |
| # Security
 | |
| NoNewPrivileges=true
 | |
| PrivateTmp=true
 | |
| 
 | |
| # Resource limits
 | |
| LimitNOFILE=65536
 | |
| 
 | |
| [Install]
 | |
| WantedBy=multi-user.target
 | |
| '''
 | |
| 
 | |
|                 service_file = f"/etc/systemd/system/{service_name}.service"
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Writing service file to {service_file}")
 | |
|                 
 | |
|                 # Write service file to temp location first, then move it with sudo
 | |
|                 temp_service = f"/tmp/n8n_service_{website_user}_{n8n_port}.service"
 | |
|                 try:
 | |
|                     with open(temp_service, 'w') as f:
 | |
|                         f.write(service_content)
 | |
|                     
 | |
|                     # Copy to systemd directory with sudo
 | |
|                     command = f"sudo cp {temp_service} {service_file}"
 | |
|                     ProcessUtilities.executioner(command)
 | |
|                     
 | |
|                     # Set proper ownership and permissions
 | |
|                     ProcessUtilities.executioner(f"sudo chmod 644 {service_file}")
 | |
|                     ProcessUtilities.executioner(f"sudo chown root:root {service_file}")
 | |
|                     
 | |
|                     os.remove(temp_service)
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Service file written successfully")
 | |
|                 except Exception as e:
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Error writing service file: {str(e)}")
 | |
|                     if os.path.exists(temp_service):
 | |
|                         os.remove(temp_service)
 | |
|                     statusWriter.writeToFile(f'Failed to create systemd service: {str(e)} [404]')
 | |
| 
 | |
|                     return
 | |
| 
 | |
| 
 | |
|                 # Enable and start service
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Enabling and starting service")
 | |
|                 commands = [
 | |
|                     "sudo systemctl daemon-reload",
 | |
|                     f"sudo systemctl enable {service_name}",
 | |
|                     f"sudo systemctl start {service_name}"
 | |
|                 ]
 | |
| 
 | |
|                 for command in commands:
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Running: {command}")
 | |
|                     ProcessUtilities.executioner(command)
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Command executed: {command}")
 | |
| 
 | |
|                 statusWriter.writeToFile('Service created and started...,85')
 | |
| 
 | |
|                 # Step 6: Configure OpenLiteSpeed reverse proxy
 | |
|                 statusWriter.writeToFile('Configuring web server...,90')
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Configuring OpenLiteSpeed reverse proxy")
 | |
| 
 | |
|                 # Configure OpenLiteSpeed vhost for reverse proxy
 | |
|                 vhost_conf_path = f"/usr/local/lsws/conf/vhosts/{domain_name}/vhost.conf"
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Vhost config path: {vhost_conf_path}")
 | |
|                 
 | |
|                 # Read existing vhost configuration using sudo
 | |
|                 command = f"sudo cat {vhost_conf_path}"
 | |
|                 vhost_content = ProcessUtilities.outputExecutioner(command)
 | |
|                 
 | |
|                 if vhost_content.find('[Errno') > -1 or vhost_content.find('No such file') > -1:
 | |
|                     statusWriter.writeToFile(f'Could not read vhost configuration: {vhost_content} [404]')
 | |
|                     return
 | |
|                 
 | |
|                 # Check if proxy configuration already exists
 | |
|                 if f'extprocessor n8n{n8n_port}' not in vhost_content:
 | |
|                     # Prepare proxy configuration to append at the end
 | |
|                     proxy_config = f'''
 | |
| 
 | |
| # n8n Proxy Configuration
 | |
| extprocessor n8n{n8n_port} {{
 | |
|   type                    proxy
 | |
|   address                 127.0.0.1:{n8n_port}
 | |
|   maxConns                100
 | |
|   pcKeepAliveTimeout      3600
 | |
|   initTimeout             300
 | |
|   retryTimeout            0
 | |
|   respBuffer              0
 | |
| }}
 | |
| 
 | |
| context / {{
 | |
|   type                    proxy
 | |
|   handler                 n8n{n8n_port}
 | |
|   addDefaultCharset       off
 | |
|   websocket               1
 | |
|   
 | |
|   extraHeaders            <<<END_extraHeaders
 | |
|   RequestHeader set X-Forwarded-For $ip
 | |
|   RequestHeader set X-Forwarded-Proto https
 | |
|   RequestHeader set X-Forwarded-Host "{domain_name}"
 | |
|   RequestHeader set Origin "{domain_name}, {domain_name}"
 | |
|   RequestHeader set Host "{domain_name}"
 | |
|   END_extraHeaders
 | |
| }}
 | |
| '''
 | |
|                     
 | |
|                     # Append proxy configuration at the end of the file
 | |
|                     new_vhost_content = vhost_content.rstrip() + proxy_config
 | |
|                     
 | |
|                     # Create a temporary file with the new configuration
 | |
|                     temp_file = f"/tmp/n8n_vhost_{domain_name}_{n8n_port}.conf"
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Writing updated vhost to temp file: {temp_file}")
 | |
|                     with open(temp_file, 'w') as f:
 | |
|                         f.write(new_vhost_content)
 | |
|                     
 | |
|                     # Backup original configuration
 | |
|                     backup_command = f"sudo cp {vhost_conf_path} {vhost_conf_path}.n8n_backup"
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Backing up original vhost")
 | |
|                     ProcessUtilities.executioner(backup_command)
 | |
|                     
 | |
|                     # Copy the new configuration to the vhost path
 | |
|                     command = f"sudo cp {temp_file} {vhost_conf_path}"
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Copying updated vhost")
 | |
|                     ProcessUtilities.executioner(command)
 | |
|                     
 | |
|                     # Set proper ownership to lsadm:lsadm
 | |
|                     chown_command = f"sudo chown lsadm:lsadm {vhost_conf_path}"
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Setting vhost ownership")
 | |
|                     ProcessUtilities.executioner(chown_command)
 | |
|                     
 | |
|                     # Clean up temp file
 | |
|                     os.remove(temp_file)
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Temp file cleaned up")
 | |
| 
 | |
|                     # Always assume vhost update succeeded since executioner doesn't return status
 | |
|                     statusWriter.writeToFile('Proxy configuration added to vhost...,92')
 | |
|                 else:
 | |
|                     logging.writeToFile(f"[_install_n8n_custom] Proxy config already exists")
 | |
|                     statusWriter.writeToFile('Proxy configuration already exists...,92')
 | |
| 
 | |
|                 # Restart OpenLiteSpeed
 | |
|                 command = "sudo /usr/local/lsws/bin/lswsctrl restart"
 | |
|                 logging.writeToFile(f"[_install_n8n_custom] Restarting OpenLiteSpeed")
 | |
|                 ProcessUtilities.executioner(command)
 | |
|                 
 | |
|                 # Always report success since executioner doesn't return status
 | |
|                 statusWriter.writeToFile('OpenLiteSpeed restarted...,94')
 | |
| 
 | |
|                 statusWriter.writeToFile('Web server configured...,95')
 | |
| 
 | |
|                 # Step 7: Verify installation
 | |
|                 statusWriter.writeToFile('Verifying installation...,98')
 | |
| 
 | |
|                 import time
 | |
|                 time.sleep(5)  # Give n8n time to start
 | |
| 
 | |
|                 # Check if service is running
 | |
|                 command = f"sudo systemctl is-active {service_name}"
 | |
|                 result = ProcessUtilities.outputExecutioner(command)
 | |
| 
 | |
|                 if result.strip() == "active":
 | |
|                     statusWriter.writeToFile(f'n8n successfully installed at https://{domain_name}/ [200]')
 | |
| 
 | |
|                     # Write installation details
 | |
|                     details = f'''
 | |
| Installation Details:
 | |
| - Domain: {domain_name}
 | |
| - n8n URL: https://{domain_name}/
 | |
| - n8n Username: {n8n_username}
 | |
| - n8n Port: {n8n_port}
 | |
| - Service Name: {service_name}
 | |
| - Installation Directory: {n8n_dir}
 | |
| - Database Name: {db_name}
 | |
| - Database User: {db_user}
 | |
| 
 | |
| To manage n8n:
 | |
| - Start: systemctl start {service_name}
 | |
| - Stop: systemctl stop {service_name}
 | |
| - Restart: systemctl restart {service_name}
 | |
| - Status: systemctl status {service_name}
 | |
| - Logs: journalctl -u {service_name} -f
 | |
| '''
 | |
|                     statusWriter.writeToFile(details)
 | |
|                 else:
 | |
| 
 | |
|                     statusWriter.writeToFile(
 | |
|                         f'n8n service failed to start. Check logs: journalctl -u {service_name} [404]\n')
 | |
|             except Exception as e:
 | |
|                 import traceback
 | |
|                 statusWriter.writeToFile(f'Installation failed: {str(e)}')
 | |
|                 statusWriter.writeToFile(f'Traceback: {traceback.format_exc()} [404]')
 | |
|         except Exception as e:
 | |
|             # If we can't even write to status file
 | |
|             import traceback
 | |
|             logging.writeToFile(f"[_install_n8n_custom] Critical error in n8n installation: {str(e)}")
 | |
|             logging.writeToFile(f"[_install_n8n_custom] Critical error traceback: {traceback.format_exc()}")
 | |
| 
 | |
|     def _perform_n8n_installation_OLD_REMOVE(self, domain_name, status_file_path):
 | |
|         """
 | |
|         Perform the actual n8n installation process
 | |
|         This runs in a background thread
 | |
|         """
 | |
|         # First, append to status file that thread started (before any imports that could fail)
 | |
|         try:
 | |
|             with open(status_file_path, 'a') as f:
 | |
|                 f.write('Background thread started successfully\n')
 | |
|                 f.write(f'Function called with domain: {domain_name}\n')
 | |
|                 f.write('About to start try block for imports...\n')
 | |
|         except Exception as e:
 | |
|             print(f"CRITICAL: Cannot write to status file {status_file_path}: {e}")
 | |
|             return
 | |
| 
 | |
|         try:
 | |
|             # Try imports one by one to catch specific failures
 | |
|             with open(status_file_path, 'a') as f:
 | |
|                 f.write('Inside try block, attempting to import CyberCPLogFileWriter...\n')
 | |
| 
 | |
|             from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
 | |
| 
 | |
|             with open(status_file_path, 'a') as f:
 | |
|                 f.write('CyberCPLogFileWriter import successful\n')
 | |
|                 f.write('Attempting to import Docker_Sites...\n')
 | |
| 
 | |
|             from plogical.DockerSites import Docker_Sites
 | |
| 
 | |
|             with open(status_file_path, 'a') as f:
 | |
|                 f.write('Docker_Sites import successful\n')
 | |
|                 f.write('Importing time module...\n')
 | |
| 
 | |
|             import time
 | |
| 
 | |
|             with open(status_file_path, 'a') as f:
 | |
|                 f.write('All imports successful, initializing status writer...\n')
 | |
| 
 | |
|             # Initialize status file writer
 | |
|             try:
 | |
|                 with open(status_file_path, 'a') as f:
 | |
|                     f.write('Creating CyberCPLogFileWriter instance...\n')
 | |
|                 status_writer = logging(status_file_path, 'a')
 | |
| 
 | |
|                 with open(status_file_path, 'a') as f:
 | |
|                     f.write('CyberCPLogFileWriter instance created, testing writeToFile...\n')
 | |
| 
 | |
|                 status_writer.writeToFile('CyberCPLogFileWriter initialized successfully')
 | |
| 
 | |
|                 with open(status_file_path, 'a') as f:
 | |
|                     f.write('First writeToFile successful\n')
 | |
| 
 | |
|                 status_writer.writeToFile('Starting n8n installation process...')
 | |
|                 status_writer.writeToFile(f'Domain: {domain_name}')
 | |
|                 status_writer.writeToFile(f'Data received: {self.data}')
 | |
| 
 | |
|                 with open(status_file_path, 'a') as f:
 | |
|                     f.write('All CyberCPLogFileWriter operations successful\n')
 | |
| 
 | |
|             except Exception as writer_error:
 | |
|                 with open(status_file_path, 'a') as f:
 | |
|                     f.write(f'CyberCPLogFileWriter error: {str(writer_error)}\n')
 | |
|                     f.write(f'Continuing without CyberCPLogFileWriter...\n')
 | |
|                 # Continue without the writer if it fails
 | |
|                 status_writer = None
 | |
| 
 | |
|             # Simplified approach - directly call DeployN8NContainer
 | |
|             def write_status(message):
 | |
|                 if status_writer:
 | |
|                     status_writer.writeToFile(message)
 | |
|                 else:
 | |
|                     with open(status_file_path, 'a') as f:
 | |
|                         f.write(f'{message}\n')
 | |
| 
 | |
|             write_status('Preparing Docker deployment...')
 | |
| 
 | |
|             # Use the same pattern as working submitDockerSiteCreation
 | |
|             # Get all required parameters from the data sent by the platform
 | |
|             sitename = self.data.get('sitename', domain_name.replace('.', '').replace('-', '')[:8])
 | |
|             Owner = self.data.get('Owner', self.data.get('websiteOwner', domain_name.replace('.', '')))
 | |
|             MysqlCPU = int(self.data.get('MysqlCPU', 1))
 | |
|             MYsqlRam = int(self.data.get('MYsqlRam', 512))
 | |
|             SiteCPU = int(self.data.get('SiteCPU', 1))
 | |
|             SiteRam = int(self.data.get('SiteRam', 512))
 | |
|             App = self.data.get('App', 'N8N')
 | |
|             WPusername = self.data.get('WPusername', 'admin')
 | |
|             WPemal = self.data.get('WPemal', self.data.get('adminEmail', f'admin@{domain_name}'))
 | |
|             WPpasswd = self.data.get('WPpasswd', self.data.get('n8nPassword', 'auto-generate'))
 | |
|             port = self.data.get('port', '8080')
 | |
|             userID = self.data.get('userID', 1)
 | |
| 
 | |
|             write_status(f'Extracted parameters - sitename: {sitename}, Owner: {Owner}, CPU: {SiteCPU}, RAM: {SiteRam}')
 | |
| 
 | |
|             # Prepare temp status path
 | |
|             from random import randint
 | |
|             tempStatusPath = "/home/cyberpanel/" + str(randint(1000, 9999))
 | |
| 
 | |
|             # Prepare data structure exactly like working submitDockerSiteCreation
 | |
|             docker_data = {
 | |
|                 'JobID': tempStatusPath,  # Use temp status path like working version
 | |
|                 'Domain': domain_name,
 | |
|                 'WPemal': WPemal,
 | |
|                 'Owner': Owner,
 | |
|                 'userID': userID,
 | |
|                 'MysqlCPU': MysqlCPU,
 | |
|                 'MYsqlRam': MYsqlRam,
 | |
|                 'SiteCPU': SiteCPU,
 | |
|                 'SiteRam': SiteRam,
 | |
|                 'sitename': sitename,
 | |
|                 'WPusername': WPusername,
 | |
|                 'WPpasswd': WPpasswd,
 | |
|                 'externalApp': "".join(domain_name.replace('.', '').replace('-', '')[:5]) + str(randint(1000, 9999)),
 | |
|                 'App': App,
 | |
|                 'finalURL': domain_name,
 | |
|                 'port': port,
 | |
|                 'ServiceName': sitename.replace(' ', '-'),
 | |
|                 'ComposePath': f'/home/docker/{domain_name}/docker-compose.yml',
 | |
|                 'MySQLPath': f'/home/docker/{domain_name}/db',
 | |
|                 'MySQLRootPass': self.data.get('dbPassword', 'auto-generated'),
 | |
|                 'MySQLDBName': f'n8n_{sitename}',
 | |
|                 'MySQLDBUser': f'n8n_{sitename}',
 | |
|                 'MySQLPassword': self.data.get('dbPassword', 'auto-generated'),
 | |
|                 'MemoryMySQL': MYsqlRam,
 | |
|                 'CPUsMySQL': MysqlCPU,
 | |
|                 'MemorySite': SiteRam,
 | |
|                 'CPUsSite': SiteCPU
 | |
|             }
 | |
| 
 | |
|             write_status(f'Docker data prepared following working pattern: {docker_data}')
 | |
| 
 | |
|             # Call the actual deployment function from DockerSites
 | |
|             try:
 | |
|                 write_status('Starting Docker_Sites deployment...')
 | |
| 
 | |
|                 # Create and run Docker_Sites instance
 | |
|                 try:
 | |
|                     write_status('Creating Docker_Sites instance...')
 | |
|                     write_status(f'Calling Docker_Sites with function: DeployN8NContainer')
 | |
|                     write_status(f'Data keys: {list(docker_data.keys())}')
 | |
| 
 | |
|                     docker_sites = Docker_Sites('DeployN8NContainer', docker_data)
 | |
|                     write_status('Docker_Sites instance created successfully')
 | |
|                     write_status(f'Docker_Sites attributes: function_run={docker_sites.function_run}')
 | |
| 
 | |
|                 except Exception as docker_init_error:
 | |
|                     write_status(f'Docker_Sites creation failed: {str(docker_init_error)}')
 | |
|                     import traceback
 | |
|                     write_status(f'Docker_Sites creation traceback: {traceback.format_exc()}')
 | |
|                     return
 | |
| 
 | |
|                 try:
 | |
|                     write_status('Starting Docker_Sites thread...')
 | |
|                     docker_sites.start()
 | |
|                     write_status('Docker deployment thread started successfully')
 | |
|                 except Exception as start_error:
 | |
|                     write_status(f'Docker_Sites start failed: {str(start_error)}')
 | |
|                     import traceback
 | |
|                     write_status(f'Docker_Sites start traceback: {traceback.format_exc()}')
 | |
|                     return
 | |
| 
 | |
|                 try:
 | |
|                     write_status('Waiting for Docker deployment completion...')
 | |
|                     docker_sites.join()
 | |
|                     write_status('Docker deployment thread completed')
 | |
|                 except Exception as join_error:
 | |
|                     write_status(f'Docker_Sites join failed: {str(join_error)}')
 | |
|                     import traceback
 | |
|                     write_status(f'Docker_Sites join traceback: {traceback.format_exc()}')
 | |
|                     return
 | |
| 
 | |
|                 # The DeployN8NContainer function writes its own status to the JobID file
 | |
|                 # Check if it was successful by reading the final status
 | |
|                 try:
 | |
|                     write_status('Reading deployment results...')
 | |
|                     with open(status_file_path, 'r') as f:
 | |
|                         final_status = f.read()
 | |
|                     write_status(f'Final status content: {final_status}')
 | |
| 
 | |
|                     if '[200]' in final_status:
 | |
|                         write_status(f'n8n successfully installed and deployed at https://{domain_name}/ [200]')
 | |
|                     else:
 | |
|                         write_status(f'Container deployment completed but with issues [404]')
 | |
|                 except Exception as read_error:
 | |
|                     write_status(f'Unable to verify deployment status: {str(read_error)} [404]')
 | |
| 
 | |
|             except Exception as e:
 | |
|                 import traceback
 | |
|                 write_status(f'Container deployment failed: {str(e)} [404]')
 | |
|                 write_status(f'Traceback: {traceback.format_exc()}')
 | |
|                 return
 | |
| 
 | |
|         except Exception as e:
 | |
|             # Write error to status file using direct file writing
 | |
|             try:
 | |
|                 import traceback
 | |
|                 with open(status_file_path, 'a') as f:
 | |
|                     f.write(f'MAIN EXCEPTION in _perform_n8n_installation: {str(e)}\n')
 | |
|                     f.write(f'Full traceback: {traceback.format_exc()}\n')
 | |
|                     f.write('Installation failed [404]\n')
 | |
|             except Exception as log_error:
 | |
|                 # If we can't even write to the status file, something is very wrong
 | |
|                 print(f"Critical error - cannot write to status file: {log_error}")
 | |
|                 print(f"Original error: {e}")
 | |
|                 import traceback
 | |
|                 print(f"Traceback: {traceback.format_exc()}")
 | |
| 
 | |
|     def getN8NInstallStatus(self):
 | |
|         try:
 | |
|             # This now uses the standard statusFunc to check Docker site creation status
 | |
|             # The status file path is provided in tempStatusPath from installN8N response
 | |
| 
 | |
|             statusFile = self.data.get('statusFile')
 | |
|             if not statusFile:
 | |
|                 # For backward compatibility, also check domainIdentifier
 | |
|                 domain_identifier = self.data.get('domainIdentifier')
 | |
|                 if domain_identifier:
 | |
|                     # Try to find the status file from previous installations
 | |
|                     import os
 | |
|                     import glob
 | |
|                     possible_files = glob.glob(f'/home/cyberpanel/*')
 | |
|                     for f in possible_files:
 | |
|                         try:
 | |
|                             with open(f, 'r') as file:
 | |
|                                 content = file.read()
 | |
|                                 if domain_identifier.replace('_', '.') in content:
 | |
|                                     statusFile = f
 | |
|                                     break
 | |
|                         except:
 | |
|                             pass
 | |
| 
 | |
|                 if not statusFile:
 | |
|                     return self.ajaxPre(0, 'statusFile or domainIdentifier is required')
 | |
| 
 | |
|             # Use the standard status function
 | |
|             self.data['statusFile'] = statusFile
 | |
|             return self.statusFunc()
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def listN8NInstallations(self):
 | |
|         try:
 | |
|             from websiteFunctions.models import Websites
 | |
| 
 | |
|             # Find all websites with n8n installations
 | |
|             n8n_sites = []
 | |
| 
 | |
|             try:
 | |
|                 websites = Websites.objects.all()
 | |
|                 for website in websites:
 | |
|                     # Check if this website has n8n running
 | |
|                     # This is a placeholder - actual implementation would check container status
 | |
|                     if hasattr(website, 'applicationInstaller') and website.applicationInstaller == 'n8n':
 | |
|                         n8n_sites.append({
 | |
|                             'domain': website.domain,
 | |
|                             'status': 'running',  # This would be dynamically checked
 | |
|                             'created': str(website.date),
 | |
|                             'path': website.path
 | |
|                         })
 | |
|             except Exception as e:
 | |
|                 pass  # Continue even if this fails
 | |
| 
 | |
|             final_dic = {
 | |
|                 'status': 1,
 | |
|                 'error_message': 'None',
 | |
|                 'installations': n8n_sites,
 | |
|                 'count': len(n8n_sites)
 | |
|             }
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 | |
| 
 | |
|     def removeN8NInstallation(self):
 | |
|         try:
 | |
|             from websiteFunctions.models import Websites
 | |
|             from websiteFunctions.website import WebsiteManager
 | |
|             import os
 | |
| 
 | |
|             domain_name = self.data.get('domainName')
 | |
|             if not domain_name:
 | |
|                 return self.ajaxPre(0, 'domainName is required')
 | |
| 
 | |
|             # Check if website exists
 | |
|             try:
 | |
|                 website = Websites.objects.get(domain=domain_name)
 | |
|             except Websites.DoesNotExist:
 | |
|                 return self.ajaxPre(0, f'Website {domain_name} not found')
 | |
| 
 | |
|             # Stop and remove n8n containers
 | |
|             # This would use Docker API to stop containers
 | |
|             # For now, simulate the removal
 | |
| 
 | |
|             # Delete the website
 | |
|             website_manager = WebsiteManager()
 | |
|             delete_result = website_manager.submitWebsiteDeletion(self.admin.pk, {'websiteName': domain_name})
 | |
| 
 | |
|             if delete_result['status'] == 0:
 | |
|                 return self.ajaxPre(0, delete_result['error_message'])
 | |
| 
 | |
|             # Clean up status files
 | |
|             status_file_path = f'/home/cyberpanel/n8n_install_{domain_name.replace(".", "_")}_status'
 | |
|             try:
 | |
|                 if os.path.exists(status_file_path):
 | |
|                     os.remove(status_file_path)
 | |
|             except:
 | |
|                 pass  # Ignore cleanup errors
 | |
| 
 | |
|             final_dic = {
 | |
|                 'status': 1,
 | |
|                 'error_message': 'None',
 | |
|                 'message': f'n8n installation {domain_name} removed successfully'
 | |
|             }
 | |
|             final_json = json.dumps(final_dic)
 | |
|             return HttpResponse(final_json)
 | |
| 
 | |
|         except BaseException as msg:
 | |
|             return self.ajaxPre(0, str(msg))
 |