diff --git a/create_account.py b/create_account.py index b316cd0bca978d77f27a51ea067a3634c675049b..ef77d78b9eed202c406e127fd9b816dbf18dfd10 100755 --- a/create_account.py +++ b/create_account.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import sys import rc_util diff --git a/dir_verify.py b/dir_verify.py new file mode 100644 index 0000000000000000000000000000000000000000..0f0127e50b50ebea248a89df0ad1f9a19eb2c545 --- /dev/null +++ b/dir_verify.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +import sys +import json +import shutil +import rc_util +from pathlib import Path +from rc_rmq import RCRMQ + +task = 'dir_verify' +dirs = ['/home', '/data/user', '/data/scratch'] + +args = rc_util.get_args() +logger = rc_util.get_logger(args) + +# Instantiate rabbitmq object +rc_rmq = RCRMQ({'exchange': 'RegUsr', 'exchange_type': 'topic'}) + +def dir_verify(ch, method, properties, body): + msg = json.loads(body) + username = msg['username'] + msg['task'] = task + msg['success'] = False + + try: + for d in dirs: + path = Path(d) / msg['username'] + + if args.dry_run: + logger.info(f'Checking dirs: {path}') + + else: + if not path.exists(): + # Make sure folder exists and with right permission + path.mkdir(mode=0o700) + + # Make sure ownership is correct + shutil.chown(path, int(msg['uid']), int(msg['gid'])) + + logger.debug(f'{path} created') + + msg['success'] = True + + except Exception as exception: + logger.error('', exc_info=True) + + # send confirm message + rc_rmq.publish_msg({ + 'routing_key': 'confirm.' + username, + 'msg': msg + }) + + logger.debug(f'User {username} confirmation sent') + + ch.basic_ack(delivery_tag=method.delivery_tag) + + +logger.info(f'Start listening to queue: {task}') +rc_rmq.start_consume({ + 'queue': task, + 'routing_key': "verify.*", + 'cb': dir_verify +}) + +logger.info('Disconnected') +rc_rmq.disconnect() diff --git a/git_commit.py b/git_commit.py new file mode 100644 index 0000000000000000000000000000000000000000..3ea965d288dd5c240e0c72d58b00921c91344777 --- /dev/null +++ b/git_commit.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +import os +import sh +import sys +import json +import rc_util +from rc_rmq import RCRMQ + +task = 'git_commit' + +# Instantiate rabbitmq object +rc_rmq = RCRMQ({'exchange': 'RegUsr', 'exchange_type': 'topic'}) + +# Define some location +repo_location = os.path.expanduser('~/git/rc-users') +users_dir = repo_location + '/users' +groups_dir = repo_location + '/groups' + +args = rc_util.get_args() +logger = rc_util.get_logger(args) + +if not args.dry_run: + git = sh.git.bake('-C', repo_location) + ldapsearch = sh.Command('ldapsearch') +else: + git = sh.echo.bake('git', '-C', repo_location) + ldapsearch = sh.echo.bake('ldapsearch') + +def git_commit(ch, method, properties, body): + msg = json.loads(body) + username = msg['username'] + ticketnum = msg.get('ticketnum', 'add-users-' + username.lower()) + msg['task'] = task + msg['success'] = False + branch_name = 'issue-' + ticketnum + user_ldif = users_dir + f'/{username}.ldif' + group_ldif = groups_dir + f'/{username}.ldif' + + logger.info("Received: %s", msg) + logger.debug("ticketnum: %s", ticketnum) + logger.debug("branch_name: %s", branch_name) + + try: + + logger.debug('git checkout master') + git.checkout('master') + logger.debug('git pull') + git.pull() + logger.debug('git checkout -b %s', branch_name) + git.checkout('-b', branch_name) + + logger.debug("open(%s, 'w'), open(%s, 'w')", user_ldif, group_ldif) + with open(user_ldif, 'w') as ldif_u,\ + open(group_ldif, 'w') as ldif_g: + logger.debug(f"ldapsearch -LLL -x -h ldapserver -b 'dc=cm,dc=cluster' uid={username} > {user_ldif}") + ldapsearch('-LLL', '-x', '-h', 'ldapserver', '-b', "dc=cm,dc=cluster", f"uid={username}", _out=ldif_u) + logger.debug(f"ldapsearch -LLL -x -h ldapserver -b 'ou=Group,dc=cm,dc=cluster' cn={username} > {group_ldif}") + ldapsearch('-LLL', '-x', '-h', 'ldapserver', '-b', "ou=Group,dc=cm,dc=cluster", f"cn={username}", _out=ldif_g) + logger.info('user ldif files generated.') + + logger.debug('git add %s', user_ldif) + git.add(user_ldif) + logger.debug('git add %s', group_ldif) + git.add(group_ldif) + logger.debug("git commit -m 'Added new cheaha user: %s'", username) + git.commit(m="Added new cheaha user: " + username) + logger.debug('git checkout master') + git.checkout('master') + + logger.debug('git merge %s --no-ff --no-edit', branch_name) + git.merge(branch_name, '--no-ff', '--no-edit') + logger.debug('git push origin master') + git.push('origin', 'master') + # merge with gitlab api + + logger.info('Added ldif files and committed to git repo') + + msg['success'] = True + except Exception as exception: + logger.error('', exc_info=True) + + # Send confirm message + logger.debug('rc_rmq.publish_msge()') + rc_rmq.publish_msg({ + 'routing_key': 'confirm.' + username, + 'msg': msg + }) + logger.info('confirmation sent') + + # Acknowledge message + logger.debug('ch.basic_ack()') + ch.basic_ack(delivery_tag=method.delivery_tag) + + +logger.info("Start listening to queue: %s", task) +rc_rmq.start_consume({ + 'queue': task, + 'routing_key': "verify.*", + 'cb': git_commit +}) + +logger.info("Disconnected") +rc_rmq.disconnect() diff --git a/mail_config.py b/mail_config.py new file mode 100644 index 0000000000000000000000000000000000000000..1146e3848f5e3a0bdcc3fc24a6fdcb711d475b0a --- /dev/null +++ b/mail_config.py @@ -0,0 +1,30 @@ +# Some variable for email +Server = 'localhost' +My_email = 'root@localhost' +Sender = 'ROOT@LOCALHOST' +Sender_alias = 'Services' +Subject = 'New User Account' +Info_url = 'https://www.google.com' + +Head = f"""From: {Sender_alias} <{Sender}> +To: <{{{{ to }}}}> +Subject: {Subject} +""" + +Body = f""" +Hi {{{{ username }}}} +Your account has been set up with: + +============================ +User ID: {{{{ username }}}} +============================ + +If you have any questions, please visit: +{Info_url} + +or email at {My_email} + +Cheers, +""" + +Whole_mail = Head + Body diff --git a/notify_user.py b/notify_user.py new file mode 100644 index 0000000000000000000000000000000000000000..753d14d790c4c1d5fea98ed3709dfaa1739f5cff --- /dev/null +++ b/notify_user.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +import sys +import json +import rc_util +import smtplib +import dataset +from rc_rmq import RCRMQ +from jinja2 import Template +from datetime import datetime +import mail_config as mail_cfg + +task = 'notify_user' + +args = rc_util.get_args() +logger = rc_util.get_logger(args) + +db = dataset.connect(f'sqlite:///.agent_db/{task}.db') +table = db['notified_user'] + +# Instantiate rabbitmq object +rc_rmq = RCRMQ({'exchange': 'RegUsr', 'exchange_type': 'topic'}) + +# Email instruction to user +def notify_user(ch, method, properties, body): + msg = json.loads(body) + username = msg['username'] + user_email = msg['email'] + msg['task'] = task + msg['success'] = False + + try: + + # Search username in database + record = table.find_one(username=username) + + if record: + # Update counter + count = record['count'] + table.update({'username': username, 'count': count + 1}, ['username']) + + logger.debug(f'User {username} counter updated to {count + 1}') + + else: + # Send email to user + receivers = [user_email, mail_cfg.My_email] + message = Template(mail_cfg.Whole_mail).render(username=username, to=user_email) + + if args.dry_run: + logger.info(f'smtp = smtplib.SMTP({mail_cfg.Server})') + logger.info(f'smtp.sendmail({mail_cfg.Sender}, {receivers}, message)') + logger.info(f"table.insert({{'username': {username}, 'count': 1, 'sent_at': datetime.now()}})") + + else: + smtp = smtplib.SMTP(mail_cfg.Server) + smtp.sendmail(mail_cfg.Sender, receivers, message) + + logger.debug(f'Email sent to: {user_email}') + + table.insert({ + 'username': username, + 'count': 1, + 'sent_at': datetime.now() + }) + + logger.debug(f'User {username} inserted into database') + + msg['success'] = True + except Exception as exception: + logger.error('', exc_info=True) + + # Send confirm message + rc_rmq.publish_msg({ + 'routing_key': 'confirm.' + username, + 'msg': msg + }) + + logger.debug(f'User {username} confirmation sent') + + # Acknowledge the message + ch.basic_ack(delivery_tag=method.delivery_tag) + + +if __name__ == "__main__": + logger.info(f'Start listening to queue: {task}') + rc_rmq.start_consume({ + 'queue': task, + 'routing_key': "notify.*", + 'cb': notify_user + }) + + logger.info('Disconnected') + rc_rmq.disconnect() diff --git a/requirements.txt b/requirements.txt index 4fd3ec63932e6b593735241cb97e87ca05ac34dd..562cb606a776a6080f5acab0f53490d766dd2a2b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,5 @@ pika==1.1.0 pyldap==3.0.0.post1 +dataset==1.3.1 +Jinja2==2.11.2 +sh==1.12.14 \ No newline at end of file diff --git a/task_manager.py b/task_manager.py new file mode 100644 index 0000000000000000000000000000000000000000..604c1ec283135ded7661e2e2f08e71e2f50a44f6 --- /dev/null +++ b/task_manager.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python +import sys +import json +import rc_util +from rc_rmq import RCRMQ +from datetime import datetime + +task = 'task_manager' + +args = rc_util.get_args() +logger = rc_util.get_logger(args) + +record = { + 'uid': -1, + 'gid': -1, + 'email': '', + 'fullname': '', + 'last_update': datetime.now(), + 'request': { + 'get_next_uid_gid': None + }, + 'create': { + 'subscribe_mail_list': None, + 'bright_account': None + }, + 'verify': { + 'git_commit': None, + 'dir_verify': None + }, + 'notify': { + 'notify_user': None + }, + 'delivery_tags': None +} + +# Currently tracking users +tracking = {} + +# Instantiate rabbitmq object +rc_rmq = RCRMQ({'exchange': 'RegUsr', 'exchange_type': 'topic'}) + +def task_manager(ch, method, properties, body): + msg = json.loads(body) + username = method.routing_key.split('.')[1] + task_name = msg['task'] + done = success = msg['success'] + routing_key = "" + + if username not in tracking: + current = tracking[username] = record.copy() + current['delivery_tags'] = [] + current['uid'] = msg.get('uid', -1) + current['gid'] = msg.get('gid', -1) + current['email'] = msg.get('email', '') + current['fullname'] = msg.get('fullname', '') + + logger.debug(f'Tracking user {username}') + else: + current = tracking[username] + + # Save the delivery tags for future use + current['delivery_tags'].append(method.delivery_tag) + + try: + if task_name in current['request']: + current['request'][task_name] = success + routing_key = 'create.' + username + done = success + + logger.debug(f'Request level task(s) done?{done}') + + elif task_name in current['create']: + current['create'][task_name] = success + routing_key = 'verify.' + username + done = True + for status in current['create'].values(): + if status is not True: + done = False + + logger.debug(f'Create level task(s) done?{done}') + + elif task_name in current['verify']: + current['verify'][task_name] = success + routing_key = 'notify.' + username + done = True + for status in current['verify'].values(): + if status is not True: + done = False + + logger.debug(f'Verify level task(s) done?{done}') + + elif task_name in current['notify']: + current['verify'][task_name] = success + routing_key = 'complete.' + username + done = success + + logger.debug(f'Notify level task(s) done?{done}') + + except Exception as exception: + logger.error('', exc_info=True) + + if done: + # Send trigger message + rc_rmq.publish_msg({ + 'routing_key': routing_key, + 'msg': { + 'username': username, + 'fullname': current['fullname'], + 'email': current['email'], + 'uid': current['uid'], + 'gid': current['gid'] + } + }) + + logger.debug(f"Trigger message '{routing_key}' sent") + + # Acknowledge all message from last level + for tag in current['delivery_tags']: + ch.basic_ack(tag) + current['delivery_tags'] = [] + + logger.debug('Previous level messages acknowledged') + + +logger.info(f'Start listening to queue: {task}') +rc_rmq.start_consume({ + 'queue': task, + 'routing_key': "confirm.*", + 'cb': task_manager +}) + +logger.info('Disconnected') +rc_rmq.disconnect()