Example #1
0
def check_playbook(book_id):
    record = book.find_by_id(book_id)
    if not record:
        raise Exception('invalid playbook')

    records = Playbook.find({'book_id': book_id})
    for item in records:
        parent = item.get('parent')
        if not item.get('parent'):
            continue

        p_item = Playbook.find_one({'book_id': book_id, 'path': parent})
        if not p_item:
            p_path = os.path.dirname(parent)
            p_path = p_path if p_path != '/' else None
            data = {
                'path': parent,
                'parent': p_path,
                'is_dir': True,
                'is_edit': False,
                'book_id': book_id,
                'role': os.path.basename(parent),
                'created_at': time.time(),
            }

            meta = Workspace.get_meta(parent)
            data.update(meta)
            data['additions'] = meta
            Playbook.insert_one(data)

    return True
Example #2
0
def get_playbook(_id):
    book = Book.find_one({'_id': ObjectId(_id)})
    if not book or not int(book.get('status')):
        return jsonify({
            'message': 'invalid id',
            'code': 154001,
        }), 400

    cursor = Playbook.find({'book_id': str(book.get('_id'))})
    cursor = cursor.sort([('is_edit', pymongo.ASCENDING),
                          ('path', pymongo.ASCENDING)])

    return jsonify({
        'message': 'ok',
        'code': 0,
        'data': list(cursor),
    })
Example #3
0
def get_entry(_id):
    book = Book.find_one(({'_id': ObjectId(_id)}))

    if not book:
        return jsonify({'message': 'book not found', 'code': 164000}), 400

    where = {
        'book_id': str(book.get('_id')),
        'is_dir': False,
        'role': 'entry',
    }
    cursor = Playbook.find(where)

    return jsonify({
        'message': 'ok',
        'code': 0,
        'data': list(cursor),
    })
Example #4
0
def get_playbook(_id):
    book = Book.find_by_id(_id)
    if not book or int(book.get('status') == -1):
        return jsonify({
            'message': 'invalid id',
            'code': 154001,
        }), 400

    cursor = Playbook.find({'book_id': str(book.get('_id'))})
    cursor = cursor.sort([('is_edit', pymongo.ASCENDING),
                          ('path', pymongo.ASCENDING)])
    # for item in cursor:
    #     db.collection('playbook').update_one({'_id': item['_id']}, {'$set': {'book_id': str(item.get('book_id'))}})
    return jsonify({
        'message': 'ok',
        'code': 0,
        'data': list(cursor),
    })
Example #5
0
def install_book_from_dir(dirname, book_id):
    wk = Workspace()
    bucket = wk.import_book_from_dir(dirname, book_id)
    playbooks = Playbook.find({'book_id': book_id})
    files = map(lambda i: i['path'], bucket)
    paths = map(lambda i: i['path'], playbooks)
    diff = list(set(paths) - set(files))
    for item in diff:
        Playbook.delete_one({'book_id': book_id, 'path': item})

    mapping = {}
    map(lambda i: {mapping['path']: i}, playbooks)
    for item in bucket:
        record = mapping.get(item['path'])
        if not record:
            Playbook.insert_one(item)
            continue
        if record['additions']:
            item['additions'].update(record['additions'])
            Playbook.update_one({'_id': record['_id']}, {'$set': item})
Example #6
0
def all_books():
    query = request.args
    job_id = query.get('id')
    where = {}
    cursor = Book.find({})
    records = list(cursor)
    for book in records:

        def get_children(item):
            return {
                'value': item['_id'],
                'label': item.get('name'),
                'isLeaf': True,
            }

        entries = Playbook.find({'book_id': str(book['_id']), 'role': 'entry'})
        children = map(get_children, entries)
        book['children'] = list(children)

    return jsonify({
        'message': 'ok',
        'code': 0,
        'data': list(records),
    })
Example #7
0
def get_job(_id):
    username = login_user.get('username')
    if not _id:
        return jsonify({'message': 'invalid id', 'code': 154000}), 400

    job = Job.find_one({
        '_id': ObjectId(_id),
        'maintainer': {
            '$in': [username]
        }
    })

    # @todo job status
    if not job:
        return jsonify({
            'message': 'invalid id',
            'code': 154001,
        }), 400

    template = job.get('template')
    inventory_type = template.get('inventory_type')
    inventory = template.get('inventory')
    if job.get('type') == 'adhoc':
        inventory_content = parse_cmdb_inventory(inventory)
        return jsonify({
            'message': 'ok',
            'code': 0,
            'data': {
                'record': job,
                'previewContent': inventory_content,
            },
        })

    if inventory_type == 'file':
        inventory_content = parse_file_inventory(inventory)
    else:
        inventory_content = parse_cmdb_inventory(inventory)

    check_playbook(job['book_id'])
    if inventory_type == 'file':
        book = Book.find_one({'_id': ObjectId(job['book_id'])})
        if not book:
            hosts = []
        else:
            hosts = get_inventory_by_book(book.get('_id'),
                                          book_name=book.get('name'))
    else:
        hosts = get_inventory_from_cmdb()

    roles = []
    condition = {
        'book_id': str(job['book_id']),
        'role': 'roles',
        'is_dir': True
    }
    parent = Playbook.find_one(condition)
    if parent:
        where = {
            'book_id': job['book_id'],
            'is_dir': True,
            'parent': parent.get('path')
        }
        cursor = Playbook.find(where)
        roles = list(cursor)

    logs = None
    task = Task.find_one({'job_id': _id})
    if task:
        log = db.collection('logs').find_one({'task_id': str(task['_id'])})
        if log:
            logs = log.get('message')

    return jsonify({
        'message': 'ok',
        'code': 0,
        'data': {
            'record': job,
            'previewContent': inventory_content,
            'hosts': hosts,
            'roles': roles,
            'logs': logs,
        },
    })
Example #8
0
def lint(book_id, options, config=None):
    """
    base on ansiblelint
    refer to ansiblelint.__main__.py
    :param book_id:
    :param options:
    :param config:
    :return: None
    """
    formatter = formatters.Formatter()
    options = get_default_options(options)
    where = {
        'book_id': str(book_id),
        'role': 'entry',
    }
    entries = Playbook.find(where)
    if not entries:
        return False

    book = Book.find_by_id(book_id)
    if not book:
        return False

    if config:
        if 'quiet' in config:
            options.quiet = options.quiet or config['quiet']

        if 'parseable' in config:
            options.parseable = options.parseable or config['parseable']

        if 'parseable_severity' in config:
            options.parseable_severity = options.parseable_severity or \
                                         config['parseable_severity']

        if 'use_default_rules' in config:
            options.use_default_rules = options.use_default_rules or config['use_default_rules']

        if 'verbosity' in config:
            options.verbosity = options.verbosity + config['verbosity']

        options.exclude_paths.extend(
            config.get('exclude_paths', []))

        if 'rulesdir' in config:
            options.rulesdir = options.rulesdir + config['rulesdir']

        if 'skip_list' in config:
            options.skip_list = options.skip_list + config['skip_list']

        if 'tags' in config:
            options.tags = options.tags + config['tags']

    if options.quiet:
        formatter = formatters.QuietFormatter()

    if options.parseable:
        formatter = formatters.ParseableFormatter()

    if options.parseable_severity:
        formatter = formatters.ParseableSeverityFormatter()

    # no args triggers auto-detection mode
    # if len(args) == 0 and not (options.listrules or options.listtags):
    #     args = get_playbooks_and_roles(options=options)

    if options.use_default_rules:
        rulesdirs = options.rulesdir + [default_rulesdir]
    else:
        rulesdirs = options.rulesdir or [default_rulesdir]

    rules = RulesCollection()
    for rulesdir in rulesdirs:
        rules.extend(RulesCollection.create_from_directory(rulesdir))

    if options.listrules:
        return 0

    if options.listtags:
        return 0

    if isinstance(options.tags, six.string_types):
        options.tags = options.tags.split(',')

    skip = set()
    for s in options.skip_list:
        skip.update(str(s).split(','))

    options.skip_list = frozenset(skip)
    with build_book_from_db(book.get('name'), options.get('roles')) as book_path:
        playbooks = []
        for record in entries:
            entry = os.path.join(book_path, record['path'][1:])
            playbooks.append(entry)

        playbooks = sorted(set(playbooks))
        matches = list()
        checked_files = set()
        for playbook in playbooks:
            runner = Runner(rules, playbook, options.tags,
                            options.skip_list, options.exclude_paths,
                            options.verbosity, checked_files)
            matches.extend(runner.run())

        matches.sort(key=lambda x: (normpath(x.filename), x.linenumber, x.rule.id))
        results = []
        for match in matches:
            filename = str(match.filename)
            filename = filename.replace(book_path, '')
            results.append({
                'lineNumber': match.linenumber,
                'line': str(match.line),
                'rule': match.rule.id,
                'filename': filename,
                'message': match.message,
            })

        return results
Example #9
0
def load_ansible_playbook(payload):
    template = payload.get('template')
    extra = payload.get('extra', {}) or {}
    if not template:
        return {
            'message': 'invalid params',
            'code': 104000,
        }
    name = template.get('name')
    if not name:
        return {
            'message': 'name required',
            'code': 104000,
        }
    entry = template.get('entry')
    if len(entry) < 2:
        return {
            'message': 'entry not found',
            'code': 104001,
        }
    book_id, entry_id = entry
    book_record = Book.find_by_id(book_id)
    if not book_record:
        return {
            'message': 'book not found',
            'code': 1040011,
        }
    entry_record = Playbook.find_by_id(entry_id)
    if not entry_record:
        return {
            'message': 'entry not found',
            'code': 104001,
        }
    inventory_type = template.get('inventory_type', 'file')
    inventory = template.get('inventory', None)
    if not inventory:
        return {'message': 'invalid param inventory', 'code': 104002}
    if inventory_type == 'file':
        inventory_record = parse_file_inventory(inventory)
    else:
        inventory_record = parse_cmdb_inventory(inventory)

    if not inventory_record:
        return {'message': 'illegal inventory', 'code': 104002}
    group_name = inventory_record.keys()
    if not inventory_record:
        return {'message': 'invalid param inventory', 'code': 104002}
    roles = template.get('roles')
    role_names = []
    if roles:
        roles = list(map(lambda i: ObjectId(i), roles))
        check = Playbook.find({
            'book_id': book_id,
            '_id': {
                '$in': roles,
            }
        })
        check = list(check)
        if not check:
            return {'message': 'invalid param role', 'code': 104003}

        role_names = list(map(lambda i: i.get('name'), check))

    extra_vars = {
        'node': list(group_name),
    }

    private_key = template.get('private_key')
    if private_key:
        key_record = Credential.find_one({
            '_id': ObjectId(private_key),
            'type': 'private_key'
        })
        if not key_record:
            return {'message': 'invalid private key', 'code': 104031}

    variables = extra.get('extraVars') or {}
    # variables.update({'node': inventory_record.get('limit')})
    if type(variables) in [dict, list]:
        variables = yaml.safe_dump(variables)

    app = template.get('app')
    if app:
        # @todo status=1
        app_record = Application.find_by_id(app)
        if not app_record:
            return {'message': 'invalid app', 'code': 104043}

        app_type = app_record.get('type')
        app_params = app_record.get('params')
        integration = Integration(app_type, app_params)
        check_app = integration.check_app_params()
        if not check_app:
            return {'message': 'invalid app', 'code': 104014}

        job_space = integration.get_job_space(name)
        if job_space and variables:
            tpl = Template(variables)
            variables = tpl.render(ECLOGUE_JOB_SPACE=job_space)

    if variables:
        variables = yaml.safe_load(variables)
        variables and extra_vars.update(variables)

    options = dict()
    extra_options = template.get('extraOptions')
    if extra_options and type(extra_options) == dict:
        options = extra_options.copy()
        # default_options = get_default_options('playbook')
        # for key, value in extra_options.items():
        #     if default_options.get(key):
        #         options[key] = value

    options['skip_tags'] = template.get('skip_tags', [])
    options['inventory'] = inventory_record
    # @todo limit
    # options['limit'] = inventory_record.get('limit', None)
    # options['credential'] = template.get('credential')
    options['limit'] = template.get('limit', 'all')
    options['forks'] = template.get('forks', 5)
    options['tags'] = template.get('tags', [])
    options['listtags'] = template.get('listtags', False)
    options['listtasks'] = template.get('listtasks', False)
    options['timeout'] = template.get('timeout', 10)
    options['verbosity'] = template.get('verbosity', 0)
    become_method = template.get('become_method')
    if become_method:
        options['become'] = 'yes'
        options['become_method'] = become_method
        if template.get('become_user'):
            options['become_user'] = template.get('become_user')

    vault_pass = template.get('vault_pass')
    if vault_pass:
        vault_record = Credential.find_one({'_id': ObjectId(vault_pass)})
        if not vault_record or not vault_record.get('body'):
            return {'message': 'invalid vault pass', 'code': 104004}

        vault_body = vault_record.get('body')
        vault = Vault({'vault_pass': config.vault.get('secret')})
        options['vault_pass'] = vault.decrypt_string(
            vault_body.get('vault_pass'))

    options['verbosity'] = template.get('verbosity', 0)
    options['diff'] = template.get('diff', False)
    # options['vault'] = template.get('vault')
    options['extra_vars'] = extra_vars
    status = int(extra.get('status', 0))

    return {
        'message': 'ok',
        'data': {
            'inventory': options['inventory'],
            'options': options,
            'name': name,
            'entry': entry_record['name'],
            'book_id': book_id,
            'book_name': book_record['name'],
            'roles': role_names,
            'inventory_type': inventory_type,
            'private_key': private_key,
            'template': template,
            'extra': extra,
            'status': status,
        }
    }
Example #10
0
def get_inventory_by_book(book_id, keyword=None, book_name='default'):
    condition = {
        'book_id': str(book_id),
        'role': 'hosts',
        'is_edit': True
    }
    cursor = Playbook.find(condition)
    records = list(cursor)
    hosts = []
    for item in records:
        loader = YamlLoader()
        inventory = HostsManager(loader=loader, sources=item['content'])
        groups = inventory.get_groups_dict()
        index = 0
        for group, names in groups.items():
            index += 1
            group = os.path.basename(group)
            if not names:
                continue

            if keyword:
                pattern = re.compile(keyword, 'i')
                res = pattern.search(group)
                if res is None:
                    continue

            data = {
                '_id': item.get('_id'),
                'name': group,
                'group_name': book_name,
                'collection': 'group',
                'parent': 'entry',
                'key': index,
                'title': group,
                'value': '@'.join(['group', str(item.get('_id')), group]),
            }
            children = []
            for name in names:
                index += 1
                if keyword:
                    pattern = re.compile(keyword, 'i')
                    res = pattern.search(name)
                    if res is None:
                        continue

                value = '@'.join(['node', str(item.get('_id')), name])
                node = {
                    '_id': item['_id'],
                    'name': name,
                    'collection': 'node',
                    'group_name': group,
                    'parent': 'group',
                    'key': index,
                    'title': name,
                    'value': value,
                }
                children.append(node)
            data['children'] = children
            hosts.append(data)
        for group, names in groups.items():
            group = os.path.basename(group)
            if group == 'all':
                continue
            for name in names:
                if keyword:
                    pattern = re.compile(keyword, 'i')
                    res = pattern.search(name)
                    if res is None:
                        continue

                value = '@'.join(['node', str(item.get('_id')), name])
                data = {
                    '_id': item['_id'],
                    'name': name,
                    'collection': 'node',
                    'group_name': group,
                    'parent': 'group',
                    'key': value,
                    'title': name,
                    'value': value,
                }
                hosts.append(data)
    return hosts