mirror of https://github.com/jumpserver/jumpserver
bug fix
parent
bd2a3e6119
commit
e408414631
|
@ -563,7 +563,7 @@ class Nav(object):
|
|||
for asset in assets:
|
||||
print ' %s' % asset.hostname
|
||||
print
|
||||
print "请输入主机名、IP或ansile支持的pattern, q退出"
|
||||
print "请输入主机名、IP或ansile支持的pattern, 多个主机:分隔, q退出"
|
||||
pattern = raw_input("\033[1;32mPattern>:\033[0m ").strip()
|
||||
if pattern == 'q':
|
||||
break
|
||||
|
@ -606,7 +606,7 @@ class Nav(object):
|
|||
self.user_perm = get_group_user_perm(self.user)
|
||||
try:
|
||||
print "进入批量上传模式"
|
||||
print "请输入主机名、IP或ansile支持的pattern, q退出"
|
||||
print "请输入主机名、IP或ansile支持的pattern, 多个主机:分隔 q退出"
|
||||
pattern = raw_input("\033[1;32mPattern>:\033[0m ").strip()
|
||||
if pattern == 'q':
|
||||
break
|
||||
|
@ -659,7 +659,7 @@ class Nav(object):
|
|||
self.user_perm = get_group_user_perm(self.user)
|
||||
try:
|
||||
print "进入批量下载模式"
|
||||
print "请输入主机名、IP或ansile支持的pattern, q退出"
|
||||
print "请输入主机名、IP或ansile支持的pattern, 多个主机:分隔,q退出"
|
||||
pattern = raw_input("\033[1;32mPattern>:\033[0m ").strip()
|
||||
if pattern == 'q':
|
||||
break
|
||||
|
|
|
@ -12,7 +12,11 @@ from ansible import utils
|
|||
from passlib.hash import sha512_crypt
|
||||
|
||||
from utils import get_rand_pass
|
||||
from jumpserver.api import logger
|
||||
|
||||
from tempfile import NamedTemporaryFile
|
||||
from django.template.loader import get_template
|
||||
from django.template import Context
|
||||
|
||||
import os.path
|
||||
|
||||
|
@ -138,6 +142,7 @@ class MyRunner(MyInventory):
|
|||
become_pass=become_pass
|
||||
)
|
||||
self.results_raw = hoc.run()
|
||||
logger.debug(self.results_raw)
|
||||
return self.results_raw
|
||||
|
||||
@property
|
||||
|
@ -353,14 +358,33 @@ class MyTask(MyRunner):
|
|||
|
||||
return self.results
|
||||
|
||||
def push_sudo_file(self, file_path):
|
||||
@staticmethod
|
||||
def gen_sudo_script(role_list, sudo_list):
|
||||
# receive role_list = [role1, role2] sudo_list = [sudo1, sudo2]
|
||||
# return sudo_alias={'NETWORK': '/sbin/ifconfig, /ls'} sudo_user={'user1': ['NETWORK', 'SYSTEM']}
|
||||
sudo_alias = {}
|
||||
sudo_user = {}
|
||||
for sudo in sudo_list:
|
||||
sudo_alias[sudo.name] = sudo.commands
|
||||
|
||||
for role in role_list:
|
||||
sudo_user[role.name] = ','.join(sudo_alias.keys())
|
||||
print sudo_alias, sudo_user
|
||||
|
||||
sudo_j2 = get_template('jperm/role_sudo.j2')
|
||||
sudo_content = sudo_j2.render(Context({"sudo_alias": sudo_alias, "sudo_user": sudo_user}))
|
||||
sudo_file = NamedTemporaryFile(delete=False)
|
||||
sudo_file.write(sudo_content)
|
||||
sudo_file.close()
|
||||
return sudo_file.name
|
||||
|
||||
def push_sudo_file(self, role_list, sudo_list):
|
||||
"""
|
||||
use template to render pushed sudoers file
|
||||
:return:
|
||||
"""
|
||||
module_args1 = file_path
|
||||
module_args1 = self.gen_sudo_script(role_list, sudo_list)
|
||||
self.run("script", module_args1, become=True)
|
||||
print self.results_raw
|
||||
return self.results
|
||||
|
||||
|
||||
|
|
|
@ -10,11 +10,8 @@ from uuid import uuid4
|
|||
from jumpserver.api import CRYPTOR
|
||||
from os import makedirs
|
||||
|
||||
from django.template.loader import get_template
|
||||
from django.template import Context
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
|
||||
from jumpserver.settings import KEY_DIR
|
||||
|
||||
|
||||
|
@ -72,45 +69,6 @@ def gen_keys(key="", key_path_dir=""):
|
|||
return key_path_dir
|
||||
|
||||
|
||||
def gen_sudo(role_custom, role_name, role_chosen):
|
||||
"""
|
||||
生成sudo file, 仅测试了cenos7
|
||||
role_custom: 自定义支持的sudo 命令 格式: 'CMD1, CMD2, CMD3, ...'
|
||||
role_name: role name
|
||||
role_chosen: 选择那些sudo的命令别名:
|
||||
NETWORKING, SOFTWARE, SERVICES, STORAGE,
|
||||
DELEGATING, PROCESSES, LOCATE, DRIVERS
|
||||
:return:
|
||||
"""
|
||||
sudo_file_basename = os.path.join(os.path.dirname(KEY_DIR), 'role_sudo_file')
|
||||
makedirs(sudo_file_basename)
|
||||
sudo_file_path = os.path.join(sudo_file_basename, role_name)
|
||||
|
||||
t = get_template('role_sudo.j2')
|
||||
content = t.render(Context({"role_custom": role_custom,
|
||||
"role_name": role_name,
|
||||
"role_chosen": role_chosen,
|
||||
}))
|
||||
with open(sudo_file_path, 'w') as f:
|
||||
f.write(content)
|
||||
return sudo_file_path
|
||||
|
||||
|
||||
def get_add_sudo_script(role_chosen_aliase, sudo_alias):
|
||||
"""
|
||||
get the sudo file
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
sudo_j2 = get_template('jperm/role_sudo.j2')
|
||||
sudo_content = sudo_j2.render(Context({"role_chosen_aliase": role_chosen_aliase,
|
||||
"sudo_alias": sudo_alias}))
|
||||
sudo_file = NamedTemporaryFile(delete=False)
|
||||
sudo_file.write(sudo_content)
|
||||
sudo_file.close()
|
||||
print(sudo_file.name)
|
||||
return sudo_file.name
|
||||
|
||||
if __name__ == "__main__":
|
||||
print gen_keys()
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ from jasset.models import Asset, AssetGroup
|
|||
from jperm.models import PermRole, PermRule, PermSudo, PermPush
|
||||
from jumpserver.models import Setting
|
||||
|
||||
from jperm.utils import updates_dict, gen_keys, get_rand_pass, get_add_sudo_script
|
||||
from jperm.utils import updates_dict, gen_keys, get_rand_pass
|
||||
from jperm.ansible_api import MyTask
|
||||
from jperm.perm_api import get_role_info, get_role_push_host
|
||||
from jumpserver.api import my_render, get_object, CRYPTOR
|
||||
|
@ -440,13 +440,8 @@ def perm_role_push(request):
|
|||
|
||||
# 3. 推送sudo配置文件
|
||||
if password_push or key_push:
|
||||
role_chosen_aliase = {} # {'dev': 'NETWORKING, SHUTDOWN'}
|
||||
sudo_alias = set([sudo for sudo in role.sudo.all()]) # set(sudo1, sudo2, sudo3)
|
||||
if sudo_alias:
|
||||
role_chosen_aliase[role.name] = ','.join(sudo.name for sudo in sudo_alias if sudo.name)
|
||||
add_sudo_script = get_add_sudo_script(role_chosen_aliase, sudo_alias)
|
||||
ret['sudo'] = task.push_sudo_file(add_sudo_script)
|
||||
os.remove(add_sudo_script)
|
||||
sudo_list = set([sudo for sudo in role.sudo.all()]) # set(sudo1, sudo2, sudo3)
|
||||
ret['sudo'] = task.push_sudo_file([role], sudo_list)
|
||||
|
||||
logger.debug('推送role结果: %s' % ret)
|
||||
success_asset = {}
|
||||
|
|
|
@ -88,8 +88,8 @@ def group_edit(request):
|
|||
|
||||
if request.method == 'GET':
|
||||
group_id = request.GET.get('id', '')
|
||||
# user_group = get_object(UserGroup, id=group_id)
|
||||
user_group = UserGroup.objects.get(id=group_id)
|
||||
user_group = get_object(UserGroup, id=group_id)
|
||||
# user_group = UserGroup.objects.get(id=group_id)
|
||||
users_selected = User.objects.filter(group=user_group)
|
||||
users_remain = User.objects.filter(~Q(group=user_group))
|
||||
users_all = User.objects.all()
|
||||
|
@ -118,7 +118,9 @@ def group_edit(request):
|
|||
if g == user_group:
|
||||
continue
|
||||
user.group.add(g)
|
||||
|
||||
user_group.name = group_name
|
||||
user_group.comment = comment
|
||||
user_group.save()
|
||||
except ServerError, e:
|
||||
error = e
|
||||
if not error:
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<form method="post" id="userForm" class="form-horizontal" action="">
|
||||
<form method="post" id="ruleForm" class="form-horizontal" action="">
|
||||
{% if error %}
|
||||
<div class="alert alert-warning text-center">{{ error }}</div>
|
||||
{% endif %}
|
||||
|
@ -34,27 +34,27 @@
|
|||
<div class="alert alert-success text-center">{{ msg }}</div>
|
||||
{% endif %}
|
||||
<div class="form-group">
|
||||
<label for="username_lab" class="col-sm-2 control-label">授权名称<span class="red-fonts">*</span></label>
|
||||
<label for="rulename" class="col-sm-2 control-label">授权名称<span class="red-fonts">*</span></label>
|
||||
<div class="col-sm-8">
|
||||
<input id="rule_name" name="rule_name" placeholder="RuleName" type="text" class="form-control" value="{{ rule.name }}">
|
||||
<input id="rulename" name="rulename" placeholder="Rule Name" type="text" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<label for="user" class="col-sm-2 control-label">用户<span class="red-fonts">*</span></label>
|
||||
<label for="user" class="col-sm-2 control-label">用户</label>
|
||||
<div class="col-sm-8">
|
||||
<select name="user" data-placeholder="用户名" class="chosen-select form-control m-b" multiple tabindex="2">
|
||||
<select name="user" id="user" data-placeholder="用户名" class="chosen-select form-control m-b" multiple tabindex="2">
|
||||
{% for user in users %}
|
||||
<option value="{{ user.id }}" {% if user in users_select %} selected {% endif %}>{{ user.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<span class="help-block m-b-none">用户和用户组必选一个</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<label for="usergroup" class="col-sm-2 control-label">用户组<span class="red-fonts">*</span></label>
|
||||
<label for="usergroup" class="col-sm-2 control-label">用户组</label>
|
||||
<div class="col-sm-8">
|
||||
<select name="usergroup" data-placeholder="请选择用户组" class="chosen-select form-control m-b" multiple tabindex="2">
|
||||
<select name="usergroup" id="usergroup" data-placeholder="请选择用户组" class="chosen-select form-control m-b" multiple tabindex="2">
|
||||
{% for user_group in user_groups %}
|
||||
<option value="{{ user_group.id }}"{% if user_group in user_groups_select %} selected {% endif %}>{{ user_group.name }}</option>
|
||||
{% endfor %}
|
||||
|
@ -63,18 +63,18 @@
|
|||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<label for="asset" class="col-sm-2 control-label">资产<span class="red-fonts">*</span></label>
|
||||
<label for="asset" class="col-sm-2 control-label">资产</label>
|
||||
<div class="col-sm-8">
|
||||
<select name="asset" data-placeholder="请选择资产" class="chosen-select form-control m-b" multiple tabindex="2">
|
||||
<select name="asset" id="asset" data-placeholder="请选择资产" class="chosen-select form-control m-b" multiple tabindex="2">
|
||||
{% for asset in assets %}
|
||||
<option value="{{ asset.id }}"{% if asset in assets_select %} selected {% endif %}>{{ asset.ip }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<span class="help-block m-b-none">资产和资产组必选一个</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<label for="assetgroup" class="col-sm-2 control-label">资产组<span class="red-fonts">*</span></label>
|
||||
<label for="assetgroup" id="assetgroup" class="col-sm-2 control-label">资产组</label>
|
||||
<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 %}
|
||||
|
@ -86,9 +86,9 @@
|
|||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<label for="role" class="col-sm-2 control-label">角色<span class="red-fonts">*</span></label>
|
||||
<div class="col-sm-8">
|
||||
<div class="col-sm-8" id="role_name">
|
||||
<select name="role" data-placeholder="请选择角色" class="chosen-select form-control m-b" multiple tabindex="2">
|
||||
{% for role in roles %}
|
||||
{% for role in roles %}
|
||||
<option value="{{ role.id }}"{% if role in roles_select %} selected {% endif %}>{{ role.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
@ -99,7 +99,7 @@
|
|||
<div class="form-group">
|
||||
<label for="comment" class="col-sm-2 control-label">备注</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="role_comment" name="role_comment" placeholder="Rule Comment" type="text" class="form-control" value="{{ rule_comment }}">
|
||||
<input id="rule_comment" name="rule_comment" placeholder="Rule Comment" type="text" class="form-control" value="{{ rule_comment }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
|
@ -118,6 +118,46 @@
|
|||
{% endblock %}
|
||||
{% block self_footer_js %}
|
||||
<script>
|
||||
$('#ruleForm').validator({
|
||||
timely: 2,
|
||||
theme: "yellow_right_effect",
|
||||
rules: {
|
||||
check_name: [/^\w{2,20}$/, '大小写字母数字和下划线,2-20位'],
|
||||
check_user: function(){
|
||||
return $('#user').val() == null
|
||||
},
|
||||
check_asset: function(){
|
||||
return $('#asset').val() == null
|
||||
}
|
||||
},
|
||||
|
||||
fields: {
|
||||
"rulename": {
|
||||
rule: "required;check_name",
|
||||
tip: "输入规则名称",
|
||||
msg: {required: "规则名称必填"}
|
||||
},
|
||||
"usergroup": {
|
||||
rule: "required(check_user)",
|
||||
tip: "请选择用户组",
|
||||
msg: {required: "用户和用户组必选一个!"}
|
||||
},
|
||||
"assetgroup": {
|
||||
rule: "required(check_asset)",
|
||||
tip: "输入资产组",
|
||||
msg: {required: "资产和资产组必选一个!"}
|
||||
},
|
||||
"role": {
|
||||
rule: "required",
|
||||
tip: "请选择角色",
|
||||
msg: {required: "必须选择角色"}
|
||||
}
|
||||
},
|
||||
valid: function(form) {
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var config = {
|
||||
'.chosen-select' : {},
|
||||
|
|
|
@ -7,11 +7,11 @@ tmp_file=$(mktemp /tmp/XXXXXXX)
|
|||
# Add Command Aliases
|
||||
add_cmd_alias() {
|
||||
sudo_file=$1
|
||||
{% for sudo in sudo_alias %}
|
||||
if $(grep '^Cmnd_Alias {{ sudo.name }}' ${sudo_file} &> /dev/null); then
|
||||
sed -i 's@^Cmnd_Alias.*{{ sudo.name }}.*@Cmnd_Alias {{ sudo.name }} = {{ sudo.commands }}@g' ${sudo_file}
|
||||
{% for sudo_name, sudo_cmd in sudo_alias.items %}
|
||||
if $(grep '^Cmnd_Alias {{ sudo_name }}' ${sudo_file} &> /dev/null); then
|
||||
sed -i 's@^Cmnd_Alias.*{{ sudo_name }}.*@Cmnd_Alias {{ sudo_name }} = {{ sudo_cmd }}@g' ${sudo_file}
|
||||
else
|
||||
echo "Cmnd_Alias {{ sudo.name }} = {{ sudo.commands }}" >> ${sudo_file}
|
||||
echo "Cmnd_Alias {{ sudo_name }} = {{ sudo_cmd }}" >> ${sudo_file}
|
||||
fi
|
||||
{% endfor %}
|
||||
}
|
||||
|
@ -19,11 +19,11 @@ add_cmd_alias() {
|
|||
|
||||
add_role_chosen() {
|
||||
sudo_file=$1
|
||||
{% for role, alias in role_chosen_aliase.items %}
|
||||
if $(grep '^{{ role }}.*' ${sudo_file} &> /dev/null); then
|
||||
sed -i 's@^{{ role }}.*@{{ role }} ALL = NOPASSWD: {{ alias }}@g' ${sudo_file}
|
||||
{% for user, alias in sudo_user.items %}
|
||||
if $(grep '^{{ user }}.*' ${sudo_file} &> /dev/null); then
|
||||
sed -i 's@^{{ user }}.*@{{ user }} ALL = (root) NOPASSWD: {{ alias }}@g' ${sudo_file}
|
||||
else
|
||||
echo "{{ role }} ALL = NOPASSWD: {{ alias }}" >> ${sudo_file}
|
||||
echo "{{ user }} ALL = (root) NOPASSWD: {{ alias }}" >> ${sudo_file}
|
||||
fi
|
||||
{% endfor %}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue