mirror of https://github.com/jumpserver/jumpserver
Merge branch 'dev' of https://git.coding.net/jumpserver/jumpserver into NormalUserPageLZ
commit
31807b674b
|
@ -37,6 +37,7 @@ nosetests.xml
|
|||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
*.log
|
||||
logs/*
|
||||
keys/*
|
||||
jumpserver.conf
|
||||
|
|
130
connect.py
130
connect.py
|
@ -19,8 +19,8 @@ import struct, fcntl, signal, socket, select
|
|||
os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings'
|
||||
if django.get_version() != '1.6':
|
||||
django.setup()
|
||||
from jumpserver.api import ServerError, User, Asset, AssetGroup, get_object
|
||||
from jumpserver.api import logger, mkdir, Log, TtyLog
|
||||
from jumpserver.api import ServerError, User, Asset, AssetGroup, get_object, mkdir
|
||||
from jumpserver.api import logger, Log, TtyLog
|
||||
from jumpserver.settings import LOG_DIR
|
||||
|
||||
|
||||
|
@ -68,9 +68,6 @@ def check_vim_status(command, ssh):
|
|||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Tty(object):
|
||||
"""
|
||||
A virtual tty class
|
||||
|
@ -252,6 +249,7 @@ class Tty(object):
|
|||
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=0777)
|
||||
mkdir(today_connect_log_dir, mode=0777)
|
||||
except OSError:
|
||||
logger.debug('创建目录 %s 失败,请修改%s目录权限' % (today_connect_log_dir, tty_log_dir))
|
||||
|
@ -289,7 +287,7 @@ class Tty(object):
|
|||
# 2. get 映射用户
|
||||
# 3. get 映射用户的账号,密码或者key
|
||||
# self.connect_info = {'user': '', 'asset': '', 'ip': '', 'port': 0, 'role_name': '', 'role_pass': '', 'role_key': ''}
|
||||
self.connect_info = {'user': 'a', 'asset': 'b', 'ip': '127.0.0.1', 'port': 22, 'role_name': 'root', 'role_pass': '', 'role_key': '/root/.ssh/id_rsa.bak'}
|
||||
self.connect_info = {'user': 'a', 'asset': 'b', 'ip': '127.0.0.1', 'port': 22, 'role_name': 'root', 'role_pass': 'redhat', 'role_key': ''}
|
||||
return self.connect_info
|
||||
|
||||
def get_connection(self):
|
||||
|
@ -452,7 +450,7 @@ class SshTty(Tty):
|
|||
#print 'ok'+tmp+'ok'
|
||||
# SSH_TTY = re.search(r'(?<=/dev/).*', tmp).group().strip()
|
||||
# SSH_TTY = ''
|
||||
channel.send('clear\n')
|
||||
# channel.send('clear\n')
|
||||
# Make ssh interactive tunnel
|
||||
self.posix_shell()
|
||||
|
||||
|
@ -468,20 +466,83 @@ class SshTty(Tty):
|
|||
pass
|
||||
|
||||
|
||||
def print_prompt():
|
||||
"""
|
||||
Print prompt
|
||||
打印提示导航
|
||||
"""
|
||||
msg = """\033[1;32m### Welcome Use JumpServer To Login. ### \033[0m
|
||||
1) Type \033[32mIP or Part IP, Host Alias or Comments \033[0m To Login.
|
||||
2) Type \033[32mP/p\033[0m To Print The Servers You Available.
|
||||
3) Type \033[32mG/g\033[0m To Print The Server Groups You Available.
|
||||
4) Type \033[32mG/g(1-N)\033[0m To Print The Server Group Hosts You Available.
|
||||
5) Type \033[32mE/e\033[0m To Execute Command On Several Servers.
|
||||
6) Type \033[32mQ/q\033[0m To Quit.
|
||||
"""
|
||||
print textwrap.dedent(msg)
|
||||
def print_user_asset_group_info(user):
|
||||
asset_groups = AssetGroup.objects.all()
|
||||
for asset_group in asset_groups:
|
||||
if asset_group.comment:
|
||||
print '[%-2s] %-10s %s' % (asset_group.id, asset_group.name, asset_group.comment)
|
||||
else:
|
||||
print '[%-2s] %-10s' % (asset_group.id, asset_group.name)
|
||||
print
|
||||
|
||||
|
||||
class Nav(object):
|
||||
def __init__(self, user):
|
||||
self.user = user
|
||||
self.search_result = {}
|
||||
|
||||
@staticmethod
|
||||
def print_nav():
|
||||
"""
|
||||
Print prompt
|
||||
打印提示导航
|
||||
"""
|
||||
msg = """\n\033[1;32m### Welcome To Use JumpServer, A Open Source System . ### \033[0m
|
||||
1) Type \033[32mID\033[0m To Login.
|
||||
2) Type \033[32m/\033[0m + \033[32mIP, Host Name, Host Alias or Comments \033[0mTo Search.
|
||||
3) Type \033[32mP/p\033[0m To Print The Servers You Available.
|
||||
4) Type \033[32mG/g\033[0m To Print The Server Groups You Available.
|
||||
5) Type \033[32mG/g\033[0m\033[0m + \033[32mGroup ID\033[0m To Print The Server Group You Available.
|
||||
6) Type \033[32mE/e\033[0m To Execute Command On Several Servers.
|
||||
7) Type \033[32mQ/q\033[0m To Quit.
|
||||
"""
|
||||
|
||||
msg = """\n\033[1;32m### 欢迎使用Jumpserver开源跳板机 ### \033[0m
|
||||
1) 输入 \033[32mID\033[0m 直接登录.
|
||||
2) 输入 \033[32m/\033[0m + \033[32mIP, 主机名, 主机别名 or 备注 \033[0m搜索.
|
||||
3) 输入 \033[32mP/p\033[0m 显示您有权限的主机.
|
||||
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[32mQ/q\033[0m 退出.
|
||||
"""
|
||||
print textwrap.dedent(msg)
|
||||
|
||||
def search(self, str_r=''):
|
||||
gid_pattern = re.compile(r'^g\d+$')
|
||||
user_asset_all = list(Asset.objects.all())
|
||||
user_asset_search = []
|
||||
if str_r:
|
||||
if gid_pattern.match(str_r):
|
||||
user_asset_search = list(Asset.objects.all())
|
||||
else:
|
||||
for asset in user_asset_all:
|
||||
if str_r in asset.ip or str_r in str(asset.comment):
|
||||
user_asset_search.append(asset)
|
||||
else:
|
||||
user_asset_search = user_asset_all
|
||||
|
||||
self.search_result = dict(zip(range(len(user_asset_search)), user_asset_search))
|
||||
|
||||
print '\033[32m[%-3s] %-15s %-15s %-5s %-5s %s \033[0m' % ('ID', 'AssetName', 'IP', 'Port', 'Role', 'Comment')
|
||||
for index, asset in self.search_result.items():
|
||||
if asset.comment:
|
||||
print '[%-3s] %-15s %-15s %-5s %-5s %s' % (index, 'asset_name'+str(index), asset.ip, asset.port, 'role', asset.comment)
|
||||
else:
|
||||
print '[%-3s] %-15s %-15s %-5s %-5s' % (index, 'asset_name'+str(index), asset.ip, asset.port, 'role')
|
||||
print
|
||||
|
||||
@staticmethod
|
||||
def print_asset_group():
|
||||
user_asset_group_all = AssetGroup.objects.all()
|
||||
|
||||
print '\033[32m[%-3s] %-15s %s \033[0m' % ('ID', 'GroupName', 'Comment')
|
||||
for asset_group in user_asset_group_all:
|
||||
if asset_group.comment:
|
||||
print '[%-3s] %-15s %s' % (asset_group.id, asset_group.name, asset_group.comment)
|
||||
else:
|
||||
print '[%-3s] %-15s' % (asset_group.id, asset_group.name)
|
||||
print
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -492,29 +553,26 @@ def main():
|
|||
if not login_user: # 判断用户是否存在
|
||||
color_print(u'没有该用户,或许你是以root运行的 No that user.', exits=True)
|
||||
|
||||
print_prompt()
|
||||
gid_pattern = re.compile(r'^g\d+$')
|
||||
nav = Nav(login_user)
|
||||
nav.print_nav()
|
||||
|
||||
try:
|
||||
while True:
|
||||
try:
|
||||
option = raw_input("\033[1;32mOpt or IP>:\033[0m ")
|
||||
option = raw_input("\033[1;32mOpt or ID>:\033[0m ").strip()
|
||||
except EOFError:
|
||||
print_prompt()
|
||||
nav.print_nav()
|
||||
continue
|
||||
except KeyboardInterrupt:
|
||||
sys.exit(0)
|
||||
if option in ['P', 'p']:
|
||||
login_user.get_asset_info(printable=True)
|
||||
if option in ['P', 'p', '\n', '']:
|
||||
nav.search()
|
||||
continue
|
||||
if option.startswith('/') or gid_pattern.match(option):
|
||||
nav.search(option.lstrip('/'))
|
||||
elif option in ['G', 'g']:
|
||||
login_user.get_asset_group_info(printable=True)
|
||||
continue
|
||||
elif gid_pattern.match(option):
|
||||
gid = option[1:].strip()
|
||||
asset_group = get_object(AssetGroup, id=gid)
|
||||
if asset_group and asset_group.is_permed(user=login_user):
|
||||
asset_group.get_asset_info(printable=True)
|
||||
nav.print_asset_group()
|
||||
continue
|
||||
elif option in ['E', 'e']:
|
||||
# exec_cmd_servers(login_name)
|
||||
|
@ -523,7 +581,11 @@ def main():
|
|||
sys.exit()
|
||||
else:
|
||||
try:
|
||||
verify_connect(login_user, option)
|
||||
asset = nav.search_result[int(option)]
|
||||
ssh_tty = SshTty('a', 'b')
|
||||
ssh_tty.connect()
|
||||
except (KeyError, ValueError):
|
||||
color_print('请输入正确ID', 'red')
|
||||
except ServerError, e:
|
||||
color_print(e, 'red')
|
||||
except IndexError:
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
sphinx-me==0.3
|
||||
django==1.6
|
||||
python-ldap==2.4.19
|
||||
pycrypto==2.6.1
|
||||
paramiko==1.15.2
|
||||
ecdsa==0.13
|
||||
|
@ -9,4 +8,9 @@ django-uuidfield==0.5.0
|
|||
psutil==2.2.1
|
||||
xlsxwriter==0.7.7
|
||||
xlrd==0.9.4
|
||||
django-bootstrap-form
|
||||
django-bootstrap-form
|
||||
tornado
|
||||
ansible
|
||||
pyinotify
|
||||
passlib
|
||||
argparse
|
|
@ -311,8 +311,12 @@ def write_excel(asset_all):
|
|||
group_all = '/'.join(group_list)
|
||||
status = asset.get_status_display()
|
||||
idc_name = asset.idc.name if asset.idc else u''
|
||||
system_type = asset.system_type if asset.idc else u''
|
||||
system_version = asset.system_version if asset.idc else u''
|
||||
system_os = unicode(system_type) + unicode(system_version)
|
||||
|
||||
alter_dic = [asset.hostname, asset.ip, idc_name, asset.mac, asset.remote_ip, asset.cpu, asset.memory,
|
||||
asset.disk, (asset.system_type + asset.system_version), asset.cabinet, group_all, status,
|
||||
asset.disk, system_os, asset.cabinet, group_all, status,
|
||||
asset.comment]
|
||||
data.append(alter_dic)
|
||||
format = workbook.add_format()
|
||||
|
@ -381,13 +385,13 @@ def excel_to_db(excel_file):
|
|||
row = table.row_values(row_num)
|
||||
if row:
|
||||
ip, port, hostname, use_default_auth, username, password, group = row
|
||||
print ip
|
||||
use_default_auth = 1 if use_default_auth == u'默认' else 0
|
||||
if get_object(Asset, ip=ip):
|
||||
continue
|
||||
if ip and port:
|
||||
asset = Asset(ip=ip,
|
||||
port=port,
|
||||
hostname=hostname,
|
||||
use_default_auth=use_default_auth,
|
||||
username=username,
|
||||
password=password
|
||||
|
|
|
@ -37,8 +37,8 @@ class AssetGroup(models.Model):
|
|||
class IDC(models.Model):
|
||||
name = models.CharField(max_length=32, verbose_name=u'机房名称')
|
||||
bandwidth = models.CharField(max_length=32, blank=True, null=True, verbose_name=u'机房带宽')
|
||||
linkman = models.CharField(max_length=16, null=True, verbose_name=u'联系人')
|
||||
phone = models.CharField(max_length=32, verbose_name=u'联系电话')
|
||||
linkman = models.CharField(max_length=16, blank=True, null=True, verbose_name=u'联系人')
|
||||
phone = models.CharField(max_length=32, blank=True, null=True, verbose_name=u'联系电话')
|
||||
address = models.CharField(max_length=128, blank=True, null=True, verbose_name=u"机房地址")
|
||||
network = models.TextField(blank=True, null=True, verbose_name=u"IP地址段")
|
||||
date_added = models.DateField(auto_now=True, null=True)
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
import ast
|
||||
from django.db.models import Q
|
||||
from django.shortcuts import get_object_or_404
|
||||
from jasset.asset_api import *
|
||||
from jumpserver.api import *
|
||||
from jumpserver.models import Setting
|
||||
from jasset.forms import AssetForm, IdcForm
|
||||
from jasset.models import Asset, IDC, AssetGroup, ASSET_TYPE, ASSET_STATUS
|
||||
from ansible_api import Tasks
|
||||
|
@ -13,7 +13,7 @@ from ansible_api import Tasks
|
|||
@require_role('admin')
|
||||
def group_add(request):
|
||||
"""
|
||||
Add asset group
|
||||
Group add view
|
||||
添加资产组
|
||||
"""
|
||||
header_title, path1, path2 = u'添加资产组', u'资产管理', u'添加资产组'
|
||||
|
@ -47,7 +47,7 @@ def group_add(request):
|
|||
@require_role('admin')
|
||||
def group_edit(request):
|
||||
"""
|
||||
Edit asset group
|
||||
Group edit view
|
||||
编辑资产组
|
||||
"""
|
||||
header_title, path1, path2 = u'编辑主机组', u'资产管理', u'编辑主机组'
|
||||
|
@ -89,7 +89,10 @@ def group_edit(request):
|
|||
|
||||
@require_role('admin')
|
||||
def group_detail(request):
|
||||
""" 主机组详情 """
|
||||
"""
|
||||
Group detail view
|
||||
主机组详情
|
||||
"""
|
||||
header_title, path1, path2 = u'主机组详情', u'资产管理', u'主机组详情'
|
||||
group_id = request.GET.get('id', '')
|
||||
group = get_object(AssetGroup, id=group_id)
|
||||
|
@ -121,7 +124,7 @@ def group_list(request):
|
|||
@require_role('admin')
|
||||
def group_del(request):
|
||||
"""
|
||||
del asset group
|
||||
Group delete view
|
||||
删除主机组
|
||||
"""
|
||||
group_ids = request.GET.get('id', '')
|
||||
|
@ -160,7 +163,7 @@ def asset_add(request):
|
|||
asset_save = af_post.save(commit=False)
|
||||
if not use_default_auth:
|
||||
password = request.POST.get('password', '')
|
||||
password_encode = CRYPTOR.encrypt(password)
|
||||
password_encode = password
|
||||
asset_save.password = password_encode
|
||||
asset_save.is_active = True if is_active else False
|
||||
asset_save.save()
|
||||
|
@ -293,7 +296,7 @@ def asset_list(request):
|
|||
s = write_excel(asset_find)
|
||||
if s[0]:
|
||||
file_name = s[1]
|
||||
smg = 'excel文件已生成,请点击下载!'
|
||||
smg = u'excel文件已生成,请点击下载!'
|
||||
return my_render('jasset/asset_excel_download.html', locals(), request)
|
||||
assets_list, p, assets, page_range, current_page, show_first, show_end = pages(asset_find, request)
|
||||
return my_render('jasset/asset_list.html', locals(), request)
|
||||
|
@ -330,13 +333,20 @@ def asset_update(request):
|
|||
return HttpResponseRedirect('/jasset/asset_detail/?id=%s' % asset_id)
|
||||
name = request.session.get('username', 'admin')
|
||||
if asset.use_default_auth:
|
||||
username = 'root'
|
||||
password = '123456'
|
||||
default = Setting.objects.all()
|
||||
if default:
|
||||
default = default[0]
|
||||
username = default.default_user
|
||||
password = default.default_password
|
||||
port = default.default_port
|
||||
else:
|
||||
return HttpResponse(u'没有设置默认用户名和密码!')
|
||||
else:
|
||||
username = asset.username
|
||||
password = asset.password
|
||||
port = asset.port
|
||||
|
||||
resource = [{"hostname": asset.ip, "port": asset.port,
|
||||
resource = [{"hostname": asset.ip, "port": port,
|
||||
"username": username, "password": password}]
|
||||
|
||||
ansible_instance = Tasks(resource)
|
||||
|
@ -446,16 +456,17 @@ def idc_del(request):
|
|||
"""
|
||||
IDC delete view
|
||||
"""
|
||||
uuid = request.GET.get('uuid', '')
|
||||
idc = get_object_or_404(IDC, uuid=uuid)
|
||||
idc.delete()
|
||||
uuid = request.GET.get('id', '')
|
||||
idc = get_object(IDC, id=uuid)
|
||||
if idc:
|
||||
idc.delete()
|
||||
return HttpResponseRedirect('/jasset/idc_list/')
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
def asset_upload(request):
|
||||
"""
|
||||
Upload file view
|
||||
Upload asset excel file view
|
||||
"""
|
||||
if request.method == 'POST':
|
||||
excel_file = request.FILES.get('file_name', '')
|
||||
|
|
|
@ -15,11 +15,11 @@ from utils import get_rand_pass
|
|||
|
||||
|
||||
import os.path
|
||||
|
||||
API_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
ANSIBLE_DIR = os.path.join(API_DIR, 'playbooks')
|
||||
|
||||
|
||||
|
||||
class AnsibleError(StandardError):
|
||||
"""
|
||||
the base AnsibleError which contains error(required),
|
||||
|
@ -61,7 +61,7 @@ class MyInventory(object):
|
|||
[{"hostname": "10.10.10.10", "port": "22", "username": "test", "password": "mypass"}, ...]
|
||||
"""
|
||||
self.resource = resource
|
||||
self.inventory = Inventory()
|
||||
self.inventory = Inventory(host_list=[])
|
||||
self.gen_inventory()
|
||||
|
||||
def add_group(self, hosts, groupname, groupvars=None):
|
||||
|
@ -101,7 +101,7 @@ class MyInventory(object):
|
|||
add hosts to inventory.
|
||||
"""
|
||||
if isinstance(self.resource, list):
|
||||
self.add_group(self.resource, 'my_group')
|
||||
self.add_group(self.resource, 'default_group')
|
||||
elif isinstance(self.resource, dict):
|
||||
for groupname, hosts_and_vars in self.resource.iteritems():
|
||||
self.add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))
|
||||
|
@ -115,21 +115,23 @@ class Command(MyInventory):
|
|||
super(Command, self).__init__(*args, **kwargs)
|
||||
self.results = ''
|
||||
|
||||
def run(self, command, module_name="command", timeout=5, forks=10, group='my_group'):
|
||||
def run(self, command, module_name="command", timeout=10, forks=10, group='default_group', pattern='*'):
|
||||
"""
|
||||
run command from andible ad-hoc.
|
||||
command : 必须是一个需要执行的命令字符串, 比如
|
||||
'uname -a'
|
||||
"""
|
||||
|
||||
if module_name not in ["raw", "command", "shell"]:
|
||||
raise CommandValueError("module_name",
|
||||
raise CommandValueError("module_name",
|
||||
"module_name must be of the 'raw, command, shell'")
|
||||
hoc = Runner(module_name=module_name,
|
||||
module_args=command,
|
||||
timeout=timeout,
|
||||
inventory=self.inventory,
|
||||
subset=group,
|
||||
forks=forks
|
||||
pattern=pattern,
|
||||
forks=forks,
|
||||
)
|
||||
self.results = hoc.run()
|
||||
|
||||
|
@ -203,7 +205,7 @@ class Tasks(Command):
|
|||
def __init__(self, *args, **kwargs):
|
||||
super(Tasks, self).__init__(*args, **kwargs)
|
||||
|
||||
def __run(self, module_args, module_name="command", timeout=5, forks=10, group='my_group'):
|
||||
def __run(self, module_args, module_name="command", timeout=5, forks=10, group='default_group', pattern='*'):
|
||||
"""
|
||||
run command from andible ad-hoc.
|
||||
command : 必须是一个需要执行的命令字符串, 比如
|
||||
|
@ -214,7 +216,8 @@ class Tasks(Command):
|
|||
timeout=timeout,
|
||||
inventory=self.inventory,
|
||||
subset=group,
|
||||
forks=forks
|
||||
pattern=pattern,
|
||||
forks=forks,
|
||||
)
|
||||
|
||||
self.results = hoc.run()
|
||||
|
@ -425,7 +428,6 @@ class MyPlaybook(MyInventory):
|
|||
def __init__(self, *args, **kwargs):
|
||||
super(MyPlaybook, self).__init__(*args, **kwargs)
|
||||
|
||||
|
||||
def run(self, playbook_relational_path, extra_vars=None):
|
||||
"""
|
||||
run ansible playbook,
|
||||
|
@ -464,7 +466,6 @@ class App(MyPlaybook):
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
|
||||
# resource = {
|
||||
# "group1": {
|
||||
|
@ -472,8 +473,10 @@ if __name__ == "__main__":
|
|||
# "vars" : {"var1": "value1", "var2": "value2"},
|
||||
# },
|
||||
# }
|
||||
# command = Command(resource)
|
||||
# print command.run("who", group="group1")
|
||||
|
||||
resource = [{"hostname": "127.0.0.1", "port": "22", "username": "yumaojun", "password": "yusky0902"}]
|
||||
command = Command(resource)
|
||||
print command.run("who")
|
||||
|
||||
# resource = [{"hostname": "192.168.10.148", "port": "22", "username": "root", "password": "xxx"}]
|
||||
# task = Tasks(resource)
|
||||
|
|
|
@ -32,14 +32,13 @@ class PermRole(models.Model):
|
|||
|
||||
class PermRule(models.Model):
|
||||
date_added = models.DateTimeField(auto_now=True)
|
||||
name = models.CharField(max_length=100)
|
||||
name = models.CharField(max_length=100, unique=True)
|
||||
comment = models.CharField(max_length=100)
|
||||
asset = models.ManyToManyField(Asset, related_name='perm_rule')
|
||||
asset_group = models.ManyToManyField(AssetGroup, related_name='perm_rule')
|
||||
user = models.ManyToManyField(User, related_name='perm_rule')
|
||||
user_group = models.ManyToManyField(UserGroup, related_name='perm_rule')
|
||||
role = models.ManyToManyField(PermRole, related_name='perm_rule')
|
||||
ssh_type = models.BooleanField()
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
|
@ -89,7 +89,7 @@ def perm_user_api(perm_info):
|
|||
the_new_users = ','.join(new_username)
|
||||
the_del_users = ','.join(del_username)
|
||||
|
||||
playbook = get_playbook(os.path.join(BASE_DIR, 'playbook', 'user_perm.yaml'),
|
||||
playbook = get_playbook(os.path.join(BASE_DIR, 'keys/../playbook', 'user_perm.yaml'),
|
||||
{'the_new_group': 'new', 'the_del_group': 'del',
|
||||
'the_new_users': the_new_users, 'the_del_users': the_del_users,
|
||||
'KEY_DIR': os.path.join(SSH_KEY_DIR, 'sysuser')})
|
||||
|
|
|
@ -4,7 +4,7 @@ import random
|
|||
import os.path
|
||||
|
||||
from paramiko.rsakey import RSAKey
|
||||
from os import chmod, mkdir
|
||||
from jumpserver.api import mkdir
|
||||
from uuid import uuid4
|
||||
|
||||
from jumpserver.settings import KEY_DIR
|
||||
|
@ -45,9 +45,8 @@ def gen_keys():
|
|||
:return: 返回目录名(uuid)
|
||||
"""
|
||||
key_basename = "key-" + uuid4().hex
|
||||
key_path_dir = os.path.join(KEY_DIR, key_basename)
|
||||
mkdir(key_path_dir, 0700)
|
||||
|
||||
key_path_dir = os.path.join(KEY_DIR, 'role_key', key_basename)
|
||||
mkdir(key_path_dir, 0755)
|
||||
key = RSAKey.generate(2048)
|
||||
private_key = os.path.join(key_path_dir, 'id_rsa')
|
||||
public_key = os.path.join(key_path_dir, 'id_rsa.pub')
|
||||
|
@ -62,8 +61,6 @@ def gen_keys():
|
|||
return key_path_dir
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print gen_keys()
|
||||
|
||||
|
|
177
jperm/views.py
177
jperm/views.py
|
@ -1,6 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
from django.db.models import Q
|
||||
from jperm.perm_api import *
|
||||
from jperm.models import PermLog as Log
|
||||
|
@ -11,12 +10,13 @@ from juser.user_api import gen_ssh_key
|
|||
from juser.models import User, UserGroup
|
||||
from jasset.models import Asset, AssetGroup
|
||||
from jperm.models import PermRole, PermRule
|
||||
from jumpserver.models import Setting
|
||||
|
||||
from jperm.utils import updates_dict, gen_keys, get_rand_pass
|
||||
from jperm.ansible_api import Tasks
|
||||
from jperm.perm_api import get_role_info
|
||||
|
||||
from jumpserver.api import my_render, get_object
|
||||
from jumpserver.api import my_render, get_object, CRYPTOR
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
|
@ -62,7 +62,7 @@ def perm_rule_detail(request):
|
|||
assets = asset_obj
|
||||
|
||||
return my_render('jperm/perm_rule_detail.html', locals(), request)
|
||||
|
||||
|
||||
|
||||
def perm_rule_add(request):
|
||||
"""
|
||||
|
@ -89,7 +89,8 @@ def perm_rule_add(request):
|
|||
asset_groups_select = request.POST.getlist('assetgroup', [])
|
||||
roles_select = request.POST.getlist('role', [])
|
||||
rule_name = request.POST.get('rulename')
|
||||
rule_comment = request.POST.get('comment')
|
||||
rule_comment = request.POST.get('rule_comment')
|
||||
rule_ssh_key = request.POST.get("use_publicKey")
|
||||
|
||||
# 获取需要授权的主机列表
|
||||
assets_obj = [Asset.objects.get(ip=asset) for asset in assets_select]
|
||||
|
@ -115,7 +116,19 @@ def perm_rule_add(request):
|
|||
rule.asset_group = asset_groups_obj
|
||||
rule.role = roles_obj
|
||||
rule.save()
|
||||
return HttpResponse(u"添加授权规则:%s" % rule.name)
|
||||
|
||||
msg = u"添加授权规则:%s" % rule.name
|
||||
# 渲染数据
|
||||
header_title, path1, path2 = "授权规则", "规则管理", "查看规则"
|
||||
rules_list = PermRule.objects.all()
|
||||
|
||||
# TODO: 搜索和分页
|
||||
keyword = request.GET.get('search', '')
|
||||
if keyword:
|
||||
rules_list = rules_list.filter(Q(name=keyword))
|
||||
rules_list, p, rules, page_range, current_page, show_first, show_end = pages(rules_list, request)
|
||||
|
||||
return my_render('jperm/perm_rule_list.html', locals(), request)
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
|
@ -131,17 +144,69 @@ def perm_rule_edit(request):
|
|||
rule = PermRule.objects.get(id=rule_id)
|
||||
|
||||
if request.method == 'GET' and rule_id:
|
||||
# 渲染数据, 获取所有的rule对象
|
||||
users = rule.user.all()
|
||||
user_groups = rule.user_group.all()
|
||||
assets = rule.asset.all()
|
||||
asset_groups = rule.asset_group.all()
|
||||
roles = rule.role.all()
|
||||
# 渲染数据, 获取所选的rule对象
|
||||
rule_comment = rule.comment
|
||||
users_select = rule.user.all()
|
||||
user_groups_select = rule.user_group.all()
|
||||
assets_select = rule.asset.all()
|
||||
asset_groups_select = rule.asset_group.all()
|
||||
roles_select = rule.role.all()
|
||||
|
||||
users = User.objects.all()
|
||||
user_groups = UserGroup.objects.all()
|
||||
assets = Asset.objects.all()
|
||||
asset_groups = AssetGroup.objects.all()
|
||||
roles = PermRole.objects.all()
|
||||
|
||||
return my_render('jperm/perm_rule_edit.html', locals(), request)
|
||||
|
||||
elif request.method == 'POST' and rule_id:
|
||||
return HttpResponse("uncompleted")
|
||||
# 获取用户选择的 用户,用户组,资产,资产组,用户角色
|
||||
rule_name = request.POST.get('rule_name')
|
||||
rule_comment = request.POST.get("rule_comment")
|
||||
users_select = request.POST.getlist('user', [])
|
||||
user_groups_select = request.POST.getlist('usergroup', [])
|
||||
assets_select = request.POST.getlist('asset', [])
|
||||
asset_groups_select = request.POST.getlist('assetgroup', [])
|
||||
roles_select = request.POST.getlist('role', [])
|
||||
|
||||
# 获取需要授权的主机列表
|
||||
assets_obj = [Asset.objects.get(ip=asset) for asset in assets_select]
|
||||
asset_groups_obj = [AssetGroup.objects.get(name=group) for group in asset_groups_select]
|
||||
group_assets_obj = [asset for asset in [group.asset_set.all() for group in asset_groups_obj]]
|
||||
calc_assets = set(group_assets_obj) | set(assets_obj)
|
||||
|
||||
# 获取需要授权的用户列表
|
||||
users_obj = [User.objects.get(name=user) for user in users_select]
|
||||
user_groups_obj = [UserGroup.objects.get(name=group) for group in user_groups_select]
|
||||
group_users_obj = [user for user in [group.user_set.all() for group in user_groups_obj]]
|
||||
calc_users = set(group_users_obj) | set(users_obj)
|
||||
|
||||
# 获取授予的角色列表
|
||||
roles_obj = [PermRole.objects.get(name=role) for role in roles_select]
|
||||
|
||||
# 仅授权成功的,写回数据库(授权规则,用户,用户组,资产,资产组,用户角色)
|
||||
rule.user = users_obj
|
||||
rule.usergroup = user_groups_obj
|
||||
rule.asset = assets_obj
|
||||
rule.asset_group = asset_groups_obj
|
||||
rule.role = roles_obj
|
||||
rule.name = rule_name
|
||||
rule.comment = rule.comment
|
||||
rule.save()
|
||||
|
||||
msg = u"更新授权规则:%s" % rule.name
|
||||
# 渲染数据
|
||||
header_title, path1, path2 = "授权规则", "规则管理", "查看规则"
|
||||
rules_list = PermRule.objects.all()
|
||||
|
||||
# TODO: 搜索和分页
|
||||
keyword = request.GET.get('search', '')
|
||||
if keyword:
|
||||
rules_list = rules_list.filter(Q(name=keyword))
|
||||
rules_list, p, rules, page_range, current_page, show_first, show_end = pages(rules_list, request)
|
||||
|
||||
return my_render('jperm/perm_rule_list.html', locals(), request)
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
|
@ -201,12 +266,24 @@ def perm_role_add(request):
|
|||
name = request.POST.get("role_name")
|
||||
comment = request.POST.get("role_comment")
|
||||
password = request.POST.get("role_password")
|
||||
encrypt_pass = CRYPTOR.encrypt(password)
|
||||
# 生成随机密码,生成秘钥对
|
||||
|
||||
key_path = gen_keys()
|
||||
role = PermRole(name=name, comment=comment, password=password, key_path=key_path)
|
||||
role = PermRole(name=name, comment=comment, password=encrypt_pass, key_path=key_path)
|
||||
role.save()
|
||||
return HttpResponse(u"添加角色: %s" % name)
|
||||
|
||||
msg = u"添加角色: %s" % name
|
||||
# 渲染 刷新数据
|
||||
header_title, path1, path2 = "系统角色", "角色管理", "查看角色"
|
||||
roles_list = PermRole.objects.all()
|
||||
# TODO: 搜索和分页
|
||||
keyword = request.GET.get('search', '')
|
||||
if keyword:
|
||||
roles_list = roles_list.filter(Q(name=keyword))
|
||||
|
||||
roles_list, p, roles, page_range, current_page, show_first, show_end = pages(roles_list, request)
|
||||
return my_render('jperm/perm_role_list.html', locals(), request)
|
||||
else:
|
||||
return HttpResponse(u"不支持该操作")
|
||||
|
||||
|
@ -252,8 +329,12 @@ def perm_role_detail(request):
|
|||
role_info = get_role_info(role_id)
|
||||
|
||||
# 渲染数据
|
||||
for key, value in role_info.iteritems():
|
||||
key = value
|
||||
rules = role_info.get("rules")
|
||||
assets = role_info.get("assets")
|
||||
asset_groups = role_info.get("asset_groups")
|
||||
users = role_info.get("users")
|
||||
user_groups = role_info.get("user_groups")
|
||||
|
||||
return my_render('jperm/perm_role_detail.html', locals(), request)
|
||||
|
||||
|
||||
|
@ -265,15 +346,40 @@ def perm_role_edit(request):
|
|||
# 渲染数据
|
||||
header_title, path1, path2 = "系统角色", "角色管理", "角色编辑"
|
||||
|
||||
# 渲染数据
|
||||
role_id = request.GET.get("id")
|
||||
role = PermRole.objects.get(id=role_id)
|
||||
role_pass = CRYPTOR.decrypt(role.password)
|
||||
if request.method == "GET":
|
||||
role_id = request.GET.get("id")
|
||||
# 渲染数据
|
||||
role = PermRole.objects.get(id=role_id)
|
||||
|
||||
return my_render('jperm/perm_role_edit.html', locals(), request)
|
||||
|
||||
if request.method == "POST":
|
||||
return HttpResponse(u"未实现")
|
||||
# 获取 POST 数据
|
||||
role_name = request.POST.get("role_name")
|
||||
role_password = request.POST.get("role_password")
|
||||
encrypt_role_pass = CRYPTOR.encrypt(role_password)
|
||||
role_comment = request.POST.get("role_comment")
|
||||
|
||||
# 写入数据库
|
||||
role.name = role_name
|
||||
role.password = encrypt_role_pass
|
||||
role.comment = role_comment
|
||||
|
||||
role.save()
|
||||
msg = u"更新系统角色: %s" % role.name
|
||||
|
||||
# 渲染 刷新数据
|
||||
header_title, path1, path2 = "系统角色", "角色管理", "查看角色"
|
||||
roles_list = PermRole.objects.all()
|
||||
# TODO: 搜索和分页
|
||||
keyword = request.GET.get('search', '')
|
||||
if keyword:
|
||||
roles_list = roles_list.filter(Q(name=keyword))
|
||||
|
||||
roles_list, p, roles, page_range, current_page, show_first, show_end = pages(roles_list, request)
|
||||
return my_render('jperm/perm_role_list.html', locals(), request)
|
||||
|
||||
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
|
@ -307,10 +413,20 @@ def perm_role_push(request):
|
|||
calc_assets = set(assets_obj) | set(group_assets_obj)
|
||||
|
||||
# 生成Inventory
|
||||
push_resource = [{"hostname": asset.ip,
|
||||
"port": asset.port,
|
||||
"username": asset.username,
|
||||
"password": asset.password} for asset in calc_assets]
|
||||
push_resource = []
|
||||
for asset in calc_assets:
|
||||
if asset.use_default_auth:
|
||||
username = Setting.default_user
|
||||
password = Setting.default_password
|
||||
port = Setting.default_port
|
||||
else:
|
||||
username = asset.username
|
||||
password = asset.password
|
||||
port = asset.port
|
||||
push_resource.append({"hostname": asset.ip,
|
||||
"port": port,
|
||||
"username": username,
|
||||
"password": password})
|
||||
|
||||
# 获取角色的推送方式,以及推送需要的信息
|
||||
roles_obj = [PermRole.objects.get(name=role_name) for role_name in role_names]
|
||||
|
@ -326,10 +442,13 @@ def perm_role_push(request):
|
|||
task = Tasks(push_resource)
|
||||
ret = {}
|
||||
ret_failed = []
|
||||
if password_push:
|
||||
ret["password_push"] = task.add_multi_user(**role_pass)
|
||||
if ret["password_push"].get("status") != "success":
|
||||
ret_failed.append(1)
|
||||
|
||||
# 因为要先建立用户,所以password 是必选项,
|
||||
# 而push key是在 password也完成的情况下的 可选项
|
||||
ret["password_push"] = task.add_multi_user(**role_pass)
|
||||
if ret["password_push"].get("status") != "success":
|
||||
ret_failed.append(1)
|
||||
|
||||
if key_push:
|
||||
ret["key_push"] = task.push_multi_key(**role_key)
|
||||
if ret["key_push"].get("status") != "success":
|
||||
|
|
|
@ -14,10 +14,8 @@ from django.core.paginator import Paginator, EmptyPage, InvalidPage
|
|||
from django.http import HttpResponse, Http404
|
||||
from django.template import RequestContext
|
||||
from juser.models import User, UserGroup
|
||||
from jlog.models import Log
|
||||
from jasset.models import Asset, AssetGroup
|
||||
# from jlog.models import Log
|
||||
from jlog.models import Log, TtyLog
|
||||
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render_to_response
|
||||
from django.core.mail import send_mail
|
||||
|
@ -197,9 +195,9 @@ def require_role(role='user'):
|
|||
|
||||
def _deco(func):
|
||||
def __deco(request, *args, **kwargs):
|
||||
request.session['pre_url'] = request.path
|
||||
if not request.user.is_authenticated():
|
||||
return HttpResponseRedirect('/login/')
|
||||
|
||||
if role == 'admin':
|
||||
# if request.session.get('role_id', 0) < 1:
|
||||
if request.user.role == 'CU':
|
||||
|
@ -395,8 +393,9 @@ def mkdir(dir_name, username='root', mode=0755):
|
|||
"""
|
||||
if not os.path.isdir(dir_name):
|
||||
os.makedirs(dir_name)
|
||||
bash("chown %s:%s '%s'" % (username, username, dir_name))
|
||||
os.chmod(dir_name, mode)
|
||||
if username:
|
||||
bash('chown %s:%s %s' % (username, username, dir_name))
|
||||
|
||||
|
||||
def http_success(request, msg):
|
||||
|
@ -414,4 +413,3 @@ def my_render(template, data, request):
|
|||
|
||||
CRYPTOR = PyCrypt(KEY)
|
||||
logger = set_log(LOG_LEVEL)
|
||||
KEY_DIR = os.path.join(BASE_DIR, 'keys')
|
||||
|
|
|
@ -17,8 +17,8 @@ config = ConfigParser.ConfigParser()
|
|||
|
||||
BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
||||
config.read(os.path.join(BASE_DIR, 'jumpserver.conf'))
|
||||
KEY_DIR = os.path.join(BASE_DIR, 'keys')
|
||||
|
||||
KEY_DIR = os.path.join(BASE_DIR, 'role_keys')
|
||||
|
||||
DB_HOST = config.get('db', 'host')
|
||||
DB_PORT = config.getint('db', 'port')
|
||||
|
@ -37,7 +37,7 @@ EMAIL_TIMEOUT = 5
|
|||
|
||||
# ======== Log ==========
|
||||
LOG_DIR = os.path.join(BASE_DIR, 'logs')
|
||||
SSH_KEY_DIR = os.path.join(BASE_DIR, 'role_keys')
|
||||
SSH_KEY_DIR = os.path.join(BASE_DIR, 'keys/role_keys')
|
||||
KEY = config.get('base', 'key')
|
||||
URL = config.get('base', 'url')
|
||||
LOG_LEVEL = config.get('base', 'log')
|
||||
|
|
|
@ -226,3 +226,14 @@ def ip_str_to_list(ip_str):
|
|||
ip str to list
|
||||
"""
|
||||
return ip_str.split(',')
|
||||
|
||||
|
||||
@register.filter(name='key_exist')
|
||||
def key_exist(username):
|
||||
"""
|
||||
ssh key is exist or not
|
||||
"""
|
||||
if os.path.isfile(os.path.join(KEY_DIR, 'user', username)):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
|
|
@ -15,7 +15,6 @@ from jumpserver.api import *
|
|||
from jumpserver.models import Setting
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from settings import BASE_DIR
|
||||
from jlog.models import Log
|
||||
|
||||
|
||||
|
@ -236,7 +235,7 @@ def Login(request):
|
|||
request.session['role_id'] = 1
|
||||
else:
|
||||
request.session['role_id'] = 0
|
||||
return HttpResponseRedirect(request.GET.get('next', '/'), )
|
||||
return HttpResponseRedirect(request.session.get('pre_url', '/'))
|
||||
# response.set_cookie('username', username, expires=604800)
|
||||
# response.set_cookie('seed', PyCrypt.md5_crypt(password), expires=604800)
|
||||
# return response
|
||||
|
@ -269,7 +268,7 @@ def setting(request):
|
|||
if '' in [username, port] and ('' in password or '' in private_key):
|
||||
return HttpResponse('所填内容不能为空, 且密码和私钥填一个')
|
||||
else:
|
||||
private_key_path = os.path.join(BASE_DIR, 'role_keys', 'default', 'default_private_key.pem')
|
||||
private_key_path = os.path.join(BASE_DIR, 'keys/role_keys', 'default', 'default_private_key.pem')
|
||||
if private_key:
|
||||
with open(private_key_path, 'w') as f:
|
||||
f.write(private_key)
|
||||
|
|
|
@ -123,21 +123,21 @@ def db_del_user(username):
|
|||
|
||||
def gen_ssh_key(username, password='',
|
||||
key_dir=os.path.join(KEY_DIR, 'user'),
|
||||
|
||||
authorized_keys=True, home="/home", length=2048):
|
||||
"""
|
||||
generate a user ssh key in a property dir
|
||||
生成一个用户ssh密钥对
|
||||
"""
|
||||
logger.debug('生成ssh key, 并设置authorized_keys')
|
||||
private_key_file = os.path.join(key_dir, username)
|
||||
mkdir(private_key_file, username)
|
||||
mkdir(key_dir)
|
||||
if os.path.isfile(private_key_file):
|
||||
os.unlink(private_key_file)
|
||||
ret = bash('echo -e "y\n"|ssh-keygen -t rsa -f %s -b %s -P "%s"' % (private_key_file, length, password))
|
||||
|
||||
if authorized_keys:
|
||||
auth_key_dir = os.path.join(home, username, '.ssh')
|
||||
mkdir(auth_key_dir, username, mode=0700)
|
||||
mkdir(auth_key_dir, mode=0700)
|
||||
authorized_key_file = os.path.join(auth_key_dir, 'authorized_keys')
|
||||
with open(private_key_file+'.pub') as pub_f:
|
||||
with open(authorized_key_file, 'w') as auth_f:
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
看山是山,看水是水
|
||||
看山不是山,看水不是水
|
||||
看山是山,看水是水
|
|
@ -0,0 +1 @@
|
|||
永远年轻,永远热泪盈眶
|
|
@ -1,17 +0,0 @@
|
|||
- hosts: the_del_group
|
||||
tasks:
|
||||
- name: del user
|
||||
user: name={{ item }} state=absent remove=yes
|
||||
with_items: [ the_del_users ]
|
||||
|
||||
- hosts: the_new_group
|
||||
tasks:
|
||||
- name: add user
|
||||
user: name={{ item }} state=present
|
||||
with_items: [ the_new_users ]
|
||||
- name: .ssh direcotory
|
||||
file: name=/home/{{ item }}/.ssh mode=700 owner={{ item }} group={{ item }} state=directory
|
||||
with_items: [ the_new_users ]
|
||||
- name: set authorizied_file
|
||||
copy: src=KEY_DIR/{{ item }}.pub dest=/home/{{ item }}/.ssh/authorizied_keys owner={{ item }} group={{ item }} mode=600
|
||||
with_items: [ the_new_users ]
|
|
@ -14,7 +14,6 @@
|
|||
</div>
|
||||
<div class="ibox-content">
|
||||
<h1 class="no-margins"><a href="/juser/user_list/">{{ users.count}}</a></h1>
|
||||
{# <div class="stat-percent font-bold text-success">{{ percent_user }} <i class="fa fa-bolt"></i></div>#}
|
||||
<small>All user</small>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -27,7 +26,6 @@
|
|||
</div>
|
||||
<div class="ibox-content">
|
||||
<h1 class="no-margins"><a href="/jasset/host_list/">{{ hosts.count }}</a></h1>
|
||||
{# <div class="stat-percent font-bold text-info">{{ percent_host }} <i class="fa fa-level-up"></i></div>#}
|
||||
<small>All host</small>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -37,7 +35,7 @@
|
|||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span class="label label-primary pull-right">Online</span>
|
||||
<h5>实时在线用户</h5>
|
||||
<h5>在线用户</h5>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_users">{{ online_user | length }}</span></a></h1>
|
||||
|
@ -55,7 +53,6 @@
|
|||
</div>
|
||||
<div class="ibox-content">
|
||||
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_hosts">{{ online_host | length }}</span></a></h1>
|
||||
{# <div class="stat-percent font-bold text-danger">{{ percent_online_host }} <i class="fa fa-level-down"></i></div>#}
|
||||
<small>Connected host</small>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -169,7 +166,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="ibox-content ibox-heading">
|
||||
<h3><i class="fa fa-user"></i> 一周Top10资产 </h3>
|
||||
<h3><i class="fa fa-inbox"></i> 一周Top10资产 </h3>
|
||||
<small><i class="fa fa-map-marker"></i> 登录次数及最近一次登录记录. </small>
|
||||
</div>
|
||||
<div class="ibox-content inspinia-timeline">
|
||||
|
@ -309,14 +306,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--</div>-->
|
||||
<!--<div class="col-xm-6" id="top10" style="width:50%;height:400px;"></div>-->
|
||||
<!--<div class="col-xm-6" id="usertop10" style="width:50%;height:400px;"></div>-->
|
||||
<!--<div class="row">-->
|
||||
<!--<div class="col-lg-6" id="hosttop10" style="width:50%;height:400px; margin-top: 20px"></div>-->
|
||||
<!--</div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -31,11 +31,11 @@
|
|||
<table class="table">
|
||||
<tr>
|
||||
<td class="text-navy">IP</td>
|
||||
<td>{{ asset.ip }}</td>
|
||||
<td>{{ asset.ip|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">主机名</td>
|
||||
<td>{{ asset.hostname }}</td>
|
||||
<td>{{ asset.hostname|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">其他IP</td>
|
||||
|
@ -53,11 +53,11 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">远控IP</td>
|
||||
<td>{{ asset.remote_ip }}</td>
|
||||
<td>{{ asset.remote_ip|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">端口</td>
|
||||
<td>{{ asset.port }}</td>
|
||||
<td>{{ asset.port|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -66,7 +66,7 @@
|
|||
<table class="table">
|
||||
{% for asset_group in asset.group.all %}
|
||||
<tr>
|
||||
<td>{{ asset_group.name }}</td>
|
||||
<td>{{ asset_group.name|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
@ -79,19 +79,19 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">机房</td>
|
||||
<td>{{ asset.idc.name }}</td>
|
||||
<td>{{ asset.idc.name|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">硬件厂商型号</td>
|
||||
<td>{{ asset.brand }}</td>
|
||||
<td>{{ asset.brand|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">CPU</td>
|
||||
<td>{{ asset.cpu }}</td>
|
||||
<td>{{ asset.cpu|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">内存</td>
|
||||
<td>{{ asset.memory }}M</td>
|
||||
<td>{{ asset.memory|default_if_none:"" }}{% if asset.memory %}M{% endif %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">硬盘</td>
|
||||
|
@ -100,7 +100,7 @@
|
|||
{% if asset.disk %}
|
||||
{% for disk, value in asset.disk|str_to_dic %}
|
||||
<tr>
|
||||
<td><span class="text-navy">{{ disk }}</span>     {{ value }}</td>
|
||||
<td><span class="text-navy">{{ disk|default_if_none:"" }}</span>     {{ value|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
@ -109,35 +109,35 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">资产编号</td>
|
||||
<td>{{ asset.number }}</td>
|
||||
<td>{{ asset.number|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">SN</td>
|
||||
<td>{{ asset.sn }}</td>
|
||||
<td>{{ asset.sn|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">主机类型</td>
|
||||
<td>{{ asset.get_asset_type_display }}</td>
|
||||
<td>{{ asset.get_asset_type_display|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">系统版本</td>
|
||||
<td>{{ asset.system_type }} {{ asset.system_version }}</td>
|
||||
<td>{{ asset.system_type|default_if_none:"" }} {{ asset.system_version|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">运行环境</td>
|
||||
<td>{{ asset.get_env_display }}</td>
|
||||
<td>{{ asset.get_env_display|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">机器状态</td>
|
||||
<td>{{ asset.get_status_display }}</td>
|
||||
<td>{{ asset.get_status_display|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">机柜号</td>
|
||||
<td>{{ asset.cabinet }}</td>
|
||||
<td>{{ asset.cabinet|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">机柜位置</td>
|
||||
<td>{{ asset.position }}</td>
|
||||
<td>{{ asset.position|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">激活</td>
|
||||
|
@ -149,7 +149,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">备注</td>
|
||||
<td>{{ asset.comment }}</td>
|
||||
<td>{{ asset.comment|default_if_none:"" }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -54,17 +54,17 @@
|
|||
<div class="col-sm-2">
|
||||
<div class="radio i-checks">
|
||||
<label>
|
||||
<input type="radio" checked="" value="no_action" name="use_default_auth"><span> 不修改 </span>
|
||||
<input type="radio" checked="" value="no_action" id="no" name="use_default_auth" class="auth"><span> 不修改 </span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio i-checks">
|
||||
<label>
|
||||
<input type="radio" name="use_default_auth"><span> 使用默认 </span>
|
||||
<input type="radio" id="default" name="use_default_auth" class="auth"><span> 使用默认 </span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio i-checks">
|
||||
<label>
|
||||
<input type="radio" id="id_use_default_auth" name="use_default_auth"><span> 用户名密码 </span>
|
||||
<input type="radio" id="pass" name="use_default_auth" class="auth"><span> 用户名密码 </span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -140,8 +140,8 @@
|
|||
$('#uuid').val(ids)
|
||||
});
|
||||
|
||||
$('#id_use_default_auth').click(function(){
|
||||
if ($(this).is(':checked')){
|
||||
$('.auth').click(function(){
|
||||
if ($(this).attr('id') == 'pass'){
|
||||
$('#admin_account').css('display', 'block')
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<div class="col-md-12 column">
|
||||
<div class="alert alert-success alert-dismissable">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h4>
|
||||
</h4> <strong>Nice!</strong> excel文件已生成请点击 <a href="/static/files/excels/{{ file_name }}" target="_blank" class="alert-link">下载</a>
|
||||
<strong>Nice!</strong> excel文件已生成请点击 <a href="/static/files/excels/{{ file_name }}" target="_blank" class="alert-link">下载</a>
|
||||
</div>
|
||||
</div>
|
|
@ -119,12 +119,12 @@
|
|||
<td class="text-center" name="id" value="{{ asset.id }}" data-editable='false'>
|
||||
<input name="id" value="{{ asset.id }}" type="checkbox" class="i-checks">
|
||||
</td>
|
||||
<td class="text-center"> {{ asset.ip }} </td>
|
||||
<td class="text-center"> {{ asset.hostname }} </td>
|
||||
<td class="text-center"> {{ asset.idc.name }} </td>
|
||||
<td class="text-center"> {{ asset.ip|default_if_none:"" }} </td>
|
||||
<td class="text-center"> {{ asset.hostname|default_if_none:"" }} </td>
|
||||
<td class="text-center"> {{ asset.idc.name|default_if_none:"" }} </td>
|
||||
<td class="text-center">{{ asset.group.all|group_str2 }}</td>
|
||||
{# <td class="text-center">{{ asset.cpu }}|{{ asset.memory }}|{{ asset.disk }}</td>#}
|
||||
<td class="text-center">{{ asset.system_type }}{{ asset.system_version }}</td>
|
||||
<td class="text-center">{{ asset.system_type|default_if_none:"" }}{{ asset.system_version|default_if_none:"" }}</td>
|
||||
<td class="text-center"> {{ asset.use_default_auth|bool2str }} </td>
|
||||
<td class="text-center" data-editable='false'>
|
||||
<a href="/jasset/asset_detail/?id={{ asset.id }}" class="btn btn-xs btn-primary">详情</a>
|
||||
|
@ -169,17 +169,17 @@
|
|||
});
|
||||
|
||||
$(document).ready(function(){
|
||||
$('#editable').editableTableWidget({editor: $('<textarea>')});
|
||||
$('.asset_del').click(function(){
|
||||
var row = $(this).closest('tr');
|
||||
$.get(
|
||||
$(this).attr('value'),
|
||||
{},
|
||||
function(data){
|
||||
alert(data);
|
||||
row.remove()
|
||||
}
|
||||
)
|
||||
if (confirm("确定删除")) {
|
||||
$.get(
|
||||
$(this).attr('value'),
|
||||
{},
|
||||
function (data) {
|
||||
row.remove()
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
|
|
|
@ -75,12 +75,12 @@
|
|||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="" class="col-sm-2 control-label">主机<span class="red-fonts">*</span></label>
|
||||
<label for="" class="col-sm-2 control-label">主机</label>
|
||||
<div class="col-sm-4">
|
||||
<div>
|
||||
<select id="assets" name="assets" class="form-control m-b" size="12" multiple>
|
||||
{% for asset in asset_all %}
|
||||
<option value="{{ asset.id }}">{{ asset.ip }}</option>
|
||||
<option value="{{ asset.id }}">{{ asset.hostname|default_if_none:"" }} - {{ asset.ip|default_if_none:"" }} - {{ asset.port|default_if_none:"" }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
@ -133,12 +133,12 @@
|
|||
timely: 2,
|
||||
theme: "yellow_right_effect",
|
||||
fields: {
|
||||
"j_group": {
|
||||
"name": {
|
||||
rule: "required",
|
||||
tip: "输入业务组名",
|
||||
tip: "输入主机组名",
|
||||
ok: "",
|
||||
msg: {required: "业务组名必须填写!"},
|
||||
data: {'data-ok':"业务组名可以使用"}
|
||||
msg: {required: "主机组名必须填写!"},
|
||||
data: {'data-ok':"主机组名可以使用"}
|
||||
}
|
||||
},
|
||||
valid: function(form) {
|
||||
|
|
|
@ -52,17 +52,17 @@
|
|||
<tbody>
|
||||
{% for asset in contacts.object_list %}
|
||||
<tr class="gradeX">
|
||||
<td class="text-center" name="j_id" value="{{ asset.id }}" data-editable='false'><input name="id" value="{{ asset.id }}" type="checkbox" class="i-checks"></td>
|
||||
<td class="text-center" name="j_ip"> {{ asset.ip }} </td>
|
||||
<td class="text-center" name="j_port"> {{ asset.port }} </td>
|
||||
<td class="text-center" name="j_idc"> {{ asset.idc.name }} </td>
|
||||
<td class="text-center" name="j_id" value="{{ asset.id|default_if_none:"" }}" data-editable='false'><input name="id" value="{{ asset.id }}" type="checkbox" class="i-checks"></td>
|
||||
<td class="text-center" name="j_ip"> {{ asset.ip|default_if_none:"" }} </td>
|
||||
<td class="text-center" name="j_port"> {{ asset.port|default_if_none:"" }} </td>
|
||||
<td class="text-center" name="j_idc"> {{ asset.idc.name|default_if_none:"" }} </td>
|
||||
<td class="text-center" name="j_group">{{ asset.bis_group.all | group_str2 }}</td>
|
||||
<td class="text-center" name="j_active"> {{ asset.is_active|bool2str }} </td>
|
||||
<td class="text-center"> {{ asset.date_added|date:"Y-m-d H:i:s" }} </td>
|
||||
<td class="text-center" name="j_comment"> {{ asset.comment }} </td>
|
||||
<td class="text-center" name="j_comment"> {{ asset.comment|default_if_none:"" }} </td>
|
||||
<td class="text-center" data-editable='false'>
|
||||
<a href="/jasset/host_detail/?id={{ asset.id }}" class="iframe btn btn-xs btn-primary">详情</a>
|
||||
<a href="/jasset/host_edit/?id={{ asset.id }}" class="btn btn-xs btn-info">编辑</a>
|
||||
<a href="/jasset/asset_detail/?id={{ asset.id }}" class="iframe btn btn-xs btn-primary">详情</a>
|
||||
<a href="/jasset/asset_edit/?id={{ asset.id }}" class="btn btn-xs btn-info">编辑</a>
|
||||
<a href="/jasset/group_del_host/?id={{ asset.id }}&gid={{ group.id }}" class="btn btn-xs btn-danger">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
<div>
|
||||
<select id="assets" name="assets" class="form-control m-b" size="12" multiple>
|
||||
{% for asset in asset_no_select %}
|
||||
<option value="{{ asset.id }}">{{ asset.ip }}</option>
|
||||
<option value="{{ asset.id }}">{{ asset.hostname|default_if_none:"" }} - {{ asset.ip|default_if_none:"" }} - {{ asset.port|default_if_none:"" }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
@ -103,7 +103,7 @@
|
|||
<div>
|
||||
<select id="asset_select" name="asset_select" class="form-control m-b" size="12" multiple>
|
||||
{% for asset in asset_select %}
|
||||
<option value="{{ asset.id }}">{{ asset.ip }}</option>
|
||||
<option value="{{ asset.id }}">{{ asset.hostname|default_if_none:"" }} - {{ asset.ip|default_if_none:"" }} - {{ asset.port|default_if_none:"" }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
<td class="text-center">
|
||||
<a href="/jasset/group_detail/?id={{ asset_group.id }}" class="btn btn-xs btn-info">详情</a>
|
||||
<a href="/jasset/group_edit/?id={{ asset_group.id }}" class="btn btn-xs btn-info">编辑</a>
|
||||
<a value="/jasset/group_del/?id={{ asset_group.id }}" id="del" class="btn btn-xs btn-danger">删除</a>
|
||||
<a value="/jasset/group_del/?id={{ asset_group.id }}" class="btn btn-xs btn-danger group_del">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -88,16 +88,17 @@
|
|||
{% block self_footer_js %}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$('#del').click(function(){
|
||||
$('.group_del').click(function(){
|
||||
var row = $(this).closest('tr');
|
||||
$.get(
|
||||
$(this).attr('value'),
|
||||
{},
|
||||
function(data){
|
||||
row.remove();
|
||||
alert(data)
|
||||
}
|
||||
)
|
||||
if (confirm('确定删除')) {
|
||||
$.get(
|
||||
$(this).attr('value'),
|
||||
{},
|
||||
function (data) {
|
||||
row.remove();
|
||||
}
|
||||
)
|
||||
}
|
||||
});
|
||||
|
||||
$('#del_check').click(function(){
|
||||
|
@ -111,15 +112,12 @@
|
|||
{id: check_array.join(',')},
|
||||
function(data){
|
||||
$('tr.gradeX input:checked').closest('tr').remove();
|
||||
alert(data);
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -40,6 +40,13 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<label for="role_password_label" class="col-sm-2 control-label">角色密码<span class="red-fonts">*</span></label>
|
||||
<div class="col-sm-8">
|
||||
<input id="role_password" name="role_password" type="password" class="form-control" value="{{ role_pass }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<label for="role_comment" class="col-sm-2 control-label">备注</label>
|
||||
<div class="col-sm-8">
|
||||
|
|
|
@ -7,6 +7,14 @@
|
|||
<div class="row">
|
||||
<div class="col-lg-10">
|
||||
<div class="ibox float-e-margins">
|
||||
<div>
|
||||
{% if error %}
|
||||
<div class="alert alert-warning text-center">{{ error }}</div>
|
||||
{% endif %}
|
||||
{% if msg %}
|
||||
<div class="alert alert-success text-center">{{ msg }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="ibox-title">
|
||||
<h5> 所有系统角色</h5>
|
||||
<div class="ibox-tools">
|
||||
|
|
|
@ -67,16 +67,6 @@
|
|||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="row">
|
||||
<div class="form-group">
|
||||
<label for="j_group" class="col-sm-2 control-label">使用密码</label>
|
||||
<div class="col-sm-1">
|
||||
<div class="radio i-checks">
|
||||
<label>
|
||||
<input type="checkbox" value="1" id="use_password" name="use_password">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="j_group" class="col-sm-2 control-label">使用秘钥</label>
|
||||
<div class="col-sm-1">
|
||||
|
|
|
@ -95,51 +95,11 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="j_group" class="col-sm-2 control-label">使用密码</label>
|
||||
<div class="col-sm-1">
|
||||
<div class="radio i-checks">
|
||||
<label>
|
||||
<input type="checkbox" value="0" id="use_password" name="use_password">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" id="admin_account_password" style="display: none">
|
||||
<label class="col-sm-1 control-label"> 密码<span class="red-fonts">*</span> </label>
|
||||
<div class="col-sm-4">
|
||||
<input type="password" name="password" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="j_group" class="col-sm-2 control-label">使用秘钥</label>
|
||||
<div class="col-sm-1">
|
||||
<div class="radio i-checks">
|
||||
<label>
|
||||
<input type="checkbox" value="1" id="use_publicKey" name="use_publicKey">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" id="admin_account_publicKey" style="display: none">
|
||||
<label class="col-sm-1 control-label"> 秘钥<span class="red-fonts">*</span> </label>
|
||||
<div class="col-sm-4">
|
||||
<input type="password" name="password" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<label for="comment" class="col-sm-2 control-label">备注</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="comment" name="comment" placeholder="Rule Comment" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}>
|
||||
<input id="rule_comment" name="rule_comment" placeholder="Rule Comment" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<div class="col-sm-8">
|
||||
<select name="user" data-placeholder="用户名" class="chosen-select form-control m-b" multiple tabindex="2">
|
||||
{% for user in users %}
|
||||
<option value="{{ user.name }}">{{ user.name }}</option>
|
||||
<option value="{{ user.name }}" {% if user in users_select %} selected {% endif %}>{{ user.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
@ -56,7 +56,7 @@
|
|||
<div class="col-sm-8">
|
||||
<select name="usergroup" data-placeholder="请选择用户组" class="chosen-select form-control m-b" multiple tabindex="2">
|
||||
{% for user_group in user_groups %}
|
||||
<option value="{{ user_group.name }}">{{ user_group.name }}</option>
|
||||
<option value="{{ user_group.name }}"{% if user_group in users_groups_select %} selected {% endif %}>{{ user_group.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
@ -67,7 +67,7 @@
|
|||
<div class="col-sm-8">
|
||||
<select name="asset" data-placeholder="请选择资产" class="chosen-select form-control m-b" multiple tabindex="2">
|
||||
{% for asset in assets %}
|
||||
<option value="{{ asset.ip }}">{{ asset.ip }}</option>
|
||||
<option value="{{ asset.ip }}"{% if asset in assets_select %} selected {% endif %}>{{ asset.ip }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
@ -78,7 +78,7 @@
|
|||
<div class="col-sm-8">
|
||||
<select name="assetgroup" data-placeholder="请选择资产组" class="chosen-select form-control m-b" multiple tabindex="2">
|
||||
{% for asset_group in asset_groups %}
|
||||
<option value="{{ asset_group.name }}">{{ asset_group.name }}</option>
|
||||
<option value="{{ asset_group.name }}"{% if asset_group in asset_groups_select %} selected {% endif %}>{{ asset_group.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
@ -89,57 +89,17 @@
|
|||
<div class="col-sm-8">
|
||||
<select name="role" data-placeholder="请选择角色" class="chosen-select form-control m-b" multiple tabindex="2">
|
||||
{% for role in roles %}
|
||||
<option value="{{ role.name }}">{{ role.name }}</option>
|
||||
<option value="{{ role.name }}"{% if role in roles_select %} selected {% endif %}>{{ role.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="j_group" class="col-sm-2 control-label">使用密码</label>
|
||||
<div class="col-sm-1">
|
||||
<div class="radio i-checks">
|
||||
<label>
|
||||
<input type="checkbox" value="0" id="use_password" name="use_password">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" id="admin_account_password" style="display: none">
|
||||
<label class="col-sm-1 control-label"> 密码<span class="red-fonts">*</span> </label>
|
||||
<div class="col-sm-4">
|
||||
<input type="password" name="password" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="j_group" class="col-sm-2 control-label">使用秘钥</label>
|
||||
<div class="col-sm-1">
|
||||
<div class="radio i-checks">
|
||||
<label>
|
||||
<input type="checkbox" value="1" id="use_publicKey" name="use_publicKey">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" id="admin_account_publicKey" style="display: none">
|
||||
<label class="col-sm-1 control-label"> 秘钥<span class="red-fonts">*</span> </label>
|
||||
<div class="col-sm-4">
|
||||
<input type="password" name="password" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<label for="comment" class="col-sm-2 control-label">备注</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="comment" name="comment" placeholder="Comment" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}>
|
||||
<input id="role_comment" name="role_comment" placeholder="Rule Comment" type="text" class="form-control" value="{{ rule_comment }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
|
|
|
@ -3,10 +3,20 @@
|
|||
{% block content %}
|
||||
{% include 'nav_cat_bar.html' %}
|
||||
|
||||
|
||||
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-lg-10">
|
||||
<div class="ibox float-e-margins">
|
||||
<div>
|
||||
{% if error %}
|
||||
<div class="alert alert-warning text-center">{{ error }}</div>
|
||||
{% endif %}
|
||||
{% if msg %}
|
||||
<div class="alert alert-success text-center">{{ msg }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="ibox-title">
|
||||
<h5> 所有规则</h5>
|
||||
<div class="ibox-tools">
|
||||
|
@ -55,19 +65,19 @@
|
|||
<tr class="gradeX" id={{ rule.id }}>
|
||||
<td class="text-center"> {{ rule.name }} </td>
|
||||
<td class="text-center">
|
||||
<a href="/jasset/asset_list/?gid={{ user.id }}">{{ rule | rule_member_count:"user" }} </a>
|
||||
{{ rule | rule_member_count:"user" }}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="/jasset/group_list/?gid={{ user.id }}">{{ rule | rule_member_count:"user_group" }}</a>
|
||||
{{ rule | rule_member_count:"user_group" }}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="/jasset/group_list/?gid={{ user.id }}">{{ rule | rule_member_count:"asset" }}</a>
|
||||
{{ rule | rule_member_count:"asset" }}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="/jasset/group_list/?gid={{ user.id }}">{{ rule | rule_member_count:"asset_group" }}</a>
|
||||
{{ rule | rule_member_count:"asset_group" }}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="/jasset/group_list/?gid={{ user.id }}">{{ rule | rule_member_count:"role" }}</a>
|
||||
{{ rule | rule_member_count:"role" }}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="/jperm/perm_rule_detail/?id={{ rule.id }}" class="btn btn-xs btn-primary">详情</a>
|
||||
|
|
|
@ -64,7 +64,13 @@
|
|||
<td class="text-center" title="{% for user_group in user.group.all %} {{ user_group.name }} {% endfor %}"> {{ user.group.all | groups2str }} </td>
|
||||
<td class="text-center"> {{ user.id | get_role }}</td>
|
||||
<td class="text-center">{{ user.is_active | bool2str }}</td>
|
||||
<td class="text-center"><a href="/juser/down_key/?id={{ user.id }}">下载</a></td>
|
||||
<td class="text-center">
|
||||
{% if user.username|key_exist %}
|
||||
<a href="/juser/down_key/?id={{ user.id }}" >下载</a>
|
||||
{% else %}
|
||||
<span style="color: #586b7d">下载</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="../user_detail/?id={{ user.id }}" class="btn btn-xs btn-primary">详情</a>
|
||||
<a href="../user_edit/?id={{ user.id }}" class="btn btn-xs btn-info">编辑</a>
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
<ul class="nav" id="side-menu">
|
||||
{% include 'nav_li_profile.html' %}
|
||||
<li id="index">
|
||||
<a href="/"><i class="fa fa-th-large"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span></a>
|
||||
<a href="/"><i class="fa fa-dashboard"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span></a>
|
||||
</li>
|
||||
<li id="juser">
|
||||
<a href="#"><i class="fa fa-rebel"></i> <span class="nav-label">用户管理</span><span class="fa arrow"></span></a>
|
||||
<a href="#"><i class="fa fa-group"></i> <span class="nav-label">用户管理</span><span class="fa arrow"></span></a>
|
||||
<ul class="nav nav-second-level">
|
||||
<li class="group_list group_edit"><a href="/juser/group_list/">查看用户组</a></li>
|
||||
<li class="group_add"><a href="/juser/group_add/">添加用户组</a></li>
|
||||
|
@ -16,7 +16,7 @@
|
|||
</ul>
|
||||
</li>
|
||||
<li id="jasset">
|
||||
<a><i class="fa fa-cube"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span></a>
|
||||
<a><i class="fa fa-inbox"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span></a>
|
||||
<ul class="nav nav-second-level">
|
||||
<li class="group_add"><a href="/jasset/group_add/">添加资产组</a></li>
|
||||
<li class="group_list group_detail group_edit"><a href="/jasset/group_list/">查看资产组</a></li>
|
||||
|
@ -44,7 +44,7 @@
|
|||
<a href="/jlog/log_list/online/"><i class="fa fa-files-o"></i> <span class="nav-label">日志审计</span><span class="label label-info pull-right"></span></a>
|
||||
</li>
|
||||
<li id="setting">
|
||||
<a href="/setting/"><i class="fa fa-files-o"></i> <span class="nav-label">设置</span><span class="label label-info pull-right"></span></a>
|
||||
<a href="/setting/"><i class="fa fa-gears"></i> <span class="nav-label">设置</span><span class="label label-info pull-right"></span></a>
|
||||
</li>
|
||||
<li class="special_link">
|
||||
<a href="http://www.jumpserver.org" target="_blank"><i class="fa fa-database"></i> <span class="nav-label">访问官网</span></a>
|
||||
|
@ -76,7 +76,7 @@
|
|||
<a><i class="fa fa-cube"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span></a>
|
||||
<ul class="nav nav-second-level">
|
||||
{# <li class="host_add host_add_multi"><a href="/jasset/host_add/">添加资产</a></li>#}
|
||||
<li class="host_list host_detail host_edit"><a href="/jasset/asset_list/">查看资产<span class="label label-info pull-right">{{ host_active_num }}/{{ host_total_num}}</span></a></li>
|
||||
<li class="asset_list asset_detail asset_edit"><a href="/jasset/asset_list/">查看资产<span class="label label-info pull-right">{{ host_active_num }}/{{ host_total_num}}</span></a></li>
|
||||
<li class="idc_list idc_detail idc_edit"><a href="/jasset/idc_list/">查看IDC</a></li>
|
||||
<li class="group_add"><a href="/jasset/group_add/">添加主机组</a></li>
|
||||
<li class="group_list group_detail group_edit"><a href="/jasset/group_list/">查看主机组</a></li>
|
||||
|
|
Loading…
Reference in New Issue