diff --git a/jperm/ansible_api.py b/jperm/ansible_api.py index ee7c2ddee..eaf2eb404 100644 --- a/jperm/ansible_api.py +++ b/jperm/ansible_api.py @@ -233,6 +233,7 @@ class Tasks(Command): ) self.results = hoc.run() + return {"msg": self.msg, "result": self.results} @property def msg(self): @@ -400,13 +401,29 @@ class Tasks(Command): return {"failed": self.msg, "ok": result} - def push_sudo(self, role_custo, role_name, role_chosen): + def push_sudo_file(self, file_path): """ use template to render pushed sudoers file :return: """ - module_args = 'src=%s dest=%s owner=root group=root mode=0440' % (username, encrypt_pass) - self.__run(module_args, "template") + module_args1 = 'src=%s dest=%s owner=root group=root mode=0440' % (file_path, '/etc/sudoers') + ret1 = self.__run(module_args1, "copy") + module_args2 = 'visudo -c | grep "parsed OK" &> /dev/null && echo "ok" || echo "failed"' + ret2 = self.__run(module_args2, "shell") + ret2_status = [host_value.get("stdout") for host_value in ret2["result"]["contacted"].values()] + + result = {} + if not ret1["msg"]: + result["step1"] = "ok" + else: + result["step1"] = "failed" + + if not ret2["msg"] and "failed" not in ret2_status: + result["step2"] = "ok" + else: + result["step2"] = "failed" + + return result class CustomAggregateStats(callbacks.AggregateStats): @@ -427,7 +444,6 @@ class CustomAggregateStats(callbacks.AggregateStats): self.results.append(runner_results) - def summarize(self, host): """ Return information about a particular host diff --git a/jperm/models.py b/jperm/models.py index 019411f9b..9fbbda50c 100644 --- a/jperm/models.py +++ b/jperm/models.py @@ -55,5 +55,13 @@ class PermRule(models.Model): return self.name +class PermPush(models.Model): + date_added = models.DateTimeField(auto_now=True) + asset = models.ManyToManyField(Asset, related_name='perm_push') + asset_group = models.ManyToManyField(AssetGroup, related_name='perm_push') + role = models.ManyToManyField(PermRole, related_name='perm_push') + is_public_key = models.BooleanField(default=False) + is_password = models.BooleanField(default=False) + diff --git a/jperm/utils.py b/jperm/utils.py index ea68488a8..450e7d13d 100644 --- a/jperm/utils.py +++ b/jperm/utils.py @@ -8,6 +8,7 @@ from os import chmod, makedirs from uuid import uuid4 from django.template.loader import get_template from django.template import Context +from tempfile import NamedTemporaryFile from jumpserver.settings import KEY_DIR @@ -88,6 +89,21 @@ def gen_sudo(role_custom, role_name, role_chosen): return sudo_file_path +def get_sudo_file(sudo_chosen_aliase, sudo_chosen_obj): + """ + 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_file = NamedTemporaryFile(delete=False) + sudo_file.write(sudo_content) + sudo_file.close() + + return sudo_file.name + if __name__ == "__main__": print gen_keys() diff --git a/jperm/views.py b/jperm/views.py index 7c4f59c82..8cf907a46 100644 --- a/jperm/views.py +++ b/jperm/views.py @@ -6,13 +6,12 @@ from jperm.models import PermLog as Log from jperm.models import SysUser 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, PermSudo +from jperm.models import PermRole, PermRule, PermSudo, PermPush from jumpserver.models import Setting -from jperm.utils import updates_dict, gen_keys, get_rand_pass +from jperm.utils import updates_dict, gen_keys, get_rand_pass, get_sudo_file from jperm.ansible_api import Tasks from jperm.perm_api import get_role_info @@ -448,24 +447,61 @@ def perm_role_push(request): key_push = request.POST.get("use_publicKey") task = Tasks(push_resource) ret = {} - ret_failed = [] + ret_failed = {} - # 因为要先建立用户,所以password 是必选项, - # 而push key是在 password也完成的情况下的 可选项 - ret["password_push"] = task.add_multi_user(**role_pass) - if ret["password_push"].get("status") != "success": - ret_failed.append(1) + # 因为要先建立用户,所以password 是必选项,而push key是在 password也完成的情况下的 可选项 + # 1. 以password 方式推送角色 + if password_push: + ret["password_push"] = task.add_multi_user(**role_pass) + if ret["password_push"].get("status") != "success": + ret_failed["step1"] == "failed" + # 2. 以秘钥 方式推送角色 if key_push: + ret["password_push"] = task.add_multi_user(**role_pass) + if ret["password_push"].get("status") != "success": + ret_failed["step2-1"] == "failed" ret["key_push"] = task.push_multi_key(**role_key) if ret["key_push"].get("status") != "success": - ret_failed.append(1) + ret_failed["step2-2"] == "failed" - print ret + # 3. 推送sudo配置文件 + sudo_chosen_aliase = {} + sudo_alias = [] + 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)] + sudo_file = get_sudo_file(sudo_chosen_aliase, sudo_chosen_obj) + ret_sudo = task.push_sudo_file(sudo_file) + if ret_sudo["step1"] != "ok" and ret_sudo["step2"] != "ok": + ret_failed["step3"] == "failed" + + # 结果汇总统计 if ret_failed: - return HttpResponse(u"推送失败") + # 推送失败 + msg = u"推送失败, 原因: %s 失败" % ','.join(ret_failed.keys()) else: - return HttpResponse(u"推送系统角色: %s" % ','.join(role_names)) + # 推送成功 写会push表 + msg = u"推送系统角色: %s" % ','.join(role_names) + push = PermPush(is_public_key=bool(key_push), is_password=bool(password_push)) + push.save() + push.asset_group = asset_groups_obj + push.asset = calc_assets + 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) @require_role('admin') diff --git a/templates/jperm/perm_role_push.html b/templates/jperm/perm_role_push.html index 91a4c7a0d..933dcb71c 100644 --- a/templates/jperm/perm_role_push.html +++ b/templates/jperm/perm_role_push.html @@ -77,6 +77,16 @@ +