Mini Shell

Direktori : /opt/maint/bin/
Upload File :
Current File : //opt/maint/bin/addon_serveraliases.py

#!/opt/imh-python/bin/python3
"""Check for bugged addon domains which cpanel adds as parked"""
from argparse import ArgumentParser
from pathlib import Path
from logging import Logger
import traceback
import sys
import rads
import yaml


def check_serveraliases(log: Logger, noop: bool):
    """Iterate primary domain configs and check serveraliases on each"""
    for cpuser_entry in Path('/var/cpanel/users').iterdir():
        user = cpuser_entry.name
        if not rads.is_cpuser(user):
            continue
        try:
            userdata = rads.UserData(user)
        except Exception as exc:
            log.warning('%s - %s: %s', user, type(exc).__name__, exc)
            continue
        primary = userdata.primary.domain
        userdata_path = Path('/var/cpanel/userdata', user)
        addons = {x.domain for x in userdata.addons}
        if not addons:
            continue
        addons.update(f"www.{x.domain}" for x in userdata.addons)
        check_primary_file(log, noop, userdata_path / primary, addons)
        check_primary_file(log, noop, userdata_path / f"{primary}_SSL", addons)


def check_primary_file(log: Logger, noop: bool, path: Path, addons: list[str]):
    """Check a primary domain's config file in userdata to see if an addon
    domain was erroneously added to the "serveralias" line"""
    try:
        with open(path, encoding='utf-8') as file:
            data = yaml.load(file, Loader=yaml.SafeLoader)
    except (OSError, ValueError):
        return
    old = data['serveralias'].split()
    if not old:
        # there should have been at least a www alias for the main
        # domain, so if we hit here, the file is mangled or the
        # file format changed. Don't touch it
        return
    new = [x for x in old if x not in addons]
    if old == new:
        return  # No changes
    if not new:
        return  # Mangled file
    log.info("old %s serveraliases: %s", path, ' '.join(old))
    log.info("new %s serveraliases: %s", path, ' '.join(new))
    data['serveralias'] = ' '.join(new)
    if noop:
        return
    save_conf(path, data)


def save_conf(path: Path, data: dict):
    """Save config changes by writing to a temp file and then moving it into
    place. Saving in this method avoids race conditions from cPanel trying
    to read it before we're done flushing contents to disk"""
    tmp_path = path.parent / f".{path.name}.tmp"
    with open(tmp_path, 'w', encoding='utf-8') as file:
        yaml.dump(data, file, default_flow_style=False)
    tmp_path.rename(path)


def main():
    """Setup logging and run check_serveraliases"""
    # blank argparse adds -h/--help
    parser = ArgumentParser(description=__doc__)
    parser.add_argument('--noop', action='store_true', help='test mode')
    noop: bool = parser.parse_args().noop
    if noop:
        fmt = '%(asctime)s %(levelname)s NOOP: %(message)s'
    else:
        fmt = '%(asctime)s %(levelname)s %(message)s'
    log = rads.setup_logging(
        path='/var/log/maint/addon_serveraliases.log',
        name='addon_serveraliases',
        fmt=fmt,
        loglevel='DEBUG',
        print_out='stdout',
        chown=(0, 0),
        chmod=0o700,
    )
    try:
        check_serveraliases(log, noop)
    except KeyboardInterrupt:
        log.warning("Canceling run on ^C")
        sys.exit(1)
    except Exception:
        log.critical(traceback.format_exc())
        sys.exit(1)


if __name__ == '__main__':
    main()

Zerion Mini Shell 1.0