def add_jenkins(): user = login_user body = request.get_json() if not body: return jsonify({ 'code': 114001, 'message': 'invalid params', }) base_url = body.get('base_url') username = body.get('username') password = body.get('password') artifacts = body.get('artifacts') if not base_url or not username or not password: return jsonify({ 'message': 'miss required params', 'code': 114002 }), 400 vault_pass = config.jenkins.get('vault') options = {'vault_pss': vault_pass} encrypt = Vault(options).encrypt_string(password) record = { 'add_by': user.username, 'setting': { 'username': username, 'baseurl': base_url, 'password': encrypt, 'artifacts': artifacts, }, 'created_at': int(time.time()) }
def encrypt_credential(text): secret = config.vault.get('secret') options = { 'vault_pass': secret } vault = Vault(options=options) return vault.encrypt_string(text)
def get_variables(self, ids, decode=False): records = self.find_by_ids(ids) variables = {} vault = Vault({'vault_pass': config.vault.get('secret')}) for record in records: config_vars = record.get('variables') if not config_vars: continue for k, v in config_vars.items(): key = '_'.join( ['ECLOGUE', 'CONFIG', record.get('name', ''), k]) if not decode: variables[key] = v continue is_encrypt = Vault.is_encrypted(v) value = v if is_encrypt: value = vault.decrypt_string(value) variables[key] = value return variables
def add_key(): user = login_user payload = request.get_json() if not payload: return jsonify({ 'message': 'illegal params', 'code': 104000, }), 400 public_key = payload.get('public_key') name = payload.get('name') if not public_key: return jsonify({'message': 'invalid public key', 'code': 104000}), 400 ssh = SSHKey(public_key) try: ssh.parse() except Exception as err: return jsonify({ 'message': 'invalid ssh key: {}'.format(str(err)), 'code': 104001, }), 400 fingerprint = ssh.hash_md5() existed = db.collection('public_keys').find_one( {'fingerprint': fingerprint}) if existed: return jsonify({ 'message': 'ssh public key existed', 'code': 104003 }), 400 options = {'vault_pass': config.vault.get('secret')} encode = Vault(options).encrypt_string(public_key) data = { 'fingerprint': fingerprint, 'user_id': user.get('user_id'), 'content': encode, 'name': name, 'created_at': time.time() } result = db.collection('public_keys').insert_one(data) data['_id'] = result.inserted_id logger.info('add public_keys', extra={'record': data}) return jsonify({ 'message': 'ok', 'code': 0, })
def parse_register(record): register = record.get('register') if not register: return record c_ids = map(lambda i: ObjectId(i), register) cfg_records = Configuration.find({'_id': {'$in': list(c_ids)}}) if not cfg_records: return record try: variables = {} content = yaml.safe_load(record.get('content', '')) if not content: return record vault = Vault({'vault_pass': config.vault.get('secret')}) for cfg in cfg_records: config_vars = cfg.get('variables') if not config_vars: continue for k, v in config_vars.items(): key = '_'.join( ['ECLOGUE', 'CONFIG', cfg.get('name', ''), k]) is_encrypt = Vault.is_encrypted(v) value = v if is_encrypt: value = vault.decrypt_string(value) variables[key] = value content = dict(content) content.update(variables) record['content'] = yaml.safe_dump(content) except Exception as e: print(e) return record
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 explore(): payload = request.get_json() form = request.form payload = payload or form if not payload: return jsonify({ 'message': 'empty request payload', 'code': 144000, }), 400 explore_type = payload.get('type') credential = payload.get('credential') # if not credential: # return jsonify({ # 'message': 'param credential required', # 'code': 144000, # }), 400 private_key = '' if credential: credential = Credential.find_by_id(credential) if not credential or not credential.get('status'): return jsonify({ 'message': 'invalid credential', 'code': 144040, }), 404 vault = Vault({'vault_pass': config.vault.get('secret')}) body = credential['body'] private_key = vault.decrypt_string(body[credential['type']]) maintainer = payload.get('maintainer') if not maintainer or type(maintainer) != list: maintainer = [login_user.get('username')] else: maintainer.extend(login_user.get('username')) if explore_type == 'manual': region = payload.get('region') group = payload.get('group') ssh_host = payload.get('ssh_host') ssh_user = payload.get('ssh_user') ssh_port = payload.get('ssh_port') or 22 if not ssh_host or not ssh_user or not ssh_port: return jsonify({ 'message': 'illegal ssh connection params', 'code': 144001, }), 400 region_record = Region.find_one({'_id': ObjectId(region)}) if not region_record: return jsonify({ 'message': 'invalid region', 'code': 144002, }), 400 group_record = Group.find_by_ids(group) if not group_record: return jsonify({ 'message': 'invalid group', 'code': 144003, }), 400 options = { 'remote_user': ssh_user, 'verbosity': 3, } hosts = ssh_host + ':' + str(ssh_port) + ',' runner = setup(hosts, options, private_key) result = runner.get_result() data = process_ansible_setup(result) records = [] if not data: return jsonify({ 'code': 144009, 'message': 'fetch target host failed', 'data': result }), 406 for item in data: item['ansible_ssh_host'] = ssh_host item['ansible_ssh_user'] = ssh_user item['ansible_ssh_port'] = ssh_port item['maintainer'] = maintainer item['group'] = list(map(lambda i: str(i['_id']), group_record)) item['add_by'] = login_user.get('username') item['state'] = 'active' where = {'ansible_ssh_host': item['ansible_ssh_host']} update = {'$set': item} result = db.collection('machines').update_one(where, update, upsert=True) extra = item.copy() extra['_id'] = result.upserted_id logger.info('add machines hostname: '.format({item['hostname']}), extra={'record': data}) records.append(item) # def func(item): # item['ansible_ssh_host'] = ssh_host # item['ansible_ssh_user'] = ssh_user # item['ansible_ssh_port'] = ssh_port # item['maintainer'] = maintainer # item['group'] = list(map(lambda i: str(i['_id']), group_record)) # item['add_by'] = login_user.get('username') # item['state'] = 'active' # # return item # # data = list(map(func, data)) # db.collection('machines').insert_many(data) return jsonify({ 'message': 'ok', 'code': 0, 'data': records, 'records': data }) files = request.files if not files: return jsonify({ 'message': 'illegal param', 'code': 104000, }), 400 file = files.get('inventory') if not files: return jsonify({ 'message': 'files required', 'code': 104001, }), 400 sources = file.read().decode('utf-8') # inventory is not only yaml with NamedTemporaryFile('w+t', delete=True) as fd: fd.write(sources) fd.seek(0) options = { 'verbosity': 0, } runner = setup(fd.name, options, private_key) result = runner.get_result() data = process_ansible_setup(result) if not data: return jsonify({ 'code': 144009, 'message': 'fetch target host failed', 'data': result }), 400 manager = runner.inventory hosts = parser_inventory(manager) records = [] default_region = db.collection('regions').find_one({'name': 'default'}) if not default_region: result = db.collection('regions').insert_one({ 'name': 'default', 'add_by': None, 'description': 'auto generate', 'created_at': time.time(), }) region_id = str(result.inserted_id) else: region_id = str(default_region.get('_id')) for node in data: hostname = node.get('ansible_hostname') for group, host in hosts.items(): where = {'name': group} # insert_data = {'$set': insert_data} existed = db.collection('groups').find_one(where) if not existed: insert_data = { 'name': group, 'region': region_id, 'description': 'auto generator', 'state': 'active', 'add_by': login_user.get('username'), 'maintainer': None, 'created_at': int(time.time()) } insert_result = db.collection('groups').insert_one( insert_data) group = insert_result.inserted_id else: group = existed['_id'] if host.get('name') == hostname: vars = host.get('vars') node['ansible_ssh_host'] = vars.get('ansible_ssh_host') node['ansible_ssh_user'] = vars.get( 'ansible_ssh_user', 'root') node['ansible_ssh_port'] = vars.get( 'ansible_ssh_port', '22') node['group'] = [group] node['add_by'] = login_user.get('username') node['state'] = 'active' break records.append(node) for record in records: where = {'ansible_ssh_host': record['ansible_ssh_host']} update = {'$set': record} result = db.collection('machines').update_one(where, update, upsert=True) extra = record.copy() extra['_id'] = result.upserted_id logger.info('add machines hostname: '.format({record['hostname']}), extra={'record': data}) return jsonify({ 'message': 'ok', 'code': 0, 'data': data, 'records': records, })
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, } }