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
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), })
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), })
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), })
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})
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), })
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, }, })
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
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, } }
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