Example #1
0
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', {})
Example #2
0
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}