def add_folder(): params = request.get_json() if not params or not params.get('id') or not params.get('folder'): return jsonify({ 'message': 'illegal param', 'code': 104000, }), 400 record_id = params.get('id') folder = params.get('folder') parent = params.get('parent') book_id = params.get('book_id') parent = parent if parent != '.' else '/' parent_path = None if parent != '/': parent_record = Playbook.find_one({ '_id': ObjectId(record_id), 'is_dir': True }) if not parent_record: return jsonify({ 'message': 'invalid params', 'code': 104001, }), 400 parent_path = parent_record.get('path') file_path = os.path.join(parent, folder) record = { 'path': file_path, 'book_id': book_id, 'parent': parent_path, 'is_dir': True, 'content': '', 'is_edit': False, 'add_by': login_user.get('username'), 'created_at': int(time.time()), 'updated_at': datetime.datetime.now().isoformat(), } meta = get_meta(file_path) record.update(meta) record['additions'] = meta check = Playbook.find_one({'book_id': book_id, 'path': record['path']}) if check: additions = check.get('additions') or {} additions.update(meta) record['additions'] = additions Playbook.update_one({'_id': check['_id']}, {'$set': record}) else: Playbook.insert_one(record) return jsonify({ 'message': 'ok', 'code': 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
def delete(_id): record = db.collection('configurations').find_one({'_id': ObjectId(_id)}) if not record: return jsonify({ 'message': 'record not found', 'code': 104040, }), 404 is_register = Playbook.find_one({'register': {'$in': [str(_id)]}}) if is_register: return jsonify({ 'message': 'target record is bind to playbook: %s' % is_register.get('name'), 'code': 104038 }), 403 Configuration.delete_one({'_id': record['_id']}) msg = 'update configuration, name: {}'.format(record.get('name')) logger.info(msg, extra={'record': record, 'force': False}) return jsonify({ 'message': 'ok', 'code': 0, })
def test_upload(self): url = self.get_api_path('/books/%s/playbook' % str(ObjectId())) response = self.client.post(url, headers=self.jwt_headers) self.assert400(response) self.assertResponseCode(response, 104004) data = self.get_data('book') data['name'] = str(uuid.uuid4()) result = Book.insert_one(data.copy()) book_id = result.inserted_id self.trash += [ [Book, book_id], ] url = self.get_api_path('/books/%s/playbook' % str(book_id)) response = self.client.post(url, headers=self.jwt_headers) self.assert400(response) self.assertResponseCode(response, 104001) headers = self.jwt_headers.copy() headers.update({'Content-Type': 'multipart/form-data'}) stream = BytesIO(bytes('mock test', 'utf-8')) params = {'file': (stream, 'test.yaml')} response = self.client.post(url, data=params, headers=headers, content_type='multipart/form-data') self.assert200(response) record = Playbook.find_one({'book_id': str(book_id)}) assert record is not None db.fs().delete(record.get('file_id')) with patch('eclogue.api.book.is_edit') as build_mock: build_mock.return_value = False stream = BytesIO(bytes('mock test', 'utf-8')) params = {'file': (stream, 'binary.mock')} response = self.client.post(url, data=params, headers=headers, content_type='multipart/form-data') self.assert200(response) record = Playbook.find_one({ 'book_id': str(book_id), 'file_id': { '$exists': True } }) assert record is not None db.fs().delete(record.get('file_id')) Playbook().collection.delete_many({'book_id': str(book_id)})
def check_playbook_node(node): """ loop check playbook parent node @param {dict} node """ parent_path = os.path.dirname(node['path']) record = Playbook.find_one({ 'book_id': node['book_id'], 'path': parent_path }) if not record: current = node.copy() current['path'] = parent_path current['parent'] = None if parent_path == '/' else os.path.dirname( parent_path) Playbook.insert_one(current) return check_playbook_node(current) where = { 'book_id': node['book_id'], 'path': node['path'], } return Playbook.update_one(where, node, upsert=True)
def parse_file_inventory(inventory_params): data = {} if type(inventory_params) != list: inventory_params = [inventory_params] for inventory_str in inventory_params: inventory_list = inventory_str.split('@') if len(inventory_list) is not 3: return False mark_name, _id, group = inventory_list record = Playbook.find_one({'_id': ObjectId(_id)}) if not record: return False node = parser_inventory(record['content'], True) # @todo make same as cmdb # record['content'] = json.dumps(record['content']) # record['limit'] = group data.update(node) return data
def upload_playbook(_id): files = request.files record = Book.find_by_id(_id) if not record: return jsonify({ "message": "book not found", "code": 104004, }), 400 if not files: return jsonify({ 'message': 'invalid files params', 'code': 104001 }), 400 file = files['file'] filename = file.filename.lstrip('/') path_list = filename.split('/') filename = '/'.join(path_list[1:]) filename = '/' + filename home_path, basename = os.path.split(filename) file_list = set(_make_path(filename)) for dirname in file_list: check = Playbook.find_one({ 'book_id': _id, 'path': dirname, }) if not check: parent_path, name = os.path.split(dirname) parent_path = parent_path if parent_path != '/' else None parent = { 'path': dirname, 'is_dir': True, 'is_edit': False, 'book_id': _id, 'parent': parent_path, 'name': name, 'created_at': time.time(), } meta = get_meta(dirname) parent.update(meta) parent['additions'] = meta Playbook.insert_one(parent) data = { 'path': filename, 'is_dir': False, 'parent': home_path or None, 'book_id': _id } can_edit = is_edit(file) if not can_edit: file_id = db.save_file(filename=filename, fileobj=file) data['file_id'] = file_id else: content = file.stream.read() content = content.decode('utf-8') data['is_encrypt'] = Vault.is_encrypted(content) if data['is_encrypt']: # @todo vault password vault = Vault() data['content'] = vault.encrypt_string(content) data['md5'] = md5(content) else: data['content'] = content data['md5'] = md5(content) meta = get_meta(data['path']) data.update(meta) data['additions'] = meta data['is_edit'] = can_edit data['created_at'] = time.time() data['updated_at'] = time.time() Playbook.update_one({ 'path': filename, 'book_id': _id }, {'$set': data}, upsert=True) return jsonify({ "message": "ok", "code": 0, })
def books(): query = request.args page = int(query.get('page', 1)) size = int(query.get('pageSize', 50)) offset = (page - 1) * size keyword = query.get('keyword') is_admin = login_user.get('is_admin') start = query.get('start') end = query.get('end') maintainer = query.get('maintainer') where = {'status': {'$ne': -1}} if keyword: where['name'] = {'$regex': keyword} if not is_admin: where['maintainer'] = {'$in': [login_user.get('username')]} elif maintainer: where['maintainer'] = {'$in': [maintainer]} date = [] if start: date.append({ 'created_at': { '$gte': int(time.mktime(time.strptime(start, '%Y-%m-%d'))) } }) if end: date.append({ 'created_at': { '$lte': int(time.mktime(time.strptime(end, '%Y-%m-%d'))) } }) if date: where['$and'] = date cursor = Book.find(where, skip=offset, limit=size) total = cursor.count() records = list(cursor) data = [] for item in records: item['job'] = None where = { 'type': 'playbook', 'template.entry': { '$in': [str(item['_id'])] } } job = db.collection('jobs').find_one(where) if job: item['job'] = { '_id': job.get('_id'), 'name': job.get('name'), 'type': job.get('type'), } if item.get('status'): data.append(item) continue where = { 'role': 'entry', 'book_id': item['_id'], } entry = Playbook.find_one(where) if not entry: Book.update_one({'_id': item['_id']}, {'$set': {'status': 0}}) item['status'] = 0 data.append(item) return jsonify({ 'message': 'ok', 'code': 0, 'data': { 'list': records, 'page': page, 'pageSize': size, 'total': total, } })
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 test_upload(self): data = self.get_data('book') playbook = self.get_data('playbook') data['name'] = str(uuid.uuid4()) result = Book.insert_one(data.copy()) book_id = result.inserted_id playbook['book_id'] = str(book_id) Playbook.insert_one(playbook) self.trash += [ [Book, book_id], [Playbook, playbook['_id']], ] headers = self.jwt_headers.copy() headers.update({'Content-Type': 'multipart/form-data'}) url = self.get_api_path('/playbook/upload') response = self.client.post(url, headers=headers) self.assert400(response) self.assertResponseCode(response, 104000) url = self.get_api_path('/playbook/upload') form = {'parent': '/', 'bookId': str(ObjectId())} response = self.client.post(url, data=form, headers=headers) self.assert400(response) self.assertResponseCode(response, 104001) stream = BytesIO(bytes('mock test', 'utf-8')) form['files'] = (stream, 'test.yaml') response = self.client.post(url, data=form, headers=headers) self.assert404(response) self.assertResponseCode(response, 104040) params = form.copy() stream = BytesIO(bytes('mock test', 'utf-8')) params['files'] = (stream, 'test.yaml') params['parent'] = ObjectId() response = self.client.post(url, data=params, headers=headers, content_type='multipart/form-data') self.assert400(response) self.assertResponseCode(response, 104004) stream = BytesIO(bytes('mock test', 'utf-8')) form['files'] = (stream, 'test.yaml') form['bookId'] = book_id response = self.client.post(url, data=form, headers=headers, content_type='multipart/form-data') self.assert200(response) record = Playbook.find_one({ 'book_id': str(book_id), '_id': { '$ne': playbook['_id'] } }) assert record is not None db.fs().delete(record.get('file_id')) with patch('eclogue.api.playbook.is_edit') as build_mock: build_mock.return_value = False stream = BytesIO(bytes('mock test', 'utf-8')) form['files'] = (stream, 'binary.mock') response = self.client.post(url, data=form, headers=headers, content_type='multipart/form-data') self.assert200(response) record = Playbook.find_one({ 'book_id': str(book_id), 'file_id': { '$exists': True } }) assert record is not None db.fs().delete(record.get('file_id')) Playbook().collection.delete_many({'book_id': str(book_id)})
def upload(): files = request.files form = request.form if not form or not form.get('parent'): return jsonify({ 'message': 'illegal param', 'code': 104000, }), 400 if not files.get('files'): return jsonify({ 'message': 'illegal param', 'code': 104001, }), 400 parent_id = form.get('parent') book_id = form.get('bookId') if parent_id == '/' and book_id: book = Book.find_one({'_id': ObjectId(book_id)}) if not book: return jsonify({ "message": "record not found", "code": 104040, }), 404 current = {'path': '/', 'book_id': book_id} else: current = Playbook.find_one({'_id': ObjectId(parent_id)}) if not current: return jsonify({ "message": "current path not found", "code": 104004, }), 400 file = files['files'] filename = file.filename path = os.path.join(current['path'], filename) # parent = Playbook.find_one({'book_id': book_id, 'path': os.path.dirname(path)}) record = { 'book_id': book_id, 'path': path, 'is_dir': False, 'parent': os.path.dirname(path), } meta = get_meta(path) record.update(meta) can_edit = is_edit(file) if not can_edit: file_id = db.save_file(filename=filename, fileobj=file) record['file_id'] = file_id else: content = file.read() content = content.decode('utf-8') record['content'] = content record['is_edit'] = can_edit record['created_at'] = int(time.time()) record['updated_at'] = datetime.datetime.now().isoformat() # where = { # 'path': path, # 'book_id': ObjectId(book_id) # } # update = { # '$set': record, # } check_playbook_node(record) # Playbook.update_one(where, update=update, upsert=True) return jsonify({ 'message': 'ok', 'code': 0, })