From 2d91f1ab3866914ac905ae389940b8311017fb88 Mon Sep 17 00:00:00 2001 From: ibuler Date: Sun, 29 Nov 2015 16:38:40 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jperm/perm_api.py | 4 +++- jperm/views.py | 15 +++++++++++++-- templates/jperm/perm_rule_add.html | 4 ---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/jperm/perm_api.py b/jperm/perm_api.py index f2f6e903e..4ebfc7d3f 100644 --- a/jperm/perm_api.py +++ b/jperm/perm_api.py @@ -266,7 +266,7 @@ def get_role_info(role_id, type="all"): return u"不支持的查询" -def get_role_push_host(role): +def get_role_push_host(role, raw=False): """ get the role push host :return: the asset object @@ -282,6 +282,8 @@ def get_role_push_host(role): group_assets.extend(asset_group.asset_set.all()) cacl_assets = set(assets) | set(group_assets) + if raw: + return {'asset': cacl_assets, 'asset_group': set(asset_groups)} # 计算所有主机 在push记录里面的 使用密码和使用秘钥状况 result = [] for asset in cacl_assets: diff --git a/jperm/views.py b/jperm/views.py index 0275848d5..4e4756749 100644 --- a/jperm/views.py +++ b/jperm/views.py @@ -106,6 +106,19 @@ def perm_rule_add(request): # 获取授予的角色列表 roles_obj = [PermRole.objects.get(id=role_id) for role_id in roles_select] + for role in roles_obj: + push_assets_or_group = get_role_push_host(role=role, raw=True) + push_assets = push_assets_or_group.get('asset') + push_asset_groups = push_assets_or_group.get('asset_group') + no_push_assets = set(assets_obj) - set(push_assets) + no_push_asset_groups = set(asset_groups_obj) - set(push_asset_groups) + if no_push_assets: + raise ServerError(u'没有推送角色 %s 的主机 %s' + % (role.name, ','.join([asset.hostname for asset in no_push_assets]))) + elif no_push_asset_groups: + raise ServerError(u'没有推送角色 %s 的主机组 %s' + % (role.name, ','.join(asset_group.name for asset_group in no_push_asset_groups))) + # 仅授权成功的,写回数据库(授权规则,用户,用户组,资产,资产组,用户角色) rule = PermRule(name=rule_name, comment=rule_comment) rule.save() @@ -117,7 +130,6 @@ def perm_rule_add(request): rule.save() msg = u"添加授权规则:%s" % rule.name - # 渲染数据 return HttpResponseRedirect('/jperm/rule/') except ServerError, e: error = e @@ -465,7 +477,6 @@ def perm_role_push(request): os.remove(add_sudo_script) print ret - # 结果汇总统计 if ret_failed: # 推送失败 diff --git a/templates/jperm/perm_rule_add.html b/templates/jperm/perm_rule_add.html index 5133a955d..cf33cbb97 100644 --- a/templates/jperm/perm_rule_add.html +++ b/templates/jperm/perm_rule_add.html @@ -136,25 +136,21 @@ $('#ruleForm').validator({ "rulename": { rule: "required;check_name", tip: "输入规则名称", - ok: "", msg: {required: "规则名称必填"} }, "usergroup": { rule: "required(check_user)", tip: "请选择用户组", - ok: "", msg: {required: "用户和用户组必选一个!"} }, "assetgroup": { rule: "required(check_asset)", tip: "输入资产组", - ok: "", msg: {required: "资产和资产组必选一个!"} }, "role": { rule: "required", tip: "请选择角色", - ok: "", msg: {required: "必须选择角色"} } }, From 52c4395b68d9f14375a00ed8d9ca6c4c9006aa05 Mon Sep 17 00:00:00 2001 From: ibuler Date: Sun, 29 Nov 2015 16:56:39 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=8E=BB=E6=8E=89runas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jperm/models.py | 1 - jperm/views.py | 9 +++------ jumpserver.conf | 2 +- templates/jperm/perm_sudo_add.html | 7 ------- templates/jperm/perm_sudo_edit.html | 7 ------- templates/jperm/role_sudo.j2 | 10 ++++------ 6 files changed, 8 insertions(+), 28 deletions(-) diff --git a/jperm/models.py b/jperm/models.py index 09cdab7de..d8c0052fd 100644 --- a/jperm/models.py +++ b/jperm/models.py @@ -22,7 +22,6 @@ 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='') diff --git a/jperm/views.py b/jperm/views.py index d99527f9b..ba4f993f2 100644 --- a/jperm/views.py +++ b/jperm/views.py @@ -466,12 +466,12 @@ def perm_role_push(request): ret_failed["step2-2"] = "failed" # 3. 推送sudo配置文件 - role_chosen_aliase = {} # {'dev': [sudo1, sudo2], 'sa': [sudo2, sudo3]} + role_chosen_aliase = {} # {'dev': 'NETWORKING, SHUTDOWN', 'sa': 'NETWORKING, SHUTDOWN'} sudo_alias = set() # set(sudo1, sudo2, sudo3) for role in roles_obj: sudos = set([sudo for sudo in role.sudo.all()]) sudo_alias.update(sudos) - role_chosen_aliase[role.name] = sudos + role_chosen_aliase[role.name] = ','.join(sudo.name for sudo in sudos) add_sudo_script = get_add_sudo_script(role_chosen_aliase, sudo_alias) ret_sudo = task.push_sudo_file(add_sudo_script) @@ -533,14 +533,13 @@ def perm_sudo_add(request): if request.method == "POST": # 获取参数: name, comment 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() if get_object(PermSudo, name=name): error = 'Sudo别名 %s已经存在' % name else: - sudo = PermSudo(name=name.strip(), runas=runas, comment=comment, commands=commands.strip()) + sudo = PermSudo(name=name.strip(), comment=comment, commands=commands.strip()) sudo.save() msg = u"添加Sudo命令别名: %s" % name # 渲染数据 @@ -564,11 +563,9 @@ def perm_sudo_edit(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() diff --git a/jumpserver.conf b/jumpserver.conf index ac9506672..6297ab00a 100644 --- a/jumpserver.conf +++ b/jumpserver.conf @@ -9,7 +9,7 @@ log = debug host = 127.0.0.1 port = 3306 user = jumpserver -password = mysql1234 +password = mysql234 database = jumpserver [websocket] diff --git a/templates/jperm/perm_sudo_add.html b/templates/jperm/perm_sudo_add.html index 65f77488c..e46890cbb 100644 --- a/templates/jperm/perm_sudo_add.html +++ b/templates/jperm/perm_sudo_add.html @@ -35,13 +35,6 @@
-
- -
- -
-
-
diff --git a/templates/jperm/perm_sudo_edit.html b/templates/jperm/perm_sudo_edit.html index bec54e0bf..42621b93a 100644 --- a/templates/jperm/perm_sudo_edit.html +++ b/templates/jperm/perm_sudo_edit.html @@ -40,13 +40,6 @@
-
- -
- -
-
-
diff --git a/templates/jperm/role_sudo.j2 b/templates/jperm/role_sudo.j2 index 1304cb690..fc54ec03c 100644 --- a/templates/jperm/role_sudo.j2 +++ b/templates/jperm/role_sudo.j2 @@ -17,14 +17,12 @@ add_cmd_alias() { add_role_chosen() { - {% 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} + {% 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} else - echo "{{ role }} ALL = ({{ sudo.runas }}) NOPASSWD: {{ sudo.name }}" >> ${sudo_file} + echo "{{ role }} ALL = NOPASSWD: {{ alias }}" >> ${sudo_file} fi - {% endfor %} {% endfor %} } From 8dd4a9fce15d0f288f91e2dac011dad036f82c79 Mon Sep 17 00:00:00 2001 From: ibuler Date: Sun, 29 Nov 2015 19:02:13 +0800 Subject: [PATCH 3/4] =?UTF-8?q?push=20role=20=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jperm/ansible_api.py | 13 +++++--- jperm/models.py | 4 ++- jperm/urls.py | 2 +- jperm/views.py | 50 +++++++++++++---------------- jumpserver/templatetags/mytags.py | 15 ++++++++- juser/views.py | 4 +-- templates/jasset/asset_add.html | 3 +- templates/jperm/perm_role_list.html | 5 ++- templates/jperm/perm_role_push.html | 19 +++++------ templates/jperm/perm_sudo_list.html | 1 - templates/juser/user_add.html | 2 +- templates/setting.html | 14 ++++---- 12 files changed, 70 insertions(+), 62 deletions(-) diff --git a/jperm/ansible_api.py b/jperm/ansible_api.py index 5ce5fe35f..1de8ef609 100644 --- a/jperm/ansible_api.py +++ b/jperm/ansible_api.py @@ -284,10 +284,10 @@ class Tasks(Command): """ push the ssh authorized key to target. """ - module_args = 'user="%s" key="{{ lookup("file", "%s") }}"' % (user, key_path) + module_args = 'user="%s" key="{{ lookup("file", "%s") }}" state=present' % (user, key_path) self.__run(module_args, "authorized_key") - 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 push_multi_key(self, **user_info): """ @@ -318,12 +318,15 @@ class Tasks(Command): return {"status": "failed", "msg": self.msg} if self.msg else {"status": "ok"} - def add_user(self, username, password): + def add_user(self, username, password=''): """ add a host user. """ - encrypt_pass = sha512_crypt.encrypt(password) - module_args = 'name=%s shell=/bin/bash password=%s' % (username, encrypt_pass) + if password: + encrypt_pass = sha512_crypt.encrypt(password) + module_args = 'name=%s shell=/bin/bash password=%s' % (username, encrypt_pass) + else: + module_args = 'name=%s shell=/bin/bash' % username self.__run(module_args, "user") return {"status": "failed", "msg": self.msg} if self.msg else {"status": "ok"} diff --git a/jperm/models.py b/jperm/models.py index d8c0052fd..e153f554c 100644 --- a/jperm/models.py +++ b/jperm/models.py @@ -59,7 +59,9 @@ 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') + role = models.ForeignKey(PermRole, related_name='perm_push') is_public_key = models.BooleanField(default=False) is_password = models.BooleanField(default=False) + success = models.BooleanField(default=False) + result = models.TextField() diff --git a/jperm/urls.py b/jperm/urls.py index 4d84ed325..1e2ccf4cd 100644 --- a/jperm/urls.py +++ b/jperm/urls.py @@ -12,7 +12,7 @@ urlpatterns = patterns('jperm.views', (r'^role/perm_role_delete/$', perm_role_delete), (r'^role/perm_role_detail/$', perm_role_detail), (r'^role/perm_role_edit/$', perm_role_edit), - (r'^role/perm_role_push/$', perm_role_push), + (r'^role/push/$', perm_role_push), (r'^sudo/$', perm_sudo_list), (r'^sudo/perm_sudo_add/$', perm_sudo_add), (r'^sudo/perm_sudo_delete/$', perm_sudo_delete), diff --git a/jperm/views.py b/jperm/views.py index ba4f993f2..86c8a5de4 100644 --- a/jperm/views.py +++ b/jperm/views.py @@ -263,6 +263,11 @@ def perm_role_add(request): try: if get_object(PermRole, name=name): raise ServerError('已经存在该用户 %s' % name) + default = get_object(Setting, name='default') + if default and name == default.field1: + raise ServerError('与默认管理账号同名') + if name == 'root': + raise ServerError('不能为root') if password: encrypt_pass = CRYPTOR.encrypt(password) else: @@ -398,15 +403,13 @@ def perm_role_push(request): """ # 渲染数据 header_title, path1, path2 = "系统角色", "角色管理", "角色推送" - - roles = PermRole.objects.all() + role_id = request.GET.get('id') + role = get_object(PermRole, id=role_id) assets = Asset.objects.all() asset_groups = AssetGroup.objects.all() if request.method == "POST": # 获取推荐角色的名称列表 - role_ids = request.POST.getlist("roles") - # 计算出需要推送的资产列表 asset_ids = request.POST.getlist("assets") asset_group_ids = request.POST.getlist("asset_groups") @@ -434,13 +437,7 @@ def perm_role_push(request): # "password": password}) push_resource = gen_resource(calc_assets) - # 获取角色的推送方式,以及推送需要的信息 - roles_obj = [PermRole.objects.get(id=role_id) for role_id in role_ids] - role_pass = {} - role_key = {} - for role in roles_obj: - role_pass[role.name] = role.password - role_key[role.name] = os.path.join(role.key_path, 'id_rsa.pub') + logger.debug('推送role res: %s' % push_resource) # 调用Ansible API 进行推送 password_push = request.POST.get("use_password") @@ -452,34 +449,31 @@ def perm_role_push(request): # 因为要先建立用户,所以password 是必选项,而push key是在 password也完成的情况下的 可选项 # 1. 以password 方式推送角色 if password_push: - ret["password_push"] = task.add_multi_user(**role_pass) + ret["password_push"] = task.add_user(role.name, CRYPTOR.decrypt(role.password)) 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["password_push"] = task.add_user(role.name) + if ret["password_push"].get("status") != "ok": ret_failed["step2-1"] = "failed" - ret["key_push"] = task.push_multi_key(**role_key) - if ret["key_push"].get("status") != "success": + ret["key_push"] = task.push_key(role.name, os.path.join(role.key_path, 'id_rsa.pub')) + if ret["key_push"].get("status") != "ok": ret_failed["step2-2"] = "failed" # 3. 推送sudo配置文件 - role_chosen_aliase = {} # {'dev': 'NETWORKING, SHUTDOWN', 'sa': 'NETWORKING, SHUTDOWN'} - sudo_alias = set() # set(sudo1, sudo2, sudo3) - for role in roles_obj: - sudos = set([sudo for sudo in role.sudo.all()]) - sudo_alias.update(sudos) - role_chosen_aliase[role.name] = ','.join(sudo.name for sudo in sudos) + role_chosen_aliase = {} # {'dev': 'NETWORKING, SHUTDOWN'} + sudo_alias = set([sudo for sudo in role.sudo.all()]) # set(sudo1, sudo2, sudo3) + role_chosen_aliase[role.name] = ','.join(sudo.name for sudo in sudo_alias) add_sudo_script = get_add_sudo_script(role_chosen_aliase, sudo_alias) - ret_sudo = task.push_sudo_file(add_sudo_script) + ret['sudo'] = task.push_sudo_file(add_sudo_script) - if ret_sudo["step1"] != "ok" or ret_sudo["step2"] != "ok": + if ret['sudo']["step1"] != "ok" or ret['sudo']["step2"] != "ok": ret_failed["step3"] = "failed" os.remove(add_sudo_script) - print ret + logger.debug('推送role结果: %s' % ret) # 结果汇总统计 if ret_failed: # 推送失败 @@ -491,7 +485,7 @@ def perm_role_push(request): push.save() push.asset_group = asset_groups_obj push.asset = calc_assets - push.role = roles_obj + push.role = role push.save() return my_render('jperm/perm_role_push.html', locals(), request) @@ -592,5 +586,7 @@ def perm_sudo_delete(request): return HttpResponse(u"不支持该操作") - +def role_push_list(request): + push_all = PermPush.objects.all() + return my_render('jperm/role_push_list.html', locals(), request) diff --git a/jumpserver/templatetags/mytags.py b/jumpserver/templatetags/mytags.py index 8adfb724a..2adb62deb 100644 --- a/jumpserver/templatetags/mytags.py +++ b/jumpserver/templatetags/mytags.py @@ -5,7 +5,7 @@ import ast import time from django import template -# from jperm.models import CmdGroup +from jperm.models import PermPush from jumpserver.api import * from jasset.models import AssetAlias @@ -259,3 +259,16 @@ def role_contain_which_sudos(role): sudo_names = [sudo.name for sudo in role.sudo.all()] return ','.join(sudo_names) + +@register.filter(name='get_push_info') +def get_push_info(push_id, arg): + push = get_object(PermPush, id=push_id) + if push and arg: + if arg == 'asset': + return [asset.hostname for asset in push.asset.all()] + if arg == 'asset_group': + return [asset_group.name for asset_group in push.asset_group.all()] + if arg == 'role': + return [role.name for role in push.role.all()] + else: + return [] diff --git a/juser/views.py b/juser/views.py index dc02487a7..f204a53c5 100644 --- a/juser/views.py +++ b/juser/views.py @@ -146,7 +146,7 @@ def user_add(request): error = '' msg = '' header_title, path1, path2 = '添加用户', '用户管理', '添加用户' - user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'} + user_role = {'SU': u'超级管理员', 'CU': u'普通用户'} group_all = UserGroup.objects.all() if request.method == 'POST': @@ -349,7 +349,7 @@ def user_edit(request): if not user_id: return HttpResponseRedirect('/') - user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'} + user_role = {'SU': u'超级管理员', 'CU': u'普通用户'} user = get_object(User, id=user_id) group_all = UserGroup.objects.all() if user: diff --git a/templates/jasset/asset_add.html b/templates/jasset/asset_add.html index 210d583d4..d2761a3b0 100644 --- a/templates/jasset/asset_add.html +++ b/templates/jasset/asset_add.html @@ -48,7 +48,6 @@ {{ af.ip|bootstrap_horizontal }}

Tips: 如果IP地址不填写, IP默认会设置与主机名一致

-
@@ -60,7 +59,7 @@
- +

Tips: 管理用户为root或用户拥有NOPASSWD:ALL sudo权限的用户

-
添加角色 - 推送角色 +{# 推送角色 #}
- @@ -66,6 +64,7 @@ diff --git a/templates/jperm/perm_role_push.html b/templates/jperm/perm_role_push.html index a44385ec7..c308bbe60 100644 --- a/templates/jperm/perm_role_push.html +++ b/templates/jperm/perm_role_push.html @@ -33,6 +33,13 @@ {% if msg %}
{{ msg }}
{% endif %} +
+ +
+ +
+
+
@@ -55,17 +62,7 @@
-
- -
- -
-
-
+
diff --git a/templates/jperm/perm_sudo_list.html b/templates/jperm/perm_sudo_list.html index 43f13ec10..2508eec8c 100644 --- a/templates/jperm/perm_sudo_list.html +++ b/templates/jperm/perm_sudo_list.html @@ -33,7 +33,6 @@
添加别名 - 删除所选
diff --git a/templates/juser/user_add.html b/templates/juser/user_add.html index 53d0351ec..9824d9c7c 100644 --- a/templates/juser/user_add.html +++ b/templates/juser/user_add.html @@ -61,7 +61,7 @@ {% ifequal session_role_id 2 %}
- +
{% for r, role_name in user_role.items %}
diff --git a/templates/setting.html b/templates/setting.html index 83fbb3285..baf3c49ad 100644 --- a/templates/setting.html +++ b/templates/setting.html @@ -49,7 +49,7 @@
- 该用户为root或用户NOPASS:ALL sudo权限的用户 + 管理用户为root或用户拥有NOPASSWD:ALL sudo权限的用户
@@ -128,13 +128,13 @@ tip: "输入端口号", ok: "", msg: {required: "端口号必填"} - }, - "key": { - rule: "required(either)", - tip: "输入密钥", - ok: "", - msg: {required: "密码和密钥必填一个!"} } +{# "key": {#} +{# rule: "required(either)",#} +{# tip: "输入密钥",#} +{# ok: "",#} +{# msg: {required: "密码和密钥必填一个!"}#} +{# }#} }, valid: function(form) { form.submit(); From f7c8ad6f38ff8bcb92c438d10f89726d508dbbd2 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 30 Nov 2015 19:06:25 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8E=A8=E9=80=81?= =?UTF-8?q?=E7=94=A8=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jperm/ansible_api.py | 4 +- jperm/models.py | 11 +-- jperm/perm_api.py | 47 ++++--------- jperm/views.py | 97 ++++++++++++++------------- templates/index.html | 88 ++++++++++++------------ templates/jperm/perm_role_detail.html | 70 +++++++++++++++---- templates/jperm/perm_role_list.html | 8 +-- templates/jperm/perm_role_push.html | 4 +- templates/jperm/perm_rule_add.html | 2 +- templates/juser/group_list.html | 7 +- templates/nav.html | 2 +- 11 files changed, 179 insertions(+), 161 deletions(-) diff --git a/jperm/ansible_api.py b/jperm/ansible_api.py index 1de8ef609..0b54ffd58 100644 --- a/jperm/ansible_api.py +++ b/jperm/ansible_api.py @@ -451,12 +451,12 @@ class Tasks(Command): if not ret1["msg"]: result["step1"] = "ok" else: - result["step1"] = "failed" + result["msg"] = ret1["msg"] if not ret2["msg"] and "failed" not in ret2_status: result["step2"] = "ok" else: - result["step2"] = "failed" + result["msg"] = ret1["msg"] return result diff --git a/jperm/models.py b/jperm/models.py index e153f554c..3a280762e 100644 --- a/jperm/models.py +++ b/jperm/models.py @@ -13,12 +13,6 @@ class PermLog(models.Model): is_finish = models.BooleanField(default=False) -class SysUser(models.Model): - username = models.CharField(max_length=100) - password = models.CharField(max_length=100) - comment = models.CharField(max_length=100, null=True, blank=True, default='') - - class PermSudo(models.Model): name = models.CharField(max_length=100, unique=True) date_added = models.DateTimeField(auto_now=True) @@ -56,12 +50,11 @@ class PermRule(models.Model): 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') + asset = models.ForeignKey(Asset, related_name='perm_push') role = models.ForeignKey(PermRole, related_name='perm_push') is_public_key = models.BooleanField(default=False) is_password = models.BooleanField(default=False) success = models.BooleanField(default=False) result = models.TextField() + date_added = models.DateTimeField(auto_now=True) diff --git a/jperm/perm_api.py b/jperm/perm_api.py index 4ebfc7d3f..080f1cb39 100644 --- a/jperm/perm_api.py +++ b/jperm/perm_api.py @@ -6,8 +6,7 @@ import uuid import re from jumpserver.models import Setting -from jperm.models import PermRole -from jperm.models import PermRule +from jperm.models import PermRole, PermPush, PermRule def get_group_user_perm(ob): @@ -266,41 +265,21 @@ def get_role_info(role_id, type="all"): return u"不支持的查询" -def get_role_push_host(role, raw=False): +def get_role_push_host(role): """ - get the role push host - :return: the asset object + asset_pushed: {'success': push.success, 'key': push.is_public_key, 'password': push.is_password, + 'result': push.result} + asset_no_push: set(asset1, asset2) """ # 计算该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) - - if raw: - return {'asset': cacl_assets, 'asset_group': set(asset_groups)} - # 计算所有主机 在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 + pushs = PermPush.objects.filter(role=role) + asset_all = Asset.objects.all() + asset_pushed = {} + for push in pushs: + asset_pushed[push.asset] = {'success': push.success, 'key': push.is_public_key, 'password': push.is_password, + 'result': push.result} + asset_no_push = set(asset_all) - set(asset_pushed.keys()) + return asset_pushed, asset_no_push if __name__ == "__main__": print get_role_info(1) diff --git a/jperm/views.py b/jperm/views.py index 86c8a5de4..38a003859 100644 --- a/jperm/views.py +++ b/jperm/views.py @@ -94,8 +94,8 @@ def perm_rule_add(request): # 获取需要授权的主机列表 assets_obj = [Asset.objects.get(id=asset_id) for asset_id in assets_select] asset_groups_obj = [AssetGroup.objects.get(id=group_id) for group_id in asset_groups_select] - # group_assets_obj = [asset for asset in [group.asset_set.all() for group in asset_groups_obj]] - # calc_assets = set(group_assets_obj) | set(assets_obj) + group_assets_obj = [asset for asset in [group.asset_set.all() for group in asset_groups_obj]] + calc_assets = set(group_assets_obj) | set(assets_obj) # 获取需要授权的用户列表 users_obj = [User.objects.get(id=user_id) for user_id in users_select] @@ -105,19 +105,13 @@ def perm_rule_add(request): # 获取授予的角色列表 roles_obj = [PermRole.objects.get(id=role_id) for role_id in roles_select] - + need_push_asset = set() for role in roles_obj: - push_assets_or_group = get_role_push_host(role=role, raw=True) - push_assets = push_assets_or_group.get('asset') - push_asset_groups = push_assets_or_group.get('asset_group') - no_push_assets = set(assets_obj) - set(push_assets) - no_push_asset_groups = set(asset_groups_obj) - set(push_asset_groups) - if no_push_assets: + asset_no_push = get_role_push_host(role=role)[1] + need_push_asset.update(set(calc_assets) - set(asset_no_push)) + if need_push_asset: raise ServerError(u'没有推送角色 %s 的主机 %s' - % (role.name, ','.join([asset.hostname for asset in no_push_assets]))) - elif no_push_asset_groups: - raise ServerError(u'没有推送角色 %s 的主机组 %s' - % (role.name, ','.join(asset_group.name for asset_group in no_push_asset_groups))) + % (role.name, ','.join([asset.hostname for asset in need_push_asset]))) # 仅授权成功的,写回数据库(授权规则,用户,用户组,资产,资产组,用户角色) rule = PermRule(name=rule_name, comment=rule_comment) @@ -264,10 +258,7 @@ def perm_role_add(request): if get_object(PermRole, name=name): raise ServerError('已经存在该用户 %s' % name) default = get_object(Setting, name='default') - if default and name == default.field1: - raise ServerError('与默认管理账号同名') - if name == 'root': - raise ServerError('不能为root') + if password: encrypt_pass = CRYPTOR.encrypt(password) else: @@ -336,7 +327,7 @@ def perm_role_detail(request): asset_groups = role_info.get("asset_groups") users = role_info.get("users") user_groups = role_info.get("user_groups") - push_info = get_role_push_host(PermRole.objects.get(id=role_id)) + pushed_asset, need_push_asset = get_role_push_host(get_object(PermRole, id=role_id)) return my_render('jperm/perm_role_detail.html', locals(), request) @@ -440,8 +431,8 @@ def perm_role_push(request): logger.debug('推送role res: %s' % push_resource) # 调用Ansible API 进行推送 - password_push = request.POST.get("use_password") - key_push = request.POST.get("use_publicKey") + password_push = True if request.POST.get("use_password") else False + key_push = True if request.POST.get("use_publicKey") else False task = Tasks(push_resource) ret = {} ret_failed = {} @@ -451,43 +442,57 @@ def perm_role_push(request): if password_push: ret["password_push"] = task.add_user(role.name, CRYPTOR.decrypt(role.password)) if ret["password_push"].get("status") != "success": - ret_failed["step1"] == "failed" + ret_failed = ret["password_push"].get('msg') # 2. 以秘钥 方式推送角色 if key_push: ret["password_push"] = task.add_user(role.name) if ret["password_push"].get("status") != "ok": - ret_failed["step2-1"] = "failed" + ret_failed = ret["password_push"].get('msg') ret["key_push"] = task.push_key(role.name, os.path.join(role.key_path, 'id_rsa.pub')) if ret["key_push"].get("status") != "ok": - ret_failed["step2-2"] = "failed" + ret_failed = ret["key_push"].get('msg') # 3. 推送sudo配置文件 - role_chosen_aliase = {} # {'dev': 'NETWORKING, SHUTDOWN'} - sudo_alias = set([sudo for sudo in role.sudo.all()]) # set(sudo1, sudo2, sudo3) - role_chosen_aliase[role.name] = ','.join(sudo.name for sudo in sudo_alias) - add_sudo_script = get_add_sudo_script(role_chosen_aliase, sudo_alias) - ret['sudo'] = task.push_sudo_file(add_sudo_script) + 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) + role_chosen_aliase[role.name] = ','.join(sudo.name for sudo in sudo_alias) + 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) + if ret['sudo'].get('msg'): + ret_failed = ret['sudo'].get('msg') + os.remove(add_sudo_script) logger.debug('推送role结果: %s' % ret) - # 结果汇总统计 - if ret_failed: - # 推送失败 - error = u"推送失败, 原因: %s 失败" % ','.join(ret_failed.keys()) - else: - # 推送成功 回写push表 - 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 - push.asset = calc_assets - push.role = role - push.save() + logger.debug('推送role错误: %s' % ret_failed) + success_asset = [] + failed_asset = [] + # 推送成功 回写push表 + for asset in calc_assets: + push_check = PermPush.objects.filter(role=role, asset=asset) + if push_check: + func = push_check.update + else: + def func(**kwargs): + PermPush(**kwargs).save() + + if ret_failed.get(asset.hostname): + failed_asset.append(asset) + func(is_password=password_push, is_public_key=key_push, role=role, asset=asset, success=False, + result=ret_failed.get(asset.hostname)) + else: + success_asset.append(asset) + func(is_password=password_push, is_public_key=key_push, role=role, asset=asset, success=True) + + if not failed_asset: + msg = u'角色 %s 推送成功[ %s ]' % (role.name, ','.join([asset.hostname for asset in success_asset])) + else: + error = u'角色 %s 推送失败 [ %s ], 推送成功 [ %s ]' % (role.name, + ','.join([asset.hostname for asset in failed_asset]), + ','.join([asset.hostname for asset in success_asset])) return my_render('jperm/perm_role_push.html', locals(), request) @@ -586,7 +591,3 @@ def perm_sudo_delete(request): return HttpResponse(u"不支持该操作") -def role_push_list(request): - push_all = PermPush.objects.all() - return my_render('jperm/role_push_list.html', locals(), request) - diff --git a/templates/index.html b/templates/index.html index 0d8baf9f9..0468ecbde 100644 --- a/templates/index.html +++ b/templates/index.html @@ -104,50 +104,48 @@
-
-
-
权限申请
- -
-
-

权限申请记录

- 最近十条权限申请记录信息. -
-
-
- {% if perm_apply_10 %} - {% for perm in perm_apply_10 %} -
-
- {% ifequal perm.status 0 %} - {{ perm.date_add|naturaltime }} - {% else %} - {{ perm.date_add|naturaltime }} - {% endifequal %} - {{ perm.applyer }} -{#
申请 {{ perm.bisgroup|ast_to_list }} 主机组权限
#} -{#
申请 {{ perm.asset|ast_to_list }} 主机权限
#} - {{ perm.date_add }} -
-
- {% endfor %} - {% else %} -

(暂无)

- {% endif %} -
-
-
+{#
#} +{#
#} +{#
权限申请
#} +{#
#} +{# #} +{# #} +{# #} +{# #} +{# #} +{# #} +{# #} +{# #} +{# #} +{# #} +{#
#} +{#
#} +{#
#} +{#

权限申请记录

#} +{# 最近十条权限申请记录信息.#} +{#
#} +{#
#} +{#
#} +{# {% if perm_apply_10 %}#} +{# {% for perm in perm_apply_10 %}#} +{#
#} +{#
#} +{# {% ifequal perm.status 0 %}#} +{# {{ perm.date_add|naturaltime }}#} +{# {% else %}#} +{# {{ perm.date_add|naturaltime }}#} +{# {% endifequal %}#} +{# {{ perm.applyer }}#} +{# {{ perm.date_add }}#} +{#
#} +{#
#} +{# {% endfor %}#} +{# {% else %}#} +{#

(暂无)

#} +{# {% endif %}#} +{#
#} +{#
#} +{#
#}
@@ -306,7 +304,7 @@
-
+{#
#}
{% endblock %} diff --git a/templates/jperm/perm_role_detail.html b/templates/jperm/perm_role_detail.html index 51d6ac9b2..a6cb9ad11 100644 --- a/templates/jperm/perm_role_detail.html +++ b/templates/jperm/perm_role_detail.html @@ -6,7 +6,7 @@ {% include 'nav_cat_bar.html' %}
-
+
授权规则 @@ -52,7 +52,7 @@
-
+
授权用户/用户组 @@ -98,7 +98,7 @@
-
+
授权主机/主机组 @@ -146,7 +146,7 @@
-
+
推送主机 @@ -175,18 +175,64 @@
- - - + + + - {% for host in push_info %} + {% for asset, info in pushed_asset.items %} - - - - + + + + {% if info.success %} + + {% else %} + + {% endif %} + + {% endfor %} + +
详情 编辑 + 推送
主机主机组使用密码使用秘钥密钥密码结果
{{ host.ip }} {{ host.group }} {{ host.password }} {{ host.pubkey }} {{ asset.hostname }} {{ info.key | yesno:"是,否,未知" }} {{ info.password | yesno:"是,否,未知" }} {{ info.success | yesno:"成功,失败,未知" }} {{ info.success | yesno:"成功,失败,未知" }}
+
+ + + + + +
+
+
+ 未推送主机 + +
+
+
+
+ + + + + + + + + {% for asset in need_push_asset %} + + + {% endfor %} diff --git a/templates/jperm/perm_role_list.html b/templates/jperm/perm_role_list.html index 0c48fd782..e9305a165 100644 --- a/templates/jperm/perm_role_list.html +++ b/templates/jperm/perm_role_list.html @@ -48,9 +48,9 @@ - - + + @@ -58,9 +58,9 @@ {% for role in roles %} - - + + - +
主机IP
{{ asset.hostname }} {{ asset.ip }}
名称 备注创建时间 sudo别名创建时间备注 操作
{{ role.name }} {{ role.comment }} {{ role.date_added | date:"Y-m-d H:i:s"}} {{ role | role_contain_which_sudos }} {{ role.date_added | date:"Y-m-d H:i:s"}} {{ role.comment }} 详情 编辑 diff --git a/templates/jperm/perm_role_push.html b/templates/jperm/perm_role_push.html index c308bbe60..dfa4a109c 100644 --- a/templates/jperm/perm_role_push.html +++ b/templates/jperm/perm_role_push.html @@ -45,7 +45,7 @@
@@ -56,7 +56,7 @@
diff --git a/templates/jperm/perm_rule_add.html b/templates/jperm/perm_rule_add.html index cf33cbb97..15eec08e9 100644 --- a/templates/jperm/perm_rule_add.html +++ b/templates/jperm/perm_rule_add.html @@ -68,7 +68,7 @@
资产和资产组必选一个 diff --git a/templates/juser/group_list.html b/templates/juser/group_list.html index 86e4ec3f6..db0f59a96 100644 --- a/templates/juser/group_list.html +++ b/templates/juser/group_list.html @@ -55,11 +55,12 @@ {% for group in user_groups.object_list %}
- + {{ group.name }} {{ group.id | members_count }} + {{ group.id | members_count }} + {{ group.comment }} 编辑 diff --git a/templates/nav.html b/templates/nav.html index b85eba8c7..61bd8fe36 100644 --- a/templates/nav.html +++ b/templates/nav.html @@ -24,7 +24,7 @@
  • 授权管理