diff --git a/backup/models.py b/backup/models.py index 0d4fdfc55..a9a4d1844 100755 --- a/backup/models.py +++ b/backup/models.py @@ -1,5 +1,3 @@ - - from django.db import models class DBUsers(models.Model): diff --git a/plogical/ClusterManager.py b/plogical/ClusterManager.py index 511c9f6e5..50251d51a 100644 --- a/plogical/ClusterManager.py +++ b/plogical/ClusterManager.py @@ -13,7 +13,7 @@ from firewall.models import FirewallRules from plogical.firewallUtilities import FirewallUtilities from plogical.processUtilities import ProcessUtilities from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging - +from plogical.mysqlUtilities import mysqlUtilities class ClusterManager: LogURL = "https://cloud.cyberpanel.net/HighAvailability/RecvData" @@ -34,7 +34,7 @@ class ClusterManager: try: finalData = {'name': self.config['name'], 'type': self.type, 'message': message, 'token': self.config['token']} resp = requests.post(ClusterManager.LogURL, data=json.dumps(finalData), verify=False) - logging.writeToFile(resp.text + '[info]') + # logging.writeToFile(resp.text + '[info]') except BaseException as msg: logging.writeToFile('%s. [31:404]' % (str(msg))) @@ -253,6 +253,12 @@ password=%s""" % (rootdbpassword, rootdbpassword) writeToFile.write(content) writeToFile.close() + ## Let this server process updates if master is down + + connection, cursor = mysqlUtilities.setupConnection() + cursor.execute("SET GLOBAL wsrep_provider_options='pc.ignore_sb=TRUE'") + connection.close() + self.PostStatus('Fail over server successfully booted. [200]') ### diff --git a/plogical/backupUtilities.py b/plogical/backupUtilities.py index e38753e41..2d57b3b9f 100755 --- a/plogical/backupUtilities.py +++ b/plogical/backupUtilities.py @@ -1,7 +1,5 @@ import os, sys -from s3transfer import TransferConfig - sys.path.append('/usr/local/CyberCP') import django @@ -10,6 +8,8 @@ try: django.setup() except: pass + + import pexpect from plogical import CyberCPLogFileWriter as logging import subprocess @@ -34,7 +34,6 @@ from xml.etree import ElementTree from xml.dom import minidom import time from shutil import copy -from distutils.dir_util import copy_tree from random import randint from plogical.processUtilities import ProcessUtilities @@ -71,6 +70,8 @@ class backupUtilities: def prepareBackupMeta(backupDomain, backupName, tempStoragePath, backupPath): try: + connection, cursor = mysqlUtilities.mysqlUtilities.setupConnection() + status = os.path.join(backupPath, 'status') logging.CyberCPLogFileWriter.statusWriter(status, 'Setting up meta data..') @@ -170,50 +171,31 @@ class backupUtilities: databasesXML = Element('Databases') for items in databases: - try: - dbuser = DBUsers.objects.get(user=items.dbUser) - userToTry = items.dbUser - except: - try: - dbusers = DBUsers.objects.all().filter(user=items.dbUser) - userToTry = items.dbUser - for it in dbusers: - dbuser = it - break - - userToTry = mysqlUtilities.mysqlUtilities.fetchuser(items.dbName) - - if userToTry == 0 or userToTry == 1: - continue - - try: - dbuser = DBUsers.objects.get(user=userToTry) - except: - try: - dbusers = DBUsers.objects.all().filter(user=userToTry) - for it in dbusers: - dbuser = it - break - - except BaseException as msg: - logging.CyberCPLogFileWriter.writeToFile( - 'While creating backup for %s, we failed to backup database %s. Error message: %s' % ( - backupDomain, items.dbName, str(msg))) - continue - except BaseException as msg: - logging.CyberCPLogFileWriter.writeToFile( - 'While creating backup for %s, we failed to backup database %s. Error message: %s' % ( - backupDomain, items.dbName, str(msg))) - continue databaseXML = Element('database') child = SubElement(databaseXML, 'dbName') child.text = str(items.dbName) - child = SubElement(databaseXML, 'dbUser') - child.text = str(userToTry) - child = SubElement(databaseXML, 'password') - child.text = str(dbuser.password) + + cursor.execute("select user,host from mysql.db where db='%s'" % (items.dbName)) + databaseUsers = cursor.fetchall() + + for databaseUser in databaseUsers: + + databaseUserXML = Element('databaseUsers') + + child = SubElement(databaseUserXML, 'dbUser') + child.text = databaseUser[0] + + child = SubElement(databaseUserXML, 'dbHost') + child.text = databaseUser[1] + + ## Fetch user password + dbuser = DBUsers.objects.get(user=databaseUser[0]) + child = SubElement(databaseUserXML, 'password') + child.text = str(dbuser.password) + + databaseXML.append(databaseUserXML) databasesXML.append(databaseXML) @@ -232,7 +214,6 @@ class backupUtilities: child.text = items metaFileXML.append(aliasesXML) - except BaseException as msg: logging.CyberCPLogFileWriter.statusWriter(status, '%s. [167:prepMeta]' % (str(msg))) @@ -260,7 +241,6 @@ class backupUtilities: dnsRecordsXML.append(dnsRecordXML) metaFileXML.append(dnsRecordsXML) - except BaseException as msg: logging.CyberCPLogFileWriter.statusWriter(status, '%s. [158:prepMeta]' % (str(msg))) @@ -316,6 +296,7 @@ class backupUtilities: except BaseException as msg: + logging.CyberCPLogFileWriter.writeToFile("%s [207][5009]" % (str(msg))) logging.CyberCPLogFileWriter.statusWriter(status, "%s [207][5009]" % (str(msg))) return 0, str(msg) @@ -562,6 +543,8 @@ class backupUtilities: domain = backupMetaData.find('masterDomain').text phpSelection = backupMetaData.find('phpSelection').text externalApp = backupMetaData.find('externalApp').text + VERSION = backupMetaData.find('VERSION').text + BUILD = backupMetaData.find('BUILD').text ### Fetch user details @@ -619,14 +602,35 @@ class backupUtilities: website = Websites.objects.get(domain=domain) for database in databases: + dbName = database.find('dbName').text - dbUser = database.find('dbUser').text - if mysqlUtilities.mysqlUtilities.createDatabase(dbName, dbUser, "cyberpanel") == 0: - raise BaseException("Failed to create Databases!") + if VERSION == '2.1' and BUILD == '1': + first = 1 - newDB = Databases(website=website, dbName=dbName, dbUser=dbUser) - newDB.save() + databaseUsers = database.findall('databaseUsers') + + for databaseUser in databaseUsers: + + dbUser = databaseUser.find('dbUser').text + + if first: + if mysqlUtilities.mysqlUtilities.createDatabase(dbName, dbUser, "cyberpanel") == 0: + raise BaseException("Failed to create Databases!") + + newDB = Databases(website=website, dbName=dbName, dbUser=dbUser) + newDB.save() + first = 0 + + + else: + dbUser = database.find('dbUser').text + + if mysqlUtilities.mysqlUtilities.createDatabase(dbName, dbUser, "cyberpanel") == 0: + raise BaseException("Failed to create Databases!") + + newDB = Databases(website=website, dbName=dbName, dbUser=dbUser) + newDB.save() ## Create dns zone @@ -692,6 +696,8 @@ class backupUtilities: ## extracting master domain for later use backupMetaData = ElementTree.parse(os.path.join(completPath, "meta.xml")) masterDomain = backupMetaData.find('masterDomain').text + VERSION = backupMetaData.find('VERSION').text + BUILD = backupMetaData.find('BUILD').text twoPointO = 0 try: @@ -854,10 +860,31 @@ class backupUtilities: databases = backupMetaData.findall('Databases/database') for database in databases: + dbName = database.find('dbName').text - password = database.find('password').text - if mysqlUtilities.mysqlUtilities.restoreDatabaseBackup(dbName, completPath, password) == 0: - raise BaseException + + if VERSION == '2.1' and BUILD == '1': + first = 1 + + databaseUsers = database.findall('databaseUsers') + + for databaseUser in databaseUsers: + + dbUser = databaseUser.find('dbUser').text + dbHost = databaseUser.find('dbHost').text + password = databaseUser.find('password').text + + if first: + first = 0 + if mysqlUtilities.mysqlUtilities.restoreDatabaseBackup(dbName, completPath, password, 1) == 0: + raise BaseException + + mysqlUtilities.mysqlUtilities.createDatabase(dbName, dbUser, password, 0, dbHost) + + else: + password = database.find('password').text + if mysqlUtilities.mysqlUtilities.restoreDatabaseBackup(dbName, completPath, password) == 0: + raise BaseException ## Databases restored diff --git a/plogical/dnsUtilities.py b/plogical/dnsUtilities.py index 4120740c5..401394dae 100755 --- a/plogical/dnsUtilities.py +++ b/plogical/dnsUtilities.py @@ -41,7 +41,7 @@ class DNS: self.status = data[2].rstrip('\n') return 1 else: - logging.CyberCPLogFileWriter.writeToFile('User %s does not have CloudFlare configured.' % (self.admin.userName)) + #logging.CyberCPLogFileWriter.writeToFile('User %s does not have CloudFlare configured.' % (self.admin.userName)) return 0 def cfTemplate(self, zoneDomain, admin, enableCheck=None): @@ -711,26 +711,30 @@ class DNS: ## Add Record to CF if SYNC Enabled - dns = DNS() - dns.admin = zone.admin - dns.loadCFKeys() + try: - cf = CloudFlare.CloudFlare(email=dns.email, token=dns.key) + dns = DNS() + dns.admin = zone.admin + dns.loadCFKeys() - if dns.status == 'Enable': - try: - params = {'name': zone.name, 'per_page': 50} - zones = cf.zones.get(params=params) + cf = CloudFlare.CloudFlare(email=dns.email, token=dns.key) - for zone in sorted(zones, key=lambda v: v['name']): - zone = zone['id'] + if dns.status == 'Enable': + try: + params = {'name': zone.name, 'per_page': 50} + zones = cf.zones.get(params=params) - DNS.createDNSRecordCloudFlare(cf, zone, name, type, value, ttl, priority) + for zone in sorted(zones, key=lambda v: v['name']): + zone = zone['id'] - except CloudFlare.exceptions.CloudFlareAPIError as e: - logging.CyberCPLogFileWriter.writeToFile(str(e)) - except Exception as e: - logging.CyberCPLogFileWriter.writeToFile(str(e)) + DNS.createDNSRecordCloudFlare(cf, zone, name, type, value, ttl, priority) + + except CloudFlare.exceptions.CloudFlareAPIError as e: + logging.CyberCPLogFileWriter.writeToFile(str(e)) + except Exception as e: + logging.CyberCPLogFileWriter.writeToFile(str(e)) + except: + pass except BaseException as msg: logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [createDNSRecord]") diff --git a/plogical/mysqlUtilities.py b/plogical/mysqlUtilities.py index 30cfc9707..8408d1a3f 100755 --- a/plogical/mysqlUtilities.py +++ b/plogical/mysqlUtilities.py @@ -107,22 +107,33 @@ class mysqlUtilities: return 0, 0 @staticmethod - def createDatabase(dbname,dbuser,dbpassword): + def createDatabase(dbname,dbuser,dbpassword, dbcreate = 1, host = None): try: + if dbcreate: + HostToUse = mysqlUtilities.LOCALHOST + else: + HostToUse = host + connection, cursor = mysqlUtilities.setupConnection() if connection == 0: return 0 - cursor.execute("CREATE DATABASE " + dbname) + + ## Create db + + if dbcreate: + cursor.execute("CREATE DATABASE " + dbname) + + ## create user if mysqlUtilities.REMOTEHOST.find('ondigitalocean') > -1: query = "CREATE USER '%s'@'%s' IDENTIFIED WITH mysql_native_password BY '%s'" % ( - dbuser, mysqlUtilities.LOCALHOST, dbpassword) + dbuser, HostToUse, dbpassword) else: query = "CREATE USER '" + dbuser + "'@'%s' IDENTIFIED BY '" % ( - mysqlUtilities.LOCALHOST) + dbpassword + "'" + HostToUse) + dbpassword + "'" if os.path.exists(ProcessUtilities.debugPath): logging.CyberCPLogFileWriter.writeToFile(query) @@ -130,14 +141,15 @@ class mysqlUtilities: cursor.execute(query) if mysqlUtilities.RDS == 0: - cursor.execute("GRANT ALL PRIVILEGES ON " + dbname + ".* TO '" + dbuser + "'@'%s'" % (mysqlUtilities.LOCALHOST)) + cursor.execute("GRANT ALL PRIVILEGES ON " + dbname + ".* TO '" + dbuser + "'@'%s'" % (HostToUse)) if os.path.exists(ProcessUtilities.debugPath): - logging.CyberCPLogFileWriter.writeToFile("GRANT ALL PRIVILEGES ON " + dbname + ".* TO '" + dbuser + "'@'%s'" % (mysqlUtilities.LOCALHOST)) + logging.CyberCPLogFileWriter.writeToFile("GRANT ALL PRIVILEGES ON " + dbname + ".* TO '" + dbuser + "'@'%s'" % (HostToUse)) else: cursor.execute( - "GRANT INDEX, DROP, UPDATE, ALTER, CREATE, SELECT, INSERT, DELETE ON " + dbname + ".* TO '" + dbuser + "'@'%s'" % (mysqlUtilities.LOCALHOST)) + "GRANT INDEX, DROP, UPDATE, ALTER, CREATE, SELECT, INSERT, DELETE ON " + dbname + ".* TO '" + dbuser + "'@'%s'" % (HostToUse)) if os.path.exists(ProcessUtilities.debugPath): - logging.CyberCPLogFileWriter.writeToFile("GRANT INDEX, DROP, UPDATE, ALTER, CREATE, SELECT, INSERT, DELETE ON " + dbname + ".* TO '" + dbuser + "'@'%s'" % (mysqlUtilities.LOCALHOST)) + logging.CyberCPLogFileWriter.writeToFile("GRANT INDEX, DROP, UPDATE, ALTER, CREATE, SELECT, INSERT, DELETE ON " + dbname + ".* TO '" + dbuser + "'@'%s'" % (HostToUse)) + connection.close() return 1 @@ -207,7 +219,14 @@ class mysqlUtilities: return 0 cursor.execute("DROP DATABASE `%s`" % (dbname)) - cursor.execute("DROP USER '"+dbuser+"'@'%s'" % (mysqlUtilities.LOCALHOST)) + + ## Try deleting all user who had priviliges on db + + cursor.execute("select user,host from mysql.db where db='%s'" % (dbname)) + databaseUsers = cursor.fetchall() + + for databaseUser in databaseUsers: + cursor.execute("DROP USER '"+databaseUser[0]+"'@'%s'" % (databaseUser[1])) connection.close() return 1 @@ -337,6 +356,7 @@ password=%s return 0 if passwordCheck == None: + connection, cursor = mysqlUtilities.setupConnection() if connection == 0: