1. 新增 PermSudo表, 用于记录 sudo别名

2. 实现Sudo表对应的 添加,显示,更新,删除页面
3. 添加角色时,需要选择对应的 sudo别名
pull/26/head
yumaojun 2015-11-24 22:03:58 +08:00
parent e57c6a9d2e
commit 1a0c9cd4e6
14 changed files with 737 additions and 29 deletions

View File

@ -20,7 +20,6 @@ API_DIR = os.path.dirname(os.path.abspath(__file__))
ANSIBLE_DIR = os.path.join(API_DIR, 'playbooks') ANSIBLE_DIR = os.path.join(API_DIR, 'playbooks')
class AnsibleError(StandardError): class AnsibleError(StandardError):
""" """
the base AnsibleError which contains error(required), the base AnsibleError which contains error(required),
@ -44,7 +43,7 @@ class CommandValueError(AnsibleError):
super(CommandValueError, self).__init__('value:invalid', field, message) super(CommandValueError, self).__init__('value:invalid', field, message)
class MyInventory(object): class MyInventory(Inventory):
""" """
this is my ansible inventory object. this is my ansible inventory object.
""" """
@ -65,7 +64,7 @@ class MyInventory(object):
self.inventory = Inventory(host_list=[]) self.inventory = Inventory(host_list=[])
self.gen_inventory() self.gen_inventory()
def add_group(self, hosts, groupname, groupvars=None): def my_add_group(self, hosts, groupname, groupvars=None):
""" """
add hosts to a group add hosts to a group
""" """
@ -83,11 +82,13 @@ class MyInventory(object):
hostport = host.get("port") hostport = host.get("port")
username = host.get("username") username = host.get("username")
password = host.get("password") password = host.get("password")
sudo_password = host.get("sudo_password")
my_host = Host(name=hostname, port=hostport) my_host = Host(name=hostname, port=hostport)
my_host.set_variable('ansible_ssh_host', hostname) my_host.set_variable('ansible_ssh_host', hostname)
my_host.set_variable('ansible_ssh_port', hostport) my_host.set_variable('ansible_ssh_port', hostport)
my_host.set_variable('ansible_ssh_user', username) my_host.set_variable('ansible_ssh_user', username)
my_host.set_variable('ansible_ssh_pass', password) my_host.set_variable('ansible_ssh_pass', password)
# set other variables # set other variables
for key, value in host.iteritems(): for key, value in host.iteritems():
if key not in ["hostname", "port", "username", "password"]: if key not in ["hostname", "port", "username", "password"]:
@ -102,10 +103,10 @@ class MyInventory(object):
add hosts to inventory. add hosts to inventory.
""" """
if isinstance(self.resource, list): if isinstance(self.resource, list):
self.add_group(self.resource, 'default_group') self.my_add_group(self.resource, 'default_group')
elif isinstance(self.resource, dict): elif isinstance(self.resource, dict):
for groupname, hosts_and_vars in self.resource.iteritems(): for groupname, hosts_and_vars in self.resource.iteritems():
self.add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars")) self.my_add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))
class Command(MyInventory): class Command(MyInventory):
@ -136,15 +137,17 @@ class Command(MyInventory):
) )
self.results = hoc.run() self.results = hoc.run()
ret = {}
if self.stdout: if self.stdout:
return {"ok": self.stdout} ret["ok"] = self.stdout
else: else:
msg = [] msg = []
if self.stderr: if self.stderr:
msg.append(self.stderr) msg.append(self.stderr)
if self.dark: if self.dark:
msg.append(self.dark) msg.append(self.dark)
return {"failed": msg} ret["failed"] = msg
return ret
@property @property
def raw_results(self): def raw_results(self):
@ -206,7 +209,14 @@ class Tasks(Command):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(Tasks, self).__init__(*args, **kwargs) super(Tasks, self).__init__(*args, **kwargs)
def __run(self, module_args, module_name="command", timeout=5, forks=10, group='default_group', pattern='*'): def __run(self,
module_args,
module_name="command",
timeout=5,
forks=10,
group='default_group',
pattern='*',
):
""" """
run command from andible ad-hoc. run command from andible ad-hoc.
command : 必须是一个需要执行的命令字符串 比如 command : 必须是一个需要执行的命令字符串 比如
@ -219,6 +229,7 @@ class Tasks(Command):
subset=group, subset=group,
pattern=pattern, pattern=pattern,
forks=forks, forks=forks,
become=False,
) )
self.results = hoc.run() self.results = hoc.run()
@ -310,7 +321,8 @@ class Tasks(Command):
delete a host user. delete a host user.
""" """
module_args = 'name=%s state=absent remove=yes move_home=yes force=yes' % (username) module_args = 'name=%s state=absent remove=yes move_home=yes force=yes' % (username)
self.__run(module_args, "user") 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"}
@ -386,9 +398,15 @@ class Tasks(Command):
"product_sn": setup.get("ansible_product_serial") "product_sn": setup.get("ansible_product_serial")
} }
return {"status": "failed", "msg": self.msg} if self.msg else {"status": "ok", "result": result} return {"failed": self.msg, "ok": result}
def push_sudo(self, role_custo, role_name, role_chosen):
"""
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")
class CustomAggregateStats(callbacks.AggregateStats): class CustomAggregateStats(callbacks.AggregateStats):
@ -475,9 +493,14 @@ if __name__ == "__main__":
# }, # },
# } # }
resource = [{"hostname": "127.0.0.1", "port": "22", "username": "yumaojun", "password": "yusky0902"}] resource = [{"hostname": "127.0.0.1", "port": "22", "username": "yumaojun", "password": "yusky0902",
command = Command(resource) # "ansible_become": "yes",
print command.run("who") # "ansible_become_method": "sudo",
# # "ansible_become_user": "root",
# "ansible_become_pass": "yusky0902",
}]
cmd = Command(resource)
print cmd.run('ls')
# resource = [{"hostname": "192.168.10.148", "port": "22", "username": "root", "password": "xxx"}] # resource = [{"hostname": "192.168.10.148", "port": "22", "username": "root", "password": "xxx"}]
# task = Tasks(resource) # task = Tasks(resource)

View File

@ -19,12 +19,23 @@ class SysUser(models.Model):
comment = models.CharField(max_length=100, null=True, blank=True, default='') 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)
commands = models.TextField()
comment = models.CharField(max_length=100, null=True, blank=True, default='')
def __unicode__(self):
return self.name
class PermRole(models.Model): class PermRole(models.Model):
name = models.CharField(max_length=100, unique=True) name = models.CharField(max_length=100, unique=True)
comment = models.CharField(max_length=100, null=True, blank=True, default='') comment = models.CharField(max_length=100, null=True, blank=True, default='')
password = models.CharField(max_length=100) password = models.CharField(max_length=100)
key_path = models.CharField(max_length=100) key_path = models.CharField(max_length=100)
date_added = models.DateTimeField(auto_now=True) date_added = models.DateTimeField(auto_now=True)
sudo = models.ManyToManyField(PermSudo, related_name='perm_role')
def __unicode__(self): def __unicode__(self):
return self.name return self.name
@ -42,3 +53,7 @@ class PermRule(models.Model):
def __unicode__(self): def __unicode__(self):
return self.name return self.name

View File

@ -13,7 +13,10 @@ urlpatterns = patterns('jperm.views',
(r'^role/perm_role_detail/$', perm_role_detail), (r'^role/perm_role_detail/$', perm_role_detail),
(r'^role/perm_role_edit/$', perm_role_edit), (r'^role/perm_role_edit/$', perm_role_edit),
(r'^role/perm_role_push/$', perm_role_push), (r'^role/perm_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),
(r'^sudo/perm_sudo_edit/$', perm_sudo_edit),
(r'^log/$', log), (r'^log/$', log),
(r'^sys_user_add/$', sys_user_add), (r'^sys_user_add/$', sys_user_add),

View File

@ -6,6 +6,8 @@ import os.path
from paramiko.rsakey import RSAKey from paramiko.rsakey import RSAKey
from os import chmod, makedirs from os import chmod, makedirs
from uuid import uuid4 from uuid import uuid4
from django.template.loader import get_template
from django.template import Context
from jumpserver.settings import KEY_DIR from jumpserver.settings import KEY_DIR
@ -62,6 +64,29 @@ def gen_keys():
return 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
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -9,7 +9,7 @@ from juser.user_api import gen_ssh_key
from juser.models import User, UserGroup from juser.models import User, UserGroup
from jasset.models import Asset, AssetGroup from jasset.models import Asset, AssetGroup
from jperm.models import PermRole, PermRule from jperm.models import PermRole, PermRule, PermSudo
from jumpserver.models import Setting 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
@ -259,19 +259,24 @@ def perm_role_add(request):
if request.method == "GET": if request.method == "GET":
default_password = get_rand_pass() default_password = get_rand_pass()
sudos = PermSudo.objects.all()
return my_render('jperm/perm_role_add.html', locals(), request) return my_render('jperm/perm_role_add.html', locals(), request)
elif request.method == "POST": elif request.method == "POST":
# 获取参数: name, comment # 获取参数: name, comment, sudo
name = request.POST.get("role_name") name = request.POST.get("role_name")
comment = request.POST.get("role_comment") comment = request.POST.get("role_comment")
password = request.POST.get("role_password") password = request.POST.get("role_password")
sudos_name = request.POST.getlist("sudo_name")
sudos_obj = [PermSudo.objects.get(name=sudo_name) for sudo_name in sudos_name]
encrypt_pass = CRYPTOR.encrypt(password) encrypt_pass = CRYPTOR.encrypt(password)
# 生成随机密码,生成秘钥对 # 生成随机密码,生成秘钥对
key_path = gen_keys() key_path = gen_keys()
role = PermRole(name=name, comment=comment, password=encrypt_pass, key_path=key_path) role = PermRole(name=name, comment=comment, password=encrypt_pass, key_path=key_path)
role.save() role.save()
role.sudo = sudos_obj
role.save()
msg = u"添加角色: %s" % name msg = u"添加角色: %s" % name
# 渲染 刷新数据 # 渲染 刷新数据
@ -350,6 +355,7 @@ def perm_role_edit(request):
role_id = request.GET.get("id") role_id = request.GET.get("id")
role = PermRole.objects.get(id=role_id) role = PermRole.objects.get(id=role_id)
role_pass = CRYPTOR.decrypt(role.password) role_pass = CRYPTOR.decrypt(role.password)
role_sudos = role.sudo.all()
if request.method == "GET": if request.method == "GET":
return my_render('jperm/perm_role_edit.html', locals(), request) return my_render('jperm/perm_role_edit.html', locals(), request)
@ -359,11 +365,14 @@ def perm_role_edit(request):
role_password = request.POST.get("role_password") role_password = request.POST.get("role_password")
encrypt_role_pass = CRYPTOR.encrypt(role_password) encrypt_role_pass = CRYPTOR.encrypt(role_password)
role_comment = request.POST.get("role_comment") role_comment = request.POST.get("role_comment")
role_sudo_names = request.POST.getlist("sudo_name")
role_sudos = [PermSudo.objects.get(name=sudo_name) for sudo_name in role_sudo_names]
# 写入数据库 # 写入数据库
role.name = role_name role.name = role_name
role.password = encrypt_role_pass role.password = encrypt_role_pass
role.comment = role_comment role.comment = role_comment
role.sudo = role_sudos
role.save() role.save()
msg = u"更新系统角色: %s" % role.name msg = u"更新系统角色: %s" % role.name
@ -380,8 +389,6 @@ def perm_role_edit(request):
return my_render('jperm/perm_role_list.html', locals(), request) return my_render('jperm/perm_role_list.html', locals(), request)
@require_role('admin') @require_role('admin')
def perm_role_push(request): def perm_role_push(request):
""" """
@ -461,6 +468,127 @@ def perm_role_push(request):
return HttpResponse(u"推送系统角色: %s" % ','.join(role_names)) return HttpResponse(u"推送系统角色: %s" % ','.join(role_names))
@require_role('admin')
def perm_sudo_list(request):
"""
list sudo commands alias
:param request:
:return:
"""
# 渲染数据
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)
@require_role('admin')
def perm_sudo_add(request):
"""
list sudo commands alias
:param request:
:return:
"""
# 渲染数据
header_title, path1, path2 = "Sudo命令", "别名管理", "添加别名"
if request.method == "GET":
return my_render('jperm/perm_sudo_add.html', locals(), request)
elif request.method == "POST":
# 获取参数: name, comment
name = request.POST.get("sudo_name")
comment = request.POST.get("sudo_comment")
commands = request.POST.get("sudo_commands")
sudo = PermSudo(name=name, comment=comment, commands=commands)
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"不支持该操作")
@require_role('admin')
def perm_sudo_edit(request):
"""
list sudo commands alias
:param request:
:return:
"""
# 渲染数据
header_title, path1, path2 = "Sudo命令", "别名管理", "编辑别名"
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")
comment = request.POST.get("sudo_comment")
sudo.name = name
sudo.commands = commands
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)
@require_role('admin')
def perm_sudo_delete(request):
"""
list sudo commands alias
:param request:
:return:
"""
if request.method == "POST":
# 获取参数删除的role对象
sudo_id = request.POST.get("id")
sudo = PermSudo.objects.get(id=sudo_id)
# 数据库里删除记录
sudo.delete()
return HttpResponse(u"删除角色: %s" % sudo.name)
else:
return HttpResponse(u"不支持该操作")

View File

@ -226,3 +226,12 @@ def ip_str_to_list(ip_str):
ip str to list ip str to list
""" """
return ip_str.split(',') return ip_str.split(',')
@register.filter(name='role_contain_which_sudos')
def role_contain_which_sudos(role):
"""
get role sudo commands
"""
sudo_names = [sudo.name for sudo in role.sudo.all()]
return ','.join(sudo_names)

View File

@ -47,6 +47,17 @@
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group">
<label for="sudo" class="col-sm-2 control-label">角色Sudo命令<span class="red-fonts">*</span></label>
<div class="col-sm-8" id="sudo_name">
<select name="sudo_name" data-placeholder="请选择Sudo别名" class="chosen-select form-control m-b" multiple tabindex="2">
{% for sudo in sudos %}
<option >{{ sudo.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="role_comment" class="col-sm-2 control-label">备注</label> <label for="role_comment" class="col-sm-2 control-label">备注</label>
<div class="col-sm-8"> <div class="col-sm-8">

View File

@ -47,6 +47,17 @@
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group">
<label for="sudo" class="col-sm-2 control-label">角色Sudo命令<span class="red-fonts">*</span></label>
<div class="col-sm-8" id="sudo_name">
<select name="sudo_name" data-placeholder="请选择Sudo别名" class="chosen-select form-control m-b" multiple tabindex="2">
{% for sudo in role_sudos %}
<option selected >{{ sudo.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="role_comment" class="col-sm-2 control-label">备注</label> <label for="role_comment" class="col-sm-2 control-label">备注</label>
<div class="col-sm-8"> <div class="col-sm-8">

View File

@ -53,6 +53,7 @@
<th class="text-center">名称 </th> <th class="text-center">名称 </th>
<th class="text-center">备注</th> <th class="text-center">备注</th>
<th class="text-center">创建时间</th> <th class="text-center">创建时间</th>
<th class="text-center">sudo别名</th>
<th class="text-center">操作</th> <th class="text-center">操作</th>
</tr> </tr>
</thead> </thead>
@ -62,6 +63,7 @@
<td class="text-center"> {{ role.name }} </td> <td class="text-center"> {{ role.name }} </td>
<td class="text-center"> {{ role.comment }} </td> <td class="text-center"> {{ role.comment }} </td>
<td class="text-center"> {{ role.date_added | date:"Y-m-d H:i:s"}} </td> <td class="text-center"> {{ role.date_added | date:"Y-m-d H:i:s"}} </td>
<td class="text-center"> {{ role | role_contain_which_sudos }} </td>
<td class="text-center"> <td class="text-center">
<a href="/jperm/role/perm_role_detail/?id={{ role.id }}" class="btn btn-xs btn-primary">详情</a> <a href="/jperm/role/perm_role_detail/?id={{ role.id }}" class="btn btn-xs btn-primary">详情</a>
<a href="/jperm/role/perm_role_edit/?id={{ role.id }}" class="btn btn-xs btn-info">编辑</a> <a href="/jperm/role/perm_role_edit/?id={{ role.id }}" class="btn btn-xs btn-info">编辑</a>
@ -99,6 +101,7 @@ function remove_role(role_id){
del_row.remove() del_row.remove()
}, },
error: function (msg) { error: function (msg) {
console.log(msg)
alert("失败: " + msg) alert("失败: " + msg)
} }
}); });

View File

@ -0,0 +1,120 @@
{% extends 'base.html' %}
{% block self_head_css_js %}
<link href="/static/css/plugins/datapicker/datepicker3.css" rel="stylesheet">
<link href="/static/css/plugins/chosen/chosen.css" rel="stylesheet">
<script src="/static/js/plugins/chosen/chosen.jquery.js"></script>
{% endblock %}
{% load mytags %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-10">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>填写基本信息</h5>
<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>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<form method="post" id="sudoForm" class="form-horizontal" action="">
{% if error %}
<div class="alert alert-warning text-center">{{ error }}</div>
{% endif %}
{% if msg %}
<div class="alert alert-success text-center">{{ msg }}</div>
{% endif %}
<div class="form-group">
<label for="sudo_name" class="col-sm-2 control-label">命令别名<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<input id="sudo_name" name="sudo_name" placeholder="Sudo Command Alias" type="text" class="form-control">
</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">
<textarea id="sudo_commands" name="sudo_commands" class="form-control" rows="3"></textarea>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="sudo_comment" class="col-sm-2 control-label">备注</label>
<div class="col-sm-8">
<input id="sudo_comment" name="sudo_comment" placeholder="Sudo Comment" type="text" class="form-control">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">取消</button>
<button id="submit_button" class="btn btn-primary" type="submit">确认保存</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block self_footer_js %}
<script>
$(document).ready(function(){
$("input.role").click(function(){
if($("input.role[value=GA]").is( ":checked" )){
$("#admin_groups").css("display", 'none');
}
else {
$("#admin_groups").css("display", 'block');
}
});
$('#use_password').click(function(){
if ($(this).is(':checked')){
$('#admin_account_password').css('display', 'block')
}
else {
$('#admin_account_password').css('display', 'none')
}
});
$('#use_publicKey').click(function(){
if ($(this).is(':checked')){
$('#admin_account_publicKey').css('display', 'block')
}
else {
$('#admin_account_publicKey').css('display', 'none')
}
});
});
var config = {
'.chosen-select' : {},
'.chosen-select-deselect' : {allow_single_deselect:true},
'.chosen-select-no-single' : {disable_search_threshold:10},
'.chosen-select-no-results': {no_results_text:'Oops, nothing found!'},
'.chosen-select-width' : {width:"95%"}
};
for (var selector in config) {
$(selector).chosen(config[selector]);
}
</script>
<script src="/static/js/cropper/cropper.min.js"></script>
<script src="/static/js/datapicker/bootstrap-datepicker.js"></script>
{% endblock %}

View File

@ -0,0 +1,120 @@
{% extends 'base.html' %}
{% block self_head_css_js %}
<link href="/static/css/plugins/datapicker/datepicker3.css" rel="stylesheet">
<link href="/static/css/plugins/chosen/chosen.css" rel="stylesheet">
<script src="/static/js/plugins/chosen/chosen.jquery.js"></script>
{% endblock %}
{% load mytags %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-10">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>填写基本信息</h5>
<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>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<form method="post" id="sudoForm" class="form-horizontal" action="">
{% if error %}
<div class="alert alert-warning text-center">{{ error }}</div>
{% endif %}
{% if msg %}
<div class="alert alert-success text-center">{{ msg }}</div>
{% endif %}
<div class="form-group">
<label for="sudo_name" class="col-sm-2 control-label">命令别名<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<input id="sudo_name" name="sudo_name" placeholder="Sudo Command Alias" type="text" class="form-control" value={{ sudo.name }}>
</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">
<textarea id="sudo_commands" name="sudo_commands" class="form-control" rows="3">{{ sudo.commands }}</textarea>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="sudo_comment" class="col-sm-2 control-label">备注</label>
<div class="col-sm-8">
<input id="sudo_comment" name="sudo_comment" placeholder="Sudo Comment" type="text" class="form-control" value={{ sudo.commnet }}>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">取消</button>
<button id="submit_button" class="btn btn-primary" type="submit">确认保存</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block self_footer_js %}
<script>
$(document).ready(function(){
$("input.role").click(function(){
if($("input.role[value=GA]").is( ":checked" )){
$("#admin_groups").css("display", 'none');
}
else {
$("#admin_groups").css("display", 'block');
}
});
$('#use_password').click(function(){
if ($(this).is(':checked')){
$('#admin_account_password').css('display', 'block')
}
else {
$('#admin_account_password').css('display', 'none')
}
});
$('#use_publicKey').click(function(){
if ($(this).is(':checked')){
$('#admin_account_publicKey').css('display', 'block')
}
else {
$('#admin_account_publicKey').css('display', 'none')
}
});
});
var config = {
'.chosen-select' : {},
'.chosen-select-deselect' : {allow_single_deselect:true},
'.chosen-select-no-single' : {disable_search_threshold:10},
'.chosen-select-no-results': {no_results_text:'Oops, nothing found!'},
'.chosen-select-width' : {width:"95%"}
};
for (var selector in config) {
$(selector).chosen(config[selector]);
}
</script>
<script src="/static/js/cropper/cropper.min.js"></script>
<script src="/static/js/datapicker/bootstrap-datepicker.js"></script>
{% endblock %}

View File

@ -0,0 +1,112 @@
{% extends 'base.html' %}
{% load mytags %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-10">
<div class="ibox float-e-margins">
<div>
{% if error %}
<div class="alert alert-warning text-center">{{ error }}</div>
{% endif %}
{% if msg %}
<div class="alert alert-success text-center">{{ msg }}</div>
{% endif %}
</div>
<div class="ibox-title">
<h5> 所有Sudo命令别名</h5>
<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>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="">
<a href="/jperm/sudo/perm_sudo_add/" class="btn btn-sm btn-primary "> 添加别名 </a>
<a id="del_btn" class="btn btn-sm btn-danger "> 删除所选 </a>
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
<input type="text" class="form-control input-sm" id="search_input" name="search" placeholder="Search">
<div class="input-group-btn">
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
- 搜索 -
</button>
</div>
</div>
</form>
</div>
<table class="table table-striped table-bordered table-hover " id="editable" >
<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 id="edittbody">
{% for sudo in sudos %}
<tr class="gradeX" id={{ sudo.id }}>
<td class="text-center"> {{ sudo.name }} </td>
<td class="text-center"> {{ sudo.commands }} </td>
<td class="text-center"> {{ sudo.date_added | date:"Y-m-d H:i:s"}} </td>
<td class="text-center">
{# <a href="/jperm/sudo/perm_sudo_detail/?id={{ sudo.id }}" class="btn btn-xs btn-primary">详情</a>#}
<a href="/jperm/sudo/perm_sudo_edit/?id={{ sudo.id }}" class="btn btn-xs btn-info">编辑</a>
<button onclick="remove_sudo({{ sudo.id }})" class="btn btn-xs btn-danger">删除</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
<div class="dataTables_info" id="editable_info" role="status" aria-live="polite">
Showing {{ users.start_index }} to {{ users.end_index }} of {{ p.count }} entries
</div>
</div>
{% include 'paginator.html' %}
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function remove_sudo(sudo_id){
if (confirm("确认删除")) {
$.ajax({
type: "POST",
url: "/jperm/sudo/perm_sudo_delete/",
data: "id=" + sudo_id,
success: function(msg){
alert( "成功: " + msg );
var del_row = $('tbody#edittbody>tr#' + sudo_id);
del_row.remove()
},
error: function (msg) {
alert("失败: " + msg)
}
});
}
}
</script>
{% endblock %}

View File

@ -0,0 +1,126 @@
## Sudoers allows particular users to run various commands as
## 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
## 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
## These are groups of related commands...
## Networking
Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool
## Installation and management of software
Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum
## Services
Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig
## Updating the locate database
Cmnd_Alias LOCATE = /usr/bin/updatedb
## Storage
Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount
## Delegating permissions
Cmnd_Alias DELEGATING = /bin/chown, /bin/chmod, /bin/chgrp
## Processes
Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall
## Drivers
Cmnd_Alias DRIVERS = /sbin/modprobe
## Custom
{% if {{ role_custom }} %}
{% Cmnd_Alias CUSTOM = {{ role_custom }} %}
{% endif %}
# Defaults specification
#
# 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
{{ role_name }} ALL = {{ role_chosen }}
## 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

View File

@ -32,10 +32,12 @@
<li class="dept_perm_list dept_perm_edit"> <li class="dept_perm_list dept_perm_edit">
<a href="/jperm/rule/">授权规则</a> <a href="/jperm/rule/">授权规则</a>
</li> </li>
<li class="sudo_list sudo_edit sudo_add cmd_list cmd_edit cmd_add sudo_detail"> <li class="sudo_list sudo_edit sudo_add cmd_list cmd_edit cmd_add sudo_detail">
<a href="/jperm/role/">系统角色</a> <a href="/jperm/role/">系统角色</a>
</li> </li>
<li class="sudo_list sudo_edit sudo_add cmd_list cmd_edit cmd_add sudo_detail">
<a href="/jperm/sudo/">Sudo命令</a>
</li>
<li class="apply_show online"><a href="/jperm/apply_show/online/">权限审批</a></li> <li class="apply_show online"><a href="/jperm/apply_show/online/">权限审批</a></li>
<li class="apply_show online"><a href="/jperm/log/">授权记录</a></li> <li class="apply_show online"><a href="/jperm/log/">授权记录</a></li>
</ul> </ul>