Пример #1
0
 def test_delete_book(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']],
     ]
     url = self.get_api_path('/books/' + str(book_id))
     not_found_url = self.get_api_path('/books/' + str(ObjectId()))
     response = self.client.delete(not_found_url, headers=self.jwt_headers)
     self.assert404(response)
     self.assertResponseCode(response, 154041)
     response = self.client.delete(url, headers=self.jwt_headers)
     self.assert200(response)
     record = Book.find_by_id(book_id)
     self.assertEqual(record, None)
     record = Book().collection.find_one({'_id': book_id})
     self.assertIsNotNone(record)
     self.assertEqual(record['_id'], book_id)
     self.assertEqual(record['status'], -1)
     playbook_record = Playbook().collection.find_one(
         {'_id': playbook['_id']})
     self.assertIsNotNone(playbook_record)
     self.assertEqual(playbook_record['status'], -1)
Пример #2
0
    def get_registry(record):
        if not record:
            return None

        book_id = record.get('book_id')
        book = Book().find_by_id(book_id) or {}

        return {
            '_id': record['_id'],
            'playbook': record.get('name'),
            'path': record.get('path'),
            'book_name': book.get('name'),
            'book_id': book_id,
        }
Пример #3
0
def get_roles_by_book(_id):
    record = Book.find_one(({'_id': ObjectId(_id)}))
    if not record:
        return jsonify({
            'message': 'book not found',
            'code': '104001',
        }), 400

    book_id = str(record['_id'])
    check_playbook(book_id)
    condition = {'book_id': book_id, 'role': 'roles', 'is_dir': True}

    parent = db.collection('playbook').find_one(condition)
    if not parent:
        return jsonify({
            'message': 'ok',
            'code': 0,
            'data': [],
        })

    where = {'book_id': book_id, 'is_dir': True, 'parent': parent.get('path')}
    cursor = db.collection('playbook').find(where)
    records = list(cursor)

    return jsonify({
        'message': 'ok',
        'code': 0,
        'data': records,
    })
Пример #4
0
 def test_download(self):
     url = self.get_api_path('/books/%s/download' % str(ObjectId()))
     response = self.client.get(url, headers=self.jwt_headers)
     self.assert404(response)
     self.assertResponseCode(response, 104040)
     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)
     playbook_file = self.get_data('playbook_file')
     playbook_file['book_id'] = playbook['book_id']
     Playbook.insert_one(playbook_file)
     self.trash += [[Book, book_id], [Playbook, playbook['_id']],
                    [Playbook, playbook_file['_id']]]
     url = self.get_api_path('/books/%s/download' % str(book_id))
     response = self.client.get(url, headers=self.jwt_headers)
     # Playbook().collection.delete_one({'_id': playbook['_id']})
     # Book().collection.delete_one({'_id': book_id})
     self.assert200(response)
     headers = response.headers
     self.assertEqual(headers['Content-Type'], 'application/zip')
     assert len(response.get_data()) > 0
     response.close()
Пример #5
0
 def test_add_book(self):
     data = self.get_data('book')
     data['name'] = str(uuid.uuid4())
     url = self.get_api_path('/books')
     response = self.client.post(url, data="{}", headers=self.jwt_headers)
     self.assert400(response)
     self.assertResponseCode(response, 154000)
     clone = data.copy()
     clone.pop('name')
     response = self.client.post(url,
                                 data=self.body(clone),
                                 headers=self.jwt_headers)
     self.assert400(response)
     self.assertResponseCode(response, 154001)
     clone = data.copy()
     clone['_id'] = str(ObjectId())
     response = self.client.post(url,
                                 data=self.body(clone),
                                 headers=self.jwt_headers)
     self.assert404(response)
     self.assertResponseCode(response, 154041)
     with patch('eclogue.api.book.AnsibleGalaxy') as mock_build:
         clone = data.copy()
         clone['importType'] = 'galaxy'
         response = self.client.post(url,
                                     data=self.body(clone),
                                     headers=self.jwt_headers)
         params = [data.get('galaxyRepo')]
         mock_build.assert_called_with(params)
         self.assert200(response)
         self.assertResponseDataHasKey(response, '_id')
         result = response.json.get('data')
         self.assertEqual(result['name'], clone.get('name'))
         Book().collection.delete_one({'_id': ObjectId(result['_id'])})
Пример #6
0
    def test_rename(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']],
        ]

        path = '/playbook/%s/rename'
        url = self.get_api_path(path % str(ObjectId()))
        response = self.client.patch(url,
                                     data=self.body({'path': ''}),
                                     headers=self.jwt_headers)
        self.assert400(response)
        self.assertResponseCode(response, 104001)
        file_path = os.path.join('newpath', playbook.get('path'))

        response = self.client.patch(url,
                                     data=self.body({'path': file_path}),
                                     headers=self.jwt_headers)
        self.assert404(response)
        self.assertResponseCode(response, 104040)
        url = self.get_api_path(path % str(playbook['_id']))
        response = self.client.patch(url,
                                     data=self.body({'path': file_path}),
                                     headers=self.jwt_headers)
        self.assert200(response)
Пример #7
0
    def test_update_book(self):
        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/' + str(book_id))
        response = self.client.put(url,
                                   data=self.body({}),
                                   headers=self.jwt_headers)
        self.assert400(response)
        self.assertResponseCode(response, 154000)
        not_found_url = self.get_api_path('/books/' + str(ObjectId()))
        body = self.body(data)
        response = self.client.put(not_found_url,
                                   data=body,
                                   headers=self.jwt_headers)
        self.assert404(response)
        self.assertResponseCode(response, 154041)

        with patch('eclogue.api.book.AnsibleGalaxy') as mock_build:
            clone = data.copy()
            clone['importType'] = 'galaxy'
            clone['status'] = 0
            response = self.client.put(url,
                                       data=self.body(clone),
                                       headers=self.jwt_headers)
            params = [data.get('galaxyRepo')]
            mock_build.assert_called_with(params, {'force': True})
            self.assert200(response)
Пример #8
0
def edit_book(_id):
    params = request.get_json() or request.form
    if not params:
        return jsonify({
            'message': 'invalid params',
            'code': 154000,
        }), 400

    name = params.get('name')
    description = params.get('description')
    status = params.get('status', 1)
    maintainer = params.get('maintainer', [])
    import_type = params.get('importType')
    galaxy_repo = params.get('galaxyRepo')
    record = Book.find_one({'_id': ObjectId(_id)})
    if not record:
        return jsonify({
            'message': 'record not found',
            'code': 154041,
        }), 404

    data = {
        'status': status,
    }

    if name:
        data['name'] = name

    if description:
        data['description'] = description

    if maintainer:
        data['maintainer'] = maintainer

    if import_type == 'galaxy':
        galaxy = AnsibleGalaxy([galaxy_repo], {'force': True})
        galaxy.install(record.get('_id'))

    Book.update_one({'_id': ObjectId(_id)}, {'$set': data}, upsert=True)
    logger.info('book update', extra={'record': record, 'changed': data})

    return jsonify({
        'message': 'ok',
        'code': 0,
        'data': data,
    })
Пример #9
0
def book_detail(_id):
    record = Book.find_by_id(_id)
    if not record:
        return jsonify({'message': 'record not found', 'code': 154041}), 400

    return jsonify({
        'message': 'ok',
        'code': 0,
        'data': record,
    })
Пример #10
0
def delete_book(_id):
    record = Book.find_by_id(_id)
    if not record:
        return jsonify({'message': 'record not found', 'code': 154041}), 404

    update = {
        '$set': {
            'status': -1,
            'delete_at': time.time(),
            'delete_by': login_user.get('username'),
            'version': str(ObjectId()),
        }
    }
    Book.update_one({'_id': record['_id']}, update=update)
    db.collection('playbook').update_many({'book_id': str(record['_id'])},
                                          update=update)

    return jsonify({
        'message': 'ok',
        'code': 0,
    })
Пример #11
0
 def test_get_playbook(self):
     book = self.get_data('book')
     playbook = self.get_data('playbook')
     result = Book.insert_one(book.copy())
     book_id = result.inserted_id
     playbook['book_id'] = str(book_id)
     Playbook.insert_one(playbook)
     self.trash += [[Book, book_id], [Playbook, playbook['_id']]]
     url = self.get_api_path('/books/%s/playbook' % str(ObjectId()))
     response = self.client.get(url, headers=self.jwt_headers)
     self.assert400(response)
     self.assertResponseCode(response, 154001)
     Book.update_one({'_id': book_id}, {'$set': {'status': -1}})
     url = self.get_api_path('/books/%s/playbook' % str(book_id))
     response = self.client.get(url, headers=self.jwt_headers)
     self.assert400(response)
     self.assertResponseCode(response, 154001)
     Book.update_one({'_id': book_id}, {'$set': {'status': 1}})
     url = self.get_api_path('/books/%s/playbook' % str(book_id))
     response = self.client.get(url, headers=self.jwt_headers)
     self.assert200(response)
Пример #12
0
    def test_edit_file(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']],
        ]

        path = '/playbook/%s/file'
        url = self.get_api_path(path % str(ObjectId()))
        response = self.client.put(url,
                                   data=self.body({}),
                                   headers=self.jwt_headers)
        self.assert400(response)
        self.assertResponseCode(response, 154000)
        url = self.get_api_path(path % str(ObjectId()))
        params = playbook.copy()
        params.pop('_id')
        register_id = str(ObjectId())
        update = {
            'description': 'big jet plane',
            'is_edit': False,
            'register': [register_id]
        }
        params.update(update)
        response = self.client.put(url,
                                   data=self.body(params),
                                   headers=self.jwt_headers)
        self.assert404(response)
        url = self.get_api_path(path % str(playbook['_id']))
        with patch('eclogue.api.playbook.Configuration') as config_mock:
            config_mock.find.return_value = None
            response = self.client.put(url,
                                       data=self.body(params),
                                       headers=self.jwt_headers)
            self.assert404(response)
            self.assertResponseCode(response, 154042)
            config_mock.find.return_value = {'_id': register_id}
            with patch('eclogue.api.playbook.Workspace') as wk_mock:
                response = self.client.put(url,
                                           data=self.body(params),
                                           headers=self.jwt_headers)
                self.assert200(response)
                wk_mock.assert_called()
                wk_mock.return_value.write_book_file.assert_called()
Пример #13
0
 def test_get_playbook(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']],
     ]
     url = self.get_api_path('/books/%s/playbook' % str(ObjectId()))
     query = {'current': str(playbook['_id'])}
     response = self.client.get(url,
                                query_string=query,
                                headers=self.jwt_headers)
     self.assert400(response)
     self.assertResponseCode(response, 154001)
     url = self.get_api_path('/books/%s/playbook' % playbook['book_id'])
     Book.update_one({'_id': book_id}, {'$set': {'status': -1}})
     response = self.client.get(url,
                                query_string=query,
                                headers=self.jwt_headers)
     self.assert400(response)
     self.assertResponseCode(response, 154001)
     Book.update_one({'_id': book_id}, {'$set': {'status': 1}})
     url = self.get_api_path('/books/%s/playbook' % playbook['book_id'])
     response = self.client.get(url,
                                query_string=query,
                                headers=self.jwt_headers)
     self.assert200(response)
     result = response.json
     data = result.get('data')
     check = map(lambda i: str(i['_id']), data)
     check = list(check)
     assert str(playbook['_id']) in check
Пример #14
0
def dispatch(book_id, entry, payload):
    print('xxxx', book_id, entry, payload)
    book = Book.find_by_id(book_id)
    if not book:
        return False

    username = payload.get('username')
    run_id = payload.get('req_id') or str(uuid.uuid4())
    params = [book_id, run_id]
    options = payload.get('options')
    if not entry:
        return False
    if type(options) == str:
        args = options.split(' ')
        pb = PlaybookCLI(args)
        pb.init_parser()
        options, args = pb.parser.parse_args(args[1:])
        options, args = pb.post_process_args(options, args)
        options = options.__dict__
        options['entry'] = args
        for i in options['inventory']:
            if not os.path.isfile(i):
                i = os.path.basename(i)
                options['inventory'] = i
                break
    queue_name = 'book_runtime'
    func = run
    task = Task(tiger,
                func=func,
                args=params,
                kwargs=options,
                queue=queue_name,
                unique=True,
                lock=True,
                lock_key=book_id)
    run_record = {
        'book_id': book_id,
        'run_id': run_id,
        'run_by': username,
        'options': options,
        'result': '',
        'state': 'pending',
        'created_at': 1,
        'updated_at': 2,
    }
    result = Perform.insert_one(run_record)
    task.delay()

    return result.inserted_id
Пример #15
0
def download_book(_id):
    record = Book.find_by_id(_id)
    if not record:
        return jsonify({'message': 'record not found', 'code': 104040}), 404

    name = record.get('name')
    wk = Workspace()
    with build_book_from_db(name) as bookspace:
        filename = name + '.zip'
        with NamedTemporaryFile('w+t', delete=False) as fd:
            make_zip(bookspace, fd.name)

            return send_file(fd.name,
                             attachment_filename=filename,
                             as_attachment=True)
Пример #16
0
 def test_book_detail(self):
     data = self.get_data('book')
     data['name'] = str(uuid.uuid4())
     result = Book.insert_one(data)
     book_id = result.inserted_id
     self.trash += [
         [Book, book_id],
     ]
     url = self.get_api_path('/books/' + str(ObjectId()))
     response = self.client.get(url, headers=self.jwt_headers)
     self.assert400(response)
     self.assertResponseCode(response, 154041)
     url = self.get_api_path('/books/' + str(book_id))
     response = self.client.get(url, headers=self.jwt_headers)
     self.assert200(response)
Пример #17
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)})
Пример #18
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),
    })
Пример #19
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),
    })
Пример #20
0
    def build_book_from_history(self, build_id):
        history = db.collection('build_history').find_one(
            {'_id': ObjectId(build_id)})
        task_id = history.get('task_id')
        file_id = history.get('file_id')
        job_info = history.get('job_info')
        book = Book.find_one({'_id': ObjectId(job_info.get('book_id'))})
        bookspace = self.get_book_space(book.get('name'))
        bookspace = os.path.join(bookspace, md5(str(task_id)))
        self.mkdir(bookspace)
        save_file = NamedTemporaryFile(delete=False, suffix='.zip').name
        with open(save_file, 'wb') as fd:
            db.fs_bucket().download_to_stream(ObjectId(file_id), fd)

        extract(save_file, bookspace)
        os.unlink(save_file)

        return bookspace
Пример #21
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),
    })
Пример #22
0
    def test_add_folder(self):
        data = self.get_data('book')
        playbook = self.get_data('playbook')
        playbook['is_dir'] = True
        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']],
        ]

        path = '/playbook/folder'
        url = self.get_api_path(path)
        response = self.client.post(url,
                                    data=self.body({
                                        'id': '',
                                        'folder': ''
                                    }),
                                    headers=self.jwt_headers)
        self.assert400(response)
        self.assertResponseCode(response, 104000)
        params = {
            'id': str(ObjectId()),
            'folder': 'test',
            'parent': playbook['path'],
            'book_id': str(book_id),
        }
        response = self.client.post(url,
                                    data=self.body(params),
                                    headers=self.jwt_headers)
        self.assert400(response)
        params['id'] = str(playbook['_id'])
        response = self.client.post(url,
                                    data=self.body(params),
                                    headers=self.jwt_headers)
        self.assert200(response)
        response = self.client.post(url,
                                    data=self.body(params),
                                    headers=self.jwt_headers)
        self.assert200(response)
Пример #23
0
def run(_id):
    book = Book.find_by_id(_id)
    if not book:
        return jsonify({'message': 'record not found', 'code': 10404}), 404

    payload = request.get_json()
    options = payload.get('options')
    entry = options.get('entry')
    args = options.get('args')
    req_id = str(current_request_id())
    params = {
        'username': login_user.get('username'),
        'req_id': req_id,
        'args': args,
        'options': options
    }
    result = dispatch(_id, entry, params)
    if not result:
        return jsonify({'message': 'invalid request', 'code': 104008}), 400

    return jsonify({'message': 'ok', 'code': 0, 'data': {'taskId': result}})
Пример #24
0
def lint_book(_id):
    # lint book use ansibleint
    book = Book.find_by_id(_id)
    if not book:
        return jsonify({'message': 'record not found', 'code': 104040}), 404

    body = request.get_json() or {}
    tags = body.get('tags')
    skiptags = body.get('skiptags')
    tasks = body.get('tasks')
    roles = body.get('roles')
    opts = dict()
    if tags:
        opts['tags'] = tags
    if tasks:
        opts['tasks'] = tasks
    if roles:
        opts['roles'] = roles
    if skiptags:
        opts['skiptags'] = skiptags

    result = lint(_id, options=opts)
    return jsonify({'message': 'ok', 'code': 0, 'data': result})
Пример #25
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),
    })
Пример #26
0
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,
    })
Пример #27
0
def run(book_id, run_id, **options):
    perform = Perform.find_one({'run_id': run_id})
    book = Book.find_by_id(book_id)
    start_at = time.time()
    state = 'progressing'
    result = ''
    old_stdout = sys.stdout
    old_stderr = sys.stderr
    sys.stderr = sys.stdout = temp_stdout = Reporter(run_id)
    try:
        if book.get('repo') == 'git':
            vcs = GitDownload(book.get('repo_options'))
            install_path = vcs.install()
            # @todo

        book_name = book.get('name')
        with build_book_from_db(book_name, build_id=run_id) as dest:
            if not dest:
                result = 'install book failed'
                logger.warning(result)
                state = 'finish'
            else:
                inventory = options['inventory']
                if type(inventory == str):
                    inventory = os.path.join(dest, inventory)

                entry = os.path.join(dest, options['entry'].pop())
                if type(options['tags']) == str:
                    options['tags'] = options['tags'].split(',')
                options['basedir'] = dest
                print('xxxxxxxxxxxxx????', inventory, options)
                runner = PlayBookRunner(inventory, options)
                runner.run([entry])
                result = runner.get_result()
                print('result', result)
                state = 'finish'
    except Exception as err:
        result = str(err)
        extra = {'run_id': run_id}
        logger.error('run task with exception: {}'.format(result), extra=extra)
        state = 'error'
        raise err

    finally:
        content = temp_stdout.getvalue()
        temp_stdout.close(True)
        sys.stdout = old_stdout
        sys.stderr = old_stderr
        print(content)
        finish_at = time.time()
        update = {
            '$set': {
                'start_at': start_at,
                'finish_at': finish_at,
                'state': state,
                'duration': finish_at - start_at,
                'result': str(result),
                'trace': content,
            }
        }
        Perform.update_one({'_id': perform['_id']}, update=update)
Пример #28
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,
        },
    })
Пример #29
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,
        }
    })
Пример #30
0
def add_book():
    params = request.get_json() or request.form
    if not params:
        return jsonify({
            'message': 'invalid params',
            'code': 154000,
        }), 400

    name = params.get('name')
    if not name:
        return jsonify({
            'message': 'name param required',
            'code': 154001,
        }), 400

    existed = Book.find_one({'name': name})
    if existed:
        return jsonify({
            'message': 'book exist',
            'code': 154003,
        }), 400

    description = params.get('description')
    status = params.get('status', 1)
    bid = params.get('_id')
    import_type = params.get('importType')
    galaxy_repo = params.get('galaxyRepo')
    maintainer = params.get('maintainer', [])
    if bid:
        record = Book.find_one({'_id': ObjectId(bid)})
        if not record:
            return jsonify({
                'message': 'record not found',
                'code': 154041,
            }), 404

    else:
        if import_type == 'galaxy' and galaxy_repo:
            galaxy = AnsibleGalaxy([galaxy_repo])
            galaxy.install()
            logger.info('import galaxy', extra={'repo': galaxy_repo})

    data = {
        'name': name,
        'description': description,
        'maintainer': maintainer,
        'import_type': import_type,
        'galaxy_repo': galaxy_repo,
        'status': int(status),
        'created_at': int(time.time())
    }

    result = Book.update_one({'_id': ObjectId(bid)}, {'$set': data},
                             upsert=True)
    data['_id'] = result.upserted_id

    return jsonify({
        'message': 'ok',
        'code': 0,
        'data': data,
    })