def salt_file_download(request): def file_iterator(file_name, chunk_size=512): with open(file_name) as f: while True: c = f.read(chunk_size) if c: yield c else: break if request.method == 'POST': tgt_select = request.POST.get('tgt_select', None) remote_file = request.POST.get('remote_file', None) sapi = SaltAPI(url=settings.SALT_API['url'], username=settings.SALT_API['user'], password=settings.SALT_API['password']) ret_bak = sapi.file_bak(tgt_select, 'cp.push', remote_file, 'list') if tgt_select == 'localhost': return render(request, 'redirect.html', {}) remote_path = remote_file.replace(remote_file.split('/')[-1], '') dl_path = './media/salt/filedownload/user_%s/%s%s' % ( request.user.id, tgt_select, remote_path) dl_file = '%s%s' % (dl_path, remote_file.split('/')[-1]) if not os.path.exists(dl_path): os.makedirs(dl_path) try: shutil.copy( '/var/cache/salt/master/minions/%s/files/%s' % (tgt_select, remote_file), dl_file) tar_file = make_tar(dl_file, '/tmp') dl_filename = 'attachment;filename="{0}"'.format( tar_file.replace('/tmp/', '%s%s' % (tgt_select, remote_path))) ret = u'主机:%s\n结果:远程文件 %s 下载成功!' % (tgt_select, remote_file) Message.objects.create(type=u'文件管理', user=request.user, action=u'文件下载', action_ip=UserIP(request), content=u'下载文件 \n%s' % ret) response = StreamingHttpResponse(file_iterator(tar_file)) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = dl_filename return response except: print 'No such file or dirctory' ret = u'主机:%s\n结果:远程文件 %s 下载失败,请确认文件是否存在!' % (tgt_select, remote_file) Message.objects.create(type=u'文件管理', user=request.user, action=u'文件下载', action_ip=UserIP(request), content=u'下载文件 \n%s' % ret) return render(request, 'salt_file_download.html', {'ret': ret}) return render(request, 'salt_file_download.html', {})
def UploadFile(request, form, group=False): ''' 定义文件上传函数 ''' danger = [] check = False is_group = False rst = '' ret = '' jid = '' fileupload = FileUpload() if request.method == 'POST': form = SaltFileForm(request.POST, request.FILES, instance=fileupload) remote_path = request.POST.get('remote_path') for i in UserDirectory.objects.filter(name='ENGINEDEV_PATH'): danger = i.directory.split(',') if len(danger) == 0: danger = ['/etc', '/boot'] if remote_path not in danger or request.user.is_superuser: if form.is_valid and request.is_ajax(): cur_name = request.FILES['file_path'].name if request.POST.get('check_type') == 'panel-group': grp = request.POST.get('tgt_select') tgt_list = SaltGroup.objects.get(nickname=grp).groupname expr_form = 'nodegroup' is_group = True tgt_select = [tgt_list] else: tgt_select = request.POST.getlist('tgt_select') tgt_list = ','.join(tgt_select) expr_form = 'list' for tgt in tgt_select: fileupload = form.save(commit=False) fileupload.user = request.user fileupload.target = tgt fileupload.file_tag = '%s-%s-%s' % ( cur_name, request.user.id, datetime.datetime.now().strftime('%Y%m%d%H%M%S')) fileupload.save() # 替换路径为<salt://>形式,详细可查看salt上传文件命令 local_path = str(fileupload.file_path).replace( 'salt/fileupload', 'salt://fileupload') remote_path = '%s/%s' % (fileupload.remote_path, cur_name) sapi = SaltAPI(url=settings.SALT_API['url'], username=settings.SALT_API['user'], password=settings.SALT_API['password']) # 备份远程文件 ret_bak = sapi.file_bak(tgt_list, 'cp.push', remote_path, expr_form) # 上传文件到远程 ret = sapi.file_copy(tgt_list, 'cp.get_file', local_path, remote_path, expr_form) # 分组上传文件时,只需从其中一台salt主机备份文件,备份完成后设置group_forloop为false group_forloop = True for k in ret: if request.POST.get('check_type') == 'panel-group': bakup_path = './media/salt/filebakup/user_%s/%s' % ( request.user.id, tgt_list) else: bakup_path = './media/salt/filebakup/user_%s/%s' % ( request.user.id, k) if not os.path.exists( '%s%s' % (bakup_path, fileupload.remote_path)): os.makedirs('%s%s' % (bakup_path, fileupload.remote_path)) if ret[k]: rst = rst + u'主机:' + k + '\n上传结果:\n' + ret[k] + '\n' if ret_bak[k]: bak_file = '%s%s/%s' % (bakup_path, fileupload.remote_path, fileupload.file_tag) # 替换路径为<salt://>形式,以便文件回滚 bak_path = bak_file.replace( './media/salt', 'salt:/') if request.POST.get( 'check_type' ) == 'panel-group' and group_forloop: shutil.copy( '/var/cache/salt/master/minions/%s/files/%s' % (k, remote_path), bak_file) try: FileRollback.objects.get_or_create( user=request.user, target=tgt_list, cur_path=remote_path, bak_path=bak_path, file_tag=fileupload.file_tag, remark=fileupload.remark, is_group=True) except: print 'not create' group_forloop = False else: try: shutil.copy( '/var/cache/salt/master/minions/%s/files/%s' % (k, remote_path), bak_file) except: print 'No such file or dirctory' try: FileRollback.objects.get_or_create( user=request.user, target=k, cur_path=remote_path, bak_path=bak_path, file_tag=fileupload.file_tag, remark=fileupload.remark) except: print 'not create' rst = rst + u'远程文件%s备份成功...' % remote_path + '\n' + '-' * 80 + '\n' else: rst = rst + u'远程文件%s不存在,备份失败...' % remote_path + '\n' + '-' * 80 + '\n' else: rst = rst + u'主机:' + k + '\n上传结果:\n失败\n' + '-' * 80 + '\n' else: rst = u'无权限更改此目录' return {'ret': rst, 'check': check, 'is_group': is_group}