Skip to content

Commit

Permalink
ver1.8.5 新增批量操作,比如批量删除,批量更新等;
Browse files Browse the repository at this point in the history
  • Loading branch information
leffss committed Nov 12, 2019
1 parent 2f7f2bf commit 7552b0a
Show file tree
Hide file tree
Showing 164 changed files with 8,185 additions and 234 deletions.
15 changes: 11 additions & 4 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,10 @@ python3 init.py

**启动 django 服务**
```bash
rm -rf logs/*
export PYTHONOPTIMIZE=1 # 解决 celery 不允许创建子进程的问题
nohup gunicorn -c gunicorn.cfg devops.wsgi:application > logs/gunicorn.log 2>&1 &
nohup daphne -b 0.0.0.0 -p 8001 devops.asgi:application > logs/daphne.log 2>&1 &
nohup daphne -b 0.0.0.0 -p 8001 --access-log=logs/daphne_access.log devops.asgi:application > logs/daphne.log 2>&1 &
nohup python3 manage.py sshd > logs/sshd.log 2>&1 &
nohup celery -A devops worker -l info -c 3 --max-tasks-per-child 40 --prefetch-multiplier 1 > logs/celery.log 2>&1 &
```
Expand Down Expand Up @@ -243,10 +244,13 @@ systemctl start nginx

# 升级日志

### ver1.8.5
新增批量操作,比如批量删除,批量更新等;

### ver1.8.4
基于 url 实现的粒度到按钮级别的权限控制
基于 url 实现的粒度到按钮级别的权限控制

左侧菜单栏根据权限自动生成
左侧菜单栏根据权限自动生成

### ver1.8.3
修正终端日志保存时用户名覆盖主机名的 BUG;
Expand Down
134 changes: 92 additions & 42 deletions apps/server/views_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,29 @@ def user_add(request):
@post_required
def user_delete(request):
pk = request.POST.get('id', None)
loguser = User.objects.get(username=request.session.get('username'))
if not pk:
try:
ids = [ int(x) for x in pk.split(',')]
except Exception:
error_message = '不合法的请求参数!'
return JsonResponse({"code": 400, "err": error_message})
remoteuser = get_object_or_404(RemoteUser, pk=pk)
if remoteuser.remoteuserbindhost_set.all().count() != 0:
error_message = '用户已绑定主机!'
return JsonResponse({"code": 401, "err": error_message})
remoteuser.delete()
event_log(loguser, 16, '主机用户 [{}] 删除成功'.format(remoteuser.name), request.META.get('REMOTE_ADDR', None), request.META.get('HTTP_USER_AGENT', None))
if not ids:
error_message = '不合法的请求参数!'
return JsonResponse({"code": 402, "err": error_message})
remoteusers = RemoteUser.objects.filter(pk__in=ids)
if not remoteusers:
error_message = '不合法的请求参数!'
return JsonResponse({"code": 403, "err": error_message})
remoteusernames = list()
for remoteuser in remoteusers:
if remoteuser.remoteuserbindhost_set.all().count() != 0:
continue
remoteuser.delete()
remoteusernames.append(remoteuser.name)
loguser = User.objects.get(username=request.session.get('username'))
event_log(
loguser, 16, '主机用户 [{}] 删除成功'.format(','.join(remoteusernames)),
request.META.get('REMOTE_ADDR', None), request.META.get('HTTP_USER_AGENT', None)
)
return JsonResponse({"code": 200, "err": ""})


Expand All @@ -123,20 +136,33 @@ def user_delete(request):
@post_required
def host_delete(request):
pk = request.POST.get('id', None)
loguser = User.objects.get(username=request.session.get('username'))
if not pk:
try:
ids = [ int(x) for x in pk.split(',')]
except Exception:
error_message = '不合法的请求参数!'
return JsonResponse({"code": 400, "err": error_message})
return JsonResponse({"code": 401, "err": error_message})
if not ids:
error_message = '不合法的请求参数!'
return JsonResponse({"code": 402, "err": error_message})
if request.session['issuperuser'] and request.session['username'] == 'admin':
host = get_object_or_404(RemoteUserBindHost, pk=pk)
hosts = RemoteUserBindHost.objects.filter(pk__in=ids)
else:
host = get_object_or_404(
RemoteUserBindHost,
hosts = RemoteUserBindHost.objects.filter(
Q(user__username=request.session['username']) | Q(group__user__username=request.session['username']),
pk=pk
pk__in=ids
)
host.delete()
event_log(loguser, 13, '主机 [{}] 删除成功'.format(host.hostname), request.META.get('REMOTE_ADDR', None), request.META.get('HTTP_USER_AGENT', None))
if not hosts:
error_message = '不合法的请求参数!'
return JsonResponse({"code": 403, "err": error_message})
hostnames = list()
for host in hosts:
host.delete()
hostnames.append(host.hostname)
loguser = User.objects.get(username=request.session.get('username'))
event_log(
loguser, 13, '主机 [{}] 删除成功'.format(','.join(hostnames)),
request.META.get('REMOTE_ADDR', None), request.META.get('HTTP_USER_AGENT', None)
)
return JsonResponse({"code": 200, "err": ""})


Expand Down Expand Up @@ -264,31 +290,41 @@ def host_add(request):
@post_required
def host_update_info(request):
hostid = request.POST.get('id', None)
if not hostid:

try:
ids = [ int(x) for x in hostid.split(',')]
except Exception:
error_message = '不合法的请求参数!'
return JsonResponse({"code": 401, "err": error_message})
if not ids:
error_message = '不合法的请求参数!'
return JsonResponse({"code": 400, "err": error_message})
return JsonResponse({"code": 402, "err": error_message})
if request.session['issuperuser'] and request.session['username'] == 'admin':
host = get_object_or_404(RemoteUserBindHost, pk=hostid)
hosts = RemoteUserBindHost.objects.filter(pk__in=ids, platform__in=[1, 3])
else:
host = get_object_or_404(
RemoteUserBindHost,
hosts = RemoteUserBindHost.objects.filter(
Q(user__username=request.session['username']) | Q(group__user__username=request.session['username']),
pk=hostid
pk__in=ids,
platform__in=[1, 3]
)
hostinfo = dict()
hostinfo['id'] = host.id
hostinfo['hostname'] = host.hostname
hostinfo['ip'] = host.ip
hostinfo['port'] = host.port
hostinfo['platform'] = host.get_platform_display()
hostinfo['username'] = host.remote_user.username
hostinfo['password'] = host.remote_user.password
if host.remote_user.enabled:
hostinfo['superusername'] = host.remote_user.superusername
hostinfo['superpassword'] = host.remote_user.superpassword
else:
hostinfo['superusername'] = None
task_host_update_info.delay(hostinfo=hostinfo)
if not hosts:
error_message = '不合法的请求参数!'
return JsonResponse({"code": 403, "err": error_message})
for host in hosts:
hostinfo = dict()
hostinfo['id'] = host.id
hostinfo['hostname'] = host.hostname
hostinfo['ip'] = host.ip
hostinfo['port'] = host.port
hostinfo['platform'] = host.get_platform_display()
hostinfo['username'] = host.remote_user.username
hostinfo['password'] = host.remote_user.password
if host.remote_user.enabled:
hostinfo['superusername'] = host.remote_user.superusername
hostinfo['superpassword'] = host.remote_user.superpassword
else:
hostinfo['superusername'] = None
task_host_update_info.delay(hostinfo=hostinfo)
return JsonResponse({"code": 200, "err": ""})


Expand All @@ -297,13 +333,27 @@ def host_update_info(request):
@post_required
def group_delete(request):
pk = request.POST.get('id', None)
try:
ids = [ int(x) for x in pk.split(',')]
except Exception:
error_message = '不合法的请求参数!'
return JsonResponse({"code": 401, "err": error_message})
if not ids:
error_message = '不合法的请求参数!'
return JsonResponse({"code": 402, "err": error_message})
user = User.objects.get(id=int(request.session.get('userid')))
if not pk:
groups = HostGroup.objects.filter(pk__in=ids, user=user)
if not groups:
error_message = '不合法的请求参数!'
return JsonResponse({"code": 400, "err": error_message})
group = get_object_or_404(HostGroup, pk=pk, user=user)
group.delete()
event_log(user, 22, '主机组 [{}] 删除成功'.format(group.group_name), request.META.get('REMOTE_ADDR', None), request.META.get('HTTP_USER_AGENT', None))
return JsonResponse({"code": 403, "err": error_message})
groupnames = list()
for group in groups:
group.delete()
groupnames.append(group.group_name)
event_log(
user, 22, '主机组 [{}] 删除成功'.format(','.join(groupnames)),
request.META.get('REMOTE_ADDR', None), request.META.get('HTTP_USER_AGENT', None)
)
return JsonResponse({"code": 200, "err": ""})


Expand Down
6 changes: 5 additions & 1 deletion apps/user/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ class Permission(models.Model):
# 当为 True 时,是一个按钮,不是菜单
is_button = models.BooleanField(default=False, verbose_name='是否为按钮')
# 排序,菜单显示排序
order = models.SmallIntegerField(default=99999, verbose_name='排序')
# SmallIntegerField 在使用 sqlite3 时字段为 smallint,范围从 -2^15 (-32,768) 到 2^15 - 1 (32,767) 的整型数据。
# 存储大小为 2 个字节。unsigned 是从 0 到 65535 的整型数据。但是使用 mysql 时就变为 tinyint,范围从 -2^7 (-128) 到
# 2^7 - 1 (123) 的整型数据。存储大小为 1 个字节。unsigned 是从 0 到 255 的整型数据。所以默认值设置大小要考虑到兼容性。
# order = models.SmallIntegerField(default=99999, verbose_name='排序')
order = models.SmallIntegerField(default=123, verbose_name='排序')

def __str__(self):
if self.menu:
Expand Down
33 changes: 32 additions & 1 deletion apps/user/templatetags/user_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
from django.conf import settings
from server.models import RemoteUserBindHost
from user.models import Permission
from collections import OrderedDict # 有序字典,python 默认字典无序
import json


register = template.Library()

Expand All @@ -22,7 +25,8 @@ def gen_menu(request):
:param request:
:return:
"""
menus = dict()
# menus = dict()
menus = OrderedDict()
current_url = request.path_info
for i in request.session[settings.INIT_MENU]:
if not i['menu']:
Expand Down Expand Up @@ -89,3 +93,30 @@ def get_all_permission(request):
Q(user__username=request.session['username']) | Q(group__user__username=request.session['username'])
).distinct()
return permissions


@register.filter()
def permission_to_ztree(permissions):
# 转换为前端 ztree 数据类型
permissions_ztree = OrderedDict()
for permission in permissions:
if not permission.menu:
permissions_ztree[permission.title] = {
'name': permission.title,
}
else:
if permission.menu in permissions_ztree:
permissions_ztree[permission.menu]['children'].append({
'name': permission.title,
})
else:
permissions_ztree[permission.menu] = {
'name': permission.menu,
'open': False,
'children': [
{'name': permission.title}
]
}
ztree_permissions = [ permissions_ztree[x] for x in permissions_ztree ]
ztree_permissions = json.dumps(ztree_permissions, ensure_ascii=True)
return ztree_permissions
Loading

0 comments on commit 7552b0a

Please sign in to comment.