HEX
Server: Apache/2.4.65 (Unix) OpenSSL/1.1.1k
System: Linux vps109042.inmotionhosting.com 4.18.0 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64
User: cisa (1010)
PHP: 8.2.30
Disabled: NONE
Upload Files
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)