Commit 39a0350e authored by yumaojun's avatar yumaojun

1. 完成Sudo 规则的 角色授权

2. 角色详情里面 新增 推送详情
3. 角色推送 支持计算与叠加
parent 951467f8
...@@ -406,8 +406,8 @@ class Tasks(Command): ...@@ -406,8 +406,8 @@ class Tasks(Command):
use template to render pushed sudoers file use template to render pushed sudoers file
:return: :return:
""" """
module_args1 = 'src=%s dest=%s owner=root group=root mode=0440' % (file_path, '/etc/sudoers') module_args1 = 'test'
ret1 = self.__run(module_args1, "copy") ret1 = self.__run(module_args1, "script")
module_args2 = 'visudo -c | grep "parsed OK" &> /dev/null && echo "ok" || echo "failed"' module_args2 = 'visudo -c | grep "parsed OK" &> /dev/null && echo "ok" || echo "failed"'
ret2 = self.__run(module_args2, "shell") ret2 = self.__run(module_args2, "shell")
ret2_status = [host_value.get("stdout") for host_value in ret2["result"]["contacted"].values()] ret2_status = [host_value.get("stdout") for host_value in ret2["result"]["contacted"].values()]
......
...@@ -337,6 +337,40 @@ def get_role_info(role_id, type="all"): ...@@ -337,6 +337,40 @@ def get_role_info(role_id, type="all"):
return u"不支持的查询" return u"不支持的查询"
def get_role_push_host(role):
"""
get the role push host
:return: the asset object
"""
# 计算该role 所有push记录 总共推送的主机
assets = []
asset_groups = []
for push in role.perm_push.all():
assets.extend(push.asset.all())
asset_groups.extend(push.asset_group.all())
group_assets = []
for asset_group in asset_groups:
group_assets.extend(asset_group.asset_set.all())
cacl_assets = set(assets) | set(group_assets)
# 计算所有主机 在push记录里面的 使用密码和使用秘钥状况
result = []
for asset in cacl_assets:
all_push = asset.perm_push.all()
if True in [push.is_password for push in all_push if role in push.role.all()]:
is_password = u"是"
else:
is_password = u"否"
if True in [push.is_public_key for push in all_push if role in push.role.all()]:
is_public_key = u"是"
else:
is_public_key = u"否"
result.append({"ip": asset.ip,
"group": ','.join([group.name for group in asset.group.all()]),
"password": is_password,
"pubkey": is_public_key})
return result
if __name__ == "__main__": if __name__ == "__main__":
print get_role_info(1) print get_role_info(1)
......
...@@ -89,7 +89,7 @@ def gen_sudo(role_custom, role_name, role_chosen): ...@@ -89,7 +89,7 @@ def gen_sudo(role_custom, role_name, role_chosen):
return sudo_file_path return sudo_file_path
def get_sudo_file(sudo_chosen_aliase, sudo_chosen_obj): def get_add_sudo_script(sudo_chosen_aliase, sudo_chosen_obj):
""" """
get the sudo file get the sudo file
:param kwargs: :param kwargs:
......
...@@ -11,9 +11,9 @@ from jasset.models import Asset, AssetGroup ...@@ -11,9 +11,9 @@ from jasset.models import Asset, AssetGroup
from jperm.models import PermRole, PermRule, PermSudo, PermPush from jperm.models import PermRole, PermRule, PermSudo, PermPush
from jumpserver.models import Setting from jumpserver.models import Setting
from jperm.utils import updates_dict, gen_keys, get_rand_pass, get_sudo_file from jperm.utils import updates_dict, gen_keys, get_rand_pass, get_add_sudo_script
from jperm.ansible_api import Tasks from jperm.ansible_api import Tasks
from jperm.perm_api import get_role_info from jperm.perm_api import get_role_info, get_role_push_host
from jumpserver.api import my_render, get_object, CRYPTOR from jumpserver.api import my_render, get_object, CRYPTOR
...@@ -338,6 +338,7 @@ def perm_role_detail(request): ...@@ -338,6 +338,7 @@ def perm_role_detail(request):
asset_groups = role_info.get("asset_groups") asset_groups = role_info.get("asset_groups")
users = role_info.get("users") users = role_info.get("users")
user_groups = role_info.get("user_groups") user_groups = role_info.get("user_groups")
push_info = get_role_push_host(PermRole.objects.get(id=role_id))
return my_render('jperm/perm_role_detail.html', locals(), request) return my_render('jperm/perm_role_detail.html', locals(), request)
...@@ -460,10 +461,10 @@ def perm_role_push(request): ...@@ -460,10 +461,10 @@ def perm_role_push(request):
if key_push: if key_push:
ret["password_push"] = task.add_multi_user(**role_pass) ret["password_push"] = task.add_multi_user(**role_pass)
if ret["password_push"].get("status") != "success": if ret["password_push"].get("status") != "success":
ret_failed["step2-1"] == "failed" ret_failed["step2-1"] = "failed"
ret["key_push"] = task.push_multi_key(**role_key) ret["key_push"] = task.push_multi_key(**role_key)
if ret["key_push"].get("status") != "success": if ret["key_push"].get("status") != "success":
ret_failed["step2-2"] == "failed" ret_failed["step2-2"] = "failed"
# 3. 推送sudo配置文件 # 3. 推送sudo配置文件
sudo_chosen_aliase = {} sudo_chosen_aliase = {}
...@@ -473,17 +474,21 @@ def perm_role_push(request): ...@@ -473,17 +474,21 @@ def perm_role_push(request):
sudo_alias.extend(role_alias) sudo_alias.extend(role_alias)
sudo_chosen_aliase[role.name] = ','.join(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)] sudo_chosen_obj = [PermSudo.objects.get(name=sudo_name) for sudo_name in set(sudo_alias)]
sudo_file = get_sudo_file(sudo_chosen_aliase, sudo_chosen_obj)
ret_sudo = task.push_sudo_file(sudo_file) add_sudo_script = get_add_sudo_script(sudo_chosen_aliase, sudo_chosen_obj)
if ret_sudo["step1"] != "ok" and ret_sudo["step2"] != "ok": ret_sudo = task.push_sudo_file(add_sudo_script)
ret_failed["step3"] == "failed"
if ret_sudo["step1"] != "ok" or ret_sudo["step2"] != "ok":
ret_failed["step3"] = "failed"
os.remove(add_sudo_script)
# 结果汇总统计 # 结果汇总统计
if ret_failed: if ret_failed:
# 推送失败 # 推送失败
msg = u"推送失败, 原因: %s 失败" % ','.join(ret_failed.keys()) error = u"推送失败, 原因: %s 失败" % ','.join(ret_failed.keys())
else: else:
# 推送成功 写会push表 # 推送成功 回写push表
msg = u"推送系统角色: %s" % ','.join(role_names) msg = u"推送系统角色: %s" % ','.join(role_names)
push = PermPush(is_public_key=bool(key_push), is_password=bool(password_push)) push = PermPush(is_public_key=bool(key_push), is_password=bool(password_push))
push.save() push.save()
...@@ -546,7 +551,7 @@ def perm_sudo_add(request): ...@@ -546,7 +551,7 @@ def perm_sudo_add(request):
comment = request.POST.get("sudo_comment") comment = request.POST.get("sudo_comment")
commands = request.POST.get("sudo_commands") commands = request.POST.get("sudo_commands")
sudo = PermSudo(name=name, comment=comment, commands=commands) sudo = PermSudo(name=name.strip(), comment=comment, commands=commands.strip())
sudo.save() sudo.save()
msg = u"添加Sudo命令别名: %s" % name msg = u"添加Sudo命令别名: %s" % name
...@@ -586,8 +591,8 @@ def perm_sudo_edit(request): ...@@ -586,8 +591,8 @@ def perm_sudo_edit(request):
name = request.POST.get("sudo_name") name = request.POST.get("sudo_name")
commands = request.POST.get("sudo_commands") commands = request.POST.get("sudo_commands")
comment = request.POST.get("sudo_comment") comment = request.POST.get("sudo_comment")
sudo.name = name sudo.name = name.strip()
sudo.commands = commands sudo.commands = commands.strip()
sudo.comment = comment sudo.comment = comment
sudo.save() sudo.save()
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
{% block content %} {% block content %}
{% include 'nav_cat_bar.html' %} {% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight"> <div class="wrapper wrapper-content animated fadeInRight">
<div class="row"> <div class="row">
<div class="col-lg-4"> <div class="col-lg-4">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
...@@ -51,8 +50,8 @@ ...@@ -51,8 +50,8 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-lg-4"> <div class="col-lg-4">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
...@@ -97,8 +96,8 @@ ...@@ -97,8 +96,8 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-lg-4"> <div class="col-lg-4">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
...@@ -143,8 +142,60 @@ ...@@ -143,8 +142,60 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label label-primary"><b>推送主机</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#"></a>
</li>
<li><a href="#"></a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div> </div>
<div class="ibox-content">
<div>
<div class="text-left">
<table class="table table-striped" id="ugedit" >
<thead>
<tr>
<th class="text-center">主机</th>
<th class="text-center">主机组</th>
<th class="text-center">使用密码</th>
<th class="text-center">使用秘钥</th>
</tr>
</thead>
<tbody>
{% for host in push_info %}
<tr class="gradeX">
<td class="text-center"> {{ host.ip }} </td>
<td class="text-center"> {{ host.group }} </td>
<td class="text-center"> {{ host.password }} </td>
<td class="text-center"> {{ host.pubkey }} </td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div> </div>
</div>
</div>
</div> </div>
</div> </div>
......
## Sudoers allows particular users to run various commands as #!/bin/bash
## the root user, without needing the root password.
##
## Examples are provided at the bottom of the file for collections
## of related commands, which can then be delegated out to particular
## users or groups.
##
## This file must be edited with the 'visudo' command.
## Host Aliases
## Groups of machines. You may prefer to use hostnames (perhaps using
## wildcards for entire domains) or IP addresses instead.
# Host_Alias FILESERVERS = fs1, fs2
# Host_Alias MAILSERVERS = smtp, smtp2
## User Aliases sudo_file=/etc/sudoers
## These aren't often necessary, as you can use regular groups
## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname
## rather than USERALIAS
# User_Alias ADMINS = jsmith, mikem
## Command Aliases # Add Command Aliases
## These are groups of related commands... add_cmd_alias() {
{% for sudo in sudo_chosen_obj %}
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
echo "Cmnd_Alias {{ sudo.name }} = {{ sudo.commands }}" >> ${sudo_file}
fi
{% endfor %}
}
{% for sudo in sudo_chosen_obj %}
Cmnd_Alias {{ sudo.name }} = {{ sudo.commands }}
{% endfor %}
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
{% endfor %}
}
add_cmd_alias
add_role_chosen
# Defaults specification \ No newline at end of file
#
# Disable "ssh hostname sudo <cmd>", because it will show the password in clear.
# You have to run "ssh -t hostname sudo <cmd>".
#
Defaults requiretty
#
# Refuse to run if unable to disable echo on the tty. This setting should also be
# changed in order to be able to use sudo without a tty. See requiretty above.
#
Defaults !visiblepw
#
# Preserving HOME has security implications since many programs
# use it when searching for configuration files. Note that HOME
# is already set when the the env_reset option is enabled, so
# this option is only effective for configurations where either
# env_reset is disabled or HOME is present in the env_keep list.
#
Defaults always_set_home
Defaults env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
#
# Adding HOME to env_keep may enable a user to run unrestricted
# commands via sudo.
#
# Defaults env_keep += "HOME"
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
## Syntax:
##
## user MACHINE=COMMANDS
##
## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
{% for role, alias in sudo_chosen_aliase.items %}
{{ role }} ALL = {{ alias }}
{% endfor %}
## Allows members of the 'sys' group to run networking, software,
## service management apps and more.
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS
## Allows people in group wheel to run all commands
%wheel ALL=(ALL) ALL
## Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: ALL
## Allows members of the users group to mount and unmount the
## cdrom as root
# %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom
## Allows members of the users group to shutdown this system
# %users localhost=/sbin/shutdown -h now
## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)
#includedir /etc/sudoers.d
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment