mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-10-29 17:26:44 +01:00
163 lines
6.9 KiB
Python
163 lines
6.9 KiB
Python
import subprocess, shlex
|
|
import install
|
|
import time
|
|
|
|
class mysqlUtilities:
|
|
|
|
@staticmethod
|
|
def createDatabase(dbname, dbuser, dbpassword, publicip):
|
|
"""
|
|
Create database and user with improved error handling and validation
|
|
"""
|
|
import logging
|
|
|
|
# Validate input parameters
|
|
if not dbname or not dbuser or not dbpassword:
|
|
logging.InstallLog.writeToFile(f"ERROR: Missing required parameters - dbname: {dbname}, dbuser: {dbuser}, password: {'SET' if dbpassword else 'EMPTY'}")
|
|
return 0
|
|
|
|
logging.InstallLog.writeToFile(f"Creating database '{dbname}' and user '{dbuser}' with password length: {len(dbpassword)}")
|
|
|
|
try:
|
|
# Step 1: Create database
|
|
createDB = "CREATE DATABASE IF NOT EXISTS " + dbname
|
|
|
|
try:
|
|
from json import loads
|
|
mysqlData = loads(open("/etc/cyberpanel/mysqlPassword", 'r').read())
|
|
|
|
initCommand = 'mariadb -h %s --port %s -u %s -p%s -e "' % (mysqlData['mysqlhost'], mysqlData['mysqlport'], mysqlData['mysqluser'], mysqlData['mysqlpassword'])
|
|
remote = 1
|
|
logging.InstallLog.writeToFile("Using remote MySQL configuration")
|
|
except:
|
|
passFile = "/etc/cyberpanel/mysqlPassword"
|
|
|
|
f = open(passFile)
|
|
data = f.read()
|
|
password = data.split('\n', 1)[0]
|
|
|
|
initCommand = 'mariadb -u root -p' + password + ' -e "'
|
|
remote = 0
|
|
logging.InstallLog.writeToFile("Using local MySQL configuration")
|
|
|
|
command = initCommand + createDB + '"'
|
|
|
|
logging.InstallLog.writeToFile(f"Executing database creation: CREATE DATABASE IF NOT EXISTS {dbname}")
|
|
|
|
if install.preFlightsChecks.debug:
|
|
print(command)
|
|
time.sleep(10)
|
|
|
|
cmd = shlex.split(command)
|
|
res = subprocess.call(cmd)
|
|
|
|
if res != 0:
|
|
logging.InstallLog.writeToFile(f"ERROR: Database creation failed with return code: {res}")
|
|
return 0
|
|
else:
|
|
logging.InstallLog.writeToFile(f"✓ Database '{dbname}' created successfully")
|
|
|
|
# Step 2: Create user (drop first if exists to avoid conflicts)
|
|
if remote:
|
|
dropUser = f"DROP USER IF EXISTS '{dbuser}'@'{publicip}'"
|
|
createUser = f"CREATE USER '{dbuser}'@'{publicip}' IDENTIFIED BY '{dbpassword}'"
|
|
host = publicip
|
|
else:
|
|
dropUser = f"DROP USER IF EXISTS '{dbuser}'@'localhost'"
|
|
createUser = f"CREATE USER '{dbuser}'@'localhost' IDENTIFIED BY '{dbpassword}'"
|
|
host = 'localhost'
|
|
|
|
# Drop user if exists
|
|
command = initCommand + dropUser + '"'
|
|
logging.InstallLog.writeToFile(f"Dropping existing user '{dbuser}'@'{host}' if exists")
|
|
|
|
if install.preFlightsChecks.debug:
|
|
print(command)
|
|
time.sleep(10)
|
|
|
|
cmd = shlex.split(command)
|
|
subprocess.call(cmd) # Ignore return code for DROP USER IF EXISTS
|
|
|
|
# Create user
|
|
command = initCommand + createUser + '"'
|
|
logging.InstallLog.writeToFile(f"Creating user '{dbuser}'@'{host}' with password")
|
|
|
|
if install.preFlightsChecks.debug:
|
|
print(command)
|
|
time.sleep(10)
|
|
|
|
cmd = shlex.split(command)
|
|
res = subprocess.call(cmd)
|
|
|
|
if res != 0:
|
|
logging.InstallLog.writeToFile(f"ERROR: User creation failed with return code: {res}")
|
|
return 0
|
|
else:
|
|
logging.InstallLog.writeToFile(f"✓ User '{dbuser}'@'{host}' created successfully")
|
|
|
|
# Step 3: Handle special cases and grant privileges
|
|
if remote:
|
|
### DigitalOcean MySQL compatibility
|
|
if mysqlData['mysqlhost'].find('ondigitalocean') > -1:
|
|
alterUserPassword = f"ALTER USER '{dbuser}'@'{publicip}' IDENTIFIED WITH mysql_native_password BY '{dbpassword}'"
|
|
command = initCommand + alterUserPassword + '"'
|
|
|
|
logging.InstallLog.writeToFile(f"Applying DigitalOcean MySQL compatibility for '{dbuser}'@'{publicip}'")
|
|
|
|
if install.preFlightsChecks.debug:
|
|
print(command)
|
|
time.sleep(10)
|
|
|
|
cmd = shlex.split(command)
|
|
res = subprocess.call(cmd)
|
|
|
|
if res != 0:
|
|
logging.InstallLog.writeToFile(f"WARNING: DigitalOcean ALTER USER failed with return code: {res}")
|
|
|
|
## RDS vs Standard MySQL permissions
|
|
if mysqlData['mysqlhost'].find('rds.amazon') == -1:
|
|
grantPrivileges = f"GRANT ALL PRIVILEGES ON {dbname}.* TO '{dbuser}'@'{publicip}'"
|
|
else:
|
|
grantPrivileges = f"GRANT INDEX, DROP, UPDATE, ALTER, CREATE, SELECT, INSERT, DELETE ON {dbname}.* TO '{dbuser}'@'{publicip}'"
|
|
host = publicip
|
|
else:
|
|
grantPrivileges = f"GRANT ALL PRIVILEGES ON {dbname}.* TO '{dbuser}'@'localhost'"
|
|
host = 'localhost'
|
|
|
|
# Grant privileges
|
|
command = initCommand + grantPrivileges + '"'
|
|
logging.InstallLog.writeToFile(f"Granting privileges on database '{dbname}' to user '{dbuser}'@'{host}'")
|
|
|
|
if install.preFlightsChecks.debug:
|
|
print(command)
|
|
time.sleep(10)
|
|
|
|
cmd = shlex.split(command)
|
|
res = subprocess.call(cmd)
|
|
|
|
if res != 0:
|
|
logging.InstallLog.writeToFile(f"ERROR: Grant privileges failed with return code: {res}")
|
|
return 0
|
|
else:
|
|
logging.InstallLog.writeToFile(f"✓ Privileges granted successfully")
|
|
|
|
# Step 4: Flush privileges
|
|
flushCommand = initCommand + "FLUSH PRIVILEGES" + '"'
|
|
logging.InstallLog.writeToFile("Flushing MySQL privileges")
|
|
|
|
cmd = shlex.split(flushCommand)
|
|
res = subprocess.call(cmd)
|
|
|
|
if res != 0:
|
|
logging.InstallLog.writeToFile(f"WARNING: FLUSH PRIVILEGES failed with return code: {res}")
|
|
else:
|
|
logging.InstallLog.writeToFile("✓ Privileges flushed successfully")
|
|
|
|
logging.InstallLog.writeToFile(f"✅ Database '{dbname}' and user '{dbuser}' created successfully!")
|
|
return 1
|
|
|
|
except BaseException as msg:
|
|
logging.InstallLog.writeToFile(f"❌ CRITICAL ERROR in createDatabase: {str(msg)}")
|
|
import traceback
|
|
logging.InstallLog.writeToFile(f"Full traceback: {traceback.format_exc()}")
|
|
return 0 |