新增资产

现在api服务端已经能获取到我们要做的操作了。接下来应该是补充获取操作后对应的程序编写

我们要做的是把post请求发过来的数据保存到数据库。我们创建repository 名字的app,并设计models创建表来存储数据。后面可以从数据库获取信息并展示出来

from django.db import models

class BusinessUnit(models.Model):
"""
业务线
"""
name = models.CharField('业务线', max_length=, unique=True) class Meta:
verbose_name_plural = "业务线表" def __str__(self):
return self.name class IDC(models.Model):
"""
机房信息
"""
name = models.CharField('机房', max_length=)
floor = models.IntegerField('楼层', default=) class Meta:
verbose_name_plural = "机房表" def __str__(self):
return self.name class Server(models.Model):
"""
服务器信息 主机
""" device_status_choices = (
(, '上架'),
(, '在线'),
(, '离线'),
(, '下架'),
)
device_status_id = models.IntegerField('设备状态', choices=device_status_choices, default=) idc = models.ForeignKey('IDC', verbose_name='IDC机房', null=True, blank=True, on_delete=models.CASCADE)
cabinet_num = models.CharField('机柜号', max_length=, null=True, blank=True)
cabinet_order = models.CharField('机柜中序号', max_length=, null=True, blank=True) business_unit = models.ForeignKey('BusinessUnit', verbose_name='属于的业务线', null=True, blank=True,
on_delete=models.CASCADE) # 基本信息 + 主板信息 + CPU信息
hostname = models.CharField('主机名', max_length=, unique=True)
os_platform = models.CharField('系统', max_length=, null=True, blank=True)
os_version = models.CharField('系统版本', max_length=, null=True, blank=True) sn = models.CharField('SN号', max_length=, db_index=True)
manufacturer = models.CharField(verbose_name='制造商', max_length=, null=True, blank=True)
model = models.CharField('型号', max_length=, null=True, blank=True) cpu_count = models.IntegerField('CPU个数', null=True, blank=True)
cpu_physical_count = models.IntegerField('CPU物理个数', null=True, blank=True)
cpu_model = models.CharField('CPU型号', max_length=, null=True, blank=True) latest_date = models.DateField('最后更新时间', null=True)
create_at = models.DateTimeField(auto_now_add=True, blank=True) class Meta:
verbose_name_plural = "服务器表" def __str__(self):
return self.hostname class Disk(models.Model):
"""
硬盘信息
"""
slot = models.CharField('插槽位', max_length=)
model = models.CharField('磁盘型号', max_length=)
capacity = models.FloatField('磁盘容量GB')
pd_type = models.CharField('磁盘类型', max_length=) server = models.ForeignKey(verbose_name='服务器', to='Server', related_name='disk_list', on_delete=models.CASCADE) class Meta:
verbose_name_plural = "硬盘表" def __str__(self):
return self.slot class NIC(models.Model):
"""
网卡信息
"""
name = models.CharField('网卡名称', max_length=)
hwaddr = models.CharField('网卡mac地址', max_length=)
netmask = models.CharField(max_length=)
ipaddrs = models.CharField('ip地址', max_length=)
up = models.BooleanField(default=False)
server = models.ForeignKey('Server', related_name='nic_list', on_delete=models.CASCADE) class Meta:
verbose_name_plural = "网卡表" def __str__(self):
return self.name class Memory(models.Model):
"""
内存信息
"""
slot = models.CharField('插槽位', max_length=)
manufacturer = models.CharField('制造商', max_length=, null=True, blank=True)
model = models.CharField('型号', max_length=)
capacity = models.FloatField('容量', null=True, blank=True)
sn = models.CharField('内存SN号', max_length=, null=True, blank=True)
speed = models.CharField('速度', max_length=, null=True, blank=True) server = models.ForeignKey('Server', related_name='memory_list', on_delete=models.CASCADE) class Meta:
verbose_name_plural = "内存表" def __str__(self):
return self.slot class AssetRecord(models.Model):
"""
资产变更记录
"""
server = models.ForeignKey('Server', related_name='servers', on_delete=models.CASCADE)
content = models.TextField(null=True)
create_at = models.DateTimeField(auto_now_add=True) class Meta:
verbose_name_plural = "资产记录表" class ErrorLog(models.Model):
"""
错误日志,如:agent采集数据错误 或 运行错误
"""
server = models.ForeignKey('Server', null=True, blank=True, on_delete=models.CASCADE)
title = models.CharField(max_length=)
content = models.TextField()
create_at = models.DateTimeField(auto_now_add=True) class Meta:
verbose_name_plural = "错误日志表" def __str__(self):
return self.title

models.py

我们可以将业务线先设置成这个。然后执行命令生成表

我们先将cert删除,并且将这里写入文件的注释掉,这样每次判断都是新增主机了

服务端接收的数据如下图,将它存入数据库

我们要将新增的这些资产信息存入数据库

先看新增server,1处有默认,2处可以为空,我们先不管

我们先看这三种硬件信息

而这三种硬件信息和我们传过来的数据一致,字段名字也一样

我们将数据字典取出来,然后update到同一个字典中,合成一个。

获得如下的字典

{
'os_platform': 'linux',
'os_version': '6.5',
'hostname': 'c1.com',
'manufacturer': 'Parallels Software International Inc.',
'model': 'Parallels Virtual Platform',
'sn': 'Parallels-1A 1B CB 3B 64 66 4B 13 86 B0 86 FF 7E 2B 20 30',
'cpu_count': ,
'cpu_physical_count': ,
'cpu_model': ' Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz'
}

然后执行创建orm对象的命令,将这个字典打散存入数据库

再看看新增硬盘,硬盘是一个槽位是一个硬盘,前面新增一台server,已经有了这台server对象了,所以硬盘所属外键server=server。for循环外层字典的值,然后将每个内层字典打散插入到Disk数据表中。

这样就保存了6个槽位的硬盘

这里for循环插入数据,插入一次连接一次数据库,我们可以进行优化一下

for循环创建Disk对象并追加到列表。bulk_create方法根据对象列表一次批量创建数据表记录

新增内存和新增硬盘一样

出问题了,因为数据结构内存和网卡没有修改,没有保存进去

修改后点击执行客户端,客户端采集信息发送给api然后保存到数据库

而新增网卡有点区别,它以name为键但是数据里没有name,

所以创建要将name加进去,循环并取出它的键加到数据库中

更新资产

我们创建cert,将主机名和我们固定采集的主机名一致,这样走的就是更新资产信息了

api服务端走的是更新资产信息,服务端要写的更新程序如下

下面看一下更新主机表的程序

下面我将主机表修改一下,执行客户端程序后又更新回来了

现在我们将数据库修改如下:

因为每次提交这里都是提交0-5的,所以新增,更新,删除就会如上

新增,删除和更新如下。新增是采集的减数据库的(采集的多出来的),删除是数据库的减采集的(数据库多出来的),更新是采集的和数据库都有的(用&集合运算)。这样获取到槽位信息,根据槽位信息对这条记录做相应的操作。

下面根据获取到要做这三个操作的硬盘槽位,对它们做对应的操作

当客户端执行采集并汇报后,服务端显然做了对应的硬盘更新

观察内存和网卡的程序是相似的,只是名字有点区别,可以用notepad++替换,然后将有区别的地方更改正确,这样就完成内存和网卡的更新操作

# 更新内存
memory_info = info['memory']['data'] # 新提交的数据 memory_slot_set = set(memory_info)
memory_slot__db_set = {i.slot for i in models.Memory.objects.filter(server=server)} # 新增 删除 更新
add_slot_set = memory_slot_set - memory_slot__db_set # 新增的槽位
del_slot_set = memory_slot__db_set - memory_slot_set # 删除的槽位
update_slot_set = memory_slot__db_set & memory_slot_set # 更新的槽位 # 新增内存 add_memory_lit = []
for slot in add_slot_set:
memory = memory_info.get(slot)
add_memory_lit.append(models.Memory(**memory, server=server)) if add_memory_lit:
models.Memory.objects.bulk_create(add_memory_lit) # 删除内存
if del_slot_set:
models.Memory.objects.filter(server=server, slot__in=del_slot_set).delete() # 更新内存
for slot in update_slot_set:
memory = memory_info.get(slot)
models.Memory.objects.filter(server=server, slot=slot).update(**memory)
 nic_info = info['nic']['data']  # 新提交的数据

    nic_name_set = set(nic_info)
nic_name__db_set = {i.name for i in models.NIC.objects.filter(server=server)} # 新增 删除 更新
add_name_set = nic_name_set - nic_name__db_set # 新增的槽位
del_name_set = nic_name__db_set - nic_name_set # 删除的槽位
update_name_set = nic_name__db_set & nic_name_set # 更新的槽位 # 新增网卡 add_nic_lit = []
for name in add_name_set:
nic = nic_info.get(name)
nic['name'] = name
add_nic_lit.append(models.NIC(**nic, server=server)) if add_nic_lit:
models.NIC.objects.bulk_create(add_nic_lit) # 删除网卡
if del_name_set:
models.NIC.objects.filter(server=server, name__in=del_name_set).delete() # 更新网卡
for name in update_name_set:
nic = nic_info.get(name)
nic['name'] = name
models.NIC.objects.filter(server=server, name=name).update(**nic)

更新资产+主机名

我们在客户端将cert文件内容改变,让它和会采集到的信息不一致,这样程序就会走更新主机名和资产信息

{
'disk': {
'status': True,
'error': '',
'data': {
'': {
'slot': '',
'pd_type': 'SAS',
'capacity': '279.396',
'model': 'SEAGATE ST300MM0006 LS08S0K2B5NV'
},
'': {
'slot': '',
'pd_type': 'SAS',
'capacity': '279.396',
'model': 'SEAGATE ST300MM0006 LS08S0K2B5AH'
},
'': {
'slot': '',
'pd_type': 'SATA',
'capacity': '476.939',
'model': 'S1SZNSAFA01085L Samsung SSD 850 PRO 512GB EXM01B6Q'
},
'': {
'slot': '',
'pd_type': 'SATA',
'capacity': '476.939',
'model': 'S1AXNSAF912433K Samsung SSD 840 PRO Series DXM06B0Q'
},
'': {
'slot': '',
'pd_type': 'SATA',
'capacity': '476.939',
'model': 'S1AXNSAF303909M Samsung SSD 840 PRO Series DXM05B0Q'
},
'': {
'slot': '',
'pd_type': 'SATA',
'capacity': '476.939',
'model': 'S1AXNSAFB00549A Samsung SSD 840 PRO Series DXM06B0Q'
}
}
},
'memory': {
'status': True,
'error': '',
'data': {
'DIMM #0': {
'capacity': ,
'slot': 'DIMM #0',
'model': 'DRAM',
'speed': '667 MHz',
'manufacturer': 'Not Specified',
'sn': 'Not Specified'
},
'DIMM #1': {
'capacity': ,
'slot': 'DIMM #1',
'model': 'DRAM',
'speed': '667 MHz',
'manufacturer': 'Not Specified',
'sn': 'Not Specified'
},
'DIMM #2': {
'capacity': ,
'slot': 'DIMM #2',
'model': 'DRAM',
'speed': '667 MHz',
'manufacturer': 'Not Specified',
'sn': 'Not Specified'
},
'DIMM #3': {
'capacity': ,
'slot': 'DIMM #3',
'model': 'DRAM',
'speed': '667 MHz',
'manufacturer': 'Not Specified',
'sn': 'Not Specified'
},
'DIMM #4': {
'capacity': ,
'slot': 'DIMM #4',
'model': 'DRAM',
'speed': '667 MHz',
'manufacturer': 'Not Specified',
'sn': 'Not Specified'
},
'DIMM #5': {
'capacity': ,
'slot': 'DIMM #5',
'model': 'DRAM',
'speed': '667 MHz',
'manufacturer': 'Not Specified',
'sn': 'Not Specified'
},
'DIMM #6': {
'capacity': ,
'slot': 'DIMM #6',
'model': 'DRAM',
'speed': '667 MHz',
'manufacturer': 'Not Specified',
'sn': 'Not Specified'
},
'DIMM #7': {
'capacity': ,
'slot': 'DIMM #7',
'model': 'DRAM',
'speed': '667 MHz',
'manufacturer': 'Not Specified',
'sn': 'Not Specified'
}
}
},
'nic': {
'status': True,
'error': '',
'data': {
'eth0': {
'up': True,
'hwaddr': '00:1c:42:a5:57:7a',
'ipaddrs': '10.211.55.4',
'netmask': '255.255.255.0'
}
}
},
'basic': {
'status': True,
'error': '',
'data': {
'os_platform': 'linux',
'os_version': '6.5',
'hostname': 'c1.com'
}
},
'cpu': {
'status': True,
'error': '',
'data': {
'cpu_count': ,
'cpu_physical_count': ,
'cpu_model': ' Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz'
}
},
'main_board': {
'status': True,
'error': '',
'data': {
'manufacturer': 'Parallels Software International Inc.',
'model': 'Parallels Virtual Platform',
'sn': 'Parallels-1A 1B CB 3B 64 66 4B 13 86 B0 86 FF 7E 2B 20 30'
}
},
'action': 'update_host',
'old_hostname': 'c2.com'
}

data.json

而提交过来的数据里面,还有老主机名,也就是文件里保存的主机名

因此服务端能从发送过来的info数据获取到主机名,从而从数据库查到这台服务器的信息,因为更新资产信息部分和之前写的单纯地更新资产信息部分是一样的。

这部分我们不用重复写了,所以直接在app里创建service模块写成函数进行调用。

from repository import models

def process_basic(info):
server_info = {} basic = info['basic']['data']
main_board = info['main_board']['data']
cpu = info['cpu']['data']
server_info.update(basic)
server_info.update(main_board)
server_info.update(cpu) hostname = info['basic']['data']['hostname'] # 新的hostname
old_hostname = info.get('old_hostname') # 老的hostname server_list = models.Server.objects.filter(hostname=old_hostname if old_hostname else hostname)
server_list.update(**server_info)
server = models.Server.objects.filter(hostname=hostname).first()
return server def process_disk(info, server):
disk_info = info['disk']['data'] # 新提交的数据 disk_slot_set = set(disk_info)
disk_slot__db_set = {i.slot for i in models.Disk.objects.filter(server=server)} # 新增 删除 更新
add_slot_set = disk_slot_set - disk_slot__db_set # 新增的槽位 添加硬盘
del_slot_set = disk_slot__db_set - disk_slot_set # 删除的槽位 减少硬盘
update_slot_set = disk_slot__db_set & disk_slot_set # 更新的槽位 更换硬盘 # 新增硬盘 add_disk_lit = []
for slot in add_slot_set:
disk = disk_info.get(slot)
add_disk_lit.append(models.Disk(**disk, server=server)) if add_disk_lit:
models.Disk.objects.bulk_create(add_disk_lit) # 删除硬盘
if del_slot_set:
models.Disk.objects.filter(server=server, slot__in=del_slot_set).delete() # 更新硬盘
for slot in update_slot_set:
disk = disk_info.get(slot)
models.Disk.objects.filter(server=server, slot=slot).update(**disk) def process_memory(info, server):
# 更新内存
memory_info = info['memory']['data'] # 新提交的数据 memory_slot_set = set(memory_info)
memory_slot__db_set = {i.slot for i in models.Memory.objects.filter(server=server)} # 新增 删除 更新
add_slot_set = memory_slot_set - memory_slot__db_set # 新增的槽位
del_slot_set = memory_slot__db_set - memory_slot_set # 删除的槽位
update_slot_set = memory_slot__db_set & memory_slot_set # 更新的槽位 # 新增内存 add_memory_lit = []
for slot in add_slot_set:
memory = memory_info.get(slot)
add_memory_lit.append(models.Memory(**memory, server=server)) if add_memory_lit:
models.Memory.objects.bulk_create(add_memory_lit) # 删除内存
if del_slot_set:
models.Memory.objects.filter(server=server, slot__in=del_slot_set).delete() # 更新内存
for slot in update_slot_set:
memory = memory_info.get(slot)
models.Memory.objects.filter(server=server, slot=slot).update(**memory) def process_nic(info, server):
nic_info = info['nic']['data'] # 新提交的数据 nic_name_set = set(nic_info)
nic_name__db_set = {i.name for i in models.NIC.objects.filter(server=server)} # 新增 删除 更新
add_name_set = nic_name_set - nic_name__db_set # 新增的槽位
del_name_set = nic_name__db_set - nic_name_set # 删除的槽位
update_name_set = nic_name__db_set & nic_name_set # 更新的槽位 # 新增网卡 add_nic_lit = []
for name in add_name_set:
nic = nic_info.get(name)
nic['name'] = name
add_nic_lit.append(models.NIC(**nic, server=server)) if add_nic_lit:
models.NIC.objects.bulk_create(add_nic_lit) # 删除网卡
if del_name_set:
models.NIC.objects.filter(server=server, name__in=del_name_set).delete() # 更新网卡
for name in update_name_set:
nic = nic_info.get(name)
nic['name'] = name
models.NIC.objects.filter(server=server, name=name).update(**nic)

service.py

然后我们导入这四个类并调用。这样就实现了更新资产信息了。

至于客户端主机名的修改,只需要将客户端这里的注释去掉就可以了

api验证

cmdb资产管理2的更多相关文章

  1. CMDB资产管理

    .传统运维和自动化运维的区别: 传统运维: 1.项目上线: a.产品经理前期调研(需求分析) b.和开发进行评审 c.开发进行开发 d.测试进行测试 e.交给运维人员进行上线 上线: 直接将代码交给运 ...

  2. Python学习路程CMDB

    本节内容 浅谈ITIL CMDB介绍 Django自定义用户认证 Restful 规范 资产管理功能开发 浅谈ITIL TIL即IT基础架构库(Information Technology Infra ...

  3. 构建CMDB的一些启发

    开篇感言: 自从学习python自动化开发以来,一直都是从技术的角度来看待一切.以为技术就是王道.但显然我是一只井底之蛙.其实技术只不过是实现功能的工具而已,仅此而已.后来学习了解CMDB,越来越发现 ...

  4. Python之路,Day19 - CMDB、CMDB、CMDB

    Python之路,Day19 - CMDB.CMDB.CMDB   本节内容 浅谈ITIL CMDB介绍 Django自定义用户认证 Restful 规范 资产管理功能开发 浅谈ITIL TIL即IT ...

  5. python运维开发(二十五)---cmdb开发

    内容目录: 浅谈ITIL CMDB介绍 Django自定义用户认证 Restful 规范 资产管理功能开发 浅谈ITIL TIL即IT基础架构库(Information Technology Infr ...

  6. Django:之CMDB资源系统

    渐谈CMDB需要内容,ITIL.CMDB介绍.Django自定义用户认证.Restful规范.资产管理功能开发. ITIL介绍 TIL即IT基础架构库(Information Technology I ...

  7. CMDB运维开发项目

    ITIL:Information Technology Infrastructure Library 信息技术基础架构库,主要适用于IT服务管理(ITSM).ITIL为企业的IT服务管理实践提供了一个 ...

  8. CMDB项目开发

    CMDB介绍 CMDB --Configuration Management Database 配置管理数据库, CMDB存储与管理企业IT架构中设备的各种配置信息,它与所有服务支持和服务交付流程都紧 ...

  9. CMDB资产管理系统开发【day25】:需求分析

    本节内容 浅谈ITIL CMDB介绍 Django自定义用户认证 Restful 规范 资产管理功能开发 浅谈ITIL TIL即IT基础架构库(Information Technology Infra ...

随机推荐

  1. tomcat安全基线

    为了符合tomcat安全基线,需要做一下加固: 1.管理用户的密码加密:<摘要算法加密tomcat登录密码> 管理用户在conf/tomcat-users.xml中配置,密码一般是明文形式 ...

  2. ros 源码安装

    版本lunar, 系统版本debian 9.8 参考: http://wiki.ros.org/lunar/Installation/Source 1. Installing bootstrap de ...

  3. SpringBoot小技巧:Jar包换War包

    SpringBoot小技巧:Jar包换War包 情景 我们都知道springBoot中已经内置了tomcat,是不需要我们额外的配置tomcat服务器的,但是有时这也可能是我们的一个瓶颈,因为如果我们 ...

  4. vs2015下C4819该文件包含不能在当前代码页(936)中表示的字符问题解决

    今天编译IfcOpenshell出现很多warning如下: C4819 该文件包含不能在当前代码页(936)中表示的字符.请将该文件保存为 Unicode 格式以防止数据丢失 解决方案: 文件——& ...

  5. 解决net core mvc 中文乱码问题

    在Startup 配置文件下的ConfigureServices方法中添加:    services.AddSingleton(HtmlEncoder.Create(UnicodeRanges.All ...

  6. spring data jpa碰到的坑

    1.不能从别的类的repository那里 执行另一个类的sql,这样映射会失败. 2.有entity,就要有repository,并且还要有id注解 3.还要多表联查未测试,估计要用map去映射出来 ...

  7. 是真的随笔qvq

    DATE:2019.11.20 今天考了试——对光荣爆零.从14:00考到18:30,隔壁计算机教室的电脑弄得心态炸裂了,各种卡,肝了一个下午的两道题以电脑死机没有代码结尾,考完才知道这是最好骗分的两 ...

  8. 解决 niceScroll 自适应DOM 高度变化

    利用dataTable展示数据列表时,当选择每页显示数量时,滚动条还是按照页面初始化时显示的,导致无法滚动查看下面的数据,  在stackoverflower 找到一个可用的方法,但不知道为什么仅写  ...

  9. 51book机票接口对接,吐血整理(含PHP封装代码)

    前言 最近在对接51book的机票接口,遇到了挺多坑,所以整理一份作为记录 机票有两个不同的接口,一个是机票,另一个是保险 一.申请 要接51book的机票,首先是要申请账号,这时候应该是有客户经理跟 ...

  10. [Centos 7]MYSQL 安装及登录问题

    1. Centos 7 上安装mysql 8 rpm -qa |grep -i mysql //看自己系统有没有装mysql wget https://dev.mysql.com/get/mysql8 ...