コード例 #1
0
ファイル: ldap.py プロジェクト: UPCnet/gummanager.cli
    def add_users(self, **kwargs):
        """
            Batch add users from a file of users. <users-file> is expected to
            contain a

            CSV with columns: username, display name, password
        """
        branch_name = getOptionFrom(kwargs, 'branch-name', None)
        usersfile = getOptionFrom(kwargs, '<users-file>')

        ld = self.Server
        # Configure a different server for batch if present
        if 'batch_server' in self.config:
            ld.set_server(server=self.config['batch_server'], port=self.config['port'])

        run_recipe_with_confirmation(
            'Batch create users from file',
            {
                'server': ld.ldap_uri,
                'branch': branch_name,

            },
            ld.add_users,
            branch_name,
            usersfile,
            stop_on_errors=False
        )
コード例 #2
0
ファイル: ldap.py プロジェクト: UPCnet/gummanager.cli
    def list_users(self, **kwargs):
        """
            Prints a list of all the users of the branch specified by <branch-name>, sorted by username
            You can filter the results (case insensitive) with the --filter=<text> option
        """

        branch_name = getOptionFrom(kwargs, 'branch-name', None)
        u_filter = getOptionFrom(kwargs, 'filter', default=None)

        users = run_recipe_without_confirmation(
            self.Server.list_users,
            branch_name,
            filter=u_filter
        )

        table = GUMTable(hrules='FRAME')
        table.from_dict_list(
            users,
            formatters={
                'name': highlighter(default='bold_yellow')
            },
            titles={
                'name': 'Username',
                'sn': 'SN'
            })
        print table.sorted('name')
コード例 #3
0
ファイル: genweb.py プロジェクト: UPCnet/gummanager.cli
    def add_instance(self, **kwargs):
        instance_name = getOptionFrom(kwargs, 'instance-name')
        environment = getOptionFrom(kwargs, 'env', default='')
        mountpoint = getOptionFrom(kwargs, 'mpoint', default='')
        ldap_branch = getOptionFrom(kwargs, 'ldap-branch', instance_name)
        allow_shared_mountpoint = getOptionFrom(kwargs, 'f', False)
        create = False

        self.extra_config = {'ldap_config': getConfiguration(kwargs['--config'])['ldap']}
        genweb_server = self.Server

        if environment and mountpoint:
            if not genweb_server.is_mountpoint_available(environment, mountpoint, allow_shared=allow_shared_mountpoint):
                print "This mountpoint is unavailable"
                return
            create = True
        else:
            available_mountpoint = genweb_server.get_available_mountpoint()
            if available_mountpoint:
                environment = available_mountpoint['environment']
                mountpoint = available_mountpoint['id']
                create = True
            else:
                print "There's no available mountpoint in any environment"
                return

        ldap_config = getConfiguration(kwargs['--config'])['ldap']
        ldap_password = ldap_config['branch_admin_password']

        if create:
            siteid = instance_name
            title = siteid.capitalize()
            language = 'ca'

            env_params = genweb_server.get_environment(environment)
            logecho = LogEcho(
                env_params.ssh_user,
                env_params.server,
                '{}/zc1.log'.format(env_params.log_folder),
                target_lines=326,
                filters=['INFO']
            )

            run_recipe_with_confirmation(
                "Adding a new Genweb",
                {
                    "name": siteid,
                    "server": environment,
                    "mountpoint": mountpoint,
                    "ldap_branch": ldap_branch,
                },
                genweb_server.new_instance,
                *[instance_name, environment, mountpoint, title, language, ldap_branch, ldap_password, logecho]
            )
コード例 #4
0
ファイル: ldap.py プロジェクト: UPCnet/gummanager.cli
    def check_user(self, **kwargs):
        """
            Checks existence and password of a user on the users folder of the branch specified by <branch-name>
        """

        branch_name = getOptionFrom(kwargs, 'branch-name', None)
        username = getOptionFrom(kwargs, 'ldap-username')
        password = getOptionFrom(kwargs, 'password', mask=True)

        run_recipe_without_confirmation(
            self.Server.check_user,
            branch_name, username, password)
コード例 #5
0
ファイル: utalk.py プロジェクト: UPCnet/gummanager.cli
    def add_instance(self, **kwargs):
        """
            Adds a existing max instance to the list used by utalk to
            know to which max route incoming messages and tweets
        """
        step_log('Checking parameters consistency')

        instance_name = getOptionFrom(kwargs, 'domain')
        hashtag = getOptionFrom(kwargs, 'hashtag', '')
        language = getOptionFrom(kwargs, 'language', 'ca')
        username = getOptionFrom(kwargs, 'username', 'restricted')
        password = getOptionFrom(kwargs, 'password')

        padded_log('Checking max server ...')
        max_config = getConfiguration(kwargs['--config'])['max']
        maxserver = MaxServer(max_config)
        max_instance = maxserver.get_instance(instance_name)

        if not max_instance:
            padded_error("There's no defined max server named {}".format(instance_name))
            return None

        padded_log('Checking oauth server ...')
        oauth_server_url = max_instance['oauth']
        oauth_instance_name = oauth_server_url.split('/')[-1]

        oauth_config = getConfiguration(kwargs['--config'])['oauth']
        oauthserver = OauthServer(oauth_config)
        oauth_instance = oauthserver.get_instance(oauth_instance_name)

        if not oauth_instance:
            padded_error("Max server {} is bound to an oauth {} that doesn't exist".format(instance_name, oauth_instance_name))
            return None

        run_recipe_with_confirmation(
            'Adding a new utalk domain',
            {
                'server': max_instance['server']['dns'],
                'name': instance_name,
                'hashtag': hashtag,
                'language': language,
            },
            self.Server.add_instance,
            name=instance_name,
            oauthserver=oauth_instance,
            maxserver=max_instance,
            hashtag=hashtag,
            restricted_user=username,
            restricted_user_password=password,
            language=language)
コード例 #6
0
ファイル: ldap.py プロジェクト: UPCnet/gummanager.cli
    def delete_user(self, **kwargs):
        """
            Deletes a single user from the users folder of the branch specified by <branch-name>
        """
        branch_name = getOptionFrom(kwargs, 'branch-name', None)
        username = getOptionFrom(kwargs, 'ldap-username')

        run_recipe_with_confirmation(
            "Adding a new user to branch",
            {
                "server": self.Server.ldap_uri,
                "branch_name": branch_name,
                "username": username
            },
            self.Server.delete_user,
            branch_name, username)
コード例 #7
0
ファイル: oauth.py プロジェクト: UPCnet/gummanager.cli
    def test(self, **kwargs):
        """
            Tests that oauth instance is working as expected.

            An username and a password of an existing user has to be provided.
        """
        instance_name = getOptionFrom(kwargs, 'instance-name', default='all')
        username = getOptionFrom(kwargs, 'username')
        password = getOptionFrom(kwargs, 'password')
        oauth = self.Server

        run_recipe_without_confirmation(
            oauth.test,
            instance_name, username, password,
            stop_on_errors=False
        )
コード例 #8
0
ファイル: ldap.py プロジェクト: UPCnet/gummanager.cli
    def add_branch(self, **kwargs):
        """
            Adds a new branch named <branch-name> on the root of the ldap server
        """
        branch_name = getOptionFrom(kwargs, 'branch-name', None)
        branch_admin_password = getOptionFrom(kwargs, 'password', mask=True)

        run_recipe_with_confirmation(
            "Adding a new branch",
            {
                "server": self.Server.ldap_uri,
                "branch_name": branch_name
            },
            self.Server.add_branch,
            branch_name,
            branch_admin_password)
コード例 #9
0
ファイル: max.py プロジェクト: UPCnet/gummanager.cli
    def upgrade(self, **kwargs):
        """
            Upgrades a max server.

            The versions used in the upgrade will be the ones defined in the versions.cfg
            of the buildout used in the instance.
        """
        instance_name = getOptionFrom(kwargs, 'instance-name')
        maxserver = self.Server

        logecho = LogEcho(
            self.config['ssh_user'],
            self.config['server'],
            '{}/{}/var/log/buildout.log'.format(self.config['instances_root'], instance_name),
            filters=['Installing', 'Got', 'Updating', 'Error'],
        )

        run_recipe_with_confirmation(
            'Upgrading an existing max server',
            {
                'name': instance_name,
                'server': self.config['server'],
                'running': maxserver.get_running_version(instance_name),
            },
            maxserver.upgrade,
            instance_name,
            logecho=logecho,
        )
コード例 #10
0
ファイル: ulearn.py プロジェクト: UPCnet/gummanager.cli
    def subscribe_users(self, **kwargs):
        """
            Subscribe users to a bunch of ulearn instance communities.
            User will be subscribed in the accorded roles
        """
        step_log('Checking instance')
        padded_log('Loading existing instances')
        instances = self.Server.get_instances()

        instance_name = getOptionFrom(kwargs, 'instance-name')
        environment = getOptionFrom(kwargs, 'env', default='')
        mountpoint = getOptionFrom(kwargs, 'mpoint', default='')
        subscriptionsfile = getOptionFrom(kwargs, 'subscriptions-file')

        # Get all instances matching instance name
        matched_instances = [instance for instance in instances if instance['plonesite'].replace('bqdc', 'mediolanum') == instance_name]

        # Try to filter by env and mountpoint if provided
        if environment:
            matched_instances = [instance for instance in matched_instances if instance['environment'] == environment]

        if mountpoint:
            matched_instances = [instance for instance in matched_instances if instance['mountpoint'] == mountpoint]

        if not matched_instances:
            padded_error("No instance named {}".format(instance_name))
        elif len(matched_instances) > 1:
            padded_error("More than 1 instance named {}".format(instance_name))
            padded_log("Try again specifying one or both of --mpoint and --env options")

        instance = matched_instances[0]

        run_recipe_with_confirmation(
            'Batch subscribe users to communities',
            {
                'server': instance['environment'],
                'mountpoint': instance['mountpoint'],
                'plonesite': instance['plonesite'],
                'url': instance['url']

            },
            self.Server.batch_subscribe_users,
            instance,
            subscriptionsfile,
            stop_on_errors=False
        )
コード例 #11
0
ファイル: ldap.py プロジェクト: UPCnet/gummanager.cli
    def add_user(self, **kwargs):
        """
            Adds a new user on the users folder of the branch specified by <branch-name>
        """
        branch_name = getOptionFrom(kwargs, 'branch-name', None)
        username = getOptionFrom(kwargs, 'ldap-username')
        password = getOptionFrom(kwargs, 'password', mask=True)

        run_recipe_with_confirmation(
            "Adding a new user to branch",
            {
                "server": self.Server.ldap_uri,
                "branch_name": branch_name,
                "username": username
            },
            self.Server.add_user,
            branch_name, username, password)
コード例 #12
0
ファイル: ulearn.py プロジェクト: UPCnet/gummanager.cli
    def add_users(self, **kwargs):
        """
            Add users from a file to a ulearn instance. User will be added to the
            related ldap branch and max instance.
        """
        step_log('Checking instance')
        padded_log('Loading existing instances')
        instances = self.Server.get_instances()

        instance_name = getOptionFrom(kwargs, 'instance-name')
        environment = getOptionFrom(kwargs, 'env', default='')
        mountpoint = getOptionFrom(kwargs, 'mpoint', default='')
        usersfile = getOptionFrom(kwargs, 'users-file')

        # Get all instances matching instance name
        matched_instances = [instance for instance in instances if instance['plonesite'].replace('bqdc', 'mediolanum') == instance_name]

        # Try to filter by env and mountpoint if provided
        if environment:
            matched_instances = [instance for instance in matched_instances if instance['environment'] == environment]

        if mountpoint:
            matched_instances = [instance for instance in matched_instances if instance['mountpoint'] == mountpoint]

        if not matched_instances:
            padded_error("No instance named {}".format(instance_name))
        elif len(matched_instances) > 1:
            padded_error("More than 1 instance named {}".format(instance_name))
            padded_log("Try again specifying one or both of --mpoint and --env options")

        instance = matched_instances[0]

        run_recipe_with_confirmation(
            'Batch create users from file',
            {
                'server': instance['environment'],
                'mountpoint': instance['mountpoint'],
                'plonesite': instance['plonesite'],
                'url': instance['url']

            },
            self.Server.batch_add_users,
            instance,
            usersfile,
            stop_on_errors=False
        )
コード例 #13
0
ファイル: oauth.py プロジェクト: UPCnet/gummanager.cli
    def allow(self, **kwargs):
        """
            Adds a new ip to the allowed to execute token-bypass endpoint.

            After adding the ip, nginx configuration will be tested and reloaded.
        """
        oauthserver = self.Server
        instance_name = getOptionFrom(kwargs, 'instance-name')
        allowed_ip = getOptionFrom(kwargs, 'ip')

        run_recipe_with_confirmation(
            'Add ip to allowed list ?',
            {
                'server': self.config.nginx['server'],
                'name': instance_name

            },
            oauthserver.add_allowed_ip,
            instance_name, allowed_ip
        )
コード例 #14
0
ファイル: max.py プロジェクト: UPCnet/gummanager.cli
    def add_instance(self, **kwargs):
        """
            Adds a new max instance.

            If only <instance-name> is given, gum will pick the first available <port-index>
            based on the existing instances, and assume <oauth-name> named as the <instance-name>.
            If you want to use a specific port index or oauth instance please specify it.
        """
        maxserver = self.Server

        instance_name = getOptionFrom(kwargs, 'instance-name')
        port_index = getOptionFrom(kwargs, 'port-index', maxserver.get_available_port())

        instance = maxserver.instance_by_port_index(port_index)
        if instance:
            print 'The specified port index is already in use by  "{}" oauth'.format(instance['name'])

        oauth_instance = getOptionFrom(kwargs, 'oauth-instance', instance_name)

        logecho = LogEcho(
            self.config['ssh_user'],
            self.config['server'],
            '{}/{}/var/log/buildout.log'.format(self.config['instances_root'], instance_name),
            filters=['Installing', 'Generated', 'Got', 'Updating'],
        )

        run_recipe_with_confirmation(
            'Adding a new max server',
            {
                'name': instance_name,
                'server': self.config['server'],
                'port_index': port_index,
                'oauth_server': oauth_instance
            },
            maxserver.new_instance,
            instance_name, port_index,
            logecho=logecho,
            oauth_instance=oauth_instance,
        )
コード例 #15
0
ファイル: oauth.py プロジェクト: UPCnet/gummanager.cli
    def disallow(self, **kwargs):
        """
            Removes a ip from the allowed ones to execute token-bypass endpoint.

            The ip must be a ip that is currently added, as this don't generate nginx
            deny statements, only removes the current allow statements.
            After adding the ip, nginx configuration will be tested and reloaded.
        """
        oauthserver = self.Server
        instance_name = getOptionFrom(kwargs, 'instance-name')
        allowed_ip = getOptionFrom(kwargs, 'ip')

        run_recipe_with_confirmation(
            'Add ip to allowed list ?',
            {
                'server': self.config.nginx['server'],
                'name': instance_name

            },
            oauthserver.remove_allowed_ip,
            instance_name, allowed_ip
        )
コード例 #16
0
ファイル: __init__.py プロジェクト: UPCnet/gummanager.cli
def main():
    try:
        getConfiguration()
    except:
        generate = raw_input('> Do you want to generate a sample .gum.conf on this folder to fill up? (Y,n): ')
        if generate.strip().upper() in ['Y', '']:
            # Write a copy of sample.gum.conf with comments stripped
            sample = open(pkg_resources.resource_filename(__name__, 'sample.gum.conf')).read()
            open('.gum.conf', 'w').write(re.sub(r'#.*?(\n|$)', r'\1', sample))

        print 'Done.'
        print
        sys.exit()

    # Workaround to allow empty <branchname> on ldap commands
    sysargs = sys.argv[1:]
    if sysargs[1:3] in [['add', 'user'], ['add', 'users'], ['list', 'users'], ['delete', 'user'], ['check', 'user']]:
        sysargs.insert(1, '.')

    doc_with_config_options = re.sub(r'gum (\w+) (?!help)(.*)', r'gum \1 \2 [-c]', __doc__)
    doc_with_config_options = doc_with_config_options.replace('\n\n    gum', '\n    gum')
    arguments = docopt.docopt(doc_with_config_options, argv=sysargs, version='GUM Cli ' + pkg_resources.require("gummanager.cli")[0].version)
    help_mode = False
    if sys.argv[2] == 'help':
        help_mode = True
        arguments['help'] = False
        for cmd in getOptionFrom(arguments, 'command'):
            if cmd in arguments:
                arguments[cmd] = True

    targets = [arg_name for arg_name, arg_value in arguments.items() if arg_name in TARGETS and arg_value is True]
    if targets == []:
        print 'No such target "{}"'.format(sys.argv[1])
        sys.exit(1)
    target_name = targets[0]

    config = getConfiguration(arguments['--config'])
    target = TARGETS[target_name](config)
    action_method_name = target.forge_command_from_arguments(arguments)

    target_method = getattr(target, action_method_name, None)
    if target_method is None:
        sys.exit('Not Implemented: {}'.format(action_method_name))

    if help_mode:
        command_line = ' .*?'.join([a for a in ['gum'] + sys.argv[1:] if a != 'help'])
        command_definition = re.search(r'\n\s*({}.*?)\n'.format(command_line), __doc__).groups()[0]
        target.help(action_method_name, definition=command_definition)
    else:
        target_method(**arguments)
コード例 #17
0
ファイル: max.py プロジェクト: UPCnet/gummanager.cli
    def stop(self, **kwargs):
        """
            Stops a max instance.

            Supervisord process must be running in order to use this command
        """
        instance_name = getOptionFrom(kwargs, 'instance-name')
        maxserver = self.Server
        status = maxserver.get_status(instance_name)

        if status['status'] == 'running':
            maxserver.stop(instance_name)
        else:
            padded_success("Already stopped")
コード例 #18
0
ファイル: utalk.py プロジェクト: UPCnet/gummanager.cli
    def test(self, **kwargs):
        instance_name = getOptionFrom(kwargs, 'domain')

        max_config = getConfiguration(kwargs['--config'])['max']
        maxserver = MaxServer(max_config)

        oauth_config = getConfiguration(kwargs['--config'])['oauth']
        oauthserver = OauthServer(oauth_config)

        self.extra_config = {
            'max': maxserver,
            'oauth': oauthserver
        }

        self.Server.test(instance_name)
コード例 #19
0
ファイル: oauth.py プロジェクト: UPCnet/gummanager.cli
    def stop(self, **kwargs):
        """
            Stops an oauth instance.

            Supervisord process must be running in order to use this command
        """
        instance_name = getOptionFrom(kwargs, 'instance-name')
        oauth = self.Server
        status = oauth.get_status(instance_name)
        if status['status'] == 'running':
            oauth.stop(instance_name)
        else:
            padded_success("Already stopped")
        if status['status'] == 'stopped':
            print '\nAlready stopped\n'
コード例 #20
0
ファイル: max.py プロジェクト: UPCnet/gummanager.cli
    def start(self, **kwargs):
        """
            Starts a max instance.

            If the instance is not loaded on supervisor, it will be loaded and started.
            In every other case the instance will be started from the prior status.
            Supervisord process must be running in order to use this command
        """
        instance_name = getOptionFrom(kwargs, 'instance-name')
        maxserver = self.Server
        status = maxserver.get_status(instance_name)
        if status['status'] == 'running':
            padded_success("Already running")
        else:
            maxserver.start(instance_name)
コード例 #21
0
ファイル: max.py プロジェクト: UPCnet/gummanager.cli
    def status(self, **kwargs):
        """
            Lists status for one or all active max instances.

            The status listed here is the status reported by supervisor. There's
            a special status 'not found'. Instances on this state are  that are created,
            but already not loaded into supervisor.
        """
        instance_name = getOptionFrom(kwargs, 'instance-name', default='all')

        oauth = self.Server
        instances = oauth.get_instances()
        if instance_name != 'all':
            instances = [instance for instance in instances if instance['name'] == instance_name]

        statuses = []
        for instance in instances:
            status = oauth.get_status(instance['name'])
            statuses.append(status)

        table = GUMTable()
        table.from_dict_list(
            statuses,
            formatters={
                'name': highlighter(default='bold_yellow'),
                'status': highlighter(values={
                    'running': 'green',
                    'unknown': 'red',
                    'down': 'red',
                    'backoff': 'red',
                    'fatal': 'red',
                    'not found': 'cyan',
                    'stopped': 'red'}

                )
            },
            titles={
                'name': 'Name',
                'status': 'Status',
                'pid': 'PID',
                'uptime': 'Started',
                'server': 'Server access'
            })
        print table.sorted('name')
コード例 #22
0
ファイル: oauth.py プロジェクト: UPCnet/gummanager.cli
    def reconfigure_nginx(self, **kwargs):
        """
            Generates a new nginx configuration file for a domain.

            A copy of the current configuration will be saved locally. Also a nginx
            testconfig will be performed to chekc the new configuration.
        """
        oauthserver = self.Server
        instance_name = getOptionFrom(kwargs, 'instance-name')

        run_recipe_with_confirmation(
            'Reconfigure nginx httpd server ?',
            {
                'server': self.config.nginx['server'],
                'name': instance_name

            },
            oauthserver.reconfigure_nginx,
            instance_name
        )
コード例 #23
0
ファイル: max.py プロジェクト: UPCnet/gummanager.cli
    def test(self, **kwargs):
        """
            Tests that a max instance is working as expected.

            An username and a password of an existing user has to be provided.
        """
        instance_name = getOptionFrom(kwargs, 'instance-name')

        maxserver = self.Server
        instance_info = maxserver.get_instance(instance_name)

        oauth_config = getConfiguration(kwargs['--config'])['oauth']
        oauthserver = OauthServer(**oauth_config)
        oauth_info = oauthserver.instance_by_dns(instance_info['oauth'])
        ldap_branch = oauth_info['ldap']['branch']
        ldap_branch = oauth_info['ldap']['branch']

        maxserver.test(instance_name, ldap_branch)

        print 'Test end'
コード例 #24
0
ファイル: ulearn.py プロジェクト: UPCnet/gummanager.cli
    def add_instance(self, **kwargs):

        step_log('Checking parameters consistency')

        instance_name = getOptionFrom(kwargs, 'instance-name')
        environment = getOptionFrom(kwargs, 'env', default='')
        mountpoint = getOptionFrom(kwargs, 'mpoint', default='')
        max_instance_name = getOptionFrom(kwargs, 'max', default=instance_name)

        padded_log('Checking max server ...')
        max_config = getConfiguration(kwargs['--config'])['max']
        maxserver = MaxServer(max_config)
        max_instance = maxserver.get_instance(max_instance_name)

        self.extra_config = {'ldap_config': getConfiguration(kwargs['--config'])['ldap']}
        ulearn_server = self.Server

        if not max_instance:
            padded_error("There's no defined max server named {}".format(max_instance_name))
            return None

        padded_log('Checking oauth server ...')
        oauth_server_url = max_instance['oauth']
        oauth_instance_name = oauth_server_url.split('/')[-1]

        oauth_config = getConfiguration(kwargs['--config'])['oauth']
        oauthserver = OauthServer(oauth_config)
        oauth_instance = oauthserver.get_instance(oauth_instance_name)

        if not oauth_instance:
            padded_error("Max server {} is bound to an oauth {} that doesn't exist".format(max_instance_name, oauth_instance_name))
            return None

        ldap_branch = re.search(r'ou=(\w+),', oauth_instance['ldap']['basedn']).groups()[0]

        allow_shared_mountpoint = getOptionFrom(kwargs, 'f', False)
        create = False
        padded_log('Checking mountpoint ...')
        if environment and mountpoint:
            if not ulearn_server.is_mountpoint_available(environment, mountpoint, allow_shared=allow_shared_mountpoint):
                padded_error("This mountpoint is unavailable")
                return
            create = True
        else:
            available_mountpoint = ulearn_server.get_available_mountpoint()
            if available_mountpoint:
                environment = available_mountpoint['environment']
                mountpoint = available_mountpoint['id']
                create = True
            else:
                padded_error("There's no available mountpoint in any environment")
                return

        ldap_config = getConfiguration(kwargs['--config'])['ldap']
        ldap_password = getOptionFrom(kwargs, 'ldappassword')

        if create:
            siteid = instance_name
            title = siteid.capitalize()
            language = 'ca'

            env_params = ulearn_server.get_environment(environment)
            logecho = LogEcho(
                env_params.ssh_user,
                env_params.server,
                '{}/{}.log'.format(env_params.log_folder, env_params.instance_name),
                target_lines=359,
                filters=['INFO GenericSetup']
            )

            run_recipe_with_confirmation(
                "Adding a new Ulearn",
                {
                    "name": siteid,
                    "server": environment,
                    "mountpoint": mountpoint,
                    "oauth_instance": max_instance['oauth'],
                    "ldap_branch": ldap_branch,
                    "max": max_instance['server']['dns']
                },
                ulearn_server.new_instance,
                *[instance_name, environment, mountpoint, title, language, max_instance_name, max_instance['server']['direct'], oauth_instance_name, ldap_branch, ldap_password, logecho]
            )