CMDB项目(一)表结构设计

时间:2024-03-18 08:07:45

一:IT系统自动化规范:ITIL

ITIL(Information  Technology  Inftastrure  Library 信息技术架构库)。ITIL为企业的IT服务器管理提供了一个客观、严谨、可量化的标准和规范。

  • ITIL他只是一个规范,是指导IT企业建立自动化系统的一个指导思想。

ITIL分以下部分:

  • 事件管理(Incident Mangaement)

事故管理负责记录、归类和安排专业的技术人员处理事故并监督整个处理过程直至事故得到解决和终止。事故管理的目的是在尽可能最小的影响客户和用户业务的情况使IT系统恢复到服务级别协议所定义的服务级别。

理解:

  事故处理、监督、服务恢复的整套流程。

  • 问题管理(Problem Management)

问题管理是指通过调查和分析IT基础架构的薄弱环节、查明事故产生的潜在原因,并制定解决事故的方案和防止事故再次发生的措施,将由于问题和事故对业务产生的负面影响减小到最低的服务管理流程。与事故管理的强调事故恢复的速度不同,问题管理强调的是找出事故的根源,

从而制定恰当的解决方案或者防止再次发生的预防措施。

理解:

      事故分析单、分析事故原因、解决根源。不同于事件管理。

  • 配置管理:

      配置管理是识别和确认系统的配置项。记录和报告配置项状态和变更请求。检查配置项的正确性和完整性等活动构成的过程。其目的是提供IT基础机构的逻辑模型。支持其他的服务管理流程特别是变更管理和发布管理的运作。

理解:

  配置可以理解成硬件系统比如:硬盘、内存等。也可以是软件系统。

  • 变更管理(change management)

变更管理是指为最短的中断时间内完成基础架构或者服务在任一方面的变更而对其进行控制的服务管理流程。变更管理的目标是确保在变更的实施过程中使用标准的方法和步骤,尽快的实施变更,以将由变更导致的业务中断对业务的影响减小到最低。

理解:

     服务更新的中断时间最小化、或者硬件更换的时间最小化。

  • 发布管理:

发布管理是指对经过测试后导入实际应用的新增或修改后的配置项进行分发和宣传的管理流程。发布管理以前又称软件控制与分发。

理解:

    IT软件的发布,需要经过:编译、测试发布到实际的应用程序中。保证程序发布的准确性!

总结:

     以上是ITTL的规范,他指导我们构建健全的IT自动化系统的核心思想!cmdb:

 二:CMDB

个人理解:

  •  它是一个准确存储所有IT资产:包括软件和硬件的信息的数据库。
  • 它可以自动收集我们所需要的硬件信息和软件信息。并具有自动更新自己的硬件信息和软件信息。
  • 他可以为为其他自动化系统提供数据源API。

难点:

  • 既然是所有自动化系统的数据来源,那么他的数据的来源和更新需要准确。那如何保证准确?
  • 首先数据的录入和更新尽可能减少人工的干预。而是有一套标准的流程和程序来自动的更新和收集我们想要的信息。而不是简单的execl数据的导入,借用大王的话就是:只是将线下的excle表格转换成线上的大的execl‘表格’(database)。
  • 因为前期的数据导入可以通过execl表格 或者其他的途径,但是数据录入之后,我们要保证数据的实时更新,比如服务器的硬盘的扩充、内存的扩充等等。这些信息都需要更新cmdb中,只有这样cmdb保存的信息才使有效的,否则形同虚设!!

总结:

  • cmdb数据:保证来源的可靠性,和更新的准确性的前提下,才能保证各个系统之间调用的准确性。当然了,也不是说cmdb自己来维护自己的数据,也可以通过比如监控、发布系统等来共同校验来保持数据的准确性,也许这就是大王说的‘调和’。

cmdb需求:

    •存储所有IT资产信息
    •数据可手动添加
    •硬件信息可自动收集
    •硬件信息可自动变更
    •可对其它系统灵活开放API
    •API接口安全认证

 解释:

  • 存储所有的IT资产信息:包括硬件信息和软件信息。
  • 数据可手动添加:含义是因为我们的硬件有备件,所有这批设备的信息由于未联网无法进行程序的收集,所以有“数据可手动添加!”
  • 硬件信息可自动收集:保证硬件信息的准确性,通过客户端实时反馈管理的硬件设备信息。
  • 硬件信息可自动变更:保证硬件信息的变更的时候,客户端收集到的信息到服务端可以进行自动的比对,并更新数据库。
  • 可对其系统灵活开放API:因为cmdb的是其他ittl的系统的数据来源,所以需要提供相应的接口方便其他系统的调用!
  • API接口安全认证:防止非法的客户端收集信息或者非法的人为操作的调用,导致数据的混乱,需要提供api的安全认证。

 三:表结构设计

a:存储对象:

设计表结构之前,我们需要知道,我们数据库存储的对象都有哪些,对象的属性(字段)都有哪些?

如下是我们目前cmdb存储的对象:

            

知道了存储的对象,那我们需要存储对象哪些信息呢?

            

存储的对象的标准:易维护!

对于办公设备的,录入简单,维护难,所以不在我们存储的对象列表中。

表结构图:

 b:表结构内容

除了存储如上对象信息,还需要额外的一些内容:

  •     各种硬件都能存
  •     资产变更有纪录
  •     资产ID永不变
  •     资产要有状态机

资产会变更要有记录:哪些硬件发生变化,一需要更新数据库,还需要做变更记录,以方便以后查询和汇总。
资产ID永不变:资产ID是唯一值,它伴随对象‘一生’。

资产要有状态机:比如说:online和offline的状态,这种状态应该是‘动态’的,由其他系统(比如说监控)的来更改这个‘状态’,也就是说多系统联动。

c:接口规范:适用所有的app的API的规范.

  • 可对内外灵活开放接口
  • 接口定义要标准化
  • 一定要提供排错依据
  • 数据返回要标准
  • 要能增删改查
  • 所有异常要抓住
  • 接口安全要注意

接口标准化:接口的功能,规范化,比如统一提供:json接口或者xml接口,而不是随便写一个接口给别人,这样会导致接口的混乱。提高维护成本。

一定要提供排错依据:这个排错依据是给调用方提供的,当接口出问题的时候,需要给调用方返回相应的错误,这样减少我们平时工作负担。

数据返回要标准:接口返回的数据要么统一定义为:json或者xml。或者2者。

要能增删改查:我们提供的api可以提供增删改查的功能。

所有异常要抓住:程序出现问题的时候,异常和错误我们要有专门的记录比如:日志,方便我们更好进行排查问题。

接口安全要注意:并不是所有者都能对接口做增删改查操作,所以我们要接口的安全的认证!

 详细表结构:

资产(asset)明细表:

 
 1 class Asset(models.Model):
 2     \'\'\'
 3     资产表:具体描述一个资产对象的属性。比如说资产的类型、名字、IP、厂商等属性。
 4     \'\'\'
 5     asset_type_choices = (
 6         #资产类型选择。
 7         (\'server\', \'服务器\'),
 8         (\'networkdevice\', \'网络设备\'),
 9         (\'storagedevice\', \'存储设备\'),
10         (\'securitydevice\', \'安全设备\'),
11         (\'securitydevice\', \'机房设备\'),
12         # (\'switch\', \'交换机\'),
13         # (\'router\', \'路由器\'),
14         # (\'firewall\', \'防火墙\'),
15         # (\'storage\', \'存储设备\'),
16         # (\'NLB\', \'NetScaler\'),
17         # (\'wireless\', \'无线AP\'),
18         (\'software\', \'软件资产\'),
19         #(\'others\', \'其它类\'),
20     )
21     asset_type = models.CharField(choices=asset_type_choices,max_length=64, default=\'server\')#资产类型选择。默认是服务器
22     name = models.CharField(max_length=64,unique=True)#资产名字,区别于资产类型。是我们给该资产起的名字。比如服务器A等。并且是唯一的。
23     sn = models.CharField(\'资产SN号\',max_length=128, unique=True)#该资产的SN号,并且SN号是唯一的类似于uuid。
24     manufactory = models.ForeignKey(\'Manufactory\',verbose_name=\'制造商\',null=True, blank=True)#和Manufactory厂商表是一对多的关系,
25     #字段可以为空。
26     #model = models.ForeignKey(\'ProductModel\', verbose_name=u\'型号\')
27     #model = models.CharField(u\'型号\',max_length=128,null=True, blank=True )
28 
29     management_ip = models.GenericIPAddressField(\'管理IP\',blank=True,null=True)#记录的该资产的管理IP或者网卡IP。由自己决定存储哪方面IP。
30     
31     contract = models.ForeignKey(\'Contract\', verbose_name=\'合同\',null=True, blank=True)#该资产的合同信息,于表:contract是对一对多关系
32     #因为一个合同有可能购买一批相同的资产。合同字段可以为空。
33     trade_date = models.DateField(\'购买时间\',null=True, blank=True)#购买该资产的交易时间。可以为空。
34     expire_date = models.DateField(\'过保修期\',null=True, blank=True)#该资产的过保时间,字段可以为空。
35     price = models.FloatField(\'价格\',null=True, blank=True)#该资产的购买的价格,方便核实资产和折算资产。
36     business_unit = models.ForeignKey(\'BusinessUnit\', verbose_name=\'所属业务线\',null=True, blank=True)#关联的业务线。
37     #需要注意:这里建立的一对多的关系,这个是个坑,一台主机只能部署一个业务。不能部署多个业务。可以为空,如果是未分配机器。
38     tags = models.ManyToManyField(\'Tag\' ,blank=True)#标签:和标签表:tag是多对多关系,是为多维度记录该资产的用途。比如说:广告部门、redis服务器等等。
39     admin = models.ForeignKey(\'UserProfile\', verbose_name=\'资产管理员\',null=True, blank=True)#管理员:我理解是维护人员的,和表:userProfile是的一对多关系。
40     idc = models.ForeignKey(\'IDC\', verbose_name=\'IDC机房\',null=True, blank=True)#属于哪个idc机房,和表idc是一对多关系。可以为空(未分配机器)
41     
42     #status = models.ForeignKey(\'Status\', verbose_name = u\'设备状态\',default=1)#该设备状态和监控系统相关联:处于上线还是下线。
43     #Configuration = models.OneToOneField(\'Configuration\',verbose_name=\'配置管理\',blank=True,null=True)#和saltstack关联。
44 
45     memo = models.TextField(\'备注\', null=True, blank=True)#设备备注信息。
46     create_date = models.DateTimeField(blank=True, auto_now_add=True)#资产创建日期。
47     update_date = models.DateTimeField(blank=True, auto_now=True)#资产更新时间。
48     class Meta:
49         verbose_name = \'资产总表\'
50         verbose_name_plural = "资产总表"
51     def __str__(self):
52         return \'<id:%s name:%s>\' %(self.id,self.name )
 

服务器信息(server)表明细:

 
 1 class Server(models.Model):
 2     \'\'\'
 3     服务器信息表:存储服务器类型、raid卡类型,操作系统的类型等信息。
 4     因为硬盘和内存、cpu和服务器关系是一对多,而服务器是父表,所以在该表中未体现
 5     该信息。
 6     \'\'\'
 7     asset = models.OneToOneField(\'Asset\')#服务器和对应服务器的资产是一对一的关系。不可能出现一对多或者多对多关系。
 8     #因为一个服务器的资产信息只可能有一份。
 9     sub_assset_type_choices = (
10         (0,\'PC服务器\'),
11         (1,\'PC服务器\'),
12         (2,\'小型机\'),
13     )
14     created_by_choices = (
15         (\'auto\',\'Auto\'),
16         (\'manual\',\'Manual\'),
17     )
18     sub_asset_type = models.SmallIntegerField(choices=sub_assset_type_choices,verbose_name="服务器类型",default=0)
19     #服务器类型。不需要在创建一个表关联,choice字段就可以指定。因为只是单个字段而不是多个字段属性无需创建表。
20     created_by = models.CharField(choices=created_by_choices,max_length=32,default=\'auto\') #auto: auto created,   manual:created manually
21     #该字段是说明该服务器是手工录入还是自动录入,因为手工录入准确性比较低允许用户进行修改。而自动录入的准确率较高,在程序层面上不允许修改。
22     hosted_on = models.ForeignKey(\'self\',related_name=\'hosted_on_server\',blank=True,null=True) #for vitural server
23     #该字段是关联到该服务器的容器。对自己表建立foreignkey。
24 
25     #sn = models.CharField(u\'SN号\',max_length=128)
26     #management_ip = models.CharField(u\'管理IP\',max_length=64,blank=True,null=True)
27     #manufactory = models.ForeignKey(verbose_name=u\'制造商\',max_length=128,null=True, blank=True)
28     \'\'\'
29     sn management_ip manufactory 属于公用字段,所以保存在资产表asset中。
30     \'\'\'
31     model = models.CharField(verbose_name=u\'型号\',max_length=128,null=True, blank=True )
32     #服务器型号。
33     # 若有多个CPU,型号应该都是一致的,故没做ForeignKey
34     raid_type = models.CharField(\'raid类型\',max_length=512, blank=True,null=True)
35     #raid卡类型,每个服务器的raid卡的类型。
36 
37     #nic = models.ManyToManyField(\'NIC\', verbose_name=u\'网卡列表\')
38     #disk
39     #physical_disk_driver = models.ManyToManyField(\'Disk\', verbose_name=u\'硬盘\',blank=True,null=True)
40     #raid_adaptor = models.ManyToManyField(\'RaidAdaptor\', verbose_name=u\'Raid卡\',blank=True,null=True)
41     #memory
42     #ram_capacity = models.IntegerField(u\'内存总大小GB\',blank=True)
43     #ram = models.ManyToManyField(\'Memory\', verbose_name=u\'内存配置\',blank=True,null=True)
44     \'\'\'
45     网卡、硬盘、内存等和服务器关系是一对多的关系,而server表属于父表,所以foreignkey需要建立在disk、nic、memory表中。
46     所以server表中没记录。
47     \'\'\'
48 
49     os_type  = models.CharField(\'操作系统类型\',max_length=64, blank=True,null=True)
50     #操作系统的类型:比如:centos5、6、7等
51     os_distribution =models.CharField(\'发型版本\',max_length=64, blank=True,null=True)
52     #系统发行版本。
53     os_release  = models.CharField(\'操作系统版本\',max_length=64, blank=True,null=True)
54     #操作系统版本。
55 
56     class Meta:
57         verbose_name = \'服务器\'
58         verbose_name_plural = "服务器"
59         #together = ["sn", "asset"]
60 
61     def __str__(self):
62         return \'%s sn:%s\' %(self.asset.name,self.asset.sn)
 

 安全设备、网络设备、软件的表结构如下:

 
 1 class SecurityDevice(models.Model):
 2     \'\'\'
 3     安全设备信息表:存储是安全设备表,需要存储的信息,最好跟相应的维护人沟通。
 4     \'\'\'
 5     asset = models.OneToOneField(\'Asset\')
 6     #和资产表asset关系是一对一关系。
 7     sub_assset_type_choices = (
 8         (0,\'防火墙\'),
 9         (1,\'入侵检测设备\'),
10         (2,\'互联网网关\'),
11         (4,\'运维审计系统\'),
12     )
13     sub_asset_type = models.SmallIntegerField(choices=sub_assset_type_choices,verbose_name="服务器类型",default=0)
14     #设备类型。
15     def __str__(self):
16         return self.asset.id
17 
18 class NetworkDevice(models.Model):
19     \'\'\'
20     网络设备表:该表存储:vlanip、intranet_ip、型号等。
21     \'\'\'
22     asset = models.OneToOneField(\'Asset\')
23     #和资产表asset关系是一对一的关系。
24     sub_assset_type_choices = (
25         (0,\'路由器\'),
26         (1,\'交换机\'),
27         (2,\'负载均衡\'),
28         (4,\'VPN设备\'),
29     )
30     sub_asset_type = models.SmallIntegerField(choices=sub_assset_type_choices,verbose_name="服务器类型",default=0)
31     #网络设备的类型。
32     vlan_ip = models.GenericIPAddressField(\'VlanIP\',blank=True,null=True)
33     intranet_ip = models.GenericIPAddressField(\'内网IP\',blank=True,null=True)
34     #sn = models.CharField(u\'SN号\',max_length=128,unique=True)
35     #manufactory = models.CharField(verbose_name=u\'制造商\',max_length=128,null=True, blank=True)
36     \'\'\'
37     sn manufactory 存储到总表中。
38     \'\'\'
39     model = models.CharField(\'型号\',max_length=128,null=True, blank=True )
40     #型号。
41     firmware = models.CharField(blank=True,null=True)
42     #firmware = models.ForeignKey(\'Software\',blank=True,null=True)
43     #每个网络设备的固件应该和设备绑定在一起,而不是单独算作资产。
44     port_num = models.SmallIntegerField(\'端口个数\',null=True, blank=True )
45     #每个网络设备的端口数目。
46     device_detail = models.TextField(\'设置详细配置\',null=True, blank=True )
47     #每个设备的配置表。
48 
49     class Meta:
50         verbose_name = \'网络设备\'
51         verbose_name_plural = "网络设备"
52 
53 class Software(models.Model):
54     \'\'\'
55     only save software which company purchased
56     即只有话费一定的成本才叫做资产。
57     \'\'\'
58     os_types_choice = (
59         (0, \'OS\'),
60         (1, \'办公\开发软件\'),
61         (2, \'业务软件\'),
62 
63     )
64     license_num = models.IntegerField(verbose_name="授权数")
65     #授权码。
66     # os_distribution_choices = ((\'windows\',\'Windows\'),
67     #                            (\'centos\',\'CentOS\'),
68     #                            (\'ubuntu\', \'Ubuntu\'))
69     # type = models.CharField(u\'系统类型\', choices=os_types_choice, max_length=64,help_text=u\'eg. GNU/Linux\',default=1)
70     # distribution = models.CharField(u\'发型版本\', choices=os_distribution_choices,max_length=32,default=\'windows\')
71     version = models.CharField(\'软件/系统版本\', max_length=64, help_text=u\'eg. CentOS release 6.5 (Final)\', unique=True)
72     #软件版本。
73     # language_choices = ((\'cn\',u\'中文\'),
74     #                     (\'en\',u\'英文\'))
75     # language = models.CharField(u\'系统语言\',choices = language_choices, default=\'cn\',max_length=32)
76     # #version = models.CharField(u\'版本号\', max_length=64,help_text=u\'2.6.32-431.3.1.el6.x86_64\' )
77 
78     def __str__(self):
79         return self.version
80     class Meta:
81         verbose_name = \'软件/系统\'
82         verbose_name_plural = "软件/系统"
 

 

网卡、硬盘、内存、cpu表结构:

注意:内存、硬盘、cpu是关联服务器表(server)还是关联资产(asset)表呢?

咱们做一个假设:

硬盘、网卡、cpu、内存关联到服务器(server)上,会出现如下情景:

  • 1、网络设备有网卡和服务器有网卡,如果我们建立一个网卡表的话,我们需要建立2张网卡表,分别关联到网络设备和服务器上。但是这2张表存储属性字段是一样的。这就造成2张表存储字段一样,造成在增删改查网络设备的网卡和服务器网卡的设备的时候,加大难度。
  • 那怎么让网络设备和服务器公用一个网卡表?关联到asset表,通过关联资产和服务器资产一对多的关系来共享一张表(网卡表)
  • 所以网卡、硬盘、cpu不能关联到服务器上。因为网卡、cpu、内存不能单独做为一个资产,因为他们属于服务器资产的一部分或者网络设备的资产的一部分。所以将他们关联到asset表上。
  • 2、还有硬盘和内存为什么还要关联asset这不仅仅因为是存储设备的资产类型 更多是为了调用接口方式的统一!!!
  • 3、因为一个服务器有多个网卡、内存、硬盘所以关联到服务器资产的时候,是一对多的关系!但是需要注意的是cpu问题,因为不同型号的cpu不能再同一个服务器上运行,所以cpu和asset表的关系是onetoone的关系。
  • 4、还有在不同的子表中,子表和父表可以建立OneToOne和Foreignkey关系。在同一张子表不可以这么做。所以server和asset表建立一对一关系,内存、硬盘等建立一对多关系!
  • 5、还有硬盘、内存、cpu的sn并不能收搜集到,所以该字段不是唯一,否则在录入数据的时候需要做很多麻烦。
  • 6、需要注意:一条业务线对应n台主机,而一台主机只能部署一条业务线。

详细表结构:

 
  1 class CPU(models.Model):
  2     \'\'\'
  3     存储cpu表:因为服务器上cpu的型号是必须一致,否则运行不了,所以和服务器对应的资产表是一对一关系。
  4     \'\'\'
  5 
  6     asset = models.OneToOneField(\'Asset\')#必须和服务器资产是一对一的关系。
  7     cpu_model = models.CharField(\'CPU型号\', max_length=128,blank=True)
  8     #cpu型号。
  9     cpu_count = models.SmallIntegerField(\'物理cpu个数\')
 10     #物理cpu的数量。
 11     cpu_core_count = models.SmallIntegerField(\'cpu核数\')
 12     #cpu的核数。
 13     memo = models.TextField(\'备注\', null=True,blank=True)
 14     #备注
 15     create_date = models.DateTimeField(auto_now_add=True)
 16     #数据创建日期。
 17     update_date = models.DateTimeField(blank=True,null=True)
 18     #cpu配件更新日期。
 19     class Meta:
 20         verbose_name = \'CPU部件\'
 21         verbose_name_plural = "CPU部件"
 22     def __str__(self):
 23         return self.cpu_model
 24 
 25 class RAM(models.Model):
 26     \'\'\'
 27     存储内存表。
 28     \'\'\'
 29     asset = models.ForeignKey(\'Asset\')#和服务器资产表是一对多的关系。
 30     sn = models.CharField(\'SN号\', max_length=128, blank=True,null=True)
 31     #sn号,但并不唯一。
 32     model =  models.CharField(\'内存型号\', max_length=128)
 33     #内存型号。
 34     slot = models.CharField(\'插槽\', max_length=64)
 35     #内存插槽。
 36     capacity = models.IntegerField(u\'内存大小(MB)\')
 37     #内存大小单位M
 38     memo = models.CharField(\'备注\',max_length=128, blank=True,null=True)
 39     #备注。
 40     create_date = models.DateTimeField(blank=True, auto_now_add=True)
 41     #创建日期。但不一定是服务器使用该内存的日期。
 42     update_date = models.DateTimeField(blank=True,null=True)
 43     #更新内存配件日期。
 44     def __str__(self):
 45         return \'%s:%s:%s\' % (self.asset_id,self.slot,self.capacity)
 46     class Meta:
 47         verbose_name = \'RAM\'
 48         verbose_name_plural = "RAM"
 49         unique_together = ("asset", "slot")
 50         \'\'\'
 51         怎么确定一个内存是唯一呢?因为搜集的SN的号有时候搜集不到,所以没定义SN为唯一。我们只能通过插槽和对应的服务器来确定内存的。
 52         所以和服务器资产和插槽做联合唯一。
 53         \'\'\'
 54     auto_create_fields = [\'sn\',\'slot\',\'model\',\'capacity\']
 55 
 56 class Disk(models.Model):
 57     \'\'\'
 58     硬盘储存表。
 59     \'\'\'
 60     asset = models.ForeignKey(\'Asset\')#和服务器资产表关系一对多。
 61     sn = models.CharField(\'SN号\', max_length=128, blank=True,null=True)
 62     \'\'\'
 63     硬盘的sn号有时候抓不到。所以不唯一。
 64     \'\'\'
 65     slot = models.CharField(\'插槽位\',max_length=64)
 66     #硬盘插槽字段。
 67     #manufactory = models.CharField(u\'制造商\', max_length=64,blank=True,null=True)
 68     model = models.CharField(\'磁盘型号\', max_length=128,blank=True,null=True)
 69     #硬盘型号。
 70     capacity = models.FloatField(\'磁盘容量GB\')
 71     #硬盘容量。
 72     disk_iface_choice = (#硬盘接口类型。
 73         (\'SATA\', \'SATA\'),
 74         (\'SAS\', \'SAS\'),
 75         (\'SCSI\', \'SCSI\'),
 76         (\'SSD\', \'SSD\'),
 77     )
 78 
 79     iface_type = models.CharField(\'接口类型\', max_length=64,choices=disk_iface_choice,default=\'SAS\')#硬盘接口类型。
 80     memo = models.TextField(\'备注\', blank=True,null=True)#备注。
 81     create_date = models.DateTimeField(blank=True, auto_now_add=True)#创建日期。
 82     update_date = models.DateTimeField(blank=True,null=True)#硬盘更新日期。
 83 
 84     auto_create_fields = [\'sn\',\'slot\',\'manufactory\',\'model\',\'capacity\',\'iface_type\']
 85     class Meta:
 86         unique_together = ("asset", "slot")
 87         verbose_name = \'硬盘\'
 88         verbose_name_plural = "硬盘"
 89     def __str__(self):
 90         return \'%s:slot:%s capacity:%s\' % (self.asset_id,self.slot,self.capacity)
 91 
 92 
 93 class NIC(models.Model):
 94     \'\'\'
 95     网卡存储表。
 96     \'\'\'
 97     asset = models.ForeignKey(\'Asset\')#网卡和对应设备资产的关系是一对多的关系。
 98     name = models.CharField(\'网卡名\', max_length=64, blank=True,null=True)#网卡的名字。
 99     sn = models.CharField(\'SN号\', max_length=128, blank=True,null=True)#网卡的sn,有时候并不能抓大信息
100     model =  models.CharField(\'网卡型号\', max_length=128, blank=True,null=True)#网卡型号。
101     macaddress = models.CharField(u\'MAC\', max_length=64,unique=True)#MAC地址,需要注意这个字段是唯一的。
102     ipaddress = models.GenericIPAddressField(\'IP\', blank=True,null=True)#网卡的ip 因为一个服务器上的网卡不一定有IP,还有vip情况,所以不是唯一。可为空。
103     netmask = models.CharField(max_length=64,blank=True,null=True)#网卡的子网掩码。
104     bonding = models.CharField(max_length=64,blank=True,null=True)#绑定IP
105     memo = models.CharField(\'备注\',max_length=128, blank=True,null=True)#网卡的备注信息。
106     create_date = models.DateTimeField(blank=True, auto_now_add=True)#数据的创建日期。
107     update_date = models.DateTimeField(blank=True,null=True)#网卡更新的时间。
108 
109     def __str__(self):
110         return \'%s:%s\' % (self.asset_id,self.macaddress)
111     class Meta:
112         verbose_name = u\'网卡\'
113         verbose_name_plural = u"网卡"
114         #unique_together = ("asset_id", "slot")
115         unique_together = ("asset", "macaddress")#通过mac地址和服务器资产的来唯一确认网卡的唯一。
116     auto_create_fields = [\'name\',\'sn\',\'model\',\'macaddress\',\'ipaddress\',\'netmask\',\'bonding\']
117 
118 class RaidAdaptor(models.Model):
119     \'\'\'
120     RAID的卡存储表。一个服务器上可以有多个raid卡。
121     \'\'\'
122     asset = models.ForeignKey(\'Asset\')#和服务器资产关系式多对一的关系。
123     sn = models.CharField(\'SN号\', max_length=128, blank=True,null=True)#不是唯一的,因为有些sn号收集不到。
124     slot = models.CharField(\'插口\',max_length=64)#raid卡插口。
125     model = models.CharField(\'型号\', max_length=64,blank=True,null=True)#raid卡型号。
126     memo = models.TextField(\'备注\', blank=True,null=True)#raid卡备注。
127     create_date = models.DateTimeField(blank=True, auto_now_add=True)#数据创建日期。
128     update_date = models.DateTimeField(blank=True,null=True)#raid卡更新日期。
129 
130     def __str__(self):
131         return self.name
132     class Meta:
133         unique_together = ("asset", "slot")##通过插槽和服务器资产来唯一确定raid卡的唯一。
134 
135 class Manufactory(models.Model):
136     \'\'\'
137     厂商存储表。
138     \'\'\'
139     manufactory = models.CharField(\'厂商名称\',max_length=64, unique=True)#厂商名称存字段。
140     support_num = models.CharField(\'支持电话\',max_length=30,blank=True)#厂商电话。
141     memo = models.CharField(\'备注\',max_length=128,blank=True)#厂商备注。
142     def __str__(self):
143         return self.manufactory
144     class Meta:
145         verbose_name = \'厂商\'
146         verbose_name_plural = "厂商"
147 
148 
149 class BusinessUnit(models.Model):
150     \'\'\'
151     业务线存储表。
152     \'\'\'
153     parent_unit = models.ForeignKey(\'self\',related_name=\'parent_level\',blank=True,null=True)
154     #自关联,当一个业务线有子业务线的时候,需要跟自身做foreignkey。
155     name = models.CharField(\'业务线\',max_length=64, unique=True)
156     #业务线名字。
157     #contact = models.ForeignKey(\'UserProfile\',default=None)
158     memo = models.CharField(\'备注\',max_length=64, blank=True)#业务线的备注。
159     def __str__(self):
160         return self.name
161     class Meta:
162         verbose_name = \'业务线\'
163         verbose_name_plural = "业务线"
 

其他表:合同、idc、标签、备件等。

 
  1 class Contract(models.Model):
  2     \'\'\'
  3     存储合同表。
  4     \'\'\'
  5     sn = models.CharField(\'合同号\', max_length=128,unique=True)#合同号。
  6     name = models.CharField(\'合同名称\', max_length=64 )#合同名称。
  7     memo = models.TextField(\'备注\', blank=True,null=True)#备注。
  8     price = models.IntegerField(\'合同金额\')#合同金额。
  9     detail = models.TextField(\'合同详细\',blank=True,null=True)
 10     start_date = models.DateField(blank=True)#合同生效期
 11     end_date = models.DateField(blank=True)#合同失效日期。
 12     license_num = models.IntegerField(\'license数量\',blank=True)#证书数量。
 13     create_date = models.DateField(auto_now_add=True)#合同录入日期。
 14     update_date= models.DateField(auto_now=True)#合同更新日期。
 15     class Meta:
 16         verbose_name = \'合同\'
 17         verbose_name_plural = "合同"
 18     def __str__(self):
 19         return self.name
 20 
 21 class IDC(models.Model):
 22     \'\'\'
 23     存储机房表。
 24     \'\'\'
 25     name = models.CharField(\'机房名称\',max_length=64,unique=True)#机房名称,是唯一的。
 26     memo = models.CharField(\'备注\',max_length=128,blank=True,null=True)#机房备注。
 27     def __str__(self):
 28         return self.name
 29     class Meta:
 30         verbose_name = \'机房\'
 31         verbose_name_plural = "机房"
 32 
 33 
 34 class Tag(models.Model):
 35     \'\'\'
 36     资产标签,可以给每个资产定义不同的名臣的,方便我们多维度去查询机器。
 37     \'\'\'
 38     name = models.CharField(\'Tag name\',max_length=32,unique=True )#标签的名字是唯一的。
 39     creater = models.ForeignKey(\'UserProfile\')#打标签的人。
 40     create_date = models.DateField(auto_now_add=True)#标签创建时间。
 41     def __str__(self):
 42         return self.name
 43 
 44 class EventLog(models.Model):
 45     \'\'\'
 46     时间变更日志存储的表。
 47     \'\'\'
 48     name = models.CharField(u\'事件名称\', max_length=100)#事件名称。
 49     event_type_choices = (
 50         (1,u\'硬件变更\'),
 51         (2,u\'新增配件\'),
 52         (3,u\'设备下线\'),
 53         (4,u\'设备上线\'),
 54         (5,u\'定期维护\'),
 55         (6,u\'业务上线\更新\变更\'),
 56         (7,u\'其它\'),
 57     )
 58     event_type = models.SmallIntegerField(u\'事件类型\', choices= event_type_choices)#事件类型。
 59     asset = models.ForeignKey(\'Asset\')#和资产的关系式一对多的关系。
 60     component = models.CharField(\'事件子项\',max_length=255, blank=True,null=True)#时间子项,比如说:一个服务器的网卡变更操作,叫做子项。
 61     detail = models.TextField(u\'事件详情\')#时间的内容。
 62     date = models.DateTimeField(u\'事件时间\',auto_now_add=True)#事件产生的日期。
 63     user = models.ForeignKey(\'UserProfile\',verbose_name=u\'事件源\')#事件的发起者。
 64     memo = models.TextField(u\'备注\', blank=True,null=True)#事件备注。
 65 
 66     def __str__(self):
 67         return self.name
 68     class Meta:
 69         verbose_name = \'事件纪录\'
 70         verbose_name_plural = "事件纪录"
 71 
 72 
 73     def colored_event_type(self):
 74         if self.event_type == 1:
 75             cell_html = \'<span style="background: orange;">%s</span>\'
 76         elif self.event_type == 2 :
 77             cell_html = \'<span style="background: yellowgreen;">%s</span>\'
 78         else:
 79             cell_html = \'<span >%s</span>\'
 80         return cell_html % self.get_event_type_display()
 81     colored_event_type.allow_tags = True
 82     colored_event_type.short_description = u\'事件类型\'
 83 
 84 
 85 class NewAssetApprovalZone(models.Model):
 86     \'\'\'
 87     备件储存表。
 88     \'\'\'
 89     sn = models.CharField(u\'资产SN号\',max_length=128, unique=True)#备件名称。是唯一的。
 90     asset_type_choices = (
 91         (\'server\', u\'服务器\'),
 92         (\'switch\', u\'交换机\'),
 93         (\'router\', u\'路由器\'),
 94         (\'firewall\', u\'防火墙\'),
 95         (\'storage\', u\'存储设备\'),
 96         (\'NLB\', u\'NetScaler\'),
 97         (\'wireless\', u\'无线AP\'),
 98         (\'software\', u\'软件资产\'),
 99         (\'others\', u\'其它类\'),
100     )
101     asset_type = models.CharField(choices=asset_type_choices,max_length=64,blank=True,null=True)#备件类型。
102     manufactory = models.CharField(max_length=64,blank=True,null=True)#备件厂商。
103     model = models.CharField(max_length=128,blank=True,null=True)#备件类型。
104     ram_size = models.IntegerField(blank=True,null=True)#备件内存大小。
105     cpu_model = models.CharField(max_length=128,blank=True,null=True)#备件cpu型号。
106     cpu_count = models.IntegerField(blank=True,null=True)#备件物理cpu个数。
107     cpu_core_count = models.IntegerField(blank=True,null=True)#备件cpu核数。
108     os_distribution =  models.CharField(max_length=64,blank=True,null=True)#系统版本
109     os_type =  models.CharField(max_length=64,blank=True,null=True)#系统类型。
110     os_release =  models.CharField(max_length=64,blank=True,null=True)#系统发行版本。
111     data = models.TextField(\'资产数据\')#资产数据。
112     date = models.DateTimeField(\'汇报日期\',auto_now_add=True)#资产录入日期。
113     approved = models.BooleanField(u\'已批准\',default=False)#资产审批状态。
114     approved_by = models.ForeignKey(\'UserProfile\',verbose_name=u\'批准人\',blank=True,null=True)#批准人,
115     approved_date = models.DateTimeField(u\'批准日期\',blank=True,null=True)#批准日期。
116 
117     def __str__(self):
118         return self.sn
119     class Meta:
120         verbose_name = \'新上线待批准资产\'
121         verbose_name_plural = "新上线待批准资产"
 

 用户表:

 
 1 class UserProfile(User):
 2     \'\'\'
 3     管理员表。继承User类。使用django的用户认证。
 4     \'\'\'
 5     name = models.CharField("姓名",max_length=32)#用户名。
 6 
 7     def __str__(self):
 8         return self.name
 9     class Meta:
10         super(User.Meta)
11         verbose_name = \'用户\'
12         verbose_name_plural = "用户"