def create_account(request): """Return tuple (tasks queue, celery connection, task reponse).""" conf = ConfigParser() conf.read('/etc/ocf-create/ocf-create.conf') celery = Celery( broker=conf.get('celery', 'broker'), backend=conf.get('celery', 'backend'), ) celery.conf.broker_use_ssl = { 'ssl_ca_certs': '/etc/ssl/certs/ca-certificates.crt', 'ssl_cert_reqs': ssl.CERT_REQUIRED, } celery.conf.redis_backend_use_ssl = { 'ssl_ca_certs': '/etc/ssl/certs/ca-certificates.crt', 'ssl_cert_reqs': ssl.CERT_REQUIRED, } # TODO: stop using pickle celery.conf.task_serializer = 'pickle' celery.conf.result_serializer = 'pickle' celery.conf.accept_content = {'pickle'} tasks = get_tasks(celery) task = tasks.validate_then_create_account.delay(request) response = wait_for_task(celery, task) return (tasks, celery, response)
def create_account(request): """Returns tuple (tasks queue, celery connection, task reponse).""" conf = ConfigParser() conf.read('/etc/ocf-create/ocf-create.conf') celery = Celery( broker=conf.get('celery', 'broker'), backend=conf.get('celery', 'backend'), ) tasks = get_tasks(celery) task = tasks.validate_then_create_account.delay(request) response = wait_for_task(celery, task) return (tasks, celery, response)
def main(argv=None): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( '--num-checks', '-n', type=int, default=100, help='number of status checks to run', ) args = parser.parse_args(argv) tasks = submission.get_tasks(celery_app()) workers, latencies = discover_workers(tasks, args.num_checks) print('{} workers: {}'.format(len(workers), sorted(workers))) print('latencies: mean: {:.02f}ms; min: {:.02}ms; max: {:.02f}ms'.format( sum(latencies) / len(latencies), min(latencies), max(latencies), ))
def main(argv=None): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( '--num-checks', '-n', type=int, default=100, help='number of status checks to run', ) args = parser.parse_args(argv) tasks = submission.get_tasks(celery_app()) workers, latencies = discover_workers(tasks, args.num_checks) print('{} workers: {}'.format(len(workers), sorted(workers))) print( 'latencies: mean: {:.02f}ms; min: {:.02}ms; max: {:.02f}ms'.format( sum(latencies) / len(latencies), min(latencies), max(latencies), ), )
def main(): parser = argparse.ArgumentParser( description='OCF account creation IRC bot', formatter_class=argparse.ArgumentDefaultsHelpFormatter, ) parser.add_argument( '-c', '--config', default='/etc/ocf-ircbot/ocf-ircbot.conf', help='Config file to read from.', ) args = parser.parse_args() conf = ConfigParser() conf.read(args.config) celery = Celery( broker=conf.get('celery', 'broker'), backend=conf.get('celery', 'backend'), ) celery.conf.broker_use_ssl = { 'ssl_ca_certs': '/etc/ssl/certs/ca-certificates.crt', 'ssl_cert_reqs': ssl.CERT_REQUIRED, } # `redis_backend_use_ssl` is an OCF patch which was proposed upstream: # https://github.com/celery/celery/pull/3831 celery.conf.redis_backend_use_ssl = { 'ssl_cert_reqs': ssl.CERT_NONE, } # TODO: stop using pickle celery.conf.task_serializer = 'pickle' celery.conf.result_serializer = 'pickle' celery.conf.accept_content = {'pickle'} creds = AccountCreationCredentials(**{ field: conf.get(*field.split('_')) for field in AccountCreationCredentials._fields }) tasks = get_tasks(celery, credentials=creds) rt_password = conf.get('rt', 'password') nickserv_password = conf.get('nickserv', 'password') rackspace_apikey = conf.get('rackspace', 'apikey') weather_apikey = conf.get('weather_underground', 'apikey') mysql_password = conf.get('mysql', 'password') marathon_creds = ( conf.get('marathon', 'user'), conf.get('marathon', 'password'), ) # irc bot thread bot = CreateBot( tasks, nickserv_password, rt_password, rackspace_apikey, weather_apikey, mysql_password, marathon_creds, ) bot_thread = threading.Thread(target=bot.start, daemon=True) bot_thread.start() # celery thread celery_thread = threading.Thread( target=create.celery_listener, args=(bot, celery, conf.get('celery', 'broker')), daemon=True, ) celery_thread.start() # timer thread timer_thread = threading.Thread( target=timer, args=(bot,), daemon=True, ) timer_thread.start() while True: for thread in (bot_thread, celery_thread, timer_thread): if not thread.is_alive(): raise RuntimeError('Thread exited: {}'.format(thread)) time.sleep(0.1)
def tasks(session, celery_app, fake_credentials): with mock.patch('ocflib.account.submission.sessionmaker', return_value=lambda: session): yield get_tasks(celery_app, credentials=fake_credentials)
dedent("""\ An exception occured in create: {traceback} Task Details: * task_id: {task_id} Try `journalctl -u ocf-create` for more details.""").format( traceback=einfo, task_id=task_id, args=args, kwargs=kwargs, einfo=einfo, ), ) except Exception as ex: print(ex) # just in case it errors again here send_problem_report( dedent("""\ An exception occured in create, but we errored trying to report it: {traceback} """).format(traceback=format_exc()), ) raise tasks = get_tasks(celery, credentials=creds) for task in tasks: locals()[task.__name__] = task task.on_failure = failure_handler
{traceback} Task Details: * task_id: {task_id} Try `journalctl -u ocf-create` for more details.""" ).format( traceback=einfo, task_id=task_id, args=args, kwargs=kwargs, einfo=einfo, )) except Exception as ex: print(ex) # just in case it errors again here send_problem_report(dedent( """\ An exception occured in create, but we errored trying to report it: {traceback} """ ).format(traceback=format_exc())) raise tasks = get_tasks(celery, credentials=creds) for task in tasks: locals()[task.__name__] = task task.on_failure = failure_handler
def celery_listener(bot): """Listen for events from Celery, relay to IRC.""" while not (hasattr(bot, 'connection') and bot.connection.connected): time.sleep(2) celery = Celery( broker=bot.celery_conf['broker'], backend=bot.celery_conf['backend'], ) celery.conf.broker_use_ssl = { 'ssl_ca_certs': '/etc/ssl/certs/ca-certificates.crt', 'ssl_cert_reqs': ssl.CERT_REQUIRED, } # `redis_backend_use_ssl` is an OCF patch which was proposed upstream: # https://github.com/celery/celery/pull/3831 celery.conf.redis_backend_use_ssl = { 'ssl_cert_reqs': ssl.CERT_NONE, } # TODO: stop using pickle celery.conf.task_serializer = 'pickle' celery.conf.result_serializer = 'pickle' celery.conf.accept_content = {'pickle'} bot.tasks = get_tasks(celery) connection = Connection( bot.celery_conf['broker'], ssl={ 'ssl_ca_certs': '/etc/ssl/certs/ca-certificates.crt', 'ssl_cert_reqs': ssl.CERT_REQUIRED, }, ) def bot_announce(targets, message): for target in targets: bot.say(target, message) def on_account_created(event): request = event['request'] if request['calnet_uid']: uid_or_gid = 'Calnet UID: {}'.format(request['calnet_uid']) elif request['callink_oid']: uid_or_gid = 'Callink OID: {}'.format(request['callink_oid']) else: uid_or_gid = 'No Calnet UID or OID set' bot_announce( IRC_CHANNELS_ANNOUNCE, '{user} created ({real_name}, {uid_or_gid})'.format( user=request['user_name'], real_name=request['real_name'], uid_or_gid=uid_or_gid, ), ) def on_account_submitted(event): request = event['request'] bot_announce( IRC_CHANNELS_OPER, '{user} ({real_name}) needs approval: {reasons}'.format( user=request['user_name'], real_name=request['real_name'], reasons=', '.join(request['reasons']), ), ) def on_account_approved(event): request = event['request'] bot_announce( IRC_CHANNELS_ANNOUNCE, '{user} was approved, now pending creation.'.format( user=request['user_name'], ), ) def on_account_rejected(event): request = event['request'] bot_announce( IRC_CHANNELS_ANNOUNCE, '{user} was rejected.'.format(user=request['user_name'], ), ) while True: with connection as conn: recv = EventReceiver( conn, app=celery, handlers={ 'ocflib.account_created': on_account_created, 'ocflib.account_submitted': on_account_submitted, 'ocflib.account_approved': on_account_approved, 'ocflib.account_rejected': on_account_rejected, }, ) recv.capture(limit=None, timeout=None)
def main(): def_group_name = '' def_callink_oid = '' def_email = '' parser = ArgumentParser(description='Create new OCF group accounts.') parser.add_argument('oid', type=int, nargs='?', help='CalLink OID for the group.') args = parser.parse_args() if args.oid: group = group_by_oid(args.oid) if not group: print(red('No group with OID {}').format(args.oid)) return if group['accounts']: print(yellow( 'Warning: there is an existing group account with OID {}: {}'.format( args.oid, ', '.join(group['accounts']), ), )) input('Press any key to continue...') def_group_name = group['name'] def_callink_oid = args.oid def_email = group['email'] content = TEMPLATE.format( group_name=def_group_name, callink_oid=def_callink_oid, email=def_email ) while True: content = edit_file(content) try: account = yaml.safe_load(content) except yaml.YAMLError as ex: print('Error parsing your YAML:') print(ex) input('Press enter to continue...') continue missing_key = False for key in ['user_name', 'group_name', 'callink_oid', 'email']: if account.get(key) is None: print('Missing value for key: ' + key) missing_key = True if missing_key: input('Press enter to continue...') continue try: password = prompt_for_new_password( validator=lambda pwd: validate_password( account['user_name'], pwd), ) except KeyboardInterrupt: # we want to allow cancelling during the "enter password" stage # without completely exiting approve print() input('Press enter to start over (or ^C again to cancel)...') continue request = NewAccountRequest( user_name=account['user_name'], real_name=account['group_name'], is_group=True, calnet_uid=None, callink_oid=account['callink_oid'], email=account['email'], encrypted_password=encrypt_password( password, RSA.importKey(CREATE_PUBLIC_KEY), ), handle_warnings=NewAccountRequest.WARNINGS_WARN, ) print() print(bold('Pending account request:')) print(dedent( """\ User Name: {request.user_name} Group Name: {request.real_name} CalLink OID: {request.callink_oid} Email: {request.email} """ ).format(request=request)) if input('Submit request? [yN] ') != 'y': input('Press enter to continue.') continue conf = ConfigParser() conf.read('/etc/ocf-create/ocf-create.conf') celery = Celery( broker=conf.get('celery', 'broker'), backend=conf.get('celery', 'backend'), ) tasks = get_tasks(celery) task = tasks.validate_then_create_account.delay(request) response = wait_for_task(celery, task) new_request = None if response.status == NewAccountResponse.REJECTED: print(bold(red( 'Account requested was rejected for the following reasons:' ))) for error in response.errors: print(red(' - {}'.format(error))) input('Press enter to start over (or ^C to cancel)...') continue elif response.status == NewAccountResponse.FLAGGED: print(bold(yellow( 'Account requested was flagged for the following reasons:' ))) for error in response.errors: print(yellow(' - {}'.format(error))) print(bold( 'You can either create the account anyway, or go back and ' 'modify the request.' )) choice = input('Create the account anyway? [yN] ') if choice in ('y', 'Y'): new_request = request._replace( handle_warnings=NewAccountRequest.WARNINGS_CREATE, ) task = tasks.validate_then_create_account.delay(new_request) response = wait_for_task(celery, task) else: input('Starting over, press enter to continue...') continue if response.status == NewAccountResponse.CREATED: print(bold(green('Account created!'))) print('Your account was created successfully.') print('You\'ve been sent an email with more information.') return else: # this shouldn't be possible; we must have entered some weird state # TODO: report via ocflib print(bold(red('Error: Entered unexpected state.'))) print(red('The request we submitted was:')) print(red(request)) print(red('The new request we submitted (if any) was:')) print(red(new_request)) print(red('The response we received was:')) print(red(response)) print(bold(red('Not really sure what to do here, sorry.'))) input('Press enter to start over...')
def main(): tasks = submission.get_tasks(celery_app()) task = tasks.status.apply_async(queue=socket.gethostname(), args=()) result = task.wait(timeout=5) print(result)