Skip to content
Snippets Groups Projects
set_app_domain.py 4.27 KiB
Newer Older
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Script to set the domain of an existing MS, CM or Monitor
'''
import os
import re
import subprocess
import sys

import utils
from utils import log


class SetAppDomain():
    USAGE = '''%s [-d] [-h] [app] <domain>
    -d: Debug mode (can be started with non root users).
    -h: Show this message.
    app: The application for which the new domain should be set.
         Possible values:
           "ms" (MediaServer), "cm" (Campus Manager), "mon" (Monitor).
         It is possible to specify which MS instance should be targetted
         by using this format: ms-<instance name> (for example ms-msuser).
    domain: The new domain.''' % __file__
    MS_INSTANCE_USER_PATTERN = r'^[a-z0-9\-]+$'
    NGINX_SERVER_NAME_PATTERN = r'^\s*server_name\s+([\w\-\_\.\ ]+);$'

    def __init__(self, *args):
        self.display_header()
        args = list(args)
        # Check if help is required
        if '-h' in args:
            log('USAGE: ' + self.USAGE)
            sys.exit(0)
        # Check current dir
        root_dir = utils.get_dir(__file__)
        if root_dir != '':
            os.chdir(root_dir)
        self.root_dir = root_dir
        # Add to python path
        if root_dir not in sys.path:
            sys.path.append(root_dir)
        # Check that this script is run by root
        self.debug = '-d' in args
        if self.debug:
            args.remove('-d')
        whoami = subprocess.check_output(['whoami']).decode('utf-8').strip()
        if whoami != 'root' and not self.debug:
            log('This script should be run as root user.')
            sys.exit(1)
        # Parse args
        if not args:
            log('Not enough arguments.')
            log('USAGE: ' + self.USAGE)
            sys.exit(1)
        new_domain = args.pop()
        if args:
            app = args.pop()
        # Change domain
        instance = None
        if app == 'cm':
            nginx_conf = '/etc/nginx/sites-available/skyreach.conf'
        elif app == 'mon':
            nginx_conf = '/etc/nginx/sites-available/msmonitor.conf'
        elif app == 'ms' or app.startswith('ms-'):
            if app.startswith('ms-'):
                instance = app[3:].strip('. -\t\n')
                if not re.match(self.MS_INSTANCE_USER_PATTERN, instance):
                    log('Invalid MS instance requested. Validation reg exp is: %s' % self.MS_INSTANCE_USER_PATTERN)
                    sys.exit(1)
            else:
                instance = 'msuser'
            nginx_conf = '/etc/nginx/sites-available/mediaserver-%s.conf' % instance
        else:
            log('Invalid app name requested.')
            log('USAGE: ' + self.USAGE)
            sys.exit(1)
        self.change_nginx_domain(nginx_conf, new_domain)
        if instance:
            self.change_ms_instance_domain(instance, new_domain)
        sys.exit(0)

    def change_nginx_domain(self, path, new_domain):
        log('Checking Nginx configuration file "%s".' % path)
        if not os.path.exists(path):
            log('The configuration file does not exist.')
            sys.exit(1)
        with open(path, 'r') as fo:
            vhost = fo.read()
        new_vhost = ''
        for line in vhost.split('\n'):
            if re.match(self.NGINX_SERVER_NAME_PATTERN, line):
                new_vhost += re.sub(self.NGINX_SERVER_NAME_PATTERN, line, new_domain) + '\n'
            else:
                new_vhost += line + '\n'
        new_vhost = new_vhost.strip() + '\n'
        if new_vhost != vhost:
            if self.debug:
                log('New Nginx conf:')
                log(new_vhost)
            else:
                with open(path, 'w') as fo:
                    fo.write(new_vhost)
                log('The configuration file "%s" has been update.' % path)
        else:
            log('The configuration file "%s" is already up to date.' % path)

    def change_ms_instance_domain(self, instance, new_domain):
        # TODO: set MS url in site settings
        # TODO: reset all local resources managers
        try:
            utils.run_commands(['sudo su %s -c "ls"' % instance])
        except Exception as e:
            log('Unable to set MS domain:\n%s' % e)
            sys.exit(1)
        else:
            log('MS domain changed')


if __name__ == '__main__':
    SetAppDomain(*sys.argv[1:])