mirror of https://github.com/jumpserver/jumpserver
404 lines
14 KiB
Python
404 lines
14 KiB
Python
# coding: utf-8
|
|
from __future__ import division
|
|
import xlrd
|
|
import xlsxwriter
|
|
from django.db.models import AutoField
|
|
from jumpserver.api import *
|
|
from jasset.models import ASSET_STATUS, ASSET_TYPE, ASSET_ENV, IDC, AssetRecord
|
|
from jperm.ansible_api import MyRunner
|
|
from jperm.perm_api import gen_resource
|
|
from jumpserver.templatetags.mytags import get_disk_info
|
|
|
|
import traceback
|
|
|
|
|
|
def group_add_asset(group, asset_id=None, asset_ip=None):
|
|
"""
|
|
资产组添加资产
|
|
Asset group add a asset
|
|
"""
|
|
if asset_id:
|
|
asset = get_object(Asset, id=asset_id)
|
|
else:
|
|
asset = get_object(Asset, ip=asset_ip)
|
|
|
|
if asset:
|
|
group.asset_set.add(asset)
|
|
|
|
|
|
def db_add_group(**kwargs):
|
|
"""
|
|
add a asset group in database
|
|
数据库中添加资产
|
|
"""
|
|
name = kwargs.get('name')
|
|
group = get_object(AssetGroup, name=name)
|
|
asset_id_list = kwargs.pop('asset_select')
|
|
|
|
if not group:
|
|
group = AssetGroup(**kwargs)
|
|
group.save()
|
|
for asset_id in asset_id_list:
|
|
group_add_asset(group, asset_id)
|
|
|
|
|
|
def db_update_group(**kwargs):
|
|
"""
|
|
add a asset group in database
|
|
数据库中更新资产
|
|
"""
|
|
group_id = kwargs.pop('id')
|
|
asset_id_list = kwargs.pop('asset_select')
|
|
group = get_object(AssetGroup, id=group_id)
|
|
|
|
for asset_id in asset_id_list:
|
|
group_add_asset(group, asset_id)
|
|
|
|
AssetGroup.objects.filter(id=group_id).update(**kwargs)
|
|
|
|
|
|
def db_asset_add(**kwargs):
|
|
"""
|
|
add asset to db
|
|
添加主机时数据库操作函数
|
|
"""
|
|
group_id_list = kwargs.pop('groups')
|
|
asset = Asset(**kwargs)
|
|
asset.save()
|
|
|
|
group_select = []
|
|
for group_id in group_id_list:
|
|
group = AssetGroup.objects.filter(id=group_id)
|
|
group_select.extend(group)
|
|
asset.group = group_select
|
|
|
|
|
|
def db_asset_update(**kwargs):
|
|
""" 修改主机时数据库操作函数 """
|
|
asset_id = kwargs.pop('id')
|
|
Asset.objects.filter(id=asset_id).update(**kwargs)
|
|
|
|
|
|
def sort_ip_list(ip_list):
|
|
""" ip地址排序 """
|
|
ip_list.sort(key=lambda s: map(int, s.split('.')))
|
|
return ip_list
|
|
|
|
|
|
def get_tuple_name(asset_tuple, value):
|
|
""""""
|
|
for t in asset_tuple:
|
|
if t[0] == value:
|
|
return t[1]
|
|
|
|
return ''
|
|
|
|
|
|
def get_tuple_diff(asset_tuple, field_name, value):
|
|
""""""
|
|
old_name = get_tuple_name(asset_tuple, int(value[0])) if value[0] else u''
|
|
new_name = get_tuple_name(asset_tuple, int(value[1])) if value[1] else u''
|
|
alert_info = [field_name, old_name, new_name]
|
|
return alert_info
|
|
|
|
|
|
def asset_diff(before, after):
|
|
"""
|
|
asset change before and after
|
|
"""
|
|
alter_dic = {}
|
|
before_dic, after_dic = before, dict(after.iterlists())
|
|
for k, v in before_dic.items():
|
|
after_dic_values = after_dic.get(k, [])
|
|
if k == 'group':
|
|
after_dic_value = after_dic_values if len(after_dic_values) > 0 else u''
|
|
uv = v if v is not None else u''
|
|
else:
|
|
after_dic_value = after_dic_values[0] if len(after_dic_values) > 0 else u''
|
|
uv = unicode(v) if v is not None else u''
|
|
if uv != after_dic_value:
|
|
alter_dic.update({k: [uv, after_dic_value]})
|
|
|
|
for k, v in alter_dic.items():
|
|
if v == [None, u'']:
|
|
alter_dic.pop(k)
|
|
|
|
return alter_dic
|
|
|
|
|
|
def asset_diff_one(before, after):
|
|
print before.__dict__, after.__dict__
|
|
fields = Asset._meta.get_all_field_names()
|
|
for field in fields:
|
|
print before.field, after.field
|
|
|
|
|
|
def db_asset_alert(asset, username, alert_dic):
|
|
"""
|
|
asset alert info to db
|
|
"""
|
|
alert_list = []
|
|
asset_tuple_dic = {'status': ASSET_STATUS, 'env': ASSET_ENV, 'asset_type': ASSET_TYPE}
|
|
for field, value in alert_dic.iteritems():
|
|
field_name = Asset._meta.get_field_by_name(field)[0].verbose_name
|
|
if field == 'idc':
|
|
old = IDC.objects.filter(id=value[0]) if value[0] else u''
|
|
new = IDC.objects.filter(id=value[1]) if value[1] else u''
|
|
old_name = old[0].name if old else u''
|
|
new_name = new[0].name if new else u''
|
|
alert_info = [field_name, old_name, new_name]
|
|
|
|
elif field in ['status', 'env', 'asset_type']:
|
|
alert_info = get_tuple_diff(asset_tuple_dic.get(field), field_name, value)
|
|
|
|
elif field == 'group':
|
|
old, new = [], []
|
|
for group_id in value[0]:
|
|
group_name = AssetGroup.objects.get(id=int(group_id)).name
|
|
old.append(group_name)
|
|
for group_id in value[1]:
|
|
group_name = AssetGroup.objects.get(id=int(group_id)).name
|
|
new.append(group_name)
|
|
if sorted(old) == sorted(new):
|
|
continue
|
|
else:
|
|
alert_info = [field_name, ','.join(old), ','.join(new)]
|
|
|
|
elif field == 'use_default_auth':
|
|
if unicode(value[0]) == 'True' and unicode(value[1]) == 'on' or \
|
|
unicode(value[0]) == 'False' and unicode(value[1]) == '':
|
|
continue
|
|
else:
|
|
name = asset.username
|
|
alert_info = [field_name, u'默认', name] if unicode(value[0]) == 'True' else \
|
|
[field_name, name, u'默认']
|
|
|
|
elif field in ['username', 'password']:
|
|
continue
|
|
|
|
elif field == 'is_active':
|
|
if unicode(value[0]) == 'True' and unicode(value[1]) == '1' or \
|
|
unicode(value[0]) == 'False' and unicode(value[1]) == '0':
|
|
continue
|
|
else:
|
|
alert_info = [u'是否激活', u'激活', u'禁用'] if unicode(value[0]) == 'True' else \
|
|
[u'是否激活', u'禁用', u'激活']
|
|
|
|
else:
|
|
alert_info = [field_name, unicode(value[0]), unicode(value[1])]
|
|
|
|
if 'alert_info' in dir():
|
|
alert_list.append(alert_info)
|
|
|
|
if alert_list:
|
|
AssetRecord.objects.create(asset=asset, username=username, content=alert_list)
|
|
|
|
|
|
def write_excel(asset_all):
|
|
data = []
|
|
now = datetime.datetime.now().strftime('%Y_%m_%d_%H_%M')
|
|
file_name = 'cmdb_excel_' + now + '.xlsx'
|
|
workbook = xlsxwriter.Workbook('static/files/excels/%s' % file_name)
|
|
worksheet = workbook.add_worksheet(u'CMDB数据')
|
|
worksheet.set_first_sheet()
|
|
worksheet.set_column('A:E', 15)
|
|
worksheet.set_column('F:F', 40)
|
|
worksheet.set_column('G:Z', 15)
|
|
title = [u'主机名', u'IP', u'IDC', u'所属主机组', u'操作系统', u'CPU', u'内存(G)', u'硬盘(G)',
|
|
u'机柜位置', u'MAC', u'远控IP', u'机器状态', u'备注']
|
|
for asset in asset_all:
|
|
group_list = []
|
|
for p in asset.group.all():
|
|
group_list.append(p.name)
|
|
|
|
disk = get_disk_info(asset.disk)
|
|
group_all = '/'.join(group_list)
|
|
status = asset.get_status_display()
|
|
idc_name = asset.idc.name if asset.idc else u''
|
|
system_type = asset.system_type if asset.system_type else u''
|
|
system_version = asset.system_version if asset.system_version else u''
|
|
system_os = unicode(system_type) + unicode(system_version)
|
|
|
|
alter_dic = [asset.hostname, asset.ip, idc_name, group_all, system_os, asset.cpu, asset.memory,
|
|
disk, asset.cabinet, asset.mac, asset.remote_ip, status, asset.comment]
|
|
data.append(alter_dic)
|
|
format = workbook.add_format()
|
|
format.set_border(1)
|
|
format.set_align('center')
|
|
format.set_align('vcenter')
|
|
format.set_text_wrap()
|
|
|
|
format_title = workbook.add_format()
|
|
format_title.set_border(1)
|
|
format_title.set_bg_color('#cccccc')
|
|
format_title.set_align('center')
|
|
format_title.set_bold()
|
|
|
|
format_ave = workbook.add_format()
|
|
format_ave.set_border(1)
|
|
format_ave.set_num_format('0.00')
|
|
|
|
worksheet.write_row('A1', title, format_title)
|
|
i = 2
|
|
for alter_dic in data:
|
|
location = 'A' + str(i)
|
|
worksheet.write_row(location, alter_dic, format)
|
|
i += 1
|
|
|
|
workbook.close()
|
|
ret = (True, file_name)
|
|
return ret
|
|
|
|
|
|
def copy_model_instance(obj):
|
|
initial = dict([(f.name, getattr(obj, f.name))
|
|
for f in obj._meta.fields
|
|
if not isinstance(f, AutoField) and \
|
|
not f in obj._meta.parents.values()])
|
|
return obj.__class__(**initial)
|
|
|
|
|
|
def ansible_record(asset, ansible_dic, username):
|
|
alert_dic = {}
|
|
asset_dic = asset.__dict__
|
|
for field, value in ansible_dic.items():
|
|
old = asset_dic.get(field)
|
|
new = ansible_dic.get(field)
|
|
if unicode(old) != unicode(new):
|
|
setattr(asset, field, value)
|
|
asset.save()
|
|
alert_dic[field] = [old, new]
|
|
|
|
db_asset_alert(asset, username, alert_dic)
|
|
|
|
|
|
def excel_to_db(excel_file):
|
|
"""
|
|
Asset add batch function
|
|
"""
|
|
try:
|
|
data = xlrd.open_workbook(filename=None, file_contents=excel_file.read())
|
|
except Exception, e:
|
|
return False
|
|
else:
|
|
table = data.sheets()[0]
|
|
rows = table.nrows
|
|
for row_num in range(1, rows):
|
|
row = table.row_values(row_num)
|
|
if row:
|
|
group_instance = []
|
|
ip, port, hostname, use_default_auth, username, password, group = row
|
|
if get_object(Asset, hostname=hostname):
|
|
continue
|
|
if isinstance(password, int) or isinstance(password, float):
|
|
password = unicode(int(password))
|
|
use_default_auth = 1 if use_default_auth == u'默认' else 0
|
|
password_encode = CRYPTOR.encrypt(password) if password else ''
|
|
if hostname:
|
|
asset = Asset(ip=ip,
|
|
port=port,
|
|
hostname=hostname,
|
|
use_default_auth=use_default_auth,
|
|
username=username,
|
|
password=password_encode
|
|
)
|
|
asset.save()
|
|
group_list = group.split('/')
|
|
for group_name in group_list:
|
|
group = get_object(AssetGroup, name=group_name)
|
|
if group:
|
|
group_instance.append(group)
|
|
if group_instance:
|
|
asset.group = group_instance
|
|
asset.save()
|
|
return True
|
|
|
|
|
|
def get_ansible_asset_info(asset_ip, setup_info):
|
|
disk_need = {}
|
|
disk_all = setup_info.get("ansible_devices")
|
|
if disk_all:
|
|
for disk_name, disk_info in disk_all.iteritems():
|
|
if disk_name.startswith('sd') or disk_name.startswith('hd') or disk_name.startswith('vd') or disk_name.startswith('xvd'):
|
|
disk_size = disk_info.get("size", '')
|
|
if 'M' in disk_size:
|
|
disk_format = round(float(disk_size[:-2]) / 1000, 0)
|
|
elif 'T' in disk_size:
|
|
disk_format = round(float(disk_size[:-2]) * 1000, 0)
|
|
else:
|
|
disk_format = float(disk_size[:-2])
|
|
disk_need[disk_name] = disk_format
|
|
all_ip = setup_info.get("ansible_all_ipv4_addresses")
|
|
other_ip_list = all_ip.remove(asset_ip) if asset_ip in all_ip else []
|
|
other_ip = ','.join(other_ip_list) if other_ip_list else ''
|
|
# hostname = setup_info.get("ansible_hostname")
|
|
# ip = setup_info.get("ansible_default_ipv4").get("address")
|
|
mac = setup_info.get("ansible_default_ipv4").get("macaddress")
|
|
brand = setup_info.get("ansible_product_name")
|
|
try:
|
|
cpu_type = setup_info.get("ansible_processor")[1]
|
|
except IndexError:
|
|
cpu_type = ' '.join(setup_info.get("ansible_processor")[0].split(' ')[:6])
|
|
|
|
memory = setup_info.get("ansible_memtotal_mb")
|
|
try:
|
|
memory_format = int(round((int(memory) / 1000), 0))
|
|
except Exception:
|
|
memory_format = memory
|
|
disk = disk_need
|
|
system_type = setup_info.get("ansible_distribution")
|
|
if system_type.lower() == "freebsd":
|
|
system_version = setup_info.get("ansible_distribution_release")
|
|
cpu_cores = setup_info.get("ansible_processor_count")
|
|
else:
|
|
system_version = setup_info.get("ansible_distribution_version")
|
|
cpu_cores = setup_info.get("ansible_processor_vcpus")
|
|
cpu = cpu_type + ' * ' + unicode(cpu_cores)
|
|
system_arch = setup_info.get("ansible_architecture")
|
|
# asset_type = setup_info.get("ansible_system")
|
|
sn = setup_info.get("ansible_product_serial")
|
|
asset_info = [other_ip, mac, cpu, memory_format, disk, sn, system_type, system_version, brand, system_arch]
|
|
return asset_info
|
|
|
|
|
|
def asset_ansible_update(obj_list, name=''):
|
|
resource = gen_resource(obj_list)
|
|
ansible_instance = MyRunner(resource)
|
|
ansible_asset_info = ansible_instance.run(module_name='setup', pattern='*')
|
|
logger.debug('获取硬件信息: %s' % ansible_asset_info)
|
|
for asset in obj_list:
|
|
try:
|
|
setup_info = ansible_asset_info['contacted'][asset.hostname]['ansible_facts']
|
|
logger.debug("setup_info: %s" % setup_info)
|
|
except KeyError, e:
|
|
logger.error("获取setup_info失败: %s" % e)
|
|
continue
|
|
else:
|
|
try:
|
|
asset_info = get_ansible_asset_info(asset.ip, setup_info)
|
|
print asset_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": 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()
|
|
|
|
|
|
def asset_ansible_update_all():
|
|
name = u'定时更新'
|
|
asset_all = Asset.objects.all()
|
|
asset_ansible_update(asset_all, name)
|
|
|