push changes
|
|
@ -0,0 +1,7 @@
|
|||
*.pyc
|
||||
ApachController/
|
||||
0*.py
|
||||
bin/
|
||||
lib/
|
||||
share/
|
||||
public/
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="django" name="Django">
|
||||
<configuration>
|
||||
<option name="rootFolder" value="$MODULE_DIR$" />
|
||||
<option name="settingsModule" value="CyberCP/settings.py" />
|
||||
<option name="manageScript" value="$MODULE_DIR$/manage.py" />
|
||||
<option name="environment" value="<map/>" />
|
||||
<option name="doNotUseTestRunner" value="false" />
|
||||
<option name="trackFilePattern" value="migrations" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="jdk" jdkName="Python 2.7" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="TemplatesService">
|
||||
<option name="TEMPLATE_CONFIGURATION" value="Django" />
|
||||
<option name="TEMPLATE_FOLDERS">
|
||||
<list>
|
||||
<option value="$MODULE_DIR$/dns/templates" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="TestRunnerService">
|
||||
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
|
||||
</component>
|
||||
</module>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 2.7" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/CyberCP.iml" filepath="$PROJECT_DIR$/.idea/CyberCP.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
import threading as multi
|
||||
from plogical.acl import ACLManager
|
||||
import plogical.CyberCPLogFileWriter as logging
|
||||
from plogical.processUtilities import ProcessUtilities
|
||||
from django.shortcuts import render
|
||||
import os
|
||||
from serverStatus.serverStatusUtil import ServerStatusUtil
|
||||
import json
|
||||
from django.shortcuts import HttpResponse
|
||||
from math import ceil
|
||||
from websiteFunctions.models import Websites
|
||||
from .models import CLPackages
|
||||
|
||||
|
||||
class CLManagerMain(multi.Thread):
|
||||
|
||||
def __init__(self, request=None, templateName=None, function=None, data=None):
|
||||
multi.Thread.__init__(self)
|
||||
self.request = request
|
||||
self.templateName = templateName
|
||||
self.function = function
|
||||
self.data = data
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
if self.function == 'submitCageFSInstall':
|
||||
self.submitCageFSInstall()
|
||||
elif self.function == 'enableOrDisable':
|
||||
self.enableOrDisable()
|
||||
|
||||
except BaseException, msg:
|
||||
logging.CyberCPLogFileWriter.writeToFile(str(msg) + ' [ContainerManager.run]')
|
||||
|
||||
def renderC(self):
|
||||
|
||||
userID = self.request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if currentACL['admin'] == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadError()
|
||||
|
||||
data = {}
|
||||
data['CL'] = 0
|
||||
data['CAGEFS'] = 0
|
||||
CLPath = '/etc/sysconfig/cloudlinux'
|
||||
CageFSPath = '/usr/sbin/cagefsctl'
|
||||
|
||||
if os.path.exists(CLPath):
|
||||
data['CL'] = 1
|
||||
|
||||
if os.path.exists(CageFSPath):
|
||||
data['CAGEFS'] = 1
|
||||
|
||||
if data['CL'] == 0:
|
||||
return render(self.request, 'CLManager/notAvailable.html', data)
|
||||
elif data['CAGEFS'] == 0:
|
||||
return render(self.request, 'CLManager/notAvailable.html', data)
|
||||
else:
|
||||
return render(self.request, self.templateName, self.data)
|
||||
|
||||
def submitCageFSInstall(self):
|
||||
try:
|
||||
userID = self.request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if currentACL['admin'] == 1:
|
||||
pass
|
||||
else:
|
||||
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
|
||||
'Not authorized to install container packages. [404].',
|
||||
1)
|
||||
return 0
|
||||
|
||||
execPath = "/usr/local/CyberCP/bin/python2 /usr/local/CyberCP/CLManager/CageFS.py"
|
||||
execPath = execPath + " --function submitCageFSInstall"
|
||||
ProcessUtilities.outputExecutioner(execPath)
|
||||
|
||||
except BaseException, msg:
|
||||
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, str(msg) + ' [404].', 1)
|
||||
|
||||
def findWebsitesJson(self, currentACL, userID, pageNumber):
|
||||
finalPageNumber = ((pageNumber * 10)) - 10
|
||||
endPageNumber = finalPageNumber + 10
|
||||
websites = ACLManager.findWebsiteObjects(currentACL, userID)[finalPageNumber:endPageNumber]
|
||||
|
||||
json_data = "["
|
||||
checker = 0
|
||||
|
||||
command = '/usr/sbin/cagefsctl --list-enabled'
|
||||
Enabled = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
for items in websites:
|
||||
if Enabled.find(items.externalApp) > -1:
|
||||
status = 1
|
||||
else:
|
||||
status = 0
|
||||
dic = {'domain': items.domain, 'externalApp': items.externalApp, 'status': status}
|
||||
|
||||
if checker == 0:
|
||||
json_data = json_data + json.dumps(dic)
|
||||
checker = 1
|
||||
else:
|
||||
json_data = json_data + ',' + json.dumps(dic)
|
||||
|
||||
json_data = json_data + ']'
|
||||
|
||||
return json_data
|
||||
|
||||
def websitePagination(self, currentACL, userID):
|
||||
websites = ACLManager.findAllSites(currentACL, userID)
|
||||
|
||||
pages = float(len(websites)) / float(10)
|
||||
pagination = []
|
||||
|
||||
if pages <= 1.0:
|
||||
pages = 1
|
||||
pagination.append('<li><a href="\#"></a></li>')
|
||||
else:
|
||||
pages = ceil(pages)
|
||||
finalPages = int(pages) + 1
|
||||
|
||||
for i in range(1, finalPages):
|
||||
pagination.append('<li><a href="\#">' + str(i) + '</a></li>')
|
||||
|
||||
return pagination
|
||||
|
||||
def getFurtherAccounts(self, userID=None, data=None):
|
||||
try:
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
pageNumber = int(data['page'])
|
||||
json_data = self.findWebsitesJson(currentACL, userID, pageNumber)
|
||||
pagination = self.websitePagination(currentACL, userID)
|
||||
|
||||
cageFSPath = '/home/cyberpanel/cagefs'
|
||||
|
||||
if os.path.exists(cageFSPath):
|
||||
default = 'On'
|
||||
else:
|
||||
default = 'Off'
|
||||
|
||||
final_dic = {'status': 1, 'listWebSiteStatus': 1, 'error_message': "None", "data": json_data,
|
||||
'pagination': pagination, 'default': default}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
except BaseException, msg:
|
||||
dic = {'status': 1, 'listWebSiteStatus': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(dic)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def enableOrDisable(self):
|
||||
try:
|
||||
websites = Websites.objects.all()
|
||||
if self.data['mode'] == 1:
|
||||
for items in websites:
|
||||
command = '/usr/sbin/cagefsctl --enable %s' % (items.externalApp)
|
||||
ProcessUtilities.executioner(command)
|
||||
else:
|
||||
for items in websites:
|
||||
command = '/usr/sbin/cagefsctl --disable %s' % (items.externalApp)
|
||||
ProcessUtilities.executioner(command)
|
||||
except BaseException, msg:
|
||||
logging.CyberCPLogFileWriter.writeToFile(str(msg))
|
||||
|
||||
def fetchPackages(self, currentACL):
|
||||
|
||||
if currentACL['admin'] == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson()
|
||||
|
||||
json_data = "["
|
||||
checker = 0
|
||||
|
||||
for items in CLPackages.objects.all():
|
||||
dic = {'name': items.name, 'SPEED': items.speed, 'VMEM': items.vmem, 'PMEM': items.pmem, 'IO': items.io, 'IOPS': items.iops, 'EP': items.ep,
|
||||
'NPROC': items.nproc, 'inodessoft': items.inodessoft, 'inodeshard': items.inodeshard}
|
||||
|
||||
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_dic = {'status': 1, 'error_message': "None", "data": json_data}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
#!/usr/local/CyberCP/bin/python2
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
import django
|
||||
sys.path.append('/usr/local/CyberCP')
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
|
||||
django.setup()
|
||||
import argparse
|
||||
from websiteFunctions.models import Websites
|
||||
from CLManager.models import CLPackages
|
||||
import pwd
|
||||
|
||||
class CLinuxPackages:
|
||||
|
||||
@staticmethod
|
||||
def listAll():
|
||||
for items in Websites.objects.all():
|
||||
itemPackage = items.package
|
||||
try:
|
||||
clPackage = CLPackages.objects.get(owner=itemPackage)
|
||||
statement = '%s %s' % (pwd.getpwnam(items.externalApp).pw_uid, clPackage.name)
|
||||
print statement
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@staticmethod
|
||||
def listPackages():
|
||||
for items in CLPackages.objects.all():
|
||||
print items.name
|
||||
|
||||
@staticmethod
|
||||
def userIDPackage(user):
|
||||
website = Websites.objects.get(externalApp=user)
|
||||
itemPackage = website.package
|
||||
try:
|
||||
clPackage = CLPackages.objects.get(owner=itemPackage)
|
||||
print clPackage
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@staticmethod
|
||||
def packageForUser(package):
|
||||
for items in Websites.objects.all():
|
||||
itemPackage = items.package
|
||||
try:
|
||||
clPackage = CLPackages.objects.get(owner=itemPackage)
|
||||
if clPackage.name == package:
|
||||
print pwd.getpwnam(items.externalApp).pw_uid
|
||||
except:
|
||||
pass
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser(description='CyberPanel Container Manager')
|
||||
parser.add_argument('--userid', help='User ID')
|
||||
parser.add_argument('--package', help='Package')
|
||||
parser.add_argument('--function', help='Function')
|
||||
parser.add_argument('--list-all', help='List all users/packages.', action='store_true')
|
||||
parser.add_argument('--list-packages', help='List all packages.', action='store_true')
|
||||
|
||||
|
||||
args = vars(parser.parse_args())
|
||||
|
||||
if args['userid']:
|
||||
CLinuxPackages.userIDPackage(args['userid'])
|
||||
elif args['package']:
|
||||
CLinuxPackages.packageForUser(args['package'])
|
||||
elif args['list_all']:
|
||||
CLinuxPackages.listAll()
|
||||
elif args['list_packages']:
|
||||
CLinuxPackages.listPackages()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
#!/usr/local/CyberCP/bin/python2
|
||||
import sys
|
||||
sys.path.append('/usr/local/CyberCP')
|
||||
import plogical.CyberCPLogFileWriter as logging
|
||||
import argparse
|
||||
from plogical.mailUtilities import mailUtilities
|
||||
from serverStatus.serverStatusUtil import ServerStatusUtil
|
||||
|
||||
|
||||
class CageFS:
|
||||
packages = ['talksho']
|
||||
users = ['5001']
|
||||
|
||||
@staticmethod
|
||||
def submitCageFSInstall():
|
||||
try:
|
||||
|
||||
mailUtilities.checkHome()
|
||||
|
||||
statusFile = open(ServerStatusUtil.lswsInstallStatusPath, 'w')
|
||||
|
||||
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
|
||||
"Starting Packages Installation..\n", 1)
|
||||
|
||||
command = 'sudo yum install cagefs -y'
|
||||
ServerStatusUtil.executioner(command, statusFile)
|
||||
|
||||
command = 'sudo /usr/sbin/cagefsctl --init'
|
||||
ServerStatusUtil.executioner(command, statusFile)
|
||||
|
||||
command = 'sudo /usr/sbin/cagefsctl --update-etc'
|
||||
ServerStatusUtil.executioner(command, statusFile)
|
||||
|
||||
command = 'sudo /usr/sbin/cagefsctl --force-update'
|
||||
ServerStatusUtil.executioner(command, statusFile)
|
||||
|
||||
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
|
||||
"Packages successfully installed.[200]\n", 1)
|
||||
|
||||
except BaseException, msg:
|
||||
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, str(msg) + ' [404].', 1)
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser(description='CyberPanel CageFS Manager')
|
||||
parser.add_argument('--function', help='Function')
|
||||
|
||||
|
||||
args = vars(parser.parse_args())
|
||||
|
||||
if args["function"] == "submitCageFSInstall":
|
||||
CageFS.submitCageFSInstall()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ClmanagerConfig(AppConfig):
|
||||
name = 'CLManager'
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models
|
||||
from packages.models import Package
|
||||
|
||||
# Create your models here.
|
||||
|
||||
class CLPackages(models.Model):
|
||||
owner = models.ForeignKey(Package)
|
||||
name = models.CharField(max_length=50,unique=True)
|
||||
speed = models.CharField(max_length=50)
|
||||
vmem = models.CharField(max_length=50)
|
||||
pmem = models.CharField(max_length=50)
|
||||
io = models.CharField(max_length=50)
|
||||
iops = models.CharField(max_length=50)
|
||||
ep = models.CharField(max_length=50)
|
||||
nproc = models.CharField(max_length=50)
|
||||
inodessoft = models.CharField(max_length=50)
|
||||
inodeshard = models.CharField(max_length=50)
|
||||
|
|
@ -0,0 +1,934 @@
|
|||
app.controller('installCageFS', function ($scope, $http, $timeout, $window) {
|
||||
|
||||
$scope.installDockerStatus = true;
|
||||
$scope.installBoxGen = true;
|
||||
$scope.dockerInstallBTN = false;
|
||||
|
||||
$scope.submitCageFSInstall = function () {
|
||||
|
||||
$scope.installDockerStatus = false;
|
||||
$scope.installBoxGen = true;
|
||||
$scope.dockerInstallBTN = true;
|
||||
|
||||
url = "/CloudLinux/submitCageFSInstall";
|
||||
|
||||
var data = {};
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
$scope.installBoxGen = false;
|
||||
getRequestStatus();
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function getRequestStatus() {
|
||||
$scope.cyberPanelLoading = false;
|
||||
|
||||
url = "/serverstatus/switchTOLSWSStatus";
|
||||
|
||||
var data = {};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
if (response.data.abort === 0) {
|
||||
$scope.requestData = response.data.requestStatus;
|
||||
$timeout(getRequestStatus, 1000);
|
||||
} else {
|
||||
// Notifications
|
||||
$scope.cyberPanelLoading = true;
|
||||
$timeout.cancel();
|
||||
$scope.requestData = response.data.requestStatus;
|
||||
if (response.data.installed === 1) {
|
||||
$timeout(function () {
|
||||
$window.location.reload();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
app.controller('listWebsitesCage', function ($scope, $http) {
|
||||
|
||||
var globalPageNumber;
|
||||
$scope.getFurtherWebsitesFromDB = function (pageNumber) {
|
||||
$scope.cyberPanelLoading = false;
|
||||
globalPageNumber = pageNumber;
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
var data = {page: pageNumber};
|
||||
|
||||
|
||||
dataurl = "/CloudLinux/submitWebsiteListing";
|
||||
|
||||
$http.post(dataurl, data, config).then(ListInitialData, cantLoadInitialData);
|
||||
|
||||
|
||||
function ListInitialData(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
if (response.data.listWebSiteStatus === 1) {
|
||||
var finalData = JSON.parse(response.data.data);
|
||||
$scope.WebSitesList = finalData;
|
||||
$scope.pagination = response.data.pagination;
|
||||
$scope.default = response.data.default;
|
||||
$("#listFail").hide();
|
||||
} else {
|
||||
$("#listFail").fadeIn();
|
||||
$scope.errorMessage = response.data.error_message;
|
||||
console.log(response.data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function cantLoadInitialData(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
console.log("not good");
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
$scope.getFurtherWebsitesFromDB(1);
|
||||
|
||||
$scope.cyberPanelLoading = true;
|
||||
|
||||
$scope.searchWebsites = function () {
|
||||
|
||||
$scope.cyberPanelLoading = false;
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
var data = {
|
||||
patternAdded: $scope.patternAdded
|
||||
};
|
||||
|
||||
dataurl = "/websites/searchWebsites";
|
||||
|
||||
$http.post(dataurl, data, config).then(ListInitialData, cantLoadInitialData);
|
||||
|
||||
|
||||
function ListInitialData(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
if (response.data.listWebSiteStatus === 1) {
|
||||
|
||||
var finalData = JSON.parse(response.data.data);
|
||||
$scope.WebSitesList = finalData;
|
||||
$("#listFail").hide();
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function cantLoadInitialData(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Connect disrupted, refresh the page.',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
$scope.enableOrDisable = function (domain, all, mode, toggle = 0) {
|
||||
$scope.cyberPanelLoading = false;
|
||||
|
||||
url = "/CloudLinux/enableOrDisable";
|
||||
|
||||
var data = {
|
||||
domain: domain,
|
||||
all: all,
|
||||
mode: mode,
|
||||
toggle: toggle
|
||||
};
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
text: response.data.success,
|
||||
type: 'success'
|
||||
});
|
||||
|
||||
if (all === 0) {
|
||||
$scope.getFurtherWebsitesFromDB(globalPageNumber);
|
||||
}
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.refreshStatus = function () {
|
||||
$scope.getFurtherWebsitesFromDB(globalPageNumber);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
app.controller('createCLPackage', function ($scope, $http) {
|
||||
|
||||
$scope.cyberPanelLoading = true;
|
||||
$scope.modifyPackageForm = true;
|
||||
$scope.toggleView = function () {
|
||||
$scope.modifyPackageForm = false;
|
||||
};
|
||||
|
||||
$scope.createPackage = function () {
|
||||
$scope.cyberPanelLoading = false;
|
||||
|
||||
url = "/CloudLinux/submitCreatePackage";
|
||||
|
||||
var data = {
|
||||
selectedPackage: $scope.selectedPackage,
|
||||
name: $scope.name,
|
||||
SPEED: $scope.SPEED,
|
||||
VMEM: $scope.VMEM,
|
||||
PMEM: $scope.PMEM,
|
||||
IO: $scope.IO,
|
||||
IOPS: $scope.IOPS,
|
||||
EP: $scope.EP,
|
||||
NPROC: $scope.NPROC,
|
||||
INODESsoft: $scope.INODESsoft,
|
||||
INODEShard: $scope.INODEShard,
|
||||
};
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
text: 'Successfully created.',
|
||||
type: 'success'
|
||||
});
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
app.controller('listCloudLinuxPackages', function ($scope, $http) {
|
||||
|
||||
$scope.cyberPanelLoading = true;
|
||||
|
||||
$scope.fetchPackageas = function () {
|
||||
$scope.cyberPanelLoading = false;
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
var data = {};
|
||||
|
||||
|
||||
dataurl = "/CloudLinux/fetchPackages";
|
||||
|
||||
$http.post(dataurl, data, config).then(ListInitialData, cantLoadInitialData);
|
||||
|
||||
|
||||
function ListInitialData(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
$scope.packages = JSON.parse(response.data.data);
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function cantLoadInitialData(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
$scope.fetchPackageas();
|
||||
|
||||
$scope.deleteCLPackage = function (name) {
|
||||
$scope.cyberPanelLoading = false;
|
||||
|
||||
url = "/CloudLinux/deleteCLPackage";
|
||||
|
||||
var data = {
|
||||
name: name
|
||||
};
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
text: 'Successfully deleted.',
|
||||
type: 'success'
|
||||
});
|
||||
$scope.fetchPackageas();
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
$scope.populatePackage = function (name, speed, vmem, pmem, io, iops, ep, nproc, inodessoft, inodeshard) {
|
||||
$scope.name = name;
|
||||
$scope.SPEED = speed;
|
||||
$scope.VMEM = vmem;
|
||||
$scope.PMEM = pmem;
|
||||
$scope.IO = io;
|
||||
$scope.IOPS = iops;
|
||||
$scope.EP = ep;
|
||||
$scope.NPROC = nproc;
|
||||
$scope.inodessoft = inodessoft;
|
||||
$scope.inodeshard = inodeshard;
|
||||
|
||||
};
|
||||
|
||||
$scope.saveSettings = function () {
|
||||
$scope.cyberPanelLoading = false;
|
||||
|
||||
url = "/CloudLinux/saveSettings";
|
||||
|
||||
var data = {
|
||||
name: $scope.name,
|
||||
SPEED: $scope.SPEED,
|
||||
VMEM: $scope.VMEM,
|
||||
PMEM: $scope.PMEM,
|
||||
IO: $scope.IO,
|
||||
IOPS: $scope.IOPS,
|
||||
EP: $scope.EP,
|
||||
NPROC: $scope.NPROC,
|
||||
INODESsoft: $scope.inodessoft,
|
||||
INODEShard: $scope.inodeshard,
|
||||
};
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
text: 'Changes successfully applied.',
|
||||
type: 'success'
|
||||
});
|
||||
$scope.fetchPackageas();
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
|
||||
app.controller('websiteContainerLimitCL', function ($scope, $http, $timeout, $window) {
|
||||
|
||||
|
||||
// Get CPU Usage of User
|
||||
|
||||
var cpu = [];
|
||||
var dataset;
|
||||
var totalPoints = 100;
|
||||
var updateInterval = 1000;
|
||||
var now = new Date().getTime();
|
||||
|
||||
var options = {
|
||||
series: {
|
||||
lines: {
|
||||
lineWidth: 1.2
|
||||
},
|
||||
bars: {
|
||||
align: "center",
|
||||
fillColor: {colors: [{opacity: 1}, {opacity: 1}]},
|
||||
barWidth: 500,
|
||||
lineWidth: 1
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
mode: "time",
|
||||
tickSize: [5, "second"],
|
||||
tickFormatter: function (v, axis) {
|
||||
var date = new Date(v);
|
||||
|
||||
if (date.getSeconds() % 20 == 0) {
|
||||
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
|
||||
var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
|
||||
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
|
||||
|
||||
return hours + ":" + minutes + ":" + seconds;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
axisLabel: "Time",
|
||||
axisLabelUseCanvas: true,
|
||||
axisLabelFontSizePixels: 12,
|
||||
axisLabelFontFamily: 'Verdana, Arial',
|
||||
axisLabelPadding: 10
|
||||
},
|
||||
yaxes: [
|
||||
{
|
||||
min: 0,
|
||||
max: 100,
|
||||
tickSize: 5,
|
||||
tickFormatter: function (v, axis) {
|
||||
if (v % 10 == 0) {
|
||||
return v + "%";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
axisLabel: "CPU loading",
|
||||
axisLabelUseCanvas: true,
|
||||
axisLabelFontSizePixels: 12,
|
||||
axisLabelFontFamily: 'Verdana, Arial',
|
||||
axisLabelPadding: 6
|
||||
}, {
|
||||
max: 5120,
|
||||
position: "right",
|
||||
axisLabel: "Disk",
|
||||
axisLabelUseCanvas: true,
|
||||
axisLabelFontSizePixels: 12,
|
||||
axisLabelFontFamily: 'Verdana, Arial',
|
||||
axisLabelPadding: 6
|
||||
}
|
||||
],
|
||||
legend: {
|
||||
noColumns: 0,
|
||||
position: "nw"
|
||||
},
|
||||
grid: {
|
||||
backgroundColor: {colors: ["#ffffff", "#EDF5FF"]}
|
||||
}
|
||||
};
|
||||
|
||||
function initData() {
|
||||
for (var i = 0; i < totalPoints; i++) {
|
||||
var temp = [now += updateInterval, 0];
|
||||
|
||||
cpu.push(temp);
|
||||
}
|
||||
}
|
||||
|
||||
function GetData() {
|
||||
|
||||
var data = {
|
||||
domain: $("#domain").text()
|
||||
};
|
||||
$.ajaxSetup({cache: false});
|
||||
|
||||
$.ajax({
|
||||
url: "/CloudLinux/getUsageData",
|
||||
dataType: 'json',
|
||||
success: update,
|
||||
type: "POST",
|
||||
headers: {'X-CSRFToken': getCookie('csrftoken')},
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify(data), // Our valid JSON string
|
||||
error: function () {
|
||||
setTimeout(GetData, updateInterval);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var temp;
|
||||
|
||||
function update(_data) {
|
||||
cpu.shift();
|
||||
|
||||
now += updateInterval;
|
||||
|
||||
temp = [now, _data.cpu];
|
||||
cpu.push(temp);
|
||||
|
||||
|
||||
dataset = [
|
||||
{label: "CPU:" + _data.cpu + "%", data: cpu, lines: {fill: true, lineWidth: 1.2}, color: "#00FF00"}
|
||||
];
|
||||
|
||||
$.plot($("#flot-placeholder1"), dataset, options);
|
||||
setTimeout(GetData, updateInterval);
|
||||
}
|
||||
|
||||
// Memory Usage of User
|
||||
|
||||
var memory = [];
|
||||
var datasetMemory;
|
||||
var totalPointsMemory = 100;
|
||||
var updateIntervalMemory = 1000;
|
||||
var nowMemory = new Date().getTime();
|
||||
|
||||
var optionsMemory = {
|
||||
series: {
|
||||
lines: {
|
||||
lineWidth: 1.2
|
||||
},
|
||||
bars: {
|
||||
align: "center",
|
||||
fillColor: {colors: [{opacity: 1}, {opacity: 1}]},
|
||||
barWidth: 500,
|
||||
lineWidth: 1
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
mode: "time",
|
||||
tickSize: [5, "second"],
|
||||
tickFormatter: function (v, axis) {
|
||||
var date = new Date(v);
|
||||
|
||||
if (date.getSeconds() % 20 == 0) {
|
||||
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
|
||||
var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
|
||||
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
|
||||
|
||||
return hours + ":" + minutes + ":" + seconds;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
axisLabel: "Time",
|
||||
axisLabelUseCanvas: true,
|
||||
axisLabelFontSizePixels: 12,
|
||||
axisLabelFontFamily: 'Verdana, Arial',
|
||||
axisLabelPadding: 10
|
||||
},
|
||||
yaxes: [
|
||||
{
|
||||
min: 0,
|
||||
max: $scope.memory,
|
||||
tickSize: 5,
|
||||
tickFormatter: function (v, axis) {
|
||||
if (v % 10 == 0) {
|
||||
return v + "MB";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
axisLabel: "CPU loading",
|
||||
axisLabelUseCanvas: true,
|
||||
axisLabelFontSizePixels: 12,
|
||||
axisLabelFontFamily: 'Verdana, Arial',
|
||||
axisLabelPadding: 6
|
||||
}, {
|
||||
max: 5120,
|
||||
position: "right",
|
||||
axisLabel: "Disk",
|
||||
axisLabelUseCanvas: true,
|
||||
axisLabelFontSizePixels: 12,
|
||||
axisLabelFontFamily: 'Verdana, Arial',
|
||||
axisLabelPadding: 6
|
||||
}
|
||||
],
|
||||
legend: {
|
||||
noColumns: 0,
|
||||
position: "nw"
|
||||
},
|
||||
grid: {
|
||||
backgroundColor: {colors: ["#ffffff", "#EDF5FF"]}
|
||||
}
|
||||
};
|
||||
|
||||
function initDataMemory() {
|
||||
for (var i = 0; i < totalPointsMemory; i++) {
|
||||
var temp = [nowMemory += updateIntervalMemory, 0];
|
||||
|
||||
memory.push(temp);
|
||||
}
|
||||
}
|
||||
|
||||
function GetDataMemory() {
|
||||
|
||||
var data = {
|
||||
domain: $("#domain").text(),
|
||||
type: 'memory'
|
||||
};
|
||||
$.ajaxSetup({cache: false});
|
||||
|
||||
$.ajax({
|
||||
url: "/CloudLinux/getUsageData",
|
||||
dataType: 'json',
|
||||
headers: {'X-CSRFToken': getCookie('csrftoken')},
|
||||
success: updateMemory,
|
||||
type: "POST",
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify(data), // Our valid JSON string
|
||||
error: function () {
|
||||
setTimeout(GetDataMemory, updateIntervalMemory);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var tempMemory;
|
||||
|
||||
function updateMemory(_data) {
|
||||
memory.shift();
|
||||
|
||||
nowMemory += updateIntervalMemory;
|
||||
|
||||
tempMemory = [nowMemory, _data.memory];
|
||||
memory.push(tempMemory);
|
||||
|
||||
|
||||
datasetMemory = [
|
||||
{
|
||||
label: "Memory:" + _data.memory + "MB",
|
||||
data: memory,
|
||||
lines: {fill: true, lineWidth: 1.2},
|
||||
color: "#00FF00"
|
||||
}
|
||||
];
|
||||
|
||||
$.plot($("#memoryUsage"), datasetMemory, optionsMemory);
|
||||
setTimeout(GetDataMemory, updateIntervalMemory);
|
||||
}
|
||||
|
||||
// Disk Usage
|
||||
|
||||
var readRate = [], writeRate = [];
|
||||
var datasetDisk;
|
||||
var totalPointsDisk = 100;
|
||||
var updateIntervalDisk = 5000;
|
||||
var now = new Date().getTime();
|
||||
|
||||
var optionsDisk = {
|
||||
series: {
|
||||
lines: {
|
||||
lineWidth: 1.2
|
||||
},
|
||||
bars: {
|
||||
align: "center",
|
||||
fillColor: {colors: [{opacity: 1}, {opacity: 1}]},
|
||||
barWidth: 500,
|
||||
lineWidth: 1
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
mode: "time",
|
||||
tickSize: [30, "second"],
|
||||
tickFormatter: function (v, axis) {
|
||||
var date = new Date(v);
|
||||
|
||||
if (date.getSeconds() % 20 == 0) {
|
||||
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
|
||||
var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
|
||||
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
|
||||
|
||||
return hours + ":" + minutes + ":" + seconds;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
axisLabel: "Time",
|
||||
axisLabelUseCanvas: true,
|
||||
axisLabelFontSizePixels: 12,
|
||||
axisLabelFontFamily: 'Verdana, Arial',
|
||||
axisLabelPadding: 10
|
||||
},
|
||||
yaxes: [
|
||||
{
|
||||
min: 0,
|
||||
max: $scope.networkSpeed,
|
||||
tickSize: 5,
|
||||
tickFormatter: function (v, axis) {
|
||||
if (v % 10 == 0) {
|
||||
return v + "mb/sec";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
axisLabel: "CPU loading",
|
||||
axisLabelUseCanvas: true,
|
||||
axisLabelFontSizePixels: 12,
|
||||
axisLabelFontFamily: 'Verdana, Arial',
|
||||
axisLabelPadding: 6
|
||||
}, {
|
||||
max: 5120,
|
||||
position: "right",
|
||||
axisLabel: "Disk",
|
||||
axisLabelUseCanvas: true,
|
||||
axisLabelFontSizePixels: 12,
|
||||
axisLabelFontFamily: 'Verdana, Arial',
|
||||
axisLabelPadding: 6
|
||||
}
|
||||
],
|
||||
legend: {
|
||||
noColumns: 0,
|
||||
position: "nw"
|
||||
},
|
||||
grid: {
|
||||
backgroundColor: {colors: ["#ffffff", "#EDF5FF"]}
|
||||
}
|
||||
};
|
||||
|
||||
function initDataDisk() {
|
||||
for (var i = 0; i < totalPointsDisk; i++) {
|
||||
var temp = [now += updateIntervalDisk, 0];
|
||||
|
||||
readRate.push(temp);
|
||||
writeRate.push(temp);
|
||||
}
|
||||
}
|
||||
|
||||
function GetDataDisk() {
|
||||
|
||||
var data = {
|
||||
domain: $("#domain").text(),
|
||||
type: 'io'
|
||||
};
|
||||
|
||||
$.ajaxSetup({cache: false});
|
||||
|
||||
$.ajax({
|
||||
url: "/CloudLinux/getUsageData",
|
||||
dataType: 'json',
|
||||
headers: {'X-CSRFToken': getCookie('csrftoken')},
|
||||
success: updateDisk,
|
||||
type: "POST",
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify(data), // Our valid JSON string
|
||||
error: function () {
|
||||
setTimeout(GetDataMemory, updateIntervalMemory);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var tempDisk;
|
||||
|
||||
function updateDisk(_data) {
|
||||
readRate.shift();
|
||||
writeRate.shift();
|
||||
|
||||
now += updateIntervalDisk;
|
||||
|
||||
tempDisk = [now, _data.readRate];
|
||||
readRate.push(tempDisk);
|
||||
|
||||
tempDisk = [now, _data.readRate];
|
||||
writeRate.push(tempDisk);
|
||||
|
||||
datasetDisk = [
|
||||
{
|
||||
label: "Read IO/s " + _data.readRate + " mb/s ",
|
||||
data: readRate,
|
||||
lines: {fill: true, lineWidth: 1.2},
|
||||
color: "#00FF00"
|
||||
},
|
||||
{
|
||||
label: "Write IO/s " + _data.writeRate + " mb/s ",
|
||||
data: writeRate,
|
||||
lines: {lineWidth: 1.2},
|
||||
color: "#FF0000"
|
||||
}
|
||||
];
|
||||
|
||||
$.plot($("#diskUsage"), datasetDisk, optionsDisk);
|
||||
setTimeout(GetDataDisk, updateIntervalDisk);
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
// Report Memory Usage
|
||||
|
||||
initDataMemory();
|
||||
|
||||
datasetMemory = [
|
||||
{label: "Memory", data: memory, lines: {fill: true, lineWidth: 1.2}, color: "#00FF00"}
|
||||
];
|
||||
|
||||
$.plot($("#memoryUsage"), datasetMemory, optionsMemory);
|
||||
setTimeout(GetDataMemory, updateIntervalMemory);
|
||||
|
||||
// Report CPU Usage
|
||||
|
||||
initData();
|
||||
|
||||
dataset = [
|
||||
{label: "CPU", data: cpu, lines: {fill: true, lineWidth: 1.2}, color: "#00FF00"}
|
||||
];
|
||||
|
||||
$.plot($("#flot-placeholder1"), dataset, options);
|
||||
setTimeout(GetData, updateInterval);
|
||||
|
||||
// Report Disk Usage
|
||||
|
||||
initDataDisk();
|
||||
|
||||
datasetDisk = [
|
||||
{label: "Read IO/s: ", data: readRate, lines: {fill: true, lineWidth: 1.2}, color: "#00FF00"},
|
||||
{label: "Write IO/s: ", data: writeRate, color: "#0044FF", bars: {show: true}, yaxis: 2}
|
||||
];
|
||||
|
||||
$.plot($("#diskUsage"), datasetDisk, optionsDisk);
|
||||
setTimeout(GetDataDisk, updateIntervalDisk);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Create Cloud Linux Package - CyberPanel" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Create CloudLinux Package." %}</h2>
|
||||
<p>{% trans "Each CloudLinux package have one associated (owner) CyberPanel package. During website creation associated CloudLinux package will be assigned to website user." %}</p>
|
||||
</div>
|
||||
<div ng-controller="createCLPackage" class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="content-box-header">
|
||||
{% trans "Create Package" %} <img ng-hide="cyberPanelLoading" src="{% static 'images/loading.gif' %}">
|
||||
</h3>
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
|
||||
<form action="/" class="form-horizontal bordered-row panel-body">
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Select Package" %} </label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="toggleView()" ng-model="selectedPackage" class="form-control">
|
||||
{% for items in packList %}
|
||||
<option>{{ items }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!------ Modification form that appears after a click --------------->
|
||||
|
||||
<div ng-hide="modifyPackageForm">
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Package Name" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="name" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "SPEED" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="SPEED" required>
|
||||
</div>
|
||||
<div class="current-pack ng-binding">Ex 100%</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "VMEM" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="VMEM" required>
|
||||
</div>
|
||||
<div class="current-pack ng-binding">Ex 256m or 1G</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "PMEM" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="PMEM" required>
|
||||
</div>
|
||||
<div class="current-pack ng-binding">Ex 256m or 1G</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "IO" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="IO" required>
|
||||
</div>
|
||||
<div class="current-pack ng-binding">Ex 1024</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "IOPS" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="IOPS" required>
|
||||
</div>
|
||||
<div class="current-pack ng-binding">Ex 1024</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "EP" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="EP" required>
|
||||
</div>
|
||||
<div class="current-pack ng-binding">Ex 10</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "NPROC" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="NPROC" required>
|
||||
</div>
|
||||
<div class="current-pack ng-binding">Ex 10</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "INODES soft" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="INODESsoft" required>
|
||||
</div>
|
||||
<div class="current-pack ng-binding">Ex 1024</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "INODES hard" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="INODEShard" required>
|
||||
</div>
|
||||
<div class="current-pack ng-binding">Ex 1024</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!------ Modification form that appears after a click --------------->
|
||||
|
||||
|
||||
<div ng-hide="modifyPackageForm" class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-click="createPackage()"
|
||||
class="btn btn-primary btn-lg ">{% trans "Create Package" %}</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Manage CloudLinux Packages - CyberPanel" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
|
||||
<div ng-controller="listCloudLinuxPackages" class="container">
|
||||
|
||||
<div id="page-title">
|
||||
<h2 id="domainNamePage">{% trans "Manage CloudLinux Packages" %}</h2>
|
||||
<p>{% trans "Manage/Delete CloudLinux Packages." %}</p>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-body">
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered"
|
||||
id="datatable-example">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name<img ng-hide="cyberPanelLoading" src="/static/images/loading.gif"></th>
|
||||
<th>SPEED</th>
|
||||
<th>VMEM</th>
|
||||
<th>PMEM</th>
|
||||
<th>IO</th>
|
||||
<th>IOPS</th>
|
||||
<th>EP</th>
|
||||
<th>NPROC</th>
|
||||
<th>INODES soft</th>
|
||||
<th>INODES hard</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr ng-repeat="pack in packages track by $index">
|
||||
<td ng-bind="pack.name"></td>
|
||||
<td ng-bind="pack.SPEED"></td>
|
||||
<td ng-bind="pack.VMEM"></td>
|
||||
<td ng-bind="pack.PMEM"></td>
|
||||
<td ng-bind="pack.IO"></td>
|
||||
<td ng-bind="pack.IOPS"></td>
|
||||
<td ng-bind="pack.EP"></td>
|
||||
<td ng-bind="pack.NPROC"></td>
|
||||
<td ng-bind="pack.inodessoft"></td>
|
||||
<td ng-bind="pack.inodeshard"></td>
|
||||
<td>
|
||||
<a ng-click='deleteCLPackage(pack.name)'
|
||||
class="btn btn-border btn-alt border-red btn-link font-red"
|
||||
title=""><span>Delete</span></a>
|
||||
<a ng-click="populatePackage(pack.name, pack.SPEED, pack.VMEM, pack.PMEM, pack.IO, pack.IOPS, pack.EP, pack.NPROC, pack.inodessoft, pack.inodeshard)" data-toggle="modal" data-target="#settings" ng-click='deleteCLPackage()'
|
||||
class="btn btn-border btn-alt border-green btn-link font-green"
|
||||
title=""><span>Edit</span></a>
|
||||
<div id="settings" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
|
||||
<!-- Modal content-->
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×
|
||||
</button>
|
||||
<h4 class="modal-title">Edit Package
|
||||
<img id="containerSettingLoading" src="/static/images/loading.gif"
|
||||
style="display: none;">
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<form name="containerSettingsForm" action="/" class="form-horizontal">
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Name" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="name" type="text" class="form-control"
|
||||
ng-model="name" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "SPEED" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="SPEED" type="text" class="form-control"
|
||||
ng-model="$parent.SPEED" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "VMEM" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="VMEM" type="text" class="form-control"
|
||||
ng-model="$parent.VMEM" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "PMEM" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="PMEM" type="text" class="form-control"
|
||||
ng-model="$parent.PMEM" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "IO" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="IO" type="text" class="form-control"
|
||||
ng-model="$parent.IO" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "IOPS" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="IOPS" type="text" class="form-control"
|
||||
ng-model="$parent.IOPS" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "EP" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="EP" type="text" class="form-control"
|
||||
ng-model="$parent.EP" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "NPROC" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="NPROC" type="text" class="form-control"
|
||||
ng-model="$parent.NPROC" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "INODES soft" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="inodessoft" type="text" class="form-control"
|
||||
ng-model="$parent.inodessoft" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "INODES hard" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="inodeshard" type="text" class="form-control"
|
||||
ng-model="$parent.inodeshard" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" ng-disabled="savingSettings"
|
||||
class="btn btn-primary"
|
||||
ng-click="saveSettings()" data-dismiss="modal">Save
|
||||
</button>
|
||||
<button type="button" ng-disabled="savingSettings"
|
||||
class="btn btn-default" data-dismiss="modal">
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div id="listFail" class="alert alert-danger">
|
||||
<p>{% trans "Cannot list websites. Error message:" %} {$ errorMessage $}</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-4 col-sm-offset-8">
|
||||
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination">
|
||||
|
||||
<li ng-repeat="page in pagination" ng-click="getFurtherWebsitesFromDB($index+1)"
|
||||
id="webPages"><a
|
||||
href="">{$ $index + 1 $}</a></li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "CageFS - CyberPanel" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
|
||||
<div ng-controller="listWebsitesCage" class="container">
|
||||
|
||||
<div id="page-title">
|
||||
<h2 id="domainNamePage">{% trans "List Websites" %}</h2>
|
||||
<p>{% trans "Enable/Disable and view CageFS status for websites." %}</p>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-body">
|
||||
<div style="padding-bottom: 0px; padding-top: 15px;" class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-6">
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
<div class="content-box remove-border clearfix text-center">
|
||||
|
||||
<a class="btn btn-primary" href="#" title="">
|
||||
<span>{% trans "Default: " %}
|
||||
<b>{$ default $}</b></span>
|
||||
</a>
|
||||
|
||||
<a href="#" ng-click="enableOrDisable(0, 0, 0, 1)"
|
||||
class="btn btn-border btn-alt border-green btn-link font-green"
|
||||
title=""><span>Toggle Default</span></a>
|
||||
|
||||
|
||||
<a href="#" ng-click="enableOrDisable(0, 1, 1, 0)" class="btn btn-success" title="Enable All">
|
||||
|
||||
<i class="fa fa-play btn-icon"></i>
|
||||
</a>
|
||||
<a href="#" ng-click="enableOrDisable(0, 1, 0, 0)" class="btn btn-warning" title="Disable All">
|
||||
|
||||
<i class="fa fa-pause btn-icon"></i>
|
||||
</a>
|
||||
|
||||
<a href="#" ng-click="refreshStatus()" class="btn btn-info" title="Refresh Status">
|
||||
<i class="fa fa-refresh btn-icon"></i>
|
||||
</a>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered"
|
||||
id="datatable-example">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Domain <img ng-hide="cyberPanelLoading" src="/static/images/loading.gif"></th>
|
||||
<th>User</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr ng-repeat="web in WebSitesList track by $index">
|
||||
<td ng-bind="web.domain"></td>
|
||||
<td ng-bind="web.externalApp"></td>
|
||||
<td>
|
||||
<a ng-click="enableOrDisable(web.domain, 0, 0, 0)" ng-hide="web.status==0"
|
||||
class="btn btn-border btn-alt border-red btn-link font-red"
|
||||
title=""><span>Disable</span></a>
|
||||
<a ng-click="enableOrDisable(web.domain, 0, 1, 0)" ng-hide="web.status==1"
|
||||
class="btn btn-border btn-alt border-green btn-link font-green"
|
||||
title=""><span>Enable</span></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div id="listFail" class="alert alert-danger">
|
||||
<p>{% trans "Cannot list websites. Error message:" %} {$ errorMessage $}</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-4 col-sm-offset-8">
|
||||
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination">
|
||||
|
||||
<li ng-repeat="page in pagination" ng-click="getFurtherWebsitesFromDB($index+1)"
|
||||
id="webPages"><a
|
||||
href="">{$ $index + 1 $}</a></li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Monitor Usage - CyberPanel" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div id="page-title">
|
||||
<h2 id="domainNamePage">{% trans "List Websites" %}</h2>
|
||||
<p>{% trans "Monitor usage of your websites." %}</p>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Websites" %}
|
||||
</h3>
|
||||
<div ng-controller="listWebsites" class="example-box-wrapper">
|
||||
|
||||
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered"
|
||||
id="datatable-example">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Domain</th>
|
||||
<th>Launch</th>
|
||||
<th>IP Address</th>
|
||||
<th>Package</th>
|
||||
<th>Owner</th>
|
||||
<th>State</th>
|
||||
<th>Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr ng-repeat="web in WebSitesList track by $index">
|
||||
<td ng-bind="web.domain"></td>
|
||||
<td><a href="/CloudLinux/manage/{$ web.domain $}"><img width="30px" height="30"
|
||||
class="center-block"
|
||||
src="{% static 'baseTemplate/assets/image-resources/webPanel.png' %}"></a>
|
||||
</td>
|
||||
<td ng-bind="web.ipAddress"></td>
|
||||
<td ng-bind="web.package"></td>
|
||||
<td ng-bind="web.admin"></td>
|
||||
<td ng-bind="web.state"></td>
|
||||
<td ng-bind="web.adminEmail"></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div id="listFail" class="alert alert-danger">
|
||||
<p>{% trans "Cannot list websites. Error message:" %} {$ errorMessage $}</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-4 col-sm-offset-8">
|
||||
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination">
|
||||
|
||||
<li ng-repeat="page in pagination" ng-click="getFurtherWebsitesFromDB($index+1)" id="webPages"><a
|
||||
href="">{$ $index + 1 $}</a></li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Not available - CyberPanel" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Not available" %}</h2>
|
||||
<p>{% trans "Either CageFS is not installed or you are not on CloudLinux OS." %}</p>
|
||||
</div>
|
||||
|
||||
{% if not CL %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="alert alert-danger">
|
||||
<p>{% trans "CageFS is only available with CloudLinux OS. " %} <a target="_blank"
|
||||
href="https://go.cyberpanel.net/CLConvert">Click
|
||||
Here</a> {% trans " for conversion details." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
|
||||
<div ng-controller="installCageFS" class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Install Packages" %} <img ng-hide="installDockerStatus"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
</h3>
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
<p>{% trans "CageFS is not installed on this server. Please proceed to installation." %}</p>
|
||||
<!------ LSWS Switch box ----------------->
|
||||
|
||||
<div style="margin-top: 2%" ng-hide="installBoxGen" class="col-md-12">
|
||||
|
||||
<form action="/" id="" class="form-horizontal bordered-row">
|
||||
<div class="form-group">
|
||||
<div style="margin-top: 2%;" class="col-sm-12">
|
||||
<textarea ng-model="requestData" rows="15"
|
||||
class="form-control">{{ requestData }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<!----- LSWS Switch box ----------------->
|
||||
<br>
|
||||
<button ng-hide="dockerInstallBTN" class="btn btn-primary" ng-click="submitCageFSInstall()">Install Now</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{{ domain }}{% trans " usage - CyberPanel" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
|
||||
<div ng-controller="websiteContainerLimitCL" class="container">
|
||||
|
||||
<div id="page-title">
|
||||
<h2 id="domainNamePage">{% trans "Usage" %}</h2>
|
||||
<p>{% trans "View CPU, Memory and Disk usage for " %} <span id="domain">{{ domain }}</span></p>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-body">
|
||||
<h2 class="title-hero">
|
||||
{% trans "CPU Usage of" %} {{ domain }}
|
||||
</h2>
|
||||
<div class="example-box-wrapper">
|
||||
<div id="flot-placeholder1" style="width:auto;height:300px"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<h2 class="title-hero">
|
||||
{% trans "Memory Usage of" %} {{ domain }}
|
||||
</h2>
|
||||
<div class="example-box-wrapper">
|
||||
<div id="memoryUsage" style="width:auto;height:300px"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<h2 class="title-hero">
|
||||
{% trans "Disk Usage of" %} {{ domain }}
|
||||
</h2>
|
||||
<div class="example-box-wrapper">
|
||||
<div id="diskUsage" style="width:auto;height:300px"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
from django.conf.urls import url
|
||||
import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^CageFS$', views.CageFS, name='CageFS'),
|
||||
url(r'^submitCageFSInstall$', views.submitCageFSInstall, name='submitCageFSInstall'),
|
||||
url(r'^submitWebsiteListing$', views.getFurtherAccounts, name='submitWebsiteListing'),
|
||||
url(r'^enableOrDisable$', views.enableOrDisable, name='enableOrDisable'),
|
||||
url(r'^CreatePackage$', views.CreatePackage, name='CreatePackageCL'),
|
||||
url(r'^submitCreatePackage$', views.submitCreatePackage, name='submitCreatePackageCL'),
|
||||
url(r'^listPackages$', views.listPackages, name='listPackagesCL'),
|
||||
url(r'^fetchPackages$', views.fetchPackages, name='fetchPackagesCL'),
|
||||
url(r'^deleteCLPackage$', views.deleteCLPackage, name='deleteCLPackage'),
|
||||
url(r'^saveSettings$', views.saveSettings, name='saveSettings'),
|
||||
url(r'^monitorUsage$', views.monitorUsage, name='monitorUsage'),
|
||||
url(r'^manage/(?P<domain>(.*))$', views.websiteContainerLimit, name='websiteContainerLimitCL'),
|
||||
url(r'^getUsageData$', views.getUsageData, name='getUsageData'),
|
||||
]
|
||||
|
|
@ -0,0 +1,358 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.shortcuts import redirect, HttpResponse
|
||||
from loginSystem.views import loadLoginPage
|
||||
from plogical.acl import ACLManager
|
||||
from CLManagerMain import CLManagerMain
|
||||
import json
|
||||
from websiteFunctions.models import Websites
|
||||
from plogical.processUtilities import ProcessUtilities
|
||||
import os
|
||||
from packages.models import Package
|
||||
from .models import CLPackages
|
||||
import subprocess
|
||||
import multiprocessing
|
||||
import pwd
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
# Create your views here.
|
||||
|
||||
def CageFS(request):
|
||||
try:
|
||||
templateName = 'CLManager/listWebsites.html'
|
||||
c = CLManagerMain(request, templateName)
|
||||
return c.renderC()
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def submitCageFSInstall(request):
|
||||
try:
|
||||
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if currentACL['admin'] == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson()
|
||||
|
||||
c = CLManagerMain(request, None, 'submitCageFSInstall')
|
||||
c.start()
|
||||
|
||||
data_ret = {'status': 1, 'error_message': 'None'}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException, msg:
|
||||
data_ret = {'status': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def getFurtherAccounts(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
wm = CLManagerMain()
|
||||
return wm.getFurtherAccounts(userID, json.loads(request.body))
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def enableOrDisable(request):
|
||||
try:
|
||||
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if currentACL['admin'] == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson()
|
||||
|
||||
data = json.loads(request.body)
|
||||
|
||||
if data['toggle'] == 1:
|
||||
cageFSPath = '/home/cyberpanel/cagefs'
|
||||
if os.path.exists(cageFSPath):
|
||||
os.remove(cageFSPath)
|
||||
else:
|
||||
writeToFile = open(cageFSPath, 'w')
|
||||
writeToFile.writelines('enable')
|
||||
writeToFile.close()
|
||||
|
||||
data_ret = {'status': 1, 'error_message': 'None', 'success': 'Default status successfully changed changed.'}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
if data['all'] == 0:
|
||||
if data['mode'] == 1:
|
||||
website = Websites.objects.get(domain=data['domain'])
|
||||
command = '/usr/sbin/cagefsctl --enable %s' % (website.externalApp)
|
||||
else:
|
||||
website = Websites.objects.get(domain=data['domain'])
|
||||
command = '/usr/sbin/cagefsctl --disable %s' % (website.externalApp)
|
||||
|
||||
ProcessUtilities.executioner(command)
|
||||
data_ret = {'status': 1, 'error_message': 'None', 'success': 'Changes successfully applied.'}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
else:
|
||||
c = CLManagerMain(request, None, 'enableOrDisable', data)
|
||||
c.start()
|
||||
|
||||
data_ret = {'status': 1, 'error_message': 'None', 'success': 'Job started in background, refresh in few seconds to see the status.'}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
|
||||
|
||||
except BaseException, msg:
|
||||
data_ret = {'status': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def CreatePackage(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
templateName = 'CLManager/createPackage.html'
|
||||
packageList = ACLManager.loadPackages(userID, currentACL)
|
||||
data = {}
|
||||
data['packList'] = packageList
|
||||
c = CLManagerMain(request, templateName, None, data)
|
||||
return c.renderC()
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def submitCreatePackage(request):
|
||||
try:
|
||||
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if currentACL['admin'] == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson()
|
||||
|
||||
data = json.loads(request.body)
|
||||
|
||||
selectedPackage = data['selectedPackage']
|
||||
|
||||
package = Package.objects.get(packageName=selectedPackage)
|
||||
|
||||
if package.clpackages_set.all().count() == 1:
|
||||
data_ret = {'status': 0, 'error_message': 'This package already have one associated CloudLinux Package.'}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
name = data['name']
|
||||
SPEED = data['SPEED']
|
||||
VMEM = data['VMEM']
|
||||
PMEM = data['PMEM']
|
||||
IO = data['IO']
|
||||
IOPS = data['IOPS']
|
||||
EP = data['EP']
|
||||
NPROC = data['NPROC']
|
||||
INODESsoft = data['INODESsoft']
|
||||
INODEShard = data['INODEShard']
|
||||
|
||||
clPackage = CLPackages(name=name, owner=package, speed=SPEED, vmem=VMEM, pmem=PMEM, io=IO, iops=IOPS, ep=EP, nproc=NPROC, inodessoft=INODESsoft, inodeshard=INODEShard)
|
||||
clPackage.save()
|
||||
|
||||
command = 'sudo lvectl package-set %s --speed=%s --pmem=%s --io=%s --nproc=%s --iops=%s --vmem=%s --ep=%s' % (name, SPEED, PMEM, IO, NPROC, IOPS, VMEM, EP)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
command = 'sudo lvectl apply all'
|
||||
ProcessUtilities.popenExecutioner(command)
|
||||
|
||||
data_ret = {'status': 1}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
|
||||
except BaseException, msg:
|
||||
data_ret = {'status': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def listPackages(request):
|
||||
try:
|
||||
templateName = 'CLManager/listPackages.html'
|
||||
c = CLManagerMain(request, templateName)
|
||||
return c.renderC()
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def fetchPackages(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
wm = CLManagerMain()
|
||||
return wm.fetchPackages(ACLManager.loadedACL(userID))
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def deleteCLPackage(request):
|
||||
try:
|
||||
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if currentACL['admin'] == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson()
|
||||
|
||||
data = json.loads(request.body)
|
||||
|
||||
name = data['name']
|
||||
|
||||
clPackage = CLPackages.objects.get(name=name)
|
||||
clPackage.delete()
|
||||
|
||||
data_ret = {'status': 1}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
|
||||
except BaseException, msg:
|
||||
data_ret = {'status': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def saveSettings(request):
|
||||
try:
|
||||
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if currentACL['admin'] == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson()
|
||||
|
||||
data = json.loads(request.body)
|
||||
|
||||
name = data['name']
|
||||
SPEED = data['SPEED']
|
||||
VMEM = data['VMEM']
|
||||
PMEM = data['PMEM']
|
||||
IO = data['IO']
|
||||
IOPS = data['IOPS']
|
||||
EP = data['EP']
|
||||
NPROC = data['NPROC']
|
||||
INODESsoft = data['INODESsoft']
|
||||
INODEShard = data['INODEShard']
|
||||
|
||||
clPackage = CLPackages.objects.get(name=name)
|
||||
clPackage.speed = SPEED
|
||||
clPackage.vmem = VMEM
|
||||
clPackage.pmem = PMEM
|
||||
clPackage.io = IO
|
||||
clPackage.iops = IOPS
|
||||
clPackage.ep = EP
|
||||
clPackage.nproc = NPROC
|
||||
clPackage.inodessoft = INODESsoft
|
||||
clPackage.inodeshard = INODEShard
|
||||
clPackage.save()
|
||||
|
||||
command = 'sudo lvectl package-set %s --speed=%s --pmem=%s --io=%s --nproc=%s --iops=%s --vmem=%s --ep=%s' % (
|
||||
name, SPEED, PMEM, IO, NPROC, IOPS, VMEM, EP)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
command = 'sudo lvectl apply all'
|
||||
ProcessUtilities.popenExecutioner(command)
|
||||
|
||||
data_ret = {'status': 1}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
|
||||
except BaseException, msg:
|
||||
data_ret = {'status': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def monitorUsage(request):
|
||||
try:
|
||||
templateName = 'CLManager/monitorUsage.html'
|
||||
c = CLManagerMain(request, templateName)
|
||||
return c.renderC()
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def websiteContainerLimit(request, domain):
|
||||
try:
|
||||
templateName = 'CLManager/websiteContainerLimit.html'
|
||||
data = {}
|
||||
data['domain'] = domain
|
||||
c = CLManagerMain(request, templateName, None, data)
|
||||
return c.renderC()
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def getUsageData(request):
|
||||
try:
|
||||
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if currentACL['admin'] == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson()
|
||||
|
||||
data = json.loads(request.body)
|
||||
domain = data['domain']
|
||||
website = Websites.objects.get(domain=domain)
|
||||
uid = pwd.getpwnam(website.externalApp).pw_uid
|
||||
|
||||
try:
|
||||
type = data['type']
|
||||
finalData = {}
|
||||
finalData['status'] = 1
|
||||
|
||||
try:
|
||||
if type == 'memory':
|
||||
|
||||
command = 'sudo lveps -o id:10,mem:10'
|
||||
output = ProcessUtilities.outputExecutioner(command).splitlines()
|
||||
for items in output:
|
||||
if items.find(website.externalApp) > -1:
|
||||
finalData['memory'] = int(items.split(' ')[-1])
|
||||
break
|
||||
|
||||
elif type == 'io':
|
||||
|
||||
finalData['readRate'] = 0
|
||||
finalData['writeRate'] = 0
|
||||
|
||||
command = 'sudo lveps -o id:10,iops:10'
|
||||
output = ProcessUtilities.outputExecutioner(command).splitlines()
|
||||
for items in output:
|
||||
if items.find(website.externalApp) > -1:
|
||||
finalData['readRate'] = int(items.split(' ')[-1])
|
||||
break
|
||||
|
||||
except:
|
||||
finalData['memory'] = '0'
|
||||
finalData['readRate'] = 0
|
||||
finalData['writeRate'] = 0
|
||||
except:
|
||||
|
||||
finalData = {}
|
||||
finalData['status'] = 1
|
||||
|
||||
command = 'sudo lveps -o id:10,cpu:10 -d'
|
||||
output = ProcessUtilities.outputExecutioner(command).splitlines()
|
||||
|
||||
for items in output:
|
||||
if items.find(website.externalApp) > -1:
|
||||
finalData['cpu'] = int(items.split(' ')[-1].rstrip('%'))
|
||||
break
|
||||
|
||||
final_json = json.dumps(finalData)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
except BaseException, msg:
|
||||
data_ret = {'status': 0, 'error_message': str(msg), 'cpu': 0, 'memory':0}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
from django.conf import settings
|
||||
from django.shortcuts import HttpResponse
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
import json
|
||||
from django.shortcuts import HttpResponse
|
||||
|
||||
class secMiddleware:
|
||||
|
||||
|
|
@ -8,8 +8,80 @@ class secMiddleware:
|
|||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request):
|
||||
try:
|
||||
uID = request.session['userID']
|
||||
ipAddr = request.META.get('REMOTE_ADDR')
|
||||
|
||||
if ipAddr.find('.') > -1:
|
||||
if request.session['ipAddr'] == ipAddr:
|
||||
pass
|
||||
else:
|
||||
del request.session['userID']
|
||||
del request.session['ipAddr']
|
||||
logging.writeToFile(request.META.get('REMOTE_ADDR'))
|
||||
final_dic = {'error_message': "Session reuse detected, IPAddress logged.",
|
||||
"errorMessage": "Session reuse detected, IPAddress logged."}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
else:
|
||||
ipAddr = request.META.get('REMOTE_ADDR').split(':')[:3]
|
||||
|
||||
if request.session['ipAddr'] == ipAddr:
|
||||
pass
|
||||
else:
|
||||
del request.session['userID']
|
||||
del request.session['ipAddr']
|
||||
logging.writeToFile(request.META.get('REMOTE_ADDR'))
|
||||
final_dic = {'error_message': "Session reuse detected, IPAddress logged.",
|
||||
"errorMessage": "Session reuse detected, IPAddress logged."}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
except:
|
||||
pass
|
||||
if request.method == 'POST':
|
||||
if request.body.find(';') > -1 or request.body.find('&&') > -1 or request.body.find('|') > -1 or request.body.find('...') > -1:
|
||||
logging.writeToFile('Bad Input on.')
|
||||
try:
|
||||
#logging.writeToFile(request.body)
|
||||
data = json.loads(request.body)
|
||||
for key, value in data.iteritems():
|
||||
if request.path.find('gitNotify') > -1:
|
||||
break
|
||||
|
||||
# if request.path.find('users') > -1 or request.path.find('firewall') > -1 or request.path.find('servicesAction') > -1 or request.path.find('sslForHostName') > -1:
|
||||
# logging.writeToFile(request.body)
|
||||
# final_dic = {'error_message': "Data supplied is not accepted.",
|
||||
# "errorMessage": "Data supplied is not accepted."}
|
||||
# final_json = json.dumps(final_dic)
|
||||
# return HttpResponse(final_json)
|
||||
|
||||
if type(value) == str or type(value) == unicode:
|
||||
pass
|
||||
else:
|
||||
continue
|
||||
|
||||
if request.build_absolute_uri().find('saveSpamAssassinConfigurations') > -1 or request.build_absolute_uri().find('docker') > -1 or request.build_absolute_uri().find('cloudAPI') > -1 or request.build_absolute_uri().find('filemanager') > -1 or request.build_absolute_uri().find('verifyLogin') > -1 or request.build_absolute_uri().find('submitUserCreation') > -1:
|
||||
continue
|
||||
if key == 'backupDestinations' or key == 'ports' or key == 'imageByPass' or key == 'passwordByPass' or key == 'cronCommand' or key == 'emailMessage' or key == 'configData' or key == 'rewriteRules' or key == 'modSecRules' or key == 'recordContentTXT' or key == 'SecAuditLogRelevantStatus' or key == 'fileContent':
|
||||
continue
|
||||
if value.find(';') > -1 or value.find('&&') > -1 or value.find('|') > -1 or value.find('...') > -1 \
|
||||
or value.find("`") > -1 or value.find("$") > -1 or value.find("(") > -1 or value.find(")") > -1 \
|
||||
or value.find("'") > -1 or value.find("[") > -1 or value.find("]") > -1 or value.find("{") > -1 or value.find("}") > -1\
|
||||
or value.find(":") > -1 or value.find("<") > -1 or value.find(">") > -1:
|
||||
logging.writeToFile(request.body)
|
||||
final_dic = {'error_message': "Data supplied is not accepted.",
|
||||
"errorMessage": "Data supplied is not accepted."}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
if key.find(';') > -1 or key.find('&&') > -1 or key.find('|') > -1 or key.find('...') > -1 \
|
||||
or key.find("`") > -1 or key.find("$") > -1 or key.find("(") > -1 or key.find(")") > -1 \
|
||||
or key.find("'") > -1 or key.find("[") > -1 or key.find("]") > -1 or key.find("{") > -1 or key.find("}") > -1\
|
||||
or key.find(":") > -1 or key.find("<") > -1 or key.find(">") > -1:
|
||||
logging.writeToFile(request.body)
|
||||
final_dic = {'error_message': "Data supplied is not accepted.", "errorMessage": "Data supplied is not accepted."}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
except BaseException, msg:
|
||||
logging.writeToFile(str(msg))
|
||||
response = self.get_response(request)
|
||||
return response
|
||||
response = self.get_response(request)
|
||||
return response
|
||||
return response
|
||||
|
|
|
|||
|
|
@ -24,13 +24,10 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|||
SECRET_KEY = 'xr%j*p!*$0d%(-(e%@-*hyoz4$f%y77coq0u)6pwmjg4)q&19f'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = False
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
|
|
@ -58,7 +55,17 @@ INSTALLED_APPS = [
|
|||
'manageSSL',
|
||||
'api',
|
||||
'filemanager',
|
||||
'emailPremium'
|
||||
'manageServices',
|
||||
'pluginHolder',
|
||||
'emailPremium',
|
||||
'emailMarketing',
|
||||
'cloudAPI',
|
||||
'highAvailability',
|
||||
's3Backups',
|
||||
'dockerManager',
|
||||
'containerization',
|
||||
'CLManager',
|
||||
'IncBackups'
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
|
@ -66,7 +73,7 @@ MIDDLEWARE = [
|
|||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.locale.LocaleMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
|
|
@ -106,7 +113,7 @@ DATABASES = {
|
|||
'USER': 'cyberpanel',
|
||||
'PASSWORD': 'Bz9gF7Hr7X4RtD',
|
||||
'HOST': '127.0.0.1',
|
||||
'PORT':'3307'
|
||||
'PORT':'3306'
|
||||
},
|
||||
'rootdb': {
|
||||
'ENGINE': 'django.db.backends.mysql',
|
||||
|
|
@ -153,7 +160,6 @@ USE_L10N = True
|
|||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/1.11/howto/static-files/
|
||||
|
||||
|
|
@ -176,4 +182,11 @@ LANGUAGES = (
|
|||
('ru', _('Russian')),
|
||||
('tr', _('Turkish')),
|
||||
('es', _('Spanish')),
|
||||
('fr', _('French')),
|
||||
('pl', _('Polish')),
|
||||
('vi', _('Vietnamese')),
|
||||
('it', _('Italian')),
|
||||
)
|
||||
|
||||
MEDIA_URL = '/home/cyberpanel/media/'
|
||||
MEDIA_ROOT = MEDIA_URL
|
||||
|
|
|
|||
|
|
@ -36,4 +36,12 @@ urlpatterns = [
|
|||
url(r'^api/',include('api.urls')),
|
||||
url(r'^filemanager/',include('filemanager.urls')),
|
||||
url(r'^emailPremium/',include('emailPremium.urls')),
|
||||
url(r'^manageservices/',include('manageServices.urls')),
|
||||
url(r'^plugins/',include('pluginHolder.urls')),
|
||||
url(r'^emailMarketing/', include('emailMarketing.urls')),
|
||||
url(r'^cloudAPI/', include('cloudAPI.urls')),
|
||||
url(r'^docker/', include('dockerManager.urls')),
|
||||
url(r'^container/', include('containerization.urls')),
|
||||
url(r'^CloudLinux/', include('CLManager.urls')),
|
||||
url(r'^IncrementalBackups/', include('IncBackups.urls')),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,375 @@
|
|||
#!/usr/local/CyberCP/bin/python2
|
||||
import os,sys
|
||||
sys.path.append('/usr/local/CyberCP')
|
||||
import django
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
|
||||
django.setup()
|
||||
import threading as multi
|
||||
from plogical.processUtilities import ProcessUtilities
|
||||
import time
|
||||
from .models import IncJob, JobSnapshots
|
||||
from websiteFunctions.models import Websites
|
||||
import plogical.randomPassword as randomPassword
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
from xml.etree.ElementTree import Element, SubElement
|
||||
from xml.etree import ElementTree
|
||||
from xml.dom import minidom
|
||||
from backup.models import DBUsers
|
||||
import plogical.mysqlUtilities as mysqlUtilities
|
||||
from plogical.backupUtilities import backupUtilities
|
||||
from plogical.dnsUtilities import DNS
|
||||
from mailServer.models import Domains as eDomains
|
||||
from random import randint
|
||||
|
||||
|
||||
class IncJobs(multi.Thread):
|
||||
|
||||
def __init__(self, function, extraArgs):
|
||||
multi.Thread.__init__(self)
|
||||
self.function = function
|
||||
self.extraArgs = extraArgs
|
||||
self.repoPath = ''
|
||||
self.passwordFile = ''
|
||||
self.statusPath = ''
|
||||
self.website = ''
|
||||
self.backupDestinations = ''
|
||||
self.jobid = 0
|
||||
|
||||
def run(self):
|
||||
|
||||
if self.function == 'createBackup':
|
||||
self.createBackup()
|
||||
|
||||
def prepareBackupMeta(self):
|
||||
try:
|
||||
|
||||
######### Generating meta
|
||||
|
||||
## XML Generation
|
||||
|
||||
metaFileXML = Element('metaFile')
|
||||
|
||||
child = SubElement(metaFileXML, 'masterDomain')
|
||||
child.text = self.website.domain
|
||||
|
||||
child = SubElement(metaFileXML, 'phpSelection')
|
||||
child.text = self.website.phpSelection
|
||||
|
||||
child = SubElement(metaFileXML, 'externalApp')
|
||||
child.text = self.website.externalApp
|
||||
|
||||
childDomains = self.website.childdomains_set.all()
|
||||
|
||||
databases = self.website.databases_set.all()
|
||||
|
||||
## Child domains XML
|
||||
|
||||
childDomainsXML = Element('ChildDomains')
|
||||
|
||||
for items in childDomains:
|
||||
childDomainXML = Element('domain')
|
||||
|
||||
child = SubElement(childDomainXML, 'domain')
|
||||
child.text = items.domain
|
||||
child = SubElement(childDomainXML, 'phpSelection')
|
||||
child.text = items.phpSelection
|
||||
child = SubElement(childDomainXML, 'path')
|
||||
child.text = items.path
|
||||
|
||||
childDomainsXML.append(childDomainXML)
|
||||
|
||||
metaFileXML.append(childDomainsXML)
|
||||
|
||||
## Databases XML
|
||||
|
||||
databasesXML = Element('Databases')
|
||||
|
||||
for items in databases:
|
||||
try:
|
||||
dbuser = DBUsers.objects.get(user=items.dbUser)
|
||||
userToTry = items.dbUser
|
||||
except:
|
||||
dbusers = DBUsers.objects.all().filter(user=items.dbUser)
|
||||
userToTry = items.dbUser
|
||||
for it in dbusers:
|
||||
dbuser = it
|
||||
break
|
||||
|
||||
userToTry = mysqlUtilities.mysqlUtilities.fetchuser(items.dbUser)
|
||||
|
||||
try:
|
||||
dbuser = DBUsers.objects.get(user=userToTry)
|
||||
except:
|
||||
dbusers = DBUsers.objects.all().filter(user=userToTry)
|
||||
for it in dbusers:
|
||||
dbuser = it
|
||||
break
|
||||
|
||||
databaseXML = Element('database')
|
||||
|
||||
child = SubElement(databaseXML, 'dbName')
|
||||
child.text = items.dbName
|
||||
child = SubElement(databaseXML, 'dbUser')
|
||||
child.text = userToTry
|
||||
child = SubElement(databaseXML, 'password')
|
||||
child.text = dbuser.password
|
||||
|
||||
databasesXML.append(databaseXML)
|
||||
|
||||
metaFileXML.append(databasesXML)
|
||||
|
||||
## Get Aliases
|
||||
|
||||
aliasesXML = Element('Aliases')
|
||||
|
||||
aliases = backupUtilities.getAliases(self.website.domain)
|
||||
|
||||
for items in aliases:
|
||||
child = SubElement(aliasesXML, 'alias')
|
||||
child.text = items
|
||||
|
||||
metaFileXML.append(aliasesXML)
|
||||
|
||||
## Finish Alias
|
||||
|
||||
## DNS Records XML
|
||||
|
||||
try:
|
||||
|
||||
dnsRecordsXML = Element("dnsrecords")
|
||||
dnsRecords = DNS.getDNSRecords(self.website.domain)
|
||||
|
||||
for items in dnsRecords:
|
||||
dnsRecordXML = Element('dnsrecord')
|
||||
|
||||
child = SubElement(dnsRecordXML, 'type')
|
||||
child.text = items.type
|
||||
child = SubElement(dnsRecordXML, 'name')
|
||||
child.text = items.name
|
||||
child = SubElement(dnsRecordXML, 'content')
|
||||
child.text = items.content
|
||||
child = SubElement(dnsRecordXML, 'priority')
|
||||
child.text = str(items.prio)
|
||||
|
||||
dnsRecordsXML.append(dnsRecordXML)
|
||||
|
||||
metaFileXML.append(dnsRecordsXML)
|
||||
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath, '%s. [158:prepMeta]' % (str(msg)), 1)
|
||||
|
||||
## Email accounts XML
|
||||
|
||||
try:
|
||||
emailRecordsXML = Element('emails')
|
||||
eDomain = eDomains.objects.get(domain=self.website.domain)
|
||||
emailAccounts = eDomain.eusers_set.all()
|
||||
|
||||
for items in emailAccounts:
|
||||
emailRecordXML = Element('emailAccount')
|
||||
|
||||
child = SubElement(emailRecordXML, 'email')
|
||||
child.text = items.email
|
||||
child = SubElement(emailRecordXML, 'password')
|
||||
child.text = items.password
|
||||
|
||||
emailRecordsXML.append(emailRecordXML)
|
||||
|
||||
metaFileXML.append(emailRecordsXML)
|
||||
except BaseException, msg:
|
||||
logging.writeToFile(self.statusPath, '%s. [warning:179:prepMeta]' % (str(msg)), 1)
|
||||
|
||||
## Email meta generated!
|
||||
|
||||
def prettify(elem):
|
||||
"""Return a pretty-printed XML string for the Element.
|
||||
"""
|
||||
rough_string = ElementTree.tostring(elem, 'utf-8')
|
||||
reparsed = minidom.parseString(rough_string)
|
||||
return reparsed.toprettyxml(indent=" ")
|
||||
|
||||
## /home/example.com/backup/backup-example.com-02.13.2018_10-24-52/meta.xml -- metaPath
|
||||
|
||||
metaPath = '/home/cyberpanel/%s' % (str(randint(1000, 9999)))
|
||||
|
||||
xmlpretty = prettify(metaFileXML).encode('ascii', 'ignore')
|
||||
metaFile = open(metaPath, 'w')
|
||||
metaFile.write(xmlpretty)
|
||||
metaFile.close()
|
||||
os.chmod(metaPath, 0640)
|
||||
|
||||
## meta generated
|
||||
|
||||
logging.statusWriter(self.statusPath, 'Meta data is ready..', 1)
|
||||
|
||||
metaPathNew = '/home/%s/meta.xml' % (self.website.domain)
|
||||
command = 'mv %s %s' % (metaPath, metaPathNew)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
command = 'chown %s:%s %s' % (self.website.externalApp, self.website.externalApp, metaPathNew)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
return 1
|
||||
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath, "%s [207][5009]" % (str(msg)), 1)
|
||||
return 0
|
||||
|
||||
def backupData(self):
|
||||
try:
|
||||
logging.statusWriter(self.statusPath, 'Backing up data..', 1)
|
||||
|
||||
if self.backupDestinations == 'local':
|
||||
backupPath = '/home/%s' % (self.website.domain)
|
||||
command = 'restic -r %s backup %s --password-file %s --exclude %s' % (self.repoPath, backupPath, self.passwordFile, self.repoPath)
|
||||
snapShotid = ProcessUtilities.outputExecutioner(command).split(' ')[-2]
|
||||
|
||||
newSnapshot = JobSnapshots(job=self.jobid, type='data:%s' % (backupPath), snapshotid=snapShotid, destination=self.backupDestinations)
|
||||
newSnapshot.save()
|
||||
|
||||
|
||||
elif self.backupDestinations[:4] == 'sftp':
|
||||
remotePath = '/home/backup/%s' % (self.website.domain)
|
||||
backupPath = '/home/%s' % (self.website.domain)
|
||||
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % (self.backupDestinations, remotePath, backupPath, self.passwordFile, self.repoPath)
|
||||
snapShotid = ProcessUtilities.outputExecutioner(command).split(' ')[-2]
|
||||
newSnapshot = JobSnapshots(job=self.jobid, type='data:%s' % (remotePath), snapshotid=snapShotid,
|
||||
destination=self.backupDestinations)
|
||||
newSnapshot.save()
|
||||
|
||||
logging.statusWriter(self.statusPath, 'Data for %s backed to %s.' % (self.website.domain, self.backupDestinations), 1)
|
||||
return 1
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath,'%s. [IncJobs.backupData.223][5009]' % str(msg), 1)
|
||||
return 0
|
||||
|
||||
def backupDatabases(self):
|
||||
try:
|
||||
logging.statusWriter(self.statusPath, 'Backing up databases..', 1)
|
||||
|
||||
databases = self.website.databases_set.all()
|
||||
|
||||
for items in databases:
|
||||
if mysqlUtilities.mysqlUtilities.createDatabaseBackup(items.dbName, '/home/cyberpanel') == 0:
|
||||
return 0
|
||||
|
||||
dbPath = '/home/cyberpanel/%s.sql' % (items.dbName)
|
||||
|
||||
if self.backupDestinations == 'local':
|
||||
command = 'restic -r %s backup %s --password-file %s' % (self.repoPath, dbPath, self.passwordFile)
|
||||
snapShotid = ProcessUtilities.outputExecutioner(command).split(' ')[-2]
|
||||
|
||||
newSnapshot = JobSnapshots(job=self.jobid, type='database:%s' % (items.dbName), snapshotid=snapShotid, destination=self.backupDestinations)
|
||||
newSnapshot.save()
|
||||
|
||||
elif self.backupDestinations[:4] == 'sftp':
|
||||
remotePath = '/home/backup/%s' % (self.website.domain)
|
||||
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % (
|
||||
self.backupDestinations, remotePath, dbPath, self.passwordFile, self.repoPath)
|
||||
snapShotid = ProcessUtilities.outputExecutioner(command).split(' ')[-2]
|
||||
newSnapshot = JobSnapshots(job=self.jobid, type='database:%s' % (items.dbName), snapshotid=snapShotid,
|
||||
destination=self.backupDestinations)
|
||||
newSnapshot.save()
|
||||
return 1
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath,'%s. [IncJobs.backupDatabases.269][5009]' % str(msg), 1)
|
||||
return 0
|
||||
|
||||
def emailBackup(self):
|
||||
try:
|
||||
logging.statusWriter(self.statusPath, 'Backing up emails..', 1)
|
||||
|
||||
backupPath = '/home/vmail/%s' % (self.website.domain)
|
||||
|
||||
if os.path.exists(backupPath):
|
||||
if self.backupDestinations == 'local':
|
||||
logging.statusWriter(self.statusPath, 'hello world', 1)
|
||||
command = 'restic -r %s backup %s --password-file %s' % (
|
||||
self.repoPath, backupPath, self.passwordFile)
|
||||
snapShotid = ProcessUtilities.outputExecutioner(command).split(' ')[-2]
|
||||
|
||||
newSnapshot = JobSnapshots(job=self.jobid, type='email:%s' % (backupPath), snapshotid=snapShotid,
|
||||
destination=self.backupDestinations)
|
||||
newSnapshot.save()
|
||||
logging.statusWriter(self.statusPath, 'hello world 2', 1)
|
||||
|
||||
elif self.backupDestinations[:4] == 'sftp':
|
||||
remotePath = '/home/backup/%s' % (self.website.domain)
|
||||
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % (
|
||||
self.backupDestinations, remotePath, backupPath, self.passwordFile, self.repoPath)
|
||||
snapShotid = ProcessUtilities.outputExecutioner(command).split(' ')[-2]
|
||||
newSnapshot = JobSnapshots(job=self.jobid, type='email:%s' % (backupPath), snapshotid=snapShotid,
|
||||
destination=self.backupDestinations)
|
||||
newSnapshot.save()
|
||||
|
||||
logging.statusWriter(self.statusPath, 'Emails for %s backed to %s.' % (self.website.domain, self.backupDestinations), 1)
|
||||
return 1
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath,'%s. [IncJobs.backupDatabases.269][5009]' % str(msg), 1)
|
||||
return 0
|
||||
|
||||
def initiateRepo(self):
|
||||
try:
|
||||
logging.statusWriter(self.statusPath, 'Will first initiate backup repo..', 1)
|
||||
|
||||
if self.backupDestinations == 'local':
|
||||
command = 'restic init --repo %s --password-file %s' % (self.repoPath, self.passwordFile)
|
||||
ProcessUtilities.executioner(command, self.website.externalApp)
|
||||
|
||||
elif self.backupDestinations[:4] == 'sftp':
|
||||
remotePath = '/home/backup/%s' % (self.website.domain)
|
||||
command = 'export PATH=${PATH}:/usr/bin && restic init --repo %s:%s --password-file %s' % (self.backupDestinations, remotePath, self.passwordFile)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
logging.statusWriter(self.statusPath, 'Repo %s initiated for %s.' % (self.backupDestinations, self.website.domain), 1)
|
||||
return 1
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath,'%s. [IncJobs.initiateRepo.47][5009]' % str(msg), 1)
|
||||
return 0
|
||||
|
||||
def createBackup(self):
|
||||
self.statusPath = self.extraArgs['tempPath']
|
||||
website = self.extraArgs['website']
|
||||
self.backupDestinations = self.extraArgs['backupDestinations']
|
||||
websiteData = self.extraArgs['websiteData']
|
||||
websiteEmails = self.extraArgs['websiteEmails']
|
||||
websiteSSLs = self.extraArgs['websiteSSLs']
|
||||
websiteDatabases = self.extraArgs['websiteDatabases']
|
||||
|
||||
self.website = Websites.objects.get(domain=website)
|
||||
|
||||
newJob = IncJob(website=self.website)
|
||||
newJob.save()
|
||||
|
||||
self.jobid = newJob
|
||||
|
||||
self.passwordFile = '/home/%s/%s' % (self.website.domain, self.website.domain)
|
||||
password = randomPassword.generate_pass()
|
||||
|
||||
self.repoPath = '/home/%s/incbackup' % (self.website.domain)
|
||||
|
||||
if not os.path.exists(self.passwordFile):
|
||||
command = 'echo "%s" > %s' % (password, self.passwordFile)
|
||||
ProcessUtilities.executioner(command, self.website.externalApp)
|
||||
|
||||
|
||||
if self.initiateRepo() == 0:
|
||||
return
|
||||
|
||||
if self.prepareBackupMeta() == 0:
|
||||
return
|
||||
|
||||
if websiteData:
|
||||
if self.backupData() == 0:
|
||||
return
|
||||
|
||||
if websiteDatabases:
|
||||
if self.backupDatabases() == 0:
|
||||
return
|
||||
|
||||
|
||||
if websiteEmails:
|
||||
if self.emailBackup() == 0:
|
||||
return
|
||||
|
||||
logging.statusWriter(self.statusPath, 'Completed', 1)
|
||||
|
|
@ -0,0 +1,541 @@
|
|||
#!/usr/local/CyberCP/bin/python2
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
sys.path.append('/usr/local/CyberCP')
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
|
||||
|
||||
import django
|
||||
try:
|
||||
django.setup()
|
||||
except:
|
||||
pass
|
||||
import threading as multi
|
||||
from plogical.processUtilities import ProcessUtilities
|
||||
from models import IncJob, JobSnapshots
|
||||
from websiteFunctions.models import Websites
|
||||
import plogical.randomPassword as randomPassword
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
from xml.etree.ElementTree import Element, SubElement
|
||||
from xml.etree import ElementTree
|
||||
from xml.dom import minidom
|
||||
from backup.models import DBUsers
|
||||
import plogical.mysqlUtilities as mysqlUtilities
|
||||
from plogical.backupUtilities import backupUtilities
|
||||
from plogical.dnsUtilities import DNS
|
||||
from mailServer.models import Domains as eDomains
|
||||
from random import randint
|
||||
try:
|
||||
from plogical.virtualHostUtilities import virtualHostUtilities
|
||||
from plogical.mailUtilities import mailUtilities
|
||||
except:
|
||||
pass
|
||||
|
||||
class IncJobs(multi.Thread):
|
||||
|
||||
def __init__(self, function, extraArgs):
|
||||
multi.Thread.__init__(self)
|
||||
self.function = function
|
||||
self.extraArgs = extraArgs
|
||||
self.repoPath = ''
|
||||
self.passwordFile = ''
|
||||
self.statusPath = ''
|
||||
self.website = ''
|
||||
self.backupDestinations = ''
|
||||
self.jobid = 0
|
||||
self.metaPath = ''
|
||||
|
||||
def run(self):
|
||||
|
||||
if self.function == 'createBackup':
|
||||
self.createBackup()
|
||||
elif self.function == 'restorePoint':
|
||||
self.restorePoint()
|
||||
|
||||
def restoreData(self):
|
||||
try:
|
||||
|
||||
if self.jobid.destination == 'local':
|
||||
repoLocation = '/home/%s/incbackup' % (self.website)
|
||||
command = 'restic -r %s restore %s --target / --password-file %s' % (repoLocation, self.jobid.snapshotid, self.passwordFile)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
elif self.jobid.destination[:4] == 'sftp':
|
||||
repoLocation = '/home/backup/%s' % (self.website)
|
||||
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s restore %s --target / --password-file %s' % (self.jobid.destination, repoLocation, self.jobid.snapshotid, self.passwordFile)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath, "%s [46][5009]" % (str(msg)), 1)
|
||||
return 0
|
||||
|
||||
def restoreDatabase(self):
|
||||
try:
|
||||
|
||||
if self.jobid.destination == 'local':
|
||||
repoLocation = '/home/%s/incbackup' % (self.website)
|
||||
command = 'restic -r %s restore %s --target / --password-file %s' % (repoLocation, self.jobid.snapshotid, self.passwordFile)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
elif self.jobid.destination[:4] == 'sftp':
|
||||
repoLocation = '/home/backup/%s' % (self.website)
|
||||
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s restore %s --target / --password-file %s' % (self.jobid.destination, repoLocation, self.jobid.snapshotid, self.passwordFile)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
|
||||
if mysqlUtilities.mysqlUtilities.restoreDatabaseBackup(self.jobid.type.split(':')[1], '/home/cyberpanel', 'dummy', 'dummy') == 0:
|
||||
raise BaseException
|
||||
|
||||
try:
|
||||
os.remove('/home/cyberpanel/%s' % (self.jobid.type.split(':')[1]))
|
||||
except:
|
||||
pass
|
||||
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath, "%s [46][5009]" % (str(msg)), 1)
|
||||
return 0
|
||||
|
||||
def restoreEmail(self):
|
||||
try:
|
||||
|
||||
if self.jobid.destination == 'local':
|
||||
repoLocation = '/home/%s/incbackup' % (self.website)
|
||||
command = 'restic -r %s restore %s --target / --password-file %s' % (repoLocation, self.jobid.snapshotid, self.passwordFile)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
elif self.jobid.destination[:4] == 'sftp':
|
||||
repoLocation = '/home/backup/%s' % (self.website)
|
||||
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s restore %s --target / --password-file %s' % (self.jobid.destination, repoLocation, self.jobid.snapshotid, self.passwordFile)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath, "%s [46][5009]" % (str(msg)), 1)
|
||||
return 0
|
||||
|
||||
def restorePoint(self):
|
||||
try:
|
||||
self.statusPath = self.extraArgs['tempPath']
|
||||
self.website = self.extraArgs['website']
|
||||
jobid = self.extraArgs['jobid']
|
||||
|
||||
self.jobid = JobSnapshots.objects.get(pk=jobid)
|
||||
|
||||
message = 'Starting restore of %s for %s.' % (self.jobid.snapshotid, self.website)
|
||||
logging.statusWriter(self.statusPath, message, 1)
|
||||
self.passwordFile = '/home/%s/%s' % (self.website, self.website)
|
||||
|
||||
|
||||
## Restore Meta first
|
||||
metaPathNew = '/home/%s/meta.xml' % (self.website)
|
||||
if self.jobid.destination == 'local':
|
||||
repoLocation = '/home/%s/incbackup' % (self.website)
|
||||
command = 'restic -r %s restore latest --target / --password-file %s --include %s' % (repoLocation, self.passwordFile, metaPathNew)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
elif self.jobid.destination[:4] == 'sftp':
|
||||
repoLocation = '/home/backup/%s' % (self.website)
|
||||
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s restore latest --target / --password-file %s --include %s' % (self.jobid.destination, repoLocation, self.passwordFile, metaPathNew)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
|
||||
## Reconstruct configs configs
|
||||
|
||||
if self.extraArgs['reconstruct']:
|
||||
execPath = "nice -n 10 /usr/local/CyberCP/bin/python2 " + virtualHostUtilities.cyberPanel + "/IncBackups/restoreMeta.py"
|
||||
execPath = execPath + " submitRestore --metaPath %s --statusFile %s" % (metaPathNew, self.statusPath)
|
||||
ProcessUtilities.outputExecutioner(execPath)
|
||||
|
||||
##
|
||||
|
||||
if self.jobid.type[:8] == 'database':
|
||||
message = 'Restoring database..'
|
||||
logging.statusWriter(self.statusPath, message, 1)
|
||||
self.restoreDatabase()
|
||||
message = 'Database restored.'
|
||||
logging.statusWriter(self.statusPath, message, 1)
|
||||
elif self.jobid.type[:4] == 'data':
|
||||
self.restoreData()
|
||||
elif self.jobid.type[:5] == 'email':
|
||||
message = 'Restoring email..'
|
||||
logging.statusWriter(self.statusPath, message, 1)
|
||||
self.restoreEmail()
|
||||
message = 'Emails restored.'
|
||||
logging.statusWriter(self.statusPath, message, 1)
|
||||
|
||||
logging.statusWriter(self.statusPath, 'Completed', 1)
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.extraArgs['tempPath'], str(msg), 1)
|
||||
|
||||
def prepareBackupMeta(self):
|
||||
try:
|
||||
|
||||
######### Generating meta
|
||||
|
||||
## XML Generation
|
||||
|
||||
metaFileXML = Element('metaFile')
|
||||
|
||||
child = SubElement(metaFileXML, 'masterDomain')
|
||||
child.text = self.website.domain
|
||||
|
||||
child = SubElement(metaFileXML, 'phpSelection')
|
||||
child.text = self.website.phpSelection
|
||||
|
||||
child = SubElement(metaFileXML, 'externalApp')
|
||||
child.text = self.website.externalApp
|
||||
|
||||
childDomains = self.website.childdomains_set.all()
|
||||
|
||||
databases = self.website.databases_set.all()
|
||||
|
||||
## Child domains XML
|
||||
|
||||
childDomainsXML = Element('ChildDomains')
|
||||
|
||||
for items in childDomains:
|
||||
childDomainXML = Element('domain')
|
||||
|
||||
child = SubElement(childDomainXML, 'domain')
|
||||
child.text = items.domain
|
||||
child = SubElement(childDomainXML, 'phpSelection')
|
||||
child.text = items.phpSelection
|
||||
child = SubElement(childDomainXML, 'path')
|
||||
child.text = items.path
|
||||
|
||||
childDomainsXML.append(childDomainXML)
|
||||
|
||||
metaFileXML.append(childDomainsXML)
|
||||
|
||||
## Databases XML
|
||||
|
||||
databasesXML = Element('Databases')
|
||||
|
||||
for items in databases:
|
||||
try:
|
||||
dbuser = DBUsers.objects.get(user=items.dbUser)
|
||||
userToTry = items.dbUser
|
||||
except:
|
||||
dbusers = DBUsers.objects.all().filter(user=items.dbUser)
|
||||
userToTry = items.dbUser
|
||||
for it in dbusers:
|
||||
dbuser = it
|
||||
break
|
||||
|
||||
userToTry = mysqlUtilities.mysqlUtilities.fetchuser(items.dbUser)
|
||||
|
||||
try:
|
||||
dbuser = DBUsers.objects.get(user=userToTry)
|
||||
except:
|
||||
dbusers = DBUsers.objects.all().filter(user=userToTry)
|
||||
for it in dbusers:
|
||||
dbuser = it
|
||||
break
|
||||
|
||||
databaseXML = Element('database')
|
||||
|
||||
child = SubElement(databaseXML, 'dbName')
|
||||
child.text = items.dbName
|
||||
child = SubElement(databaseXML, 'dbUser')
|
||||
child.text = userToTry
|
||||
child = SubElement(databaseXML, 'password')
|
||||
child.text = dbuser.password
|
||||
|
||||
databasesXML.append(databaseXML)
|
||||
|
||||
metaFileXML.append(databasesXML)
|
||||
|
||||
## Get Aliases
|
||||
|
||||
aliasesXML = Element('Aliases')
|
||||
|
||||
aliases = backupUtilities.getAliases(self.website.domain)
|
||||
|
||||
for items in aliases:
|
||||
child = SubElement(aliasesXML, 'alias')
|
||||
child.text = items
|
||||
|
||||
metaFileXML.append(aliasesXML)
|
||||
|
||||
## Finish Alias
|
||||
|
||||
## DNS Records XML
|
||||
|
||||
try:
|
||||
|
||||
dnsRecordsXML = Element("dnsrecords")
|
||||
dnsRecords = DNS.getDNSRecords(self.website.domain)
|
||||
|
||||
for items in dnsRecords:
|
||||
dnsRecordXML = Element('dnsrecord')
|
||||
|
||||
child = SubElement(dnsRecordXML, 'type')
|
||||
child.text = items.type
|
||||
child = SubElement(dnsRecordXML, 'name')
|
||||
child.text = items.name
|
||||
child = SubElement(dnsRecordXML, 'content')
|
||||
child.text = items.content
|
||||
child = SubElement(dnsRecordXML, 'priority')
|
||||
child.text = str(items.prio)
|
||||
|
||||
dnsRecordsXML.append(dnsRecordXML)
|
||||
|
||||
metaFileXML.append(dnsRecordsXML)
|
||||
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath, '%s. [158:prepMeta]' % (str(msg)), 1)
|
||||
|
||||
## Email accounts XML
|
||||
|
||||
try:
|
||||
emailRecordsXML = Element('emails')
|
||||
eDomain = eDomains.objects.get(domain=self.website.domain)
|
||||
emailAccounts = eDomain.eusers_set.all()
|
||||
|
||||
for items in emailAccounts:
|
||||
emailRecordXML = Element('emailAccount')
|
||||
|
||||
child = SubElement(emailRecordXML, 'email')
|
||||
child.text = items.email
|
||||
child = SubElement(emailRecordXML, 'password')
|
||||
child.text = items.password
|
||||
|
||||
emailRecordsXML.append(emailRecordXML)
|
||||
|
||||
metaFileXML.append(emailRecordsXML)
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath, '%s. [warning:179:prepMeta]' % (str(msg)), 1)
|
||||
|
||||
## Email meta generated!
|
||||
|
||||
def prettify(elem):
|
||||
"""Return a pretty-printed XML string for the Element.
|
||||
"""
|
||||
rough_string = ElementTree.tostring(elem, 'utf-8')
|
||||
reparsed = minidom.parseString(rough_string)
|
||||
return reparsed.toprettyxml(indent=" ")
|
||||
|
||||
## /home/example.com/backup/backup-example.com-02.13.2018_10-24-52/meta.xml -- metaPath
|
||||
|
||||
metaPath = '/home/cyberpanel/%s' % (str(randint(1000, 9999)))
|
||||
|
||||
xmlpretty = prettify(metaFileXML).encode('ascii', 'ignore')
|
||||
metaFile = open(metaPath, 'w')
|
||||
metaFile.write(xmlpretty)
|
||||
metaFile.close()
|
||||
os.chmod(metaPath, 0640)
|
||||
|
||||
## meta generated
|
||||
|
||||
logging.statusWriter(self.statusPath, 'Meta data is ready..', 1)
|
||||
|
||||
metaPathNew = '/home/%s/meta.xml' % (self.website.domain)
|
||||
command = 'mv %s %s' % (metaPath, metaPathNew)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
return 1
|
||||
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath, "%s [207][5009]" % (str(msg)), 1)
|
||||
return 0
|
||||
|
||||
def backupData(self):
|
||||
try:
|
||||
logging.statusWriter(self.statusPath, 'Backing up data..', 1)
|
||||
|
||||
if self.backupDestinations == 'local':
|
||||
backupPath = '/home/%s' % (self.website.domain)
|
||||
command = 'restic -r %s backup %s --password-file %s --exclude %s' % (self.repoPath, backupPath, self.passwordFile, self.repoPath)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
snapShotid = result.split(' ')[-2]
|
||||
|
||||
newSnapshot = JobSnapshots(job=self.jobid, type='data:%s' % (backupPath), snapshotid=snapShotid, destination=self.backupDestinations)
|
||||
newSnapshot.save()
|
||||
|
||||
elif self.backupDestinations[:4] == 'sftp':
|
||||
remotePath = '/home/backup/%s' % (self.website.domain)
|
||||
backupPath = '/home/%s' % (self.website.domain)
|
||||
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % (self.backupDestinations, remotePath, backupPath, self.passwordFile, self.repoPath)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
snapShotid = result.split(' ')[-2]
|
||||
newSnapshot = JobSnapshots(job=self.jobid, type='data:%s' % (remotePath), snapshotid=snapShotid,
|
||||
destination=self.backupDestinations)
|
||||
newSnapshot.save()
|
||||
|
||||
logging.statusWriter(self.statusPath, 'Data for %s backed to %s.' % (self.website.domain, self.backupDestinations), 1)
|
||||
return 1
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath,'%s. [IncJobs.backupData.223][5009]' % str(msg), 1)
|
||||
return 0
|
||||
|
||||
def backupDatabases(self):
|
||||
try:
|
||||
logging.statusWriter(self.statusPath, 'Backing up databases..', 1)
|
||||
|
||||
databases = self.website.databases_set.all()
|
||||
|
||||
for items in databases:
|
||||
if mysqlUtilities.mysqlUtilities.createDatabaseBackup(items.dbName, '/home/cyberpanel') == 0:
|
||||
return 0
|
||||
|
||||
dbPath = '/home/cyberpanel/%s.sql' % (items.dbName)
|
||||
|
||||
if self.backupDestinations == 'local':
|
||||
command = 'restic -r %s backup %s --password-file %s' % (self.repoPath, dbPath, self.passwordFile)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
snapShotid = result.split(' ')[-2]
|
||||
|
||||
newSnapshot = JobSnapshots(job=self.jobid, type='database:%s' % (items.dbName), snapshotid=snapShotid, destination=self.backupDestinations)
|
||||
newSnapshot.save()
|
||||
|
||||
elif self.backupDestinations[:4] == 'sftp':
|
||||
remotePath = '/home/backup/%s' % (self.website.domain)
|
||||
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % (
|
||||
self.backupDestinations, remotePath, dbPath, self.passwordFile, self.repoPath)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
snapShotid = result.split(' ')[-2]
|
||||
newSnapshot = JobSnapshots(job=self.jobid, type='database:%s' % (items.dbName), snapshotid=snapShotid,
|
||||
destination=self.backupDestinations)
|
||||
newSnapshot.save()
|
||||
|
||||
try:
|
||||
os.remove('/home/cyberpanel/%s' % (items.dbName))
|
||||
except:
|
||||
pass
|
||||
return 1
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath,'%s. [IncJobs.backupDatabases.269][5009]' % str(msg), 1)
|
||||
return 0
|
||||
|
||||
def emailBackup(self):
|
||||
try:
|
||||
logging.statusWriter(self.statusPath, 'Backing up emails..', 1)
|
||||
|
||||
backupPath = '/home/vmail/%s' % (self.website.domain)
|
||||
|
||||
if self.backupDestinations == 'local':
|
||||
command = 'restic -r %s backup %s --password-file %s' % (
|
||||
self.repoPath, backupPath, self.passwordFile)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
snapShotid = result.split(' ')[-2]
|
||||
|
||||
newSnapshot = JobSnapshots(job=self.jobid, type='email:%s' % (backupPath), snapshotid=snapShotid,
|
||||
destination=self.backupDestinations)
|
||||
newSnapshot.save()
|
||||
|
||||
elif self.backupDestinations[:4] == 'sftp':
|
||||
remotePath = '/home/backup/%s' % (self.website.domain)
|
||||
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % (
|
||||
self.backupDestinations, remotePath, backupPath, self.passwordFile, self.repoPath)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
snapShotid = result.split(' ')[-2]
|
||||
newSnapshot = JobSnapshots(job=self.jobid, type='email:%s' % (backupPath), snapshotid=snapShotid,
|
||||
destination=self.backupDestinations)
|
||||
newSnapshot.save()
|
||||
|
||||
|
||||
logging.statusWriter(self.statusPath, 'Emails for %s backed to %s.' % (self.website.domain, self.backupDestinations), 1)
|
||||
return 1
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath,'%s. [IncJobs.emailBackup.269][5009]' % str(msg), 1)
|
||||
return 0
|
||||
|
||||
def initiateRepo(self):
|
||||
try:
|
||||
logging.statusWriter(self.statusPath, 'Will first initiate backup repo..', 1)
|
||||
|
||||
if self.backupDestinations == 'local':
|
||||
command = 'restic init --repo %s --password-file %s' % (self.repoPath, self.passwordFile)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
|
||||
elif self.backupDestinations[:4] == 'sftp':
|
||||
remotePath = '/home/backup/%s' % (self.website.domain)
|
||||
command = 'export PATH=${PATH}:/usr/bin && restic init --repo %s:%s --password-file %s' % (self.backupDestinations, remotePath, self.passwordFile)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
else:
|
||||
logging.statusWriter(self.statusPath, 'AWS implementation is currently pending. [5009]', 1)
|
||||
return 0
|
||||
|
||||
logging.statusWriter(self.statusPath, 'Repo %s initiated for %s.' % (self.backupDestinations, self.website.domain), 1)
|
||||
return 1
|
||||
except BaseException, msg:
|
||||
logging.statusWriter(self.statusPath,'%s. [IncJobs.initiateRepo.47][5009]' % str(msg), 1)
|
||||
return 0
|
||||
|
||||
def createBackup(self):
|
||||
self.statusPath = self.extraArgs['tempPath']
|
||||
website = self.extraArgs['website']
|
||||
self.backupDestinations = self.extraArgs['backupDestinations']
|
||||
websiteData = self.extraArgs['websiteData']
|
||||
websiteEmails = self.extraArgs['websiteEmails']
|
||||
websiteSSLs = self.extraArgs['websiteSSLs']
|
||||
websiteDatabases = self.extraArgs['websiteDatabases']
|
||||
|
||||
self.website = Websites.objects.get(domain=website)
|
||||
|
||||
newJob = IncJob(website=self.website)
|
||||
newJob.save()
|
||||
|
||||
self.jobid = newJob
|
||||
|
||||
self.passwordFile = '/home/%s/%s' % (self.website.domain, self.website.domain)
|
||||
|
||||
self.repoPath = '/home/%s/incbackup' % (self.website.domain)
|
||||
|
||||
if not os.path.exists(self.passwordFile):
|
||||
password = randomPassword.generate_pass()
|
||||
command = 'echo "%s" > %s' % (password, self.passwordFile)
|
||||
ProcessUtilities.executioner(command, self.website.externalApp)
|
||||
|
||||
|
||||
if self.initiateRepo() == 0:
|
||||
return
|
||||
|
||||
if self.prepareBackupMeta() == 0:
|
||||
return
|
||||
|
||||
if websiteData:
|
||||
if self.backupData() == 0:
|
||||
return
|
||||
|
||||
if websiteDatabases:
|
||||
if self.backupDatabases() == 0:
|
||||
return
|
||||
|
||||
if websiteEmails:
|
||||
if self.emailBackup() == 0:
|
||||
return
|
||||
|
||||
## meta generated
|
||||
|
||||
logging.statusWriter(self.statusPath, 'Taking backup of meta file, this file can be used to reconstruct at later point..', 1)
|
||||
|
||||
metaPathNew = '/home/%s/meta.xml' % (self.website.domain)
|
||||
|
||||
if self.backupDestinations == 'local':
|
||||
command = 'restic -r %s backup %s --password-file %s' % (
|
||||
self.repoPath, metaPathNew, self.passwordFile)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
elif self.backupDestinations[:4] == 'sftp':
|
||||
remotePath = '/home/backup/%s' % (self.website.domain)
|
||||
command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % (
|
||||
self.backupDestinations, remotePath, metaPathNew, self.passwordFile, self.repoPath)
|
||||
result = ProcessUtilities.outputExecutioner(command)
|
||||
logging.statusWriter(self.statusPath, result, 1)
|
||||
|
||||
try:
|
||||
os.remove(metaPathNew)
|
||||
except:
|
||||
pass
|
||||
|
||||
logging.statusWriter(self.statusPath, 'Completed', 1)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class IncbackupsConfig(AppConfig):
|
||||
name = 'IncBackups'
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models
|
||||
from websiteFunctions.models import Websites
|
||||
from datetime import datetime
|
||||
|
||||
class IncJob(models.Model):
|
||||
website = models.ForeignKey(Websites)
|
||||
date = models.DateTimeField(default=datetime.now, blank=True)
|
||||
|
||||
class JobSnapshots(models.Model):
|
||||
job = models.ForeignKey(IncJob)
|
||||
type = models.CharField(max_length=300)
|
||||
snapshotid = models.CharField(max_length=50)
|
||||
destination = models.CharField(max_length=200, default='')
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
#!/usr/local/CyberCP/bin/python2
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
sys.path.append('/usr/local/CyberCP')
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
|
||||
|
||||
import django
|
||||
try:
|
||||
django.setup()
|
||||
except:
|
||||
pass
|
||||
from websiteFunctions.models import Websites
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
from xml.etree import ElementTree
|
||||
import plogical.mysqlUtilities as mysqlUtilities
|
||||
from databases.models import Databases
|
||||
import argparse
|
||||
try:
|
||||
from plogical.virtualHostUtilities import virtualHostUtilities
|
||||
from plogical.mailUtilities import mailUtilities
|
||||
except:
|
||||
pass
|
||||
|
||||
class restoreMeta():
|
||||
|
||||
@staticmethod
|
||||
def startRestore(metaPath, statusPath):
|
||||
try:
|
||||
|
||||
## extracting master domain for later use
|
||||
backupMetaData = ElementTree.parse(metaPath)
|
||||
masterDomain = backupMetaData.find('masterDomain').text
|
||||
|
||||
########### Creating child/sub/addon/parked domains
|
||||
|
||||
logging.statusWriter(statusPath, "Creating Child Domains!", 1)
|
||||
|
||||
### Restoring Child Domains if any.
|
||||
|
||||
childDomains = backupMetaData.findall('ChildDomains/domain')
|
||||
|
||||
try:
|
||||
for childDomain in childDomains:
|
||||
|
||||
domain = childDomain.find('domain').text
|
||||
phpSelection = childDomain.find('phpSelection').text
|
||||
path = childDomain.find('path').text
|
||||
|
||||
virtualHostUtilities.createDomain(masterDomain, domain, phpSelection, path, 0, 0, 0,
|
||||
'admin', 0)
|
||||
except BaseException, msg:
|
||||
logging.writeToFile(str(msg) + " [startRestore]")
|
||||
return 0
|
||||
|
||||
## Restore Aliases
|
||||
|
||||
logging.statusWriter(statusPath, "Restoring Domain Aliases!", 1)
|
||||
|
||||
aliases = backupMetaData.findall('Aliases/alias')
|
||||
|
||||
for items in aliases:
|
||||
virtualHostUtilities.createAlias(masterDomain, items.text, 0, "", "", "admin")
|
||||
|
||||
## Restoring email accounts
|
||||
|
||||
logging.statusWriter(statusPath, "Restoring email accounts!", 1)
|
||||
|
||||
emailAccounts = backupMetaData.findall('emails/emailAccount')
|
||||
|
||||
try:
|
||||
for emailAccount in emailAccounts:
|
||||
|
||||
email = emailAccount.find('email').text
|
||||
username = email.split("@")[0]
|
||||
password = emailAccount.find('password').text
|
||||
|
||||
result = mailUtilities.createEmailAccount(masterDomain, username, password)
|
||||
if result[0] == 0:
|
||||
logging.statusWriter(statusPath, 'Email existed, updating password according to last snapshot. %s' % (email))
|
||||
if mailUtilities.changeEmailPassword(email, password, 1)[0] == 0:
|
||||
logging.statusWriter(statusPath,
|
||||
'Failed changing password for: %s' % (
|
||||
email))
|
||||
else:
|
||||
logging.statusWriter(statusPath,
|
||||
'Password changed for: %s' % (
|
||||
email))
|
||||
|
||||
else:
|
||||
logging.statusWriter(statusPath,
|
||||
'Email created: %s' % (
|
||||
email))
|
||||
|
||||
except BaseException, msg:
|
||||
logging.writeToFile(str(msg) + " [startRestore]")
|
||||
return 0
|
||||
|
||||
## Emails restored
|
||||
|
||||
## restoring databases
|
||||
|
||||
logging.statusWriter(statusPath, "Restoring Databases!", 1)
|
||||
|
||||
## Create databases
|
||||
|
||||
databases = backupMetaData.findall('Databases/database')
|
||||
website = Websites.objects.get(domain=masterDomain)
|
||||
|
||||
for database in databases:
|
||||
dbName = database.find('dbName').text
|
||||
dbUser = database.find('dbUser').text
|
||||
dbPassword = database.find('password').text
|
||||
|
||||
try:
|
||||
dbExist = Databases.objects.get(dbName=dbName)
|
||||
logging.statusWriter(statusPath, 'Database exists, changing Database password.. %s' % (dbName))
|
||||
mysqlUtilities.mysqlUtilities.changePassword(dbUser, dbPassword, 1)
|
||||
if mysqlUtilities.mysqlUtilities.changePassword(dbUser, dbPassword, 1) == 0:
|
||||
logging.statusWriter(statusPath, 'Failed changing password for database: %s' % (dbName))
|
||||
else:
|
||||
logging.statusWriter(statusPath, 'Password successfully changed for database: %s.' % (dbName))
|
||||
except:
|
||||
logging.statusWriter(statusPath, 'Database did not exist, creating new.. %s' % (dbName))
|
||||
if mysqlUtilities.mysqlUtilities.createDatabase(dbName, dbUser, "cyberpanel") == 0:
|
||||
logging.statusWriter(statusPath, 'Failed the creation of database: %s' % (dbName))
|
||||
else:
|
||||
logging.statusWriter(statusPath, 'Database: %s successfully created.' % (dbName))
|
||||
|
||||
|
||||
try:
|
||||
newDB = Databases(website=website, dbName=dbName, dbUser=dbUser)
|
||||
newDB.save()
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
## Databases restored
|
||||
|
||||
try:
|
||||
os.remove(metaPath)
|
||||
except:
|
||||
pass
|
||||
|
||||
except BaseException, msg:
|
||||
logging.writeToFile(str(msg) + " [startRestore]")
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser(description='CyberPanel Installer')
|
||||
parser.add_argument('function', help='Specific a function to call!')
|
||||
parser.add_argument('--metaPath', help='')
|
||||
parser.add_argument('--statusFile', help='!')
|
||||
|
||||
## backup restore arguments
|
||||
|
||||
parser.add_argument('--backupFile', help='')
|
||||
parser.add_argument('--dir', help='')
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.function == "submitRestore":
|
||||
restoreMeta.startRestore(args.metaPath,args.statusFile)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,494 @@
|
|||
//*** Backup site ****//
|
||||
|
||||
app.controller('createIncrementalBackups', function ($scope, $http, $timeout) {
|
||||
|
||||
$scope.destination = true;
|
||||
$scope.backupButton = true;
|
||||
$scope.cyberpanelLoading = true;
|
||||
$scope.runningBackup = true;
|
||||
$scope.restoreSt = true;
|
||||
|
||||
|
||||
$scope.fetchDetails = function () {
|
||||
getBackupStatus();
|
||||
$scope.populateCurrentRecords();
|
||||
$scope.destination = false;
|
||||
$scope.runningBackup = true;
|
||||
};
|
||||
|
||||
function getBackupStatus() {
|
||||
|
||||
$scope.cyberpanelLoadingBottom = false;
|
||||
|
||||
url = "/IncrementalBackups/getBackupStatus";
|
||||
|
||||
var data = {
|
||||
websiteToBeBacked: $scope.websiteToBeBacked,
|
||||
tempPath: $scope.tempPath
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
|
||||
|
||||
if (response.data.backupStatus === 1) {
|
||||
|
||||
if (response.data.abort === 1) {
|
||||
$timeout.cancel();
|
||||
$scope.cyberpanelLoadingBottom = true;
|
||||
$scope.destination = false;
|
||||
$scope.runningBackup = false;
|
||||
$scope.backupButton = false;
|
||||
$scope.cyberpanelLoading = true;
|
||||
$scope.fileName = response.data.fileName;
|
||||
$scope.status = response.data.status;
|
||||
$scope.populateCurrentRecords();
|
||||
return;
|
||||
} else {
|
||||
$scope.destination = true;
|
||||
$scope.backupButton = true;
|
||||
$scope.runningBackup = false;
|
||||
|
||||
$scope.fileName = response.data.fileName;
|
||||
$scope.status = response.data.status;
|
||||
$timeout(getBackupStatus, 2000);
|
||||
|
||||
}
|
||||
} else {
|
||||
$timeout.cancel();
|
||||
$scope.cyberpanelLoadingBottom = true;
|
||||
$scope.cyberpanelLoading = true;
|
||||
$scope.backupButton = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$scope.destinationSelection = function () {
|
||||
$scope.backupButton = false;
|
||||
};
|
||||
|
||||
$scope.populateCurrentRecords = function () {
|
||||
|
||||
url = "/IncrementalBackups/fetchCurrentBackups";
|
||||
|
||||
var data = {
|
||||
websiteToBeBacked: $scope.websiteToBeBacked,
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
if (response.data.status === 1) {
|
||||
$scope.records = JSON.parse(response.data.data);
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.createBackup = function () {
|
||||
|
||||
$scope.status = '';
|
||||
|
||||
$scope.cyberpanelLoading = false;
|
||||
|
||||
|
||||
url = "/IncrementalBackups/submitBackupCreation";
|
||||
|
||||
var data = {
|
||||
websiteToBeBacked: $scope.websiteToBeBacked,
|
||||
backupDestinations: $scope.backupDestinations,
|
||||
websiteData: $scope.websiteData,
|
||||
websiteEmails: $scope.websiteEmails,
|
||||
websiteSSLs: $scope.websiteSSLs,
|
||||
websiteDatabases: $scope.websiteDatabases
|
||||
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
|
||||
if (response.data.status === 1) {
|
||||
$scope.tempPath = response.data.tempPath;
|
||||
getBackupStatus();
|
||||
}else{
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.deleteBackup = function (id) {
|
||||
|
||||
|
||||
url = "/IncrementalBackups/deleteBackup";
|
||||
|
||||
var data = {
|
||||
backupID: id,
|
||||
websiteToBeBacked: $scope.websiteToBeBacked
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
|
||||
|
||||
if (response.data.status === 1) {
|
||||
|
||||
$scope.populateCurrentRecords();
|
||||
|
||||
}else{
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
$scope.restore = function (id) {
|
||||
|
||||
$scope.cyberpanelLoading = false;
|
||||
|
||||
|
||||
url = "/IncrementalBackups/fetchRestorePoints";
|
||||
|
||||
var data = {
|
||||
id: id,
|
||||
websiteToBeBacked: $scope.websiteToBeBacked
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
$scope.jobs = JSON.parse(response.data.data);
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.restorePoint = function (id, reconstruct) {
|
||||
|
||||
$scope.status = '';
|
||||
|
||||
$scope.cyberpanelLoading = false;
|
||||
$scope.restoreSt = false;
|
||||
|
||||
|
||||
url = "/IncrementalBackups/restorePoint";
|
||||
|
||||
var data = {
|
||||
websiteToBeBacked: $scope.websiteToBeBacked,
|
||||
jobid : id,
|
||||
reconstruct: reconstruct
|
||||
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
|
||||
if (response.data.status === 1) {
|
||||
$scope.tempPath = response.data.tempPath;
|
||||
getBackupStatus();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
});
|
||||
|
||||
///** Backup site ends **///
|
||||
|
||||
|
||||
app.controller('incrementalDestinations', function ($scope, $http) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
$scope.sftpHide = true;
|
||||
$scope.awsHide = true;
|
||||
|
||||
$scope.fetchDetails = function () {
|
||||
|
||||
if ($scope.destinationType === 'SFTP') {
|
||||
$scope.sftpHide = false;
|
||||
$scope.populateCurrentRecords();
|
||||
} else {
|
||||
$scope.sftpHide = true;
|
||||
$scope.awsHide = false;
|
||||
$scope.populateCurrentRecords();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.populateCurrentRecords = function () {
|
||||
|
||||
$scope.cyberpanelLoading = false;
|
||||
|
||||
|
||||
url = "/IncrementalBackups/populateCurrentRecords";
|
||||
|
||||
var type = 'SFTP';
|
||||
if ($scope.destinationType === 'SFTP') {
|
||||
type = 'SFTP';
|
||||
} else {
|
||||
type = 'AWS';
|
||||
}
|
||||
|
||||
var data = {
|
||||
type: type
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
$scope.records = JSON.parse(response.data.data);
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.addDestination = function (type) {
|
||||
$scope.cyberpanelLoading = false;
|
||||
|
||||
|
||||
url = "/IncrementalBackups/addDestination";
|
||||
|
||||
if (type === 'SFTP') {
|
||||
var data = {
|
||||
type: type,
|
||||
IPAddress: $scope.IPAddress,
|
||||
password: $scope.password,
|
||||
backupSSHPort: $scope.backupSSHPort
|
||||
};
|
||||
} else {
|
||||
var data = {
|
||||
type: type,
|
||||
AWS_ACCESS_KEY_ID: $scope.AWS_ACCESS_KEY_ID,
|
||||
AWS_SECRET_ACCESS_KEY: $scope.AWS_SECRET_ACCESS_KEY,
|
||||
};
|
||||
}
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
$scope.populateCurrentRecords();
|
||||
if (response.data.status === 1) {
|
||||
new PNotify({
|
||||
title: 'Success!',
|
||||
text: 'Destination successfully added.',
|
||||
type: 'success'
|
||||
});
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.removeDestination = function (type, ipAddress) {
|
||||
$scope.cyberpanelLoading = false;
|
||||
|
||||
|
||||
url = "/IncrementalBackups/removeDestination";
|
||||
|
||||
var data = {
|
||||
type: type,
|
||||
IPAddress: ipAddress,
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
$scope.populateCurrentRecords();
|
||||
if (response.data.status === 1) {
|
||||
new PNotify({
|
||||
title: 'Success!',
|
||||
text: 'Destination successfully removed.',
|
||||
type: 'success'
|
||||
});
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
new PNotify({
|
||||
title: 'Operation Failed!',
|
||||
text: 'Could not connect to server, please refresh this page',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Create Incremental Backup" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Back up Website" %} - <a target="_blank" href="http://go.cyberpanel.net/backup"
|
||||
style="height: 23px;line-height: 21px;"
|
||||
class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>{% trans "Backup Docs" %}</span></a>
|
||||
</h2>
|
||||
<p>{% trans "This page can be used to create incremental backups for your websites." %}</p>
|
||||
</div>
|
||||
|
||||
<div ng-controller="createIncrementalBackups" class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Back up Website" %} <img ng-hide="cyberpanelLoading"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
</h3>
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
|
||||
<form action="/" class="form-horizontal bordered-row">
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Select Website" %} </label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="fetchDetails()" ng-model="websiteToBeBacked" class="form-control">
|
||||
{% for items in websiteList %}
|
||||
<option>{{ items }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="destination" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Destination" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="destinationSelection()" ng-model="backupDestinations"
|
||||
class="form-control">
|
||||
{% for items in destinations %}
|
||||
<option>{{ items }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="destination" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Backup Content" %}</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input ng-model="websiteData" type="checkbox" value="">
|
||||
Data
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-9">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input ng-model="websiteDatabases" type="checkbox" value="">
|
||||
Databases
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-9">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input ng-model="websiteEmails" type="checkbox" value="">
|
||||
Emails
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<!---
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-9">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input ng-model="websiteSSLs" type="checkbox" value="">
|
||||
SSL Certificates
|
||||
</label>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
|
||||
<!---- if Back up is running ----->
|
||||
|
||||
<div ng-hide="runningBackup" class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<div class="col-sm-12">
|
||||
<textarea ng-model="status" class="form-control" rows="10"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!---- if Back up is running------>
|
||||
|
||||
<div ng-hide="backupButton" class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-click="createBackup()"
|
||||
class="btn btn-primary btn-lg btn-block">{% trans "Create Back up" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!------ List of records --------------->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<div class="col-sm-12">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "ID" %}</th>
|
||||
<th>{% trans "Date" %}</th>
|
||||
<th>{% trans "Restore" %}</th>
|
||||
<th>{% trans "Delete" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="record in records track by $index">
|
||||
<td ng-bind="record.id"></td>
|
||||
<td ng-bind="record.date"></td>
|
||||
<td>
|
||||
<a ng-click="restore(record.id)" data-toggle="modal" data-target="#settings"
|
||||
ng-click='deleteCLPackage()'
|
||||
class="btn btn-border btn-alt border-green btn-link font-green"
|
||||
title=""><span>Restore Points</span></a>
|
||||
<div id="settings" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog modal-lg">
|
||||
|
||||
<!-- Modal content-->
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">
|
||||
×
|
||||
</button>
|
||||
<h4 class="modal-title">Restore Points
|
||||
<img ng-hide="cyberpanelLoading"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Job ID" %}</th>
|
||||
<th>{% trans "Snapshot ID" %}</th>
|
||||
<th>{% trans "Type" %}</th>
|
||||
<th>{% trans "Destination" %}</th>
|
||||
<th>{% trans "Action" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="job in jobs track by $index">
|
||||
<td ng-bind="job.id"></td>
|
||||
<td ng-bind="job.snapshotid"></td>
|
||||
<td ng-bind="job.type"></td>
|
||||
<td ng-bind="job.destination"></td>
|
||||
<td>
|
||||
<a ng-click="restorePoint(job.id, 0)" class="btn btn-border btn-alt border-green btn-link font-green"
|
||||
title=""><span>Restore</span></a>
|
||||
<a ng-click="restorePoint(job.id, 1)" class="btn btn-border btn-alt border-green btn-link font-green"
|
||||
title=""><span>Restore and Reconstruct</span></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div ng-hide="restoreSt" class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<div class="col-sm-12">
|
||||
<textarea ng-model="status"
|
||||
class="form-control"
|
||||
rows="7"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" ng-disabled="savingSettings"
|
||||
class="btn btn-default" data-dismiss="modal">
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<a href="">
|
||||
<td ng-click="deleteBackup(record.id)"><img
|
||||
src="{% static 'images/delete.png' %}"></td>
|
||||
</a>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!------ List of records --------------->
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Set up Back up Destinations" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Set up Incremental Back up Destinations" %} - <a target="_blank"
|
||||
href="http://go.cyberpanel.net/remote-backup"
|
||||
style="height: 23px;line-height: 21px;"
|
||||
class="btn btn-border btn-alt border-red btn-link font-red"
|
||||
title=""><span>{% trans "Remote Backups" %}</span></a>
|
||||
</h2>
|
||||
<p>{% trans "On this page you can set up your Back up destinations. (SFTP and AWS)" %}</p>
|
||||
</div>
|
||||
|
||||
<div ng-controller="incrementalDestinations" class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Set up Back up Destinations." %} <img ng-hide="cyberpanelLoading"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
</h3>
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
|
||||
<form action="/" class="form-horizontal bordered-row">
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Select Type" %} </label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="fetchDetails()" ng-model="destinationType" class="form-control">
|
||||
<option>SFTP</option>
|
||||
<option>AWS</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--- SFTP --->
|
||||
|
||||
<div ng-hide="sftpHide" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "IP Address" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="IPAddress" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="sftpHide" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Password" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input placeholder="" type="password" class="form-control" ng-model="password" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="sftpHide" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Port" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input placeholder="{% trans "Backup server SSH Port, leave empty for 22." %}"
|
||||
type="text" class="form-control" ng-model="backupSSHPort" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="sftpHide" class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-click="addDestination('SFTP')"
|
||||
class="btn btn-primary btn-lg btn-block">{% trans "Add Destination" %}</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--- SFTP --->
|
||||
|
||||
|
||||
|
||||
|
||||
<!------ List of Destinations --------------->
|
||||
|
||||
<div ng-hide="sftpHide" class="form-group">
|
||||
|
||||
<div class="col-sm-12">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "IP" %}</th>
|
||||
<th>{% trans "Port" %}</th>
|
||||
<th>{% trans "Delete" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="record in records track by $index">
|
||||
<td ng-bind="record.ip"></td>
|
||||
<td ng-bind="record.port"></td>
|
||||
<td ng-click="removeDestination('SFTP',record.ip)"><img src="{% static 'images/delete.png' %}">
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!------ List of records --------------->
|
||||
|
||||
|
||||
<!--- SFTP End --->
|
||||
|
||||
<!--- AWS Start --->
|
||||
|
||||
<div ng-hide="awsHide" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "AWS_ACCESS_KEY_ID" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="AWS_ACCESS_KEY_ID" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="awsHide" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "AWS_SECRET_ACCESS_KEY" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input placeholder="" type="password" class="form-control" ng-model="AWS_SECRET_ACCESS_KEY" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="awsHide" class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-click="addDestination('AWS')"
|
||||
class="btn btn-primary btn-lg btn-block">{% trans "Add Destination" %}</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--- SFTP --->
|
||||
|
||||
|
||||
|
||||
|
||||
<!------ List of Destinations --------------->
|
||||
|
||||
<div ng-hide="awsHide" class="form-group">
|
||||
|
||||
<div class="col-sm-12">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "AWS_ACCESS_KEY_ID" %}</th>
|
||||
<th>{% trans "Delete" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="record in records track by $index">
|
||||
<td ng-bind="record.AWS_ACCESS_KEY_ID"></td>
|
||||
<td ng-click="removeDestination('AWS', record.AWS_ACCESS_KEY_ID)"><img src="{% static 'images/delete.png' %}">
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!------ List of records --------------->
|
||||
|
||||
|
||||
<!--- AWS End --->
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
from django.conf.urls import url
|
||||
import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^createBackup$', views.createBackup, name='createBackupInc'),
|
||||
url(r'^backupDestinations$', views.backupDestinations, name='backupDestinationsInc'),
|
||||
url(r'^addDestination$', views.addDestination, name='addDestinationInc'),
|
||||
url(r'^populateCurrentRecords$', views.populateCurrentRecords, name='populateCurrentRecordsInc'),
|
||||
url(r'^removeDestination$', views.removeDestination, name='removeDestinationInc'),
|
||||
url(r'^fetchCurrentBackups$', views.fetchCurrentBackups, name='fetchCurrentBackupsInc'),
|
||||
url(r'^submitBackupCreation$', views.submitBackupCreation, name='submitBackupCreationInc'),
|
||||
url(r'^getBackupStatus$', views.getBackupStatus, name='getBackupStatusInc'),
|
||||
url(r'^deleteBackup$', views.deleteBackup, name='deleteBackupInc'),
|
||||
url(r'^fetchRestorePoints$', views.fetchRestorePoints, name='fetchRestorePointsInc'),
|
||||
url(r'^restorePoint$', views.restorePoint, name='restorePointInc'),
|
||||
]
|
||||
|
|
@ -0,0 +1,543 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.shortcuts import render
|
||||
from plogical.acl import ACLManager
|
||||
from django.shortcuts import HttpResponse
|
||||
from plogical.processUtilities import ProcessUtilities
|
||||
from plogical.virtualHostUtilities import virtualHostUtilities
|
||||
import json
|
||||
import os
|
||||
from loginSystem.models import Administrator
|
||||
from websiteFunctions.models import Websites
|
||||
from .models import IncJob, JobSnapshots
|
||||
from .IncBackupsControl import IncJobs
|
||||
from random import randint
|
||||
import time
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
# Create your views here.
|
||||
|
||||
|
||||
def defRenderer(request, templateName, args):
|
||||
return render(request, templateName, args)
|
||||
|
||||
def createBackup(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if ACLManager.currentContextPermission(currentACL, 'createBackup') == 0:
|
||||
return ACLManager.loadError()
|
||||
|
||||
websitesName = ACLManager.findAllSites(currentACL, userID)
|
||||
|
||||
destinations = []
|
||||
destinations.append('local')
|
||||
|
||||
path = '/home/cyberpanel/sftp'
|
||||
|
||||
for items in os.listdir(path):
|
||||
destinations.append('sftp:%s' % (items))
|
||||
|
||||
for items in os.listdir(path):
|
||||
destinations.append('s3:s3.amazonaws.com/%s' % (items))
|
||||
|
||||
return defRenderer(request, 'IncBackups/createBackup.html', {'websiteList': websitesName, 'destinations': destinations})
|
||||
except BaseException, msg:
|
||||
return HttpResponse(str(msg))
|
||||
|
||||
def backupDestinations(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
|
||||
return ACLManager.loadError()
|
||||
|
||||
return defRenderer(request, 'IncBackups/incrementalDestinations.html', {})
|
||||
except BaseException, msg:
|
||||
return HttpResponse(str(msg))
|
||||
|
||||
def addDestination(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
|
||||
return ACLManager.loadErrorJson('destStatus', 0)
|
||||
|
||||
data = json.loads(request.body)
|
||||
|
||||
if data['type'] == 'SFTP':
|
||||
|
||||
ipAddress = data['IPAddress']
|
||||
password = data['password']
|
||||
|
||||
ipFile = '/home/cyberpanel/sftp/%s' % (ipAddress)
|
||||
|
||||
try:
|
||||
port = data['backupSSHPort']
|
||||
except:
|
||||
port = "22"
|
||||
|
||||
if os.path.exists(ipFile):
|
||||
final_dic = {'status': 0, 'error_message': 'This destination already exists.'}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
|
||||
try:
|
||||
os.mkdir('/home/cyberpanel/sftp')
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
execPath = "/usr/local/CyberCP/bin/python2 " + virtualHostUtilities.cyberPanel + "/plogical/backupUtilities.py"
|
||||
execPath = execPath + " submitDestinationCreation --ipAddress " + ipAddress + " --password " \
|
||||
+ password + " --port " + port
|
||||
|
||||
output = ProcessUtilities.outputExecutioner(execPath)
|
||||
|
||||
if output.find('1,') > -1:
|
||||
|
||||
content = '%s\n%s' % (ipAddress, port)
|
||||
writeToFile = open(ipFile, 'w')
|
||||
writeToFile.write(content)
|
||||
writeToFile.close()
|
||||
|
||||
command = 'cat /root/.ssh/config'
|
||||
currentConfig = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
tmpFile = '/home/cyberpanel/sshconfig'
|
||||
|
||||
writeToFile = open(tmpFile, 'w')
|
||||
writeToFile.write(currentConfig)
|
||||
|
||||
content = """Host %s
|
||||
IdentityFile ~/.ssh/cyberpanel
|
||||
Port %s
|
||||
""" % (ipAddress, port)
|
||||
writeToFile.write(content)
|
||||
writeToFile.close()
|
||||
|
||||
|
||||
command = 'mv %s /root/.ssh/config' % (tmpFile)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
command = 'chown root:root /root/.ssh/config'
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
final_dic = {'status': 1, 'error_message': 'None'}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
|
||||
else:
|
||||
final_dic = {'status': 0, 'error_message': output}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
else:
|
||||
aws = '/home/cyberpanel/aws'
|
||||
|
||||
try:
|
||||
os.mkdir(aws)
|
||||
except:
|
||||
pass
|
||||
|
||||
AWS_ACCESS_KEY_ID = data['AWS_ACCESS_KEY_ID']
|
||||
AWS_SECRET_ACCESS_KEY = data['AWS_SECRET_ACCESS_KEY']
|
||||
|
||||
awsFile = '/home/cyberpanel/aws/%s' % (AWS_ACCESS_KEY_ID)
|
||||
|
||||
writeToFile = open(awsFile, 'w')
|
||||
writeToFile.write(AWS_SECRET_ACCESS_KEY)
|
||||
writeToFile.close()
|
||||
|
||||
final_dic = {'status': 1}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
except BaseException, msg:
|
||||
final_dic = {'status': 0, 'error_message': str(msg)}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
def populateCurrentRecords(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
|
||||
return ACLManager.loadErrorJson('fetchStatus', 0)
|
||||
|
||||
data = json.loads(request.body)
|
||||
|
||||
if data['type'] == 'SFTP':
|
||||
|
||||
path = '/home/cyberpanel/sftp'
|
||||
|
||||
if os.path.exists(path):
|
||||
|
||||
json_data = "["
|
||||
checker = 0
|
||||
|
||||
for items in os.listdir(path):
|
||||
fullPath = '/home/cyberpanel/sftp/%s' % (items)
|
||||
|
||||
data = open(fullPath, 'r').readlines()
|
||||
dic = {
|
||||
'ip': data[0].strip('\n'),
|
||||
'port': data[1],
|
||||
}
|
||||
|
||||
if checker == 0:
|
||||
json_data = json_data + json.dumps(dic)
|
||||
checker = 1
|
||||
else:
|
||||
json_data = json_data + ',' + json.dumps(dic)
|
||||
else:
|
||||
final_json = json.dumps({'status': 1, 'error_message': "None", "data": ''})
|
||||
return HttpResponse(final_json)
|
||||
else:
|
||||
path = '/home/cyberpanel/aws'
|
||||
|
||||
if os.path.exists(path):
|
||||
|
||||
json_data = "["
|
||||
checker = 0
|
||||
|
||||
for items in os.listdir(path):
|
||||
dic = {
|
||||
'AWS_ACCESS_KEY_ID': items
|
||||
}
|
||||
|
||||
if checker == 0:
|
||||
json_data = json_data + json.dumps(dic)
|
||||
checker = 1
|
||||
else:
|
||||
json_data = json_data + ',' + json.dumps(dic)
|
||||
else:
|
||||
final_json = json.dumps({'status': 1, 'error_message': "None", "data": ''})
|
||||
return HttpResponse(final_json)
|
||||
|
||||
json_data = json_data + ']'
|
||||
final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data})
|
||||
return HttpResponse(final_json)
|
||||
|
||||
except BaseException, msg:
|
||||
final_dic = {'status': 0, 'error_message': str(msg)}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
def removeDestination(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
|
||||
return ACLManager.loadErrorJson('destStatus', 0)
|
||||
|
||||
data = json.loads(request.body)
|
||||
|
||||
ipAddress = data['IPAddress']
|
||||
|
||||
if data['type'] == 'SFTP':
|
||||
ipFile = '/home/cyberpanel/sftp/%s' % (ipAddress)
|
||||
else:
|
||||
ipFile = '/home/cyberpanel/aws/%s' % (ipAddress)
|
||||
|
||||
|
||||
os.remove(ipFile)
|
||||
|
||||
final_dic = {'status': 1, 'error_message': 'None'}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
except BaseException, msg:
|
||||
final_dic = {'destStatus': 0, 'error_message': str(msg)}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
def fetchCurrentBackups(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
|
||||
data = json.loads(request.body)
|
||||
backupDomain = data['websiteToBeBacked']
|
||||
|
||||
if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson('fetchStatus', 0)
|
||||
|
||||
if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson()
|
||||
|
||||
website = Websites.objects.get(domain=backupDomain)
|
||||
|
||||
backups = website.incjob_set.all()
|
||||
|
||||
json_data = "["
|
||||
checker = 0
|
||||
|
||||
for items in reversed(backups):
|
||||
|
||||
includes = ""
|
||||
|
||||
jobs = items.jobsnapshots_set.all()
|
||||
|
||||
for job in jobs:
|
||||
includes = '%s,%s:%s' % (includes, job.type, job.snapshotid)
|
||||
|
||||
dic = {'id': items.id,
|
||||
'date': str(items.date),
|
||||
'includes': includes
|
||||
}
|
||||
|
||||
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, msg:
|
||||
final_dic = {'status': 0, 'error_message': str(msg)}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
def submitBackupCreation(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
|
||||
data = json.loads(request.body)
|
||||
backupDomain = data['websiteToBeBacked']
|
||||
backupDestinations = data['backupDestinations']
|
||||
|
||||
if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson('metaStatus', 0)
|
||||
|
||||
tempPath = "/home/cyberpanel/" + str(randint(1000, 9999))
|
||||
|
||||
try:
|
||||
websiteData = data['websiteData']
|
||||
except:
|
||||
websiteData = False
|
||||
|
||||
try:
|
||||
websiteEmails = data['websiteEmails']
|
||||
except:
|
||||
websiteEmails = False
|
||||
|
||||
try:
|
||||
websiteSSLs = data['websiteSSLs']
|
||||
except:
|
||||
websiteSSLs = False
|
||||
|
||||
|
||||
try:
|
||||
websiteDatabases = data['websiteDatabases']
|
||||
except:
|
||||
websiteDatabases = False
|
||||
|
||||
extraArgs = {}
|
||||
extraArgs['website'] = backupDomain
|
||||
extraArgs['tempPath'] = tempPath
|
||||
extraArgs['backupDestinations'] = backupDestinations
|
||||
extraArgs['websiteData'] = websiteData
|
||||
extraArgs['websiteEmails'] = websiteEmails
|
||||
extraArgs['websiteSSLs'] = websiteSSLs
|
||||
extraArgs['websiteDatabases'] = websiteDatabases
|
||||
|
||||
startJob = IncJobs('createBackup', extraArgs)
|
||||
startJob.start()
|
||||
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
final_json = json.dumps({'status': 1, 'error_message': "None", 'tempPath': tempPath})
|
||||
return HttpResponse(final_json)
|
||||
|
||||
except BaseException, msg:
|
||||
logging.writeToFile(str(msg))
|
||||
final_dic = {'status': 0, 'metaStatus': 0, 'error_message': str(msg)}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
def getBackupStatus(request):
|
||||
try:
|
||||
data = json.loads(request.body)
|
||||
|
||||
status = data['tempPath']
|
||||
backupDomain = data['websiteToBeBacked']
|
||||
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
|
||||
if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson('fetchStatus', 0)
|
||||
|
||||
## file name read ends
|
||||
|
||||
if os.path.exists(status):
|
||||
command = "sudo cat " + status
|
||||
result = ProcessUtilities.outputExecutioner(command, 'cyberpanel')
|
||||
|
||||
if result.find("Completed") > -1:
|
||||
|
||||
### Removing Files
|
||||
|
||||
os.remove(status)
|
||||
|
||||
final_json = json.dumps(
|
||||
{'backupStatus': 1, 'error_message': "None", "status": result, "abort": 1})
|
||||
return HttpResponse(final_json)
|
||||
|
||||
elif result.find("[5009]") > -1:
|
||||
## removing status file, so that backup can re-run
|
||||
try:
|
||||
os.remove(status)
|
||||
except:
|
||||
pass
|
||||
|
||||
final_json = json.dumps(
|
||||
{'backupStatus': 1, 'error_message': "None", "status": result,
|
||||
"abort": 1})
|
||||
return HttpResponse(final_json)
|
||||
else:
|
||||
final_json = json.dumps(
|
||||
{'backupStatus': 1, 'error_message': "None", "status": result,
|
||||
"abort": 0})
|
||||
return HttpResponse(final_json)
|
||||
else:
|
||||
final_json = json.dumps({'backupStatus': 1, 'error_message': "None", "status": 1, "abort": 0})
|
||||
return HttpResponse(final_json)
|
||||
|
||||
except BaseException, msg:
|
||||
final_dic = {'backupStatus': 0, 'error_message': str(msg)}
|
||||
final_json = json.dumps(final_dic)
|
||||
logging.writeToFile(str(msg) + " [backupStatus]")
|
||||
return HttpResponse(final_json)
|
||||
|
||||
def deleteBackup(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
data = json.loads(request.body)
|
||||
backupDomain = data['websiteToBeBacked']
|
||||
|
||||
if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson('fetchStatus', 0)
|
||||
|
||||
id = data['backupID']
|
||||
|
||||
IncJob.objects.get(id=id).delete()
|
||||
|
||||
final_dic = {'status': 1, 'error_message': 'None'}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
except BaseException, msg:
|
||||
final_dic = {'destStatus': 0, 'error_message': str(msg)}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
def fetchRestorePoints(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
data = json.loads(request.body)
|
||||
backupDomain = data['websiteToBeBacked']
|
||||
|
||||
if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson('fetchStatus', 0)
|
||||
|
||||
data = json.loads(request.body)
|
||||
id = data['id']
|
||||
|
||||
incJob = IncJob.objects.get(id=id)
|
||||
|
||||
backups = incJob.jobsnapshots_set.all()
|
||||
|
||||
json_data = "["
|
||||
checker = 0
|
||||
|
||||
for items in backups:
|
||||
|
||||
dic = {'id': items.id,
|
||||
'snapshotid': items.snapshotid,
|
||||
'type': items.type,
|
||||
'destination': items.destination,
|
||||
}
|
||||
|
||||
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, msg:
|
||||
final_dic = {'status': 0, 'error_message': str(msg)}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
def restorePoint(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
|
||||
data = json.loads(request.body)
|
||||
backupDomain = data['websiteToBeBacked']
|
||||
jobid = data['jobid']
|
||||
|
||||
if ACLManager.checkOwnership(backupDomain, admin, currentACL) == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson('metaStatus', 0)
|
||||
|
||||
tempPath = "/home/cyberpanel/" + str(randint(1000, 9999))
|
||||
|
||||
extraArgs = {}
|
||||
extraArgs['website'] = backupDomain
|
||||
extraArgs['jobid'] = jobid
|
||||
extraArgs['tempPath'] = tempPath
|
||||
extraArgs['reconstruct'] = data['reconstruct']
|
||||
|
||||
|
||||
startJob = IncJobs('restorePoint', extraArgs)
|
||||
startJob.start()
|
||||
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
final_json = json.dumps({'status': 1, 'error_message': "None", 'tempPath': tempPath})
|
||||
return HttpResponse(final_json)
|
||||
|
||||
except BaseException, msg:
|
||||
logging.writeToFile(str(msg))
|
||||
final_dic = {'status': 0, 'metaStatus': 0, 'error_message': str(msg)}
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
|
@ -23,17 +23,13 @@ Webhosting control panel that uses OpenLiteSpeed as web server.
|
|||
* PHP 5.6
|
||||
* PHP 7.0
|
||||
* PHP 7.1
|
||||
|
||||
* PHP 7.2
|
||||
|
||||
# Installation Instructions
|
||||
|
||||
|
||||
```
|
||||
wget http://cyberpanel.net/install.tar.gz
|
||||
tar zxf install.tar.gz
|
||||
cd install
|
||||
chmod +x install.py
|
||||
python install.py [IP Address]
|
||||
sh <(curl https://cyberpanel.net/install.sh || wget -O - https://cyberpanel.net/install.sh)
|
||||
```
|
||||
|
||||
# Resources
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ urlpatterns = [
|
|||
|
||||
url(r'^loginAPI', views.loginAPI, name='loginAPI'),
|
||||
|
||||
url(r'^getUserInfo$', views.getUserInfo, name='getUserInfo'),
|
||||
url(r'^changeUserPassAPI', views.changeUserPassAPI, name='changeUserPassAPI'),
|
||||
|
||||
url(r'^changePackageAPI', views.changePackageAPI, name='changePackageAPI'),
|
||||
url(r'^fetchSSHkey', views.fetchSSHkey, name='fetchSSHkey'),
|
||||
url(r'^remoteTransfer', views.remoteTransfer, name='remoteTransfer'),
|
||||
|
|
@ -19,11 +21,7 @@ urlpatterns = [
|
|||
|
||||
url(r'^cancelRemoteTransfer', views.cancelRemoteTransfer, name='cancelRemoteTransfer'),
|
||||
|
||||
|
||||
url(r'^cyberPanelVersion', views.cyberPanelVersion, name='cyberPanelVersion'),
|
||||
url(r'^putSSHkey', views.putSSHkey, name='putSSHkey'),
|
||||
|
||||
|
||||
url(r'^changeAdminPassword', views.changeAdminPassword, name='changeAdminPassword'),
|
||||
url(r'^runAWSBackups$', views.runAWSBackups, name='runAWSBackups'),
|
||||
|
||||
]
|
||||
376
api/views.py
|
|
@ -6,21 +6,21 @@ from django.http import HttpResponse
|
|||
from loginSystem.models import Administrator
|
||||
from plogical.virtualHostUtilities import virtualHostUtilities
|
||||
from plogical import hashPassword
|
||||
from plogical.installUtilities import installUtilities
|
||||
from packages.models import Package
|
||||
from baseTemplate.views import renderBase
|
||||
from random import randint
|
||||
from websiteFunctions.models import Websites,ChildDomains
|
||||
from websiteFunctions.models import Websites
|
||||
import os
|
||||
from baseTemplate.models import version
|
||||
import subprocess
|
||||
import shlex
|
||||
import re
|
||||
from plogical.mailUtilities import mailUtilities
|
||||
from websiteFunctions.website import WebsiteManager
|
||||
from s3Backups.s3Backups import S3Backups
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
from plogical.processUtilities import ProcessUtilities
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
# Create your views here.
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def verifyConn(request):
|
||||
try:
|
||||
if request.method == 'POST':
|
||||
|
|
@ -31,6 +31,11 @@ def verifyConn(request):
|
|||
|
||||
admin = Administrator.objects.get(userName=adminUser)
|
||||
|
||||
if admin.api == 0:
|
||||
data_ret = {"verifyConn": 0, 'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
if hashPassword.check_password(admin.password, adminPass):
|
||||
data_ret = {"verifyConn": 1}
|
||||
json_data = json.dumps(data_ret)
|
||||
|
|
@ -45,7 +50,23 @@ def verifyConn(request):
|
|||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@csrf_exempt
|
||||
def createWebsite(request):
|
||||
data = json.loads(request.body)
|
||||
adminUser = data['adminUser']
|
||||
admin = Administrator.objects.get(userName=adminUser)
|
||||
|
||||
if admin.api == 0:
|
||||
data_ret = {"existsStatus": 0, 'createWebSiteStatus': 0,
|
||||
'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
wm = WebsiteManager()
|
||||
return wm.createWebsiteAPI(json.loads(request.body))
|
||||
|
||||
@csrf_exempt
|
||||
def getUserInfo(request):
|
||||
try:
|
||||
if request.method == 'POST':
|
||||
|
||||
|
|
@ -53,74 +74,44 @@ def createWebsite(request):
|
|||
|
||||
adminUser = data['adminUser']
|
||||
adminPass = data['adminPass']
|
||||
domain = data['domainName']
|
||||
adminEmail = data['ownerEmail']
|
||||
packageName = data['packageName']
|
||||
websiteOwner = data['websiteOwner']
|
||||
ownerPassword = data['ownerPassword']
|
||||
externalApp = "".join(re.findall("[a-zA-Z]+", domain))[:7]
|
||||
data['ssl'] = 0
|
||||
data['dkimCheck'] = 0
|
||||
data['openBasedir'] = 1
|
||||
|
||||
|
||||
phpSelection = "PHP 7.0"
|
||||
username = data['username']
|
||||
|
||||
admin = Administrator.objects.get(userName=adminUser)
|
||||
|
||||
if admin.api == 0:
|
||||
data_ret = {"status": 0, 'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
if hashPassword.check_password(admin.password, adminPass):
|
||||
pass
|
||||
else:
|
||||
data_ret = {"existsStatus": 0, 'createWebSiteStatus': 0,
|
||||
data_ret = {"status": 0,
|
||||
'error_message': "Could not authorize access to API"}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
if adminEmail is None:
|
||||
adminEmail = "usman@cyberpersons.com"
|
||||
|
||||
try:
|
||||
websiteOwn = Administrator(userName=websiteOwner, password=hashPassword.hash_password(ownerPassword),
|
||||
email=adminEmail, type=3, owner=admin.pk,
|
||||
initWebsitesLimit=1)
|
||||
websiteOwn.save()
|
||||
except BaseException,msg:
|
||||
pass
|
||||
|
||||
|
||||
## Create Configurations
|
||||
|
||||
numberOfWebsites = str(Websites.objects.count() + ChildDomains.objects.count())
|
||||
sslpath = "/home/" + domain + "/public_html"
|
||||
|
||||
## Create Configurations
|
||||
|
||||
execPath = "sudo python " + virtualHostUtilities.cyberPanel + "/plogical/virtualHostUtilities.py"
|
||||
|
||||
execPath = execPath + " createVirtualHost --virtualHostName " + domain + \
|
||||
" --administratorEmail " + adminEmail + " --phpVersion '" + phpSelection + \
|
||||
"' --virtualHostUser " + externalApp + " --numberOfSites " + numberOfWebsites + \
|
||||
" --ssl " + str(data['ssl']) + " --sslPath " + sslpath + " --dkimCheck " + str(data['dkimCheck']) \
|
||||
+ " --openBasedir " + str(data['openBasedir']) + ' --websiteOwner ' + websiteOwner \
|
||||
+ ' --package ' + packageName
|
||||
|
||||
output = subprocess.check_output(shlex.split(execPath))
|
||||
|
||||
if output.find("1,None") > -1:
|
||||
data_ret = {'createWebSiteStatus': 1, 'error_message': "None", "existsStatus": 0}
|
||||
user = Administrator.objects.get(userName=username)
|
||||
data_ret = {'status': 0,
|
||||
'firstName': user.firstName,
|
||||
'lastName': user.lastName,
|
||||
'email': user.email,
|
||||
'adminStatus': user.acl.adminStatus,
|
||||
'error_message': "None"}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
else:
|
||||
data_ret = {'createWebSiteStatus': 0, 'error_message': output, "existsStatus": 0}
|
||||
except:
|
||||
data_ret = {'status': 0, 'error_message': "User does not exists."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
|
||||
except BaseException, msg:
|
||||
data_ret = {'createWebSiteStatus': 0, 'error_message': str(msg), "existsStatus": 0}
|
||||
data_ret = {'status': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@csrf_exempt
|
||||
def changeUserPassAPI(request):
|
||||
try:
|
||||
if request.method == 'POST':
|
||||
|
|
@ -130,11 +121,17 @@ def changeUserPassAPI(request):
|
|||
|
||||
websiteOwner = data['websiteOwner']
|
||||
ownerPassword = data['ownerPassword']
|
||||
|
||||
adminUser = data['adminUser']
|
||||
adminPass = data['adminPass']
|
||||
|
||||
admin = Administrator.objects.get(userName=adminUser)
|
||||
|
||||
if admin.api == 0:
|
||||
data_ret = {"changeStatus": 0, 'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
if hashPassword.check_password(admin.password, adminPass):
|
||||
pass
|
||||
else:
|
||||
|
|
@ -159,6 +156,7 @@ def changeUserPassAPI(request):
|
|||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@csrf_exempt
|
||||
def changePackageAPI(request):
|
||||
try:
|
||||
if request.method == 'POST':
|
||||
|
|
@ -172,6 +170,11 @@ def changePackageAPI(request):
|
|||
|
||||
admin = Administrator.objects.get(userName=adminUser)
|
||||
|
||||
if admin.api == 0:
|
||||
data_ret = {"changePackage": 0, 'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
if hashPassword.check_password(admin.password, adminPass):
|
||||
pass
|
||||
else:
|
||||
|
|
@ -198,16 +201,24 @@ def changePackageAPI(request):
|
|||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@csrf_exempt
|
||||
def deleteWebsite(request):
|
||||
try:
|
||||
if request.method == 'POST':
|
||||
data = json.loads(request.body)
|
||||
websiteName = data['domainName']
|
||||
|
||||
adminUser = data['adminUser']
|
||||
adminPass = data['adminPass']
|
||||
|
||||
admin = Administrator.objects.get(userName=adminUser)
|
||||
|
||||
if admin.api == 0:
|
||||
data_ret = {"websiteDeleteStatus": 0, 'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
data['websiteName'] = data['domainName']
|
||||
|
||||
if hashPassword.check_password(admin.password, adminPass):
|
||||
pass
|
||||
else:
|
||||
|
|
@ -216,44 +227,40 @@ def deleteWebsite(request):
|
|||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
website = Websites.objects.get(domain=websiteName)
|
||||
website = Websites.objects.get(domain=data['websiteName'])
|
||||
websiteOwner = website.admin
|
||||
|
||||
if admin.websites_set.all().count() == 0:
|
||||
websiteOwner.delete()
|
||||
try:
|
||||
if admin.websites_set.all().count() == 0:
|
||||
websiteOwner.delete()
|
||||
except:
|
||||
pass
|
||||
|
||||
## Deleting master domain
|
||||
|
||||
numberOfWebsites = str(Websites.objects.count() + ChildDomains.objects.count())
|
||||
|
||||
|
||||
execPath = "sudo python " + virtualHostUtilities.cyberPanel + "/plogical/virtualHostUtilities.py"
|
||||
|
||||
execPath = execPath + " deleteVirtualHostConfigurations --virtualHostName " + websiteName + \
|
||||
" --numberOfSites " + numberOfWebsites
|
||||
|
||||
subprocess.check_output(shlex.split(execPath))
|
||||
|
||||
data_ret = {'websiteDeleteStatus': 1, 'error_message': "None"}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
wm = WebsiteManager()
|
||||
return wm.submitWebsiteDeletion(admin.pk, data)
|
||||
|
||||
except BaseException, msg:
|
||||
data_ret = {'websiteDeleteStatus': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@csrf_exempt
|
||||
def submitWebsiteStatus(request):
|
||||
try:
|
||||
if request.method == 'POST':
|
||||
data = json.loads(request.body)
|
||||
websiteName = data['websiteName']
|
||||
state = data['state']
|
||||
adminUser = data['adminUser']
|
||||
adminPass = data['adminPass']
|
||||
|
||||
admin = Administrator.objects.get(userName=adminUser)
|
||||
|
||||
if admin.api == 0:
|
||||
data_ret = {"websiteStatus": 0, 'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
if hashPassword.check_password(admin.password, adminPass):
|
||||
pass
|
||||
else:
|
||||
|
|
@ -262,50 +269,39 @@ def submitWebsiteStatus(request):
|
|||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
website = Websites.objects.get(domain=websiteName)
|
||||
|
||||
if state == "Suspend":
|
||||
virtualHostUtilities.suspendVirtualHost(websiteName)
|
||||
installUtilities.reStartLiteSpeed()
|
||||
website.state = 0
|
||||
else:
|
||||
virtualHostUtilities.UnsuspendVirtualHost(websiteName)
|
||||
installUtilities.reStartLiteSpeed()
|
||||
website.state = 1
|
||||
|
||||
website.save()
|
||||
|
||||
data_ret = {'websiteStatus': 1, 'error_message': "None"}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
wm = WebsiteManager()
|
||||
return wm.submitWebsiteStatus(admin.pk, json.loads(request.body))
|
||||
|
||||
except BaseException, msg:
|
||||
data_ret = {'websiteStatus': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@csrf_exempt
|
||||
def loginAPI(request):
|
||||
try:
|
||||
if request.method == "POST":
|
||||
username = request.POST['username']
|
||||
password = request.POST['password']
|
||||
|
||||
username = request.POST['username']
|
||||
password = request.POST['password']
|
||||
admin = Administrator.objects.get(userName=username)
|
||||
|
||||
admin = Administrator.objects.get(userName=username)
|
||||
|
||||
if hashPassword.check_password(admin.password, password):
|
||||
request.session['userID'] = admin.pk
|
||||
return redirect(renderBase)
|
||||
else:
|
||||
return HttpResponse("Invalid Credentials.")
|
||||
if admin.api == 0:
|
||||
data_ret = {"userID": 0, 'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
if hashPassword.check_password(admin.password, password):
|
||||
request.session['userID'] = admin.pk
|
||||
return redirect(renderBase)
|
||||
else:
|
||||
return HttpResponse("Invalid Credentials.")
|
||||
|
||||
except BaseException, msg:
|
||||
data = {'userID': 0, 'loginStatus': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def fetchSSHkey(request):
|
||||
try:
|
||||
if request.method == "POST":
|
||||
|
|
@ -315,13 +311,19 @@ def fetchSSHkey(request):
|
|||
|
||||
admin = Administrator.objects.get(userName=username)
|
||||
|
||||
if admin.api == 0:
|
||||
data_ret = {"status": 0, 'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
if hashPassword.check_password(admin.password, password):
|
||||
|
||||
pubKey = os.path.join("/root",".ssh",'cyberpanel.pub')
|
||||
execPath = "sudo cat " + pubKey
|
||||
data = subprocess.check_output(shlex.split(execPath))
|
||||
execPath = "cat " + pubKey
|
||||
data = ProcessUtilities.outputExecutioner(execPath)
|
||||
|
||||
data_ret = {
|
||||
'status': 1,
|
||||
'pubKeyStatus': 1,
|
||||
'error_message': "None",
|
||||
'pubKey':data
|
||||
|
|
@ -330,6 +332,7 @@ def fetchSSHkey(request):
|
|||
return HttpResponse(json_data)
|
||||
else:
|
||||
data_ret = {
|
||||
'status' : 0,
|
||||
'pubKeyStatus': 0,
|
||||
'error_message': "Could not authorize access to API."
|
||||
}
|
||||
|
|
@ -337,10 +340,11 @@ def fetchSSHkey(request):
|
|||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException, msg:
|
||||
data = {'pubKeyStatus': 0,'error_message': str(msg)}
|
||||
data = {'status' : 0, 'pubKeyStatus': 0,'error_message': str(msg)}
|
||||
json_data = json.dumps(data)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@csrf_exempt
|
||||
def remoteTransfer(request):
|
||||
try:
|
||||
if request.method == "POST":
|
||||
|
|
@ -348,11 +352,18 @@ def remoteTransfer(request):
|
|||
data = json.loads(request.body)
|
||||
username = data['username']
|
||||
password = data['password']
|
||||
ipAddress = data['ipAddress']
|
||||
accountsToTransfer = data['accountsToTransfer']
|
||||
|
||||
|
||||
admin = Administrator.objects.get(userName=username)
|
||||
|
||||
if admin.api == 0:
|
||||
data_ret = {"transferStatus": 0, 'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
ipAddress = data['ipAddress']
|
||||
accountsToTransfer = data['accountsToTransfer']
|
||||
|
||||
if hashPassword.check_password(admin.password, password):
|
||||
dir = str(randint(1000, 9999))
|
||||
|
||||
|
|
@ -368,9 +379,9 @@ def remoteTransfer(request):
|
|||
|
||||
## Accounts to transfer is a path to file, containing accounts.
|
||||
|
||||
execPath = "sudo python " + virtualHostUtilities.cyberPanel + "/plogical/remoteTransferUtilities.py"
|
||||
execPath = "/usr/local/CyberCP/bin/python2 " + virtualHostUtilities.cyberPanel + "/plogical/remoteTransferUtilities.py"
|
||||
execPath = execPath + " remoteTransfer --ipAddress " + ipAddress + " --dir " + dir + " --accountsToTransfer " + path
|
||||
subprocess.Popen(shlex.split(execPath))
|
||||
ProcessUtilities.popenExecutioner(execPath)
|
||||
|
||||
return HttpResponse(json.dumps({"transferStatus": 1, "dir": dir}))
|
||||
|
||||
|
|
@ -385,6 +396,7 @@ def remoteTransfer(request):
|
|||
json_data = json.dumps(data)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@csrf_exempt
|
||||
def fetchAccountsFromRemoteServer(request):
|
||||
try:
|
||||
if request.method == "POST":
|
||||
|
|
@ -393,6 +405,12 @@ def fetchAccountsFromRemoteServer(request):
|
|||
password = data['password']
|
||||
|
||||
admin = Administrator.objects.get(userName=username)
|
||||
|
||||
if admin.api == 0:
|
||||
data_ret = {"fetchStatus": 0, 'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
if hashPassword.check_password(admin.password, password):
|
||||
|
||||
records = Websites.objects.all()
|
||||
|
|
@ -428,7 +446,7 @@ def fetchAccountsFromRemoteServer(request):
|
|||
json_data = json.dumps(data)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def FetchRemoteTransferStatus(request):
|
||||
try:
|
||||
if request.method == "POST":
|
||||
|
|
@ -436,13 +454,20 @@ def FetchRemoteTransferStatus(request):
|
|||
username = data['username']
|
||||
password = data['password']
|
||||
|
||||
admin = Administrator.objects.get(userName=username)
|
||||
|
||||
if admin.api == 0:
|
||||
data_ret = {"fetchStatus": 0, 'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
dir = "/home/backup/transfer-"+str(data['dir'])+"/backup_log"
|
||||
|
||||
try:
|
||||
command = "sudo cat "+ dir
|
||||
status = subprocess.check_output(shlex.split(command))
|
||||
command = "cat "+ dir
|
||||
status = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
|
||||
admin = Administrator.objects.get(userName=username)
|
||||
if hashPassword.check_password(admin.password, password):
|
||||
|
||||
final_json = json.dumps({'fetchStatus': 1, 'error_message': "None", "status": status})
|
||||
|
|
@ -462,28 +487,37 @@ def FetchRemoteTransferStatus(request):
|
|||
json_data = json.dumps(data)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@csrf_exempt
|
||||
def cancelRemoteTransfer(request):
|
||||
try:
|
||||
if request.method == "POST":
|
||||
data = json.loads(request.body)
|
||||
username = data['username']
|
||||
password = data['password']
|
||||
dir = "/home/backup/transfer-"+str(data['dir'])
|
||||
|
||||
admin = Administrator.objects.get(userName=username)
|
||||
|
||||
if admin.api == 0:
|
||||
data_ret = {"cancelStatus": 0, 'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
dir = "/home/backup/transfer-"+str(data['dir'])
|
||||
|
||||
|
||||
|
||||
if hashPassword.check_password(admin.password, password):
|
||||
|
||||
path = dir + "/pid"
|
||||
|
||||
command = "sudo cat " + path
|
||||
pid = subprocess.check_output(shlex.split(command))
|
||||
command = "cat " + path
|
||||
pid = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
command = "sudo kill -KILL " + pid
|
||||
subprocess.call(shlex.split(command))
|
||||
command = "kill -KILL " + pid
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
command = "sudo rm -rf " + dir
|
||||
subprocess.call(shlex.split(command))
|
||||
command = "rm -rf " + dir
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
data = {'cancelStatus': 1, 'error_message': "None"}
|
||||
json_data = json.dumps(data)
|
||||
|
|
@ -500,6 +534,7 @@ def cancelRemoteTransfer(request):
|
|||
json_data = json.dumps(data)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@csrf_exempt
|
||||
def cyberPanelVersion(request):
|
||||
try:
|
||||
if request.method == 'POST':
|
||||
|
|
@ -512,6 +547,11 @@ def cyberPanelVersion(request):
|
|||
|
||||
admin = Administrator.objects.get(userName=adminUser)
|
||||
|
||||
if admin.api == 0:
|
||||
data_ret = {"getVersion": 0, 'error_message': "API Access Disabled."}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
if hashPassword.check_password(admin.password, adminPass):
|
||||
|
||||
Version = version.objects.get(pk=1)
|
||||
|
|
@ -541,105 +581,15 @@ def cyberPanelVersion(request):
|
|||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def putSSHkey(request):
|
||||
try:
|
||||
if request.method == 'POST':
|
||||
|
||||
data = json.loads(request.body)
|
||||
|
||||
adminUser = data['username']
|
||||
adminPass = data['password']
|
||||
pubKey = data['putSSHKey']
|
||||
|
||||
|
||||
admin = Administrator.objects.get(userName=adminUser)
|
||||
|
||||
if hashPassword.check_password(admin.password, adminPass):
|
||||
keyPath = "/home/cyberpanel/.ssh"
|
||||
|
||||
if not os.path.exists(keyPath):
|
||||
os.makedirs(keyPath)
|
||||
|
||||
|
||||
## writeKey
|
||||
|
||||
authorized_keys = keyPath+"/authorized_keys"
|
||||
presenseCheck = 0
|
||||
try:
|
||||
data = open(authorized_keys, "r").readlines()
|
||||
for items in data:
|
||||
if items.find(pubKey) > -1:
|
||||
presenseCheck = 1
|
||||
except:
|
||||
pass
|
||||
|
||||
if presenseCheck == 0:
|
||||
writeToFile = open(authorized_keys, 'a')
|
||||
writeToFile.writelines("#Added by CyberPanel\n")
|
||||
writeToFile.writelines("\n")
|
||||
writeToFile.writelines(pubKey)
|
||||
writeToFile.writelines("\n")
|
||||
writeToFile.close()
|
||||
|
||||
##
|
||||
|
||||
command = "sudo chmod g-w /home/cyberpanel"
|
||||
cmd = shlex.split(command)
|
||||
res = subprocess.call(cmd)
|
||||
|
||||
os.chmod(keyPath,0700)
|
||||
os.chmod(authorized_keys, 0600)
|
||||
|
||||
|
||||
data_ret = {"putSSHKey": 1,
|
||||
'error_message': "None",}
|
||||
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
else:
|
||||
data_ret = {"putSSHKey": 0,
|
||||
'error_message': "Could not authorize access to API"}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException, msg:
|
||||
data_ret = {"putSSHKey": 0,
|
||||
'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def changeAdminPassword(request):
|
||||
@csrf_exempt
|
||||
def runAWSBackups(request):
|
||||
try:
|
||||
|
||||
data = json.loads(request.body)
|
||||
|
||||
adminPass = data['password']
|
||||
randomFile = data['randomFile']
|
||||
|
||||
if os.path.exists(randomFile):
|
||||
os.remove(randomFile)
|
||||
admin = Administrator.objects.get(userName="admin")
|
||||
admin.password = hashPassword.hash_password(adminPass)
|
||||
admin.save()
|
||||
data_ret = {"changed": 1,
|
||||
'error_message': "None"}
|
||||
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
else:
|
||||
data_ret = {"changed": 0,
|
||||
'error_message': "Failed to authorize access to change password!"}
|
||||
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
|
||||
|
||||
s3 = S3Backups(request, None, 'runAWSBackups')
|
||||
s3.start()
|
||||
except BaseException, msg:
|
||||
data_ret = {"changed": 0,
|
||||
'error_message': "Failed to authorize access to change password!"}
|
||||
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
|
||||
logging.writeToFile(str(msg) + ' [API.runAWSBackups]')
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
from signals import *
|
||||
from plogical.pluginManagerGlobal import pluginManagerGlobal
|
||||
|
||||
class pluginManager:
|
||||
|
||||
@staticmethod
|
||||
def preBackupSite(request):
|
||||
return pluginManagerGlobal.globalPlug(request, preBackupSite)
|
||||
|
||||
@staticmethod
|
||||
def postBackupSite(request, response):
|
||||
return pluginManagerGlobal.globalPlug(request, postBackupSite, response)
|
||||
|
||||
@staticmethod
|
||||
def preRestoreSite(request):
|
||||
return pluginManagerGlobal.globalPlug(request, preRestoreSite)
|
||||
|
||||
@staticmethod
|
||||
def postRestoreSite(request, response):
|
||||
return pluginManagerGlobal.globalPlug(request, postRestoreSite, response)
|
||||
|
||||
@staticmethod
|
||||
def preSubmitBackupCreation(request):
|
||||
return pluginManagerGlobal.globalPlug(request, preSubmitBackupCreation)
|
||||
|
||||
@staticmethod
|
||||
def preBackupStatus(request):
|
||||
return pluginManagerGlobal.globalPlug(request, preBackupStatus)
|
||||
|
||||
@staticmethod
|
||||
def postBackupStatus(request, response):
|
||||
return pluginManagerGlobal.globalPlug(request, postBackupStatus, response)
|
||||
|
||||
@staticmethod
|
||||
def preDeleteBackup(request):
|
||||
return pluginManagerGlobal.globalPlug(request, preDeleteBackup)
|
||||
|
||||
@staticmethod
|
||||
def postDeleteBackup(request, response):
|
||||
return pluginManagerGlobal.globalPlug(request, postDeleteBackup, response)
|
||||
|
||||
@staticmethod
|
||||
def preSubmitRestore(request):
|
||||
return pluginManagerGlobal.globalPlug(request, preSubmitRestore)
|
||||
|
||||
@staticmethod
|
||||
def preSubmitDestinationCreation(request):
|
||||
return pluginManagerGlobal.globalPlug(request, preSubmitDestinationCreation)
|
||||
|
||||
@staticmethod
|
||||
def postSubmitDestinationCreation(request, response):
|
||||
return pluginManagerGlobal.globalPlug(request, postSubmitDestinationCreation, response)
|
||||
|
||||
@staticmethod
|
||||
def preDeleteDestination(request):
|
||||
return pluginManagerGlobal.globalPlug(request, preDeleteDestination)
|
||||
|
||||
@staticmethod
|
||||
def postDeleteDestination(request, response):
|
||||
return pluginManagerGlobal.globalPlug(request, postDeleteDestination, response)
|
||||
|
||||
@staticmethod
|
||||
def preSubmitBackupSchedule(request):
|
||||
return pluginManagerGlobal.globalPlug(request, preSubmitBackupSchedule)
|
||||
|
||||
@staticmethod
|
||||
def postSubmitBackupSchedule(request, response):
|
||||
return pluginManagerGlobal.globalPlug(request, postSubmitBackupSchedule, response)
|
||||
|
||||
@staticmethod
|
||||
def preScheduleDelete(request):
|
||||
return pluginManagerGlobal.globalPlug(request, preScheduleDelete)
|
||||
|
||||
@staticmethod
|
||||
def postScheduleDelete(request, response):
|
||||
return pluginManagerGlobal.globalPlug(request, postScheduleDelete, response)
|
||||
|
||||
@staticmethod
|
||||
def preSubmitRemoteBackups(request):
|
||||
return pluginManagerGlobal.globalPlug(request, preSubmitRemoteBackups)
|
||||
|
||||
@staticmethod
|
||||
def postSubmitRemoteBackups(request, response):
|
||||
return pluginManagerGlobal.globalPlug(request, postSubmitRemoteBackups, response)
|
||||
|
||||
@staticmethod
|
||||
def preStarRemoteTransfer(request):
|
||||
return pluginManagerGlobal.globalPlug(request, preStarRemoteTransfer)
|
||||
|
||||
@staticmethod
|
||||
def postStarRemoteTransfer(request, response):
|
||||
return pluginManagerGlobal.globalPlug(request, postStarRemoteTransfer, response)
|
||||
|
||||
@staticmethod
|
||||
def preRemoteBackupRestore(request):
|
||||
return pluginManagerGlobal.globalPlug(request, preRemoteBackupRestore)
|
||||
|
||||
@staticmethod
|
||||
def postRemoteBackupRestore(request, response):
|
||||
return pluginManagerGlobal.globalPlug(request, postRemoteBackupRestore, response)
|
||||
|
||||
@staticmethod
|
||||
def postDeleteBackup(request, response):
|
||||
return pluginManagerGlobal.globalPlug(request, postRemoteBackupRestore, response)
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
# The world is a prison for the believer.
|
||||
|
||||
from django.dispatch import Signal
|
||||
|
||||
## This event is fired before CyberPanel core load template for create backup page.
|
||||
preBackupSite = Signal(providing_args=["request"])
|
||||
|
||||
## This event is fired after CyberPanel core load template for create backup page.
|
||||
postBackupSite = Signal(providing_args=["request", "response"])
|
||||
|
||||
## This event is fired before CyberPanel core load template for restore backup page.
|
||||
preRestoreSite = Signal(providing_args=["request"])
|
||||
|
||||
## This event is fired after CyberPanel core load template for restore backup page.
|
||||
postRestoreSite = Signal(providing_args=["request", "response"])
|
||||
|
||||
## This event is fired before CyberPanel core start creating backup of a website
|
||||
preSubmitBackupCreation = Signal(providing_args=["request"])
|
||||
|
||||
## This event is fired before CyberPanel core starts to load status of backup started earlier througb submitBackupCreation
|
||||
preBackupStatus = Signal(providing_args=["request"])
|
||||
|
||||
## This event is fired after CyberPanel core has loaded backup status
|
||||
postBackupStatus = Signal(providing_args=["request", "response"])
|
||||
|
||||
## This event is fired before CyberPanel core start deletion of a backup
|
||||
preDeleteBackup = Signal(providing_args=["request"])
|
||||
|
||||
## This event is fired after CyberPanel core finished the backup deletion
|
||||
postDeleteBackup = Signal(providing_args=["request", "response"])
|
||||
|
||||
## This event is fired before CyberPanel core start restoring a backup.
|
||||
preSubmitRestore = Signal(providing_args=["request"])
|
||||
|
||||
## This event is fired before CyberPanel core starts to add a remote backup destination
|
||||
preSubmitDestinationCreation = Signal(providing_args=["request"])
|
||||
|
||||
## This event is fired after CyberPanel core is finished adding remote backup destination
|
||||
postSubmitDestinationCreation = Signal(providing_args=["request", "response"])
|
||||
|
||||
## This event is fired before CyberPanel core starts to delete a backup destination
|
||||
preDeleteDestination = Signal(providing_args=["request"])
|
||||
|
||||
## This event is fired after CyberPanel core finished deleting a backup destination
|
||||
postDeleteDestination = Signal(providing_args=["request", "response"])
|
||||
|
||||
## This event is fired before CyberPanel core start adding a backup schedule
|
||||
preSubmitBackupSchedule = Signal(providing_args=["request"])
|
||||
|
||||
## This event is fired after CyberPanel core finished adding a backup schedule
|
||||
postSubmitBackupSchedule = Signal(providing_args=["request", "response"])
|
||||
|
||||
## This event is fired before CyberPanel core start the deletion of backup schedule
|
||||
preScheduleDelete = Signal(providing_args=["request"])
|
||||
|
||||
## This event is fired after CyberPanel core finished the deletion of backup schedule
|
||||
postScheduleDelete = Signal(providing_args=["request", "response"])
|
||||
|
||||
## This event is fired before CyberPanel core star the remote backup process
|
||||
preSubmitRemoteBackups = Signal(providing_args=["request"])
|
||||
|
||||
## This event is fired after CyberPanel core finished remote backup process
|
||||
postSubmitRemoteBackups = Signal(providing_args=["request", "response"])
|
||||
|
||||
## This event is fired before CyberPanel core star the remote backup process
|
||||
preStarRemoteTransfer = Signal(providing_args=["request"])
|
||||
|
||||
## This event is fired after CyberPanel core finished remote backup process
|
||||
postStarRemoteTransfer = Signal(providing_args=["request", "response"])
|
||||
|
||||
## This event is fired before CyberPanel core start restore of remote backups
|
||||
preRemoteBackupRestore = Signal(providing_args=["request"])
|
||||
|
||||
## This event is fired after CyberPanel core finished restoring remote backups in local server
|
||||
postRemoteBackupRestore = Signal(providing_args=["request", "response"])
|
||||
|
|
@ -63,8 +63,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<div class="col-sm-12">
|
||||
<div ng-hide="connectionFailed" class="alert alert-danger">
|
||||
<p>{% trans "Connection to" %} {$ IPAddress $} {% trans "failed. Please delete and re-add. " %} {$ errorMessage $} </p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,121 +3,134 @@
|
|||
{% block title %}{% trans "Schedule Back up - CyberPanel" %} {% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Schedule Back up" %} - <a target="_blank" href="http://go.cyberpanel.net/remote-backup" style="height: 23px;line-height: 21px;" class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>{% trans "Remote Backups" %}</span></a></h2>
|
||||
<p>{% trans "On this page you can schedule Back ups to localhost or remote server (If you have added one)." %}</p>
|
||||
</div>
|
||||
|
||||
<div ng-controller="scheduleBackup" class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Schedule Back up" %} <img ng-hide="scheduleBackupLoading" src="{% static 'images/loading.gif' %}">
|
||||
</h3>
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
|
||||
<form action="/" class="form-horizontal bordered-row">
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Select Destination" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="scheduleFreqView()" ng-model="backupDest" class="form-control">
|
||||
{% for items in destinations %}
|
||||
<option>{{ items }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="scheduleFreq" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Select Frequency" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="scheduleBtnView()" ng-model="backupFreq" class="form-control">
|
||||
<option>Daily</option>
|
||||
<option>Weekly</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div ng-hide="scheduleBtn" class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-click="addSchedule()" class="btn btn-primary btn-lg btn-block">{% trans "Add Destination" %}</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!------ List of Destinations --------------->
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
|
||||
<div ng-hide="canNotAddSchedule" class="alert alert-danger">
|
||||
<p>{% trans "Cannot add schedule. Error message:" %} {$ errorMessage $} </p>
|
||||
</div>
|
||||
|
||||
<div ng-hide="scheduleAdded" class="alert alert-success">
|
||||
<p>{% trans "Schedule Added" %}</p>
|
||||
</div>
|
||||
|
||||
<div ng-hide="couldNotConnect" class="alert alert-danger">
|
||||
<p>{% trans "Could not connect to server. Please refresh this page." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<div class="col-sm-12">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "ID" %}</th>
|
||||
<th>{% trans "Destination" %}</th>
|
||||
<th>{% trans "Frequency" %}</th>
|
||||
<th>{% trans "Delete" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="record in records track by $index">
|
||||
<td ng-bind="record.id"></td>
|
||||
<td ng-bind="record.destLoc"></td>
|
||||
<td ng-bind="record.frequency"></td>
|
||||
<td ng-click="delSchedule(record.destLoc,record.frequency)"><img src="{% static 'images/delete.png' %}"></td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!------ List of records --------------->
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
{% load static %}
|
||||
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Schedule Back up" %} - <a target="_blank" href="http://go.cyberpanel.net/remote-backup"
|
||||
style="height: 23px;line-height: 21px;"
|
||||
class="btn btn-border btn-alt border-red btn-link font-red"
|
||||
title=""><span>{% trans "Remote Backups" %}</span></a></h2>
|
||||
<p>{% trans "On this page you can schedule Back ups to localhost or remote server (If you have added one)." %}</p>
|
||||
</div>
|
||||
|
||||
<div ng-controller="scheduleBackup" class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Schedule Back up" %} <img ng-hide="scheduleBackupLoading"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
</h3>
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
|
||||
<form action="/" class="form-horizontal bordered-row">
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Select Destination" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="scheduleFreqView()" ng-model="backupDest" class="form-control">
|
||||
{% for items in destinations %}
|
||||
<option>{{ items }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="scheduleFreq" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Select Frequency" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="scheduleBtnView()" ng-model="backupFreq" class="form-control">
|
||||
<option>Daily</option>
|
||||
<option>Weekly</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="localPath" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Local Path" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input name="dom" type="text" class="form-control" ng-model="localPathValue"
|
||||
placeholder="{% trans "Local directory where backups will be moved after creation." %}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div ng-hide="scheduleBtn" class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-click="addSchedule()"
|
||||
class="btn btn-primary btn-lg btn-block">{% trans "Add Destination" %}</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!------ List of Destinations --------------->
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
|
||||
<div ng-hide="canNotAddSchedule" class="alert alert-danger">
|
||||
<p>{% trans "Cannot add schedule. Error message:" %} {$ errorMessage $} </p>
|
||||
</div>
|
||||
|
||||
<div ng-hide="scheduleAdded" class="alert alert-success">
|
||||
<p>{% trans "Schedule Added" %}</p>
|
||||
</div>
|
||||
|
||||
<div ng-hide="couldNotConnect" class="alert alert-danger">
|
||||
<p>{% trans "Could not connect to server. Please refresh this page." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<div class="col-sm-12">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "ID" %}</th>
|
||||
<th>{% trans "Destination" %}</th>
|
||||
<th>{% trans "Frequency" %}</th>
|
||||
<th>{% trans "Delete" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="record in records track by $index">
|
||||
<td ng-bind="record.id"></td>
|
||||
<td ng-bind="record.destLoc"></td>
|
||||
<td ng-bind="record.frequency"></td>
|
||||
<td ng-click="delSchedule(record.destLoc,record.frequency)"><img
|
||||
src="{% static 'images/delete.png' %}"></td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!------ List of records --------------->
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -13,60 +13,94 @@
|
|||
<h2>{% trans "Back up" %}</h2>
|
||||
<p>{% trans "Back up and restore sites." %}</p>
|
||||
</div>
|
||||
<div class="panel">
|
||||
<div class="panel col-md-11">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
<h3 class="content-box-header">
|
||||
{% trans "Available Functions" %}
|
||||
</h3>
|
||||
|
||||
<div class="example-box-wrapper">
|
||||
{% if viewStatus == 0 %}
|
||||
<div class="row">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<a href="{% url 'backupSite' %}" title="{% trans 'Back up Site' %}" class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "Back up" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="glyph-icon icon-dashboard"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{% if createBackup or admin %}
|
||||
|
||||
</div>
|
||||
<div class="col-md-3 btn-min-width">
|
||||
<a href="{% url 'backupSite' %}" title="{% trans 'Back up Site' %}" class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "Back up" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="fa fa-clone"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
{% endif %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<a href="{% url 'backupSite' %}" title="{% trans 'Back up Site' %}" class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "Back up" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="glyph-icon icon-dashboard"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{% if restoreBackup or admin %}
|
||||
|
||||
|
||||
<div class="col-md-6">
|
||||
<a href="{% url 'restoreSite' %}" title="{% trans 'Restore Back up' %}" class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "Restore" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="glyph-icon icon-dashboard"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-3 btn-min-width">
|
||||
<a href="{% url 'restoreSite' %}" title="{% trans 'Restore Back up' %}" class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "Restore" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="fa fa-undo"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if addDeleteDestinations or admin %}
|
||||
|
||||
<div class="col-md-3 btn-min-width">
|
||||
<a href="{% url 'backupDestinations' %}" title="{% trans 'Add/Delete Destinations' %}" class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "Add/Delete Destinations" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="fa fa-map-pin"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if scheDuleBackups or admin %}
|
||||
|
||||
<div class="col-md-3 btn-min-width">
|
||||
<a href="{% url 'scheduleBackup' %}" title="{% trans 'Schedule Back up' %}" class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "Schedule Back up" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="fa fa-refresh"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if remoteBackups or admin %}
|
||||
|
||||
<div class="col-md-3 btn-min-width">
|
||||
<a href="{% url 'remoteBackups' %}" title="{% trans 'Remote Back ups' %}" class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "Remote Back ups" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="fa fa-cloud-upload"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -74,4 +108,4 @@
|
|||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ urlpatterns = [
|
|||
|
||||
url(r'^cancelRemoteBackup', views.cancelRemoteBackup, name='cancelRemoteBackup'),
|
||||
|
||||
url(r'^localInitiate$', views.localInitiate, name='localInitiate'),
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
1593
backup/views.py
0
baseTemplate/static/baseTemplate/assets/bootstrap/css/bootstrap-theme.css
vendored
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/bootstrap/css/bootstrap-theme.css.map
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/bootstrap/css/bootstrap-theme.min.css
vendored
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/bootstrap/css/bootstrap-theme.min.css.map
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/bootstrap/css/bootstrap.css
vendored
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/bootstrap/css/bootstrap.css.map
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/bootstrap/css/bootstrap.min.css
vendored
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/bootstrap/css/bootstrap.min.css.map
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/bootstrap/fonts/glyphicons-halflings-regular.eot
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/bootstrap/fonts/glyphicons-halflings-regular.svg
Executable file → Normal file
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
0
baseTemplate/static/baseTemplate/assets/bootstrap/fonts/glyphicons-halflings-regular.ttf
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/bootstrap/fonts/glyphicons-halflings-regular.woff
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/bootstrap/fonts/glyphicons-halflings-regular.woff2
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/bootstrap/js/bootstrap.js
vendored
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/bootstrap/js/bootstrap.min.js
vendored
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/elements/loading-indicators.css
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/elements/response-messages.css
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/elements/responsive-tables.css
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/finalBase/fontawesome-webfont.eot
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/finalBase/fontawesome-webfont.svg
Executable file → Normal file
|
Before Width: | Height: | Size: 280 KiB After Width: | Height: | Size: 280 KiB |
0
baseTemplate/static/baseTemplate/assets/finalBase/fontawesome-webfont.ttf
Executable file → Normal file
0
baseTemplate/static/baseTemplate/assets/finalBase/fontawesome-webfont.woff
Executable file → Normal file
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |