From 88d8a29a1462a602fb2dad21292d33bb639fc288 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Sat, 24 Sep 2016 21:59:01 +0200 Subject: [PATCH] Improve documentation --- gvafile/fileservertasks/tasks.py | 420 +++++++++++++++++++++++++++---- salt/bootstrap.sh | 1 + 2 files changed, 367 insertions(+), 54 deletions(-) diff --git a/gvafile/fileservertasks/tasks.py b/gvafile/fileservertasks/tasks.py index 3f4473a..2c02c4a 100644 --- a/gvafile/fileservertasks/tasks.py +++ b/gvafile/fileservertasks/tasks.py @@ -6,6 +6,7 @@ This module defines `Celery`_ tasks to manage file system entities. """ from __future__ import absolute_import, unicode_literals +from copy import deepcopy import os import subprocess from tempfile import mkstemp @@ -68,15 +69,25 @@ def _build_mail_directory_name(username): @shared_task -def setup_file_sftp_userdir(username): +def setup_file_sftp_userdir(username, *args, **kwargs): """ This task creates the home directory for an SFTP user if it does not exist yet. - :param str username: the user name + :param str username: the username :raises Exception: if the SFTP directory of the user cannot be created - :return: the created directory name - :rtype: str + :return: a dictionary with the key :py:const:`username` set to the + username value and a new key :py:const:`sftp_directory` set to the + path of the created SFTP directory + :rtype: dict + + .. note:: + + This variant can only be used at the beginning of a Celery task chain + or as a standalone task. + + Use :py:func:`fileservertasks.tasks.setup_file_sftp_userdir_chained` + at other positions in the task chain. """ sftp_directory = _build_sftp_directory_name(username) @@ -89,22 +100,54 @@ def setup_file_sftp_userdir(username): sftp_directory], stderr=subprocess.STDOUT) except subprocess.CalledProcessError as cpe: log_and_raise( - cpe, 'cold not create SFTP directory for user %s', username) + cpe, 'could not create SFTP directory for user %s', username) _LOGGER.info( 'created sftp directory %s for user %s', sftp_directory, username) - return sftp_directory + return {'username': username, 'sftp_directory': sftp_directory} @shared_task -def delete_file_sftp_userdir(username): +def setup_file_sftp_userdir_chained(previous_result, *args, **kwargs): + """ + This task creates the home directory for an SFTP user if it does not exist + yet. + + :param dict previous_result: a dictionary describing the result of the + previous step in the Celery task chain. This dictionary must contain a + :py:const:`username` key + :raises Exception: if the SFTP directory of the user cannot be created + :return: a copy of the :py:obj:`previous_result` dictionary with a new + :py:const:`sftp_directory` key set to the path of the created SFTP + directory + :rtype: dict + + """ + username = previous_result['username'] + retval = deepcopy(previous_result) + retval.update(setup_file_sftp_userdir(username)) + return retval + + +@shared_task +def delete_file_sftp_userdir(username, *args, **kwargs): """ This task recursively deletes the home directory of an SFTP user if it - does not exist yet. + exists. - :param str username: the user name + :param str username: the username :raises Exception: if the SFTP directory of the user cannot be removed - :return: the removed directory name - :rtype: str + :return: a dictionary with the key :py:const:`username` set to the username + value and the new key :py:const:`sftp_directory` set to the path of the + deleted SFTP directory + :rtype: dict + + .. note:: + + This variant can only be used at the beginning of a Celery task chain + or as a standalone task. + + Use :py:func:`fileservertasks.tasks.delete_file_sftp_userdir_chained` + at other positions in the task chain. """ sftp_directory = _build_sftp_directory_name(username) @@ -117,20 +160,52 @@ def delete_file_sftp_userdir(username): cpe, 'could not remove SFTP directory for user %s', username) _LOGGER.info( "deleted sftp directory %s of user %s", sftp_directory, username) - return sftp_directory + return {'username': username, 'sftp_directory': sftp_directory} @shared_task -def setup_file_mail_userdir(username): +def delete_file_sftp_userdir_chained(previous_result, *args, **kwargs): + """ + This task recursively deletes the home directory of an SFTP user if it + exists. + + :param dict previous_result: a dictionary describing the result of the + previous step in the Celery task chain. This dictionary must contain a + :py:const:`username` key + :raises Exception: if the SFTP directory of the user cannot be removed + :return: a copy of the :py:obj:`previous_result` dictionary with a new + :py:const:`sftp_directory` key set to the path of the removed SFTP + directory + :rtype: dict + + """ + username = previous_result['username'] + retval = deepcopy(previous_result) + retval.update(delete_file_sftp_userdir(username)) + return retval + + +@shared_task +def setup_file_mail_userdir(username, *args, **kwargs): """ This task creates the mail base directory for a user if it does not exist yet. - :param str username: the user name + :param str username: the username :raises Exception: if the mail base directory for the user cannot be created - :return: the created directory name - :rtype: str + :return: a dictionary with the key :py:const:`username` set to the + username value and a new key :py:const:`mail_directory` set to the path + of the created mail directory + :rtype: dict + + .. note:: + + This variant can only be used at the beginning of a Celery task chain + or as a standalone task. + + Use :py:func:`fileservertasks.tasks.setup_file_mail_userdir_chained` + at other positions in the task chain. """ mail_directory = _build_mail_directory_name(username) @@ -143,19 +218,52 @@ def setup_file_mail_userdir(username): cpe, 'could not create mail base directory for user %s', username) _LOGGER.info( 'created mail directory %s for user %s', mail_directory, username) - return mail_directory + return {'username': username, 'mail_directory': mail_directory} @shared_task -def delete_file_mail_userdir(username): +def setup_file_mail_userdir_chained(previous_result, *args, **kwargs): + """ + This task creates the mail base directory for a user if it does not exist + yet. + + :param dict previous_result: a dictionary containing the result of the + previous step in the Celery task chain. This dictionary must contain a + :py:const:`username` key + :raises Exception: if the mail base directory for the user cannot be + created + :return: a copy of the :py:obj:`previous_result` dictionary with a new + :py:const:`mail_directory` key set to the path of the created mail + directory + :rtype: dict + + """ + username = previous_result['username'] + retval = deepcopy(previous_result) + retval.update(setup_file_mail_userdir(username)) + return retval + + +@shared_task +def delete_file_mail_userdir(username, *args, **kwargs): """ This task recursively deletes the mail base directory for a user if it does not exist yet. - :param str username: the user name - :raises Exception: if the mail base directory of the user cannot be removed - :return: the removed directory name - :rtype: str + :param str username: the username + :raises Exception: if the mail base directory of the user cannot be deleted + :return: a dictionary with the key :py:const:`username` set to the + username value and a new key :py:const:`mail_directory` set to the path + of the deleted mail directory + :rtype: dict + + .. note:: + + This variant can only be used at the beginning of a Celery task chain + or as a standalone task. + + Use :py:func:`fileservertasks.tasks.delete_file_mail_userdir_chained` + at other positions in the task chain. """ mail_directory = _build_mail_directory_name(username) @@ -168,20 +276,52 @@ def delete_file_mail_userdir(username): cpe, 'could not remove mail base directory of user %s', username) _LOGGER.info( 'deleted mail directory %s of user %s', mail_directory, username) - return mail_directory + return {'username': username, 'mail_directory': mail_directory} + +@shared_task +def delete_file_mail_userdir_chained(previous_result, *args, **kwargs): + """ + This task recursively deletes the mail base directory for a user if it + does not exist yet. + + :param dict previous_result: a dictionary describing the result of the + previous step in the Celery task chain. This dictionary must contain a + :py:const:`username` key + :raises Exception: if the mail base directory of the user cannot be deleted + :return: a copy of the :py:obj:`previous_result` dictionary with a new + :py:const:`mail_directory` key set to the path of the deleted mail + directory + :rtype: str + + """ + username = previous_result['username'] + retval = deepcopy(previous_result) + retval.update(delete_file_mail_userdir(username)) + return retval @shared_task -def create_file_mailbox(username, mailboxname): +def create_file_mailbox(username, mailboxname, *args, **kwargs): """ This task creates a new mailbox directory for the given user and mailbox name. - :param str username: the user name + :param str username: the username :param str mailboxname: the mailbox name :raises Exception: if the mailbox directory cannot be created - :return: the created mailbox directory name - :rtype: str + :return: a dictionary with the keys :py:const:`username` and + :py:const:`mailboxname` set to the values of username and mailboxname + and a new key :py:const:`mailbox_directory` set to the path of the + created mailbox directory + :rtype: dict + + .. note:: + + This variant can only be used at the beginning of a Celery task chain + or as a standalone task. + + Use :py:func:`fileservertasks.tasks.create_file_mailbox_chained` at + other positions in the task chain. """ mailbox_directory = os.path.join( @@ -197,19 +337,56 @@ def create_file_mailbox(username, mailboxname): _LOGGER.info( 'created mailbox directory %s for user %s', mailbox_directory, username) - return mailbox_directory + return { + 'username': username, 'mailboxname': mailboxname, + 'mailbox_directory': mailbox_directory + } @shared_task -def delete_file_mailbox(username, mailboxname): +def create_file_mailbox_chained(previous_result, *args, **kwargs): + """ + This task creates a new mailbox directory for the given user and mailbox + name. + + :param dict previous_result: a dictionary describing the result of the + previous step in the Celery task chain. This dictionary must contain a + :py:const:`username` and a :py:const:`mailboxname` key + :raises Exception: if the mailbox directory cannot be created + :return: a copy of the :py:obj:`previous_result` dictionary with a new + :py:const:`mailbox_directory` key set to the path of the created + mailbox directory + :rtype: dict + + """ + username = previous_result['username'] + mailboxname = previous_result['mailboxname'] + retval = deepcopy(previous_result) + retval.update(create_file_mailbox(username, mailboxname)) + return retval + + +@shared_task +def delete_file_mailbox(username, mailboxname, *args, **kwargs): """ This task deletes the given mailbox of the given user. - :param str username: the user name + :param str username: the username :param str mailboxname: the mailbox name :raises Exception: if the mailbox directory cannot be deleted - :return: the deleted mailbox directory name - :rtype: str + :return: a dictionary with the keys :py:const:`username` and + :py:const:`mailboxname` set to the values of username and mailboxname + and a new key :py:const:`mailbox_directory` set to the path of the + deleted mailbox directory + :rtype: dict + + .. note:: + + This variant can only be used at the beginning of a Celery task chain + or as a standalone task. + + Use :py:func:`fileservertasks.tasks.delete_file_mailbox_chained` for + other positions in the task chain. """ mailbox_directory = os.path.join( @@ -224,20 +401,56 @@ def delete_file_mailbox(username, mailboxname): username) _LOGGER.info( 'deleted mailbox directory %s of user %s', mailbox_directory, username) - return mailbox_directory + return { + 'username': username, 'mailboxname': mailboxname, + 'mailbox_directory': mailbox_directory + } + +@shared_task +def delete_file_mailbox_chained(previous_result, *args, **kwargs): + """ + This task deletes the given mailbox of the given user. + + :param dict previous_result: a dictionary describing the result of the + previous step in the Celery task chain. This dictionary must contain a + :py:const:`username` and a :py:const:`mailboxname` key + :raises Exception: if the mailbox directory cannot be deleted + :return: a copy of the :py:obj:`previous_result` dictionary with a new + :py:const:`mailbox_directory` key set to the path of the deleted + mailbox directory + :rtype: dict + + """ + username = previous_result['username'] + mailboxname = previous_result['mailboxname'] + retval = deepcopy(previous_result) + retval.update(delete_file_mailbox(username, mailboxname)) + return retval @shared_task -def create_file_website_hierarchy(username, sitename): +def create_file_website_hierarchy(username, sitename, *args, **kwargs): """ This task creates the directory hierarchy for a website. - :param str username: the user name - :param str sitename: name of the website + :param str username: the username + :param str sitename: the sitename :raises Exception: if the website directory hierarchy directory cannot be created - :return: the directory name - :rtype: str + :return: a dictionary with the keys :py:const:`username` and + :py:const:`sitename` set to the values of username and sitename and a + new key :py:const:`website_directory` set to the path of the created + website directory + :rtype: dict + + .. note:: + + This variant can only be used at the beginning of a Celery task chain + or as a standalone task. + + Use + :py:func:`fileservertasks.tasks.create_file_website_hierarchy_chained` + at other positions in the task chain """ website_directory = os.path.join( @@ -271,20 +484,55 @@ def create_file_website_hierarchy(username, sitename): _LOGGER.info( 'created website directory %s for user %s', website_directory, username) - return website_directory + return { + 'username': username, 'sitename': sitename, + 'website_directory': website_directory, + } @shared_task -def delete_file_website_hierarchy(username, sitename): +def create_file_website_hierarchy_chained(previous_result, *args, **kwargs): """ - This task deletes the website hierarchy recursively. + This task creates the directory hierarchy for a website. - :param str username: the user name - :param str sitename: name of the website + :param dict previous_result: a dictionary describing the result of the + previous step in the Celery task chain. This dictionary must contain a + :py:const:`username` and a :py:const:`sitename` key :raises Exception: if the website directory hierarchy directory cannot be - deleted - :return: the directory name - :rtype: str + created + :return: a copy of the :py:obj:`previous_result` dictionary with a new + :py:const:`website_directory` key set to the path of the created + website directory + :rtype: dict + + """ + username = previous_result['username'] + sitename = previous_result['sitename'] + retval = deepcopy(previous_result) + retval.update(create_file_website_hierarchy(username, sitename)) + return retval + + +@shared_task +def delete_file_website_hierarchy(username, sitename, *args, **kwargs): + """ + This task deletes a website hierarchy recursively. + + :param str username: a username + :param str sitename: a site name + :return: a dictionary with the keys :py:const:`username` and + :py:const:`sitename` set to their original values and a new key + :py:const:`website_directory` set to the path of the deleted website + :rtype: dict + + .. note:: + + This variant can only be used at the beginning of a Celery task chain + or as a standalone task. + + Use + :py:func:`fileservertasks.tasks.delete_file_website_hierarchy_chained` + at other positions in the task chain """ website_directory = os.path.join( @@ -300,20 +548,58 @@ def delete_file_website_hierarchy(username, sitename): "website %s"), username, sitename) _LOGGER.info( 'deleted website directory %s of user %s', website_directory, username) - return website_directory + return { + 'username': username, 'sitename': sitename, + 'website_directory': website_directory, + } @shared_task -def set_file_ssh_authorized_keys(username, ssh_keys): +def delete_file_website_hierarchy_chained(previous_result, *args, **kwargs): """ - This task sets the authorized keys for ssh logins. + This task deletes the website hierarchy recursively. - :param str username: the user name - :param list ssh_key: an ssh_key + :param dict previous_result: a dictionary describing the result of the + previous step in the Celery task chain. This dictionary must contain a + :py:const:`username` and a :py:const:`sitename` key + :raises Exception: if the website directory hierarchy directory cannot be + deleted + :return: a copy of the :py:obj:`previous_result` dictionary with a new + :py:const:`website_directory` set to the path of the deleted website + directory + :rtype: dict + + """ + username = previous_result['username'] + sitename = previous_result['sitename'] + retval = deepcopy(previous_result) + retval.update(delete_file_website_hierarchy(username, sitename)) + return retval + + +@shared_task +def set_file_ssh_authorized_keys(username, ssh_keys, *args, **kwargs): + """ + This task set the authorized keys for ssh logins. + + :param str username: a username + :param list ssh_keys: a list of ssh keys :raises Exception: if the update of the creation or update of ssh authorized_keys failed - :return: the name of the authorized_keys file - :rtype: str + :return: a dictionary with the keys :py:const:`username` and + :py:const:`ssh_keys` set to their original values and a new key + :py:const:`ssh_authorized_keys` set to the path of the SSH + authorized_keys file + :rtype: dict + + .. note:: + + This variant can only be used at the beginning of a Celery task chain + or as a standalone task. + + Use + :py:func:`fileservertasks.tasks.set_file_ssh_authorized_keys_chained` + at other positions in the task chain """ ssh_authorized_keys_file = _build_authorized_keys_path(username) @@ -354,4 +640,30 @@ def set_file_ssh_authorized_keys(username, ssh_keys): log_and_raise( cpe, 'could not remove the authorized_keys file of user %s', username) - return ssh_authorized_keys_file + return { + 'username': username, 'ssh_keys': ssh_keys, + 'ssh_authorized_keys': ssh_authorized_keys_file, + } + + +@shared_task +def set_file_ssh_authorized_keys_chained(previous_result, *args, **kwargs): + """ + This task sets the authorized keys for ssh logins. + + :param dict previous_result: a dictionary describing the result of the + previous step in the Celery task chain. This dictionary must contain a + :py:const:`username` and a :py:const:`ssh_keys` key + :raises Exception: if the update of the creation or update of ssh + authorized_keys failed + :return: a copy of the :py:obj:`previous_result` dictionary with a new + :py:const:`ssh_authorized_keys` set to the path of the SSH + authorized_keys file + :rtype: dict + + """ + username = previous_result['username'] + ssh_keys = previous_result['ssh_keys'] + retval = deepcopy(previous_result) + retval.update(set_file_ssh_authorized_keys(username, ssh_keys)) + return retval diff --git a/salt/bootstrap.sh b/salt/bootstrap.sh index 61a103a..c24ee37 100755 --- a/salt/bootstrap.sh +++ b/salt/bootstrap.sh @@ -28,5 +28,6 @@ EOF cat >/etc/salt/grains <