mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-12-15 16:42:34 +00:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3533c01011 | ||
|
|
77ec2d5a86 | ||
|
|
8b707dc8f5 | ||
|
|
8dcc9c8d53 | ||
|
|
0ca0519ef1 | ||
|
|
8de50a0e83 | ||
|
|
64b7fb6a3d | ||
|
|
a114e173e0 | ||
|
|
402df81048 | ||
|
|
2a51eeef10 | ||
|
|
4b593e56f9 | ||
|
|
9f3c83b052 | ||
|
|
a864c38238 | ||
|
|
547408222d | ||
|
|
0ad26254ef | ||
|
|
b7e138f919 | ||
|
|
2ec415fd84 | ||
|
|
b3c12e8861 | ||
|
|
da8f30fc72 | ||
|
|
cddb0ce537 | ||
|
|
124e26fa32 | ||
|
|
59c689cd61 | ||
|
|
0cc36b1302 | ||
|
|
0ac9d19252 | ||
|
|
d9e497e8be | ||
|
|
e18ae7f82c | ||
|
|
e5286686b9 | ||
|
|
332316b0af | ||
|
|
8f666785d2 | ||
|
|
0ed4b84b63 | ||
|
|
97591e6f03 | ||
|
|
5d5d8ab32a | ||
|
|
5489f3ae36 | ||
|
|
ce7a3d1f33 |
@@ -76,5 +76,13 @@ Web批量执行命令
|
||||

|
||||
|
||||
|
||||
### License & Copyright
|
||||
|
||||
Copyright (c) 2014-2017 Beijing Duizhan Tech, Inc., All rights reserved.
|
||||
|
||||
Licensed under The GNU General Public License version 2 (GPLv2) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
||||
|
||||
https://www.gnu.org/licenses/gpl-2.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
|
||||
@@ -331,7 +331,7 @@ class SshTty(Tty):
|
||||
if msg.errno == errno.EAGAIN:
|
||||
continue
|
||||
now_timestamp = time.time()
|
||||
termlog.write(x)
|
||||
#termlog.write(x)
|
||||
termlog.recoder = False
|
||||
log_time_f.write('%s %s\n' % (round(now_timestamp-pre_timestamp, 4), len(x)))
|
||||
log_time_f.flush()
|
||||
@@ -522,8 +522,12 @@ class Nav(object):
|
||||
asset_info = get_asset_info(asset)
|
||||
# 获取该资产包含的角色
|
||||
role = [str(role.name) for role in self.user_perm.get('asset').get(asset).get('role')]
|
||||
try:
|
||||
print line % (index, asset.ip, asset_info.get('port'),
|
||||
self.truncate_str(asset.hostname), str(role).replace("'", ''), asset.comment)
|
||||
except:
|
||||
print line % (index, asset.ip, asset_info.get('port'),
|
||||
self.truncate_str(asset.hostname), str(role).replace("'", ''), '')
|
||||
print
|
||||
|
||||
def try_connect(self):
|
||||
|
||||
@@ -8,10 +8,18 @@ services:
|
||||
- "8888:80"
|
||||
- "2222:22"
|
||||
# environment:
|
||||
# - ENGINE=mysql
|
||||
# - MYSQL_HOST=192.168.64.5
|
||||
# - USE_MYSQL=true
|
||||
# - MYSQL_ENGINE=mysql
|
||||
# - MYSQL_HOST=192.168.50.143
|
||||
# - MYSQL_PORT=3306
|
||||
# - MYSQL_USER=root
|
||||
# - MYSQL_USER=jumpserver
|
||||
# - MYSQL_PASS=love1314
|
||||
# - MYSQL_NAME=jumpserver
|
||||
# - MAIL_ENABLED=false
|
||||
# - USE_MAIL=true
|
||||
# - MAIL_ENABLED=1
|
||||
# - MAIL_HOST=smtp.163.com
|
||||
# - MAIL_PORT=25
|
||||
# - MAIL_USER=jumpserver@163.com
|
||||
# - MAIL_PASS=123456
|
||||
# - MAIL_USE_TLS=False
|
||||
# - MAIL_USE_SSL=False
|
||||
|
||||
@@ -6,12 +6,12 @@ port = 80
|
||||
log = debug
|
||||
|
||||
[db]
|
||||
engine = __ENGINE__
|
||||
engine = __MYSQL_ENGINE__
|
||||
host = __MYSQL_HOST__
|
||||
port = __MYSQL_PORT__
|
||||
user = __MYSQL_USER__
|
||||
password = __MYSQL_PASS__
|
||||
database = __DATEBASE__
|
||||
database = __MYSQL_NAME__
|
||||
|
||||
[mail]
|
||||
mail_enable = __MAIL_ENABLED__
|
||||
@@ -20,6 +20,7 @@ email_port = __MAIL_PORT__
|
||||
email_host_user = __MAIL_USER__
|
||||
email_host_password = __MAIL_PASS__
|
||||
email_use_tls = __MAIL_USE_TLS__
|
||||
email_use_ssl = __MAIL_USE_SSL__
|
||||
|
||||
[connect]
|
||||
nav_sort_by = ip
|
||||
|
||||
@@ -3,7 +3,7 @@ cp -r /jumpserver/install/docker/config_tmpl.conf /jumpserver/jumpserver.conf
|
||||
if [ ! -n "${USE_MYSQL}" ]; then
|
||||
sed -i "s/__USE_MYSQL__/false/" /jumpserver/jumpserver.conf
|
||||
else
|
||||
sed -i "s/__USE_MYSQL__/true/" /jumpserver/jumpserver.conf
|
||||
sed -i "s/__MYSQL_ENGINE__/${MYSQL_ENGINE}/" /jumpserver/jumpserver.conf
|
||||
sed -i "s/__MYSQL_HOST__/${MYSQL_HOST}/" /jumpserver/jumpserver.conf
|
||||
sed -i "s/__MYSQL_PORT__/${MYSQL_PORT}/" /jumpserver/jumpserver.conf
|
||||
sed -i "s/__MYSQL_USER__/${MYSQL_USER}/" /jumpserver/jumpserver.conf
|
||||
@@ -11,8 +11,8 @@ sed -i "s/__MYSQL_PASS__/${MYSQL_PASS}/" /jumpserver/jumpserver.conf
|
||||
sed -i "s/__MYSQL_NAME__/${MYSQL_NAME}/" /jumpserver/jumpserver.conf
|
||||
fi
|
||||
|
||||
if [ ! -n "${MAIL_ENABLED}" ]; then
|
||||
sed -i "s/__MAIL_ENABLED__/false/" /jumpserver/jumpserver.conf
|
||||
if [ ! -n "${USE_MAIL}" ]; then
|
||||
sed -i "s/__USE_MAIL__/false/" /jumpserver/jumpserver.conf
|
||||
else
|
||||
sed -i "s/__MAIL_ENABLED__/${MAIL_ENABLED}/" /jumpserver/jumpserver.conf
|
||||
sed -i "s/__MAIL_HOST__/${MAIL_HOST}/" /jumpserver/jumpserver.conf
|
||||
@@ -25,7 +25,11 @@ sed -i "s/__MAIL_USE_TLS__/false/" /jumpserver/jumpserver.conf
|
||||
else
|
||||
sed -i "s/__MAIL_USE_TLS__/${MAIL_USE_TLS}/" /jumpserver/jumpserver.conf
|
||||
fi
|
||||
|
||||
if [ ! -n "${MAIL_USE_SSL}" ]; then
|
||||
sed -i "s/__MAIL_USE_SSL__/false/" /jumpserver/jumpserver.conf
|
||||
else
|
||||
sed -i "s/__MAIL_USE_SSL__/${MAIL_USE_SSL}/" /jumpserver/jumpserver.conf
|
||||
fi
|
||||
if [ ! -f "/etc/ssh/sshd_config" ]; then
|
||||
cp -r /jumpserver/install/docker/sshd_config /etc/ssh/sshd_config
|
||||
fi
|
||||
@@ -42,12 +46,16 @@ if [ ! -f "/etc/ssh/ssh_host_ed25519_key" ]; then
|
||||
ssh-keygen -t ed25519 -b 1024 -f /etc/ssh/ssh_host_ed25519_key -N ''
|
||||
fi
|
||||
|
||||
# handle empty data directory
|
||||
mkdir -p /data/logs
|
||||
|
||||
/usr/sbin/sshd -E /data/logs/jumpserver.log
|
||||
python /jumpserver/manage.py syncdb --noinput
|
||||
if [ ! -f "/home/init.locked" ]; then
|
||||
python manage.py loaddata install/initial_data.yaml
|
||||
python /jumpserver/manage.py loaddata install/initial_data.yaml
|
||||
date > /home/init.locked
|
||||
fi
|
||||
python /jumpserver/run_server.py >> /data/logs/jumpserver.log &
|
||||
python /jumpserver/manage.py crontab add >> /data/logs/jumpserver.log &
|
||||
python /jumpserver/run_server.py >> /dev/null &
|
||||
chmod -R 777 /data/logs/jumpserver.log
|
||||
tail -f /data/logs/jumpserver.log
|
||||
|
||||
@@ -85,12 +85,12 @@ class PreSetup(object):
|
||||
|
||||
@property
|
||||
def _is_redhat(self):
|
||||
if self.dist.startswith("centos") or self.dist.startswith("red") or self.dist == "fedora" or self.dist == "amazon linux ami":
|
||||
if self.dist.startswith("centos") or self.dist.startswith("red") or self.dist == "fedora" or self.dist == "oracle" or self.dist == "amazon linux ami":
|
||||
return True
|
||||
|
||||
@property
|
||||
def _is_centos7(self):
|
||||
if self.dist.startswith("centos") and self.version.startswith("7"):
|
||||
if (self.dist.startswith("centos") or self.dist.startswith("centos linux")) and self.version.startswith("7"):
|
||||
return True
|
||||
|
||||
@property
|
||||
@@ -104,8 +104,8 @@ class PreSetup(object):
|
||||
return True
|
||||
|
||||
def check_platform(self):
|
||||
if not (self._is_redhat or self._is_ubuntu):
|
||||
print(u"支持的平台: CentOS, RedHat, Fedora, Debian, Ubuntu, Amazon Linux, 暂不支持其他平台安装.")
|
||||
if not (self._is_redhat or self._is_ubuntu or self._is_centos7):
|
||||
print(u"支持的平台: CentOS, RedHat, Fedora, Oracle Linux, Debian, Ubuntu, Amazon Linux, 暂不支持其他平台安装.")
|
||||
exit()
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#sphinx-me==0.3
|
||||
PyYAML==3.10
|
||||
django==1.6
|
||||
pycrypto==2.4.1
|
||||
paramiko==1.16.0
|
||||
|
||||
@@ -409,6 +409,17 @@ class MyTask(MyRunner):
|
||||
self.run("script", module_args1, become=True)
|
||||
return self.results
|
||||
|
||||
def recyle_cmd_alias(self, role_name):
|
||||
"""
|
||||
recyle sudo cmd alias
|
||||
:return:
|
||||
"""
|
||||
if role_name == 'root':
|
||||
return {"status": "failed", "msg": "can't recyle root privileges"}
|
||||
module_args = "sed -i 's/^%s.*//' /etc/sudoers" % role_name
|
||||
self.run("command", module_args, become=True)
|
||||
return self.results
|
||||
|
||||
|
||||
class CustomAggregateStats(callbacks.AggregateStats):
|
||||
"""
|
||||
|
||||
@@ -81,6 +81,7 @@ def perm_rule_detail(request):
|
||||
return my_render('jperm/perm_rule_detail.html', locals(), request)
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
def perm_rule_add(request):
|
||||
"""
|
||||
add rule page
|
||||
@@ -533,6 +534,8 @@ def perm_role_push(request):
|
||||
sudo_list = set([sudo for sudo in role.sudo.all()]) # set(sudo1, sudo2, sudo3)
|
||||
if sudo_list:
|
||||
ret['sudo'] = task.push_sudo_file([role], sudo_list)
|
||||
else:
|
||||
ret['sudo'] = task.recyle_cmd_alias(role.name)
|
||||
|
||||
logger.debug('推送role结果: %s' % ret)
|
||||
success_asset = {}
|
||||
@@ -576,7 +579,7 @@ def perm_role_push(request):
|
||||
if not failed_asset:
|
||||
msg = u'系统用户 %s 推送成功[ %s ]' % (role.name, ','.join(success_asset.keys()))
|
||||
else:
|
||||
error = u'系统用户 %s 推送失败 [ %s ], 推送成功 [ %s ] 进入系统用户详情,查看失败原因' % (role.name,
|
||||
error = u'系统用户 %s 推送失败 [ %s ], 推送成功 [ %s ] 请点系统用户->点对应名称->点失败,查看失败原因' % (role.name,
|
||||
','.join(failed_asset.keys()),
|
||||
','.join(success_asset.keys()))
|
||||
return my_render('jperm/perm_role_push.html', locals(), request)
|
||||
|
||||
@@ -151,7 +151,7 @@ def server_add_user(username, ssh_key_pwd=''):
|
||||
add a system user in jumpserver
|
||||
在jumpserver服务器上添加一个用户
|
||||
"""
|
||||
bash("adduser -s '%s' '%s'" % (os.path.join(BASE_DIR, 'init.sh'), username))
|
||||
bash("useradd -s '%s' '%s'" % (os.path.join(BASE_DIR, 'init.sh'), username))
|
||||
gen_ssh_key(username, ssh_key_pwd)
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ from django.shortcuts import get_object_or_404
|
||||
from django.db.models import Q
|
||||
from juser.user_api import *
|
||||
from jperm.perm_api import get_group_user_perm
|
||||
import re
|
||||
|
||||
MAIL_FROM = EMAIL_HOST_USER
|
||||
|
||||
@@ -159,15 +160,23 @@ def user_add(request):
|
||||
if '' in [username, password, ssh_key_pwd, name, role]:
|
||||
error = u'带*内容不能为空'
|
||||
raise ServerError
|
||||
|
||||
check_user_is_exist = User.objects.filter(username=username)
|
||||
if check_user_is_exist:
|
||||
error = u'用户 %s 已存在' % username
|
||||
raise ServerError
|
||||
|
||||
if username in ['root']:
|
||||
error = u'用户不能为root'
|
||||
raise ServerError
|
||||
|
||||
except ServerError:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
if not re.match(r"^\w+$",username):
|
||||
error = u'用户名不合法'
|
||||
raise ServerError(error)
|
||||
user = db_add_user(username=username, name=name,
|
||||
password=password,
|
||||
email=email, role=role, uuid=uuid_r,
|
||||
|
||||
@@ -416,7 +416,7 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
|
||||
data = ''
|
||||
pre_timestamp = time.time()
|
||||
while True:
|
||||
r, w, e = select.select([self.channel, sys.stdin], [], [])
|
||||
r, w, e = select.select([self.channel], [], [])
|
||||
if self.channel in r:
|
||||
recv = self.channel.recv(1024)
|
||||
if not len(recv):
|
||||
@@ -494,7 +494,7 @@ def main():
|
||||
[
|
||||
(r'/ws/monitor', MonitorHandler),
|
||||
(r'/ws/terminal', WebTerminalHandler),
|
||||
(r'/kill', WebTerminalKillHandler),
|
||||
(r'/ws/kill', WebTerminalKillHandler),
|
||||
(r'/ws/exec', ExecHandler),
|
||||
(r"/static/(.*)", tornado.web.StaticFileHandler,
|
||||
dict(path=os.path.join(os.path.dirname(__file__), "static"))),
|
||||
|
||||
@@ -28,6 +28,11 @@ PROC_NAME="jumpserver"
|
||||
lockfile=/var/lock/subsys/${PROC_NAME}
|
||||
|
||||
start() {
|
||||
if [ $(whoami) != 'root' ];then
|
||||
echo "Sorry, JMS must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
jump_start=$"Starting ${PROC_NAME} service:"
|
||||
if [ -f $lockfile ];then
|
||||
echo -n "jumpserver is running..."
|
||||
|
||||
@@ -13,7 +13,7 @@ WSSHClient.prototype._generateEndpoint = function (options) {
|
||||
var protocol = 'ws://';
|
||||
}
|
||||
|
||||
var endpoint = protocol + document.URL.match(RegExp('//(.*?)/'))[1] + '/ws/terminal' + document.URL.match(/(\?.*)/);
|
||||
var endpoint = protocol + document.URL.match(RegExp('//(.*?)/'))[1] + '/ws/terminal' + document.URL.match(/\?.*/);
|
||||
return endpoint;
|
||||
};
|
||||
WSSHClient.prototype.connect = function (options) {
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="{% url 'log_list' 'online' %}" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
|
||||
<li><a href="{% url 'log_list' 'offline' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 登录历史</a></li>
|
||||
<li class="active"><a href="{% url 'log_list' 'exec' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
|
||||
<li class="active"><a href="{% url 'log_list' 'exec' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 批量命令 </a></li>
|
||||
<li><a href="{% url 'log_list' 'file' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
|
||||
<div class="" style="float: right">
|
||||
<form id="search_form" method="get" action="" class="pull-right mail-search">
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="{% url 'log_list' 'online' %}" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
|
||||
<li><a href="{% url 'log_list' 'offline' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 登录历史</a></li>
|
||||
<li><a href="{% url 'log_list' 'exec' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
|
||||
<li><a href="{% url 'log_list' 'exec' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 批量命令 </a></li>
|
||||
<li class="active"><a href="{% url 'log_list' 'file' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
|
||||
<div class="" style="float: right">
|
||||
<form id="search_form" method="get" action="" class="pull-right mail-search">
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="{% url 'log_list' 'online' %}" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
|
||||
<li class="active"><a href="{% url 'log_list' 'offline' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 登录历史</a></li>
|
||||
<li><a href="{% url 'log_list' 'exec' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
|
||||
<li><a href="{% url 'log_list' 'exec' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 批量命令 </a></li>
|
||||
<li><a href="{% url 'log_list' 'file' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="{% url 'log_list' 'online' %}" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
|
||||
<li><a href="{% url 'log_list' 'offline' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 登录历史</a></li>
|
||||
<li><a href="{% url 'log_list' 'exec' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
|
||||
<li><a href="{% url 'log_list' 'exec' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 批量命令 </a></li>
|
||||
<li><a href="{% url 'log_list' 'file' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
|
||||
<div class="" style="float: right">
|
||||
<form id="search_form" method="get" action="" class="pull-right mail-search">
|
||||
@@ -215,7 +215,7 @@
|
||||
|
||||
function cut(num, login_type){
|
||||
var protocol = window.location.protocol;
|
||||
var endpoint = protocol + '//' + document.URL.match(RegExp('//(.*?)/'))[1] + '/kill';
|
||||
var endpoint = protocol + '//' + document.URL.match(RegExp('//(.*?)/'))[1] + '/ws/kill';
|
||||
if (login_type=='web'){
|
||||
var g_url = endpoint + '?id=' + num;
|
||||
console.log(g_url);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
.terminal {
|
||||
border: #000 solid 5px;
|
||||
font-family: "Monaco", "Microsoft Yahei", "DejaVu Sans Mono", "Liberation Mono", monospace;
|
||||
font-family: Consolas, Monaco, monospace;
|
||||
font-size: 11px;
|
||||
color: #f0f0f0;
|
||||
background: #000;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<label for="role_name" class="col-sm-2 control-label">用户名称<span class="red-fonts">*</span></label>
|
||||
<div class="col-sm-8">
|
||||
<input id="role_name" name="role_name" placeholder="Role Name" type="text" class="form-control">
|
||||
<span class="help-block m-b-none">如果客户端是网络设备,填写已配置的SSH登录用户,支持SSH协议V2.0以上 </span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
@@ -44,7 +45,7 @@
|
||||
<label for="role_password" class="col-sm-2 control-label">用户密码</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="role_password" name="role_password" placeholder="Role Password" type="password" class="form-control">
|
||||
<span class="help-block m-b-none">如果不添加密码,会自动生成</span>
|
||||
<span class="help-block m-b-none">如果客户端是网络设备这里必填,如果客户端是服务器,密码不会被推送,不会修改客户端原有的用户密码,请忽略这里</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
||||
@@ -66,10 +66,11 @@
|
||||
<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="col-sm-8">
|
||||
<div class="radio i-checks">
|
||||
<label>
|
||||
<input type="checkbox" value="1" id="use_publicKey" name="use_publicKey" checked>
|
||||
<span class="help-block m-b-none">如果资产是网络设备,请取消复选框(模拟推送),如果资产是服务器,要选中复选框 </span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -126,6 +126,7 @@ $('#userForm').validator({
|
||||
timely: 2,
|
||||
theme: "yellow_right_effect",
|
||||
rules: {
|
||||
check_name: [/(?!^root$)^[\w.]{2,20}$/i, '大小写字母数字和下划线小数点,2-20位,并且非root'],
|
||||
check_username: [/^[\w.]{3,20}$/, '大小写字母数字和下划线小数点'],
|
||||
type_m: function(element){
|
||||
return $("#M").is(":checked");
|
||||
@@ -133,7 +134,7 @@ $('#userForm').validator({
|
||||
},
|
||||
fields: {
|
||||
"username": {
|
||||
rule: "required;check_username",
|
||||
rule: "required;check_username;check_name",
|
||||
tip: "输入用户名",
|
||||
ok: "",
|
||||
msg: {required: "必须填写!"}
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<input name="setting" value="default" style="display: none">
|
||||
<div class="col-sm-8">
|
||||
<input id="username" name="username" placeholder="Username" type="text" value="{{ setting_default.field1 }}" class="form-control">
|
||||
<span class="help-block m-b-none"> 管理账号是服务器存在的root等高权限账号(或拥有NOPASSWD: ALL sudo权限),用来推送新建系统用户</span>
|
||||
<span class="help-block m-b-none"> 管理用户是指客户端上的如root等高权限账号(或拥有NOPASSWD: ALL sudo权限),用来推送新建系统用户</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
|
||||
Reference in New Issue
Block a user