Пример #1
0
 def run(
     self,
     module_name="shell",
     module_args="",
     timeout=10,
     forks=10,
     pattern="*",
     become=False,
     become_method="sudo",
     become_user="******",
     become_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=become,
         become_method=become_method,
         become_user=become_user,
         become_pass=become_pass,
     )
     self.results_raw = hoc.run()
     logger.debug(self.results_raw)
     return self.results_raw
Пример #2
0
def asset_ansible_update(obj_list, name=''):
    resource = gen_resource(obj_list)
    ansible_instance = MyRunner(resource)
    ansible_instance.run(module_name='setup', pattern='*')
    ansible_asset_info = ansible_instance.results
    logger.debug('获取硬件信息: %s' % ansible_asset_info)
    for asset in obj_list:
        try:
            setup_info = ansible_asset_info['ok'][asset.hostname]
            logger.debug("setup_info: %s" % setup_info)
        except KeyError as e:
            logger.error("获取setup_info失败: %s" % e)
            continue
        else:
            try:
                asset_info = get_ansible_asset_info(asset.ip, setup_info)
                other_ip, mac, cpu, memory, disk, sn, system_type, system_version, brand, system_arch = asset_info
                asset_dic = {
                    "other_ip": other_ip,
                    "mac": mac,
                    "cpu": cpu,
                    "memory": memory,
                    "disk": json.dumps(disk),
                    "sn": sn,
                    "system_type": system_type,
                    "system_version": system_version,
                    "system_arch": system_arch,
                    "brand": brand
                }

                ansible_record(asset, asset_dic, name)
            except Exception as e:
                logger.error("save setup info failed! %s" % e)
                traceback.print_exc()
Пример #3
0
def gen_ssh_key(username, password='',
                key_dir=os.path.join(settings.KEY_DIR, 'user'),
                authorized_keys=True, home="/home", length=2048):
    """
    生成用户ssh密匙对
    :param username:
    :param password:
    :param key_dir:
    :param authorized_keys:
    :param home:
    :param length:
    :return:
    """
    logger.debug('生成ssh_key,并设置authorized_keys')
    private_key_file = os.path.join(key_dir, username+'.perm')
    os.mkdir(key_dir, mode=777)
    if os.path.isfile(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)

    if authorized_keys:
        auth_key_dir = os.path.join(home, username, '.ssh')
        mkdir(auth_key_dir, username=username, mode=700)
        authorized_key_file = os.path.join(auth_key_dir, 'authorized_keys')
        with open(private_key_file + '.pub') as pub_f:
            with open(authorized_key_file, 'w') as auth_f:
                auth_f.write(pub_f.read())
        os.chmod(authorized_key_file, mode=0600)
        chown(authorized_key_file, username)
Пример #4
0
def perm_sudo_add(request):
    """
    list sudo commands alias
    :param request:
    :return:
    """
    # 渲染数据
    header_title, path1, path2 = "Sudo命令", "别名管理", "添加别名"
    try:
        if request.method == "POST":
            # 获取参数: name, comment
            name = request.POST.get("sudo_name").strip().upper()
            comment = request.POST.get("sudo_comment").strip()
            commands = request.POST.get("sudo_commands").strip()

            if not name or not commands:
                raise ServerError(u"sudo name 和 commands是必填项!")

            pattern = re.compile(r'[\n,\r]')
            deal_space_commands = list_drop_str(pattern.split(commands), u'')
            deal_all_commands = map(trans_all, deal_space_commands)
            commands = ', '.join(deal_all_commands)
            logger.debug(u'添加sudo %s: %s' % (name, commands))

            if get_object(PermSudo, name=name):
                error = 'Sudo别名 %s已经存在' % name
            else:
                sudo = PermSudo(name=name.strip(),
                                comment=comment,
                                commands=commands)
                sudo.save()
                msg = u"添加Sudo命令别名: %s" % name
    except ServerError, e:
        error = e
Пример #5
0
def del_register(request):
    """
    删除注册信息
    不同意用户的注册申请

    """
    logger.debug("开始删除注册记录, 执行函数: del_register")
    if request.method == "GET":
        user_ids = request.GET.get('id', '')
        logger.debug("%s -- GET del uids: %s" % (datetime.now(),user_ids))
        user_id_list = user_ids.split(',')
    elif request.method == "POST":
        user_ids = request.POST.get('id', '')
        looger.debug("%s -- POST del uids: %s" % (datetime.now(), user_ids))
        user_id_list = user_ids.split(',')
    else:
        logger.debug("%s -- 非GET, 也不是POST请求无法处理的错误" % datetime.now())
        return HttpResponse('错误请求')
    for user_id in user_id_list:
        try:
            user = RegisterUser.objects.get(id=int(user_id))
            logger.debug("%s -- del user: %s" % (datetime.now(), user.name))
        except:
            return HttpResponse(u'error')
        else:
            if user and user.username != 'admin':
                user.delete()
                logger.debug(u"删除注册记录:%s(%s) " % (user.name, user.username))
                return HttpResponse(u'删除成功')
Пример #6
0
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)

    try:
        if request.method == "POST":
            name = request.POST.get("sudo_name").upper()
            commands = request.POST.get("sudo_commands")
            comment = request.POST.get("sudo_comment")

            if not name or not commands:
                raise ServerError(u"sudo name 和 commands是必填项!")

            pattern = re.compile(r'[\n,\r]')
            deal_space_commands = list_drop_str(pattern.split(commands), u'')
            deal_all_commands = map(trans_all, deal_space_commands)
            commands = ', '.join(deal_all_commands).strip()
            logger.debug(u'添加sudo %s: %s' % (name, commands))

            sudo.name = name.strip()
            sudo.commands = commands
            sudo.comment = comment
            sudo.save()

            msg = u"更新命令别名: %s" % name
    except ServerError, e:
        error = e
Пример #7
0
def asset_apply(request):
    """
    普通用户可以对需要访问的主机提出申请

    """
    error = ""
    msg = "" 
    # 取得登陆用户的ID
    uid = request.user.id
    # 取得用户ID对应的User对象
    user = User.objects.get(id=uid)
    logger.debug("访问主机申请")
    # 通过User对象获取用户所有的授权规则
    rule = user.perm_rule.all()[0]
    # 所有主机
    assets = Asset.objects.all()
    asset_appled = []
    
    if request.method == "POST": 
        asset_selected = request.POST.getlist('asset')   
        if asset_selected == []: 
            error = "请至少选择一台主机"
        else: 
            for asset_id in asset_selected:
                asset = Asset.objects.get(id=asset_id)
                if asset not in rule.asset.all():
                    msg = msg + asset.ip + " "  

            if msg != "":
                new_apply = ApplyHosts(username=user.username, hosts=msg,is_added=0)
                new_apply.save()
                msg = "申请已受理, 请耐心等待!"
                
    return render(request, 'avazu/asset_apply.html', locals())
Пример #8
0
 def run(self,
         module_name='shell',
         module_args='',
         timeout=10,
         forks=10,
         pattern='*',
         become=False,
         become_method='sudo',
         become_user='******',
         become_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=become,
                  become_method=become_method,
                  become_user=become_user,
                  become_pass=become_pass)
     self.results_raw = hoc.run()
     logger.debug(self.results_raw)
     return self.results_raw
Пример #9
0
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)

    try:
        if request.method == "POST":
            name = request.POST.get("sudo_name").upper()
            commands = request.POST.get("sudo_commands")
            comment = request.POST.get("sudo_comment")

            if not name or not commands:
                raise ServerError(u"sudo name 和 commands是必填项!")

            pattern = re.compile(r'[\n,\r]')
            deal_space_commands = list_drop_str(pattern.split(commands), u'')
            deal_all_commands = map(trans_all, deal_space_commands)
            commands = ', '.join(deal_all_commands).strip()
            logger.debug(u'添加sudo %s: %s' % (name, commands))

            sudo.name = name.strip()
            sudo.commands = commands
            sudo.comment = comment
            sudo.save()

            msg = u"更新命令别名: %s" % name
    except ServerError, e:
        error = e
Пример #10
0
def gen_ssh_key(username,
                password='',
                key_dir=os.path.join(settings.KEY_DIR, 'user'),
                authorized_keys=True,
                home="/home",
                length=2048):
    """
    generate a user ssh key in a property dir
    生成一个用户ssh密钥对
    """
    logger.debug('生成ssh key, 并设置authorized_keys')
    private_key_file = os.path.join(key_dir, username + '.pem')
    mkdir(key_dir, mode=777)
    if os.path.isfile(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))

    if authorized_keys:
        auth_key_dir = os.path.join(home, username, '.ssh')
        mkdir(auth_key_dir, username=username, mode=700)
        authorized_key_file = os.path.join(auth_key_dir, 'authorized_keys')
        with open(private_key_file + '.pub') as pub_f:
            with open(authorized_key_file, 'w') as auth_f:
                auth_f.write(pub_f.read())
        os.chmod(authorized_key_file, 0o600)
        chown(authorized_key_file, username)
Пример #11
0
def Yanzhengma():
    VerificationCode = str(random.randint(100000, 999999))
    TYPE = "touser"
    touser = str(sys.argv[1])

    TIME = str(sys.argv[2])
    content = VerificationCode
    subject = "验证码:"

    corpid = '*****************'
    corpsecret = '**********************************'
    accesstoken = gettoken(corpid, corpsecret)
    #发送验证码
    Status = senddata(accesstoken, TYPE, touser, subject, content)
    logger.debug(Status)
    logger.debug("New user login:"******"\t" + USER)
    Times = 4
    Status = "no"
    while (Times >= 2) and (Status == "no"):
        try:
            VerificationCodeInput = ""
            print '\033[1;33;40m'
            VerificationCodeInput = str(raw_input("请输入验证码:\033[1;37;40m"))
            print '\033[0m'
        except Exception, e:
            print Exception, ":", e
        if (VerificationCodeInput == VerificationCode):
            #print "欢迎登陆希望金融小分队跳板机!"
            Status = "ok"
        else:
            print '\033[1;31;40m'
            print "请输入正确的验证码!!!"
            print '\033[0m'
            Times -= 1
Пример #12
0
def perm_role_edit(request):
    """
    edit role page
    """
    # 渲染数据
    header_title, path1, path2 = "系统用户", "系统用户管理", "系统用户编辑"

    # 渲染数据
    role_id = request.GET.get("id")
    role = PermRole.objects.get(id=role_id)
    ori_name = role.name
    if request.method == "GET":
        # role_pass = CRYPTOR.decrypt(role.password)
        sudo_all = PermSudo.objects.all()
        role_sudos = role.sudo.all()
        sudo_all = PermSudo.objects.all()
        return my_render('jperm/perm_role_edit.html', locals(), request)

    if request.method == "POST":
        # 获取 POST 数据
        role_name = request.POST.get("role_name")
        role_password = request.POST.get("role_password")
        role_comment = request.POST.get("role_comment")
        role_sudo_names = request.POST.getlist("sudo_name")
        role_sudos = [
            PermSudo.objects.get(id=sudo_id) for sudo_id in role_sudo_names
        ]
        key_content = request.POST.get("role_key", "")
        if len(role_password) > 64:
            raise ServerError(u'密码长度不能超过64位!')

        try:
            # if not role:
            #     raise ServerError('该系统用户不能存在')
            if role_name == "root":
                raise ServerError(u'禁止使用root用户作为系统用户,这样非常危险!')
            if PermRole.objects.get(
                    name=role_name) and (role_name != ori_name):
                raise ServerError(u'role %s is already exists.' % role_name)
            if role_password:
                encrypt_pass = CRYPTOR.encrypt(role_password)
                role.password = encrypt_pass
            # 生成随机密码,生成秘钥对
            if key_content:
                try:
                    key_path = gen_keys(key=key_content,
                                        key_path_dir=role.key_path)
                except SSHException:
                    raise ServerError('输入的密钥不合法')
                logger.debug('Recreate role key: %s' % role.key_path)
            # 写入数据库
            role.name = role_name
            role.comment = role_comment
            role.sudo = role_sudos

            role.save()
            msg = u"更新系统用户: %s" % role.name
            return HttpResponseRedirect(reverse('role_list'))
        except ServerError, e:
            error = e
Пример #13
0
def perm_sudo_add(request):
    """
    list sudo commands alias
    :param request:
    :return:
    """
    # 渲染数据
    header_title, path1, path2 = "Sudo命令", "别名管理", "添加别名"
    try:
        if request.method == "POST":
            # 获取参数: name, comment
            name = request.POST.get("sudo_name").strip().upper()
            comment = request.POST.get("sudo_comment").strip()
            commands = request.POST.get("sudo_commands").strip()

            if not name or not commands:
                raise ServerError(u"sudo name 和 commands是必填项!")

            pattern = re.compile(r'[\n,\r]')
            deal_space_commands = list_drop_str(pattern.split(commands), u'')
            deal_all_commands = map(trans_all, deal_space_commands)
            commands = ', '.join(deal_all_commands)
            logger.debug(u'添加sudo %s: %s' % (name, commands))

            if get_object(PermSudo, name=name):
                error = 'Sudo别名 %s已经存在' % name
            else:
                sudo = PermSudo(name=name.strip(), comment=comment, commands=commands)
                sudo.save()
                msg = u"添加Sudo命令别名: %s" % name
    except ServerError, e:
        error = e
Пример #14
0
    def download(self):
        while True:
            if not self.user_perm:
                self.user_perm = get_group_user_perm(self.user)
            try:
                print("进入批量下载模式")
                print("请输入主机名或ansile支持的pattern, 多个主机:分隔,q退出")
                pattern = input("\033[1;32mPattern>:\033[0m ").strip()
                if pattern == 'q':
                    break
                else:
                    assets = self.user_perm.get('asset').keys()
                    res = gen_resource({'user': self.user, 'asset': assets}, perm=self.user_perm)
                    runner = MyRunner(res)
                    asset_name_str = ''
                    print("匹配用户:\n")
                    for inv in runner.inventory.get_hosts(pattern=pattern):
                        asset_name_str += '%s ' % inv.name
                        print(' %s' % inv.name)
                    if not asset_name_str:
                        color_print('没有匹配主机')
                        continue
                    print()
                    while True:
                        tmp_dir = get_tmp_dir()
                        logger.debug('Download tmp dir: %s' % tmp_dir)
                        print("请输入文件路径(不支持目录)")
                        file_path = input("\033[1;32mPath>:\033[0m ").strip()
                        if file_path == 'q':
                            break

                        if not file_path:
                            color_print("文件路径为空")
                            continue

                        runner.run('fetch', module_args='src=%s dest=%s' % (file_path, tmp_dir), pattern=pattern)
                        ret = runner.results
                        FileLog(user=self.user.name, host=asset_name_str, filename=file_path, type='download',
                                remote_ip=remote_ip, result=ret).save()
                        logger.debug('Download file result: %s' % ret)
                        os.chdir('/tmp')
                        tmp_dir_name = os.path.basename(tmp_dir)
                        if not os.listdir(tmp_dir):
                            color_print('下载全部失败')
                            continue
                        bash('tar czf %s.tar.gz %s && sz %s.tar.gz' % (tmp_dir, tmp_dir_name, tmp_dir))

                        if ret.get('failed'):
                            error = '文件名称: %s \n下载失败: [ %s ] \n下载成功 [ %s ]' % \
                                    ('%s.tar.gz' % tmp_dir_name, ', '.join(ret.get('failed').keys()),
                                     ', '.join(ret.get('ok').keys()))
                            color_print(error)
                        else:
                            msg = '文件名称: %s \n下载成功 [ %s ]' % (
                                '%s.tar.gz' % tmp_dir_name, ', '.join(ret.get('ok').keys()))
                            color_print(msg, 'green')
                        print
            except IndexError:
                pass
Пример #15
0
def server_del_user(username):
    """
    删除系统上的用户
    :param username:
    :return:
    """
    bash('userdel -r -f %s' % username)
    logger.debug('rm -f %s/%s_*.perm' % (os.path.join(settings.KEY_DIR, 'user'), username))
    bash('rm -f %s/%s_*.perm' % (os.path.join(settings.KEY_DIR,'user'),username))
Пример #16
0
def perm_role_add(request):
    """
    add role page
    """
    # 渲染数据
    header_title, path1, path2 = "系统用户", "系统用户管理", "添加系统用户"
    login_user_id = request.user.id
    if not login_user_id:
        return HttpResponseRedirect(reverse('index'))
    login_user = User.objects.get(id=login_user_id)
    productlines = ProductLine.objects.all()
    sudos = PermSudo.objects.all().filter(productLine=login_user.productLine)

    if request.method == "POST":
        # 获取参数: name, comment
        name = request.POST.get("role_name", "").strip()
        comment = request.POST.get("role_comment", "")
        password = request.POST.get("role_password", "")
        key_content = request.POST.get("role_key", "")
        sudo_ids = request.POST.getlist('sudo_name')
        productline_name = request.POST.get('productline_name', '')
        productLine = get_object_or_404(ProductLine, name=productline_name)

        try:
            if get_object(PermRole, name=name, productLine=productLine):
                raise ServerError(u'已经存在该用户 %s' % name)
            if name == "root":
                raise ServerError(u'禁止使用root用户作为系统用户,这样非常危险!')
            default = get_object(Setting, name='default')
            if len(password) > 64:
                raise ServerError(u'密码长度不能超过64位!')

            if password:
                encrypt_pass = CRYPTOR.encrypt(password)
            else:
                encrypt_pass = CRYPTOR.encrypt(CRYPTOR.gen_rand_pass(20))
            # 生成随机密码,生成秘钥对
            sudos_obj = [
                get_object(PermSudo, id=sudo_id) for sudo_id in sudo_ids
            ]
            if key_content:
                try:
                    key_path = gen_keys(key=key_content)
                except SSHException, e:
                    raise ServerError(e)
            else:
                key_path = gen_keys()
            logger.debug('generate role key: %s' % key_path)
            role = PermRole(name=name,
                            productLine=productLine,
                            comment=comment,
                            password=encrypt_pass,
                            key_path=key_path)
            role.save()
            role.sudo = sudos_obj
            msg = u"添加系统用户: %s" % name
            return HttpResponseRedirect(reverse('role_list'))
Пример #17
0
    def download(self):
        while True:
            if not self.user_perm:
                self.user_perm = get_group_user_perm(self.user)
            try:
                print "进入批量下载模式"
                print "请输入主机名或ansible支持的pattern, 多个主机:分隔,q退出"
                pattern = raw_input("\033[1;32mPattern>:\033[0m ").strip()
                if pattern == 'q':
                    break
                else:
                    assets = self.user_perm.get('asset').keys()
                    res = gen_resource({'user': self.user, 'asset': assets}, perm=self.user_perm)
                    runner = MyRunner(res)
                    asset_name_str = ''
                    print "匹配主机:\n"
                    for inv in runner.inventory.get_hosts(pattern=pattern):
                        asset_name_str += '%s ' % inv.name
                        print ' %s' % inv.name
                    if not asset_name_str:
                        color_print('没有匹配主机')
                        continue
                    print
                    while True:
                        tmp_dir = get_tmp_dir()
                        logger.debug('Download tmp dir: %s' % tmp_dir)
                        print "请输入文件路径(不支持目录)"
                        file_path = raw_input("\033[1;32mPath>:\033[0m ").strip()
                        if file_path == 'q':
                            break

                        if not file_path:
                            color_print("文件路径为空")
                            continue

                        runner.run('fetch', module_args='src=%s dest=%s' % (file_path, tmp_dir), pattern=pattern)
                        ret = runner.results
                        FileLog(user=self.user.name, host=asset_name_str, filename=file_path, type='download',
                                remote_ip=remote_ip, result=ret).save()
                        logger.debug('Download file result: %s' % ret)
                        os.chdir('/tmp')
                        tmp_dir_name = os.path.basename(tmp_dir)
                        if not os.listdir(tmp_dir):
                            color_print('下载全部失败')
                            continue
                        bash('tar czf %s.tar.gz %s && sz %s.tar.gz' % (tmp_dir, tmp_dir_name, tmp_dir))

                        if ret.get('failed'):
                            error = '文件名称: %s \n下载失败: [ %s ] \n下载成功 [ %s ]' % \
                                    ('%s.tar.gz' % tmp_dir_name, ', '.join(ret.get('failed').keys()), ', '.join(ret.get('ok').keys()))
                            color_print(error)
                        else:
                            msg = '文件名称: %s \n下载成功 [ %s ]' % ('%s.tar.gz' % tmp_dir_name, ', '.join(ret.get('ok').keys()))
                            color_print(msg, 'green')
                        print
            except IndexError:
                pass
Пример #18
0
def perm_role_edit(request):
    """
    edit role page
    """
    # 渲染数据
    header_title, path1, path2 = "系统用户", "系统用户管理", "系统用户编辑"

    # 渲染数据
    role_id = request.GET.get("id")
    role = PermRole.objects.get(id=role_id)
    role_pass = CRYPTOR.decrypt(role.password)
    sudo_all = PermSudo.objects.all()
    role_sudos = role.sudo.all()
    sudo_all = PermSudo.objects.all()
    if request.method == "GET":
        return my_render('jperm/perm_role_edit.html', locals(), request)

    if request.method == "POST":
        # 获取 POST 数据
        role_name = request.POST.get("role_name")
        role_password = request.POST.get("role_password")
        role_comment = request.POST.get("role_comment")
        role_sudo_names = request.POST.getlist("sudo_name")
        role_sudos = [PermSudo.objects.get(id=sudo_id) for sudo_id in role_sudo_names]
        key_content = request.POST.get("role_key", "")
        if len(role_password) > 64:
            raise ServerError(u'密码长度不能超过64位!')

        try:
            if not role:
                raise ServerError('该系统用户不能存在')

            if role_name == "root":
                raise ServerError(u'禁止使用root用户作为系统用户,这样非常危险!')

            if role_password:
                encrypt_pass = CRYPTOR.encrypt(role_password)
                role.password = encrypt_pass
            # 生成随机密码,生成秘钥对
            if key_content:
                try:
                    key_path = gen_keys(key=key_content, key_path_dir=role.key_path)
                except SSHException:
                    raise ServerError('输入的密钥不合法')
                logger.debug('Recreate role key: %s' % role.key_path)
            # 写入数据库
            role.name = role_name
            role.comment = role_comment
            role.sudo = role_sudos

            role.save()
            msg = u"更新系统用户: %s" % role.name
            return HttpResponseRedirect(reverse('role_list'))
        except ServerError, e:
            error = e
Пример #19
0
def download(request):
    user = request.user
    assets = list(get_group_user_perm(user).get('asset').keys())
    asset_select = []
    if request.method == 'POST':
        remote_ip = request.META.get('REMOTE_ADDR')
        asset_ids = request.POST.getlist('asset_ids', '')
        file_path = request.POST.get('file_path')
        date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
        download_dir = get_tmp_dir()
        for asset_id in asset_ids:
            asset_select.append(get_object(Asset, id=asset_id))

        if not set(asset_select).issubset(set(assets)):
            illegal_asset = set(asset_select).issubset(set(assets))
            return HttpResponse(
                '没有权限的服务器 %s' %
                ','.join([asset.hostname for asset in illegal_asset]))

        res = gen_resource({'user': user, 'asset': asset_select})
        runner = MyRunner(res)
        runner.run('fetch',
                   module_args='src=%s dest=%s' % (file_path, download_dir),
                   pattern='*')
        FileLog(user=request.user.username,
                host=' '.join([asset.hostname for asset in asset_select]),
                filename=file_path,
                type='download',
                remote_ip=remote_ip,
                result=runner.results).save()
        logger.debug(runner.results)
        tmp_dir_name = os.path.basename(download_dir)
        file_zip = '/tmp/' + tmp_dir_name + '.zip'
        zf = zipfile.ZipFile(file_zip, "w", zipfile.ZIP_DEFLATED)

        for dirname, subdirs, files in os.walk(download_dir):
            arcname = dirname.split(download_dir)[-1]
            if arcname:
                zf.write(dirname, arcname)
            for filename in files:
                filename = os.path.join(dirname, filename)
                arcname = filename.split(download_dir)[-1]
                zf.write(filename, arcname)

        zf.close()
        f = open(file_zip, 'rb')
        data = f.read()
        f.close()
        response = HttpResponse(data, content_type='application/octet-stream')
        response[
            'Content-Disposition'] = 'attachment; filename=%s.zip' % tmp_dir_name
        return response

    return render(request, 'download.html', locals())
Пример #20
0
def server_del_user(username):
    """
    delete a user from jumpserver linux system
    删除系统上的某用户
    """
    bash('userdel -r -f %s' % username)
    logger.debug('rm -f %s/%s_*.pem' %
                 (os.path.join(settings.KEY_DIR, 'user'), username))
    bash('rm -f %s/%s_*.pem' %
         (os.path.join(settings.KEY_DIR, 'user'), username))
    bash('rm -f %s/%s.pem*' %
         (os.path.join(settings.KEY_DIR, 'user'), username))
Пример #21
0
 def get_connect_info(self):
     """
     获取需要登陆的主机的信息和映射用户的账号密码
     """
     asset_info = get_asset_info(self.asset)
     role_key = get_role_key(self.user, self.role)  # 获取角色的key,因为ansible需要权限是600,所以统一生成用户_角色key
     role_pass = CRYPTOR.decrypt(self.role.password)
     connect_info = {'user': self.user, 'asset': self.asset, 'ip': asset_info.get('ip'),
                     'port': int(asset_info.get('port')), 'role_name': self.role.name,
                     'role_pass': role_pass, 'role_key': role_key}
     logger.debug(connect_info)
     return connect_info
Пример #22
0
 def get_connect_info(self):
     """
     获取需要登陆的主机的信息和映射用户的账号密码
     """
     asset_info = get_asset_info(self.asset)
     role_key = get_role_key(self.user, self.role)  # 获取角色的key,因为ansible需要权限是600,所以统一生成用户_角色key
     role_pass = CRYPTOR.decrypt(self.role.password)
     connect_info = {'user': self.user, 'asset': self.asset, 'ip': asset_info.get('ip'),
                     'port': int(asset_info.get('port')), 'role_name': self.role.name,
                     'role_pass': role_pass, 'role_key': role_key}
     logger.debug(connect_info)
     return connect_info
Пример #23
0
def perm_role_add(request):
    """
    add role page
    """
    # 渲染数据
    header_title, path1, path2 = "系统用户", "系统用户管理", "添加系统用户"
    sudos = PermSudo.objects.all()

    if request.method == "POST":
        # 获取参数: name, comment
        name = request.POST.get("role_name", "").strip()
        comment = request.POST.get("role_comment", "")
        password = request.POST.get("role_password", "")
        key_content = request.POST.get("role_key", "")
        sudo_ids = request.POST.getlist('sudo_name')

        try:
            if get_object(PermRole, name=name):
                raise ServerError('已经存在该用户 %s' % name)
            if name == "root":
                raise ServerError('禁止使用root用户作为系统用户,这样非常危险!')
            default = get_object(Setting, name='default')
            if len(password) > 64:
                raise ServerError('密码长度不能超过64位!')

            if password:
                encrypt_pass = CRYPTOR.encrypt(password)
            else:
                encrypt_pass = CRYPTOR.encrypt(CRYPTOR.gen_rand_pass(20))
            # 生成随机密码,生成秘钥对
            sudos_obj = [
                get_object(PermSudo, id=sudo_id) for sudo_id in sudo_ids
            ]
            if key_content:
                try:
                    key_path = gen_keys(key=key_content)
                except SSHException as e:
                    raise ServerError(e)
            else:
                key_path = gen_keys()
            logger.debug('generate role key: %s' % key_path)
            role = PermRole(name=name,
                            comment=comment,
                            password=encrypt_pass,
                            key_path=key_path)
            role.save()
            role.sudo = sudos_obj
            msg = "添加系统用户: %s" % name
            return HttpResponseRedirect(reverse('role_list'))
        except ServerError as e:
            error = e
    return my_render('jperm/perm_role_add.html', locals(), request)
Пример #24
0
def perm_role_get(request):
    asset_id = request.GET.get('id', 0)
    if asset_id:
        asset = get_object(Asset, id=asset_id)
        if asset:
            role = user_have_perm(request.user, asset=asset)
            logger.debug(u'获取授权系统用户: ' + ','.join([i.name for i in role]))
            return HttpResponse(','.join([i.name for i in role]))
    else:
        roles = get_group_user_perm(request.user).get('role').keys()
        return HttpResponse(','.join(i.name for i in roles))

    return HttpResponse('error')
Пример #25
0
def perm_role_get(request):
    asset_id = request.GET.get('id', 0)
    if asset_id:
        asset = get_object(Asset, id=asset_id)
        if asset:
            role = user_have_perm(request.user, asset=asset)
            logger.debug(u'获取授权系统用户: ' + ','.join([i.name for i in role]))
            return HttpResponse(','.join([i.name for i in role]))
    else:
        roles = get_group_user_perm(request.user).get('role').keys()
        return HttpResponse(','.join(i.name for i in roles))

    return HttpResponse('error')
Пример #26
0
    def get_log(self):
        """
        Logging user command and output.
        记录用户的日志
        """
        banned_list = ['/', '\0', '*', '?']
        tty_log_dir = os.path.join(LOG_DIR, 'tty')
        date_today = datetime.datetime.now()
        date_start = date_today.strftime('%Y%m%d')
        time_start = date_today.strftime('%H%M%S')
        today_connect_log_dir = os.path.join(tty_log_dir, date_start)
        filename = '%s_%s_%s' % (self.username, self.asset_name, time_start)
        for banned_char in banned_list:
            filename = filename.replace(banned_char, '_')
        log_file_path = os.path.join(today_connect_log_dir, filename)
        try:
            mkdir(os.path.dirname(today_connect_log_dir), mode=777)
            mkdir(today_connect_log_dir, mode=777)
        except OSError as e:
            logger.debug('创建目录 %s 失败,请修改%s目录权限 With error msg: %s' %
                         (today_connect_log_dir, tty_log_dir, e))
            raise ServerError('创建目录 %s 失败,请修改%s目录权限' %
                              (today_connect_log_dir, tty_log_dir))
        try:
            log_file_f = open(log_file_path + '.log', 'a')
            log_time_f = open(log_file_path + '.time', 'a')
        except IOError as e:
            logger.debug('创建tty日志文件失败, 请修改目录%s权限 With error msg: %s' %
                         (today_connect_log_dir, e))
            raise ServerError('创建tty日志文件失败, 请修改目录%s权限' % today_connect_log_dir)

        if self.login_type == 'ssh':  # 如果是ssh连接过来,记录connect.py的pid,web terminal记录为日志的id
            pid = os.getpid()
            self.remote_ip = remote_ip  # 获取远端IP
        else:
            pid = 0

        log = Log(user=self.username,
                  host=self.asset_name,
                  remote_ip=self.remote_ip,
                  login_type=self.login_type,
                  log_path=log_file_path,
                  start_time=date_today,
                  pid=pid)
        log.save()
        if self.login_type == 'web':
            log.pid = log.id  # 设置log id为websocket的id, 然后kill时干掉websocket
            log.save()

        log_file_f.write('Start at %s\r\n' % datetime.datetime.now())
        return log_file_f, log_time_f, log
Пример #27
0
    def get_log(self):
        """
        Logging user command and output.
        记录用户的日志
        """
        tty_log_dir = os.path.join(LOG_DIR, "tty")
        date_today = datetime.datetime.now()
        date_start = date_today.strftime("%Y%m%d")
        time_start = date_today.strftime("%H%M%S")
        today_connect_log_dir = os.path.join(tty_log_dir, date_start)
        log_file_path = os.path.join(today_connect_log_dir, "%s_%s_%s" % (self.username, self.asset_name, time_start))

        try:
            mkdir(os.path.dirname(today_connect_log_dir), mode=0777)
            mkdir(today_connect_log_dir, mode=0777)
        except OSError:
            logger.debug("创建目录 %s 失败,请修改%s目录权限" % (today_connect_log_dir, tty_log_dir))
            raise ServerError("创建目录 %s 失败,请修改%s目录权限" % (today_connect_log_dir, tty_log_dir))

        try:
            log_file_f = open(log_file_path + ".log", "a")
            log_time_f = open(log_file_path + ".time", "a")
        except IOError:
            logger.debug("创建tty日志文件失败, 请修改目录%s权限" % today_connect_log_dir)
            raise ServerError("创建tty日志文件失败, 请修改目录%s权限" % today_connect_log_dir)

        if self.login_type == "ssh":  # 如果是ssh连接过来,记录connect.py的pid,web terminal记录为日志的id
            pid = os.getpid()
            self.remote_ip = remote_ip  # 获取远端IP
        else:
            pid = 0

        log = Log(
            user=self.username,
            host=self.asset_name,
            remote_ip=self.remote_ip,
            login_type=self.login_type,
            log_path=log_file_path,
            start_time=date_today,
            pid=pid,
        )
        log.save()
        if self.login_type == "web":
            log.pid = log.id  # 设置log id为websocket的id, 然后kill时干掉websocket
            log.save()

        log_file_f.write("Start at %s\r\n" % datetime.datetime.now())
        return log_file_f, log_time_f, log
Пример #28
0
 def run(self, module_name='shell', module_args='', timeout=10, forks=10, pattern='*',
         become=False, become_method='sudo', become_user='******', become_pass=''):
     """
     run module from andible ad-hoc.
     module_name: ansible module_name
     module_args: ansible module args
     """
     if module_name == 'user_check':
         hoc = Runner(module_name='command',
                      module_args='cat /etc/group',
                      timeout=timeout,
                      inventory=self.inventory,
                      pattern=pattern,
                      forks=forks,
                      become=become,
                      become_method=become_method,
                      become_user=become_user,
                      become_pass=become_pass
                      )
         temp_result= hoc.run()
         output = temp_result['contacted']
         temp_list = list()
         for node in output.keys():
             lines = output[node]['stdout'].split('\n')
             groups = [line.split(':')[0] for line in lines]
             if module_name == 'user_check':
                 for g in groups:
                     temp_name = 'name='+g
                     if module_args.split(' ')[0] == temp_name:
                         temp_list.append(node)
                         break
         if temp_list:
             return {'flag': False, 'nodes': temp_list}
     
     hoc = Runner(module_name=module_name,
                  module_args=module_args,
                  timeout=timeout,
                  inventory=self.inventory,
                  pattern=pattern,
                  forks=forks,
                  become=become,
                  become_method=become_method,
                  become_user=become_user,
                  become_pass=become_pass
                  )
     self.results_raw = hoc.run()
     logger.debug(self.results_raw)
     return self.results_raw
Пример #29
0
def upload(request):
    user = request.user
    assets = list(get_group_user_perm(user).get('asset').keys())
    asset_select = []
    if request.method == 'POST':
        remote_ip = request.META.get('REMOTE_ADDR')
        asset_ids = request.POST.getlist('asset_ids', '')
        upload_files = request.FILES.getlist('file[]', None)
        date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
        upload_dir = get_tmp_dir()
        # file_dict = {}
        for asset_id in asset_ids:
            asset_select.append(get_object(Asset, id=asset_id))

        if not set(asset_select).issubset(set(assets)):
            illegal_asset = set(asset_select).issubset(set(assets))
            return HttpResponse(
                '没有权限的服务器 %s' %
                ','.join([asset.hostname for asset in illegal_asset]))

        for upload_file in upload_files:
            file_path = '%s/%s' % (upload_dir, upload_file.name)
            with open(file_path, 'wb+') as f:
                for chunk in upload_file.chunks():
                    f.write(chunk)

        res = gen_resource({'user': user, 'asset': asset_select})
        runner = MyRunner(res)
        runner.run('copy',
                   module_args='src=%s dest=%s' % (upload_dir, '/tmp'),
                   pattern='*')
        ret = runner.results
        logger.debug(ret)
        FileLog(user=request.user.username,
                host=' '.join([asset.hostname for asset in asset_select]),
                filename=' '.join([f.name for f in upload_files]),
                type='upload',
                remote_ip=remote_ip,
                result=ret).save()
        if ret.get('failed'):
            error = '上传目录: %s <br> 上传失败: [ %s ] <br>上传成功 [ %s ]' % (
                upload_dir, ', '.join(list(ret.get('failed').keys())),
                ', '.join(list(ret.get('ok').keys())))
            return HttpResponse(error, status=500)
        msg = '上传目录: %s <br> 传送成功 [ %s ]' % (upload_dir, ', '.join(
            list(ret.get('ok').keys())))
        return HttpResponse(msg)
    return my_render('upload.html', locals(), request)
Пример #30
0
def user_del(request):
    if request.method == "GET":
        user_ids = request.GET.get('id', '')
        user_id_list = user_ids.split(',')
    elif request.method == "POST":
        user_ids = request.POST.get('id', '')
        user_id_list = user_ids.split(',')
    else:
        return HttpResponse('错误请求')

    for user_id in user_id_list:
        user = get_object(User, id=user_id)
        if user and user.username != 'admin':
            logger.debug("删除用户 %s " % user.username)
            server_del_user(user.username)
            user.delete()
    return HttpResponse('删除成功')
Пример #31
0
 def get_connect_info(self):
     """
     获取需要登陆的主机的信息和映射用户的账号密码
     """
     asset_info = get_asset_info(self.asset)
     role_key = get_role_key(self.user, self.role)  # 获取角色的key,因为ansible需要权限是600,所以统一生成用户_角色key
     role_pass = CRYPTOR.decrypt(self.role.password)
     connect_info = {
         "user": self.user,
         "asset": self.asset,
         "ip": asset_info.get("ip"),
         "port": int(asset_info.get("port")),
         "role_name": self.role.name,
         "role_pass": role_pass,
         "role_key": role_key,
     }
     logger.debug(connect_info)
     return connect_info
Пример #32
0
def perm_role_add(request):
    """
    add role page
    """
    # 渲染数据
    header_title, path1, path2 = "系统用户", "系统用户管理", "添加系统用户"
    sudos = PermSudo.objects.all()

    if request.method == "POST":
        # 获取参数: name, comment
        name = request.POST.get("role_name", "").strip()
        comment = request.POST.get("role_comment", "")
        password = request.POST.get("role_password", "")
        key_content = request.POST.get("role_key", "")
        sudo_ids = request.POST.getlist('sudo_name')

        try:
            if get_object(PermRole, name=name):
                raise ServerError(u'已经存在该用户 %s' % name)
            if name == "root":
                raise ServerError(u'禁止使用root用户作为系统用户,这样非常危险!')
            default = get_object(Setting, name='default')
            if len(password) > 64:
                raise ServerError(u'密码长度不能超过64位!')

            if password:
                encrypt_pass = CRYPTOR.encrypt(password)
            else:
                encrypt_pass = CRYPTOR.encrypt(CRYPTOR.gen_rand_pass(20))
            # 生成随机密码,生成秘钥对
            sudos_obj = [get_object(PermSudo, id=sudo_id) for sudo_id in sudo_ids]
            if key_content:
                try:
                    key_path = gen_keys(key=key_content)
                except SSHException, e:
                    raise ServerError(e)
            else:
                key_path = gen_keys()
            logger.debug('generate role key: %s' % key_path)
            role = PermRole(name=name, comment=comment, password=encrypt_pass, key_path=key_path)
            role.save()
            role.sudo = sudos_obj
            msg = u"添加系统用户: %s" % name
            return HttpResponseRedirect(reverse('role_list'))
Пример #33
0
def perm_sudo_add(request):
    """
    list sudo commands alias
    :param request:
    :return:
    """
    # 渲染数据
    header_title, path1, path2 = "Sudo命令", "别名管理", "添加别名"
    login_user_id = request.user.id
    if not login_user_id:
        return HttpResponseRedirect(reverse('index'))
    login_user = User.objects.get(id=login_user_id)
    productlines = ProductLine.objects.all()
    try:
        if request.method == "POST":
            # 获取参数: name, comment
            name = request.POST.get("sudo_name").strip().upper()
            comment = request.POST.get("sudo_comment").strip()
            commands = request.POST.get("sudo_commands").strip()
            productline_name = request.POST.get('productline_name', '')
            productLine = get_object_or_404(ProductLine, name=productline_name)

            if not name or not commands:
                raise ServerError(u"sudo name 和 commands是必填项!")

            pattern = re.compile(r'[\n,\r]')
            deal_space_commands = list_drop_str(pattern.split(commands), u'')
            deal_all_commands = map(trans_all, deal_space_commands)
            commands = ', '.join(deal_all_commands)
            logger.debug(u'添加sudo %s: %s' % (name, commands))

            if get_object(PermSudo, name=name, productLine=productLine):
                error = 'Sudo别名 %s已经存在' % name
            else:
                sudo = PermSudo(name=name.strip(),
                                comment=comment,
                                productLine=productLine,
                                commands=commands)
                sudo.save()
                msg = u"添加Sudo命令别名: %s" % name
    except ServerError, e:
        error = e
Пример #34
0
 def run(self, module_name='shell', module_args='', timeout=10, forks=10, pattern='*',
         become=False, become_method='sudo', become_user='******', become_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=become,
                  become_method=become_method,
                  become_user=become_user,
                  become_pass=become_pass
                  )
     self.results_raw = hoc.run()
     logger.debug(self.results_raw)
     return self.results_raw
Пример #35
0
    def upload(self):
        while True:
            try:
                print "进入批量上传模式"
                print
                print "授权包含该系统用户的所有主机"
                assets = self.user_perm.get('asset').keys()
                for asset in assets:
                    print ' %s' % asset.hostname
                print
                print "请输入主机名或ansible支持的pattern, 多个主机:分隔 q退出"
                print
                pattern = raw_input("\033[1;32mPattern>:\033[0m ").strip()
                if pattern == 'q':
                    break
                else:
                    res = gen_resource({'user': self.user, 'asset': assets}, perm=self.user_perm)
                    runner = MyRunner(res)
                    asset_name_str = ''
                    print "匹配主机:"
                    for inv in runner.inventory.get_hosts(pattern=pattern):
                        print inv.name
                        asset_name_str += '%s ' % inv.name

                    if not asset_name_str:
                        color_print('没有匹配主机')
                        continue
                    tmp_dir = get_tmp_dir()
                    logger.debug('Upload tmp dir: %s' % tmp_dir)
                    os.chdir(tmp_dir)
                    bash('rz')
                    filename_str = ' '.join(os.listdir(tmp_dir))
                    if not filename_str:
                        color_print("上传文件为空")
                        continue
                    logger.debug('上传文件: %s' % filename_str)

                    runner = MyRunner(res)
                    runner.run('copy', module_args='src=%s dest=%s directory_mode'
                                                     % (tmp_dir, '/tmp'), pattern=pattern)
                    ret = runner.results
                    FileLog(user=self.user.username, name=self.user.name, host=asset_name_str, filename=filename_str,
                            remote_ip=remote_ip, type='upload', result=ret).save()
                    logger.debug('Upload file: %s' % ret)
                    if ret.get('failed'):
                        error = '上传目录: %s \n上传失败: [ %s ] \n上传成功 [ %s ]' % (tmp_dir,
                                                                             ', '.join(ret.get('failed').keys()),
                                                                             ', '.join(ret.get('ok').keys()))
                        color_print(error)
                    else:
                        msg = '上传目录: %s \n传送成功 [ %s ]' % (tmp_dir, ', '.join(ret.get('ok').keys()))
                        color_print(msg, 'green')
                    print

            except IndexError:
                pass
Пример #36
0
    def upload(self):
        while True:
            if not self.user_perm:
                self.user_perm = get_group_user_perm(self.user)
            try:
                print "进入批量上传模式"
                print "请输入主机名或ansible支持的pattern, 多个主机:分隔 q退出"
                pattern = raw_input("\033[1;32mPattern>:\033[0m ").strip()
                if pattern == 'q':
                    break
                else:
                    assets = self.user_perm.get('asset').keys()
                    res = gen_resource({'user': self.user, 'asset': assets}, perm=self.user_perm)
                    runner = MyRunner(res)
                    asset_name_str = ''
                    print "匹配主机:"
                    for inv in runner.inventory.get_hosts(pattern=pattern):
                        print inv.name
                        asset_name_str += '%s ' % inv.name

                    if not asset_name_str:
                        color_print('没有匹配主机')
                        continue
                    tmp_dir = get_tmp_dir()
                    logger.debug('Upload tmp dir: %s' % tmp_dir)
                    os.chdir(tmp_dir)
                    bash('rz')
                    filename_str = ' '.join(os.listdir(tmp_dir))
                    if not filename_str:
                        color_print("上传文件为空")
                        continue
                    logger.debug('上传文件: %s' % filename_str)

                    runner = MyRunner(res)
                    runner.run('copy', module_args='src=%s dest=%s directory_mode'
                                                     % (tmp_dir, tmp_dir), pattern=pattern)
                    ret = runner.results
                    FileLog(user=self.user.name, host=asset_name_str, filename=filename_str,
                            remote_ip=remote_ip, type='upload', result=ret).save()
                    logger.debug('Upload file: %s' % ret)
                    if ret.get('failed'):
                        error = '上传目录: %s \n上传失败: [ %s ] \n上传成功 [ %s ]' % (tmp_dir,
                                                                             ', '.join(ret.get('failed').keys()),
                                                                             ', '.join(ret.get('ok').keys()))
                        color_print(error)
                    else:
                        msg = '上传目录: %s \n传送成功 [ %s ]' % (tmp_dir, ', '.join(ret.get('ok').keys()))
                        color_print(msg, 'green')
                    print

            except IndexError:
                pass
Пример #37
0
def add_register(request):
    """
    为注册用户创建jumpserver账号

    """
    logger.debug('添加注册用户到jumpserver, 执行函数: add_register')
    if request.method == 'GET':
        uid = request.GET.get('id','')
        logger.debug('选中的用户ID为: %s' % uid)
        # 取出选中的注册用户记录
        try: 
            new_user = RegisterUser.objects.get(id=uid)
            logger.debug("添加用户: %s(%s)", (new_user.username, new_user.name))
        except:
            logger.debug("ERROR: 在注册用户表(registereduser)中没有找到用户, 添加失败")
            return HttpResponse("ERROR: 注册失败")
        msg = add_register_user(new_user)
        return HttpResponse(msg)
    else:
        return HttpResponse('improssable!')
Пример #38
0
def add_register_user(register_user):
    """
    创建用户账号
    """
    logger.debug("进入工具函数: 'add_register_user'")
    # 用户姓名
    name = register_user.name
    # 注册账号名及密码
    username = register_user.username
    password = register_user.password
    email = register_user.email
    # 自动生成用户UUID及SSH密钥
    uuid_r = uuid.uuid4().get_hex()
    ssh_key_pwd = PyCrypt.gen_rand_pass(16)
    # 默认用户不加入任何组
    groups = []
    admin_groups = []
    # 用户默认为普通用户
    role = 'CU'
    # 默认激活用户账号
    is_active = 1

    try:
        # 创建jumpserver的User对象
        user = db_add_user(username=username,
                           name=name,
                           password=password,
                           email=email,
                           role=role,
                           uuid=uuid_r,
                           groups=groups,
                           admin_groups=admin_groups,
                           ssh_key_pwd=ssh_key_pwd,
                           is_active=is_active,
                           date_joined=datetime.now())
        logger.debug("jumpserver用户添加成功: %s", user.username)
        # 在堡垒机上添加jumpserver用户对应的操作系统账号
        server_add_user(username=username, ssh_key_pwd=ssh_key_pwd)
        logger.debug("操作系统账号添加成功: %s", user.username)

    except ServerError, e:
        loggeo.debug(u'jumpserver用户账号添加失败: %s' % username)
        raise ServerError
Пример #39
0
    except ServerError, e:
        loggeo.debug(u'jumpserver用户账号添加失败: %s' % username)
        raise ServerError

    # 开始为用户创建授权规则(PermRule)
    # 默认为每一个新注册用户创建一个与账号名相同的授权规则
    # 该授权中含有一个名为'zero'的资产组, 资产组中所包含的主机数量为0
    #

    rule_name = user.username
    # 授权规则说明信息
    rule_comment = u'给(%s)的授权. 创建于: %s' % (user.name, datetime.now())  # 授权规则说明
    # 创建一个授权规则对象, 随后更新授权信息
    new_rule = PermRule(name=rule_name, comment=rule_comment)
    new_rule.save()
    logger.debug("%s :授权规则对象创建成功" % new_rule.name)

    try:
        # 授权规则对应的用户
        rule_to_user = user
        logger.debug("规则对应的用户为 %s" % user.username)
        # 'zero'资产组
        # 默认每个注册用户都会被赋予'zero'资产组
        #
        asset_group = AssetGroup.objects.get(name='zero')
        logger.debug("规则对应的资产组为: %s" % asset_group.name)
    except e:
        logger.debug("ERROR: 无法找到用户或资产组: %s" % e)
        return "ERROR: 更新授权规则失败"

    # 系统用户, 账号关联到的系统账号(jperm_permrole)
Пример #40
0
    def upload(self):
        while True:
            if not self.user_perm:
                self.user_perm = get_group_user_perm(self.user)
            try:
                print "进入批量上传模式"
                print "请输入主机名或ansile支持的pattern, 多个主机:分隔 q退出"
                pattern = raw_input("\033[1;32mPattern>:\033[0m ").strip()
                if pattern == "q":
                    break
                else:
                    assets = self.user_perm.get("asset").keys()
                    res = gen_resource({"user": self.user, "asset": assets}, perm=self.user_perm)
                    runner = MyRunner(res)
                    asset_name_str = ""
                    print "匹配主机:"
                    for inv in runner.inventory.get_hosts(pattern=pattern):
                        print inv.name
                        asset_name_str += "%s " % inv.name

                    if not asset_name_str:
                        color_print("没有匹配主机")
                        continue
                    tmp_dir = get_tmp_dir()
                    logger.debug("Upload tmp dir: %s" % tmp_dir)
                    os.chdir(tmp_dir)
                    bash("rz")
                    filename_str = " ".join(os.listdir(tmp_dir))
                    if not filename_str:
                        color_print("上传文件为空")
                        continue
                    logger.debug("上传文件: %s" % filename_str)

                    runner = MyRunner(res)
                    runner.run(
                        "copy", module_args="src=%s dest=%s directory_mode" % (tmp_dir, tmp_dir), pattern=pattern
                    )
                    ret = runner.results
                    FileLog(
                        user=self.user.name,
                        host=asset_name_str,
                        filename=filename_str,
                        remote_ip=remote_ip,
                        type="upload",
                        result=ret,
                    ).save()
                    logger.debug("Upload file: %s" % ret)
                    if ret.get("failed"):
                        error = "上传目录: %s \n上传失败: [ %s ] \n上传成功 [ %s ]" % (
                            tmp_dir,
                            ", ".join(ret.get("failed").keys()),
                            ", ".join(ret.get("ok").keys()),
                        )
                        color_print(error)
                    else:
                        msg = "上传目录: %s \n传送成功 [ %s ]" % (tmp_dir, ", ".join(ret.get("ok").keys()))
                        color_print(msg, "green")
                    print

            except IndexError:
                pass
Пример #41
0
def perm_role_edit(request):
    """
    edit role page
    """
    # 渲染数据
    header_title, path1, path2 = "系统用户", "系统用户管理", "系统用户编辑"

    # 渲染数据
    role_id = request.GET.get("id")
    role = PermRole.objects.get(id=role_id)
    role_pass = CRYPTOR.decrypt(role.password)
    role_sudos = role.sudo.all()

    productlines = ProductLine.objects.all()
    username = request.user.username
    user_perm = request.session['role_id']
    if user_perm == 2:
        sudo_all = PermSudo.objects.all()
    elif user_perm == 1:
        login_user = get_object(User, username=username)
        sudo_all = PermSudo.objects.all().filter(
            productLine=login_user.productLine)
    if request.method == "GET":
        return my_render('jperm/perm_role_edit.html', locals(), request)

    if request.method == "POST":
        # 获取 POST 数据
        role_name = request.POST.get("role_name")
        role_password = request.POST.get("role_password")
        role_comment = request.POST.get("role_comment")
        role_sudo_names = request.POST.getlist("sudo_name")
        role_sudos = [
            PermSudo.objects.get(id=sudo_id) for sudo_id in role_sudo_names
        ]
        key_content = request.POST.get("role_key", "")
        productline_name = request.POST.get('productline_name', '')
        productLine = get_object_or_404(ProductLine, name=productline_name)

        if len(role_password) > 64:
            raise ServerError(u'密码长度不能超过64位!')

        try:
            if not role:
                raise ServerError('该系统用户不能存在')

            if role_name == "root":
                raise ServerError(u'禁止使用root用户作为系统用户,这样非常危险!')

            if role_password:
                encrypt_pass = CRYPTOR.encrypt(role_password)
                role.password = encrypt_pass
            # 生成随机密码,生成秘钥对
            if key_content:
                try:
                    key_path = gen_keys(key=key_content,
                                        key_path_dir=role.key_path)
                except SSHException:
                    raise ServerError('输入的密钥不合法')
                logger.debug('Recreate role key: %s' % role.key_path)
            # 写入数据库
            role.name = role_name
            role.comment = role_comment
            role.sudo = role_sudos
            role.productLine = productLine
            role.save()
            msg = u"更新系统用户: %s" % role.name
            return HttpResponseRedirect(reverse('role_list'))
        except ServerError, e:
            error = e
Пример #42
0
         else:
             return HttpResponse("filter_type: ?")
     except ServerError, e:
         return HttpResponse(e)
 if request.method == "POST":
     try:
         # 获取参数删除的role对象
         role_id = request.POST.get("id")
         role = get_object(PermRole, id=role_id)
         if not role:
             logger.warning(u"Delete Role: role_id %s not exist" % role_id)
             raise ServerError(u"role_id %s 无数据记录" % role_id)
         role_key = role.key_path
         # 删除推送到主机上的role
         recycle_assets = [push.asset for push in role.perm_push.all() if push.success]
         logger.debug(u"delete role %s - delete_assets: %s" % (role.name, recycle_assets))
         if recycle_assets:
             recycle_resource = gen_resource(recycle_assets)
             task = MyTask(recycle_resource)
             try:
                 msg_del_user = task.del_user(get_object(PermRole, id=role_id).name)
                 msg_del_sudo = task.del_user_sudo(get_object(PermRole, id=role_id).name)
             except Exception, e:
                 logger.warning(u"Recycle Role failed: %s" % e)
                 raise ServerError(u"回收已推送的系统用户失败: %s" % e)
             logger.info(u"delete role %s - execute delete user: %s" % (role.name, msg_del_user))
             logger.info(u"delete role %s - execute delete sudo: %s" % (role.name, msg_del_sudo))
             # TODO: 判断返回结果,处理异常
         # 删除存储的秘钥,以及目录
         try:
             key_files = os.listdir(role_key)
Пример #43
0
    def download(self):
        while True:
            if not self.user_perm:
                self.user_perm = get_group_user_perm(self.user)
            try:
                print "进入批量下载模式"
                print "请输入主机名或ansile支持的pattern, 多个主机:分隔,q退出"
                pattern = raw_input("\033[1;32mPattern>:\033[0m ").strip()
                if pattern == "q":
                    break
                else:
                    assets = self.user_perm.get("asset").keys()
                    res = gen_resource({"user": self.user, "asset": assets}, perm=self.user_perm)
                    runner = MyRunner(res)
                    asset_name_str = ""
                    print "匹配主机:\n"
                    for inv in runner.inventory.get_hosts(pattern=pattern):
                        asset_name_str += "%s " % inv.name
                        print " %s" % inv.name
                    if not asset_name_str:
                        color_print("没有匹配主机")
                        continue
                    print
                    while True:
                        tmp_dir = get_tmp_dir()
                        logger.debug("Download tmp dir: %s" % tmp_dir)
                        print "请输入文件路径(不支持目录)"
                        file_path = raw_input("\033[1;32mPath>:\033[0m ").strip()
                        if file_path == "q":
                            break

                        if not file_path:
                            color_print("文件路径为空")
                            continue

                        runner.run("fetch", module_args="src=%s dest=%s" % (file_path, tmp_dir), pattern=pattern)
                        ret = runner.results
                        FileLog(
                            user=self.user.name,
                            host=asset_name_str,
                            filename=file_path,
                            type="download",
                            remote_ip=remote_ip,
                            result=ret,
                        ).save()
                        logger.debug("Download file result: %s" % ret)
                        os.chdir("/tmp")
                        tmp_dir_name = os.path.basename(tmp_dir)
                        if not os.listdir(tmp_dir):
                            color_print("下载全部失败")
                            continue
                        bash("tar czf %s.tar.gz %s && sz %s.tar.gz" % (tmp_dir, tmp_dir_name, tmp_dir))

                        if ret.get("failed"):
                            error = "文件名称: %s \n下载失败: [ %s ] \n下载成功 [ %s ]" % (
                                "%s.tar.gz" % tmp_dir_name,
                                ", ".join(ret.get("failed").keys()),
                                ", ".join(ret.get("ok").keys()),
                            )
                            color_print(error)
                        else:
                            msg = "文件名称: %s \n下载成功 [ %s ]" % (
                                "%s.tar.gz" % tmp_dir_name,
                                ", ".join(ret.get("ok").keys()),
                            )
                            color_print(msg, "green")
                        print
            except IndexError:
                pass
Пример #44
0
def perm_role_push(request):
    """
    the role push page
    """
    # 渲染数据
    header_title, path1, path2 = "系统用户", "系统用户管理", "系统用户推送"
    role_id = request.GET.get('id')
    asset_ids = request.GET.get('asset_id')
    role = get_object(PermRole, id=role_id)
    assets = Asset.objects.all()
    asset_groups = AssetGroup.objects.all()
    if asset_ids:
        need_push_asset = [
            get_object(Asset, id=asset_id) for asset_id in asset_ids.split(',')
        ]

    if request.method == "POST":
        # 获取推荐角色的名称列表
        # 计算出需要推送的资产列表
        asset_ids = request.POST.getlist("assets")
        asset_group_ids = request.POST.getlist("asset_groups")
        assets_obj = [Asset.objects.get(id=asset_id) for asset_id in asset_ids]
        asset_groups_obj = [
            AssetGroup.objects.get(id=asset_group_id)
            for asset_group_id in asset_group_ids
        ]
        group_assets_obj = []
        for asset_group in asset_groups_obj:
            group_assets_obj.extend(asset_group.asset_set.all())
        calc_assets = list(set(assets_obj) | set(group_assets_obj))

        push_resource = gen_resource(calc_assets)

        # 调用Ansible API 进行推送
        password_push = True if request.POST.get("use_password") else False
        key_push = True if request.POST.get("use_publicKey") else False
        task = MyTask(push_resource)
        ret = {}

        # 因为要先建立用户,而push key是在 password也完成的情况下的 可选项
        # 1. 以秘钥 方式推送角色
        if key_push:
            ret["pass_push"] = task.add_user(role.name)
            ret["key_push"] = task.push_key(
                role.name, os.path.join(role.key_path, 'id_rsa.pub'))

        # 2. 推送账号密码 <为了安全 系统用户统一使用秘钥进行通信, 不再提供密码方式的推送>
        # elif password_push:
        #     ret["pass_push"] = task.add_user(role.name, CRYPTOR.decrypt(role.password))

        # 3. 推送sudo配置文件
        if key_push:
            sudo_list = set([sudo for sudo in role.sudo.all()
                             ])  # set(sudo1, sudo2, sudo3)
            if sudo_list:
                ret['sudo'] = task.push_sudo_file([role], sudo_list)

        logger.debug('推送role结果: %s' % ret)
        success_asset = {}
        failed_asset = {}
        logger.debug(ret)
        for push_type, result in ret.items():
            if result.get('failed'):
                for hostname, info in result.get('failed').items():
                    if hostname in failed_asset.keys():
                        if info in failed_asset.get(hostname):
                            failed_asset[hostname] += info
                    else:
                        failed_asset[hostname] = info

        for push_type, result in ret.items():
            if result.get('ok'):
                for hostname, info in result.get('ok').items():
                    if hostname in failed_asset.keys():
                        continue
                    elif hostname in success_asset.keys():
                        if str(info) in success_asset.get(hostname, ''):
                            success_asset[hostname] += str(info)
                    else:
                        success_asset[hostname] = str(info)

        # 推送成功 回写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 failed_asset.get(asset.hostname):
                func(is_password=password_push,
                     is_public_key=key_push,
                     role=role,
                     asset=asset,
                     success=False,
                     result=failed_asset.get(asset.hostname))
            else:
                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(
                success_asset.keys()))
        else:
            error = u'系统用户 %s 推送失败 [ %s ], 推送成功 [ %s ] 进入系统用户详情,查看失败原因' % (
                role.name, ','.join(failed_asset.keys()), ','.join(
                    success_asset.keys()))
    return my_render('jperm/perm_role_push.html', locals(), request)
Пример #45
0
     except ServerError, e:
         return HttpResponse(e)
 if request.method == "POST":
     try:
         # 获取参数删除的role对象
         role_id = request.POST.get("id")
         role = get_object(PermRole, id=role_id)
         if not role:
             logger.warning(u"Delete Role: role_id %s not exist" % role_id)
             raise ServerError(u"role_id %s 无数据记录" % role_id)
         role_key = role.key_path
         # 删除推送到主机上的role
         recycle_assets = [
             push.asset for push in role.perm_push.all() if push.success
         ]
         logger.debug(u"delete role %s - delete_assets: %s" %
                      (role.name, recycle_assets))
         if recycle_assets:
             recycle_resource = gen_resource(recycle_assets)
             task = MyTask(recycle_resource)
             try:
                 msg_del_user = task.del_user(
                     get_object(PermRole, id=role_id).name)
                 msg_del_sudo = task.del_user_sudo(
                     get_object(PermRole, id=role_id).name)
             except Exception, e:
                 logger.warning(u"Recycle Role failed: %s" % e)
                 raise ServerError(u"回收已推送的系统用户失败: %s" % e)
             logger.info(u"delete role %s - execute delete user: %s" %
                         (role.name, msg_del_user))
             logger.info(u"delete role %s - execute delete sudo: %s" %
                         (role.name, msg_del_sudo))
Пример #46
0
def gen_resource(ob, perm=None):
    """
    ob为用户或资产列表或资产queryset, 如果同时输入用户和{'role': role1, 'asset': []},则获取用户在这些资产上的信息
    生成MyInventory需要的 resource文件
    """
    res = []
    if isinstance(ob, dict):
        role = ob.get('role')
        asset_r = ob.get('asset')
        user = ob.get('user')
        if not perm:
            perm = get_group_user_perm(user)

        if role:
            roles = perm.get('role', {}).keys()  # 获取用户所有授权角色
            if role not in roles:
                return {}

            role_assets_all = perm.get('role').get(role).get(
                'asset')  # 获取用户该角色所有授权主机
            assets = set(role_assets_all) & set(asset_r)  # 获取用户提交中合法的主机

            for asset in assets:
                asset_info = get_asset_info(asset)
                role_key = get_role_key(user, role)
                info = {
                    'hostname': asset.hostname,
                    'ip': asset.ip,
                    'port': asset_info.get('port', 22),
                    'ansible_ssh_private_key_file': role_key,
                    'username': role.name,
                    # 'password': CRYPTOR.decrypt(role.password)
                }

                if os.path.isfile(role_key):
                    info['ssh_key'] = role_key

                res.append(info)
        else:
            for asset, asset_info in perm.get('asset').items():
                if asset not in asset_r:
                    continue
                asset_info = get_asset_info(asset)
                try:
                    role = sorted(
                        list(perm.get('asset').get(asset).get('role')))[0]
                except IndexError:
                    continue

                role_key = get_role_key(user, role)
                info = {
                    'hostname': asset.hostname,
                    'ip': asset.ip,
                    'port': asset_info.get('port', 22),
                    'username': role.name,
                    'password': CRYPTOR.decrypt(role.password),
                }
                if os.path.isfile(role_key):
                    info['ssh_key'] = role_key

                res.append(info)

    elif isinstance(ob, User):
        if not perm:
            perm = get_group_user_perm(ob)

        for asset, asset_info in perm.get('asset').items():
            asset_info = get_asset_info(asset)
            info = {
                'hostname': asset.hostname,
                'ip': asset.ip,
                'port': asset_info.get('port', 22)
            }
            try:
                role = sorted(list(
                    perm.get('asset').get(asset).get('role')))[0]
            except IndexError:
                continue
            info['username'] = role.name
            info['password'] = CRYPTOR.decrypt(role.password)

            role_key = get_role_key(ob, role)
            if os.path.isfile(role_key):
                info['ssh_key'] = role_key
            res.append(info)

    elif isinstance(ob, (list, QuerySet)):
        for asset in ob:
            info = get_asset_info(asset)
            res.append(info)
    logger.debug('生成res: %s' % res)
    return res
Пример #47
0
def perm_role_push(request):
    """
    the role push page
    """
    # 渲染数据
    header_title, path1, path2 = "系统用户", "系统用户管理", "系统用户推送"
    role_id = request.GET.get('id')
    asset_ids = request.GET.get('asset_id')
    role = get_object(PermRole, id=role_id)
    assets = Asset.objects.all()
    asset_groups = AssetGroup.objects.all()
    if asset_ids:
        need_push_asset = [get_object(Asset, id=asset_id) for asset_id in asset_ids.split(',')]

    if request.method == "POST":
        # 获取推荐角色的名称列表
        # 计算出需要推送的资产列表
        asset_ids = request.POST.getlist("assets")
        asset_group_ids = request.POST.getlist("asset_groups")
        assets_obj = [Asset.objects.get(id=asset_id) for asset_id in asset_ids]
        asset_groups_obj = [AssetGroup.objects.get(id=asset_group_id) for asset_group_id in asset_group_ids]
        group_assets_obj = []
        for asset_group in asset_groups_obj:
            group_assets_obj.extend(asset_group.asset_set.all())
        calc_assets = list(set(assets_obj) | set(group_assets_obj))

        push_resource = gen_resource(calc_assets)

        # 调用Ansible API 进行推送
        password_push = True if request.POST.get("use_password") else False
        key_push = True if request.POST.get("use_publicKey") else False
        task = MyTask(push_resource)
        ret = {}

        # 因为要先建立用户,而push key是在 password也完成的情况下的 可选项
        # 1. 以秘钥 方式推送角色
        if key_push:
            ret["pass_push"] = task.add_user(role.name)
            ret["key_push"] = task.push_key(role.name, os.path.join(role.key_path, 'id_rsa.pub'))

        # 2. 推送账号密码 <为了安全 系统用户统一使用秘钥进行通信, 不再提供密码方式的推送>
        # elif password_push:
        #     ret["pass_push"] = task.add_user(role.name, CRYPTOR.decrypt(role.password))

        # 3. 推送sudo配置文件
        if key_push:
            sudo_list = set([sudo for sudo in role.sudo.all()])  # set(sudo1, sudo2, sudo3)
            if sudo_list:
                ret['sudo'] = task.push_sudo_file([role], sudo_list)

        logger.debug('推送role结果: %s' % ret)
        success_asset = {}
        failed_asset = {}
        logger.debug(ret)
        for push_type, result in ret.items():
            if result.get('failed'):
                for hostname, info in result.get('failed').items():
                    if hostname in failed_asset.keys():
                        if info in failed_asset.get(hostname):
                            failed_asset[hostname] += info
                    else:
                        failed_asset[hostname] = info

        for push_type, result in ret.items():
            if result.get('ok'):
                for hostname, info in result.get('ok').items():
                    if hostname in failed_asset.keys():
                        continue
                    elif hostname in success_asset.keys():
                        if str(info) in success_asset.get(hostname, ''):
                            success_asset[hostname] += str(info)
                    else:
                        success_asset[hostname] = str(info)

        # 推送成功 回写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 failed_asset.get(asset.hostname):
                func(is_password=password_push, is_public_key=key_push, role=role, asset=asset, success=False,
                     result=failed_asset.get(asset.hostname))
            else:
                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(success_asset.keys()))
        else:
            error = u'系统用户 %s 推送失败 [ %s ], 推送成功 [ %s ] 进入系统用户详情,查看失败原因' % (role.name,
                                                                ','.join(failed_asset.keys()),
                                                                ','.join(success_asset.keys()))
    return my_render('jperm/perm_role_push.html', locals(), request)