Commit b8cb6f42 authored by wangyong's avatar wangyong

Merge branch 'dev' into cmdb

parents d25e2362 a143797a
...@@ -37,6 +37,7 @@ nosetests.xml ...@@ -37,6 +37,7 @@ nosetests.xml
.mr.developer.cfg .mr.developer.cfg
.project .project
.pydevproject .pydevproject
*.log
logs/* logs/*
keys/* keys/*
jumpserver.conf jumpserver.conf
......
This diff is collapsed.
sphinx-me==0.3 sphinx-me==0.3
django==1.6 django==1.6
python-ldap==2.4.19
pycrypto==2.6.1 pycrypto==2.6.1
paramiko==1.15.2 paramiko==1.15.2
ecdsa==0.13 ecdsa==0.13
...@@ -9,4 +8,9 @@ django-uuidfield==0.5.0 ...@@ -9,4 +8,9 @@ django-uuidfield==0.5.0
psutil==2.2.1 psutil==2.2.1
xlsxwriter==0.7.7 xlsxwriter==0.7.7
xlrd==0.9.4 xlrd==0.9.4
django-bootstrap-form django-bootstrap-form
\ No newline at end of file tornado
ansible
pyinotify
passlib
argparse
\ No newline at end of file
...@@ -145,7 +145,7 @@ def asset_add(request): ...@@ -145,7 +145,7 @@ def asset_add(request):
asset_save = af_post.save(commit=False) asset_save = af_post.save(commit=False)
if not use_default_auth: if not use_default_auth:
password = request.POST.get('password', '') password = request.POST.get('password', '')
password_encode = CRYPTOR.encrypt(password) password_encode = password
asset_save.password = password_encode asset_save.password = password_encode
if not ip: if not ip:
asset_save.ip = hostname asset_save.ip = hostname
......
...@@ -15,11 +15,11 @@ from utils import get_rand_pass ...@@ -15,11 +15,11 @@ from utils import get_rand_pass
import os.path import os.path
API_DIR = os.path.dirname(os.path.abspath(__file__)) 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),
...@@ -61,7 +61,7 @@ class MyInventory(object): ...@@ -61,7 +61,7 @@ class MyInventory(object):
[{"hostname": "10.10.10.10", "port": "22", "username": "test", "password": "mypass"}, ...] [{"hostname": "10.10.10.10", "port": "22", "username": "test", "password": "mypass"}, ...]
""" """
self.resource = resource self.resource = resource
self.inventory = Inventory() self.inventory = Inventory(host_list=[])
self.gen_inventory() self.gen_inventory()
def add_group(self, hosts, groupname, groupvars=None): def add_group(self, hosts, groupname, groupvars=None):
...@@ -79,14 +79,17 @@ class MyInventory(object): ...@@ -79,14 +79,17 @@ class MyInventory(object):
for host in hosts: for host in hosts:
# set connection variables # set connection variables
hostname = host.get("hostname") hostname = host.get("hostname")
hostip = host.get('ip', hostname)
hostport = host.get("port") hostport = host.get("port")
username = host.get("username") username = host.get("username")
password = host.get("password") password = host.get("password")
ssh_key = host.get("ssh_key")
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', hostip)
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)
my_host.set_variable('ansible_ssh_private_key_file', ssh_key)
# 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"]:
...@@ -101,47 +104,78 @@ class MyInventory(object): ...@@ -101,47 +104,78 @@ 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, 'my_group') self.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.add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))
class MyRunner(MyInventory):
"""
This is a General object for parallel execute modules.
"""
def __init__(self, *args, **kwargs):
super(MyRunner, self).__init__(*args, **kwargs)
self.results = {}
def run(self, module_name, module_args='', timeout=10, forks=10, pattern='',
sudo=False, sudo_user='root', sudo_pass=''):
"""
run module from andible ad-hoc.
module_name: ansible module_name
module_args: ansible module args
"""
hoc = Runner(module_name=module_name,
module_args=module_args,
timeout=timeout,
inventory=self.inventory,
pattern=pattern,
forks=forks,
become=sudo,
become_method='sudo',
become_user=sudo_user,
become_pass=sudo_pass
)
self.results = hoc.run()
return self.results
class Command(MyInventory): class Command(MyInventory):
""" """
this is a command object for parallel execute command. this is a command object for parallel execute command.
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(Command, self).__init__(*args, **kwargs) super(Command, self).__init__(*args, **kwargs)
self.results = '' self.results = {}
def run(self, command, module_name="command", timeout=5, forks=10, group='my_group'): def run(self, command, module_name="command", timeout=10, forks=10, pattern='*'):
""" """
run command from andible ad-hoc. run command from andible ad-hoc.
command : 必须是一个需要执行的命令字符串, 比如 command : 必须是一个需要执行的命令字符串, 比如
'uname -a' 'uname -a'
""" """
data = {}
if module_name not in ["raw", "command", "shell"]: if module_name not in ["raw", "command", "shell"]:
raise CommandValueError("module_name", raise CommandValueError("module_name",
"module_name must be of the 'raw, command, shell'") "module_name must be of the 'raw, command, shell'")
hoc = Runner(module_name=module_name, hoc = Runner(module_name=module_name,
module_args=command, module_args=command,
timeout=timeout, timeout=timeout,
inventory=self.inventory, inventory=self.inventory,
subset=group, pattern=pattern,
forks=forks forks=forks,
) )
self.results = hoc.run() self.results = hoc.run()
if self.stdout: if self.stdout:
return {"ok": self.stdout} data['ok'] = self.stdout
else: if self.stderr:
msg = [] data['err'] = self.stderr
if self.stderr: if self.dark:
msg.append(self.stderr) data['dark'] = self.dark
if self.dark:
msg.append(self.dark) return data
return {"failed": msg}
@property @property
def raw_results(self): def raw_results(self):
...@@ -172,7 +206,7 @@ class Command(MyInventory): ...@@ -172,7 +206,7 @@ class Command(MyInventory):
result = {} result = {}
all = self.results.get("contacted") all = self.results.get("contacted")
for key, value in all.iteritems(): for key, value in all.iteritems():
result[key] = value.get("stdout") result[key] = value.get("stdout")
return result return result
@property @property
...@@ -183,7 +217,8 @@ class Command(MyInventory): ...@@ -183,7 +217,8 @@ class Command(MyInventory):
result = {} result = {}
all = self.results.get("contacted") all = self.results.get("contacted")
for key, value in all.iteritems(): for key, value in all.iteritems():
result[key] = { if value.get("stderr") or value.get("warnings"):
result[key] = {
"stderr": value.get("stderr"), "stderr": value.get("stderr"),
"warnings": value.get("warnings"),} "warnings": value.get("warnings"),}
return result return result
...@@ -203,7 +238,7 @@ class Tasks(Command): ...@@ -203,7 +238,7 @@ 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='my_group'): 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 : 必须是一个需要执行的命令字符串, 比如
...@@ -214,7 +249,8 @@ class Tasks(Command): ...@@ -214,7 +249,8 @@ class Tasks(Command):
timeout=timeout, timeout=timeout,
inventory=self.inventory, inventory=self.inventory,
subset=group, subset=group,
forks=forks pattern=pattern,
forks=forks,
) )
self.results = hoc.run() self.results = hoc.run()
...@@ -368,7 +404,7 @@ class Tasks(Command): ...@@ -368,7 +404,7 @@ class Tasks(Command):
result[key] = { result[key] = {
"all_ip": setup.get("ansible_all_ipv4_addresses"), "all_ip": setup.get("ansible_all_ipv4_addresses"),
"hostname" : setup.get("ansible_hostname" ), "hostname" : setup.get("ansible_hostname"),
"default_ip": setup.get("ansible_default_ipv4").get("address"), "default_ip": setup.get("ansible_default_ipv4").get("address"),
"default_mac": setup.get("ansible_default_ipv4").get("macaddress"), "default_mac": setup.get("ansible_default_ipv4").get("macaddress"),
"product_name": setup.get("ansible_product_name"), "product_name": setup.get("ansible_product_name"),
...@@ -385,8 +421,6 @@ class Tasks(Command): ...@@ -385,8 +421,6 @@ class Tasks(Command):
return {"status": "failed", "msg": self.msg} if self.msg else {"status": "ok", "result": result} return {"status": "failed", "msg": self.msg} if self.msg else {"status": "ok", "result": result}
class CustomAggregateStats(callbacks.AggregateStats): class CustomAggregateStats(callbacks.AggregateStats):
""" """
Holds stats about per-host activity during playbook runs. Holds stats about per-host activity during playbook runs.
...@@ -405,7 +439,6 @@ class CustomAggregateStats(callbacks.AggregateStats): ...@@ -405,7 +439,6 @@ class CustomAggregateStats(callbacks.AggregateStats):
self.results.append(runner_results) self.results.append(runner_results)
def summarize(self, host): def summarize(self, host):
""" """
Return information about a particular host Return information about a particular host
...@@ -425,7 +458,6 @@ class MyPlaybook(MyInventory): ...@@ -425,7 +458,6 @@ class MyPlaybook(MyInventory):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(MyPlaybook, self).__init__(*args, **kwargs) super(MyPlaybook, self).__init__(*args, **kwargs)
def run(self, playbook_relational_path, extra_vars=None): def run(self, playbook_relational_path, extra_vars=None):
""" """
run ansible playbook, run ansible playbook,
...@@ -464,7 +496,6 @@ class App(MyPlaybook): ...@@ -464,7 +496,6 @@ class App(MyPlaybook):
if __name__ == "__main__": if __name__ == "__main__":
pass
# resource = { # resource = {
# "group1": { # "group1": {
...@@ -472,8 +503,10 @@ if __name__ == "__main__": ...@@ -472,8 +503,10 @@ if __name__ == "__main__":
# "vars" : {"var1": "value1", "var2": "value2"}, # "vars" : {"var1": "value1", "var2": "value2"},
# }, # },
# } # }
# command = Command(resource)
# print command.run("who", group="group1") resource = [{"hostname": "127.0.0.1", "port": "22", "username": "yumaojun", "password": "yusky0902"}]
command = Command(resource)
print command.run("who")
# 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)
......
...@@ -5,20 +5,6 @@ from jasset.models import Asset, AssetGroup ...@@ -5,20 +5,6 @@ from jasset.models import Asset, AssetGroup
from juser.models import User, UserGroup from juser.models import User, UserGroup
class PermLog(models.Model):
datetime = models.DateTimeField(auto_now_add=True)
action = models.CharField(max_length=100, null=True, blank=True, default='')
results = models.CharField(max_length=1000, null=True, blank=True, default='')
is_success = models.BooleanField(default=False)
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 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='')
...@@ -32,14 +18,13 @@ class PermRole(models.Model): ...@@ -32,14 +18,13 @@ class PermRole(models.Model):
class PermRule(models.Model): class PermRule(models.Model):
date_added = models.DateTimeField(auto_now=True) date_added = models.DateTimeField(auto_now=True)
name = models.CharField(max_length=100) name = models.CharField(max_length=100, unique=True)
comment = models.CharField(max_length=100) comment = models.CharField(max_length=100)
asset = models.ManyToManyField(Asset, related_name='perm_rule') asset = models.ManyToManyField(Asset, related_name='perm_rule')
asset_group = models.ManyToManyField(AssetGroup, related_name='perm_rule') asset_group = models.ManyToManyField(AssetGroup, related_name='perm_rule')
user = models.ManyToManyField(User, related_name='perm_rule') user = models.ManyToManyField(User, related_name='perm_rule')
user_group = models.ManyToManyField(UserGroup, related_name='perm_rule') user_group = models.ManyToManyField(UserGroup, related_name='perm_rule')
role = models.ManyToManyField(PermRole, related_name='perm_rule') role = models.ManyToManyField(PermRole, related_name='perm_rule')
ssh_type = models.BooleanField()
def __unicode__(self): def __unicode__(self):
return self.name return self.name
\ No newline at end of file
This diff is collapsed.
...@@ -13,11 +13,4 @@ urlpatterns = patterns('jperm.views', ...@@ -13,11 +13,4 @@ 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'^log/$', log),
(r'^sys_user_add/$', sys_user_add),
(r'^perm_user_list/$', sys_user_list),
(r'^sys_user_del/$', sys_user_del),
(r'^sys_user_edit/$', sys_user_edit),
) )
...@@ -4,7 +4,7 @@ import random ...@@ -4,7 +4,7 @@ import random
import os.path import os.path
from paramiko.rsakey import RSAKey from paramiko.rsakey import RSAKey
from os import chmod, mkdir from jumpserver.api import mkdir
from uuid import uuid4 from uuid import uuid4
from jumpserver.settings import KEY_DIR from jumpserver.settings import KEY_DIR
...@@ -45,13 +45,13 @@ def gen_keys(): ...@@ -45,13 +45,13 @@ def gen_keys():
:return: 返回目录名(uuid) :return: 返回目录名(uuid)
""" """
key_basename = "key-" + uuid4().hex key_basename = "key-" + uuid4().hex
key_path_dir = os.path.join(KEY_DIR, key_basename) key_path_dir = os.path.join(KEY_DIR, 'role_key', key_basename)
mkdir(key_path_dir, 0700) mkdir(key_path_dir, 0755)
key = RSAKey.generate(2048) key = RSAKey.generate(2048)
private_key = os.path.join(key_path_dir, 'id_rsa') private_key = os.path.join(key_path_dir, 'id_rsa')
public_key = os.path.join(key_path_dir, 'id_rsa.pub') public_key = os.path.join(key_path_dir, 'id_rsa.pub')
key.write_private_key_file(private_key) key.write_private_key_file(private_key)
os.chmod(private_key, 0644)
with open(public_key, 'w') as content_file: with open(public_key, 'w') as content_file:
for data in [key.get_name(), for data in [key.get_name(),
...@@ -62,8 +62,6 @@ def gen_keys(): ...@@ -62,8 +62,6 @@ def gen_keys():
return key_path_dir return key_path_dir
if __name__ == "__main__": if __name__ == "__main__":
print gen_keys() print gen_keys()
......
This diff is collapsed.
...@@ -3,26 +3,27 @@ ...@@ -3,26 +3,27 @@
import os, sys, time, re import os, sys, time, re
from Crypto.Cipher import AES from Crypto.Cipher import AES
import crypt import crypt
import pwd
from binascii import b2a_hex, a2b_hex from binascii import b2a_hex, a2b_hex
import hashlib import hashlib
import datetime import datetime
import random import random
import subprocess import subprocess
from settings import * import json
import logging
from settings import *
from django.core.paginator import Paginator, EmptyPage, InvalidPage from django.core.paginator import Paginator, EmptyPage, InvalidPage
from django.http import HttpResponse, Http404 from django.http import HttpResponse, Http404
from django.template import RequestContext from django.template import RequestContext
from juser.models import User, UserGroup from juser.models import User, UserGroup
from jasset.models import Asset, AssetGroup
# from jlog.models import Log
from jlog.models import Log, TtyLog from jlog.models import Log, TtyLog
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from jasset.models import Asset, AssetGroup
from jperm.models import PermRule, PermRole
from jumpserver.models import Setting
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.core.mail import send_mail from django.core.mail import send_mail
import json
import logging
def set_log(level): def set_log(level):
...@@ -30,11 +31,15 @@ def set_log(level): ...@@ -30,11 +31,15 @@ def set_log(level):
return a log file object return a log file object
根据提示设置log打印 根据提示设置log打印
""" """
log_file = os.path.join(LOG_DIR, 'jumpserver.log')
if not os.path.isfile(log_file):
os.mknod(log_file)
os.chmod(log_file, 0777)
log_level_total = {'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARN, 'error': logging.ERROR, log_level_total = {'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARN, 'error': logging.ERROR,
'critical': logging.CRITICAL} 'critical': logging.CRITICAL}
logger_f = logging.getLogger('jumpserver') logger_f = logging.getLogger('jumpserver')
logger_f.setLevel(logging.DEBUG) logger_f.setLevel(logging.DEBUG)
fh = logging.FileHandler(os.path.join(LOG_DIR, 'jumpserver.log')) fh = logging.FileHandler(log_file)
fh.setLevel(log_level_total.get(level, logging.DEBUG)) fh.setLevel(log_level_total.get(level, logging.DEBUG))
formatter = logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s - %(message)s') formatter = logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter) fh.setFormatter(formatter)
...@@ -42,6 +47,63 @@ def set_log(level): ...@@ -42,6 +47,63 @@ def set_log(level):
return logger_f return logger_f
def get_asset_info(asset):
default = get_object(Setting, name='default')
info = {'hostname': asset.hostname, 'ip': asset.ip}
if asset.use_default_auth:
if default:
info['port'] = default.default_port
info['username'] = default.default_user
info['password'] = CRYPTOR.decrypt(default.default_password)
info['ssh_key'] = default.default_pri_key_path
else:
info['port'] = asset.port
info['username'] = asset.username
info['password'] = asset.password
return info
def get_role(user, asset):
roles = []
rules = PermRule.objects.filter(user=user, asset=asset)
for rule in rules:
roles.extend(list(rule.role.all()))
return roles
def get_role_key(user, role):
"""
由于role的key的权限是所有人可以读的, ansible要求为600,所以拷贝一份到特殊目录
:param user:
:param role:
:return: self key path
"""
user_role_key_dir = os.path.join(KEY_DIR, 'user')
user_role_key_path = os.path.join(user_role_key_dir, '%s_%s.pem' % (user.username, role.name))
mkdir(user_role_key_dir, mode=777)
if not os.path.isfile(user_role_key_path):
with open(os.path.join(role.key_path, 'id_rsa')) as fk:
with open(user_role_key_path, 'w') as fu:
fu.write(fk.read())
print user_role_key_path, user.username
chown(user_role_key_path, user.username)
os.chmod(user_role_key_path, 0600)
return user_role_key_path
def chown(path, user, group=''):
if not group:
group = user
try:
uid = pwd.getpwnam(user).pw_uid
gid = pwd.getpwnam(group).pw_gid
os.chown(path, uid, gid)
except KeyError:
pass
def page_list_return(total, current=1): def page_list_return(total, current=1):
""" """
page page
...@@ -159,8 +221,7 @@ class PyCrypt(object): ...@@ -159,8 +221,7 @@ class PyCrypt(object):
try: try:
plain_text = cryptor.decrypt(a2b_hex(text)) plain_text = cryptor.decrypt(a2b_hex(text))
except TypeError: except TypeError:
# raise ServerError('Decrypt password error, TYpe error.') raise ServerError('Decrypt password error, TYpe error.')
pass
return plain_text.rstrip('\0') return plain_text.rstrip('\0')
...@@ -197,9 +258,9 @@ def require_role(role='user'): ...@@ -197,9 +258,9 @@ def require_role(role='user'):
def _deco(func): def _deco(func):
def __deco(request, *args, **kwargs): def __deco(request, *args, **kwargs):
request.session['pre_url'] = request.path
if not request.user.is_authenticated(): if not request.user.is_authenticated():
return HttpResponseRedirect('/login/') return HttpResponseRedirect('/login/')
if role == 'admin': if role == 'admin':
# if request.session.get('role_id', 0) < 1: # if request.session.get('role_id', 0) < 1:
if request.user.role == 'CU': if request.user.role == 'CU':
...@@ -388,15 +449,16 @@ def bash(cmd): ...@@ -388,15 +449,16 @@ def bash(cmd):
return subprocess.call(cmd, shell=True) return subprocess.call(cmd, shell=True)
def mkdir(dir_name, username='root', mode=0755): def mkdir(dir_name, username='', mode=0755):
""" """
insure the dir exist and mode ok insure the dir exist and mode ok
目录存在,如果不存在就建立,并且权限正确 目录存在,如果不存在就建立,并且权限正确
""" """
if not os.path.isdir(dir_name): if not os.path.isdir(dir_name):
os.makedirs(dir_name) os.makedirs(dir_name)
bash("chown %s:%s '%s'" % (username, username, dir_name)) os.chmod(dir_name, mode)
os.chmod(dir_name, mode) if username:
chown(dir_name, username)
def http_success(request, msg): def http_success(request, msg):
...@@ -414,4 +476,3 @@ def my_render(template, data, request): ...@@ -414,4 +476,3 @@ def my_render(template, data, request):
CRYPTOR = PyCrypt(KEY) CRYPTOR = PyCrypt(KEY)
logger = set_log(LOG_LEVEL) logger = set_log(LOG_LEVEL)
KEY_DIR = os.path.join(BASE_DIR, 'keys')
...@@ -17,8 +17,8 @@ config = ConfigParser.ConfigParser() ...@@ -17,8 +17,8 @@ config = ConfigParser.ConfigParser()
BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
config.read(os.path.join(BASE_DIR, 'jumpserver.conf')) config.read(os.path.join(BASE_DIR, 'jumpserver.conf'))
KEY_DIR = os.path.join(BASE_DIR, 'keys')
KEY_DIR = os.path.join(BASE_DIR, 'role_keys')
DB_HOST = config.get('db', 'host') DB_HOST = config.get('db', 'host')
DB_PORT = config.getint('db', 'port') DB_PORT = config.getint('db', 'port')
...@@ -37,7 +37,7 @@ EMAIL_TIMEOUT = 5 ...@@ -37,7 +37,7 @@ EMAIL_TIMEOUT = 5
# ======== Log ========== # ======== Log ==========
LOG_DIR = os.path.join(BASE_DIR, 'logs') LOG_DIR = os.path.join(BASE_DIR, 'logs')
SSH_KEY_DIR = os.path.join(BASE_DIR, 'role_keys') SSH_KEY_DIR = os.path.join(BASE_DIR, 'keys/role_keys')
KEY = config.get('base', 'key') KEY = config.get('base', 'key')
URL = config.get('base', 'url') URL = config.get('base', 'url')
LOG_LEVEL = config.get('base', 'log') LOG_LEVEL = config.get('base', 'log')
......
...@@ -226,3 +226,14 @@ def ip_str_to_list(ip_str): ...@@ -226,3 +226,14 @@ 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='key_exist')
def key_exist(username):
"""
ssh key is exist or not
"""
if os.path.isfile(os.path.join(KEY_DIR, 'user', username)):
return True
else:
return False
...@@ -15,7 +15,6 @@ from jumpserver.api import * ...@@ -15,7 +15,6 @@ from jumpserver.api import *
from jumpserver.models import Setting from jumpserver.models import Setting
from django.contrib.auth import authenticate, login, logout from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from settings import BASE_DIR
from jlog.models import Log from jlog.models import Log
...@@ -80,18 +79,19 @@ def index_cu(request): ...@@ -80,18 +79,19 @@ def index_cu(request):
# user = get_object(User, id=user_id) # user = get_object(User, id=user_id)
login_types = {'L': 'LDAP', 'M': 'MAP'} login_types = {'L': 'LDAP', 'M': 'MAP'}
username = request.user.username username = request.user.username
posts = Asset.object.all() # TODO: need fix,liuzheng need Asset help
host_count = len(posts) # posts = Asset.object.all()
# host_count = len(posts)
new_posts = [] #
post_five = [] # new_posts = []
for post in posts: # post_five = []
if len(post_five) < 5: # for post in posts:
post_five.append(post) # if len(post_five) < 5:
else: # post_five.append(post)
new_posts.append(post_five) # else:
post_five = [] # new_posts.append(post_five)
new_posts.append(post_five) # post_five = []
# new_posts.append(post_five)
return render_to_response('index_cu.html', locals(), context_instance=RequestContext(request)) return render_to_response('index_cu.html', locals(), context_instance=RequestContext(request))
...@@ -235,7 +235,7 @@ def Login(request): ...@@ -235,7 +235,7 @@ def Login(request):
request.session['role_id'] = 1 request.session['role_id'] = 1
else: else:
request.session['role_id'] = 0 request.session['role_id'] = 0
return HttpResponseRedirect(request.GET.get('next', '/'), ) return HttpResponseRedirect(request.session.get('pre_url', '/'))
# response.set_cookie('username', username, expires=604800) # response.set_cookie('username', username, expires=604800)
# response.set_cookie('seed', PyCrypt.md5_crypt(password), expires=604800) # response.set_cookie('seed', PyCrypt.md5_crypt(password), expires=604800)
# return response # return response
...@@ -268,7 +268,7 @@ def setting(request): ...@@ -268,7 +268,7 @@ def setting(request):
if '' in [username, port] and ('' in password or '' in private_key): if '' in [username, port] and ('' in password or '' in private_key):
return HttpResponse('所填内容不能为空, 且密码和私钥填一个') return HttpResponse('所填内容不能为空, 且密码和私钥填一个')
else: else:
private_key_path = os.path.join(BASE_DIR, 'role_keys', 'default', 'default_private_key.pem') private_key_path = os.path.join(BASE_DIR, 'keys/role_keys', 'default', 'default_private_key.pem')
if private_key: if private_key:
with open(private_key_path, 'w') as f: with open(private_key_path, 'w') as f:
f.write(private_key) f.write(private_key)
......
...@@ -123,27 +123,27 @@ def db_del_user(username): ...@@ -123,27 +123,27 @@ def db_del_user(username):
def gen_ssh_key(username, password='', def gen_ssh_key(username, password='',
key_dir=os.path.join(KEY_DIR, 'user'), key_dir=os.path.join(KEY_DIR, 'user'),
authorized_keys=True, home="/home", length=2048): authorized_keys=True, home="/home", length=2048):
""" """
generate a user ssh key in a property dir generate a user ssh key in a property dir
生成一个用户ssh密钥对 生成一个用户ssh密钥对
""" """
logger.debug('生成ssh key, 并设置authorized_keys')
private_key_file = os.path.join(key_dir, username) private_key_file = os.path.join(key_dir, username)
mkdir(private_key_file, username) mkdir(key_dir, mode=777)
if os.path.isfile(private_key_file): if os.path.isfile(private_key_file):
os.unlink(private_key_file) os.unlink(private_key_file)
ret = bash('echo -e "y\n"|ssh-keygen -t rsa -f %s -b %s -P "%s"' % (private_key_file, length, password)) ret = bash('echo -e "y\n"|ssh-keygen -t rsa -f %s -b %s -P "%s"' % (private_key_file, length, password))
if authorized_keys: if authorized_keys:
auth_key_dir = os.path.join(home, username, '.ssh') auth_key_dir = os.path.join(home, username, '.ssh')
mkdir(auth_key_dir, username, mode=0700) mkdir(auth_key_dir, mode=0700)
authorized_key_file = os.path.join(auth_key_dir, 'authorized_keys') authorized_key_file = os.path.join(auth_key_dir, 'authorized_keys')
with open(private_key_file+'.pub') as pub_f: with open(private_key_file+'.pub') as pub_f:
with open(authorized_key_file, 'w') as auth_f: with open(authorized_key_file, 'w') as auth_f:
auth_f.write(pub_f.read()) auth_f.write(pub_f.read())
os.chmod(authorized_key_file, 0600) os.chmod(authorized_key_file, 0600)
bash('chown %s:%s %s' % (username, username, authorized_key_file)) chown(authorized_key_file, username)
def server_add_user(username, password, ssh_key_pwd, ssh_key_login_need): def server_add_user(username, password, ssh_key_pwd, ssh_key_login_need):
......
...@@ -96,36 +96,37 @@ def group_edit(request): ...@@ -96,36 +96,37 @@ def group_edit(request):
if request.method == 'GET': if request.method == 'GET':
group_id = request.GET.get('id', '') group_id = request.GET.get('id', '')
user_group = get_object(UserGroup, id=group_id) # user_group = get_object(UserGroup, id=group_id)
if user_group: user_group = UserGroup.objects.get(id=group_id)
users_all = User.objects.all() users_selected = User.objects.filter(group=user_group)
users_selected = user_group.user_set.all() users_remain = User.objects.filter(~Q(group=user_group))
users_remain = [user for user in users_all if user not in users_selected] users_all = User.objects.all()
else: elif request.method == 'POST':
group_id = request.POST.get('group_id', '') group_id = request.POST.get('group_id', '')
group_name = request.POST.get('group_name', '') group_name = request.POST.get('group_name', '')
comment = request.POST.get('comment', '') comment = request.POST.get('comment', '')
users_selected = request.POST.getlist('users_selected') users_selected = request.POST.getlist('users_selected')
users = []
try: try:
if '' in [group_id, group_name]: if '' in [group_id, group_name]:
raise ServerError('组名不能为空') raise ServerError('组名不能为空')
user_group = get_object(UserGroup, id=group_id) if len(UserGroup.objects.filter(name=group_name)) > 1:
other_group = get_object(UserGroup, name=group_name)
if other_group and other_group.id != int(group_id):
raise ServerError(u'%s 用户组已存在' % group_name) raise ServerError(u'%s 用户组已存在' % group_name)
# add user group
for user in User.objects.filter(id__in=users_selected):
user.group.add(UserGroup.objects.get(id=group_id))
# delete user group
user_group = UserGroup.objects.get(id=group_id)
for user in [user for user in User.objects.filter(group=user_group) if user not in User.objects.filter(id__in=users_selected)]:
user_group_all = user.group.all()
user.group.clear()
for g in user_group_all:
if g == user_group:
continue
user.group.add(g)
for user_id in users_selected:
users.extend(User.objects.filter(id=user_id))
if user_group:
user_group.update(name=group_name, comment=comment)
user_group.user_set.clear()
user_group.user_set = users
except ServerError, e: except ServerError, e:
error = e error = e
...@@ -133,8 +134,8 @@ def group_edit(request): ...@@ -133,8 +134,8 @@ def group_edit(request):
return HttpResponseRedirect('/juser/group_list/') return HttpResponseRedirect('/juser/group_list/')
else: else:
users_all = User.objects.all() users_all = User.objects.all()
users_selected = user_group.user_set.all() users_selected = User.objects.filter(group=user_group)
users_remain = [user for user in users_all if user not in users_selected] users_remain = User.objects.filter(~Q(group=user_group))
return my_render('juser/group_edit.html', locals(), request) return my_render('juser/group_edit.html', locals(), request)
......
看山是山,看水是水
看山不是山,看水不是水
看山是山,看水是水
永远年轻,永远热泪盈眶
- hosts: the_del_group
tasks:
- name: del user
user: name={{ item }} state=absent remove=yes
with_items: [ the_del_users ]
- hosts: the_new_group
tasks:
- name: add user
user: name={{ item }} state=present
with_items: [ the_new_users ]
- name: .ssh direcotory
file: name=/home/{{ item }}/.ssh mode=700 owner={{ item }} group={{ item }} state=directory
with_items: [ the_new_users ]
- name: set authorizied_file
copy: src=KEY_DIR/{{ item }}.pub dest=/home/{{ item }}/.ssh/authorizied_keys owner={{ item }} group={{ item }} mode=600
with_items: [ the_new_users ]
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<h1 class="no-margins"><a href="/juser/user_list/">{{ users.count}}</a></h1> <h1 class="no-margins"><a href="/juser/user_list/">{{ users.count}}</a></h1>
{# <div class="stat-percent font-bold text-success">{{ percent_user }} <i class="fa fa-bolt"></i></div>#}
<small>All user</small> <small>All user</small>
</div> </div>
</div> </div>
...@@ -27,7 +26,6 @@ ...@@ -27,7 +26,6 @@
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<h1 class="no-margins"><a href="/jasset/host_list/">{{ hosts.count }}</a></h1> <h1 class="no-margins"><a href="/jasset/host_list/">{{ hosts.count }}</a></h1>
{# <div class="stat-percent font-bold text-info">{{ percent_host }} <i class="fa fa-level-up"></i></div>#}
<small>All host</small> <small>All host</small>
</div> </div>
</div> </div>
...@@ -37,7 +35,7 @@ ...@@ -37,7 +35,7 @@
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<span class="label label-primary pull-right">Online</span> <span class="label label-primary pull-right">Online</span>
<h5>实时在线用户</h5> <h5>在线用户</h5>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_users">{{ online_user | length }}</span></a></h1> <h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_users">{{ online_user | length }}</span></a></h1>
...@@ -55,7 +53,6 @@ ...@@ -55,7 +53,6 @@
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_hosts">{{ online_host | length }}</span></a></h1> <h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_hosts">{{ online_host | length }}</span></a></h1>
{# <div class="stat-percent font-bold text-danger">{{ percent_online_host }} <i class="fa fa-level-down"></i></div>#}
<small>Connected host</small> <small>Connected host</small>
</div> </div>
</div> </div>
...@@ -169,7 +166,7 @@ ...@@ -169,7 +166,7 @@
</div> </div>
</div> </div>
<div class="ibox-content ibox-heading"> <div class="ibox-content ibox-heading">
<h3><i class="fa fa-user"></i> 一周Top10资产 </h3> <h3><i class="fa fa-inbox"></i> 一周Top10资产 </h3>
<small><i class="fa fa-map-marker"></i> 登录次数及最近一次登录记录. </small> <small><i class="fa fa-map-marker"></i> 登录次数及最近一次登录记录. </small>
</div> </div>
<div class="ibox-content inspinia-timeline"> <div class="ibox-content inspinia-timeline">
...@@ -309,14 +306,7 @@ ...@@ -309,14 +306,7 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<!--</div>-->
<!--<div class="col-xm-6" id="top10" style="width:50%;height:400px;"></div>-->
<!--<div class="col-xm-6" id="usertop10" style="width:50%;height:400px;"></div>-->
<!--<div class="row">-->
<!--<div class="col-lg-6" id="hosttop10" style="width:50%;height:400px; margin-top: 20px"></div>-->
<!--</div>-->
</div>
</div> </div>
{% endblock %} {% endblock %}
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
{{ af.ip|bootstrap_horizontal }} {{ af.ip|bootstrap_horizontal }}
<p class="col-sm-offset-2">Tips: 如果IP地址不填写, IP默认会设置与主机名一致</p> <p class="col-sm-offset-2">Tips: 如果IP地址不填写, IP默认会设置与主机名一致</p>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="j_group" class="col-sm-2 control-label">管理账号<span class="red-fonts"> *</span></label> <label for="j_group" class="col-sm-2 control-label">管理账号<span class="red-fonts"> *</span></label>
......
...@@ -54,17 +54,29 @@ ...@@ -54,17 +54,29 @@
<div class="col-sm-2"> <div class="col-sm-2">
<div class="radio i-checks"> <div class="radio i-checks">
<label> <label>
<<<<<<< HEAD
<input type="radio" checked="" value="no_action" id="no" name="use_default_auth" class="auth"><span> 不修改 </span>
=======
<input type="radio" checked="" value="" id="no" name="use_default_auth" class="auth"><span> 不修改 </span> <input type="radio" checked="" value="" id="no" name="use_default_auth" class="auth"><span> 不修改 </span>
>>>>>>> cmdb
</label> </label>
</div> </div>
<div class="radio i-checks"> <div class="radio i-checks">
<label> <label>
<<<<<<< HEAD
<input type="radio" id="default" name="use_default_auth" class="auth"><span> 使用默认 </span>
=======
<input type="radio" id="default" name="use_default_auth" class="auth" value="default"><span> 使用默认 </span> <input type="radio" id="default" name="use_default_auth" class="auth" value="default"><span> 使用默认 </span>
>>>>>>> cmdb
</label> </label>
</div> </div>
<div class="radio i-checks"> <div class="radio i-checks">
<label> <label>
<<<<<<< HEAD
<input type="radio" id="pass" name="use_default_auth" class="auth"><span> 用户名密码 </span>
=======
<input type="radio" id="pass" name="use_default_auth" class="auth" value="user_passwd"><span> 用户名密码 </span> <input type="radio" id="pass" name="use_default_auth" class="auth" value="user_passwd"><span> 用户名密码 </span>
>>>>>>> cmdb
</label> </label>
</div> </div>
</div> </div>
...@@ -126,6 +138,21 @@ ...@@ -126,6 +138,21 @@
</div> </div>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
<<<<<<< HEAD
$('#host_edit').click(function () {
var args = {};
var match = null;
var uuid = decodeURIComponent(location.search.substring(1));
var reg = /(?:([^&amp;]+)=([^&amp;]+))/g;
while((match = reg.exec(uuid))!==null){
args[match[1]] = match[2];
}
var ids = args['uuid'];
$('#uuid').val(ids)
});
=======
>>>>>>> cmdb
$('.auth').click(function(){ $('.auth').click(function(){
if ($(this).attr('id') == 'pass'){ if ($(this).attr('id') == 'pass'){
$('#admin_account').css('display', 'block') $('#admin_account').css('display', 'block')
......
...@@ -40,6 +40,13 @@ ...@@ -40,6 +40,13 @@
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group">
<label for="role_password_label" class="col-sm-2 control-label">角色密码<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<input id="role_password" name="role_password" type="password" class="form-control" value="{{ role_pass }}">
</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">
......
...@@ -7,6 +7,14 @@ ...@@ -7,6 +7,14 @@
<div class="row"> <div class="row">
<div class="col-lg-10"> <div class="col-lg-10">
<div class="ibox float-e-margins"> <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"> <div class="ibox-title">
<h5> 所有系统角色</h5> <h5> 所有系统角色</h5>
<div class="ibox-tools"> <div class="ibox-tools">
......
...@@ -67,16 +67,6 @@ ...@@ -67,16 +67,6 @@
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="row"> <div class="row">
<div class="form-group">
<label for="j_group" class="col-sm-2 control-label">使用密码</label>
<div class="col-sm-1">
<div class="radio i-checks">
<label>
<input type="checkbox" value="1" id="use_password" name="use_password">
</label>
</div>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="j_group" class="col-sm-2 control-label">使用秘钥</label> <label for="j_group" class="col-sm-2 control-label">使用秘钥</label>
<div class="col-sm-1"> <div class="col-sm-1">
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<form method="post" id="userForm" class="form-horizontal" action=""> <form method="post" id="ruleForm" class="form-horizontal" action="">
{% if error %} {% if error %}
<div class="alert alert-warning text-center">{{ error }}</div> <div class="alert alert-warning text-center">{{ error }}</div>
{% endif %} {% endif %}
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
<div class="alert alert-success text-center">{{ msg }}</div> <div class="alert alert-success text-center">{{ msg }}</div>
{% endif %} {% endif %}
<div class="form-group"> <div class="form-group">
<label for="username" class="col-sm-2 control-label">授权名称<span class="red-fonts">*</span></label> <label for="rulename" class="col-sm-2 control-label">授权名称<span class="red-fonts">*</span></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="rulename" name="rulename" placeholder="Rule Name" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}> <input id="rulename" name="rulename" placeholder="Rule Name" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}>
</div> </div>
...@@ -48,11 +48,11 @@ ...@@ -48,11 +48,11 @@
<option value="{{ user.name }}">{{ user.name }}</option> <option value="{{ user.name }}">{{ user.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
<span class="help-block m-b-none">用户和用户组必选一个</span>
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="usergroup" class="col-sm-2 control-label">用户组<span class="red-fonts">*</span></label> <label for="usergroup" class="col-sm-2 control-label">用户组</label>
<div class="col-sm-8"> <div class="col-sm-8">
<select name="usergroup" data-placeholder="请选择用户组" class="chosen-select form-control m-b" multiple tabindex="2"> <select name="usergroup" data-placeholder="请选择用户组" class="chosen-select form-control m-b" multiple tabindex="2">
{% for user_group in user_groups %} {% for user_group in user_groups %}
...@@ -70,11 +70,11 @@ ...@@ -70,11 +70,11 @@
<option value="{{ asset.ip }}">{{ asset.ip }}</option> <option value="{{ asset.ip }}">{{ asset.ip }}</option>
{% endfor %} {% endfor %}
</select> </select>
<span class="help-block m-b-none">资产和资产组必选一个</span>
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="assetgroup" class="col-sm-2 control-label">资产组<span class="red-fonts">*</span></label> <label for="assetgroup" class="col-sm-2 control-label">资产组</label>
<div class="col-sm-8"> <div class="col-sm-8">
<select name="assetgroup" data-placeholder="请选择资产组" class="chosen-select form-control m-b" multiple tabindex="2"> <select name="assetgroup" data-placeholder="请选择资产组" class="chosen-select form-control m-b" multiple tabindex="2">
{% for asset_group in asset_groups %} {% for asset_group in asset_groups %}
...@@ -95,51 +95,11 @@ ...@@ -95,51 +95,11 @@
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="j_group" class="col-sm-2 control-label">使用密码</label>
<div class="col-sm-1">
<div class="radio i-checks">
<label>
<input type="checkbox" value="0" id="use_password" name="use_password">
</label>
</div>
</div>
</div>
<div class="form-group" id="admin_account_password" style="display: none">
<label class="col-sm-1 control-label"> 密码<span class="red-fonts">*</span> </label>
<div class="col-sm-4">
<input type="password" name="password" class="form-control">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="j_group" class="col-sm-2 control-label">使用秘钥</label>
<div class="col-sm-1">
<div class="radio i-checks">
<label>
<input type="checkbox" value="1" id="use_publicKey" name="use_publicKey">
</label>
</div>
</div>
</div>
<div class="form-group" id="admin_account_publicKey" style="display: none">
<label class="col-sm-1 control-label"> 秘钥<span class="red-fonts">*</span> </label>
<div class="col-sm-4">
<input type="password" name="password" class="form-control">
</div>
</div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="comment" class="col-sm-2 control-label">备注</label> <label for="comment" class="col-sm-2 control-label">备注</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="comment" name="comment" placeholder="Rule Comment" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}> <input id="rule_comment" name="rule_comment" placeholder="Rule Comment" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}>
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
...@@ -158,6 +118,37 @@ ...@@ -158,6 +118,37 @@
{% endblock %} {% endblock %}
{% block self_footer_js %} {% block self_footer_js %}
<script> <script>
$('#ruleForm').submit(function() {
var result = {};
var data = $(this).serializeArray();
$.each(data, function (i, field) {
result[field.name] = field.value;
});
if (result['user'] || result['usergroup'] || result['asset'] || result['assetgroup'] || result['rulename'] || result['role']) {
if (result['rulename'] === '') {
alert("请添加授权名称");
return false
}
if (!result['user'] && !result['usergroup']) {
alert("用户和用户组必选1个");
return false
}
if (!result['asset'] && !result['assetgroup']) {
alert("资产和资产组必选1个");
return false
}
if (!result['role']) {
alert("请填写角色");
return false
}
return true
} else {
alert("请填必选项");
return false;
}
});
$(document).ready(function(){ $(document).ready(function(){
$("input.role").click(function(){ $("input.role").click(function(){
if($("input.role[value=GA]").is( ":checked" )){ if($("input.role[value=GA]").is( ":checked" )){
......
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
<div class="col-sm-8"> <div class="col-sm-8">
<select name="user" data-placeholder="用户名" class="chosen-select form-control m-b" multiple tabindex="2"> <select name="user" data-placeholder="用户名" class="chosen-select form-control m-b" multiple tabindex="2">
{% for user in users %} {% for user in users %}
<option value="{{ user.name }}">{{ user.name }}</option> <option value="{{ user.name }}" {% if user in users_select %} selected {% endif %}>{{ user.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
<div class="col-sm-8"> <div class="col-sm-8">
<select name="usergroup" data-placeholder="请选择用户组" class="chosen-select form-control m-b" multiple tabindex="2"> <select name="usergroup" data-placeholder="请选择用户组" class="chosen-select form-control m-b" multiple tabindex="2">
{% for user_group in user_groups %} {% for user_group in user_groups %}
<option value="{{ user_group.name }}">{{ user_group.name }}</option> <option value="{{ user_group.name }}"{% if user_group in users_groups_select %} selected {% endif %}>{{ user_group.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
<div class="col-sm-8"> <div class="col-sm-8">
<select name="asset" data-placeholder="请选择资产" class="chosen-select form-control m-b" multiple tabindex="2"> <select name="asset" data-placeholder="请选择资产" class="chosen-select form-control m-b" multiple tabindex="2">
{% for asset in assets %} {% for asset in assets %}
<option value="{{ asset.ip }}">{{ asset.ip }}</option> <option value="{{ asset.ip }}"{% if asset in assets_select %} selected {% endif %}>{{ asset.ip }}</option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
<div class="col-sm-8"> <div class="col-sm-8">
<select name="assetgroup" data-placeholder="请选择资产组" class="chosen-select form-control m-b" multiple tabindex="2"> <select name="assetgroup" data-placeholder="请选择资产组" class="chosen-select form-control m-b" multiple tabindex="2">
{% for asset_group in asset_groups %} {% for asset_group in asset_groups %}
<option value="{{ asset_group.name }}">{{ asset_group.name }}</option> <option value="{{ asset_group.name }}"{% if asset_group in asset_groups_select %} selected {% endif %}>{{ asset_group.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
...@@ -89,57 +89,17 @@ ...@@ -89,57 +89,17 @@
<div class="col-sm-8"> <div class="col-sm-8">
<select name="role" data-placeholder="请选择角色" class="chosen-select form-control m-b" multiple tabindex="2"> <select name="role" data-placeholder="请选择角色" class="chosen-select form-control m-b" multiple tabindex="2">
{% for role in roles %} {% for role in roles %}
<option value="{{ role.name }}">{{ role.name }}</option> <option value="{{ role.name }}"{% if role in roles_select %} selected {% endif %}>{{ role.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="j_group" class="col-sm-2 control-label">使用密码</label>
<div class="col-sm-1">
<div class="radio i-checks">
<label>
<input type="checkbox" value="0" id="use_password" name="use_password">
</label>
</div>
</div>
</div>
<div class="form-group" id="admin_account_password" style="display: none">
<label class="col-sm-1 control-label"> 密码<span class="red-fonts">*</span> </label>
<div class="col-sm-4">
<input type="password" name="password" class="form-control">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="j_group" class="col-sm-2 control-label">使用秘钥</label>
<div class="col-sm-1">
<div class="radio i-checks">
<label>
<input type="checkbox" value="1" id="use_publicKey" name="use_publicKey">
</label>
</div>
</div>
</div>
<div class="form-group" id="admin_account_publicKey" style="display: none">
<label class="col-sm-1 control-label"> 秘钥<span class="red-fonts">*</span> </label>
<div class="col-sm-4">
<input type="password" name="password" class="form-control">
</div>
</div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="comment" class="col-sm-2 control-label">备注</label> <label for="comment" class="col-sm-2 control-label">备注</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="comment" name="comment" placeholder="Comment" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}> <input id="role_comment" name="role_comment" placeholder="Rule Comment" type="text" class="form-control" value="{{ rule_comment }}">
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
......
...@@ -3,10 +3,20 @@ ...@@ -3,10 +3,20 @@
{% 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-10"> <div class="col-lg-10">
<div class="ibox float-e-margins"> <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"> <div class="ibox-title">
<h5> 所有规则</h5> <h5> 所有规则</h5>
<div class="ibox-tools"> <div class="ibox-tools">
...@@ -55,19 +65,19 @@ ...@@ -55,19 +65,19 @@
<tr class="gradeX" id={{ rule.id }}> <tr class="gradeX" id={{ rule.id }}>
<td class="text-center"> {{ rule.name }} </td> <td class="text-center"> {{ rule.name }} </td>
<td class="text-center"> <td class="text-center">
<a href="/jasset/asset_list/?gid={{ user.id }}">{{ rule | rule_member_count:"user" }} </a> {{ rule | rule_member_count:"user" }}
</td> </td>
<td class="text-center"> <td class="text-center">
<a href="/jasset/group_list/?gid={{ user.id }}">{{ rule | rule_member_count:"user_group" }}</a> {{ rule | rule_member_count:"user_group" }}
</td> </td>
<td class="text-center"> <td class="text-center">
<a href="/jasset/group_list/?gid={{ user.id }}">{{ rule | rule_member_count:"asset" }}</a> {{ rule | rule_member_count:"asset" }}
</td> </td>
<td class="text-center"> <td class="text-center">
<a href="/jasset/group_list/?gid={{ user.id }}">{{ rule | rule_member_count:"asset_group" }}</a> {{ rule | rule_member_count:"asset_group" }}
</td> </td>
<td class="text-center"> <td class="text-center">
<a href="/jasset/group_list/?gid={{ user.id }}">{{ rule | rule_member_count:"role" }}</a> {{ rule | rule_member_count:"role" }}
</td> </td>
<td class="text-center"> <td class="text-center">
<a href="/jperm/perm_rule_detail/?id={{ rule.id }}" class="btn btn-xs btn-primary">详情</a> <a href="/jperm/perm_rule_detail/?id={{ rule.id }}" class="btn btn-xs btn-primary">详情</a>
......
...@@ -93,6 +93,7 @@ type="checkbox" name="selected" value="{{ group.id }}"> ...@@ -93,6 +93,7 @@ type="checkbox" name="selected" value="{{ group.id }}">
$(document).ready(function(){ $(document).ready(function(){
$('.del').click(function(){ $('.del').click(function(){
var row = $(this).closest('tr'); var row = $(this).closest('tr');
if (confirm("确定删除")) {
$.get( $.get(
$(this).attr('value'), $(this).attr('value'),
{}, {},
...@@ -101,7 +102,7 @@ type="checkbox" name="selected" value="{{ group.id }}"> ...@@ -101,7 +102,7 @@ type="checkbox" name="selected" value="{{ group.id }}">
alert(data); alert(data);
} }
) )}
}); });
$('#del_btn').click(function(){ $('#del_btn').click(function(){
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
<div class="col-sm-8"> <div class="col-sm-8">
<input id="password" name="password" placeholder="Password" type="password" class="form-control"> <input id="password" name="password" placeholder="Password" type="password" class="form-control">
<span class="help-block m-b-none"> <span class="help-block m-b-none">
登陆web的密码 登陆web的密码(如不修改请留空)
</span> </span>
</div> </div>
</div> </div>
......
...@@ -64,7 +64,13 @@ ...@@ -64,7 +64,13 @@
<td class="text-center" title="{% for user_group in user.group.all %} {{ user_group.name }} {% endfor %}"> {{ user.group.all | groups2str }} </td> <td class="text-center" title="{% for user_group in user.group.all %} {{ user_group.name }} {% endfor %}"> {{ user.group.all | groups2str }} </td>
<td class="text-center"> {{ user.id | get_role }}</td> <td class="text-center"> {{ user.id | get_role }}</td>
<td class="text-center">{{ user.is_active | bool2str }}</td> <td class="text-center">{{ user.is_active | bool2str }}</td>
<td class="text-center"><a href="/juser/down_key/?id={{ user.id }}">下载</a></td> <td class="text-center">
{% if user.username|key_exist %}
<a href="/juser/down_key/?id={{ user.id }}" >下载</a>
{% else %}
<span style="color: #586b7d">下载</span>
{% endif %}
</td>
<td class="text-center"> <td class="text-center">
<a href="../user_detail/?id={{ user.id }}" class="btn btn-xs btn-primary">详情</a> <a href="../user_detail/?id={{ user.id }}" class="btn btn-xs btn-primary">详情</a>
<a href="../user_edit/?id={{ user.id }}" class="btn btn-xs btn-info">编辑</a> <a href="../user_edit/?id={{ user.id }}" class="btn btn-xs btn-info">编辑</a>
......
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
<ul class="nav" id="side-menu"> <ul class="nav" id="side-menu">
{% include 'nav_li_profile.html' %} {% include 'nav_li_profile.html' %}
<li id="index"> <li id="index">
<a href="/"><i class="fa fa-th-large"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span></a> <a href="/"><i class="fa fa-dashboard"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span></a>
</li> </li>
<li id="juser"> <li id="juser">
<a href="#"><i class="fa fa-rebel"></i> <span class="nav-label">用户管理</span><span class="fa arrow"></span></a> <a href="#"><i class="fa fa-group"></i> <span class="nav-label">用户管理</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li class="group_list group_edit"><a href="/juser/group_list/">查看用户组</a></li> <li class="group_list group_edit"><a href="/juser/group_list/">查看用户组</a></li>
<li class="group_add"><a href="/juser/group_add/">添加用户组</a></li> <li class="group_add"><a href="/juser/group_add/">添加用户组</a></li>
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
</ul> </ul>
</li> </li>
<li id="jasset"> <li id="jasset">
<a><i class="fa fa-cube"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span></a> <a><i class="fa fa-inbox"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li class="group_add"><a href="/jasset/group_add/">添加资产组</a></li> <li class="group_add"><a href="/jasset/group_add/">添加资产组</a></li>
<li class="group_list group_detail group_edit"><a href="/jasset/group_list/">查看资产组</a></li> <li class="group_list group_detail group_edit"><a href="/jasset/group_list/">查看资产组</a></li>
...@@ -29,11 +29,11 @@ ...@@ -29,11 +29,11 @@
<li id="jperm"> <li id="jperm">
<a href="#"><i class="fa fa-edit"></i> <span class="nav-label">授权管理</span><span class="fa arrow"></span></a> <a href="#"><i class="fa fa-edit"></i> <span class="nav-label">授权管理</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li class="dept_perm_list dept_perm_edit"> <li class="rule ">
<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="role">
<a href="/jperm/role/">系统角色</a> <a href="/jperm/role/">系统角色</a>
</li> </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>
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
<a href="/jlog/log_list/online/"><i class="fa fa-files-o"></i> <span class="nav-label">日志审计</span><span class="label label-info pull-right"></span></a> <a href="/jlog/log_list/online/"><i class="fa fa-files-o"></i> <span class="nav-label">日志审计</span><span class="label label-info pull-right"></span></a>
</li> </li>
<li id="setting"> <li id="setting">
<a href="/setting/"><i class="fa fa-files-o"></i> <span class="nav-label">设置</span><span class="label label-info pull-right"></span></a> <a href="/setting/"><i class="fa fa-gears"></i> <span class="nav-label">设置</span><span class="label label-info pull-right"></span></a>
</li> </li>
<li class="special_link"> <li class="special_link">
<a href="http://www.jumpserver.org" target="_blank"><i class="fa fa-database"></i> <span class="nav-label">访问官网</span></a> <a href="http://www.jumpserver.org" target="_blank"><i class="fa fa-database"></i> <span class="nav-label">访问官网</span></a>
......
1.1
\ No newline at end of file
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