def run(self, module_name='shell', module_args='', timeout=10, forks=10, pattern='*', become=False, become_method='sudo', become_user='******', become_pass='', transport='paramiko'): """ run module from andible ad-hoc. module_name: ansible module_name module_args: ansible module args """ hoc = Runner(module_name=module_name, module_args=module_args, timeout=timeout, inventory=self.inventory, pattern=pattern, forks=forks, become=become, become_method=become_method, become_user=become_user, become_pass=become_pass, transport=transport) self.results_raw = hoc.run() logger.debug(self.results_raw) return self.results_raw
def download(self): while True: try: print "进入批量下载模式" print "请输入主机名或ansible支持的pattern, 多个主机:分隔,q退出" pattern = raw_input("\033[1;32mPattern>:\033[0m ").strip() if pattern == 'q': break else: assets = self.user_perm.get('asset').keys() res = gen_resource({'user': self.user, 'asset': assets}, perm=self.user_perm) runner = MyRunner(res) asset_name_str = '' print "匹配主机:\n" for inv in runner.inventory.get_hosts(pattern=pattern): asset_name_str += '%s ' % inv.name print ' %s' % inv.name if not asset_name_str: color_print('没有匹配主机') continue print while True: tmp_dir = get_tmp_dir() logger.debug('Download tmp dir: %s' % tmp_dir) print "请输入文件路径(不支持目录)" file_path = raw_input("\033[1;32mPath>:\033[0m ").strip() if file_path == 'q': break if not file_path: color_print("文件路径为空") continue runner.run('fetch', module_args='src=%s dest=%s' % (file_path, tmp_dir), pattern=pattern) ret = runner.results FileLog(user=self.user.name, host=asset_name_str, filename=file_path, type='download', remote_ip=remote_ip, result=ret).save() logger.debug('Download file result: %s' % ret) os.chdir('/tmp') tmp_dir_name = os.path.basename(tmp_dir) if not os.listdir(tmp_dir): color_print('下载全部失败') continue bash('tar czf %s.tar.gz %s && sz %s.tar.gz' % (tmp_dir, tmp_dir_name, tmp_dir)) if ret.get('failed'): error = '文件名称: %s \n下载失败: [ %s ] \n下载成功 [ %s ]' % \ ('%s.tar.gz' % tmp_dir_name, ', '.join(ret.get('failed').keys()), ', '.join(ret.get('ok').keys())) color_print(error) else: msg = '文件名称: %s \n下载成功 [ %s ]' % ('%s.tar.gz' % tmp_dir_name, ', '.join(ret.get('ok').keys())) color_print(msg, 'green') print except IndexError: pass
def get_connect_info(self): """ 获取需要登陆的主机的信息和映射用户的账号密码 """ asset_info = get_asset_info(self.asset) role_key = get_role_key(self.user, self.role) # 获取角色的key,因为ansible需要权限是600,所以统一生成用户_角色key role_pass = CRYPTOR.decrypt(self.role.password) connect_info = {'user': self.user, 'asset': self.asset, 'ip': asset_info.get('ip'), 'port': int(asset_info.get('port')), 'role_name': self.role.name, 'role_pass': role_pass, 'role_key': role_key} logger.debug(connect_info) return connect_info
def get_log(self): """ Logging user command and output. 记录用户的日志 """ tty_log_dir = os.path.join(LOG_DIR, 'tty') date_today = datetime.datetime.now() date_start = date_today.strftime('%Y%m%d') time_start = date_today.strftime('%H%M%S') today_connect_log_dir = os.path.join(tty_log_dir, date_start) log_file_path = os.path.join( today_connect_log_dir, '%s_%s_%s' % (self.username, self.asset_name, time_start)) try: mkdir(os.path.dirname(today_connect_log_dir), mode=777) mkdir(today_connect_log_dir, mode=777) except OSError: logger.debug('创建目录 %s 失败,请修改%s目录权限' % (today_connect_log_dir, tty_log_dir)) raise ServerError('创建目录 %s 失败,请修改%s目录权限' % (today_connect_log_dir, tty_log_dir)) try: log_file_f = open(log_file_path + '.log', 'a') log_time_f = open(log_file_path + '.time', 'a') except IOError: logger.debug('创建tty日志文件失败, 请修改目录%s权限' % today_connect_log_dir) raise ServerError('创建tty日志文件失败, 请修改目录%s权限' % today_connect_log_dir) if self.login_type == 'ssh': # 如果是ssh连接过来,记录connect.py的pid,web terminal记录为日志的id pid = os.getpid() self.remote_ip = remote_ip # 获取远端IP else: pid = 0 log = Log(user=self.username, host=self.asset_name, remote_ip=self.remote_ip, login_type=self.login_type, log_path=log_file_path, start_time=date_today, pid=pid) log.save() if self.login_type == 'web': log.pid = log.id # 设置log id为websocket的id, 然后kill时干掉websocket log.save() log_file_f.write('Start at %s\r\n' % datetime.datetime.now()) return log_file_f, log_time_f, log
def get_connect_info(self): """ 获取需要登陆的主机的信息和映射用户的账号密码 """ asset_info = get_asset_info(self.asset) role_key = get_role_key( self.user, self.role) # 获取角色的key,因为ansible需要权限是600,所以统一生成用户_角色key role_pass = CRYPTOR.decrypt(self.role.password) connect_info = { 'user': self.user, 'asset': self.asset, 'ip': asset_info.get('ip'), 'port': int(asset_info.get('port')), 'role_name': self.role.name, 'role_pass': role_pass, 'role_key': role_key } logger.debug(connect_info) return connect_info
def get_log(self): """ Logging user command and output. 记录用户的日志 """ tty_log_dir = os.path.join(LOG_DIR, 'tty') date_today = datetime.datetime.now() date_start = date_today.strftime('%Y%m%d') time_start = date_today.strftime('%H%M%S') today_connect_log_dir = os.path.join(tty_log_dir, date_start) log_file_path = os.path.join(today_connect_log_dir, '%s_%s_%s' % (self.username, self.asset_name, time_start)) try: mkdir(os.path.dirname(today_connect_log_dir), mode=777) mkdir(today_connect_log_dir, mode=777) except OSError: logger.debug('创建目录 %s 失败,请修改%s目录权限' % (today_connect_log_dir, tty_log_dir)) raise ServerError('创建目录 %s 失败,请修改%s目录权限' % (today_connect_log_dir, tty_log_dir)) try: log_file_f = open(log_file_path + '.log', 'a') log_time_f = open(log_file_path + '.time', 'a') except IOError: logger.debug('创建tty日志文件失败, 请修改目录%s权限' % today_connect_log_dir) raise ServerError('创建tty日志文件失败, 请修改目录%s权限' % today_connect_log_dir) if self.login_type == 'ssh': # 如果是ssh连接过来,记录connect.py的pid,web terminal记录为日志的id pid = os.getpid() self.remote_ip = remote_ip # 获取远端IP else: pid = 0 log = Log(user=self.username, host=self.asset_name, remote_ip=self.remote_ip, login_type=self.login_type, log_path=log_file_path, start_time=date_today, pid=pid) log.save() if self.login_type == 'web': log.pid = log.id # 设置log id为websocket的id, 然后kill时干掉websocket log.save() log_file_f.write('Start at %s\r\n' % datetime.datetime.now()) return log_file_f, log_time_f, log
def upload(self): while True: try: print "进入批量上传模式" print "请输入主机名或ansible支持的pattern, 多个主机:分隔 q退出" pattern = raw_input("\033[1;32mPattern>:\033[0m ").strip() if pattern == 'q': break else: assets = self.user_perm.get('asset').keys() res = gen_resource({'user': self.user, 'asset': assets}, perm=self.user_perm) runner = MyRunner(res) asset_name_str = '' print "匹配主机:" for inv in runner.inventory.get_hosts(pattern=pattern): print inv.name asset_name_str += '%s ' % inv.name if not asset_name_str: color_print('没有匹配主机') continue tmp_dir = get_tmp_dir() logger.debug('Upload tmp dir: %s' % tmp_dir) os.chdir(tmp_dir) bash('rz') filename_str = ' '.join(os.listdir(tmp_dir)) if not filename_str: color_print("上传文件为空") continue logger.debug('上传文件: %s' % filename_str) runner = MyRunner(res) runner.run('copy', module_args='src=%s dest=%s directory_mode' % (tmp_dir, '/tmp'), pattern=pattern) ret = runner.results FileLog(user=self.user.name, host=asset_name_str, filename=filename_str, remote_ip=remote_ip, type='upload', result=ret).save() logger.debug('Upload file: %s' % ret) if ret.get('failed'): error = '上传目录: %s \n上传失败: [ %s ] \n上传成功 [ %s ]' % (tmp_dir, ', '.join(ret.get('failed').keys()), ', '.join(ret.get('ok').keys())) color_print(error) else: msg = '上传目录: %s \n传送成功 [ %s ]' % (tmp_dir, ', '.join(ret.get('ok').keys())) color_print(msg, 'green') print except IndexError: pass
def download(self): while True: try: print "进入批量下载模式" print "请输入主机名或ansible支持的pattern, 多个主机:分隔,q退出" pattern = raw_input("\033[1;32mPattern>:\033[0m ").strip() if pattern == 'q': break else: assets = self.user_perm.get('asset').keys() res = gen_resource({ 'user': self.user, 'asset': assets }, perm=self.user_perm) runner = MyRunner(res) asset_name_str = '' print "匹配主机:\n" for inv in runner.inventory.get_hosts(pattern=pattern): asset_name_str += '%s ' % inv.name print ' %s' % inv.name if not asset_name_str: color_print('没有匹配主机') continue print while True: tmp_dir = get_tmp_dir() logger.debug('Download tmp dir: %s' % tmp_dir) print "请输入文件路径(不支持目录)" file_path = raw_input( "\033[1;32mPath>:\033[0m ").strip() if file_path == 'q': break if not file_path: color_print("文件路径为空") continue runner.run('fetch', module_args='src=%s dest=%s' % (file_path, tmp_dir), pattern=pattern) ret = runner.results FileLog(user=self.user.name, host=asset_name_str, filename=file_path, type='download', remote_ip=remote_ip, result=ret).save() logger.debug('Download file result: %s' % ret) os.chdir('/tmp') tmp_dir_name = os.path.basename(tmp_dir) if not os.listdir(tmp_dir): color_print('下载全部失败') continue bash('tar czf %s.tar.gz %s && sz %s.tar.gz' % (tmp_dir, tmp_dir_name, tmp_dir)) if ret.get('failed'): error = '文件名称: %s \n下载失败: [ %s ] \n下载成功 [ %s ]' % \ ('%s.tar.gz' % tmp_dir_name, ', '.join(ret.get('failed').keys()), ', '.join(ret.get('ok').keys())) color_print(error) else: msg = '文件名称: %s \n下载成功 [ %s ]' % ( '%s.tar.gz' % tmp_dir_name, ', '.join( ret.get('ok').keys())) color_print(msg, 'green') print except IndexError: pass
def upload(self): while True: try: print "进入批量上传模式" print "请输入主机名或ansible支持的pattern, 多个主机:分隔 q退出" pattern = raw_input("\033[1;32mPattern>:\033[0m ").strip() if pattern == 'q': break else: assets = self.user_perm.get('asset').keys() res = gen_resource({ 'user': self.user, 'asset': assets }, perm=self.user_perm) runner = MyRunner(res) asset_name_str = '' print "匹配主机:" for inv in runner.inventory.get_hosts(pattern=pattern): print inv.name asset_name_str += '%s ' % inv.name if not asset_name_str: color_print('没有匹配主机') continue tmp_dir = get_tmp_dir() logger.debug('Upload tmp dir: %s' % tmp_dir) os.chdir(tmp_dir) bash('rz') filename_str = ' '.join(os.listdir(tmp_dir)) if not filename_str: color_print("上传文件为空") continue logger.debug('上传文件: %s' % filename_str) runner = MyRunner(res) runner.run('copy', module_args='src=%s dest=%s directory_mode' % (tmp_dir, '/tmp'), pattern=pattern) ret = runner.results FileLog(user=self.user.name, host=asset_name_str, filename=filename_str, remote_ip=remote_ip, type='upload', result=ret).save() logger.debug('Upload file: %s' % ret) if ret.get('failed'): error = '上传目录: %s \n上传失败: [ %s ] \n上传成功 [ %s ]' % ( tmp_dir, ', '.join(ret.get('failed').keys()), ', '.join(ret.get('ok').keys())) color_print(error) else: msg = '上传目录: %s \n传送成功 [ %s ]' % (tmp_dir, ', '.join( ret.get('ok').keys())) color_print(msg, 'green') print except IndexError: pass