二次开发jumpserver——整合jumpserver与zabbix推送主机功能

Posted 辣个提莫有毒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二次开发jumpserver——整合jumpserver与zabbix推送主机功能相关的知识,希望对你有一定的参考价值。

jasset/forms.py

             "ip", "other_ip", "hostname", "port", "group", "username", "password", "use_default_auth",
              "idc", "mac", "remote_ip", "brand", "cpu", "memory", "disk", "system_type", "system_version",
              "cabinet", "position", "number", "status", "asset_type", "env", "sn", "is_active", "comment",
 -            "system_arch"
 +            "system_arch", "zbx_hostid"
          ]
# coding:utf-8
from django import forms

from jasset.models import IDC, Asset, AssetGroup


class AssetForm(forms.ModelForm):

    class Meta:
        model = Asset

        fields = [
            "ip", "other_ip", "hostname", "port", "group", "username", "password", "use_default_auth",
            "idc", "mac", "remote_ip", "brand", "cpu", "memory", "disk", "system_type", "system_version",
            "cabinet", "position", "number", "status", "asset_type", "env", "sn", "is_active", "comment",
            "system_arch", "zbx_hostid"
        ]


class AssetGroupForm(forms.ModelForm):
    class Meta:
        model = AssetGroup
        fields = [
            "name", "comment"
        ]


class IdcForm(forms.ModelForm):
    class Meta:
        model = IDC
        fields = [\'name\', "bandwidth", "operator", \'linkman\', \'phone\', \'address\', \'network\', \'comment\']
        widgets = {
            \'name\': forms.TextInput(attrs={\'placeholder\': \'Name\'}),
            \'network\': forms.Textarea(
                attrs={\'placeholder\': \'192.168.1.0/24\\n192.168.2.0/24\'})
        }

 

jasset/models.py

 

     date_added = models.DateTimeField(auto_now=True, null=True)
      is_active = models.BooleanField(default=True, verbose_name=u"是否激活")
      comment = models.CharField(max_length=128, blank=True, null=True, verbose_name=u"备注")
 +    zbx_hostid = models.CharField(max_length=32, blank=True, verbose_name=u"zabbix主机ID")
  
      def __unicode__(self):
          return self.ip

 

# coding: utf-8

import datetime
from django.db import models
from juser.models import User, UserGroup

ASSET_ENV = (
    (1, U\'生产环境\'),
    (2, U\'测试环境\')
    )

ASSET_STATUS = (
    (1, u"已使用"),
    (2, u"未使用"),
    (3, u"报废")
    )

ASSET_TYPE = (
    (1, u"物理机"),
    (2, u"虚拟机"),
    (3, u"交换机"),
    (4, u"路由器"),
    (5, u"防火墙"),
    (6, u"Docker"),
    (7, u"其他")
    )


class AssetGroup(models.Model):
    GROUP_TYPE = (
        (\'P\', \'PRIVATE\'),
        (\'A\', \'ASSET\'),
    )
    name = models.CharField(max_length=80, unique=True)
    comment = models.CharField(max_length=160, blank=True, null=True)

    def __unicode__(self):
        return self.name


class IDC(models.Model):
    name = models.CharField(max_length=32, verbose_name=u\'机房名称\')
    bandwidth = models.CharField(max_length=32, blank=True, null=True, default=\'\', verbose_name=u\'机房带宽\')
    linkman = models.CharField(max_length=16, blank=True, null=True, default=\'\', verbose_name=u\'联系人\')
    phone = models.CharField(max_length=32, blank=True, null=True, default=\'\', verbose_name=u\'联系电话\')
    address = models.CharField(max_length=128, blank=True, null=True, default=\'\', verbose_name=u"机房地址")
    network = models.TextField(blank=True, null=True, default=\'\', verbose_name=u"IP地址段")
    date_added = models.DateField(auto_now=True, null=True)
    operator = models.CharField(max_length=32, blank=True, default=\'\', null=True, verbose_name=u"运营商")
    comment = models.CharField(max_length=128, blank=True, default=\'\', null=True, verbose_name=u"备注")

    def __unicode__(self):
        return self.name

    class Meta:
        verbose_name = u"IDC机房"
        verbose_name_plural = verbose_name


class Asset(models.Model):
    """
    asset modle
    """
    ip = models.CharField(max_length=32, blank=True, null=True, verbose_name=u"主机IP")
    other_ip = models.CharField(max_length=255, blank=True, null=True, verbose_name=u"其他IP")
    hostname = models.CharField(unique=True, max_length=128, verbose_name=u"主机名")
    port = models.IntegerField(blank=True, null=True, verbose_name=u"端口号")
    group = models.ManyToManyField(AssetGroup, blank=True, verbose_name=u"所属主机组")
    username = models.CharField(max_length=16, blank=True, null=True, verbose_name=u"管理用户名")
    password = models.CharField(max_length=256, blank=True, null=True, verbose_name=u"密码")
    use_default_auth = models.BooleanField(default=True, verbose_name=u"使用默认管理账号")
    idc = models.ForeignKey(IDC, blank=True, null=True,  on_delete=models.SET_NULL, verbose_name=u\'机房\')
    mac = models.CharField(max_length=20, blank=True, null=True, verbose_name=u"MAC地址")
    remote_ip = models.CharField(max_length=16, blank=True, null=True, verbose_name=u\'远控卡IP\')
    brand = models.CharField(max_length=64, blank=True, null=True, verbose_name=u\'硬件厂商型号\')
    cpu = models.CharField(max_length=64, blank=True, null=True, verbose_name=u\'CPU\')
    memory = models.CharField(max_length=128, blank=True, null=True, verbose_name=u\'内存\')
    disk = models.CharField(max_length=1024, blank=True, null=True, verbose_name=u\'硬盘\')
    system_type = models.CharField(max_length=32, blank=True, null=True, verbose_name=u"系统类型")
    system_version = models.CharField(max_length=8, blank=True, null=True, verbose_name=u"系统版本号")
    system_arch = models.CharField(max_length=16, blank=True, null=True, verbose_name=u"系统平台")
    cabinet = models.CharField(max_length=32, blank=True, null=True, verbose_name=u\'机柜号\')
    position = models.IntegerField(blank=True, null=True, verbose_name=u\'机器位置\')
    number = models.CharField(max_length=32, blank=True, null=True, verbose_name=u\'资产编号\')
    status = models.IntegerField(choices=ASSET_STATUS, blank=True, null=True, default=1, verbose_name=u"机器状态")
    asset_type = models.IntegerField(choices=ASSET_TYPE, blank=True, null=True, verbose_name=u"主机类型")
    env = models.IntegerField(choices=ASSET_ENV, blank=True, null=True, verbose_name=u"运行环境")
    sn = models.CharField(max_length=128, blank=True, null=True, verbose_name=u"SN编号")
    date_added = models.DateTimeField(auto_now=True, null=True)
    is_active = models.BooleanField(default=True, verbose_name=u"是否激活")
    comment = models.CharField(max_length=128, blank=True, null=True, verbose_name=u"备注")
    zbx_hostid = models.CharField(max_length=32, blank=True, verbose_name=u"zabbix主机ID")

    def __unicode__(self):
        return self.ip


class AssetRecord(models.Model):
    asset = models.ForeignKey(Asset)
    username = models.CharField(max_length=30, null=True)
    alert_time = models.DateTimeField(auto_now_add=True)
    content = models.TextField(null=True, blank=True)
    comment = models.TextField(null=True, blank=True)


class AssetAlias(models.Model):
    user = models.ForeignKey(User)
    asset = models.ForeignKey(Asset)
    alias = models.CharField(max_length=100, blank=True, null=True)

    def __unicode__(self):
        return self.alias

 

 

jasset/urls.py

 

     url(r\'^asset/edit_batch/$\', asset_edit_batch, name=\'asset_edit_batch\'),
      url(r\'^asset/update/$\', asset_update, name=\'asset_update\'),
      url(r\'^asset/update_batch/$\', asset_update_batch, name=\'asset_update_batch\'),
 +    url(r\'^asset/zabbix_update_batch/$\', zabbix_update_batch, name=\'zabbix_update_batch\'),
      url(r\'^asset/upload/$\', asset_upload, name=\'asset_upload\'),
      url(r\'^group/del/$\', group_del, name=\'asset_group_del\'),
      url(r\'^group/add/$\', group_add, name=\'asset_group_add\'),

 

# coding:utf-8
from django.conf.urls import patterns, include, url
from jasset.views import *

urlpatterns = patterns(\'\',
    url(r\'^asset/add/$\', asset_add, name=\'asset_add\'),
    url(r"^asset/add_batch/$", asset_add_batch, name=\'asset_add_batch\'),
    url(r\'^asset/list/$\', asset_list, name=\'asset_list\'),
    url(r\'^asset/del/$\', asset_del, name=\'asset_del\'),
    url(r"^asset/detail/$", asset_detail, name=\'asset_detail\'),
    url(r\'^asset/edit/$\', asset_edit, name=\'asset_edit\'),
    url(r\'^asset/edit_batch/$\', asset_edit_batch, name=\'asset_edit_batch\'),
    url(r\'^asset/update/$\', asset_update, name=\'asset_update\'),
    url(r\'^asset/update_batch/$\', asset_update_batch, name=\'asset_update_batch\'),
    url(r\'^asset/zabbix_update_batch/$\', zabbix_update_batch, name=\'zabbix_update_batch\'),
    url(r\'^asset/upload/$\', asset_upload, name=\'asset_upload\'),
    url(r\'^group/del/$\', group_del, name=\'asset_group_del\'),
    url(r\'^group/add/$\', group_add, name=\'asset_group_add\'),
    url(r\'^group/list/$\', group_list, name=\'asset_group_list\'),
    url(r\'^group/edit/$\', group_edit, name=\'asset_group_edit\'),
    url(r\'^idc/add/$\', idc_add, name=\'idc_add\'),
    url(r\'^idc/list/$\', idc_list, name=\'idc_list\'),
    url(r\'^idc/edit/$\', idc_edit, name=\'idc_edit\'),
    url(r\'^idc/del/$\', idc_del, name=\'idc_del\'),
)

 

 

jasset/views.py

                 asset_save.save()
                  af_post.save_m2m()
  
 -                msg = u\'主机 %s 添加成功\' % hostname
 +                #add host to zabbix
 +                if IS_ZABBIX:
 +                    #全局开启
 +                    zbx_result = ZABBIX_API.create_host(hostname, ip, 5)
 +                    if zbx_result.get(\'result\'):
 +                        #同步zabbix成功
 +                        zbx_hostid = zbx_result[\'result\'][\'hostids\'][0]
 +                        #更新asset数据库
 +                        Asset.objects.filter(hostname=hostname).update(zbx_hostid=zbx_hostid)
 +                        msg = u\'主机 %s 添加成功,同步至zabbix成功,hostid: %s\' %(hostname,zbx_hostid)
 +                    else:
 +                        #同步zabbix失败
 +                        zbx_error = zbx_result.get(\'error\')[\'data\']
 +                        msg = u\'主机 %s 添加成功,同步至zabbix失败,失败原因:%s\' %(hostname,zbx_error)
 +                else:
 +                    msg = u\'主机 %s 添加成功\' % hostname
              else:
                  esg = u\'主机 %s 添加失败\' % hostname
  
 @@ -180,16 +195,28 @@ def asset_del(request):
      删除主机
      """
      asset_id = request.GET.get(\'id\', \'\')
 +    zbx_hostid = request.GET.get(\'zbx_hostid\', \'\')

      if asset_id:
          Asset.objects.filter(id=asset_id).delete()
  
 +    if zbx_hostid:
 +        #同步删除zabbix
 +        ZABBIX_API.delete_host(zbx_hostid)

      if request.method == \'POST\':
          asset_batch = request.GET.get(\'arg\', \'\')
          asset_id_all = str(request.POST.get(\'asset_id_all\', \'\'))
  
          if asset_batch:
              for asset_id in asset_id_all.split(\',\'):
                  asset = get_object(Asset, id=asset_id)
 +                #同步删除zabbix
 +                batch_zbx_hostid = asset.zbx_hostid
 +                ZABBIX_API.delete_host(batch_zbx_hostid)
                  asset.delete()
  
      return HttpResponse(u\'删除成功\')
 @@ -204,6 +231,7 @@ def asset_edit(request):
      header_title, path1, path2 = u\'修改资产\', u\'资产管理\', u\'修改资产\'
  
      asset_id = request.GET.get(\'id\', \'\')
 +    zbx_hostid = request.GET.get(\'zbx_hostid\', \'\')
      username = request.user.username
      asset = get_object(Asset, id=asset_id)
      if asset:
 @@ -246,6 +274,11 @@ def asset_edit(request):
                      info = asset_diff(af_post.__dict__.get(\'initial\'), request.POST)
                      db_asset_alert(asset, username, info)
  
 +                    if zbx_hostid:
 +                        #同步修改zabbix
 +                        zbx_result = ZABBIX_API.update_host(zbx_hostid, hostname)
 +                        #print zbx_result

                      smg = u\'主机 %s 修改成功\' % ip
                  else:
                      emg = u\'主机 %s 修改失败\' % ip
 @@ -491,6 +524,32 @@ def asset_update_batch(request):
      return HttpResponse(u\'批量更新成功!\')
  
  

 +@require_role(\'admin\')
 +def zabbix_update_batch(request):
 +    if request.method == \'POST\':
 +        arg = request.GET.get(\'arg\', \'\')
 +        name = unicode(request.user.username) + \' - \' + u\'自动更新\'
 +        if arg == \'all\':
 +            asset_list = Asset.objects.all()
 +        else:
 +            asset_id_all = unicode(request.POST.get(\'asset_id_all\', \'\'))
 +            asset_id_all = asset_id_all.split(\',\')
 +            for asset_id in asset_id_all:
 +                asset = get_object(Asset, id=asset_id)
 +                if not asset.zbx_hostid:
 +                    #同步zabbix
 +                    hostname = asset.hostname
 +                    ip = asset.ip
 +                    zbx_result =  ZABBIX_API.create_host(hostname,ip,5)
 +                    if zbx_result.get(\'result\'):
 +                        add_zbx_hostid = zbx_result[\'result\'][\'hostids\'][0]
 +                        asset.zbx_hostid = add_zbx_hostid
 +                        asset.save()
 +        return HttpResponse(u\'批量更新成功!\')
 +    return HttpResponse(u\'批量更新成功!\')

  @require_role(\'admin\')
  def idc_add(request):
      """

 

 

# coding:utf-8

from django.db.models import Q
from jasset.asset_api import *
from jumpserver.api import *
from jumpserver.models import Setting
from jasset.forms import AssetForm, IdcForm
from jasset.models import Asset, IDC, AssetGroup, ASSET_TYPE, ASSET_STATUS
from jperm.perm_api import get_group_asset_perm, get_group_user_perm


@require_role(\'admin\')
def group_add(request):
    """
    Group add view
    添加资产组
    """
    header_title, path1, path2 = u\'添加资产组\', u\'资产管理\', u\'添加资产组\'
    asset_all = Asset.objects.all()

    if request.method == \'POST\':
        name = request.POST.get(\'name\', \'\')
        asset_select = request.POST.getlist(\'asset_select\', [])
        comment = request.POST.get(\'comment\', \'\')

        try:
            if not name:
                emg = u\'组名不能为空\'
                raise ServerError(emg)

            asset_group_test = get_object(AssetGroup, name=name)
            if asset_group_test:
                emg = u"该组名 %s 已存在" % name
                raise ServerError(emg)

        except ServerError:
            pass

        else:
            db_add_group(name=name, comment=comment, asset_select=asset_select)
            smg = u"主机组 %s 添加成功" % name

    return my_render(\'jasset/group_add.html\', locals(), request)


@require_role(\'admin\')
def group_edit(request):
    """
    Group edit view
    编辑资产组
    """
    header_title, path1, path2 = u\'编辑主机组\', u\'资产管理\', u\'编辑主机组\'
    group_id = request.GET.get(\'id\', \'\')
    group = get_object(AssetGroup, id=group_id)

    asset_all = Asset.objects.all()
    asset_select = Asset.objects.filter(group=group)
    asset_no_select = [a for a in asset_all if a not in asset_select]

    if request.method == \'POST\':
        name = request.POST.get(\'name\', \'\')
        asset_select = request.POST.getlist(\'asset_select\', [])
        comment = request.POST.get(\'comment\', \'\')

        try:
            if not name:
                emg = u\'组名不能为空\'
                raise ServerError(emg)

            if group.name != name:
                asset_group_test = get_object(AssetGroup, name=name)
                if asset_group_test:
                    emg = u"该组名 %s 已存在" % name
                    raise ServerError(emg)

        except ServerError:
            pass

        else:
            group.asset_set.clear()
            db_update_group(id=group_id, name=name, comment=comment, asset_select=asset_select)
            smg = u"主机组 %s 添加成功" % name

        return HttpResponseRedirect(reverse(\'asset_group_list\'))

    return my_render(\'jasset/group_edit.html\', locals(), request)


@require_role(\'admin\')
def group_list(request):
    """
    list asset group
    列出资产组
    """
    header_title, path1, path2 = u\'查看资产组\', u\'资产管理\', u\'查看资产组\'
    keyword = request.GET.get(\'keyword\', \'\')
    asset_group_list = AssetGroup.objects.all()
    group_id = request.GET.get(\'id\')
    if group_id:
        asset_group_list = asset_group_list.filter(id=group_id)
    if keyword:
        asset_group_list = asset_group_list.filter(Q(name__contains=keyword) | Q(comment__contains=keyword))

    asset_group_list, p, asset_groups, page_range, current_page, show_first, show_end = pages(asset_group_list, request)
    return my_render(\'jasset/group_list.html\', locals(), request)


@require_role(\'admin\')
def group_del(request):
    """
    Group delete view
    删除主机组
    """
    group_ids = request.GET.get(\'id\', \'\')
    group_id_list = group_ids.split(\',\')

    for group_id in group_id_list:
        AssetGroup.objects.filter(id=group_id).delete()

    return HttpResponse(u\'删除成功\')


@require_role(\'admin\')
def asset_add(request):
    """
    Asset add view
    添加资产
    """
    header_title, path1, path2 = u\'添加资产\', u\'资产管理\', u\'添加资产\'
    asset_group_all = AssetGroup.objects.all()
    af = AssetForm()
    default_setting = get_object(Setting, name=\'default\')
    default_port = default_setting.field2 if default_setting else \'\'
    if request.method == \'POST\':
        af_post = AssetForm(request.POST)
        ip = request.POST.get(\'ip\', \'\')
        hostname = request.POST.get(\'hostname\', \'\')

        is_active = True if request.POST.get(\'is_active\') == \'1\' else False
        use_default_auth = request.POST.get(\'use_default_auth\', \'\')
        try:
            if Asset.objects.filter(hostname=unicode(hostname)):
                error = u\'该主机名 %s 已存在!\' % hostname
                raise ServerError(error)
            if len(hostname) > 54:
                error = u"主机名长度不能超过53位!"
                raise ServerError(error)
        except ServerError:
            pass
        else:
            if af_post.is_valid():
                asset_save = af_post.save(commit=False)
                if not use_default_auth:
                    password = request.POST.get(\'password\', \'\')
                    password_encode = CRYPTOR.encrypt(password)
                    asset_save.password = password_encode
                if not ip:
                    asset_save.ip = hostname
                asset_save.is_active = True if is_active else False
                asset_save.save()
                af_post.save_m2m()

                #add host to zabbix
                if IS_ZABBIX:
                    #全局开启
                    zbx_result = ZABBIX_API.create_host(hostname, ip, 5)
                    if zbx_result.get(\'result\'):
                        #同步zabbix成功
                        zbx_hostid = zbx_result[\'result\'][\'hostids\'][0]
                        #更新asset数据库
                        Asset.objects.filter(hostname=hostname).update(zbx_hostid=zbx_hostid)
                        msg = u\'主机 %s 添加成功,同步至zabbix成功,hostid: %s\' %(hostname,zbx_hostid)
                    else:
                        #同步zabbix失败
                        zbx_error = zbx_result.get(\'error\')[\'data\']
                        msg = u\'主机 %s 添加成功,同步至zabbix失败,失败原因:%s\' %(hostname,zbx_error)
                else:
                    msg = u\'主机 %s 添加成功\' % hostname
            else:
                esg = u\'主机 %s 添加失败\' % hostname

    return my_render(\'jasset/asset_add.html\', locals(), request)


@require_role(\'admin\')
def asset_add_batch(request):
    header_title, path1, path2 = u\'添加资产\', u\'资产管理\', u\'批量添加\'
    return my_render(\'jasset/asset_add_batch.html\', locals(), request)


@require_role(\'admin\')
def asset_del(request):
    """
    del a asset
    删除主机
    """
    asset_id = request.GET.get(\'id\', \'\')
    zbx_hostid = request.GET.get(\'zbx_hostid\', \'\')


    if asset_id:
        Asset.objects.filter(id=asset_id).delete()

    if zbx_hostid:
        #同步删除zabbix
        ZABBIX_API.delete_host(zbx_hostid)



    if request.method == \'POST\':
        asset_batch = request.GET.get(\'arg\', \'\')
        asset_id_all = str(request.POST.get(\'asset_id_all\', \'\'))

        if asset_batch:
            for asset_id in asset_id_all.split(\',\'):
                asset = get_object(Asset, id=asset_id)
                #同步删除zabbix
                batch_zbx_hostid = asset.zbx_hostid
                ZABBIX_API.delete_host(batch_zbx_hostid)
                asset.delete()

    return HttpResponse(u\'删除成功\')


@require_role(role=\'super\')
def asset_edit(request):
    """
    edit a asset
    修改主机
    """
    header_title, path1, path2 = u\'修改资产\', u\'资产管理\', u\'修改资产\'

    asset_id = request.GET.get(\'id\', \'\')
    zbx_hostid = request.GET.get(\'zbx_hostid\', \'\')
    username = request.user.username
    asset = get_object(Asset, id=asset_id)
    if asset:
        password_old = asset.password
    # asset_old = copy_model_instance(asset)
    af = AssetForm(instance=asset)
    if request.method == \'POST\':
        af_post = AssetForm(request.POST, instance=asset)
        ip = request.POST.get(\'ip\', \'\')
        hostname = request.POST.get(\'hostname\', \'\')
        password = request.POST.get(\'password\', \'\')
        is_active = True if request.POST.get(\'is_active\') == \'1\' else False
        use_default_auth = request.POST.get(\'use_default_auth\', \'\')
        try:
            asset_test = get_object(Asset, hostname=hostname)
            if asset_test and asset_id != unicode(asset_test.id):
                emg = u\'该主机名 %s 已存在!\' % hostname
                raise ServerError(emg)
            if len(hostname) > 54:
                emg = u\'主机名长度不能超过54位!\'
                raise ServerError(emg)
            else:
                if af_post.is_valid():
                    af_save = af_post.save(commit=False)
                    if use_default_auth:
                        af_save.username = \'\'
                        af_save.password = \'\'
                        # af_save.port = None
                    else:
                        if password:
                            password_encode = CRYPTOR.encrypt(password)
                            af_save.password = password_encode
                        else:
                            af_save.password = password_old
                    af_save.is_active = True if is_active else False
                    af_save.save()
                    af_post.save_m2m()
                    # asset_new = get_object(Asset, id=asset_id)
                    # asset_diff_one(asset_old, asset_new)
                    info = asset_diff(af_post.__dict__.get(\'initial\'), request.POST)
                    db_asset_alert(asset, username, info)

                    if zbx_hostid:
                        #同步修改zabbix
                        zbx_result = ZABBIX_API.update_host(zbx_hostid, hostname)
                        #print zbx_result

                    smg = u\'主机 %s 修改成功\' % ip
                else:
                    emg = u\'主机 %s 修改失败\' % ip
                    raise ServerError(emg)
        except ServerError as e:
            error = e.message
            return my_render(\'jasset/asset_edit.html\', locals(), request)
        return HttpResponseRedirect(reverse(\'asset_detail\')+\'?id=%s\' % asset_id)

    return my_render(\'jasset/asset_edit.html\', locals(), request)


@require_role(\'user\')
def asset_list(request):
    """
    asset list view
    """
    header_title, path1, path2 = u\'查看资产\', u\'资产管理\', u\'查看资产\'
    username = request.user.username
    user_perm = request.session[\'role_id\']
    idc_all = IDC.objects.filter()
    asset_group_all = AssetGroup.objects.all()
    asset_types = ASSET_TYPE
    asset_status = ASSET_STATUS
    idc_name = request.GET.get(\'idc\', \'\')
    group_name = request.GET.get(\'group\', \'\')
    asset_type = request.GET.get(\'asset_type\', \'\')
    status = request.GET.get(\'status\', \'\')
    keyword = request.GET.get(\'keyword\', \'\')
    export = request.GET.get("export", False)
    group_id = request.GET.get("group_id", \'\')
    idc_id = request.GET.get("idc_id", \'\')
    asset_id_all = request.GET.getlist("id", \'\')

    if group_id:
        group = get_object(AssetGroup, id=group_id)
        if group:
            asset_find = Asset.objects.filter(group=group)
    elif idc_id:
        idc = get_object(IDC, id=idc_id)
        if idc:
            asset_find = Asset.objects.filter(idc=idc)
    else:
        if user_perm != 0:
            asset_find = Asset.objects.all()
        else:
            asset_id_all = []
            user = get_object(User, username=username)
            asset_perm = get_group_user_perm(user) if user else {\'asset\': \'\'}
            user_asset_perm = asset_perm[\'asset\'].keys()
            for asset in user_asset_perm:
                asset_id_all.append(asset.id)
            asset_find = Asset.objects.filter(pk__in=asset_id_all)
            asset_group_all = list(asset_perm[\'asset_group\'])

    if idc_name:
        asset_find = asset_find.filter(idc__name__contains=idc_name)

    if group_name:
        asset_find = asset_find.filter(group__name__contains=group_name)

    if asset_type:
        asset_find = asset_find.filter(asset_type__contains=asset_type)

    if status:
        asset_find = asset_find.filter(status__contains=status)

    if keyword:
        asset_find = asset_find.filter(
            Q(hostname__contains=keyword) |
            Q(other_ip__contains=keyword) |
            Q(ip__contains=keyword) |
            Q(remote_ip__contains=keyword) |
            Q(comment__contains=keyword) |
            Q(username__contains=keyword) |
            Q(group__name__contains=keyword) |
            Q(cpu__contains=keyword) |
            Q(memory__contains=keyword) |
            Q(disk__contains=keyword) |
            Q(brand__contains=keyword) |
            Q(cabinet__contains=keyword) |
            Q(sn__contains=keyword) |
            Q(system_type__contains=keyword) |
            Q(system_version__contains=keyword))

    if export:
        if asset_id_all:
            asset_find = []
            for asset_id in asset_id_all:
                asset = get_object(Asset, id=asset_id)
                if asset:
                    asset_find.append(asset)
        s = write_excel(asset_find)
        if s[0]:
            file_name = s[1]
        smg = u\'excel文件已生成,请点击下载!\'
        return my_render(\'jasset/asset_excel_download.html\', locals(), request)
    assets_list, p, assets, page_range, current_page, show_first, show_end = pages(asset_find, request)
    if user_perm != 0:
        return my_render(\'jasset/asset_list.html\', locals(), request)
    else:
        return my_render(\'jasset/asset_cu_list.html\', locals(), request)


@require_role(\'admin\')
def asset_edit_batch(request):
    af = AssetForm()
    name = request.user.username
    asset_group_all = AssetGroup.objects.all()

    if request.method == \'POST\':
        env = request.POST.get(\'env\', \'\')
        idc_id = request.POST.get(\'idc\', \'\')
        port = request.POST.get(\'port\', \'\')
        use_default_auth = request.POST.get(\'use_default_auth\', \'\')
        username = request.POST.get(\'username\', \'\')
        password = request.POST.get(\'password\', \'\')
        group = request.POST.getlist(\'group\', [])
        cabinet = request.POST.get(\'cabinet\', \'\')
        comment = request.POST.get(\'comment\', \'\')
        asset_id_all = unicode(request.GET.get(\'asset_id_all\', \'\'))
        asset_id_all = asset_id_all.split(\',\')
        for asset_id in asset_id_all:
            alert_list = []
            asset = get_object(Asset, id=asset_id)
            if asset:
                if env:
                    if asset.env != env:
                        asset.env = env
                        alert_list.append([u\'运行环境\', asset.env, env])
                if idc_id:
                    idc = get_object(IDC, id=idc_id)
                    name_old = asset.idc.name if asset.idc else u\'\'
                    if idc and idc.name != name_old:
                        asset.idc = idc
                        alert_list.append([u\'机房\', name_old, idc.name])
                if port:
                    if unicode(asset.port) != port:
                        asset.port = port
                        alert_list.append([u\'端口号\', asset.port, port])

                if use_default_auth:
                    if use_default_auth == \'default\':
                        asset.use_default_auth = 1
                        asset.username = \'\'
                        asset.password = \'\'
                        alert_list.append([u\'使用默认管理账号\', asset.use_default_auth, u\'默认\'])
                    elif use_default_auth == \'user_passwd\':
                        asset.use_default_auth = 0
                        asset.username = username
                        password_encode = CRYPTOR.encrypt(password)
                        asset.password = password_encode
                        alert_list.append([u\'使用默认管理账号\', asset.use_default_auth, username])
                if group:
                    group_new, group_old, group_new_name, group_old_name = [], asset.group.all(), [], []
                    for group_id in group:
                        g = get_object(AssetGroup, id=group_id)
                        if g:
                            group_new.append(g)
                    if not set(group_new) < set(group_old):
                        group_instance = list(set(group_new) | set(group_old))
                        for g in group_instance:
                            group_new_name.append(g.name)
                        for g in group_old:
                            group_old_name.append(g.name)
                        asset.group = group_instance
                        alert_list.append([u\'主机组\', \',\'.join(group_old_name), \',\'.join(group_new_name)])
                if cabinet:
                    if asset.cabinet != cabinet:
                        asset.cabinet = cabinet
                        alert_list.append([u\'机柜号\', asset.cabinet, cabinet])
                if comment:
                    if asset.comment != comment:
                        asset.comment = comment
                        alert_list.append([u\'备注\', asset.comment, comment])
                asset.save()

            if alert_list:
                recode_name = unicode(name) + \' - \' + u\'批量\'
                AssetRecord.objects.create(asset=asset, username=recode_name, content=alert_list)
        return my_render(\'jasset/asset_update_status.html\', locals(), request)

    return my_render(\'jasset/asset_edit_batch.html\', locals(), request)


@require_role(\'admin\')
def asset_detail(request):
    """
    Asset detail view
    """
    header_title, path1, path2 = u\'主机详细信息\', u\'资产管理\', u\'主机详情\'
    asset_id = request.GET.get(\'id\', \'\')
    asset = get_object(Asset, id=asset_id)
    perm_info = get_group_asset_perm(asset)
    log = Log.objects.filter(host=asset.hostname)
    if perm_info:
        user_perm = []
        for perm, value in perm_info.items():
            if perm == \'user\':
                for user, role_dic in value.items():
                    user_perm.append([user, role_dic.get(\'role\', \'\')])
            elif perm == \'user_group\' or perm == \'rule\':
                user_group_perm = value
    print perm_info

    asset_record = AssetRecord.objects.filter(asset=asset).order_by(\'-alert_time\')

    return my_render(\'jasset/asset_detail.html\', locals(), request)


@require_role(\'admin\')
def asset_update(request):
    """
    Asset update host info via ansible view
    """
    asset_id = request.GET.get(\'id\', \'\')
    asset = get_object(Asset, id=asset_id)
    name = request.user.username
    if not asset:
        return HttpResponseRedirect(reverse(\'asset_detail\')+\'?id=%s\' % asset_id)
    else:
        asset_ansible_update([asset], name)
    return HttpResponseRedirect(reverse(\'asset_detail\')+\'?id=%s\' % asset_id)


@require_role(\'admin\')
def asset_update_batch(request):
    if request.method == \'POST\':
        arg = request.GET.get(\'arg\', \'\')
        name = unicode(request.user.username) + \' - \' + u\'自动更新\'
        if arg == \'all\':
            asset_list = Asset.objects.all()
        else:
            asset_list = []
            asset_id_all = unicode(request.POST.get(\'asset_id_all\', \'\'))
            asset_id_all = asset_id_all.split(\',\')
            for asset_id in asset_id_all:
                asset = get_object(Asset, id=asset_id)
                if asset:
                    asset_list.append(asset)
        asset_ansible_update(asset_list, name)
        return HttpResponse(u\'批量更新成功!\')
    return HttpResponse(u\'批量更新成功!\')



@require_role(\'admin\')
def zabbix_update_batch(request):
    if request.method == \'POST\':
        arg = request.GET.get(\'arg\', \'\')
        name = unicode(request.user.username) + \' - \' + u\'自动更新\'
        if arg == \'all\':
            asset_list = Asset.objects.all()
        else:
            asset_id_all = unicode(request.POST.get(\'asset_id_all\', \'\'))
            asset_id_all = asset_id_all.split(\',\')
            for asset_id in asset_id_all:
                asset = get_object(Asset, id=asset_id)
                if not asset.zbx_hostid:
                    #同步zabbix
                    hostname = asset.hostname
                    ip = asset.ip
                    zbx_result =  ZABBIX_API.create_host(hostname,ip,5)
                    if zbx_result.get(\'result\'):
                        add_zbx_hostid = zbx_result[\'result\'][\'hostids\'][0]
                        asset.zbx_hostid = add_zbx_hostid
                        asset.save()
        return HttpResponse(u\'批量更新成功!\')
    return HttpResponse(u\'批量更新成功!\')


@require_role(\'admin\')
def idc_add(request):
    """
    IDC add view
    """
    header_title, path1, path2 = u\'添加IDC\', u\'资产管理\', u\'添加IDC\'
    if request.method == \'POST\':
        idc_form = IdcForm(request.POST)
        if idc_form.is_valid():
            idc_name = idc_form.cleaned_data[\'name\']

            if IDC.objects.filter(name=idc_name):
                emg = u\'添加失败, 此IDC %s 已存在!\' % idc_name
                return my_render(\'jasset/idc_add.html\', locals(), request)
            else:
                idc_form.save()
                smg = u\'IDC: %s添加成功\' % idc_name
            return HttpResponseRedirect(reverse(\'idc_list\'))
    else:
        idc_form = IdcForm()
    return my_render(\'jasset/idc_add.html\', locals(), request)


@require_role(\'admin\')
def idc_list(request):
    """
    IDC list view
    """
    header_title, path1, path2 = u\'查看IDC\', u\'资产管理\', u\'查看IDC\'
    posts = IDC.objects.all()
    keyword = request.GET.get(\'keyword\', \'\')
    if keyword:
        posts = IDC.objects.filter(Q(name__contains=keyword) | Q(comment__contains=keyword))
    else:
        posts = IDC.objects.exclude(name=\'ALL\').order_by(\'id\')
    contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
    return my_render(\'jasset/idc_list.html\', locals(), request)


@require_role(\'admin\')
def idc_edit(request):
    """
    IDC edit view
    """
    header_title, path1, path2 = u\'编辑IDC\', u\'资产管理\', u\'编辑IDC\'
    idc_id = request.GET.get(\'id\', \'\')
    idc = get_object(IDC, id=idc_id)
    if request.method == \'POST\':
        idc_form = IdcForm(request.POST, instance=idc)
        if idc_form.is_valid():
            idc_form.save()
            return HttpResponseRedirect(reverse(\'idc_list\'))
    else:
        idc_form = IdcForm(instance=idc)
        return my_render(\'jasset/idc_edit.html\', locals(), request)


@require_role(\'admin\')
def idc_del(request):
    """
    IDC delete view
    """
    idc_ids = request.GET.get(\'id\', \'\')
    idc_id_list = idc_ids.split(\',\')

    for idc_id in idc_id_list:
        IDC.objects.filter(id=idc_id).delete()

    return HttpResponseRedirect(reverse(\'idc_list\'))


@require_role(\'admin\')
def asset_upload(request):
    """
    Upload asset excel file view
    """
    if request.method == \'POST\':
        excel_file = request.FILES.get(\'file_name\', \'\')
        ret = excel_to_db(excel_file)
        if ret:
            smg = u\'批量添加成功\'
        else:
            emg = u\'批量添加失败,请检查格式.\'
    return my_render(\'jasset/asset_add_batch.html\', locals(), request)

 

jumpserver.conf

 key = 941enj9neshd1wes
  ip = 0.0.0.0
  port = 8000
 -log = debug
 +log = DEBUG
  
  [db]
  engine = mysql
  host = 127.0.0.1
  port = 3306
 -user = jumpserver
 -password = mysql234
 +user = root
 +password = xxx
  database = jumpserver
  
  [mail]
 @@ -24,3 +24,9 @@ email_use_ssl = False
  
  [connect]
  nav_sort_by = ip
 
 +[zbx]
 +is_zbx = True
 +zbx_url = http://127.0.0.1:8888/zabbix/api_jsonrpc.php
 +zbx_user = Admin
 +zbx_pwd = zabbix

 

[base]
url = http://127.0.0.1
key = 941enj9neshd1wes
ip = 0.0.0.0
port = 8000
log = DEBUG

[db]
engine = mysql
host = 127.0.0.1
port = 3306
user = root
password = xxx
database = jumpserver

[mail]
mail_enable = 1
email_host = 
email_port = 587
email_host_user = 
email_host_password = 
email_use_tls = False
email_use_ssl = False

[connect]
nav_sort_by = ip

[zbx]
is_zbx = True
zbx_url = http://127.0.0.1:8888/zabbix/api_jsonrpc.php
zbx_user = Admin
zbx_pwd = zabbix

 

 

jumpserver/api.py

import uuid
  import json
  import logging
 +import urllib2
  
  from settings import *
  from django.core.paginator import Paginator, EmptyPage, InvalidPage
 @@ -506,5 +507,333 @@ def get_mac_address():
      return mac
  
  
 +class zbx_api(object):
 +
 +    def __init__(self, url, username, password):
 +        self.url = url
 +        self.username = username
 +        self.password = password
 +
 +    def requestJson(self, url, values):
 +        \'\'\'
 +        请求方法,错误返回dict:{"request_error" : "some errors."}
 +        \'\'\'
 +        data = json.dumps(values)
 +        try:
 +            req = urllib2.Request(url, data, {\'Content-Type\' : \'application/json-rpc\'})
 +            response = urllib2.urlopen(req, data=None, timeout=5)
 +            data_get = response.read()
 +            out_put = json.loads(data_get)
 +            return out_put
 +        except Exception as e:
 +            \'\'\'
 +            请求接口出错
 +            \'\'\'
 +            return {"request_error" : "request zabbix api error: %s" %e}
 +
 +    def __get_token(self):
 +        \'\'\'
 +        返回结果
 +        {
 +            "jsonrpc": "2.0",
 +            "result": "0424bd59b807674191e7d77572075f33",
 +            "id": 1
 +        }
 +
 +        错误返回
 +        {
 +            "request_error" : "some errors."
 +        }
 +        \'\'\'
 +        values = {
 +            "jsonrpc" : "2.0",
 +            "method" : "user.login",
 +            "params" : {
 +                "user" : self.username,
 +                "password" : self.password
 +            },
 +            "id" : 1
 +        }
 +        idvalue = self.requestJson(self.url, values)
 +        return idvalue
 +
 +
 +    def create_host(self, hostname, ip, groupid):
 +        \'\'\'
 +        创建成功
 +        {
 +            "jsonrpc": "2.0",
 +            "result": {
 +                "hostids": [
 +                    "107819"
 +                ]
 +            },
 +            "id": 1
 +        }
 +
 +        创建失败
 +        {
 +          "jsonrpc": "2.0",
 +          "error": {
 +            "code": -32602,
 +            "message": "Invalid params.",
 +            "data": "Host with the same name \\"test\\" already exists."
 +          },
 +          "id": 1
 +        }
 +        \'\'\'
 +        token = self.__get_token()
 +        if not token.get("request_error"):
 +            values = {
 +                "jsonrpc": "2.0",
 +                "method": "host.create",
 +                "params": {
 +                    "host": hostname,
 +                    "interfaces": [
 +                        {
 +                            "type": 1,
 +                            "main": 1,
 +                            "useip": 1,
 +                            "ip": ip,
 +                            "dns": "",
 +                            "port": "10050"
 +                        }
 +                    ],
 +                    "groups": [
 +                        {
 +                            "groupid": groupid
 +                        }
 +                    ],
 +                },
 +                "auth": token["result"],
 +                "id": 5
 +            }
 +            idvalue = self.requestJson(self.url, values)
 +            return idvalue
 +
 +    def delete_host(self, *hostids):
 +        \'\'\'
 +        成功
 +        {
 +            "jsonrpc": "2.0",
 +            "result": {
 +                "hostids": [
 +                    "13",
 +                    "32"
 +                ]
 +            },
 +            "id": 1
 +        }
 +
 +        失败
 +        {
 +          "jsonrpc": "2.0",
 +          "error": {
 +            "code": -32500,
 +            "message": "Application error.",
 +            "data": "No permissions to referred object or it does not exist!"
 +          },
 +          "id": 1
 +        }
 +        \'\'\'
 +        token = self.__get_token()
 +        if not token.get("request_error"):
 +            \'\'\'
 +            获取token成功
 +            \'\'\'
 +            values = {
 +                "jsonrpc" : "2.0",
 +                "method" : "host.delete",
 +                "params" : list(hostids),
 +                "auth" : token["result"],
 +                "id" : 7
 +            }
 +            idvalue = self.requestJson(self.url, values)
 +            return idvalue
 +
 +
 +    def update_host(self, hostid, hostname):
 +        \'\'\'
 +        修改zabbix name
 +
 +        成功
 +        {
 +          "jsonrpc": "2.0",
 +          "result": {
 +            "hostids": [
 +              "10151"
 +            ]
 +          },
 +          "id": 1
 +        }
 +
 +        失败
 +        {
 +          "jsonrpc": "2.0",
 +          "error": {
 +            "code": -32602,
 +            "message": "Invalid params.",
 +            "data": "No permissions to referred object or it does not exist!"
 +          },
 +          "id": 1
 +        }
 +        \'\'\'
 +
 +        token = self.__get_token()
 +        if not token.get("request_error"):
 +            \'\'\'
 +            获取token成功
 +            \'\'\'
 +            values = {
 +                "jsonrpc" : "2.0",
 +                "method" : "host.update",
 +                "params" : {
 +                    "hostid" : hostid,
 +                    "host" : hostname
 +                },
 +                "auth" : token["result"],
 +                "id" : 8
 +            }
 +            idvalue = self.requestJson(self.url, values)
 +            return idvalue
 +
 +    def create_hostgroup(self, hostgroup_name):
 +        \'\'\'
 +        创建成功
 +        {
 +            "jsonrpc": "2.0",
 +            "result": {
 +                "groupids": [
 +                    "107819"
 +                ]
 +            },
 +            "id": 1
 +        }
 +
 +
 +        创建失败
 +        {
 +            "jsonrpc": "2.0",
 +            "error": {
 +                "code" : -32602,
 +                "message" : "Invalid params.",
 +                "data" : "Host group \\"Linux servers\\" already exists."
 +            },
 +            "id": 1
 +        }
 +
 +        \'\'\'
 +        token = self.__get_token()
 +        if not token.get("request_error"):
 +            \'\'\'
 +            获取token成功
 +            \'\'\'
 +            values = {
 +                "jsonrpc" : "2.0",
 +                "method" : "hostgroup.create",
 +                "params" : {
 +                    "name" : hostgroup_name
 +                },
 +                "auth" : token["result"],
 +                "id" : 2
 +            }
 +            idvalue = self.requestJson(self.url, values)
 +            return idvalue
 +        #else:
 +        #    print "get token error: %s" %token.get("request_error")
 +
 +
 +    def delete_hostgroup(self, *args):
 +
 +        \'\'\'
 +        请求成功
 +                {
 +            "jsonrpc": "2.0",
 +            "result": {
 +                "groupids": [
 +                    "107824",
 +                    "107825"
 +                ]
 +            },
 +            "id": 1
 +        }
 +
 +        请求失败
 +        {
 +          "jsonrpc": "2.0",
 +          "error": {
 +            "code": -32500,
 +            "message": "Application error.",
 +            "data": "No permissions to referred object or it does not exist!"
 +          },
 +          "id": 1
 +        }
 +        \'\'\'
 +
 +
 +        token = self.__get_token()
 +        if not token.get("request_error"):
 +            values = {
 +                "jsonrpc" : "2.0",
 +                "method" : "hostgroup.delete",
 +                "params" : list(args),
 +                "auth" : token["result"],
 +                "id" : 3
 +            }
 +            idvalue = self.requestJson(self.url, values)
 +            return  idvalue
 +
 +
 +
 +
 +    def hostgroup_get(self, *args):
 +        \'\'\'
 +        结果不为空:
 +        {
 +            "jsonrpc": "2.0",
 +            "result": [
 +                {
 +                    "groupid": "2",
 +                    "name": "Linux servers",
 +                    "internal": "0"
 +                },
 +                {
 +                    "groupid": "4",
 +                    "name": "Zabbix servers",
 +                    "internal": "0"
 +                }
 +            ],
 +            "id": 1
 +        }
 +
 +        结果为空:
 +        {
 +          "jsonrpc": "2.0",
 +          "result": [],
 +          "id": 1
 +            }
 +        \'\'\'
 +
 +        token = self.__get_token()
 +        if not token.get("request_error"):
 +            values = {
 +                "jsonrpc" : "2.0",
 +                "method" : "hostgroup.get",
 +                "params" : {
 +                    "output" : "extend",
 +                    "filter" : {
 +                        "name" : list(*args)
 +                    }
 +                },
 +                "auth" : token["result"],
 +                "id" : 4
 +            }
 +            idvalue = self.requestJson(self.url, values)
 +            return idvalue

  CRYPTOR = PyCrypt(KEY)
  logger = set_log(LOG_LEVEL)
 
 +ZABBIX_API = zbx_api(ZBX_URL, ZBX_USER, ZBX_PWD)

 

# coding: utf-8

import os, sys, time, re
from Crypto.Cipher import AES
import crypt
import pwd
from binascii import b2a_hex, a2b_hex
import hashlib
import datetime
import random
import subprocess
import uuid
import json
import logging
import urllib2

from settings import *
from django.core.paginator import Paginator, EmptyPage, InvalidPage
from django.http import HttpResponse, Http404
from django.template import RequestContext
from juser.models import User, UserGroup
from jlog.models import Log, TtyLog
from jasset.models import Asset, AssetGroup
from jperm.models import PermRule, PermRole
from jumpserver.models import Setting
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.core.mail import send_mail
from django.core.urlresolvers import reverse


def set_log(level, filename=\'jumpserver.log\'):
    """
    return a log file object
    根据提示设置log打印
    """
    log_file = os.path.join(LOG_DIR, filename)
    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,
                       \'critical\': logging.CRITICAL}
    logger_f = logging.getLogger(\'jumpserver\')
    logger_f.setLevel(logging.DEBUG)
    fh = logging.FileHandler(log_file)
    fh.setLevel(log_level_total.get(level, logging.DEBUG))
    formatter = logging.Formatter(\'%(asctime)s - %(filename)s - %(levelname)s - %(message)s\')
    fh.setFormatter(formatter)
    logger_f.addHandler(fh)
    return logger_f


def list_drop_str(a_list, a_str):
    for i in a_list:
        if i == a_str:
            a_list.remove(a_str)
    return a_list


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[\'username\'] = default.field1
            try:
                info[\'password\'] = CRYPTOR.decrypt(default.field3)
            except ServerError:
                pass
            if os.path.isfile(default.field4):
                info[\'ssh_key\'] = default.field4
    else:
        info[\'username\'] = asset.username
        info[\'password\'] = CRYPTOR.decrypt(asset.password)
    try:
        info[\'port\'] = int(asset.port)
    except TypeError:
        info[\'port\'] = int(default.field2)

    return info


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())
        logger.debug(u"创建新的系统用户key %s, Owner: %s" % (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):
    """
    page
    分页,返回本次分页的最小页数到最大页数列表
    """
    min_page = current - 2 if current - 4 > 0 else 1
    max_page = min_page + 4 if min_page + 4 < total else total

    return range(min_page, max_page + 1)


def pages(post_objects, request):
    """
    page public function , return page\'s object tuple
    分页公用函数,返回分页的对象元组
    """
    paginator = Paginator(post_objects, 20)
    try:
        current_page = int(request.GET.get(\'page\', \'1\'))
    except ValueError:
        current_page = 1

    page_range = page_list_return(len(paginator.page_range), current_page)

    try:
        page_objects = paginator.page(current_page)
    except (EmptyPage, InvalidPage):
        page_objects = paginator.page(paginator.num_pages)

    if current_page >= 5:
        show_first = 1
    else:
        show_first = 0

    if current_page <= (len(paginator.page_range) - 3):
        show_end = 1
    else:
        show_end = 0

    # 所有对象, 分页器, 本页对象, 所有页码, 本页页码,是否显示第一页,是否显示最后一页
    return post_objects, paginator, page_objects, page_range, current_page, show_first, show_end


class PyCrypt(object):
    """
    This class used to encrypt and decrypt password.
    加密类
    """

    def __init__(self, key):
        self.key = key
        self.mode = AES.MODE_CBC

    @staticmethod
    def gen_rand_pass(length=16, especial=False):
        """
        random password
        随机生成密码
        """
        salt_key = \'1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_\'
        symbol = \'!@$%^&*()_\'
        salt_list = []
        if especial:
            for i in range(length - 4):
                salt_list.append(random.choice(salt_key))
            for i in range(4):
                salt_list.append(random.choice(symbol))
        else:
            for i in range(length):
                salt_list.append(random.choice(salt_key))
        salt = \'\'.join(salt_list)
        return salt

    @staticmethod
    def md5_crypt(string):
        """
        md5 encrypt method
        md5非对称加密方法
        """
        return hashlib.new("md5", string).hexdigest()

    @staticmethod
    def gen_sha512(salt, password):
        """
        generate sha512 format password
        生成sha512加密密码
        """
        return crypt.crypt(password, \'$6$%s$\' % salt)

    def encrypt(self, passwd=None, length=32):
        """
        encrypt gen password
        对称加密之加密生成密码
        """
        if not passwd:
            passwd = self.gen_rand_pass()

        cryptor = AES.new(self.key, self.mode, b\'8122ca7d906ad5e1\')
        try:
            count = len(passwd)
        except TypeError:
            raise ServerError(\'Encrypt password error, TYpe error.\')

        add = (length - (count % length))
        passwd += (\'\\0\' * add)
        cipher_text = cryptor.encrypt(passwd)
        return b2a_hex(cipher_text)

    def decrypt(self, text):
        """
        decrypt pass base the same key
        对称加密之解密,同一个加密随机数
        """
        cryptor = AES.new(self.key, self.mode, b\'8122ca7d906ad5e1\')
        try:
            plain_text = cryptor.decrypt(a2b_hex(text))
        except TypeError:
            raise ServerError(\'Decrypt password error, TYpe error.\')
        return plain_text.rstrip(\'\\0\')


class ServerError(Exception):
    """
    self define exception
    自定义异常
    """
    pass


def get_object(model, **kwargs):
    """
    use this function for query
    使用改封装函数查询数据库
    """
    for value in kwargs.values():
        if not value:
            return None

    the_object = model.objects.filter(**kwargs)
    if len(the_object) == 1:
        the_object = the_object[0]
    else:
        the_object = None
    return the_object


def require_role(role=\'user\'):
    """
    decorator for require user role in ["super", "admin", "user"]
    要求用户是某种角色 ["super", "admin", "user"]的装饰器
    """

    def _deco(func):
        def __deco(request, *args, **kwargs):
            request.session[\'pre_url\'] = request.path
            if not request.user.is_authenticated():
                return HttpResponseRedirect(reverse(\'login\'))
            if role == \'admin\':
                # if request.session.get(\'role_id\', 0) < 1:
                if request.user.role == \'CU\':
                    return HttpResponseRedirect(reverse(\'index\'))
            elif role == \'super\':
                # if request.session.get(\'role_id\', 0) < 2:
                if request.user.role in [\'CU\', \'GA\']:
                    return HttpResponseRedirect(reverse(\'index\'))
            return func(request, *args, **kwargs)

        return __deco

    return _deco


def is_role_request(request, role=\'user\'):
    """
    require this request of user is right
    要求请求角色正确
    """
    role_all = {\'user\': \'CU\', \'admin\': \'GA\', \'super\': \'SU\'}
    if request.user.role == role_all.get(role, \'CU\'):
        return True
    else:
        return False


def get_session_user_dept(request):
    """
    get department of the user in session
    获取session中用户的部门
    """
    # user_id = request.session.get(\'user_id\', 0)
    # print \'#\' * 20
    # print user_id
    # user = User.objects.filter(id=user_id)
    # if user:
    #     user = user[0]
    #     return user, None
    return request.user, None


@require_role
def get_session_user_info(request):
    """
    get the user info of the user in session, for example id, username etc.
    获取用户的信息
    """
    # user_id = request.session.get(\'user_id\', 0)
    # user = get_object(User, id=user_id)
    # if user:
    #     return [user.id, user.username, user]
    return [request.user.id, request.user.username, request.user]


def get_user_dept(request):
    """
    get the user dept id
    获取用户的部门id
    """
    user_id = request.user.id
    if user_id:
        user_dept = User.objects.get(id=user_id).dept
        return user_dept.id


def api_user(request):
    hosts = Log.objects.filter(is_finished=0).count()
    users = Log.objects.filter(is_finished=0).values(\'user\').distinct().count()
    ret = {\'users\': users, \'hosts\': hosts}
    json_data = json.dumps(ret)
    return HttpResponse(json_data)


def view_splitter(request, su=None, adm=None):
    """
    for different user use different view
    视图分页器
    """
    if is_role_request(request, \'super\'):
        return su(request)
    elif is_role_request(request, \'admin\'):
        return adm(request)
    else:
        return HttpResponseRedirect(reverse(\'login\'))


def validate(request, user_group=None, user=None, asset_group=None, asset=None, edept=None):
    """
    validate the user request
    判定用户请求是否合法
    """
    dept = get_session_user_dept(request)[1]
    if edept:
        if dept.id != int(edept[0]):
            return False

    if user_group:
        dept_user_groups = dept.usergroup_set.all()
        user_group_ids = []
        for group in dept_user_groups:
            user_group_ids.append(str(group.id))

        if not set(user_group).issubset(set(user_group_ids)):
            return False

    if user:
        dept_users = dept.user_set.all()
        user_ids = []
        for dept_user in dept_users:
            user_ids.append(str(dept_user.id))

        if not set(user).issubset(set(user_ids)):
            return False

    if asset_group:
        dept_asset_groups = dept.bisgroup_set.all()
        asset_group_ids = []
        for group in dept_asset_groups:
            asset_group_ids.append(str(group.id))

        if not set(asset_group).issubset(set(asset_group_ids)):
            return False

    if asset:
        dept_assets = dept.asset_set.all()
        asset_ids = []
        for dept_asset in dept_assets:
            asset_ids.append(str(dept_asset.id))

        if not set(asset).issubset(set(asset_ids)):
            return False

    return True


def verify(request, user_group=None, user=None, asset_group=None, asset=None, edept=None):
    dept = get_session_user_dept(request)[1]
    if edept:
        if dept.id != int(edept[0]):
            return False

    if user_group:
        dept_user_groups = dept.usergroup_set.all()
        user_groups = []
        for user_group_id in user_group:
            user_groups.extend(UserGroup.objects.filter(id=user_group_id))
        if not set(user_groups).issubset(set(dept_user_groups)):
            return False

    if user:
        dept_users = dept.user_set.all()
        users = []
        for user_id in user:
            users.extend(User.objects.filter(id=user_id))

        if not set(users).issubset(set(dept_users)):
            return False

    if asset_group:
        dept_asset_groups = dept.bisgroup_set.all()
        asset_group_ids = []
        for group in dept_asset_groups:
            asset_group_ids.append(str(group.id))

        if not set(asset_group).issubset(set(asset_group_ids)):
            return False

    if asset:
        dept_assets = dept.asset_set.all()
        asset_ids = []
        for a in dept_assets:
            asset_ids.append(str(a.id))
        print asset, asset_ids
        if not set(asset).issubset(set(asset_ids)):
            return False

    return True


def bash(cmd):
    """
    run a bash shell command
    执行bash命令
    """
    return subprocess.call(cmd, shell=True)


def mkdir(dir_name, username=\'\', mode=755):
    """
    insure the dir exist and mode ok
    目录存在,如果不存在就建立,并且权限正确
    """
    cmd = \'[ ! -d %s ] && mkdir -p %s && chmod %s %s\' % (dir_name, dir_name, mode, dir_name)
    bash(cmd)
    if username:
        chown(dir_name, username)


def http_success(request, msg):
    return render_to_response(\'success.html\', locals())


def http_error(request, emg):
    message = emg
    return render_to_response(\'error.html\', locals())


def my_render(template, data, request):
    return render_to_response(template, data, context_instance=RequestContext(request))


def get_tmp_dir():
    seed = uuid.uuid4().hex[:4]
    dir_name = os.path.join(\'/tmp\', \'%s-%s\' % (datetime.datetime.now().strftime(\'%Y%m%d-%H%M%S\'), seed))
    mkdir(dir_name, mode=777)
    return dir_name


def defend_attack(func):
    def _deco(request, *args, **kwargs):
        if int(request.session.get(\'visit\', 1)) > 10:
            logger.debug(\'请求次数: %s\' % request.session.get(\'visit\', 1))
            return HttpResponse(\'Forbidden\', status=403)
        request.session[\'visit\'] = request.session.get(\'visit\', 1) + 1
        request.session.set_expiry(300)
        return func(request, *args, **kwargs)
    return _deco


def get_mac_address():
    node = uuid.getnode()
    mac = uuid.UUID(int=node).hex[-12:]
    return mac


class zbx_api(object):

    def __init__(self, url, username, password):
        self.url = url
        self.username = username
        self.password = password

    def requestJson(self, url, values):
        \'\'\'
        请求方法,错误返回dict:{"request_error" : "some errors."}
        \'\'\'
        data = json.dumps(values)
        try:
            req = urllib2.Request(url, data, {\'Content-Type\' : \'application/json-rpc\'})
            response = urllib2.urlopen(req, data=None, timeout=5)
            data_get = response.read()
            out_put = json.loads(data_get)
            return out_put
        except Exception as e:
            \'\'\'
            请求接口出错
            \'\'\'
            return {"request_error" : "request zabbix api error: %s" %e}

    def __get_token(self):
        \'\'\'
        返回结果
        {
            "jsonrpc": "2.0",
            "result": "0424bd59b807674191e7d77572075f33",
            "id": 1
        }
        错误返回
        {
            "request_error" : "some errors."
        }
        \'\'\'
        values = {
            "jsonrpc" : "2.0",
            "metho

以上是关于二次开发jumpserver——整合jumpserver与zabbix推送主机功能的主要内容,如果未能解决你的问题,请参考以下文章

docker-compose安装jumpserver

Jumpserver 深度集成OpenLdap的二次开发

Jumpserver 深度集成OpenLdap的二次开发

新增站内信功能,支持通过VS Code直连Linux-SSH协议资产,JumpServer堡垒机v2.11.0发布

【jumpserver】JumpServer 文档

Jumpserver