Beispiel #1
0
def task_router(task):
    """
    Task router, with sanity check
    """

    error_msg = None

    # Define and lookup the required variables
    attempts = task.get('attempts')
    role = task.get('role')
    uuid = task.get('uuid')
    username = task.get('username', settings.REMOTE_USER)
    password = task.get('password')
    target_ip = task.get('ip')
    extra_vars = task.get('extra_vars')
    only_tags = task.get('only_tags')
    status = redis_helper.get_status(uuid)

    if status['status'] == 'Aborted':
        return

    # Make sure there is at least 30 seconds between retries.
    # If not, pop it back into the queue
    if task.get('last_update'):
        last_update = float(task['last_update'])
        if last_update + 30 >= time.mktime(time.gmtime()):
            redis_helper.add_to_queue(task)
            return

    attempts += 1
    task['attempts'] = attempts

    # Make sure we received all required fields
    if not ((password or has_ssh_keys()) and target_ip and role):
        return False

    # Give it maximum three attempts
    if attempts > 3:
        status_report = {
            'state': 'Failed',
            'msg': 'Too many attempts.',
            'username': username,
            'role': role,
            'target_ip': target_ip,
            'uuid': uuid,
            'attempts': attempts,
            'created_at': status['created_at'],
            'processing_time': time.mktime(time.gmtime()) - float(status['created_at'])
        }
        print json.dumps(status_report)

        redis_helper.update_status(
            uuid=uuid,
            status='Failed'
        )
        return False

    status_report = {
        'state': 'Started',
        'role': role,
        'username': username,
        'target_ip': target_ip,
        'uuid': uuid,
        'attempts': attempts,
        'created_at': status['created_at']
    }
    print json.dumps(status_report)

    redis_helper.update_status(
        uuid=uuid,
        attempts=attempts,
        status='Provisioning'
    )

    inventory = ansible_helper.generate_inventory(
        target_ip=target_ip
    )

    if role in settings.MODULES:
        if role == 'ping':
            run_module = ansible_helper.ping_vm(
                remote_user=username,
                remote_pass=password,
                inventory=inventory
            )
        elif role == 'ssh-keys':
            run_module = ansible_helper.install_ssh_keys(
                remote_user=username,
                remote_pass=password,
                inventory=inventory,
                extra_vars=extra_vars,
            )

        if len(run_module['dark']) > 0:
            failed = True
            error_msg = run_module['dark'][target_ip].get('msg')

        if run_module['contacted'] > 0:
            failed = run_module['contacted'][target_ip].get('failed')
            error_msg = run_module['contacted'][target_ip].get('msg')

        if failed:
            task['last_update'] = str(time.mktime(time.gmtime()))
            redis_helper.update_status(
                uuid=uuid,
                msg=error_msg,
            )
            redis_helper.add_to_queue(task)
            status_report = {
                'state': 'Failed',
                'msg': 'Failed attempt. New attempt scheduled.',
                'username': username,
                'role': role,
                'target_ip': target_ip,
                'uuid': uuid,
                'attempts': attempts,
                'created_at': status['created_at'],
            }
            print json.dumps(status_report)
            return

    elif role in settings.PLAYBOOKS:
        run_playbook = ansible_helper.provision(
            remote_user=username,
            remote_pass=password,
            inventory=inventory,
            role=role,
            extra_vars=extra_vars,
            only_tags=only_tags,
        )

        if not (
            run_playbook[target_ip]['unreachable'] == 0 and
            run_playbook[target_ip]['failures'] == 0
        ):
            task['last_update'] = str(time.mktime(time.gmtime()))
            redis_helper.add_to_queue(task)

            status_report = {
                'state': 'Failed',
                'msg': 'Failed attempt. New attempt scheduled.',
                'username': username,
                'role': role,
                'target_ip': target_ip,
                'uuid': uuid,
                'attempts': attempts,
                'created_at': status['created_at'],
            }
            print json.dumps(status_report)
            return
    else:
        print 'Unknown role/playbook: {}'.format(role)
        redis_helper.update_status(
            uuid=uuid,
            msg='Unknown role/playbook: {}'.format(role)
        )
        return

    redis_helper.update_status(
        uuid=uuid,
        attempts=attempts,
        status='Done',
        install_notes=doc_parser.get_docs(
            role=role,
            extra_vars=extra_vars
        )
    )

    status_report = {
        'state': 'Finished',
        'role': role,
        'username': username,
        'target_ip': target_ip,
        'uuid': uuid,
        'created_at': status['created_at'],
        'processing_time': time.mktime(time.gmtime()) - float(status['created_at'])
    }
    print json.dumps(status_report)
Beispiel #2
0
def create_job():
    uuid = str(uuid4())
    timestamp = str(time.mktime(time.gmtime()))
    response.content_type = 'application/json'

    try:
        payload = json.load(request.body)
    except:
        return raise_error(400, 'Invalid JSON payload.')

    ip = payload.get('ip')
    role = payload.get('role').lower()
    username = payload.get('username')
    password = payload.get('password')
    extra_vars = payload.get('extra_vars', {})
    only_tags = payload.get('only_tags', 'all')

    if not (ip and role and username and password):
        return raise_error(400, 'Missing one of the required arguments.')

    if role not in (settings.MODULES + settings.PLAYBOOKS):
        return raise_error(400, 'Invalid role.')

    # Weave role handler
    if role == 'weave':
        if not extra_vars:
            return raise_error(400, 'extra_vars are required when using the role weave.')

        extra_vars['is_master'] = extra_vars.get('is_master', False)
        extra_vars['is_slave'] = extra_vars.get('is_slave', False)

        # Must be either master or slave
        if not (extra_vars['is_master'] or extra_vars['is_slave']):
            return raise_error(400, 'Must be either master or slave when using role weave.')

        # A passphrase must always be supplied.
        if not extra_vars.get('passphrase'):
            return raise_error(400, 'A passphrase is always required when using role weave.')

        # If the role is a slave, the master IP and passphrase is required.
        if extra_vars['is_slave'] and not extra_vars.get('master_ip'):
            return raise_error(400, 'master_ip is required when setting up a weave slave node.')

    # NodeBB role handler
    if role == 'nodebb':
        if not extra_vars:
            return raise_error(400, 'extra_vars are required when using the role nodebb.')

        # A secret must always be supplied.
        if not extra_vars.get('secret'):
            return raise_error(400, 'A secret is always required when using role nodebb.')

        extra_vars['is_master'] = extra_vars.get('is_master', False)

    if only_tags:
        only_tags = only_tags.split(',')

    redis_helper.create_status(uuid, role, ip)
    task = redis_helper.add_to_queue({
        'created_at': timestamp,
        'last_update': None,
        'role': role,
        'ip': ip,
        'username': username,
        'password': password,
        'uuid': uuid,
        'attempts': 0,
        'extra_vars': extra_vars,
        'only_tags': only_tags,
    })

    if task:
        response.status = 201
        return uuid
    else:
        return raise_error(500, 'Unable to process request.')
Beispiel #3
0
def task_router(task):
    """
    Task router, with sanity check
    """

    # Define and lookup the required variables
    attempts = task.get('attempts')
    role = task.get('role')
    uuid = task.get('uuid')
    username = task.get('username')
    password = task.get('password')
    target_ip = task.get('ip')
    extra_vars = task.get('extra_vars')
    only_tags = task.get('only_tags')
    status = redis_helper.get_status(uuid)

    if status['status'] == 'Aborted':
        return

    # Make sure there is at least 30 seconds between retries.
    # If not, pop it back into the queue
    if task.get('last_update'):
        last_update = float(task['last_update'])
        if last_update + 30 >= time.mktime(time.gmtime()):
            redis_helper.add_to_queue(task)
            return

    attempts += 1
    task['attempts'] = attempts

    # Make sure we received all required fields
    if not (username and password and target_ip and role):
        return False

    # Give it maximum three attempts
    if attempts > 3:
        print 'Too many attempts for {}@{} (uuid: {})'.format(
            username,
            target_ip,
            uuid
        )
        redis_helper.update_status(
            uuid=uuid,
            status='Failed'
        )
        return False

    print 'Got task \'{}\' for {}@{} (attempt: {}, uuid: {})'.format(
        role,
        username,
        target_ip,
        attempts,
        uuid,
    )

    redis_helper.update_status(
        uuid=uuid,
        attempts=attempts,
        status='Provisioning'
    )

    inventory = ansible_helper.generate_inventory(
        target_ip=target_ip
    )

    if role in settings.MODULES:
        if role == 'ping':
            run_module = ansible_helper.ping_vm(
                remote_user=username,
                remote_pass=password,
                inventory=inventory
            )
        elif role == 'ssh-keys':
            run_module = ansible_helper.install_ssh_keys(
                remote_user=username,
                remote_pass=password,
                inventory=inventory,
                extra_vars=extra_vars,
            )

        if len(run_module['dark']) > 0:
            task['last_update'] = str(time.mktime(time.gmtime()))
            redis_helper.update_status(
                uuid=uuid,
                msg=run_module['dark'][target_ip]['msg']
            )
            redis_helper.add_to_queue(task)
            print 'Failed provisioning {} for {}@{} (uuid: {})'.format(
                role,
                username,
                target_ip,
                uuid,
            )
            return

    elif role in settings.PLAYBOOKS:
        run_playbook = ansible_helper.provision(
            remote_user=username,
            remote_pass=password,
            inventory=inventory,
            role=role,
            extra_vars=extra_vars,
            only_tags=only_tags,
        )

        if not (
            run_playbook[target_ip]['unreachable'] == 0 and
            run_playbook[target_ip]['failures'] == 0
        ):
            task['last_update'] = str(time.mktime(time.gmtime()))
            redis_helper.add_to_queue(task)
            print 'Failed provisioning {} for {}@{} (uuid: {})'.format(
                role,
                username,
                target_ip,
                uuid,
            )
            return
    else:
        print 'Unknown role/playbook: {}'.format(role)
        redis_helper.update_status(
            uuid=uuid,
            msg='Unknown role/playbook: {}'.format(role)
        )
        return

    redis_helper.update_status(
        uuid=uuid,
        attempts=attempts,
        status='Done'
    )

    print 'Done provisioning {} for {}@{} (uuid: {})'.format(
        role,
        username,
        target_ip,
        uuid,
    )
Beispiel #4
0
def create_job():
    uuid = str(uuid4())
    timestamp = str(time.mktime(time.gmtime()))
    response.content_type = 'application/json'

    try:
        payload = json.load(request.body)
    except:
        return raise_error(400, 'Invalid JSON payload.')

    ip = payload.get('ip')
    role = payload.get('role').lower()
    username = payload.get('username')
    password = payload.get('password')
    extra_vars = payload.get('extra_vars') if payload.get('extra_vars') else {}
    only_tags = payload.get('only_tags') if payload.get('only_tags') else 'all'

    if not (ip and role and username and password):
        return raise_error(400, 'Missing one of the required arguments.')

    if role not in (settings.MODULES + settings.PLAYBOOKS):
        return raise_error(400, 'Invalid role.')

    # Add public ip as an extra var for easier read back.
    extra_vars['public_ip'] = ip

    # Weave role handler
    if role == 'weave':
        if not extra_vars:
            return raise_error(
                400, 'extra_vars are required when using the role weave.')

        extra_vars['is_master'] = extra_vars.get('is_master', False)
        extra_vars['is_slave'] = extra_vars.get('is_slave', False)

        # Must be either master or slave
        if not (extra_vars['is_master'] or extra_vars['is_slave']):
            return raise_error(
                400, 'Must be either master or slave when using role weave.')

        # A passphrase must always be supplied.
        if not extra_vars.get('passphrase'):
            return raise_error(
                400, 'A passphrase is always required when using role weave.')

        # If the role is a slave, the master IP and passphrase is required.
        if extra_vars['is_slave'] and not extra_vars.get('master_ip'):
            return raise_error(
                400,
                'master_ip is required when setting up a weave slave node.')

    # NodeBB role handler
    if role == 'nodebb':
        if not extra_vars:
            return raise_error(
                400, 'extra_vars are required when using the role nodebb.')

        # A secret must always be supplied.
        if not extra_vars.get('secret'):
            return raise_error(
                400, 'A secret is always required when using role nodebb.')

        extra_vars['is_master'] = extra_vars.get('is_master', False)

    if only_tags:
        only_tags = only_tags.split(',')

    redis_helper.create_status(uuid, role, ip)
    task = redis_helper.add_to_queue({
        'created_at': timestamp,
        'last_update': None,
        'role': role,
        'ip': ip,
        'username': username,
        'password': password,
        'uuid': uuid,
        'attempts': 0,
        'extra_vars': extra_vars,
        'only_tags': only_tags,
    })

    if task:
        response.status = 201
        return uuid
    else:
        return raise_error(500, 'Unable to process request.')
Beispiel #5
0
def task_router(task):
    """
    Task router, with sanity check
    """

    error_msg = None

    # Define and lookup the required variables
    attempts = task.get('attempts')
    role = task.get('role')
    uuid = task.get('uuid')
    username = task.get('username')
    password = task.get('password')
    target_ip = task.get('ip')
    extra_vars = task.get('extra_vars')
    only_tags = task.get('only_tags')
    status = redis_helper.get_status(uuid)

    if status['status'] == 'Aborted':
        return

    # Make sure there is at least 30 seconds between retries.
    # If not, pop it back into the queue
    if task.get('last_update'):
        last_update = float(task['last_update'])
        if last_update + 30 >= time.mktime(time.gmtime()):
            redis_helper.add_to_queue(task)
            return

    attempts += 1
    task['attempts'] = attempts

    # Make sure we received all required fields
    if not (username and password and target_ip and role):
        return False

    # Give it maximum three attempts
    if attempts > 3:
        print 'Too many attempts for {}@{} (uuid: {})'.format(
            username, target_ip, uuid)
        redis_helper.update_status(uuid=uuid, status='Failed')
        return False

    print 'Got task \'{}\' for {}@{} (attempt: {}, uuid: {})'.format(
        role,
        username,
        target_ip,
        attempts,
        uuid,
    )

    redis_helper.update_status(uuid=uuid,
                               attempts=attempts,
                               status='Provisioning')

    inventory = ansible_helper.generate_inventory(target_ip=target_ip)

    if role in settings.MODULES:
        if role == 'ping':
            run_module = ansible_helper.ping_vm(remote_user=username,
                                                remote_pass=password,
                                                inventory=inventory)
        elif role == 'ssh-keys':
            run_module = ansible_helper.install_ssh_keys(
                remote_user=username,
                remote_pass=password,
                inventory=inventory,
                extra_vars=extra_vars,
            )

        if len(run_module['dark']) > 0:
            failed = True
            error_msg = run_module['dark'][target_ip].get('msg')

        if run_module['contacted'] > 0:
            failed = run_module['contacted'][target_ip].get('failed')
            error_msg = run_module['contacted'][target_ip].get('msg')

        if failed:
            task['last_update'] = str(time.mktime(time.gmtime()))
            redis_helper.update_status(
                uuid=uuid,
                msg=error_msg,
            )
            redis_helper.add_to_queue(task)
            print 'Failed provisioning {} for {}@{} (uuid: {})'.format(
                role,
                username,
                target_ip,
                uuid,
            )
            return

    elif role in settings.PLAYBOOKS:
        run_playbook = ansible_helper.provision(
            remote_user=username,
            remote_pass=password,
            inventory=inventory,
            role=role,
            extra_vars=extra_vars,
            only_tags=only_tags,
        )

        if not (run_playbook[target_ip]['unreachable'] == 0
                and run_playbook[target_ip]['failures'] == 0):
            task['last_update'] = str(time.mktime(time.gmtime()))
            redis_helper.add_to_queue(task)
            print 'Failed provisioning {} for {}@{} (uuid: {})'.format(
                role,
                username,
                target_ip,
                uuid,
            )
            return
    else:
        print 'Unknown role/playbook: {}'.format(role)
        redis_helper.update_status(
            uuid=uuid, msg='Unknown role/playbook: {}'.format(role))
        return

    redis_helper.update_status(uuid=uuid,
                               attempts=attempts,
                               status='Done',
                               install_notes=doc_parser.get_docs(
                                   role, extra_vars))

    print 'Done provisioning {} for {}@{} (uuid: {})'.format(
        role,
        username,
        target_ip,
        uuid,
    )