File: //opt/cwprads/update_primary_domain
#!/usr/lib/cwprads/venv/bin/python3
import argparse
import sys
import subprocess
import os
import re
import pymysql
API_PATH = "/scripts/cwp_api"
def change_primary_domain(username, olddomain, newdomain):
root_cwp = pymysql.connect(
read_default_file='/root/.my.cnf', database="root_cwp"
)
cur = root_cwp.cursor(pymysql.cursors.DictCursor)
# Sanity checks
cur.execute('SELECT * FROM user WHERE username=%s', username)
result = cur.fetchall()
if len(result) == 0:
print("User not found!")
sys.exit(2)
if len(result) > 1:
print("Multipe records for user found!")
sys.exit(3)
if result[0]['domain'] != olddomain:
print(
f"Account domain {result[0]['domain']} doesn't",
f"match specified olddomain, {olddomain} ",
)
cur.execute('SELECT * FROM user WHERE domain=%s', olddomain)
result = cur.fetchall()
if len(result) == 0:
print(f"Domain {olddomain} not found.")
sys.exit(4)
print(f"Domain found on other account {result[0]['username']}")
sys.exit(5)
# Update domain in mysql
cur.execute(
'UPDATE user SET domain=%s WHERE id=%s', (newdomain, result[0]['id'])
)
root_cwp.commit()
# Rebuild and reload services
apicmds = ["webservers rebuild_all", "webservers reload"]
if os.path.isfile(f"/var/named/{olddomain}.db"):
os.rename(f"/var/named/{olddomain}.db", f"/var/named/{newdomain}.db")
elif os.path.isfile(f"/var/named/{newdomain}.db"):
print(
f"No zone found for {olddomain},",
f"a zone already exists for {newdomain}",
)
else:
print(
f"No zone found for {olddomain} or {newdomain},",
"generating a new zone",
)
apicmds.extend([f"account rebuild_var_named {username} {newdomain}"])
try:
with open('/etc/named.conf') as file:
file_contents = file.read()
except (FileNotFoundError, PermissionError) as e:
print(f"Error opening named.conf: {e}")
sys.exit(1)
file_contents = re.sub(
fr'(^zone.*$)',
lambda match: match.group(0).replace(olddomain, newdomain),
file_contents,
flags=re.MULTILINE,
)
try:
with open('/etc/named.conf', 'w') as file:
file.write(file_contents)
except (PermissionError, OSError) as e:
print(f"Error writing named.conf: {e}")
sys.exit(1)
try:
result = subprocess.run(
['named-checkconf', '-z', '/etc/named.conf'],
capture_output=True,
text=True,
)
result.check_returncode()
print("named.conf check passed.")
except (subprocess.CalledProcessError, FileNotFoundError) as e:
print(
f"An error occurred while running 'named-checkconf': {e} \n{e.stdout}"
)
sys.exit(1)
for apicmd in apicmds:
command = [API_PATH]
command.extend(apicmd.split(" "))
print(f"Running {command}")
subprocess.run(command, check=False)
subprocess.run(["/opt/imh-cwp-dns/update_zone", newdomain], check=False)
# Update mail dirs
if os.path.isdir(f"/var/vmail/{olddomain}"):
if not os.path.isdir(f"/var/vmail/{newdomain}"):
print(f"Maildir for {newdomain} found, moving")
os.rename(f"/var/vmail/{olddomain}", f"/var/vmail/{newdomain}")
else:
print(
f"Target mail dir /var/vmail/{newdomain} already exists!",
"Please check the mail dirs in /var/vmail",
)
else:
print(f"No maildir for {olddomain} found, not moving")
sys.exit(0)
parser = argparse.ArgumentParser(description="Change CWP Primary Domain")
parser.add_argument("username", type=str, help="Username to change domain for")
parser.add_argument("olddomain", type=str, help="Old Primary Domain")
parser.add_argument("newdomain", type=str, help="New Primary Domain")
args = parser.parse_args()
change_primary_domain(args.username, args.olddomain, args.newdomain)