批量上传下载

pull/26/head
ibuler 2015-12-02 13:35:06 +08:00
parent e95c47ff6a
commit 0e6fd89f0b
7 changed files with 132 additions and 28 deletions

View File

@ -16,16 +16,17 @@ import django
import paramiko
import struct, fcntl, signal, socket, select
from io import open as copen
import uuid
os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings'
if django.get_version() != '1.6':
django.setup()
from django.contrib.sessions.models import Session
from jumpserver.api import ServerError, User, Asset, PermRole, AssetGroup, get_object, mkdir, get_asset_info, get_role
from jumpserver.api import logger, Log, TtyLog, get_role_key, CRYPTOR
from jumpserver.api import logger, Log, TtyLog, get_role_key, CRYPTOR, bash, get_tmp_dir
from jperm.perm_api import gen_resource, get_group_asset_perm, get_group_user_perm, user_have_perm
from jumpserver.settings import LOG_DIR
from jperm.ansible_api import Command
from jperm.ansible_api import Command, MyRunner
from jlog.log_api import escapeString
login_user = get_object(User, username=getpass.getuser())
@ -484,6 +485,8 @@ class Nav(object):
4) 输入 \033[32mG/g\033[0m 显示您有权限的主机组.
5) 输入 \033[32mG/g\033[0m\033[0m + \033[32m组ID\033[0m 显示该组下主机.
6) 输入 \033[32mE/e\033[0m 批量执行命令.
7) 输入 \033[32mU/u\033[0m 批量上传文件.
7) 输入 \033[32mD/d\033[0m 批量下载文件.
7) 输入 \033[32mQ/q\033[0m 退出.
"""
print textwrap.dedent(msg)
@ -668,6 +671,91 @@ class Nav(object):
log.is_finished = True
log.end_time = datetime.datetime.now()
def upload(self):
while True:
if not self.user_perm:
self.user_perm = get_group_user_perm(self.user)
try:
print "请输入主机名、IP或ansile支持的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)
logger.debug("Muti upload file res: %s" % res)
asset_name_str = ''
for inv in runner.inventory.get_hosts(pattern=pattern):
print inv.name
asset_name_str += inv.name
print
tmp_dir = get_tmp_dir()
logger.debug('Upload tmp dir: %s' % tmp_dir)
os.chdir(tmp_dir)
bash('rz')
runner = MyRunner(res)
runner.run('copy', module_args='src=%s dest=%s directory_mode'
% (tmp_dir, tmp_dir), pattern=pattern)
ret = runner.get_result()
logger.debug(ret)
if ret.get('failed'):
print ret
error = '上传目录: %s \n上传失败: [ %s ] \n上传成功 [ %s ]' % (tmp_dir,
', '.join(ret.get('failed').keys()),
', '.join(ret.get('ok')))
color_print(error)
else:
msg = '上传目录: %s \n传送成功 [ %s ]' % (tmp_dir, ', '.join(ret.get('ok')))
color_print(msg, 'green')
print
except IndexError:
pass
def download(self):
while True:
if not self.user_perm:
self.user_perm = get_group_user_perm(self.user)
try:
print "进入批量下载模式"
print "请输入主机名、IP或ansile支持的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)
logger.debug("Muti Muti file res: %s" % res)
for inv in runner.inventory.get_hosts(pattern=pattern):
print inv.name
print
tmp_dir = get_tmp_dir()
logger.debug('Download tmp dir: %s' % tmp_dir)
while True:
print "请输入文件路径(不支持目录)"
file_path = raw_input("\033[1;32mPath>:\033[0m ").strip()
if file_path == 'q':
break
runner.run('fetch', module_args='src=%s dest=%s' % (file_path, tmp_dir), pattern=pattern)
ret = runner.get_result()
os.chdir('/tmp')
tmp_dir_name = os.path.basename(tmp_dir)
bash('tar czf %s.tar.gz %s && sz %s.tar.gz' % (tmp_dir, tmp_dir_name, tmp_dir))
if ret.get('failed'):
print ret
error = '文件名称: %s 下载失败: [ %s ] \n下载成功 [ %s ]' % \
('%s.tar.gz' % tmp_dir_name, ', '.join(ret.get('failed').keys()), ', '.join(ret.get('ok')))
color_print(error)
else:
msg = '文件名称: %s 下载成功 [ %s ]' % ('%s.tar.gz' % tmp_dir_name, ', '.join(ret.get('ok')))
color_print(msg, 'green')
print
except IndexError:
pass
def main():
"""
@ -701,6 +789,10 @@ def main():
elif option in ['E', 'e']:
nav.exec_cmd()
continue
elif option in ['U', 'u']:
nav.upload()
elif option in ['D', 'd']:
nav.download()
elif option in ['Q', 'q', 'exit']:
sys.exit()
else:

View File

@ -140,6 +140,22 @@ class MyRunner(MyInventory):
self.results = hoc.run()
return self.results
def get_result(self):
result = {'failed': {}, 'ok': []}
dark = self.results.get('dark')
contacted = self.results.get('contacted')
if dark:
for host, info in dark.items():
result['failed'][host] = info.get('msg')
if contacted:
for host, info in contacted.items():
if info.get('msg'):
result['failed'][host] = info.get('msg')
else:
result['ok'].append(host)
return result
class Command(MyInventory):
"""

View File

@ -9,6 +9,7 @@ import hashlib
import datetime
import random
import subprocess
import uuid
import json
import logging
@ -482,5 +483,10 @@ def my_render(template, data, request):
return render_to_response(template, data, context_instance=RequestContext(request))
def get_tmp_dir():
dir_name = os.path.join('/tmp', uuid.uuid4().hex)
mkdir(dir_name, mode=0777)
return dir_name
CRYPTOR = PyCrypt(KEY)
logger = set_log(LOG_LEVEL)

View File

@ -6,19 +6,13 @@ urlpatterns = patterns('',
(r'^$', 'jumpserver.views.index'),
(r'^api/user/$', 'jumpserver.api.api_user'),
(r'^skin_config/$', 'jumpserver.views.skin_config'),
(r'^install/$', 'jumpserver.views.install'),
(r'^base/$', 'jumpserver.views.base'),
(r'^login/$', 'jumpserver.views.Login'),
(r'^logout/$', 'jumpserver.views.Logout'),
(r'^file/upload/$', 'jumpserver.views.upload'),
(r'^file/download/$', 'jumpserver.views.download'),
(r'^setting', 'jumpserver.views.setting'),
(r'^error/$', 'jumpserver.views.httperror'),
(r'^juser/', include('juser.urls')),
(r'^jasset/', include('jasset.urls')),
(r'^jlog/', include('jlog.urls')),
(r'^jperm/', include('jperm.urls')),
(r'^node_auth/', 'jumpserver.views.node_auth'),
(r'download/(\d{4}/\d\d/\d\d/.*)', 'jumpserver.views.download_file'),
(r'test2', 'jumpserver.views.test2'),
)

View File

@ -294,7 +294,7 @@ def upload(request):
upload_files = request.FILES.getlist('file[]', None)
date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
upload_dir = "/tmp/%s/%s" % (user.username, date_now)
mkdir(upload_dir)
mkdir(upload_dir, mode=0777)
filenames = {}
for asset_id in asset_ids:
asset_select.append(get_object(Asset, id=asset_id))
@ -312,24 +312,22 @@ def upload(request):
res = gen_resource({'user': user, 'asset': asset_select})
runner = MyRunner(res)
ret = runner.run('copy', module_args='src=%s dest=%s directory_mode' % (upload_dir, '/tmp/hello/'), pattern='*')
runner.run('copy', module_args='src=%s dest=%s directory_mode'
% (upload_dir, upload_dir), pattern='*')
ret = runner.get_result()
logger.debug(ret)
error = '上传失败: '
if ret.get('dark'):
error += ','.join(ret.get('dark').keys())
for asset, info in ret.get('contacted').items():
if info.get('msg'):
error += ',%s' % asset
if error:
if ret.get('failed'):
error = '上传目录: %s <br> 上传失败: [ %s ] <br>上传成功 [ %s ]' % (upload_dir,
', '.join(ret.get('failed').keys()),
', '.join(ret.get('ok')))
return HttpResponse(error, status=500)
return HttpResponse('传送成功')
msg = '上传目录: %s <br> 传送成功 [ %s ]' % (upload_dir, ', '.join(ret.get('ok')))
return HttpResponse(msg)
return my_render('upload.html', locals(), request)
@login_required(login_url='/login')
def download(request):
documents = []
return render_to_response('download.html', locals(), context_instance=RequestContext(request))

View File

@ -16,12 +16,6 @@
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">Config option 1</a>
</li>
<li><a href="#">Config option 2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>

View File

@ -66,6 +66,8 @@
<div class="ibox-content">
<div>
<form id="my-awesome-dropzone" class="dropzone" action="">
<div class="alert alert-warning text-center" id="error" style="display: none"></div>
<div class="alert alert-success text-center" id="msg" style="display: none"></div>
<div class="dropzone-previews">
<div class="form-group">
<div class="col-sm-10">
@ -111,10 +113,12 @@
this.on("sendingmultiple", function() {
});
this.on("successmultiple", function(files, response) {
alert(response)
$('#msg').css('display', 'block');
$('#msg').html(response)
});
this.on("errormultiple", function(files, response) {
console.log(response)
$('#error').css('display', 'block');
$('#error').html(response)
});
}