From 88b95d511fab026ac3c28fe420259f684579e060 Mon Sep 17 00:00:00 2001 From: usmannasir <01-134132-158@student.bahria.edu.pk> Date: Mon, 10 Sep 2018 01:45:43 +0500 Subject: [PATCH] Virtual machine manager --- CyberCP/settings.py | 8 +- CyberCP/urls.py | 3 + CyberTronAPI/CyberTronLogger.py | 35 + CyberTronAPI/__init__.py | 0 CyberTronAPI/cybertron.py | 489 ++++++++ CyberTronAPI/hashPassword.py | 13 + CyberTronAPI/logLevel.py | 2 + CyberTronAPI/randomPassword.py | 38 + CyberTronAPI/sslUtilities.py | 341 ++++++ CyberTronAPI/test.py | 29 + CyberTronAPI/virtualMachineAPI.py | 638 ++++++++++ CyberTronAPI/virtualMachineAPIKVM.py | 613 ++++++++++ CyberTronAPI/virtualMachineAPIOpenVZ.py | 668 ++++++++++ backup/static/backup/backup.js | 478 +++++++- backup/templates/backup/createSnapshots.html | 99 ++ backup/urls.py | 8 + backup/views.py | 50 +- .../templates/baseTemplate/homePageVMM.html | 85 ++ .../templates/baseTemplate/index.html | 16 +- .../templates/baseTemplate/indexVMM.html | 392 ++++++ baseTemplate/urls.py | 7 +- baseTemplate/views.py | 25 +- hypervisor/__init__.py | 0 hypervisor/admin.py | 6 + hypervisor/apps.py | 8 + hypervisor/hypervisor.py | 144 +++ hypervisor/migrations/__init__.py | 0 hypervisor/models.py | 13 + hypervisor/static/hypervisor/hypervisor.js | 287 +++++ .../hypervisor/createHyperVisor.html | 91 ++ hypervisor/templates/hypervisor/indexVMM.html | 56 + hypervisor/templates/hypervisor/listHV.html | 147 +++ hypervisor/tests.py | 6 + hypervisor/urls.py | 12 + hypervisor/views.py | 56 + install/install.py | 297 ++++- install/openlitespeed.tar.gz | Bin 4090810 -> 4090810 bytes ipManagement/__init__.py | 0 ipManagement/admin.py | 6 + ipManagement/apps.py | 8 + ipManagement/migrations/__init__.py | 0 ipManagement/models.py | 20 + .../static/ipManagement/ipManagement.js | 458 +++++++ .../templates/ipManagement/createIPPool.html | 114 ++ .../templates/ipManagement/indexVMM.html | 56 + .../templates/ipManagement/listIPPools.html | 209 ++++ ipManagement/tests.py | 6 + ipManagement/urls.py | 23 + ipManagement/views.py | 335 ++++++ packages/models.py | 9 + packages/static/packages/packages.js | 312 ++++- .../templates/packages/createPackageVMM.html | 102 ++ .../templates/packages/deletePackageVMM.html | 85 ++ packages/templates/packages/indexVMM.html | 70 ++ .../templates/packages/modifyPackageVMM.html | 122 ++ packages/urls.py | 23 +- packages/views.py | 212 +++- plogical/.my.cnf.4370 | 0 plogical/.mysql.4370 | 0 plogical/CyberCPLogFileWriter.py | 0 plogical/__init__.py | 0 plogical/acl.py | 0 plogical/aclVMM.py | 277 +++++ plogical/adminPass.py | 0 plogical/alias.py | 0 plogical/applicationInstaller.py | 0 plogical/backupManager.py | 3 + plogical/backupSchedule.py | 0 plogical/backupScheduleLocal.py | 0 plogical/backupUtilities.py | 0 plogical/childDomain.py | 0 plogical/dnsUtilities.py | 0 plogical/domain.xml | 0 plogical/filemanager.py | 0 plogical/findBWUsage.py | 0 plogical/firewallManager.py | 0 plogical/firewallUtilities.py | 0 plogical/ftpUtilities.py | 0 plogical/getSystemInformation.py | 0 plogical/hashPassword.py | 0 plogical/installUtilities.py | 0 plogical/letsEncrypt.py | 0 plogical/mailUtilities.py | 0 plogical/modSec.py | 0 plogical/mysqlUtilities.py | 1 - plogical/phpUtilities.py | 0 plogical/processUtilities.py | 0 plogical/randomPassword.py | 0 plogical/remoteBackup.py | 0 plogical/remoteTransferUtilities.py | 0 plogical/serverLogs.py | 0 plogical/sslUtilities.py | 0 plogical/test.py | 0 plogical/tuning.py | 0 plogical/upgrade.py | 0 plogical/vhost.py | 0 plogical/virtualHostUtilities.py | 21 + plogical/website.py | 4 +- requirments.txt | 1 + static/backup/backup.js | 478 +++++++- static/hypervisor/hypervisor.js | 287 +++++ static/ipManagement/ipManagement.js | 458 +++++++ static/packages/packages.js | 312 ++++- static/userManagment/userManagment.js | 2 +- static/vpsManagement/backup.png | Bin 0 -> 2414 bytes static/vpsManagement/changePassword.png | Bin 0 -> 2919 bytes static/vpsManagement/close-32.png | Bin 0 -> 1039 bytes static/vpsManagement/console.png | Bin 0 -> 1111 bytes static/vpsManagement/delete.png | Bin 0 -> 894 bytes static/vpsManagement/hostname.png | Bin 0 -> 2891 bytes static/vpsManagement/install.png | Bin 0 -> 1910 bytes static/vpsManagement/pnotify.custom.min.css | 10 + static/vpsManagement/pnotify.custom.min.js | 31 + static/vpsManagement/powerOff.png | Bin 0 -> 599 bytes static/vpsManagement/restart.png | Bin 0 -> 903 bytes static/vpsManagement/settings-gears.png | Bin 0 -> 1228 bytes static/vpsManagement/snapshots.png | Bin 0 -> 988 bytes static/vpsManagement/vpsManagement.js | 1041 ++++++++++++++++ static/vpsManagement/vpsON.png | Bin 0 -> 757 bytes static/vpsManagement/vpsOff.png | Bin 0 -> 667 bytes .../static/userManagment/userManagment.js | 2 +- vpsManagement/__init__.py | 0 vpsManagement/admin.py | 6 + vpsManagement/apps.py | 8 + vpsManagement/migrations/__init__.py | 0 vpsManagement/models.py | 33 + vpsManagement/static/vpsManagement/backup.png | Bin 0 -> 2414 bytes .../static/vpsManagement/changePassword.png | Bin 0 -> 2919 bytes .../static/vpsManagement/close-32.png | Bin 0 -> 1039 bytes .../static/vpsManagement/console.png | Bin 0 -> 1111 bytes vpsManagement/static/vpsManagement/delete.png | Bin 0 -> 894 bytes .../static/vpsManagement/hostname.png | Bin 0 -> 2891 bytes .../static/vpsManagement/install.png | Bin 0 -> 1910 bytes .../vpsManagement/pnotify.custom.min.css | 10 + .../vpsManagement/pnotify.custom.min.js | 31 + .../static/vpsManagement/powerOff.png | Bin 0 -> 599 bytes .../static/vpsManagement/restart.png | Bin 0 -> 903 bytes .../static/vpsManagement/settings-gears.png | Bin 0 -> 1228 bytes .../static/vpsManagement/snapshots.png | Bin 0 -> 988 bytes .../static/vpsManagement/vpsManagement.js | 1070 +++++++++++++++++ vpsManagement/static/vpsManagement/vpsON.png | Bin 0 -> 757 bytes vpsManagement/static/vpsManagement/vpsOff.png | Bin 0 -> 667 bytes .../templates/vpsManagement/createVPS.html | 193 +++ .../templates/vpsManagement/indexVMM.html | 68 ++ .../templates/vpsManagement/listVPS.html | 161 +++ .../templates/vpsManagement/manageVPS.html | 402 +++++++ .../templates/vpsManagement/sshKeys.html | 84 ++ vpsManagement/tests.py | 6 + vpsManagement/urls.py | 36 + vpsManagement/views.py | 164 +++ vpsManagement/vpsManager.py | 660 ++++++++++ .../websiteFunctions/createWebsite.html | 1 - 152 files changed, 13102 insertions(+), 89 deletions(-) create mode 100755 CyberTronAPI/CyberTronLogger.py create mode 100755 CyberTronAPI/__init__.py create mode 100755 CyberTronAPI/cybertron.py create mode 100755 CyberTronAPI/hashPassword.py create mode 100755 CyberTronAPI/logLevel.py create mode 100755 CyberTronAPI/randomPassword.py create mode 100755 CyberTronAPI/sslUtilities.py create mode 100755 CyberTronAPI/test.py create mode 100755 CyberTronAPI/virtualMachineAPI.py create mode 100755 CyberTronAPI/virtualMachineAPIKVM.py create mode 100755 CyberTronAPI/virtualMachineAPIOpenVZ.py create mode 100644 backup/templates/backup/createSnapshots.html create mode 100644 baseTemplate/templates/baseTemplate/homePageVMM.html create mode 100644 baseTemplate/templates/baseTemplate/indexVMM.html create mode 100644 hypervisor/__init__.py create mode 100644 hypervisor/admin.py create mode 100644 hypervisor/apps.py create mode 100644 hypervisor/hypervisor.py create mode 100644 hypervisor/migrations/__init__.py create mode 100644 hypervisor/models.py create mode 100644 hypervisor/static/hypervisor/hypervisor.js create mode 100644 hypervisor/templates/hypervisor/createHyperVisor.html create mode 100644 hypervisor/templates/hypervisor/indexVMM.html create mode 100644 hypervisor/templates/hypervisor/listHV.html create mode 100644 hypervisor/tests.py create mode 100644 hypervisor/urls.py create mode 100644 hypervisor/views.py create mode 100644 ipManagement/__init__.py create mode 100644 ipManagement/admin.py create mode 100644 ipManagement/apps.py create mode 100644 ipManagement/migrations/__init__.py create mode 100644 ipManagement/models.py create mode 100644 ipManagement/static/ipManagement/ipManagement.js create mode 100644 ipManagement/templates/ipManagement/createIPPool.html create mode 100644 ipManagement/templates/ipManagement/indexVMM.html create mode 100644 ipManagement/templates/ipManagement/listIPPools.html create mode 100644 ipManagement/tests.py create mode 100644 ipManagement/urls.py create mode 100644 ipManagement/views.py create mode 100644 packages/templates/packages/createPackageVMM.html create mode 100644 packages/templates/packages/deletePackageVMM.html create mode 100644 packages/templates/packages/indexVMM.html create mode 100644 packages/templates/packages/modifyPackageVMM.html mode change 100644 => 100755 plogical/.my.cnf.4370 mode change 100644 => 100755 plogical/.mysql.4370 mode change 100644 => 100755 plogical/CyberCPLogFileWriter.py mode change 100644 => 100755 plogical/__init__.py mode change 100644 => 100755 plogical/acl.py create mode 100755 plogical/aclVMM.py mode change 100644 => 100755 plogical/adminPass.py mode change 100644 => 100755 plogical/alias.py mode change 100644 => 100755 plogical/applicationInstaller.py mode change 100644 => 100755 plogical/backupManager.py mode change 100644 => 100755 plogical/backupSchedule.py mode change 100644 => 100755 plogical/backupScheduleLocal.py mode change 100644 => 100755 plogical/backupUtilities.py mode change 100644 => 100755 plogical/childDomain.py mode change 100644 => 100755 plogical/dnsUtilities.py mode change 100644 => 100755 plogical/domain.xml mode change 100644 => 100755 plogical/filemanager.py mode change 100644 => 100755 plogical/findBWUsage.py mode change 100644 => 100755 plogical/firewallManager.py mode change 100644 => 100755 plogical/firewallUtilities.py mode change 100644 => 100755 plogical/ftpUtilities.py mode change 100644 => 100755 plogical/getSystemInformation.py mode change 100644 => 100755 plogical/hashPassword.py mode change 100644 => 100755 plogical/installUtilities.py mode change 100644 => 100755 plogical/letsEncrypt.py mode change 100644 => 100755 plogical/mailUtilities.py mode change 100644 => 100755 plogical/modSec.py mode change 100644 => 100755 plogical/mysqlUtilities.py mode change 100644 => 100755 plogical/phpUtilities.py mode change 100644 => 100755 plogical/processUtilities.py mode change 100644 => 100755 plogical/randomPassword.py mode change 100644 => 100755 plogical/remoteBackup.py mode change 100644 => 100755 plogical/remoteTransferUtilities.py mode change 100644 => 100755 plogical/serverLogs.py mode change 100644 => 100755 plogical/sslUtilities.py mode change 100644 => 100755 plogical/test.py mode change 100644 => 100755 plogical/tuning.py mode change 100644 => 100755 plogical/upgrade.py mode change 100644 => 100755 plogical/vhost.py mode change 100644 => 100755 plogical/virtualHostUtilities.py mode change 100644 => 100755 plogical/website.py create mode 100644 static/hypervisor/hypervisor.js create mode 100644 static/ipManagement/ipManagement.js create mode 100644 static/vpsManagement/backup.png create mode 100644 static/vpsManagement/changePassword.png create mode 100644 static/vpsManagement/close-32.png create mode 100644 static/vpsManagement/console.png create mode 100644 static/vpsManagement/delete.png create mode 100644 static/vpsManagement/hostname.png create mode 100644 static/vpsManagement/install.png create mode 100644 static/vpsManagement/pnotify.custom.min.css create mode 100644 static/vpsManagement/pnotify.custom.min.js create mode 100644 static/vpsManagement/powerOff.png create mode 100644 static/vpsManagement/restart.png create mode 100644 static/vpsManagement/settings-gears.png create mode 100644 static/vpsManagement/snapshots.png create mode 100644 static/vpsManagement/vpsManagement.js create mode 100644 static/vpsManagement/vpsON.png create mode 100644 static/vpsManagement/vpsOff.png create mode 100644 vpsManagement/__init__.py create mode 100644 vpsManagement/admin.py create mode 100644 vpsManagement/apps.py create mode 100644 vpsManagement/migrations/__init__.py create mode 100644 vpsManagement/models.py create mode 100644 vpsManagement/static/vpsManagement/backup.png create mode 100644 vpsManagement/static/vpsManagement/changePassword.png create mode 100644 vpsManagement/static/vpsManagement/close-32.png create mode 100644 vpsManagement/static/vpsManagement/console.png create mode 100644 vpsManagement/static/vpsManagement/delete.png create mode 100644 vpsManagement/static/vpsManagement/hostname.png create mode 100644 vpsManagement/static/vpsManagement/install.png create mode 100644 vpsManagement/static/vpsManagement/pnotify.custom.min.css create mode 100644 vpsManagement/static/vpsManagement/pnotify.custom.min.js create mode 100644 vpsManagement/static/vpsManagement/powerOff.png create mode 100644 vpsManagement/static/vpsManagement/restart.png create mode 100644 vpsManagement/static/vpsManagement/settings-gears.png create mode 100644 vpsManagement/static/vpsManagement/snapshots.png create mode 100644 vpsManagement/static/vpsManagement/vpsManagement.js create mode 100644 vpsManagement/static/vpsManagement/vpsON.png create mode 100644 vpsManagement/static/vpsManagement/vpsOff.png create mode 100644 vpsManagement/templates/vpsManagement/createVPS.html create mode 100644 vpsManagement/templates/vpsManagement/indexVMM.html create mode 100644 vpsManagement/templates/vpsManagement/listVPS.html create mode 100644 vpsManagement/templates/vpsManagement/manageVPS.html create mode 100644 vpsManagement/templates/vpsManagement/sshKeys.html create mode 100644 vpsManagement/tests.py create mode 100644 vpsManagement/urls.py create mode 100644 vpsManagement/views.py create mode 100644 vpsManagement/vpsManager.py diff --git a/CyberCP/settings.py b/CyberCP/settings.py index 20c3aba70..a28cda9eb 100644 --- a/CyberCP/settings.py +++ b/CyberCP/settings.py @@ -24,7 +24,7 @@ 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 = ['*'] @@ -58,8 +58,12 @@ INSTALLED_APPS = [ 'manageSSL', 'api', 'filemanager', - 'manageServices', 'emailPremium', + 'manageServices', + 'ipManagement', + 'vpsManagement', + 'hypervisor' + ] MIDDLEWARE = [ diff --git a/CyberCP/urls.py b/CyberCP/urls.py index 3780c7b72..1c7b2c2f8 100644 --- a/CyberCP/urls.py +++ b/CyberCP/urls.py @@ -37,4 +37,7 @@ urlpatterns = [ url(r'^filemanager/',include('filemanager.urls')), url(r'^emailPremium/',include('emailPremium.urls')), url(r'^manageservices/',include('manageServices.urls')), + url(r'^ip/', include('ipManagement.urls')), + url(r'^vps/',include('vpsManagement.urls')), + url(r'^hv/',include('hypervisor.urls')), ] diff --git a/CyberTronAPI/CyberTronLogger.py b/CyberTronAPI/CyberTronLogger.py new file mode 100755 index 000000000..f38b111c8 --- /dev/null +++ b/CyberTronAPI/CyberTronLogger.py @@ -0,0 +1,35 @@ +import subprocess +import time + +class CyberTronLogger: + fileName = "/home/cyberpanel/error-logs.txt" + operationsLogFile = "/home/cyberpanel/error-logs.txt" + + @staticmethod + def writeToFile(message,level,method): + try: + file = open(CyberTronLogger.fileName,'a') + file.writelines("[" + time.strftime( + "%I-%M-%S-%a-%b-%Y") + "] [" + level + ":" + method + "] " + message + "\n") + file.close() + file.close() + except IOError: + return "Can not write to error file!" + + @staticmethod + def operationsLog(message,level,method): + try: + file = open(CyberTronLogger.operationsLogFile, 'a') + file.writelines("[" + time.strftime( + "%I-%M-%S-%a-%b-%Y") + "] [" + level + ":"+ method + "] " + message + "\n") + file.close() + except IOError: + return "Can not write to error file!" + + @staticmethod + def readLastNFiles(numberOfLines,fileName): + try: + lastFewLines = subprocess.check_output(["tail", "-n",str(numberOfLines),fileName]) + return lastFewLines + except subprocess.CalledProcessError: + return "File was empty!" \ No newline at end of file diff --git a/CyberTronAPI/__init__.py b/CyberTronAPI/__init__.py new file mode 100755 index 000000000..e69de29bb diff --git a/CyberTronAPI/cybertron.py b/CyberTronAPI/cybertron.py new file mode 100755 index 000000000..ffa424b3d --- /dev/null +++ b/CyberTronAPI/cybertron.py @@ -0,0 +1,489 @@ +#!/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 CyberTronLogger import CyberTronLogger as logger +from inspect import stack +from shlex import split +from subprocess import call,CalledProcessError +from os.path import join +from random import randint +from logLevel import logLevel +from ipManagement.models import IPAddresses +from packages.models import VMPackage as Package +from django.db.models import Max +import CyberTronAPI.randomPassword as randomPassword +from vpsManagement.models import VPS, SSHKeys +from loginSystem.models import Administrator +from CyberTronAPI.virtualMachineAPIKVM import virtualMachineAPI +import plogical.CyberCPLogFileWriter as logging +from os import remove + + +class CyberTron(multi.Thread): + imagesPath = join('/var', 'lib', 'libvirt', 'images') + templatesPath = join('/var', 'lib', 'libvirt', 'templates') + + def __init__(self, data): + multi.Thread.__init__(self) + self.data = data + + def run(self): + try: + self.createVirtualMachine(self.data) + except BaseException, msg: + logger.writeToFile(str(msg), "Error", stack()[0][3]) + + def setupNetworkingFiles(self, ipAddress, osName, ipPool, hostName, tempStatusPath): + try: + + if logLevel.debug == True: + logger.operationsLog('Setting up network for: ' + ipAddress + '.', 'Debug', stack()[0][3]) + + uploadSource = [] + + ## Set Device name + deviceName = '' + + if osName == 'centos-6': + deviceName = 'eth0' + elif osName == 'centos-7.2': + deviceName = 'ens3' + elif osName == 'debian-9' or osName == 'ubuntu-16.04': + deviceName = 'ens3' + + + if osName.find("centos") > -1: + ###### /etc/sysconfig/network-scripts/ifcfg-eth0 + + eth0 = "/home/cyberpanel/ifcfg-ens3" + str(randint(10000, 99999)) + eth0File = open(eth0, 'w') + + eth0File.writelines('DEVICE="' + deviceName + '"\n') + eth0File.writelines('NM_CONTROLLED="yes"\n') + eth0File.writelines('ONBOOT=yes\n') + eth0File.writelines('TYPE=Ethernet\n') + eth0File.writelines('BOOTPROTO=static\n') + eth0File.writelines('NAME="System ' + deviceName + '"\n') + eth0File.writelines('IPADDR=' + ipAddress + '\n') + eth0File.writelines('NETMASK=' + ipPool.netmask + '\n') + + eth0File.close() + + uploadSource.append(eth0) + + ###### /etc/sysconfig/network + + network = "/home/cyberpanel/network_" + str(randint(10000, 99999) + 1) + networkFile = open(network, 'w') + + networkFile.writelines('NETWORKING=yes\n') + networkFile.writelines('HOSTNAME=' + hostName + '\n') + networkFile.writelines('GATEWAY=' + ipPool.gateway + '\n') + + networkFile.close() + + uploadSource.append(network) + + ###### /etc/resolv.conf + + resolv = "/home/cyberpanel/resolv_" + str(randint(10000, 99999) + 2) + resolvFile = open(resolv, 'w') + + resolvFile.writelines("nameserver 8.8.8.8\n") + + resolvFile.close() + + uploadSource.append(resolv) + elif osName == 'ubuntu-18.04': + + eth0 = "/home/cyberpanel/interfaces_" + str(randint(10000, 99999)) + eth0File = open(eth0, 'w') + + eth0File.writelines('# This file describes the network interfaces available on your system\n') + eth0File.writelines('# For more information, see netplan(5).\n') + + eth0File.writelines('\n') + + eth0File.writelines('network:\n') + eth0File.writelines(' version: 2\n') + eth0File.writelines(' renderer: networkd\n') + eth0File.writelines(' ethernets:\n') + eth0File.writelines(' ens2:\n') + eth0File.writelines(' dhcp4: yes\n') + eth0File.writelines(' ens3:\n') + eth0File.writelines(' dhcp4: no\n') + eth0File.writelines(' addresses: [' + ipAddress + '/24]\n') + eth0File.writelines(' gateway4: ' + ipPool.gateway + '\n') + eth0File.writelines(' nameservers:\n') + eth0File.writelines(' addresses: [8.8.8.8,8.8.4.4]\n') + + eth0File.writelines('\n') + + eth0File.close() + + uploadSource.append(eth0) + elif osName.find("debian") > -1 or osName.find("ubuntu") > -1: + ###### ip + + eth0 = "/home/cyberpanel/interfaces_" + str(randint(10000, 99999)) + eth0File = open(eth0, 'w') + + eth0File.writelines('# This file describes the network interfaces available on your system\n') + eth0File.writelines('# and how to activate them. For more information, see interfaces(5).\n') + + eth0File.writelines('\n') + + eth0File.writelines('# The loopback network interface\n') + eth0File.writelines('auto lo\n') + eth0File.writelines('iface lo inet loopback\n') + + eth0File.writelines('\n') + + ## To deal with Debian 9.3 and ubuntu 16.04 issue. + + eth0File.writelines('# The primary network interface\n') + + + eth0File.writelines('allow-hotplug ' + deviceName + '\n') + eth0File.writelines('iface ' + deviceName + ' inet static\n') + + + eth0File.writelines(' address ' + ipAddress + '\n') + eth0File.writelines(' netmask ' + ipPool.netmask + '\n') + eth0File.writelines(' gateway ' + ipPool.gateway + '\n') + eth0File.writelines('# dns-* options are implemented by the resolvconf package, if installed\n') + eth0File.writelines('dns-nameservers 8.8.8.8\n') + eth0File.writelines('dns-search com\n') + + eth0File.close() + + uploadSource.append(eth0) + elif osName.find("fedora") > -1: + + ###### /etc/sysconfig/network-scripts/ifcfg-ens3 + + eth0 = "/home/cyberpanel/interfaces_" + str(randint(10000, 99999)) + eth0File = open(eth0, 'w') + + eth0File.writelines('TYPE=Ethernet\n') + eth0File.writelines('PROXY_METHOD=none\n') + + eth0File.writelines('BROWSER_ONLY=no\n') + eth0File.writelines('BOOTPROTO=none\n') + eth0File.writelines('DEFROUTE=yes\n') + + eth0File.writelines('IPV4_FAILURE_FATAL=no\n') + eth0File.writelines('IPV6INIT=yes\n') + eth0File.writelines('IPV6_AUTOCONF=yes\n') + + eth0File.writelines('IPV6_DEFROUTE=yes\n') + eth0File.writelines('IPV6_FAILURE_FATAL=no\n') + eth0File.writelines('IPV6_ADDR_GEN_MODE=stable-privacy\n') + eth0File.writelines('NAME=ens3\n') + eth0File.writelines('ONBOOT=yes\n') + eth0File.writelines('AUTOCONNECT_PRIORITY=-999\n') + + eth0File.writelines('DEVICE=ens3\n') + eth0File.writelines('IPADDR=' + ipAddress + '\n') + eth0File.writelines('NETMASK=' + ipPool.netmask + '\n') + eth0File.writelines('GATEWAY=' + ipPool.gateway + '\n') + eth0File.writelines('DNS1=8.8.8.8\n') + eth0File.writelines('IPV6_PRIVACY=no\n') + + eth0File.close() + uploadSource.append(eth0) + elif osName.find("freebsd") > -1: + + ###### /etc/rc.conf + + eth0 = "/home/cyberpanel/ifcfg-eth0_" + str(randint(10000, 99999)) + eth0File = open(eth0, 'w') + + eth0File.writelines('DEVICE="eth0"\n') + eth0File.writelines('NM_CONTROLLED="yes"\n') + eth0File.writelines('ONBOOT=yes\n') + eth0File.writelines('TYPE=Ethernet\n') + eth0File.writelines('BOOTPROTO=static\n') + eth0File.writelines('NAME="System eth0"\n') + eth0File.writelines('IPADDR=' + ipAddress + '\n') + eth0File.writelines('NETMASK=' + ipPool.gateway + '\n') + + eth0File.close() + + uploadSource.append(eth0) + if logLevel.debug == True: + logger.operationsLog('Network settings installed for: ' + ipAddress + '.', 'Debug', stack()[0][3]) + + return uploadSource + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, str(msg) + ' [404]') + return 0 + + def buildCustomDisk(self, vmName, osName, size, rootPassword, uploadCommand, tempStatusPath): + try: + + sourcePath = join(virtualMachineAPI.templatesPath, osName + ".img") + tempPath = join(virtualMachineAPI.imagesPath, vmName + "-temp.qcow2") + finalPath = join(virtualMachineAPI.imagesPath, vmName + ".qcow2") + + ## Creating temporary disk image. + + command = "sudo cp " + sourcePath + " " + tempPath + result = call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Temporary image created for: " + vmName + ".", "Debug", stack()[0][3]) + + command = "sudo qemu-img create -f qcow2 " + finalPath + " " + size + result = call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Created resized final image for: " + vmName + ".", "Debug", stack()[0][3]) + + command = "sudo virt-resize --expand /dev/sda1 " + tempPath + " " + finalPath + result = call(split(command)) + + if result == 1: + remove(tempPath) + raise CalledProcessError + else: + remove(tempPath) + + if logLevel.debug == True: + logger.operationsLog("Disk resized and ready to use for: " + vmName + ".", "Debug", + stack()[0][3]) + + command = "sudo virt-customize -a " + finalPath + " --root-password password:" + rootPassword + uploadCommand + call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Root password and network configured for: " + vmName + ".", "Debug", + stack()[0][3]) + return 1 + + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, str(msg) + ' [404]') + return 0 + + def setupVMDisk(self, vmName, osName, uploadSource, rootPassword, package, tempStatusPath, sshKey = None): + try: + size = package.diskSpace + 'G' + + if osName.find('centos') > -1: + uploadCommand = " --upload " + uploadSource[0] + ":" + "/etc/sysconfig/network-scripts/ifcfg-eth0" + uploadCommand = uploadCommand + " --upload " + uploadSource[1] + ":" + "/etc/sysconfig/network" + uploadCommand = uploadCommand + " --upload " + uploadSource[2] + ":" + "/etc/resolv.conf" + elif osName == 'ubuntu-18.04': + uploadCommand = " --upload " + uploadSource[0] + ":" + "/etc/netplan/01-netcfg.yaml --firstboot-command 'dpkg-reconfigure openssh-server'" + elif osName.find('debian') > -1 or osName.find('ubuntu') > -1: + uploadCommand = " --upload " + uploadSource[0] + ":" + "/etc/network/interfaces --firstboot-command 'ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key && ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key && ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key'" + elif osName.find('fedora') > -1: + uploadCommand = " --upload " + uploadSource[0] + ":" + "/etc/sysconfig/network-scripts/ifcfg-ens3" + + finalImageLocation = join(CyberTron.imagesPath, vmName + '.qcow2') + + ## "virt-builder centos-7.1 -o /var/lib/libvirt/images192.168.100.1.qcow2 --size 50G --format qcow2 --upload ifcfg-eth0:/etc/sysconfig/network-scripts/ --upload network:/etc/sysconfig + + if osName == 'debian-9' or osName == 'fedora-28' or osName == 'ubuntu-16.04': + self.buildCustomDisk(vmName, osName, size, rootPassword, uploadCommand, tempStatusPath) + else: + if sshKey != None: + command = "sudo virt-builder " + osName + " -o " + finalImageLocation + " --size " + size + \ + " --format qcow2 --root-password password:" + rootPassword + uploadCommand + " --ssh-inject 'root:string:" + sshKey + "'" + else: + command = "sudo virt-builder " + osName + " -o " + finalImageLocation + " --size " + size + \ + " --format qcow2 --root-password password:" + rootPassword + uploadCommand + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Disk image created for: " + vmName + ".", "Debug", stack()[0][3]) + + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, str(msg) + ' [404]') + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, str(msg) + ' [404]') + return 0 + + def bootVirtualMachine(self, package, vmName, vncHost, vncPort, vncPassword, webSocketPort, hostname, bridgeName, tempStatusPath): + try: + + if logLevel.debug == True: + logger.operationsLog('Booting: ' + vmName + '.', 'Debug', stack()[0][3]) + + finalImageLocation = join(CyberTron.imagesPath, vmName + ".qcow2") + + # virt-install --name 109.238.12.214 --ram 2048 --vcpus=1 --disk 109.238.12.214.qcow2 --graphics vnc,listen=localhost,port=5500 --noautoconsole --hvm --import --os-type=linux --os-variant=rhel7 --network bridge=virbr0 + + command = "sudo virt-install --name " + hostname + " --ram " + str(package.guaranteedRam) + " --vcpu " + str(package.cpuCores) + " --disk " + \ + finalImageLocation + " --graphics vnc,listen=" + vncHost + ",port=" + vncPort + ",password=" + vncPassword + \ + " --noautoconsole --hvm --import --autostart --os-type=linux " \ + + "--network bridge=" + bridgeName + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Successfully booted: " + vmName + ".", "Debug", stack()[0][3]) + + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, str(msg) + ' [404]') + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, str(msg) + ' [404]') + return 0 + + def createVirtualMachine(self, data): + try: + + osName = data['osName'] + vpsPackage = data['vpsPackage'] + vpsOwner = data['vpsOwner'] + vpsIP = data['vpsIP'] + hostname = data['hostname'] + rootPassword = data['rootPassword'] + networkSpeed = data['networkSpeed'] + + logging.CyberCPLogFileWriter.statusWriter(data['tempStatusPath'], 'Running some checks..,0') + + try: + sshKey = data['sshKey'] + key = SSHKeys.objects.get(keyName=sshKey) + sshKey = key.key + except: + sshKey = None + + + owner = Administrator.objects.get(userName=vpsOwner) + package = Package.objects.get(packageName=vpsPackage) + ip = IPAddresses.objects.get(ipAddr=vpsIP) + + ## Some checks + + if ip.used == 1: + logging.CyberCPLogFileWriter.statusWriter(data['tempStatusPath'], 'This IP is already in use. [404]') + return 0, 'This IP is already in use.' + + if VPS.objects.filter(hostName=hostname).count() > 0: + logging.CyberCPLogFileWriter.statusWriter(data['tempStatusPath'], 'Hostname is already taken. [404]') + return 0, 'Hostname is already taken.' + + logging.CyberCPLogFileWriter.statusWriter(data['tempStatusPath'], 'Starting to create virtual machine..,10') + + logger.operationsLog('Starting to create virtual machine: ' + vpsIP, 'Info', stack()[0][3]) + + ## + + uploadSource = self.setupNetworkingFiles(vpsIP, osName, ip.pool, hostname, data['tempStatusPath']) + + ## + + logging.CyberCPLogFileWriter.statusWriter(data['tempStatusPath'], + 'Creating virtual machine disk..,20') + + if self.setupVMDisk(hostname, osName, uploadSource, rootPassword, package, data['tempStatusPath'], sshKey) == 0: + logging.CyberCPLogFileWriter.statusWriter(data['tempStatusPath'], 'Failed to setup virtual machine disk. [404]') + return 0 + + logging.CyberCPLogFileWriter.statusWriter(data['tempStatusPath'], + 'Booting virtual machine..,80') + + ## Server IP + + ipFile = "/etc/cyberpanel/machineIP" + f = open(ipFile) + ipData = f.read() + vncHost = ipData.split('\n', 1)[0] + + ## Finding VNC Port + if VPS.objects.count() == 0: + vncPort = 5900 + webSocketPort = 0 + else: + vncPort = VPS.objects.all().aggregate(Max('vncPort'))['vncPort__max'] + 1 + webSocketPort = VPS.objects.count() + + vncPassword = randomPassword.generate_pass(50) + + if self.bootVirtualMachine(package, hostname, vncHost, str(vncPort), vncPassword, str(webSocketPort), hostname, 'virbr0', data['tempStatusPath']) == 0: + logging.CyberCPLogFileWriter.statusWriter(data['tempStatusPath'], 'Failed to boot virtual machine. [404]') + return 0 + + ## Saving VM To database + + newVPS = VPS(owner=owner, ipAddr=ip, package=package, hostName=hostname, networkSpeed=networkSpeed, + vncPort=vncPort, vncPassword=vncPassword, websocketPort=webSocketPort) + newVPS.save() + ip.used = 1 + ip.save() + + ## Installing network limitations + + ## Reading interface name + + interfaceFile = "/etc/cyberpanel/interfaceName" + f = open(interfaceFile) + interfaceData = f.read() + interfaceName = interfaceData.split('\n', 1)[0] + + virtualMachineAPI.limitVMSpeed(str(newVPS.id), vpsIP, 'virbr0', networkSpeed) + logging.CyberCPLogFileWriter.statusWriter(data['tempStatusPath'], 'Virtual Machine successfully created.. [200]') + + logger.operationsLog('Virtual machine ' + vpsIP + ' successfully created.', 'Success', stack()[0][3]) + + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + logging.CyberCPLogFileWriter.statusWriter(data['tempStatusPath'], str(msg) + ' [404]') + return 0 + diff --git a/CyberTronAPI/hashPassword.py b/CyberTronAPI/hashPassword.py new file mode 100755 index 000000000..b360186fe --- /dev/null +++ b/CyberTronAPI/hashPassword.py @@ -0,0 +1,13 @@ +import uuid +import hashlib + + +def hash_password(password): + # uuid is used to generate a random number + salt = uuid.uuid4().hex + return hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ':' + salt + + +def check_password(hashed_password, user_password): + password, salt = hashed_password.split(':') + return password == hashlib.sha256(salt.encode() + user_password.encode()).hexdigest() \ No newline at end of file diff --git a/CyberTronAPI/logLevel.py b/CyberTronAPI/logLevel.py new file mode 100755 index 000000000..dc9ac62f8 --- /dev/null +++ b/CyberTronAPI/logLevel.py @@ -0,0 +1,2 @@ +class logLevel: + debug = False \ No newline at end of file diff --git a/CyberTronAPI/randomPassword.py b/CyberTronAPI/randomPassword.py new file mode 100755 index 000000000..2eb292e45 --- /dev/null +++ b/CyberTronAPI/randomPassword.py @@ -0,0 +1,38 @@ +from os import urandom +from random import choice + +char_set = {'small': 'abcdefghijklmnopqrstuvwxyz', + 'nums': '0123456789', + 'big': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + } + + +def generate_pass(length=14): + """Function to generate a password""" + + password = [] + + while len(password) < length: + key = choice(char_set.keys()) + a_char = urandom(1) + if a_char in char_set[key]: + if check_prev_char(password, char_set[key]): + continue + else: + password.append(a_char) + return ''.join(password) + + +def check_prev_char(password, current_char_set): + """Function to ensure that there are no consecutive + UPPERCASE/lowercase/numbers/special-characters.""" + + index = len(password) + if index == 0: + return False + else: + prev_char = password[index - 1] + if prev_char in current_char_set: + return True + else: + return False \ No newline at end of file diff --git a/CyberTronAPI/sslUtilities.py b/CyberTronAPI/sslUtilities.py new file mode 100755 index 000000000..bae2d6830 --- /dev/null +++ b/CyberTronAPI/sslUtilities.py @@ -0,0 +1,341 @@ +import CyberCPLogFileWriter as logging +import shutil +import os +import shlex +import subprocess +import socket + +class sslUtilities: + + Server_root = "/usr/local/lsws" + + @staticmethod + def checkIfSSLMap(virtualHostName): + try: + data = open("/usr/local/lsws/conf/httpd_config.conf").readlines() + + sslCheck = 0 + + for items in data: + if items.find("listener") >-1 and items.find("SSL") > -1: + sslCheck = 1 + continue + if sslCheck == 1: + if items.find("}") > -1: + return 0 + if items.find(virtualHostName) > -1 and sslCheck == 1: + data = filter(None, items.split(" ")) + if data[1] == virtualHostName: + return 1 + + except BaseException,msg: + logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [IO Error with main config file [checkIfSSLMap]]") + return 0 + + + @staticmethod + def installSSLForDomain(virtualHostName): + + + pathToStoreSSL = sslUtilities.Server_root + "/conf/vhosts/" + "SSL-" + virtualHostName + + confPath = sslUtilities.Server_root + "/conf/vhosts/" + virtualHostName + completePathToConfigFile = confPath + "/vhost.conf" + + try: + map = " map " + virtualHostName + " " + virtualHostName + "\n" + + if sslUtilities.checkSSLListener()!=1: + + writeDataToFile = open("/usr/local/lsws/conf/httpd_config.conf", 'a') + + listener = "listener SSL {" + "\n" + address = " address *:443" + "\n" + secure = " secure 1" + "\n" + keyFile = " keyFile " + pathToStoreSSL + "/privkey.pem" + "\n" + certFile = " certFile " + pathToStoreSSL + "/fullchain.pem" + "\n" + certChain = " certChain 1" + "\n" + sslProtocol = " sslProtocol 30" + "\n" + map = " map " + virtualHostName + " " + virtualHostName + "\n" + final = "}" + "\n" + "\n" + + writeDataToFile.writelines("\n") + writeDataToFile.writelines(listener) + writeDataToFile.writelines(address) + writeDataToFile.writelines(secure) + writeDataToFile.writelines(keyFile) + writeDataToFile.writelines(certFile) + writeDataToFile.writelines(certChain) + writeDataToFile.writelines(sslProtocol) + writeDataToFile.writelines(map) + writeDataToFile.writelines(final) + writeDataToFile.writelines("\n") + writeDataToFile.close() + + + else: + + if sslUtilities.checkIfSSLMap(virtualHostName) == 0: + + data = open("/usr/local/lsws/conf/httpd_config.conf").readlines() + writeDataToFile = open("/usr/local/lsws/conf/httpd_config.conf", 'w') + sslCheck = 0 + + for items in data: + if items.find("listener")>-1 and items.find("SSL") > -1: + sslCheck = 1 + + if (sslCheck == 1): + writeDataToFile.writelines(items) + writeDataToFile.writelines(map) + sslCheck = 0 + else: + writeDataToFile.writelines(items) + writeDataToFile.close() + + ###################### Write per host Configs for SSL ################### + + data = open(completePathToConfigFile,"r").readlines() + + ## check if vhssl is already in vhconf file + + vhsslPresense = 0 + + for items in data: + if items.find("vhssl")>-1: + vhsslPresense = 1 + + + if vhsslPresense == 0: + writeSSLConfig = open(completePathToConfigFile,"a") + + vhssl = "vhssl {" + "\n" + keyFile = " keyFile " + pathToStoreSSL + "/privkey.pem" + "\n" + certFile = " certFile " + pathToStoreSSL + "/fullchain.pem" + "\n" + certChain = " certChain 1" + "\n" + sslProtocol = " sslProtocol 30" + "\n" + final = "}" + + writeSSLConfig.writelines("\n") + + writeSSLConfig.writelines(vhssl) + writeSSLConfig.writelines(keyFile) + writeSSLConfig.writelines(certFile) + writeSSLConfig.writelines(certChain) + writeSSLConfig.writelines(sslProtocol) + writeSSLConfig.writelines(final) + + + writeSSLConfig.writelines("\n") + + writeSSLConfig.close() + + return 1 + + except BaseException,msg: + logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [installSSLForDomain]]") + return 0 + + + @staticmethod + def checkSSLListener(): + try: + data = open("/usr/local/lsws/conf/httpd_config.conf").readlines() + for items in data: + if items.find("listener SSL") > -1: + return 1 + + except BaseException,msg: + logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [IO Error with main config file [checkSSLListener]]") + return str(msg) + return 0 + + @staticmethod + def getDNSRecords(virtualHostName): + try: + + withoutWWW = socket.gethostbyname(virtualHostName) + withWWW = socket.gethostbyname('www.' + virtualHostName) + + return [1, withWWW, withoutWWW] + + except BaseException, msg: + return [0, "347 " + str(msg) + " [issueSSLForDomain]"] + + + @staticmethod + def obtainSSLForADomain(virtualHostName,adminEmail,sslpath, aliasDomain = None): + try: + + ## Obtaining Server IP + + ipFile = "/etc/cyberpanel/machineIP" + f = open(ipFile) + ipData = f.read() + serverIPAddress = ipData.split('\n', 1)[0] + + ## Obtaining Domain IPs + + if aliasDomain == None: + + ipRecords = sslUtilities.getDNSRecords(virtualHostName) + + + if ipRecords[0] == 1: + + if serverIPAddress == ipRecords[1] and serverIPAddress == ipRecords[2]: + command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + " -d www." + virtualHostName + logging.CyberCPLogFileWriter.writeToFile( + "SSL successfully issued for domain : " + virtualHostName + " and www." + virtualHostName) + else: + if serverIPAddress == ipRecords[2]: + command = "certbot certonly -n --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + logging.CyberCPLogFileWriter.writeToFile( + "SSL is issued without 'www' due to DNS error for domain : " + virtualHostName) + else: + logging.CyberCPLogFileWriter.writeToFile( + "DNS Records for " + virtualHostName + " does not point to this server, issuing self signed certificate.") + return 0 + else: + logging.CyberCPLogFileWriter.writeToFile( + "Failed to obtain DNS records for " + virtualHostName + ", issuing self signed certificate.") + return 0 + + else: + + ipRecords = sslUtilities.getDNSRecords(virtualHostName) + + if ipRecords[0] == 1: + + if serverIPAddress == ipRecords[1] and serverIPAddress == ipRecords[2]: + + ipRecordsAlias = sslUtilities.getDNSRecords(aliasDomain) + + if serverIPAddress == ipRecordsAlias[1] and serverIPAddress == ipRecordsAlias[2]: + + command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + " -d www." + virtualHostName + " -d " + aliasDomain + " -d www." + aliasDomain + + else: + if serverIPAddress == ipRecordsAlias[2]: + command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + " -d www." + virtualHostName + " -d " + aliasDomain + else: + command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + " -d www." + virtualHostName + + else: + if serverIPAddress == ipRecords[2]: + + ipRecordsAlias = sslUtilities.getDNSRecords(aliasDomain) + + if serverIPAddress == ipRecordsAlias[1] and serverIPAddress == ipRecordsAlias[2]: + + command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + " -d " + aliasDomain + " -d www." + aliasDomain + + else: + if serverIPAddress == ipRecordsAlias[2]: + command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + " -d " + aliasDomain + else: + command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + + logging.CyberCPLogFileWriter.writeToFile( + "SSL is issued without 'www' due to DNS error for domain : " + virtualHostName) + else: + + ipRecordsAlias = sslUtilities.getDNSRecords(aliasDomain) + + if serverIPAddress == ipRecordsAlias[1] and serverIPAddress == ipRecordsAlias[2]: + command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + aliasDomain + " -d www." + aliasDomain + else: + if serverIPAddress == ipRecordsAlias[2]: + command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + aliasDomain + else: + return 0 + else: + logging.CyberCPLogFileWriter.writeToFile( + "Failed to obtain DNS records for " + virtualHostName + ", issuing self signed certificate.") + return 0 + + ## SSL Paths + + + pathToStoreSSL = sslUtilities.Server_root + "/conf/vhosts/" + "SSL-" + virtualHostName + + if not os.path.exists(pathToStoreSSL): + os.mkdir(pathToStoreSSL) + + pathToStoreSSLPrivKey = pathToStoreSSL + "/privkey.pem" + pathToStoreSSLFullChain = pathToStoreSSL + "/fullchain.pem" + + + ## + + output = subprocess.check_output(shlex.split(command)) + + data = output.split('\n') + + if output.find('Congratulations!') > -1: + + ###### Copy SSL To config location ###### + + + for items in data: + if items.find(virtualHostName) > -1 and items.find('fullchain.pem') > -1: + srcFullChain = items.strip(' ') + elif items.find(virtualHostName) > -1 and items.find('privkey.pem') > -1: + srcPrivKey = items.strip(' ') + + + if os.path.exists(pathToStoreSSLPrivKey): + os.remove(pathToStoreSSLPrivKey) + if os.path.exists(pathToStoreSSLFullChain): + os.remove(pathToStoreSSLFullChain) + + shutil.copy(srcPrivKey, pathToStoreSSLPrivKey) + shutil.copy(srcFullChain, pathToStoreSSLFullChain) + + return 1 + + elif output.find('no action taken.') > -1: + return 1 + elif output.find('Failed authorization procedure') > -1: + logging.CyberCPLogFileWriter.writeToFile('Failed authorization procedure for ' + virtualHostName + " while issuing Let's Encrypt SSL.") + return 0 + elif output.find('Too many SSL requests for this domain, please try to get SSL at later time.') > -1: + logging.CyberCPLogFileWriter.writeToFile( + 'Too many SSL requests for ' + virtualHostName + " please try to get SSL at later time.") + return 0 + + except BaseException,msg: + logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [Failed to obtain SSL. [obtainSSLForADomain]]") + return 0 + + +def issueSSLForDomain(domain,adminEmail,sslpath, aliasDomain = None): + try: + + if sslUtilities.obtainSSLForADomain(domain, adminEmail, sslpath, aliasDomain) == 1: + + if sslUtilities.installSSLForDomain(domain) == 1: + return [1, "None"] + else: + return [0, "210 Failed to install SSL for domain. [issueSSLForDomain]"] + else: + pathToStoreSSL = sslUtilities.Server_root + "/conf/vhosts/" + "SSL-" + domain + + if not os.path.exists(pathToStoreSSL): + os.mkdir(pathToStoreSSL) + + pathToStoreSSLPrivKey = pathToStoreSSL + "/privkey.pem" + pathToStoreSSLFullChain = pathToStoreSSL + "/fullchain.pem" + + command = 'openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -keyout ' + pathToStoreSSLPrivKey + ' -out ' + pathToStoreSSLFullChain + cmd = shlex.split(command) + subprocess.call(cmd) + + if sslUtilities.installSSLForDomain(domain) == 1: + logging.CyberCPLogFileWriter.writeToFile("Self signed SSL issued for " + domain + ".") + return [1, "None"] + else: + return [0, "220 Failed to install SSL for domain. [issueSSLForDomain]"] + + except BaseException,msg: + return [0, "347 "+ str(msg)+ " [issueSSLForDomain]"] diff --git a/CyberTronAPI/test.py b/CyberTronAPI/test.py new file mode 100755 index 000000000..3cdf320f0 --- /dev/null +++ b/CyberTronAPI/test.py @@ -0,0 +1,29 @@ +#!/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 CyberTronLogger import CyberTronLogger as logger +from inspect import stack +from shlex import split +from subprocess import call,CalledProcessError +from os.path import join +from random import randint +from logLevel import logLevel +from ipManagement.models import IPAddresses +from packages.models import VMPackage as Package +from django.db.models import Max +import CyberTronAPI.randomPassword as randomPassword +from vpsManagement.models import VPS +from loginSystem.models import Administrator +from CyberTronAPI.virtualMachineAPIKVM import virtualMachineAPI + + +def setupVMDisk(): + + command = 'sudo virt-builder centos-7.2 -o /var/lib/libvirt/images/199.241.188.139.qcow2 --size 100G --root-password password:9xvps --upload /home/cyberpanel/ifcfg-ens384536:/etc/sysconfig/network-scripts/ifcfg-eth0 --upload /home/cyberpanel/network_62835:/etc/sysconfig/network --upload /home/cyberpanel/resolv_80440:/etc/resolv.conf' + result = call(split(command)) + +setupVMDisk() \ No newline at end of file diff --git a/CyberTronAPI/virtualMachineAPI.py b/CyberTronAPI/virtualMachineAPI.py new file mode 100755 index 000000000..a87afba35 --- /dev/null +++ b/CyberTronAPI/virtualMachineAPI.py @@ -0,0 +1,638 @@ +from CyberTronLogger import CyberTronLogger as logger +from inspect import stack +from shlex import split +from subprocess import call,CalledProcessError +from os.path import join +from os import remove +from random import randint +from shutil import move +import libvirt +from logLevel import logLevel + +class virtualMachineAPI: + + ## os.path.join + templatesPath = join('/var','lib','libvirt','templates') + imagesPath = join('/var','lib','libvirt','images') + + + @staticmethod + def setupNetworkingFiles(vmName, osName, ipAddress, netmask, gateway, hostName): + try: + + if logLevel.debug == True: + logger.operationsLog('Setting up network for: ' + vmName + '.', 'Debug', stack()[0][3]) + + uploadSource = [] + + if osName.find("centos") > -1: + ###### /etc/sysconfig/network-scripts/ifcfg-eth0 + + eth0 = "ifcfg-eth0_" + str(randint(10000, 99999)) + eth0File = open(eth0, 'w') + + eth0File.writelines('DEVICE="eth0"\n') + eth0File.writelines('NM_CONTROLLED="yes"\n') + eth0File.writelines('ONBOOT=yes\n') + eth0File.writelines('TYPE=Ethernet\n') + eth0File.writelines('BOOTPROTO=static\n') + eth0File.writelines('NAME="System eth0"\n') + eth0File.writelines('IPADDR=' + ipAddress + '\n') + eth0File.writelines('NETMASK=' + netmask + '\n') + + eth0File.close() + + uploadSource.append(eth0) + + ###### /etc/sysconfig/network + + network = "network_" + str(randint(10000, 99999) + 1) + networkFile = open(network, 'w') + + networkFile.writelines('NETWORKING=yes\n') + networkFile.writelines('HOSTNAME=' + hostName + '\n') + networkFile.writelines('GATEWAY=' + gateway + '\n') + + networkFile.close() + + uploadSource.append(network) + + ###### /etc/resolv.conf + + resolv = "resolv_" + str(randint(10000, 99999) + 2) + resolvFile = open(resolv, 'w') + + resolvFile.writelines("nameserver 8.8.8.8\n") + + resolvFile.close() + + uploadSource.append(resolv) + elif osName.find("debian") > -1 or osName.find("ubuntu") > -1: + + ###### /etc/network/interfaces + + eth0 = "interfaces_" + str(randint(10000, 99999)) + eth0File = open(eth0, 'w') + + eth0File.writelines('# This file describes the network interfaces available on your system\n') + eth0File.writelines('# and how to activate them. For more information, see interfaces(5).\n') + + eth0File.writelines('\n') + + eth0File.writelines('# The loopback network interface\n') + eth0File.writelines('auto lo\n') + eth0File.writelines('iface lo inet loopback\n') + + eth0File.writelines('\n') + + ## To deal with Debian 9.3 and ubuntu 16.04 issue. + + eth0File.writelines('# The primary network interface\n') + + if osName == "debian-9.3.x64" or osName == "ubuntu-16.04.x32" or osName == "ubuntu-16.04.x64" or osName == "ubuntu-17.10.x64": + eth0File.writelines('allow-hotplug ens3\n') + eth0File.writelines('iface ens3 inet static\n') + else: + eth0File.writelines('allow-hotplug eth0\n') + eth0File.writelines('iface eth0 inet static\n') + + eth0File.writelines(' address '+ipAddress+'\n') + eth0File.writelines(' netmask ' + netmask +'\n') + eth0File.writelines(' gateway ' + gateway + '\n') + eth0File.writelines('# dns-* options are implemented by the resolvconf package, if installed\n') + eth0File.writelines('dns-nameservers 8.8.8.8\n') + eth0File.writelines('dns-search com\n') + + eth0File.close() + + uploadSource.append(eth0) + elif osName.find("fedora") > -1: + + ###### /etc/sysconfig/network-scripts/ifcfg-ens3 + + eth0 = "interfaces_" + str(randint(10000, 99999)) + eth0File = open(eth0, 'w') + + eth0File.writelines('TYPE=Ethernet\n') + eth0File.writelines('PROXY_METHOD=none\n') + + + eth0File.writelines('BROWSER_ONLY=no\n') + eth0File.writelines('BOOTPROTO=none\n') + eth0File.writelines('DEFROUTE=yes\n') + + + eth0File.writelines('IPV4_FAILURE_FATAL=no\n') + eth0File.writelines('IPV6INIT=yes\n') + eth0File.writelines('IPV6_AUTOCONF=yes\n') + + eth0File.writelines('IPV6_DEFROUTE=yes\n') + eth0File.writelines('IPV6_FAILURE_FATAL=no\n') + eth0File.writelines('IPV6_ADDR_GEN_MODE=stable-privacy\n') + eth0File.writelines('NAME=ens3\n') + eth0File.writelines('ONBOOT=yes\n') + eth0File.writelines('AUTOCONNECT_PRIORITY=-999\n') + + eth0File.writelines('DEVICE=ens3\n') + eth0File.writelines('IPADDR=' + ipAddress + '\n') + eth0File.writelines('NETMASK=' + netmask + '\n') + eth0File.writelines('GATEWAY=' + gateway + '\n') + eth0File.writelines('DNS1=8.8.8.8\n') + eth0File.writelines('IPV6_PRIVACY=no\n') + + eth0File.close() + uploadSource.append(eth0) + elif osName.find("freebsd") > -1: + + ###### /etc/rc.conf + + eth0 = "ifcfg-eth0_" + str(randint(10000, 99999)) + eth0File = open(eth0, 'w') + + eth0File.writelines('DEVICE="eth0"\n') + eth0File.writelines('NM_CONTROLLED="yes"\n') + eth0File.writelines('ONBOOT=yes\n') + eth0File.writelines('TYPE=Ethernet\n') + eth0File.writelines('BOOTPROTO=static\n') + eth0File.writelines('NAME="System eth0"\n') + eth0File.writelines('IPADDR=' + ipAddress + '\n') + eth0File.writelines('NETMASK=' + netmask + '\n') + + eth0File.close() + + uploadSource.append(eth0) + + if logLevel.debug == True: + logger.operationsLog('Network settings installed for: ' + vmName + '.', 'Debug', stack()[0][3]) + + return uploadSource + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + ''' + vmName = Usually IP Address. + osName = Examples operatingSystem-X.xx.x86 + uploadSource = An array containing complete path of files to be uploaded to the image after creation. + rootPassword = Virtual Machine root password. + ''' + + @staticmethod + def setupVMDisk(vmName, osName, size, uploadSource, rootPassword): + try: + + if logLevel.debug == True: + logger.operationsLog('Creating disk image for: ' + vmName + '.', 'Debug', stack()[0][3]) + + sourcePath = join(virtualMachineAPI.templatesPath,osName+".qcow2") + tempPath = join(virtualMachineAPI.imagesPath,vmName+"-temp.qcow2") + finalPath = join(virtualMachineAPI.imagesPath,vmName+".qcow2") + + ## Build upload command + + uploadCommand = "" + + if osName.find('centos') > -1: + uploadCommand = " --upload " + uploadSource[0] + ":" + "/etc/sysconfig/network-scripts/ifcfg-eth0" + uploadCommand = uploadCommand + " --upload " + uploadSource[1] + ":" + "/etc/sysconfig/network" + uploadCommand = uploadCommand + " --upload " + uploadSource[2] + ":" + "/etc/resolv.conf" + elif osName.find('debian') > -1: + uploadCommand = " --upload " + uploadSource[0] + ":" + "/etc/network/interfaces" + " --firstboot-command 'apt-get purge openssh-server -y' --firstboot-command 'apt-get install openssh-server -y'" + elif osName.find('ubuntu') > -1: + uploadCommand = " --upload " + uploadSource[0] + ":" + "/etc/network/interfaces" + " --firstboot-command 'apt-get remove openssh-server -y' --firstboot-command 'apt-get install openssh-server -y'" + elif osName.find('fedora') > -1: + uploadCommand = " --upload " + uploadSource[0] + ":" + "/etc/sysconfig/network-scripts/ifcfg-ens3" + " --firstboot-command 'yum erase openssh-server -y' --firstboot-command 'yum install openssh-server -y'" + + ## Creating temporary disk image. + + command = "qemu-img create -b " + sourcePath + " -f qcow2 " + tempPath + result = call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Temporary image created for: " + vmName + ".", "Debug", stack()[0][3]) + + ## Checking size, if less or = 3GB, no need to resize. + + if int(size) <= 3: + move(tempPath, finalPath) + + if logLevel.debug == True: + logger.operationsLog("Image successfully prepared for: " + vmName + ".", "Debug", stack()[0][3]) + + else: + + command = "qemu-img create -f qcow2 " + finalPath + " " + size + "G" + result = call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Created resized final image for: " + vmName + ".", "Debug", stack()[0][3]) + + if osName == "centos-7.4.x64": + + command = "virt-resize --expand /dev/sda2 --lv-expand /dev/centos/root " + tempPath + " " + finalPath + result = call(split(command)) + + + if result == 1: + remove(tempPath) + raise CalledProcessError + else: + remove(tempPath) + + if logLevel.debug == True: + logger.operationsLog("Disk resized and ready to use for: " + vmName + ".", "Debug", + stack()[0][3]) + elif osName == "centos-6.9.x64" or osName == "centos-6.9.x32": + + command = "virt-resize --expand /dev/sda2 --lv-expand /dev/VolGroup/lv_root " + tempPath + " " + finalPath + result = call(split(command)) + + if result == 1: + remove(tempPath) + raise CalledProcessError + else: + remove(tempPath) + + if logLevel.debug == True: + logger.operationsLog("Disk resized and ready to use for: " + vmName + ".", "Debug", + stack()[0][3]) + elif osName == "debian-7.11.x32" or osName == "debian-7.11.x64": + + command = "virt-resize --expand /dev/sda1 --lv-expand /dev/debian/root " + tempPath + " " + finalPath + result = call(split(command)) + + if result == 1: + remove(tempPath) + raise CalledProcessError + else: + remove(tempPath) + + if logLevel.debug == True: + logger.operationsLog("Disk resized and ready to use for: " + vmName + ".", "Debug", + stack()[0][3]) + elif osName == "debian-8.10.x32" or osName == "debian-8.10.x64" or osName == "debian-9.3.x64": + command = "virt-resize --expand /dev/sda2 --lv-expand /dev/debian/root " + tempPath + " " + finalPath + result = call(split(command)) + + if result == 1: + remove(tempPath) + raise CalledProcessError + else: + remove(tempPath) + + if logLevel.debug == True: + logger.operationsLog("Disk resized and ready to use for: " + vmName + ".", "Debug", + stack()[0][3]) + elif osName == "fedora-27.x64" or osName == "fedora-26.x64": + command = "virt-resize --expand /dev/sda2 --lv-expand /dev/fedora/root " + tempPath + " " + finalPath + result = call(split(command)) + + if result == 1: + remove(tempPath) + raise CalledProcessError + else: + remove(tempPath) + + if logLevel.debug == True: + logger.operationsLog("Disk resized and ready to use for: " + vmName + ".", "Debug", + stack()[0][3]) + elif osName == "ubuntu-14.04.x32" or osName == "ubuntu-14.04.x64" or osName == "ubuntu-16.04.x32" or osName == "ubuntu-16.04.x64" or osName == "ubuntu-17.10.x64": + command = "virt-resize --expand /dev/sda2 --lv-expand /dev/ubuntu/root " + tempPath + " " + finalPath + result = call(split(command)) + + if result == 1: + remove(tempPath) + raise CalledProcessError + else: + remove(tempPath) + + if logLevel.debug == True: + logger.operationsLog("Disk resized and ready to use for: " + vmName + ".", "Debug", + stack()[0][3]) + + + ## Setup network and customize root password + + command = "virt-customize -a " + finalPath + " --root-password password:" + rootPassword + uploadCommand + call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Root password and network configured for: " + vmName + ".", "Debug", + stack()[0][3]) + return 1 + + return 1 + + except BaseException,msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError,msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + + """ + Function to create Virtual Machine Disk, which can than be used to create virtual machine. + + vmName = Name of vps, this will be combined with imgDestination and format. + osName = Name of OS, with which this image should be created. + vmDestination = Destination on disk where this image should be placed. + size = Size in GBs. + format = Examples, qcow2, img, qcow, recommend is qcow2. + uploadSource = An array containing complete path of files to be uploaded to the image after creation. + debug = Enable or disable extended debug logging. Defaults to false. + + """ + + @staticmethod + def createVirtualMachineDisk(vmName, osName , vmDestination, size, format, uploadSource): + try: + + if logLevel.debug == True: + logger.operationsLog('Creating disk image for: ' + vmName + '.', 'Debug', stack()[0][3]) + + ## Build upload command + + uploadCommand = "" + + if osName.find('centos') > -1: + uploadCommand = " --upload " + uploadSource[0] + ":" + "/etc/sysconfig/network-scripts/ifcfg-eth0" + uploadCommand = uploadCommand + " --upload " + uploadSource[1] + ":" + "/etc/sysconfig/network" + uploadCommand = uploadCommand + " --upload " + uploadSource[2] + ":" + "/etc/resolv.conf" + + ## Final Image Location -- finalImageLocation = /var/lib/libvirt/192.168.100.1.qcow2 + + finalImageLocation = join(vmDestination, vmName + "." + format) + + ## "virt-builder centos-7.1 -o /var/lib/libvirt/images192.168.100.1.qcow2 --size 50G --format qcow2 --upload ifcfg-eth0:/etc/sysconfig/network-scripts/ --upload network:/etc/sysconfig + + command = "virt-builder " + osName + " -o " + finalImageLocation + " --size " + size + " --format " + format + uploadCommand + result = call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Disk image created for: " + vmName + ".", "Debug", stack()[0][3]) + + ## Remove temporary generated files + + #for tempFiles in uploadSource: + #remove(tempFiles) + + return 1 + + except BaseException,msg: + if logLevel.debug == True: + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError,msg: + if logLevel.debug == True: + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + """ + vmName = Name of the virtual machine, usually the IP Address. + vmRam = Ram to be assigned to this virtual machine. + vmVCPUs = Virtual CPUs to be assigned to this virtual machine. + vmDestination = Path where VM image will be housed. + format = Examples, qcow2, img, qcow, recommend is qcow2. + vncPort = VNC Port for this virtual machine. + osType = OS Type e.g. linux,windows. + osVariant = OS Variant e.g. centos 6, centos 7. + bridgeName = Bridge name to which the interface of this VM will be attached. + debug = Enable or disable extended debug logging. Defaults to false. + + """ + + @staticmethod + def bootVirtualMachine(vmName, vmRam, vmVCPUs, vncHost, vncPort, osType, osVariant, bridgeName): + try: + + if logLevel.debug == True: + logger.operationsLog('Booting: ' + vmName + '.','Debug',stack()[0][3]) + + + finalImageLocation = join(virtualMachineAPI.imagesPath,vmName+".qcow2") + + # virt-install --name 109.238.12.214 --ram 2048 --vcpus=1 --disk 109.238.12.214.qcow2 --graphics vnc,listen=localhost,port=5500 --noautoconsole --hvm --import --os-type=linux --os-variant=rhel7 --network bridge=virbr0 + + command = "virt-install --name " + vmName + " --ram " + vmRam + " --vcpu " + vmVCPUs + " --disk " + \ + finalImageLocation + " --graphics vnc,listen=" +vncHost + ",port=" + vncPort + \ + " --noautoconsole --hvm --import --autostart --os-type=" + osType + " --os-variant=" + \ + osVariant + " --network bridge=" + bridgeName + result = call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Successfully booted: " + vmName + ".", "Debug", stack()[0][3]) + + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + """ + + + osName = Name of OS, with which this image should be created. + imgDestination = Destination on disk where this image should be placed. + imgName = Name of vps, this will be combined with imgDestination. + size = Size in GBs. + format = Examples, qcow2, img, qcow, recommend is qcow2. + uploadSource = An array containing complete path of files to be uploaded to the image after creation. + UploadDestination = Corressponding array of upload source, defining upload destination of files. + + -- + + vmName = Name of the virtual machine, usually the IP Address. + vmRam = Ram to be assigned to this virtual machine. + vmVCPUs = Virtual CPUs to be assigned to this virtual machine. + diskImage = A complete path to disk image for this virtual machine. + vncPort = VNC Port for this virtual machine. + osType = OS Type e.g. linux,windows. + osVariant = OS Variant e.g. centos 6, centos 7. + bridgeName = Bridge name to which the interface of this VM will be attached. + + """ + + @staticmethod + def createVirtualMachine(vmName, osName, rootPassword, size, vncHost, vmRam, vmVCPUs, vncPort, osType, osVariant, bridgeName, ipAddress, netmask, gateway, hostName): + try: + + logger.operationsLog('Starting to create virtual machine: ' + vmName, 'Info', stack()[0][3]) + + ## + + uploadSource = virtualMachineAPI.setupNetworkingFiles(vmName, osName, ipAddress, netmask, gateway, hostName) + + ## + + if virtualMachineAPI.setupVMDisk(vmName, osName, size, uploadSource, rootPassword) == 0: + return 0 + + ## + + if virtualMachineAPI.bootVirtualMachine(vmName, vmRam, vmVCPUs, vncHost, vncPort, osType, osVariant, bridgeName) == 0: + return 0 + + ## + + logger.operationsLog('Virtual machine ' + vmName + ' successfully created.', 'Success', stack()[0][3]) + + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + @staticmethod + def deleteVirtualMachine(virtualMachineName): + try: + + obtainStatus, virtualMachine = virtualMachineAPI.obtainVirtualMachineObject(virtualMachineName) + + if obtainStatus == 1: + + if virtualMachine.hasCurrentSnapshot(): + snapShots = virtualMachine.listAllSnapshots() + for snapShot in snapShots: + snapShot.delete() + + if virtualMachine.isActive(): + virtualMachine.destroy() + + virtualMachine.undefine() + + ## Removing virtual machine file. + + try: + pathToImg = join(virtualMachineAPI.imagesPath, virtualMachineName + '.qcow2') + remove(pathToImg) + except BaseException,msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + + ## + + return 1,'No error.' + else: + return 0,'Failed to obtain virtual machine object.' + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def obtainVirtualMachineObject(virtualMachineName): + try: + connection = libvirt.open('qemu:///system') + + if connection == None: + return 0, 'Failed to establish connection.' + + virtualMachine = connection.lookupByName(virtualMachineName) + + if virtualMachine == None: + return 0, 'Can not find virtual machine.' + + return 1,virtualMachine + + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def revertToSnapshot(virtualMachineName, snapshotName): + try: + obtainStatus, virtualMachine = virtualMachineAPI.obtainVirtualMachineObject(virtualMachineName) + + if obtainStatus == 1: + snapshot = virtualMachine.snapshotLookupByName(snapshotName) + virtualMachine.revertToSnapshot(snapshot) + return 1, 'No error.' + else: + return 0,'Failed to obtain virtual machine object.' + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def softReboot(virtualMachineName): + try: + obtainStatus, virtualMachine = virtualMachineAPI.obtainVirtualMachineObject(virtualMachineName) + if obtainStatus == 1: + if virtualMachine.reboot(): + return 1, 'No error.' + else: + return 0,'Failed to reboot.' + else: + return 0,'Failed to obtain virtual machine object.' + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def hardShutdown(virtualMachineName): + try: + obtainStatus, virtualMachine = virtualMachineAPI.obtainVirtualMachineObject(virtualMachineName) + if obtainStatus == 1: + if virtualMachine.destroy(): + return 1, 'No error.' + else: + return 0,'Failed to shutdown.' + else: + return 0,'Failed to obtain virtual machine object.' + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + + + +virtualMachineAPI.createVirtualMachine('192.111.145.235','centos-7.4.x64',"litespeedtech","50",'192.111.145.234','2048','2','5900','linux','rhel7','virbr0','192.111.145.235','255.255.255.248','192.111.145.233','usman.cybertronproject.com') + +#print virtualMachineAPI.deleteVirtualMachine('109.238.12.214') + +#print virtualMachineAPI.revertToSnapshot('109.238.12.214','CyberPanel') +#virtualMachineAPI.softReboot('109.238.12.214') \ No newline at end of file diff --git a/CyberTronAPI/virtualMachineAPIKVM.py b/CyberTronAPI/virtualMachineAPIKVM.py new file mode 100755 index 000000000..03bd8a5f8 --- /dev/null +++ b/CyberTronAPI/virtualMachineAPIKVM.py @@ -0,0 +1,613 @@ +from CyberTronLogger import CyberTronLogger as logger +from inspect import stack +from shlex import split +from subprocess import call,CalledProcessError +from os.path import join +from os import remove, path +from random import randint +import libvirt +from logLevel import logLevel +from xml.etree import ElementTree + + + +class virtualMachineAPI: + + ## os.path.join + templatesPath = join('/var','lib','libvirt','templates') + imagesPath = join('/var','lib','libvirt','images') + + @staticmethod + def obtainVirtualMachineObject(virtualMachineName): + try: + connection = libvirt.open('qemu:///system') + + if connection == None: + return 0, 'Failed to establish connection.' + + virtualMachine = connection.lookupByName(virtualMachineName) + + if virtualMachine == None: + return 0, 'Can not find virtual machine.' + + return 1, virtualMachine + + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def limitVMSpeed(vpsID, vpsIP, interface, interfaceLimit): + try: + ## Creating class + + command = 'tc class add dev ' + interface + ' parent 2:1 classid ' + '2:' + vpsID + ' htb rate ' + interfaceLimit + logger.writeToFile(command,'Info',stack()[0][3]) + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + ## Create IP Filter. + + command = 'tc filter add dev ' + interface + ' parent 2:0 protocol ip prio 1 u32 match ip src ' + vpsIP + ' flowid 2:' + vpsID + logger.writeToFile(command,'Info',stack()[0][3]) + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + @staticmethod + def removeVMSpeedLimit(vpsID, interface): + try: + ## Removing filter. + + command = 'tc filter del dev ' + interface + ' parent 2:0 protocol ip prio 1 u32 flowid 2:' + vpsID + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + ## Removing class. + + command = 'tc class del dev ' + interface + ' classid 2:' + vpsID + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + @staticmethod + def deleteVirtualMachine(virtualMachineName): + try: + + obtainStatus, virtualMachine = virtualMachineAPI.obtainVirtualMachineObject(virtualMachineName) + + if obtainStatus == 1: + + if virtualMachine.hasCurrentSnapshot(): + snapShots = virtualMachine.listAllSnapshots() + for snapShot in snapShots: + snapShot.delete() + + if virtualMachine.isActive(): + virtualMachine.destroy() + + virtualMachine.undefine() + + ## Removing virtual machine file. + + try: + pathToImg = join(virtualMachineAPI.imagesPath, virtualMachineName + '.qcow2') + remove(pathToImg) + except BaseException,msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + + ## + + return 1,'No error.' + else: + return 0,'Failed to obtain virtual machine object.' + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def revertToSnapshot(virtualMachineName, snapshotName): + try: + obtainStatus, virtualMachine = virtualMachineAPI.obtainVirtualMachineObject(virtualMachineName) + + if obtainStatus == 1: + snapshot = virtualMachine.snapshotLookupByName(snapshotName) + virtualMachine.revertToSnapshot(snapshot) + return 1, 'No error.' + else: + return 0,'Failed to obtain virtual machine object.' + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def softReboot(virtualMachineName): + try: + obtainStatus, virtualMachine = virtualMachineAPI.obtainVirtualMachineObject(virtualMachineName) + if obtainStatus == 1: + if virtualMachine.isActive(): + virtualMachine.reboot() + return 1, 'No error.' + else: + command = 'virsh start ' + virtualMachineName + call(split(command)) + return 1, 'No error.' + else: + return 0,'Failed to obtain virtual machine object.' + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def hardShutdown(virtualMachineName): + try: + obtainStatus, virtualMachine = virtualMachineAPI.obtainVirtualMachineObject(virtualMachineName) + if obtainStatus == 1: + if virtualMachine.isActive(): + virtualMachine.destroy() + return 1, 'No error.' + else: + return 0, 'VPS is not running.' + else: + return 0,'Failed to obtain virtual machine object.' + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def setupNetworkingFiles(vmName, ipAddress, netmask, gateway, hostName): + try: + + if logLevel.debug == True: + logger.operationsLog('Setting up network for: ' + vmName + '.', 'Debug', stack()[0][3]) + + uploadSource = [] + + ###### /etc/sysconfig/network-scripts/ifcfg-eth0 + + eth0 = "ifcfg-eth0_" + str(randint(10000, 99999)) + eth0File = open(eth0, 'w') + + eth0File.writelines('DEVICE="eth0"\n') + eth0File.writelines('NM_CONTROLLED="yes"\n') + eth0File.writelines('ONBOOT=yes\n') + eth0File.writelines('TYPE=Ethernet\n') + eth0File.writelines('BOOTPROTO=static\n') + eth0File.writelines('NAME="System eth0"\n') + eth0File.writelines('IPADDR=' + ipAddress + '\n') + eth0File.writelines('NETMASK=' + netmask + '\n') + + eth0File.close() + + uploadSource.append(eth0) + + ###### /etc/sysconfig/network + + network = "network_" + str(randint(10000, 99999) + 1) + networkFile = open(network, 'w') + + networkFile.writelines('NETWORKING=yes\n') + networkFile.writelines('HOSTNAME=' + hostName + '\n') + networkFile.writelines('GATEWAY=' + gateway + '\n') + + networkFile.close() + + uploadSource.append(network) + + ###### /etc/resolv.conf + + resolv = "resolv_" + str(randint(10000, 99999) + 2) + resolvFile = open(resolv, 'w') + + resolvFile.writelines("nameserver 8.8.8.8\n") + + resolvFile.close() + + uploadSource.append(resolv) + + if logLevel.debug == True: + logger.operationsLog('Network settings installed for: ' + vmName + '.', 'Debug', stack()[0][3]) + + return uploadSource + + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + ''' + vmName = Usually IP Address. + osName = Examples operatingSystem-X.xx.x86 + uploadSource = An array containing complete path of files to be uploaded to the image after creation. + rootPassword = Virtual Machine root password. + ''' + + @staticmethod + def setupVMDisk(vmName, package, uploadSource, rootPassword): + try: + + if logLevel.debug == True: + logger.operationsLog('Creating disk image for: ' + vmName + '.', 'Debug', stack()[0][3]) + + sourcePath = join(virtualMachineAPI.templatesPath, package + ".qcow2") + finalPath = join(virtualMachineAPI.imagesPath, vmName + ".qcow2") + + ## Build upload command + + uploadCommand = "" + + uploadCommand = " --upload " + uploadSource[0] + ":" + "/etc/sysconfig/network-scripts/ifcfg-eth0" + uploadCommand = uploadCommand + " --upload " + uploadSource[1] + ":" + "/etc/sysconfig/network" + uploadCommand = uploadCommand + " --upload " + uploadSource[2] + ":" + "/etc/resolv.conf" + ## Creating temporary disk image. + + command = "qemu-img create -b " + sourcePath + " -f qcow2 " + finalPath + result = call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Temporary image created for: " + vmName + ".", "Debug", stack()[0][3]) + + ## Setup network and customize root password + + command = "virt-customize -a " + finalPath + " --root-password password:" + rootPassword + uploadCommand + call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Root password and network configured for: " + vmName + ".", "Debug", + stack()[0][3]) + return 1 + + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + """ + vmName = Name of the virtual machine, usually the IP Address. + vmRam = Ram to be assigned to this virtual machine. + vmVCPUs = Virtual CPUs to be assigned to this virtual machine. + vmDestination = Path where VM image will be housed. + format = Examples, qcow2, img, qcow, recommend is qcow2. + vncPort = VNC Port for this virtual machine. + osType = OS Type e.g. linux,windows. + osVariant = OS Variant e.g. centos 6, centos 7. + bridgeName = Bridge name to which the interface of this VM will be attached. + debug = Enable or disable extended debug logging. Defaults to false. + + """ + + @staticmethod + def bootVirtualMachine(vmName, vmVCPUs, vmRam, vncHost, vncPort, bridgeName, webSocketPort, vncPassword): + try: + + if logLevel.debug == True: + logger.operationsLog('Booting: ' + vmName + '.', 'Debug', stack()[0][3]) + + finalImageLocation = join(virtualMachineAPI.imagesPath, vmName + ".qcow2") + + # virt-install --name 109.238.12.214 --ram 2048 --vcpus=1 --disk 109.238.12.214.qcow2 --graphics vnc,listen=localhost,port=5500 --noautoconsole --hvm --import --os-type=linux --os-variant=rhel7 --network bridge=virbr0 + + command = "virt-install --name " + vmName + " --ram " + vmRam + " --vcpu " + vmVCPUs + " --disk " + \ + finalImageLocation + " --graphics vnc,listen=" + vncHost + ",port=" + vncPort + ",password=" + vncPassword + \ + ' --qemu-commandline=' + '"' + '-vnc :' + webSocketPort + ',websocket' + '"' + \ + " --noautoconsole --hvm --import --autostart --os-type=linux " \ + + "--network bridge=" + bridgeName + logger.writeToFile(command,"Info", stack()[0][3]) + result = call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Successfully booted: " + vmName + ".", "Debug", stack()[0][3]) + + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + """ + + + osName = Name of OS, with which this image should be created. + imgDestination = Destination on disk where this image should be placed. + imgName = Name of vps, this will be combined with imgDestination. + size = Size in GBs. + format = Examples, qcow2, img, qcow, recommend is qcow2. + uploadSource = An array containing complete path of files to be uploaded to the image after creation. + UploadDestination = Corressponding array of upload source, defining upload destination of files. + + -- + + vmName = Name of the virtual machine, usually the IP Address. + vmRam = Ram to be assigned to this virtual machine. + vmVCPUs = Virtual CPUs to be assigned to this virtual machine. + diskImage = A complete path to disk image for this virtual machine. + vncPort = VNC Port for this virtual machine. + osType = OS Type e.g. linux,windows. + osVariant = OS Variant e.g. centos 6, centos 7. + bridgeName = Bridge name to which the interface of this VM will be attached. + + """ + + @staticmethod + def createVirtualMachine(vmName, package, rootPassword, vmVCPUs, vmRam, vncHost, vncPort, bridgeName, ipAddress, netmask, gateway, hostName, webSocketPort, vncPassword): + try: + + logger.operationsLog('Starting to create virtual machine: ' + vmName, 'Info', stack()[0][3]) + + ## + + uploadSource = virtualMachineAPI.setupNetworkingFiles(vmName, ipAddress, netmask, gateway, hostName) + + ## + if virtualMachineAPI.setupVMDisk(vmName, package, uploadSource, rootPassword) == 0: + return 0 + + ## + + if virtualMachineAPI.bootVirtualMachine(vmName, vmVCPUs, vmRam, vncHost, vncPort, bridgeName, webSocketPort, vncPassword) == 0: + return 0 + + ## + + logger.operationsLog('Virtual machine ' + vmName + ' successfully created.', 'Success', stack()[0][3]) + + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + +#virtualMachineAPI.createVirtualMachine('192.111.145.237', 'forthPlan', 'litespeed12', '2', '2048', '192.111.145.234', '5904','virbr0','192.111.145.237','255.255.255.248','192.111.145.233','usman.cybertronproject.com') + +#print virtualMachineAPI.deleteVirtualMachine('109.238.12.214') +#print virtualMachineAPI.revertToSnapshot('109.238.12.214','CyberPanel') +#virtualMachineAPI.softReboot('109.238.12.214') + + @staticmethod + def isActive(virtualMachineName): + try: + obtainStatus, virtualMachine = virtualMachineAPI.obtainVirtualMachineObject(virtualMachineName) + if obtainStatus == 1: + if virtualMachine.isActive(): + return 1 + else: + return 0 + else: + return 0 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + @staticmethod + def getCurrentUsedRam(virtualMachineName): + try: + obtainStatus, virtualMachine = virtualMachineAPI.obtainVirtualMachineObject(virtualMachineName) + if obtainStatus == 1: + if virtualMachine.isActive(): + memStats = virtualMachine.memoryStats() + return int(memStats['unused']/1024) + else: + return 0 + else: + return 0 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + @staticmethod + def getBandwidthUsage(virtualMachineName): + try: + obtainStatus, virtualMachine = virtualMachineAPI.obtainVirtualMachineObject(virtualMachineName) + if obtainStatus == 1: + if virtualMachine.isActive(): + tree = ElementTree.fromstring(virtualMachine.XMLDesc()) + iface = tree.find('devices/interface/target').get('dev') + memStats = virtualMachine.interfaceStats(iface) + ## memStats[0] are read bytes, memStats[4] write bytes + return (memStats[0] + memStats[4])/(1024 * 1024) + else: + return 0 + else: + return 0 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + @staticmethod + def calculateDiskPercentage(virtualMachineName, actualDisk): + try: + vpsImagePath = '/var/lib/libvirt/images/' + virtualMachineName + ".qcow2" + sizeInMB = float(path.getsize(vpsImagePath)) / (1024.0 * 1024) + diskUsagePercentage = float(100) / float((int(actualDisk.rstrip('GB')) * 1024)) + diskUsagePercentage = float(diskUsagePercentage) * float(sizeInMB) + diskUsagePercentage = int(diskUsagePercentage) + + if diskUsagePercentage > 100: + return 100, sizeInMB + + return diskUsagePercentage, sizeInMB + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0,0 + + @staticmethod + def calculateRamPercentage(virtualMachineName, actualRam): + try: + unUsedRam = virtualMachineAPI.getCurrentUsedRam(virtualMachineName) + usedRam = int(actualRam.rstrip('MB')) - unUsedRam + + ramUsagePercentage = float(100) / int(actualRam.rstrip('MB')) + ramUsagePercentage = int(float(ramUsagePercentage) * float(usedRam)) + + if ramUsagePercentage > 100: + return 100 + + return ramUsagePercentage + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + @staticmethod + def calculateBWPercentage(virtualMachineName, actualBW): + try: + usedBW = virtualMachineAPI.getBandwidthUsage(virtualMachineName) + availBW = int(actualBW.rstrip('TB')) * 1024 * 1024 + + bwPercentage = float(100) / availBW + bwPercentage = int(float(bwPercentage) * usedBW) + + if bwPercentage > 100: + return 100 + + return bwPercentage + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + @staticmethod + def changeHostname(virtualMachineName, newHostname): + try: + command = "virt-customize -d " + virtualMachineName + " --hostname " + newHostname + call(split(command)) + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def changeRootPassword(virtualMachineName, newPassword): + try: + command = "virt-customize -d " + virtualMachineName + " --root-password password:" + newPassword + call(split(command)) + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def createSnapshot(virtualMachineName, snapshotName): + try: + command = "virsh snapshot-create-as --domain " + virtualMachineName + " --name " + snapshotName + call(split(command)) + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def deleteSnapshot(virtualMachineName, snapshotName): + try: + command = "virsh snapshot-delete --domain " + virtualMachineName + " --snapshotname " + snapshotName + call(split(command)) + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) \ No newline at end of file diff --git a/CyberTronAPI/virtualMachineAPIOpenVZ.py b/CyberTronAPI/virtualMachineAPIOpenVZ.py new file mode 100755 index 000000000..3e52e73fb --- /dev/null +++ b/CyberTronAPI/virtualMachineAPIOpenVZ.py @@ -0,0 +1,668 @@ +from CyberTronLogger import CyberTronLogger as logger +from inspect import stack +from shlex import split +from subprocess import call, CalledProcessError +from os.path import join +from os import remove,path +from random import randint +from shutil import move +from time import sleep +from logLevel import logLevel +from multiprocessing import Process + +class virtualMachineAPIOpenVZ: + ## os.path.join + templatesPath = join('/var', 'lib', 'libvirt', 'templates') + imagesPath = join('/vz', 'root') + defaultInterface = 'eth0' + backupPath = join('/vz','dump') + + @staticmethod + def setupNetworkingFiles(vmName, osName, ipAddress, netmask, gateway, hostName): + try: + + if logLevel.debug == True: + logger.operationsLog('Setting up network for: ' + vmName + '.', 'Debug', stack()[0][3]) + + uploadSource = [] + + if osName.find("centos") > -1: + ###### /etc/sysconfig/network-scripts/ifcfg-eth0 + + eth0 = "ifcfg-eth0_" + str(randint(10000, 99999)) + eth0File = open(eth0, 'w') + + eth0File.writelines('DEVICE="eth0"\n') + eth0File.writelines('NM_CONTROLLED="yes"\n') + eth0File.writelines('ONBOOT=yes\n') + eth0File.writelines('TYPE=Ethernet\n') + eth0File.writelines('BOOTPROTO=static\n') + eth0File.writelines('NAME="System eth0"\n') + eth0File.writelines('IPADDR=' + ipAddress + '\n') + eth0File.writelines('NETMASK=' + netmask + '\n') + + eth0File.close() + + uploadSource.append(eth0) + + ###### /etc/sysconfig/network + + network = "network_" + str(randint(10000, 99999) + 1) + networkFile = open(network, 'w') + + networkFile.writelines('NETWORKING=yes\n') + networkFile.writelines('HOSTNAME=' + hostName + '\n') + networkFile.writelines('GATEWAY=' + gateway + '\n') + + networkFile.close() + + uploadSource.append(network) + + ###### /etc/resolv.conf + + resolv = "resolv_" + str(randint(10000, 99999) + 2) + resolvFile = open(resolv, 'w') + + resolvFile.writelines("nameserver 8.8.8.8\n") + + resolvFile.close() + + uploadSource.append(resolv) + elif osName.find("debian") > -1 or osName.find("ubuntu") > -1: + + ###### /etc/network/interfaces + + eth0 = "interfaces_" + str(randint(10000, 99999)) + eth0File = open(eth0, 'w') + + eth0File.writelines('# This file describes the network interfaces available on your system\n') + eth0File.writelines('# and how to activate them. For more information, see interfaces(5).\n') + + eth0File.writelines('\n') + + eth0File.writelines('# The loopback network interface\n') + eth0File.writelines('auto lo\n') + eth0File.writelines('iface lo inet loopback\n') + + eth0File.writelines('\n') + + ## To deal with Debian 9.3 and ubuntu 16.04 issue. + + eth0File.writelines('# The primary network interface\n') + + + eth0File.writelines('allow-hotplug eth0\n') + eth0File.writelines('iface eth0 inet static\n') + + eth0File.writelines(' address ' + ipAddress + '\n') + eth0File.writelines(' netmask ' + netmask + '\n') + eth0File.writelines(' gateway ' + gateway + '\n') + eth0File.writelines('# dns-* options are implemented by the resolvconf package, if installed\n') + eth0File.writelines('dns-nameservers 8.8.8.8\n') + eth0File.writelines('dns-search com\n') + + eth0File.close() + + uploadSource.append(eth0) + elif osName.find("fedora") > -1: + + ###### /etc/sysconfig/network-scripts/ifcfg-ens3 + + eth0 = "interfaces_" + str(randint(10000, 99999)) + eth0File = open(eth0, 'w') + + eth0File.writelines('TYPE=Ethernet\n') + eth0File.writelines('PROXY_METHOD=none\n') + + eth0File.writelines('BROWSER_ONLY=no\n') + eth0File.writelines('BOOTPROTO=none\n') + eth0File.writelines('DEFROUTE=yes\n') + + eth0File.writelines('IPV4_FAILURE_FATAL=no\n') + eth0File.writelines('IPV6INIT=yes\n') + eth0File.writelines('IPV6_AUTOCONF=yes\n') + + eth0File.writelines('IPV6_DEFROUTE=yes\n') + eth0File.writelines('IPV6_FAILURE_FATAL=no\n') + eth0File.writelines('IPV6_ADDR_GEN_MODE=stable-privacy\n') + eth0File.writelines('NAME=eth0\n') + eth0File.writelines('ONBOOT=yes\n') + eth0File.writelines('AUTOCONNECT_PRIORITY=-999\n') + + eth0File.writelines('DEVICE=eth0\n') + eth0File.writelines('IPADDR=' + ipAddress + '\n') + eth0File.writelines('NETMASK=' + netmask + '\n') + eth0File.writelines('GATEWAY=' + gateway + '\n') + eth0File.writelines('DNS1=8.8.8.8\n') + eth0File.writelines('IPV6_PRIVACY=no\n') + + eth0File.close() + uploadSource.append(eth0) + + if logLevel.debug == True: + logger.operationsLog('Network settings installed for: ' + vmName + '.', 'Debug', stack()[0][3]) + + return uploadSource + + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + @staticmethod + def createContainer(vmName, containerID, osTemplate): + try: + + command = "vzctl create " + containerID + " --ostemplate " + osTemplate + result = call(split(command)) + + if result == 1: + raise CalledProcessError + + if logLevel.debug == True: + logger.operationsLog("Container successfully created for: " + vmName + ".", "Debug", + stack()[0][3]) + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + @staticmethod + def bootVirtualMachine(vmName, osTemplate, containerID, rootPassword, hostName, macAddress, uploadSource, cpuUnits, + cpuPercentage, vmVCPUs, vmRam, vmSwap, burstVMRam, size, + dnsNSOne="8.8.8.8", dnsNSTwo="8.8.4.4", + ioPriority=3, uploadSpeed=0, bandwidthSuspend=1, debug=False): + try: + ioPriority = str(ioPriority) + + command = "vzctl set " + containerID + " --save --name " + vmName + " --onboot yes --hostname " + hostName + \ + " --netif_add eth0,,," + macAddress + " --nameserver " + dnsNSOne + " --nameserver " + dnsNSTwo + \ + " --cpus " + vmVCPUs + " --ram " + vmRam + " --swap " + vmSwap + " --diskspace " + size + \ + " --userpasswd root:" + rootPassword + " --ioprio " + ioPriority + " --cpuunits " + cpuUnits + \ + " --cpulimit " + cpuPercentage + + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + + + command = "vzctl start " + containerID + + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + sleep(2) + + finalVMPath = join(virtualMachineAPIOpenVZ.imagesPath,containerID) + + if osTemplate.find('centos') > -1: + move(uploadSource[0],finalVMPath + '/etc/sysconfig/network-scripts/ifcfg-eth0') + move(uploadSource[1], finalVMPath + '/etc/sysconfig/network') + move(uploadSource[2], finalVMPath + '/etc/resolv.conf') + elif osTemplate.find('debian') > -1: + move(uploadSource[0], finalVMPath + '/etc/network/interfaces') + elif osTemplate.find('ubuntu') > -1: + move(uploadSource[0], finalVMPath + '/etc/network/interfaces') + elif osTemplate.find('fedora') > -1: + move(uploadSource[0], finalVMPath + '/etc/sysconfig/network-scripts/ifcfg-eth0') + + command = "vzctl exec " + containerID + " /etc/init.d/network restart" + + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + return 1 + + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + + + """ + + vmName = Name of the virtual machine, usually the IP Address. + containerID = Container ID of VPS, which usually identify OpenVZ VPS. Starts 100 and above. + osTemplate = osTemplate that will be used to boot OpenVZ Container. + rootPassword = VPS Root Password. + size = Size in GBs of OpenVZ Container. + vmRam = Guranteed dedicated virtual machine ram. + burstVMRam = Burstable ram, ram that VM can acquire if it is avaiable by host node. + bandwidth = Bandwidth allowed to container. + """ + + @staticmethod + def createVirtualMachine(vmName, containerID, osTemplate, rootPassword, size, vmRam, vmSwap, burstVMRam, bandwidth, cpuUnits, + vmVCPUs,cpuPercentage, ipAddress, netmask, gateway, hostName, macAddress, + dnsNSOne = "8.8.8.8", dnsNSTwo = "8.8.4.4", networkSpeed = '0', + ioPriority = 3, uploadSpeed = 0, bandwidthSuspend = 1): + try: + + logger.operationsLog('Starting to create virtual machine: ' + vmName, 'Info', stack()[0][3]) + + ## + + uploadSource = virtualMachineAPIOpenVZ.setupNetworkingFiles(vmName, osTemplate, ipAddress, netmask, gateway, hostName) + + ## + + if virtualMachineAPIOpenVZ.createContainer(vmName, containerID, osTemplate) == 0: + raise BaseException("Failed to create container.") + + ## + + if virtualMachineAPIOpenVZ.bootVirtualMachine(vmName, osTemplate, containerID, rootPassword, hostName, macAddress, uploadSource, + cpuUnits, cpuPercentage, vmVCPUs, vmRam, vmSwap, burstVMRam, + size, dnsNSOne, dnsNSTwo, + ioPriority, uploadSpeed,bandwidthSuspend) == 0: + raise BaseException("Failed to boot container.") + + + #if virtualMachineAPIOpenVZ.limitContainerSpeed(containerID, ipAddress, virtualMachineAPIOpenVZ.defaultInterface, networkSpeed) == 0: + # raise BaseException("Failed to set network limits.") + + ## + + logger.operationsLog('Virtual machine ' + vmName + ' successfully created.', 'Success', stack()[0][3]) + + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + @staticmethod + def deleteVirtualMachine(containerID): + try: + + result = virtualMachineAPIOpenVZ.hardShutdown(containerID) + + if result[0] == 1: + + command = "vzctl destroy " + containerID + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + return 1,'No error.' + + else: + return 0, 'Failed to stop virtual machine.' + + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def softReboot(containerID): + try: + + command = "vzctl restart " + containerID + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + return 1,'No error.' + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def hardShutdown(containerID): + try: + + command = "vzctl stop " + containerID + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + return 1,'No error.' + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def startContainer(containerID): + try: + + command = "vzctl start " + containerID + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + return 1,'No error.' + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def suspendContainer(containerID): + try: + + command = "vzctl suspend " + containerID + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + return 1,'No error.' + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def resumeContainer(containerID): + try: + command = "vzctl resume " + containerID + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + return 1, 'No error.' + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0, str(msg) + + @staticmethod + def limitContainerSpeed(containerID, containerIP, interface, interfaceLimit): + try: + ## Creating class + + command = 'tc class add dev ' + interface + ' parent 2:1 classid ' + '2:' + containerID + ' htb rate '+ interfaceLimit + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + ## Create IP Filter. + + command = 'tc filter add dev ' + interface + ' parent 2:0 protocol ip prio 1 u32 match ip src ' + containerIP + ' flowid 2:' + containerID + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + @staticmethod + def removeContainerSpeedLimit(containerID, interface): + try: + ## Removing filter. + + command = 'tc filter del dev ' + interface + ' parent 2:0 protocol ip prio 1 u32 flowid 2:' + containerID + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + ## Removing class. + + command = 'tc class del dev ' + interface + ' classid 2:' + containerID + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + + @staticmethod + def createBackup(containerID, suspend = False , stop = False): + try: + + statusFilePath = join(virtualMachineAPIOpenVZ.backupPath, 'vzdump-' + containerID + '.log') + + if path.exists(statusFilePath): + remove(statusFilePath) + + if suspend == True: + command = 'vzdump --compress --suspend ' + containerID + elif stop == True: + command = 'vzdump --compress --stop ' + containerID + else: + command = 'vzdump --compress ' + containerID + + result = call(split(command)) + + if result == 1: + raise CalledProcessError + else: + pass + + return 1 + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + @staticmethod + def initiateBackup(containerID, suspend=False, stop=False): + try: + p = Process(target=virtualMachineAPIOpenVZ.createBackup, args=(containerID, suspend, stop,)) + p.start() + # pid = open(backupPath + 'pid', "w") + # pid.write(str(p.pid)) + # pid.close() + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + + @staticmethod + def checkBackupCreationStatus(containerID): + try: + + statusFilePath = join(virtualMachineAPIOpenVZ.backupPath,'vzdump-' + containerID + '.log') + + statusFile = open(statusFilePath, 'r') + dataInStatusFile = statusFile.read() + statusFile.close() + + if dataInStatusFile.find('Finished Backup of') > -1: + return 1,dataInStatusFile + else: + return 0,dataInStatusFile + + + except BaseException, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + except CalledProcessError, msg: + if logLevel.debug == True: + logger.operationsLog(str(msg), "Error", stack()[0][3]) + logger.writeToFile(str(msg), "Error", stack()[0][3]) + return 0 + + +def main(): + + virtualMachineAPIOpenVZ.initiateBackup('105') + + while(1): + retValue = virtualMachineAPIOpenVZ.checkBackupCreationStatus('105') + + if retValue[0] == 0: + print retValue[1] + else: + print "Completed" + break + +#main() + + + + + + +virtualMachineAPIOpenVZ.createVirtualMachine('192.111.145.235','102',"centos-7-x86_64-minimal","litespeed12", + '70G','4G','2G','6G','100GB','900','2','20%','192.111.145.235','255.255.255.248', + '192.111.145.233','cybertronproject.com','FE:FF:FF:FF:FF:FF', '8.8.8.8', '8.8.4.4', + '2Mbit', 4, 0, 1) + + +#virtualMachineAPIOpenVZ.removeContainerSpeedLimit('105','eth0') +#virtualMachineAPIOpenVZ.limitContainerSpeed('105','192.111.145.238','eth0','256Kbit') + +#print virtualMachineAPI.deleteVirtualMachine('109.238.12.214') + +#print virtualMachineAPI.revertToSnapshot('109.238.12.214','CyberPanel') + +#virtualMachineAPIOpenVZ.deleteVirtualMachine('102') +#virtualMachineAPIOpenVZ.softReboot('102') +#virtualMachineAPIOpenVZ.hardShutdown('102') +#virtualMachineAPIOpenVZ.startContainer('102') diff --git a/backup/static/backup/backup.js b/backup/static/backup/backup.js index b83f9bcce..159550915 100644 --- a/backup/static/backup/backup.js +++ b/backup/static/backup/backup.js @@ -1550,4 +1550,480 @@ app.controller('remoteBackupControl', function($scope, $http, $timeout) { }); -///** Backup site ends **/// \ No newline at end of file +///** Backup site ends **/// + + +/////////////// Snapshots + +/* Java script code for Snapshots */ +app.controller('snapshotsCTRL', function($scope,$http) { + + $scope.getCurrentSnapshots = function(){ + + $scope.tronLoading = false; + + var url = "/backup/fetchCurrentSnapshots"; + + var data = { + hostName: $("#hostname").text() + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + $scope.tronLoading = true; + $scope.snapshotTable = false; + + if(response.data.success === 1){ + + $scope.snapshots = JSON.parse(response.data.data); + } + else + { + new PNotify({ + title: 'Operation Failed!', + 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.getCurrentSnapshots(); + + /// Administrative Tasks + + $scope.tronLoading = true; + $scope.createSnapshotBox = true; + + + $scope.showSnapshotForm = function () { + $scope.createSnapshotBox = false; + $scope.createSnapshotBTN = true; + $scope.snapshotTable = true; + + }; + + + $scope.createSnapShot = function(){ + + $scope.tronLoading = false; + + + var url = "/backup/submitSnapshotCreation"; + + var data = { + hostName: $("#hostname").text(), + snapshotName: $scope.snapshotName + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + $scope.tronLoading = true; + + if(response.data.success === 1){ + + new PNotify({ + title: 'Operation Successfull!', + text: response.data.successMessage, + type:'success' + }); + + $scope.getCurrentSnapshots(); + $scope.createSnapshotBox = true; + $scope.createSnapshotBTN = false; + + } + else + { + + new PNotify({ + title: 'Operation failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + + $scope.tronLoading = true; + new PNotify({ + title: 'Operation failed!', + text: "Could not connect to server. Please refresh this page.", + type:'error' + }); + + + } + + }; + $scope.deleteSnapshot = function(snapshotName){ + + $scope.tronLoading = false; + + + var url = "/backup/deletSnapshot"; + + var data = { + hostName: $("#hostname").text(), + snapshotName: snapshotName + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + $scope.tronLoading = true; + + if(response.data.success === 1){ + + new PNotify({ + title: 'Operation Successfull!', + text: response.data.successMessage, + type:'success' + }); + + $scope.getCurrentSnapshots(); + + } + else + { + + new PNotify({ + title: 'Operation failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + + $scope.tronLoading = true; + new PNotify({ + title: 'Operation failed!', + text: "Could not connect to server. Please refresh this page.", + type:'error' + }); + + + } + + }; + $scope.revertToSnapshot = function(snapshotName){ + + $scope.tronLoading = false; + + + var url = "/backup/revertToSnapshot"; + + var data = { + hostName: $("#hostname").text(), + snapshotName: snapshotName + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + $scope.tronLoading = true; + + if(response.data.success === 1){ + + new PNotify({ + title: 'Operation Successfull!', + text: response.data.successMessage, + type:'success' + }); + + } + else + { + + new PNotify({ + title: 'Operation failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + + $scope.tronLoading = true; + new PNotify({ + title: 'Operation failed!', + text: "Could not connect to server. Please refresh this page.", + type:'error' + }); + + + } + + }; + + + $scope.changeRootPassword = function(vpsID){ + + $scope.tronLoading = false; + + + var url = "/vps/changeRootPassword"; + + var data = { + hostName: $("#vpsHostname").text(), + newPassword: $scope.newPassword + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + $scope.tronLoading = true; + + if(response.data.success === 1){ + + $scope.successMessage = response.data.successMessage; + + new PNotify({ + title: 'Operation Successfull!', + text: response.data.successMessage, + type:'success' + }); + + } + else + { + new PNotify({ + title: 'Operation failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + + $scope.tronLoading = true; + new PNotify({ + title: 'Operation failed!', + text: "Could not connect to server. Please refresh this page.", + type:'error' + }); + + + } + + }; + $scope.reinstallOS = function(vpsID){ + + $scope.tronLoading = false; + + + var url = "/vps/reInstallOS"; + + var data = { + hostName: $("#vpsHostname").text(), + rootPassword: $scope.reinstallPassword + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + $scope.tronLoading = true; + + if(response.data.success === 1){ + + $scope.successMessage = response.data.successMessage; + + new PNotify({ + title: 'Operation Successfull!', + text: response.data.successMessage, + type:'success' + }); + + } + else + { + + new PNotify({ + title: 'Operation failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + + $scope.tronLoading = true; + new PNotify({ + title: 'Operation failed!', + text: "Could not connect to server. Please refresh this page.", + type:'error' + }); + + + } + + }; + + + $scope.restartVPS = function(vpsID){ + + $scope.tronLoading = false; + $scope.poolCreationFailed = true; + $scope.poolCreated = true; + $scope.couldNotConnect = true; + + + + var url = "/vps/restartVPS"; + + var data = {vpsID: vpsID}; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + if(response.data.success === 1){ + + $scope.tronLoading = true; + $scope.poolCreationFailed = true; + $scope.poolCreated = false; + $scope.couldNotConnect = true; + $scope.successMessage = response.data.successMessage; + $scope.getFurtherVPS(currentPageNumber); + } + else + { + $scope.tronLoading = true; + $scope.poolCreationFailed = false; + $scope.poolCreated = true; + $scope.couldNotConnect = true; + $scope.errorMessage = response.data.error_message; + + } + } + function cantLoadInitialDatas(response) { + $scope.tronLoading = true; + $scope.poolCreationFailed = true; + $scope.poolCreated = true; + $scope.couldNotConnect = false; + + } + + }; + $scope.shutdownVPS = function(vpsID){ + + $scope.tronLoading = false; + $scope.poolCreationFailed = true; + $scope.poolCreated = true; + $scope.couldNotConnect = true; + + + + var url = "/vps/shutdownVPS"; + + var data = {vpsID: vpsID}; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + if(response.data.success === 1){ + + $scope.tronLoading = true; + $scope.poolCreationFailed = true; + $scope.poolCreated = false; + $scope.couldNotConnect = true; + $scope.successMessage = response.data.successMessage; + $scope.getFurtherVPS(currentPageNumber); + } + else + { + $scope.tronLoading = true; + $scope.poolCreationFailed = false; + $scope.poolCreated = true; + $scope.couldNotConnect = true; + $scope.errorMessage = response.data.error_message; + + } + } + function cantLoadInitialDatas(response) { + $scope.tronLoading = true; + $scope.poolCreationFailed = true; + $scope.poolCreated = true; + $scope.couldNotConnect = false; + + } + + }; + +}); +/* Java script code for Snapshots ends here */ \ No newline at end of file diff --git a/backup/templates/backup/createSnapshots.html b/backup/templates/backup/createSnapshots.html new file mode 100644 index 000000000..79e071e0d --- /dev/null +++ b/backup/templates/backup/createSnapshots.html @@ -0,0 +1,99 @@ +{% extends "baseTemplate/index.html" %} +{% load i18n %} +{% block title %}{% trans "Create Snapshots - CyberTron" %}{% endblock %} +{% block content %} + +{% load static %} +{% get_current_language as LANGUAGE_CODE %} + + +
{% trans "On this page you can create, delete or revert to Virtual Machine Snapshot." %}
+
+ {% trans "Use the tabs to navigate through the control panel." %}
+