sudo添加runas

pull/26/head
ibuler 2015-11-29 15:18:05 +08:00
parent 98f0655da4
commit 29e1090d2c
8 changed files with 91 additions and 93 deletions

View File

@ -326,7 +326,7 @@ class Tasks(Command):
module_args = 'name=%s shell=/bin/bash password=%s' % (username, encrypt_pass)
self.__run(module_args, "user")
return {"status": "failed","msg": self.msg} if self.msg else {"status": "ok"}
return {"status": "failed", "msg": self.msg} if self.msg else {"status": "ok"}
def add_multi_user(self, **user_info):
"""
@ -438,7 +438,7 @@ class Tasks(Command):
use template to render pushed sudoers file
:return:
"""
module_args1 = 'test'
module_args1 = file_path
ret1 = self.__run(module_args1, "script")
module_args2 = 'visudo -c | grep "parsed OK" &> /dev/null && echo "ok" || echo "failed"'
ret2 = self.__run(module_args2, "shell")
@ -457,6 +457,7 @@ class Tasks(Command):
return result
class CustomAggregateStats(callbacks.AggregateStats):
"""
Holds stats about per-host activity during playbook runs.

View File

@ -22,6 +22,7 @@ class SysUser(models.Model):
class PermSudo(models.Model):
name = models.CharField(max_length=100, unique=True)
date_added = models.DateTimeField(auto_now=True)
runas = models.CharField(max_length=200, default='root')
commands = models.TextField()
comment = models.CharField(max_length=100, null=True, blank=True, default='')

View File

@ -96,23 +96,21 @@ def gen_sudo(role_custom, role_name, role_chosen):
return sudo_file_path
def get_add_sudo_script(sudo_chosen_aliase, sudo_chosen_obj):
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({"sudo_chosen_aliase": sudo_chosen_aliase,
"sudo_chosen_obj": sudo_chosen_obj}))
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()

View File

@ -376,7 +376,6 @@ def perm_role_edit(request):
return my_render('jperm/perm_role_edit.html', locals(), request)
@require_role('admin')
def perm_role_push(request):
"""
@ -385,23 +384,19 @@ def perm_role_push(request):
# 渲染数据
header_title, path1, path2 = "系统角色", "角色管理", "角色推送"
if request.method == "GET":
# 渲染数据
roles = PermRole.objects.all()
assets = Asset.objects.all()
asset_groups = AssetGroup.objects.all()
return my_render('jperm/perm_role_push.html', locals(), request)
roles = PermRole.objects.all()
assets = Asset.objects.all()
asset_groups = AssetGroup.objects.all()
if request.method == "POST":
# 获取推荐角色的名称列表
role_names = request.POST.getlist("roles")
role_ids = request.POST.getlist("roles")
# 计算出需要推送的资产列表
asset_ips = request.POST.getlist("assets")
asset_group_names = request.POST.getlist("asset_groups")
assets_obj = [Asset.objects.get(ip=asset_ip) for asset_ip in asset_ips]
asset_groups_obj = [AssetGroup.objects.get(name=asset_group_name) for asset_group_name in asset_group_names]
asset_ids = request.POST.getlist("assets")
asset_group_ids = request.POST.getlist("asset_groups")
assets_obj = [Asset.objects.get(id=asset_id) for asset_id in asset_ids]
asset_groups_obj = [AssetGroup.objects.get(id=asset_group_id) for asset_group_id in asset_group_ids]
group_assets_obj = []
for asset_group in asset_groups_obj:
group_assets_obj.extend(asset_group.asset_set.all())
@ -423,10 +418,9 @@ def perm_role_push(request):
# "username": username,
# "password": password})
push_resource = gen_resource(calc_assets)
print push_resource
# 获取角色的推送方式,以及推送需要的信息
roles_obj = [PermRole.objects.get(name=role_name) for role_name in role_names]
roles_obj = [PermRole.objects.get(id=role_id) for role_id in role_ids]
role_pass = {}
role_key = {}
for role in roles_obj:
@ -457,31 +451,28 @@ def perm_role_push(request):
ret_failed["step2-2"] = "failed"
# 3. 推送sudo配置文件
sudo_chosen_aliase = {}
sudo_alias = []
role_chosen_aliase = {} # {'dev': [sudo1, sudo2], 'sa': [sudo2, sudo3]}
sudo_alias = set() # set(sudo1, sudo2, sudo3)
for role in roles_obj:
role_alias = [sudo.name for sudo in role.sudo.all()]
sudo_alias.extend(role_alias)
sudo_chosen_aliase[role.name] = ','.join(role_alias)
sudo_chosen_obj = [PermSudo.objects.get(name=sudo_name) for sudo_name in set(sudo_alias)]
add_sudo_script = get_add_sudo_script(sudo_chosen_aliase, sudo_chosen_obj)
sudos = set([sudo for sudo in role.sudo.all()])
sudo_alias.update(sudos)
role_chosen_aliase[role.name] = sudos
add_sudo_script = get_add_sudo_script(role_chosen_aliase, sudo_alias)
ret_sudo = task.push_sudo_file(add_sudo_script)
if ret_sudo["step1"] != "ok" or ret_sudo["step2"] != "ok":
ret_failed["step3"] = "failed"
# os.remove(add_sudo_script)
os.remove(add_sudo_script)
print ret
# 结果汇总统计
if ret_failed:
# 推送失败
error = u"推送失败, 原因: %s 失败" % ','.join(ret_failed.keys())
else:
# 推送成功 回写push表
msg = u"推送系统角色: %s" % ','.join(role_names)
msg = u"推送系统角色: %s" % ','.join(role_chosen_aliase.keys())
push = PermPush(is_public_key=bool(key_push), is_password=bool(password_push))
push.save()
push.asset_group = asset_groups_obj
@ -489,16 +480,7 @@ def perm_role_push(request):
push.role = roles_obj
push.save()
# 渲染 刷新数据
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)
return my_render('jperm/perm_role_push.html', locals(), request)
@require_role('admin')
@ -534,34 +516,22 @@ def perm_sudo_add(request):
# 渲染数据
header_title, path1, path2 = "Sudo命令", "别名管理", "添加别名"
if request.method == "GET":
return my_render('jperm/perm_sudo_add.html', locals(), request)
elif request.method == "POST":
if request.method == "POST":
# 获取参数: name, comment
name = request.POST.get("sudo_name")
comment = request.POST.get("sudo_comment")
commands = request.POST.get("sudo_commands")
name = request.POST.get("sudo_name").strip()
runas = request.POST.get('sudo_runas', 'root').strip()
comment = request.POST.get("sudo_comment").strip()
commands = request.POST.get("sudo_commands").strip()
sudo = PermSudo(name=name.strip(), comment=comment, commands=commands.strip())
sudo.save()
msg = u"添加Sudo命令别名: %s" % name
if get_object(PermSudo, name=name):
error = 'Sudo别名 %s已经存在' % name
else:
sudo = PermSudo(name=name.strip(), runas=runas, comment=comment, commands=commands.strip())
sudo.save()
msg = u"添加Sudo命令别名: %s" % name
# 渲染数据
header_title, path1, path2 = "Sudo命令", "别名管理", "查看别名"
# 获取所有sudo 命令别名
sudos_list = PermSudo.objects.all()
# TODO: 搜索和分页
keyword = request.GET.get('search', '')
if keyword:
roles_list = sudos_list.filter(Q(name=keyword))
sudos_list, p, sudos, page_range, current_page, show_first, show_end = pages(sudos_list, request)
return my_render('jperm/perm_sudo_list.html', locals(), request)
else:
return HttpResponse(u"不支持该操作")
return my_render('jperm/perm_sudo_add.html', locals(), request)
@require_role('admin')
@ -576,29 +546,21 @@ def perm_sudo_edit(request):
sudo_id = request.GET.get("id")
sudo = PermSudo.objects.get(id=sudo_id)
if request.method == "GET":
return my_render('jperm/perm_sudo_edit.html', locals(), request)
if request.method == "POST":
name = request.POST.get("sudo_name")
commands = request.POST.get("sudo_commands")
runas = request.POST.get('sudo_runas', 'root')
comment = request.POST.get("sudo_comment")
sudo.name = name.strip()
sudo.commands = commands.strip()
sudo.runas = runas.strip()
sudo.comment = comment
sudo.save()
msg = u"更新命令别名: %s" % name
# 渲染数据
header_title, path1, path2 = "Sudo命令", "别名管理", "查看别名"
# 获取所有sudo 命令别名
sudos_list = PermSudo.objects.all()
# TODO: 搜索和分页
keyword = request.GET.get('search', '')
if keyword:
sudos_list = sudos_list.filter(Q(name=keyword))
sudos_list, p, sudos, page_range, current_page, show_first, show_end = pages(sudos_list, request)
return my_render('jperm/perm_sudo_list.html', locals(), request)
return my_render('jperm/perm_sudo_edit.html', locals(), request)
@require_role('admin')

View File

@ -38,7 +38,7 @@
<div class="col-sm-8">
<select name="assets" id="assets" 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.id }}">{{ asset.ip }}</option>
{% endfor %}
</select>
</div>
@ -49,7 +49,7 @@
<div class="col-sm-8">
<select name="asset_groups" 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.id }}">{{ asset_group.name }}</option>
{% endfor %}
</select>
</div>
@ -60,7 +60,7 @@
<div class="col-sm-8">
<select name="roles" 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.id }}">{{ role.name }}</option>
{% endfor %}
</select>
</div>
@ -124,13 +124,11 @@ $('#pushForm').validator({
"asset_groups": {
rule: "required(check_asset)",
tip: "输入资产组",
ok: "",
msg: {required: "资产和资产组必选一个!"}
},
"roles": {
rule: "required",
tip: "请选择角色",
ok: "",
msg: {required: "必须选择角色"}
}
},

View File

@ -36,9 +36,17 @@
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="sudo_commands_label" class="col-sm-2 control-label">系统命令<span class="red-fonts">*</span></label>
<label for="sudo_runas" class="col-sm-2 control-label">RunAs<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<textarea id="sudo_commands" name="sudo_commands" class="form-control" rows="3"></textarea>
<input id="sudo_runas" name="sudo_runas" placeholder="Sudo RunAs User" type="text" class="form-control">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="sudo_commands" class="col-sm-2 control-label">系统命令<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<textarea id="sudo_commands" name="sudo_commands" class="form-control" rows="3" placeholder="/bin/grep, /bin/find"></textarea>
<span class="help-block m-b-none">sudo命令逗号分隔, 不支持换行</span>
</div>
</div>
<div class="hr-line-dashed"></div>
@ -64,7 +72,28 @@
{% endblock %}
{% block self_footer_js %}
<script>
$('#sudoForm').validator({
timely: 2,
theme: "yellow_right_effect",
rules: {
check_name: [/^\w{2,20}$/, '大小写字母数字和下划线,2-20位']
},
fields: {
"sudo_name": {
rule: "required;check_name"
},
"sudo_runas": {
rule: "required;check_name"
},
"sudo_commands": {
rule: "required"
}
},
valid: function(form) {
form.submit();
}
});
</script>
{% endblock %}

View File

@ -40,6 +40,13 @@
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="sudo_runas" class="col-sm-2 control-label">RunAs<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<input id="sudo_runas" name="sudo_runas" placeholder="Sudo RunAs User" type="text" class="form-control" value="{{ sudo.runas }}">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="sudo_commands_label" class="col-sm-2 control-label">系统命令<span class="red-fonts">*</span></label>
<div class="col-sm-8">

View File

@ -6,7 +6,7 @@ sudo_file=/etc/sudoers
# Add Command Aliases
add_cmd_alias() {
{% for sudo in sudo_chosen_obj %}
{% 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}
else
@ -17,12 +17,14 @@ add_cmd_alias() {
add_role_chosen() {
{% for role, alias in sudo_chosen_aliase.items %}
if $(grep '^{{ role }}' ${sudo_file} &> /dev/null); then
sed -i 's@^{{ role }}.*@{{ role }} ALL = {{ alias }}@g' ${sudo_file}
else
echo "{{ role }} ALL = {{ alias }}" >> ${sudo_file}
fi
{% for role, sudos in role_chosen_aliase.items %}
{% for sudo in sudos %}
if $(grep '^{{ role }}.*sudo.name' ${sudo_file} &> /dev/null); then
sed -i 's@^{{ role }}.*sudo.name@{{ role }} ALL = ({{ sudo.runas }}) NOPASSWD: {{ sudo.name }}@g' ${sudo_file}
else
echo "{{ role }} ALL = ({{ sudo.runas }}) NOPASSWD: {{ sudo.name }}" >> ${sudo_file}
fi
{% endfor %}
{% endfor %}
}