bug fix: create proper backups incase of multiple database users

This commit is contained in:
Usman Nasir
2021-04-11 22:58:22 +05:00
parent 8ce49c303d
commit c83eb3ab6c
5 changed files with 136 additions and 81 deletions

View File

@@ -1,5 +1,3 @@
from django.db import models
class DBUsers(models.Model):

View File

@@ -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]')
###

View File

@@ -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,51 +171,32 @@ 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')
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)
metaFileXML.append(databasesXML)
@@ -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,7 +602,28 @@ class backupUtilities:
website = Websites.objects.get(domain=domain)
for database in databases:
dbName = database.find('dbName').text
if VERSION == '2.1' and BUILD == '1':
first = 1
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:
@@ -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,7 +860,28 @@ class backupUtilities:
databases = backupMetaData.findall('Databases/database')
for database in databases:
dbName = database.find('dbName').text
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

View File

@@ -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,6 +711,8 @@ class DNS:
## Add Record to CF if SYNC Enabled
try:
dns = DNS()
dns.admin = zone.admin
dns.loadCFKeys()
@@ -731,6 +733,8 @@ class DNS:
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]")

View File

@@ -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
## 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: