CMDB资产管理系统开发【day25】:表结构设计1
资产表
# _*_coding:utf-8_*_ __author__ = 'jieli' from assets.myauth import UserProfile from django.db import models class Asset(models.Model): asset_type_choices = ( ('server', u'服务器'), ('networkdevice', u'网络设备'), ('storagedevice', u'存储设备'), ('securitydevice', u'安全设备'), ('securitydevice', u'机房设备'), # ('switch', u'交换机'), # ('router', u'路由器'), # ('firewall', u'防火墙'), # ('storage', u'存储设备'), # ('NLB', u'NetScaler'), # ('wireless', u'无线AP'), ('software', u'软件资产'), # ('others', u'其它类'), ''' 为什么我不把这些删除?,我就想告诉你,经历了N次的改变才到这一步,这就是你交钱来学的意义 你写了5万行代码就是多少行代码的水平,首先有一个资产类型 ''' ) asset_type = models.CharField(choices=asset_type_choices, max_length=64, default='server') name = models.CharField(max_length=64, unique=True) ''' 这个资产名,是自己起的名字,这个可不可以重复?不可以重复 也不允许他重复,自己起是为了作为唯一标识的, ''' sn = models.CharField(u'资产SN号', max_length=128, unique=True) ''' sn号是比较唯一的 ''' manufactory = models.ForeignKey('Manufactory', verbose_name=u'制造商', null=True, blank=True) ''' 制造商就那么几个,所以把他做成外键,blank=True是什么意思?null=True?收据库里可以为空,如果你在dgone里 数据库允许为空,但是admin不允许为空,如果你要想让这个字段不为一个必填,就必须null=True, blank=True这两个同时用 ''' # model = models.ForeignKey('ProductModel', verbose_name=u'型号') # model = models.CharField(u'型号',max_length=128,null=True, blank=True ) management_ip = models.GenericIPAddressField(u'管理IP', blank=True, null=True) ''' 我什么管理ip就没有写唯一? 因为为也不知道你要存什么,也可以通过外网ip连接,也可以通过管理皮地址连接,虚拟机和物理机关联起来 ''' contract = models.ForeignKey('Contract', verbose_name=u'合同', null=True, blank=True) ''' 合同可能是买一批机器,我做了个外键,运维也不关注合同的具体条款 ''' trade_date = models.DateField(u'购买时间', null=True, blank=True) expire_date = models.DateField(u'过保修期', null=True, blank=True) ''' 可以实现自动过保 ''' price = models.FloatField(u'价格', null=True, blank=True) ''' 运维关注价格干啥?成本核算,这些钱花那了,那些业务线花了我多钱,每个业务线到底用了我多少成本? ''' business_unit = models.ForeignKey('BusinessUnit', verbose_name=u'所属业务线', null=True, blank=True) tags = models.ManyToManyField('Tag', blank=True) ''' 允许给资产打标签,虽然你刚才你有一些业务线的划分,但是有一些资产你就是想随手做一些标记? 为了区分的时候好区分,一台机器可以加很多标记,以后从各个维度去看你的组织架构 ''' admin = models.ForeignKey('UserProfile', verbose_name=u'资产管理员', null=True, blank=True) ''' 刚买来的资产,也可以没有资产管理员 ''' idc = models.ForeignKey('IDC', verbose_name=u'IDC机房', null=True, blank=True) ''' 也可以为空,因为还没有进机房 ''' status_choices = ((0, '在线'), (1, '已下线'), (2, '未知'), (3, '故障'), (4, '备用'), ) status = models.SmallIntegerField(choices=status_choices, default=0) # status = models.ForeignKey('Status', verbose_name = u'设备状态',default=1) # Configuration = models.OneToOneField('Configuration',verbose_name='配置管理',blank=True,null=True) memo = models.TextField(u'备注', null=True, blank=True) create_date = models.DateTimeField(blank=True, auto_now_add=True) update_date = models.DateTimeField(blank=True, auto_now=True) ''' auto_now=True?每次变更自动更新 ''' class Meta: verbose_name = '资产总表' verbose_name_plural = "资产总表" ''' 先忘记它,你一会就知道了? ''' def __str__(self): return '<id:%s name:%s>' % (self.id, self.name)
服务器设备
class Server(models.Model): """服务器设备""" asset = models.OneToOneField('Asset') ''' server和资产能一对多吗?一个资产只能属于一个server,不能属于多个server 一对一为什么不写一张表上了? 因为这样冗余字段就太多了,服务器和存储设备很多冗余字段不一样很多属性不一样 前十周就够写脚本用了,想往上走不能光靠忽悠 ''' sub_assset_type_choices = ( (0, 'PC服务器'), (1, '刀片机'), (2, '小型机'), ) created_by_choices = ( ('auto', 'Auto'), ('manual', 'Manual'), ) ''' 为什么要区分手动还是自动? 1、默认自动添加的绝对准确不需要修改 2、手动添加的有可能错误允许修改,每个资产都有管理ip,但是机柜、软件没有 ''' sub_asset_type = models.SmallIntegerField(choices=sub_assset_type_choices, verbose_name="服务器类型", default=0) ''' 在汽车之家就没有区分,直接用服务器型号区分, ''' created_by = models.CharField(choices=created_by_choices, max_length=32, default='auto') # auto: auto created, manual:created manually hosted_on = models.ForeignKey('self', related_name='hosted_on_server', blank=True, null=True) # for vitural server ''' 虚拟机和物理机关联起来,就是为了虚拟机做的,但是我一直没有用上这个,多少物理机上要多少台虚拟机,虚拟机也有 SN物理机上也有SN但是不一样,虚拟机有固定的ID 自动生成sn号抓不出来,关联自己 ''' # sn = models.CharField(u'SN号',max_length=128) # management_ip = models.CharField(u'管理IP',max_length=64,blank=True,null=True) # manufactory = models.ForeignKey(verbose_name=u'制造商',max_length=128,null=True, blank=True) ''' 每个资产都有生产厂商、管理IP、SN(但是机柜、软件没有),所以我把他提成了公共信息 ''' model = models.CharField(verbose_name=u'型号', max_length=128, null=True, blank=True) # 若有多个CPU,型号应该都是一致的,故没做ForeignKey ''' model怎么存到了server? 每个资产都用型号,应该存到公共里面,那我为什么存到这里呢? 记住这?这里是有一个坑的,你先记住,后面你就明白了 ''' # nic = models.ManyToManyField('NIC', verbose_name=u'网卡列表') # disk raid_type = models.CharField(u'raid类型', max_length=512, blank=True, null=True) ''' 服务器都有radi类型 ''' # physical_disk_driver = models.ManyToManyField('Disk', verbose_name=u'硬盘',blank=True,null=True) # raid_adaptor = models.ManyToManyField('RaidAdaptor', verbose_name=u'Raid卡',blank=True,null=True) # memory # ram_capacity = models.IntegerField(u'内存总大小GB',blank=True) # ram = models.ManyToManyField('Memory', verbose_name=u'内存配置',blank=True,null=True) ''' 在汽车之家就是这关联的,硬盘椰丝直接和server表关联的 ?我真的忘记了,一会讲到硬盘的时候再来讲???? 之前写的多对多,是不是有问题呀!就会出现一个硬盘属于多个机器,应该是一对多,每个硬盘应该去关联server ''' os_type = models.CharField(u'操作系统类型', max_length=64, blank=True, null=True) os_distribution = models.CharField(u'发型版本', max_length=64, blank=True, null=True) os_release = models.CharField(u'操作系统版本', max_length=64, blank=True, null=True) class Meta: verbose_name = '服务器' verbose_name_plural = "服务器" # together = ["sn", "asset"] def __str__(self): return '%s sn:%s' % (self.asset.name, self.asset.sn)
安全设备
class SecurityDevice(models.Model): """安全设备""" asset = models.OneToOneField('Asset') sub_assset_type_choices = ( (0, '防火墙'), (1, '入侵检测设备'), (2, '互联网网关'), (4, '运维审计系统'), ) sub_asset_type = models.SmallIntegerField(choices=sub_assset_type_choices, verbose_name="服务器类型", default=0) def __str__(self): return self.asset.id
网络设备
class SecurityDevice(models.Model): """安全设备""" asset = models.OneToOneField('Asset') sub_assset_type_choices = ( (0, '防火墙'), (1, '入侵检测设备'), (2, '互联网网关'), (4, '运维审计系统'), ) sub_asset_type = models.SmallIntegerField(choices=sub_assset_type_choices, verbose_name="服务器类型", default=0) def __str__(self): return self.asset.id class NetworkDevice(models.Model): """网络设备""" asset = models.OneToOneField('Asset') sub_assset_type_choices = ( (0, '路由器'), (1, '交换机'), (2, '负载均衡'), (4, 'VPN设备'), ) sub_asset_type = models.SmallIntegerField(choices=sub_assset_type_choices, verbose_name="网络设备类型", default=0) vlan_ip = models.GenericIPAddressField(u'VlanIP', blank=True, null=True) intranet_ip = models.GenericIPAddressField(u'内网IP', blank=True, null=True) """ intranet_ip和内网IP有什么区别?这是我们网络工程师说让存两个 """ # sn = models.CharField(u'SN号',max_length=128,unique=True) # manufactory = models.CharField(verbose_name=u'制造商',max_length=128,null=True, blank=True) model = models.CharField(u'型号', max_length=128, null=True, blank=True) firmware = models.ForeignKey('Software', blank=True, null=True) """ 固件是寄生在资产上面的, """ port_num = models.SmallIntegerField(u'端口个数', null=True, blank=True) device_detail = models.TextField(u'设置详细配置', null=True, blank=True) class Meta: verbose_name = '网络设备' verbose_name_plural = "网络设备"
软件资产
class Software(models.Model): ''' only save software which company purchased 花了钱的才叫资产 ''' sub_assset_type_choices = ( (0, 'OS'), (1, '办公\开发软件'), (2, '业务软件'), ) sub_asset_type = models.SmallIntegerField(choices=sub_assset_type_choices, verbose_name="服务器类型", default=0) license_num = models.IntegerField(verbose_name="授权数") # os_distribution_choices = (('windows','Windows'), # ('centos','CentOS'), # ('ubuntu', 'Ubuntu')) # type = models.CharField(u'系统类型', choices=os_types_choice, max_length=64,help_text=u'eg. GNU/Linux',default=1) # distribution = models.CharField(u'发型版本', choices=os_distribution_choices,max_length=32,default='windows') version = models.CharField(u'软件/系统版本', max_length=64, help_text=u'eg. CentOS release 6.5 (Final)', unique=True) # language_choices = (('cn',u'中文'), # ('en',u'英文')) # language = models.CharField(u'系统语言',choices = language_choices, default='cn',max_length=32) # #version = models.CharField(u'版本号', max_length=64,help_text=u'2.6.32-431.3.1.el6.x86_64' ) def __str__(self): return self.version class Meta: verbose_name = '软件/系统' verbose_name_plural = "软件/系统" '''机柜和服务器是怎样关联的'''
CPU组件
class Software(models.Model): ''' only save software which company purchased 花了钱的才叫资产 ''' sub_assset_type_choices = ( (0, 'OS'), (1, '办公\开发软件'), (2, '业务软件'), ) sub_asset_type = models.SmallIntegerField(choices=sub_assset_type_choices, verbose_name="服务器类型", default=0) license_num = models.IntegerField(verbose_name="授权数") # os_distribution_choices = (('windows','Windows'), # ('centos','CentOS'), # ('ubuntu', 'Ubuntu')) # type = models.CharField(u'系统类型', choices=os_types_choice, max_length=64,help_text=u'eg. GNU/Linux',default=1) # distribution = models.CharField(u'发型版本', choices=os_distribution_choices,max_length=32,default='windows') version = models.CharField(u'软件/系统版本', max_length=64, help_text=u'eg. CentOS release 6.5 (Final)', unique=True) # language_choices = (('cn',u'中文'), # ('en',u'英文')) # language = models.CharField(u'系统语言',choices = language_choices, default='cn',max_length=32) # #version = models.CharField(u'版本号', max_length=64,help_text=u'2.6.32-431.3.1.el6.x86_64' ) def __str__(self): return self.version class Meta: verbose_name = '软件/系统' verbose_name_plural = "软件/系统" '''机柜和服务器是怎样关联的''' class CPU(models.Model): """CPU组件""" asset = models.OneToOneField('Asset') ''' CPU怎么没写ForeignKey?怎么写的OneToOneField 内存可以是不同型号,不同大小 但是cpu型号不一能,那肯定就炸了, 型号主频肯定一样的,还有必要存多条吗? 这样就节省了空间,一堆一关联资产 所以这里就不用一对多了 ''' cpu_model = models.CharField(u'CPU型号', max_length=128, blank=True) cpu_count = models.SmallIntegerField(u'物理cpu个数') cpu_core_count = models.SmallIntegerField(u'cpu核数') memo = models.TextField(u'备注', null=True, blank=True) create_date = models.DateTimeField(auto_now_add=True) update_date = models.DateTimeField(blank=True, null=True) ''' 为什么没有联合唯一,因为我已经逐条唯一了 ''' class Meta: verbose_name = 'CPU部件' verbose_name_plural = "CPU部件" def __str__(self): return self.cpu_model
内存组件
class RAM(models.Model): """内存组件""" asset = models.ForeignKey('Asset') sn = models.CharField(u'SN号', max_length=128, blank=True, null=True) model = models.CharField(u'内存型号', max_length=128) slot = models.CharField(u'插槽', max_length=64) capacity = models.IntegerField(u'内存大小(MB)') memo = models.CharField(u'备注', max_length=128, blank=True, null=True) create_date = models.DateTimeField(blank=True, auto_now_add=True) update_date = models.DateTimeField(blank=True, null=True) ''' 内存:SN 内存 插槽 因为没有唯一,所以要进行联合唯一,没有唯一就无法区分 通过查槽和aseet联合唯一,可以是不同型号,不同大小 ''' def __str__(self): return '%s:%s:%s' % (self.asset_id, self.slot, self.capacity) class Meta: verbose_name = 'RAM' verbose_name_plural = "RAM" unique_together = ("asset", "slot") auto_create_fields = ['sn', 'slot', 'model', 'capacity']
硬盘组件
class Disk(models.Model): """硬盘组件""" asset = models.ForeignKey('Asset') '''asset 硬盘我什么要关联asset? 统一调用的方式,你这个硬盘我还要判断从server表里面判断, 硬盘只有服务器有硬盘,网卡和硬盘配件是同一级别, 我掉网卡就知道通过asset,那硬盘也要从asset去掉 ''' sn = models.CharField(u'SN号', max_length=128, blank=True, null=True) """ 硬盘里为什么要有SN,服务器有服务器的SN,硬盘有硬盘的SN,没有SN如何保修?,我都没写成比填 因为有时候SN有时候抓不到,尤其是虚拟机就更抓不到了, """ slot = models.CharField(u'插槽位', max_length=64) """ 通过曹位和sn联合唯一索引,因为单独通过插槽是无法定位的 """ # manufactory = models.CharField(u'制造商', max_length=64,blank=True,null=True) model = models.CharField(u'磁盘型号', max_length=128, blank=True, null=True) capacity = models.FloatField(u'磁盘容量GB') disk_iface_choice = ( ('SATA', 'SATA'), ('SAS', 'SAS'), ('SCSI', 'SCSI'), ('SSD', 'SSD'), ) iface_type = models.CharField(u'接口类型', max_length=64, choices=disk_iface_choice, default='SAS') memo = models.TextField(u'备注', blank=True, null=True) create_date = models.DateTimeField(blank=True, auto_now_add=True) update_date = models.DateTimeField(blank=True, null=True) """ 硬盘配件更新了,这个时间就更新,比如硬盘坏了,需要更换 """ auto_create_fields = ['sn', 'slot', 'manufactory', 'model', 'capacity', 'iface_type'] """ 硬件收集过来,有那些配件可以自动更新,这是我自己加的,程序里面没有 """ class Meta: unique_together = ("asset", "slot") """ unique_together联合唯一,如何保证disk是唯一的,如果更换硬盘如何判断硬盘 """ verbose_name = '硬盘' verbose_name_plural = "硬盘" def __str__(self): return '%s:slot:%s capacity:%s' % (self.asset_id, self.slot, self.capacity) """ 硬盘里面为什么要有SN """
网卡组件
class NIC(models.Model): """网卡组件""" asset = models.ForeignKey('Asset') ''' 一台serveassetr有多个IP,网络设备,路由器、交换机、防火墙的 还是单独建一个表字段不一样, 不能用server,只能用asset的原因? 网络设备和网卡是一样的为什么不能存到一张表里面? 管理资产最好最大限度的存在一起, 什么是一对一? 一对一的限制只是在一张表里面不是两张表, 不会限制第二张表,程序层面上的限制,数据库层面不限制 onetonone只是限制一张表上的 ''' name = models.CharField(u'网卡名', max_length=64, blank=True, null=True) sn = models.CharField(u'SN号', max_length=128, blank=True, null=True) model = models.CharField(u'网卡型号', max_length=128, blank=True, null=True) macaddress = models.CharField(u'MAC', max_length=64, unique=True) ''' Mac不唯一就没有唯一,因为虚拟机的Mac地址经常重复,把虚拟机存进来就傻逼了, ''' ipaddress = models.GenericIPAddressField(u'IP', blank=True, null=True) ''' 有很多网卡,有的网卡没IP,IP我什么不能唯一?虚拟IP, ''' netmask = models.CharField(max_length=64, blank=True, null=True) bonding = models.CharField(max_length=64, blank=True, null=True) memo = models.CharField(u'备注', max_length=128, blank=True, null=True) create_date = models.DateTimeField(blank=True, auto_now_add=True) update_date = models.DateTimeField(blank=True, null=True) def __str__(self): return '%s:%s' % (self.asset_id, self.macaddress) class Meta: verbose_name = u'网卡' verbose_name_plural = u"网卡" # unique_together = ("asset_id", "slot") unique_together = ("asset", "macaddress") auto_create_fields = ['name', 'sn', 'model', 'macaddress', 'ipaddress', 'netmask', 'bonding']
Raid
class RaidAdaptor(models.Model): """ Raid卡 有的有,有的没有,一台机器上可以有多个Raid?可以有 """ asset = models.ForeignKey('Asset') sn = models.CharField(u'SN号', max_length=128, blank=True, null=True) slot = models.CharField(u'插口', max_length=64) model = models.CharField(u'型号', max_length=64, blank=True, null=True) memo = models.TextField(u'备注', blank=True, null=True) create_date = models.DateTimeField(blank=True, auto_now_add=True) update_date = models.DateTimeField(blank=True, null=True) def __str__(self): return self.name class Meta: unique_together = ("asset", "slot") """ asset和slot联合唯一 """
厂商
class Manufactory(models.Model): """厂商""" manufactory = models.CharField(u'厂商名称', max_length=64, unique=True) support_num = models.CharField(u'支持电话', max_length=30, blank=True) memo = models.CharField(u'备注', max_length=128, blank=True) def __str__(self): return self.manufactory class Meta: verbose_name = '厂商' verbose_name_plural = "厂商"
业务线
class BusinessUnit(models.Model): """业务线""" parent_unit = models.ForeignKey('self', related_name='parent_level', blank=True, null=True) name = models.CharField(u'业务线', max_length=64, unique=True) # contact = models.ForeignKey('UserProfile',default=None) memo = models.CharField(u'备注', max_length=64, blank=True) def __str__(self): return self.name class Meta: verbose_name = '业务线' verbose_name_plural = "业务线"
合同
class Contract(models.Model): """合同""" sn = models.CharField(u'合同号', max_length=128, unique=True) name = models.CharField(u'合同名称', max_length=64) memo = models.TextField(u'备注', blank=True, null=True) price = models.IntegerField(u'合同金额') detail = models.TextField(u'合同详细', blank=True, null=True) start_date = models.DateField(blank=True) end_date = models.DateField(blank=True) license_num = models.IntegerField(u'license数量', blank=True) create_date = models.DateField(auto_now_add=True) update_date = models.DateField(auto_now=True) class Meta: verbose_name = '合同' verbose_name_plural = "合同" def __str__(self): return self.name
IDC
class IDC(models.Model): """ 机房 机房名称要不要唯一?肯定要唯一 """ name = models.CharField(u'机房名称', max_length=64, unique=True) memo = models.CharField(u'备注', max_length=128, blank=True, null=True) def __str__(self): return self.name class Meta: verbose_name = '机房' verbose_name_plural = "机房"
资产标签
class Tag(models.Model): """ 资产标签 打标签要不要唯一?肯定要唯一 """ name = models.CharField('Tag name', max_length=32, unique=True) creator = models.ForeignKey('UserProfile') create_date = models.DateField(auto_now_add=True) def __str__(self): return self.name
事件日志
class EventLog(models.Model): """ 事件 日志表 资产类型 什么是事件指向? 就是存这资产是硬盘、还是内存、还是网卡发生变更 一个资产可以有多个事件吗? """ name = models.CharField(u'事件名称', max_length=100) event_type_choices = ( (1, u'硬件变更'), (2, u'新增配件'), (3, u'设备下线'), (4, u'设备上线'), (5, u'定期维护'), (6, u'业务上线\更新\变更'), (7, u'其它'), ) event_type = models.SmallIntegerField(u'事件类型', choices=event_type_choices) asset = models.ForeignKey('Asset') component = models.CharField('事件子项', max_length=255, blank=True, null=True) detail = models.TextField(u'事件详情') date = models.DateTimeField(u'事件时间', auto_now_add=True) user = models.ForeignKey('UserProfile', verbose_name=u'事件源') memo = models.TextField(u'备注', blank=True, null=True) def __str__(self): return self.name class Meta: verbose_name = '事件纪录' verbose_name_plural = "事件纪录" def colored_event_type(self): if self.event_type == 1: cell_html = '<span style="background: orange;">%s</span>' elif self.event_type == 2: cell_html = '<span style="background: yellowgreen;">%s</span>' else: cell_html = '<span >%s</span>' return cell_html % self.get_event_type_display() colored_event_type.allow_tags = True colored_event_type.short_description = u'事件类型' ''' 自定义后台 '''
作者:罗阿红
出处:http://www.cnblogs.com/luoahong/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。