python之CMDB

浅谈ITIL

TIL即IT基础架构库(Information Technology Infrastructure Library, ITIL,信息技术基础架构库)由英国政府部门CCTA(Central Computing and Telecommunications Agency)在20世纪80年代末制订,现由英国商务部OGC(Office of Government Commerce)负责管理,主要适用于IT服务管理(ITSM)。ITIL为企业的IT服务管理实践提供了一个客观、严谨、可量化的标准和规范。

1、事件管理(Incident Management)

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

2、问题管理(Problem Management)

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

3、配置管理(Configuration Management)

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

4、变更管理(Change Management)

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

5、发布管理(Release Management)

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

事件管理的目标是在不影响业务的情况下,尽可能快速的恢复服务,从而保证最佳的效率和服务的可持续性。事件管理流程的建立包括事件分类,确定事件的优先级和建立事件的升级机制。

问题管理是调查基础设施和所有可用信息,包括事件数据库,来确定引起事件发生的真正潜在原因,一起提供的服务中可能存在的故障。

配置管理的目标是:定义和控制服务与基础设施的部件,并保持准确的配置信息。

变更管理的目标是:以受控的方式,确保所有变更得到评估、批准、实施和评审。

发布管理的目标是:在实际运行环境的发布中,交付、分发并跟踪一个或多个变更。

服务台:服务台是IT部门和IT服务用户之间的单一联系点。它通过提供一个集中和专职的服务联系点促进了组织业务流程与服务管理基础架构集成。服务台的主要目标是协调客户(用户)和IT部门之间的联系,为IT服务运作提供支持,从而提高客户的满意度。

CMDB介绍

CMDB --Configuration Management Database 配置管理数据库, CMDB存储与管理企业IT架构中设备的各种配置信息,它与所有服务支持和服务交付流程都紧密相联,支持这些流程的运转、发挥配置信息的价值,同时依赖于相关流程保证数据的准确性。

在实际的项目中,CMDB常常被认为是构建其它ITIL流程的基础而优先考虑,ITIL项目的成败与是否成功建立CMDB有非常大的关系。
70%~80%的IT相关问题与环境的变更有着直接的关系。实施变更管理的难点和重点并不是工具,而是流程。即通过一个自动化的、可重复的流程管理变更,使得当变更发生的时候,有一个标准化的流程去执行,能够预测到这个变更对整个系统管理产生的影响,并对这些影响进行评估和控制。而变更管理流程自动化的实现关键就是CMDB。
CMDB工具中至少包含这几种关键的功能:整合、调和、同步、映射和可视化。
  • 整合是指能够充分利用来自其他数据源的信息,对CMDB中包含的记录源属性进行存取,将多个数据源合并至一个视图中,生成连同来自CMDB和其他数据源信息在内的报告;
  • 调和能力是指通过对来自每个数据源的匹配字段进行对比,保证CMDB中的记录在多个数据源中没有重复现象,维持CMDB中每个配置项目数据源的完整性;自动调整流程使得初始实施、数据库管理员的手动运作和现场维护支持工作降至最低;
  • 同步指确保CMDB中的信息能够反映联合数据源的更新情况,在联合数据源更新频率的基础上确定CMDB更新日程,按照经过批准的变更来更新 CMDB,找出未被批准的变更;
  • 应用映射与可视化,说明应用间的关系并反应应用和其他组件之间的依存关系,了解变更造成的影响并帮助诊断问题。

CMDB 资产管理部分实现 

需求

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

立业之本:定义表结构

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

重中之重:接口设计好 

  • 可对内外灵活开放接口
  • 接口定义要标准化
  • 一定要提供排错依据
  • 数据返回要标准
  • 要能增删改查
  • 所有异常要抓住
  • 接口安全要注意
  1 # -*- coding:utf-8 -*-
  2 from django.db import models
  3 from Wolf.models import UserProfile
  4 # Create your models here.
  5 
  6 class Asset(models.Model):
  7     asset_type_choices = (
  8         ('server', u'服务器'),
  9         ('switch', u'交换机'),
 10         ('router', u'路由器'),
 11         ('firewall', u'防火墙'),
 12         ('storage', u'存储设备'),
 13         ('NLB', u'负载均衡'),
 14         ('wireless', u'无线AP'),
 15         ('software', u'软件资产'),
 16         ('others', u'其它类'),
 17     )
 18     asset_type = models.CharField(u'资产类型', choices=asset_type_choices,max_length=64, default='server')
 19     name = models.CharField(u'名字', max_length=64, unique=True)
 20     sn = models.CharField(u'资产SN号', max_length=128, unique=True)
 21     manufactory = models.ForeignKey('Manufactory', verbose_name=u'制造商', null=True, blank=True)
 22     #model = models.ForeignKey('ProductModel', verbose_name=u'型号')
 23     management_ip = models.GenericIPAddressField(u'管理IP', blank=True, null=True)
 24 
 25     contract = models.ForeignKey('Contract', verbose_name=u'合同', null=True, blank=True)
 26     trade_date = models.DateField(u'购买时间', null=True, blank=True)
 27     expire_date = models.DateField(u'过保修期', null=True, blank=True)
 28     price = models.FloatField(u'价格',null=True, blank=True)
 29     business_unit = models.ForeignKey('BusinessUnit', verbose_name=u'所属业务线', null=True, blank=True)
 30     tags = models.ManyToManyField('Tag', verbose_name=u'标签', blank=True)
 31     admin = models.ForeignKey(UserProfile, verbose_name=u'资产管理员', null=True, blank=True)
 32     idc = models.ForeignKey('IDC', verbose_name=u'IDC机房', null=True, blank=True)
 33 
 34     #status = models.ForeignKey('Status', verbose_name = u'设备状态',default=1)
 35     #Configuration = models.OneToOneField('Configuration',verbose_name='配置管理',blank=True,null=True)
 36 
 37     memo = models.TextField(u'备注', null=True, blank=True)
 38     create_date = models.DateTimeField(blank=True, auto_now_add=True)
 39     update_date = models.DateTimeField(blank=True, auto_now=True)
 40 
 41     class Meta:
 42         verbose_name = '资产总表'
 43         verbose_name_plural = "资产总表"
 44 
 45     def __str__(self):
 46         return 'id:%s name:%s'  % (self.id,self.name )
 47 
 48 class Server(models.Model):
 49     # server关联asset,反向关联,对于资产来说,是一对多关系
 50     asset = models.OneToOneField('Asset',verbose_name=u'资产')
 51     created_by_choices = (
 52         ('auto', 'Auto'),
 53         ('manual', 'Manual'),
 54     )
 55     created_by = models.CharField(choices=created_by_choices,max_length=32,
 56                                   verbose_name=u'添加类型',default='auto') #auto: auto created,   manual:created manually
 57     hosted_on = models.ForeignKey('self',related_name='hosted_on_server',blank=True,null=True) #for vitural server
 58     #sn = models.CharField(u'SN号',max_length=128)
 59     #management_ip = models.CharField(u'管理IP',max_length=64,blank=True,null=True)
 60     #manufactory = models.ForeignKey(verbose_name=u'制造商',max_length=128,null=True, blank=True)
 61     model = models.CharField(u'型号',max_length=128,null=True, blank=True )
 62     # 若有多个CPU,型号应该都是一致的,故没做ForeignKey
 63 
 64     #nic = models.ManyToManyField('NIC', verbose_name=u'网卡列表')
 65     #disk
 66     raid_type = models.CharField(u'raid类型',max_length=512, blank=True,null=True)
 67     #physical_disk_driver = models.ManyToManyField('Disk', verbose_name=u'硬盘',blank=True,null=True)
 68     #raid_adaptor = models.ManyToManyField('RaidAdaptor', verbose_name=u'Raid卡',blank=True,null=True)
 69     #memory
 70     #ram_capacity = models.IntegerField(u'内存总大小GB',blank=True)
 71     #ram = models.ManyToManyField('Memory', verbose_name=u'内存配置',blank=True,null=True)
 72 
 73     os_type = models.CharField(u'操作系统类型',max_length=64, blank=True,null=True)
 74     os_distribution =models.CharField(u'发型版本',max_length=64, blank=True,null=True)
 75     os_release  = models.CharField(u'操作系统版本',max_length=64, blank=True,null=True)
 76 
 77     create_date = models.DateTimeField(verbose_name=u'创建日期', blank=True, auto_now_add=True)
 78     update_date = models.DateTimeField(verbose_name=u'更新日期', blank=True,null=True)
 79     class Meta:
 80         verbose_name = '服务器'
 81         verbose_name_plural = "服务器"
 82         #together = ["sn", "asset"]
 83 
 84     def __str__(self):
 85         return '%s sn:%s' %(self.asset.name,self.asset.sn)
 86 
 87 
 88 class NetworkDevice(models.Model):
 89     asset = models.OneToOneField('Asset')
 90     vlan_ip = models.GenericIPAddressField(u'VlanIP',blank=True,null=True)
 91     intranet_ip = models.GenericIPAddressField(u'内网IP',blank=True,null=True)
 92     sn = models.CharField(u'SN号',max_length=128,unique=True)
 93     #manufactory = models.CharField(verbose_name=u'制造商',max_length=128,null=True, blank=True)
 94     model = models.CharField(u'型号',max_length=128,null=True, blank=True )
 95     firmware = models.ForeignKey('Software',blank=True,null=True)
 96     port_num = models.SmallIntegerField(u'端口个数',null=True, blank=True )
 97     device_detail = models.TextField(u'设置详细配置',null=True, blank=True )
 98     create_date = models.DateTimeField(verbose_name=u'创建日期',auto_now_add=True)
 99     update_date = models.DateTimeField(verbose_name=u'更新日期',blank=True,null=True)
100 
101     class Meta:
102         verbose_name = '网络设备'
103         verbose_name_plural = "网络设备"
104 
105 class Software(models.Model):
106     #sn = models.CharField(u'SN号',max_length=64, unique=True)
107     os_types_choice = (
108         ('linux', 'Linux'),
109         ('windows', 'Windows'),
110         ('network_firmware', 'Network Firmware'),
111         ('software', 'Softwares'),
112     )
113     os_distribution_choices = (('windows','Windows'),
114                                ('centos','CentOS'),
115                                ('ubuntu', 'Ubuntu'))
116     type = models.CharField(u'软件类型', choices=os_types_choice, max_length=64,help_text=u'eg. GNU/Linux',default=1)
117     distribution = models.CharField(u'发型版本', choices=os_distribution_choices,max_length=32,default='windows')
118     version = models.CharField(u'软件/系统版本', max_length=64, help_text=u'eg. CentOS release 6.5 (Final)', unique=True)
119     language_choices = (('cn',u'中文'),
120                         ('en',u'英文'))
121     language = models.CharField(u'系统语言',choices = language_choices, default='cn',max_length=32)
122     #version = models.CharField(u'版本号', max_length=64,help_text=u'2.6.32-431.3.1.el6.x86_64' )
123 
124     class Meta:
125         verbose_name = '软件/系统'
126         verbose_name_plural = "软件/系统"
127 
128     def __str__(self):
129         return self.version
130 
131 class CPU(models.Model):
132     asset = models.OneToOneField('Asset', verbose_name=u'资产')
133     cpu_model = models.CharField(u'CPU型号', max_length=128, blank=True)
134     cpu_count = models.SmallIntegerField(u'物理cpu个数')
135     cpu_core_count = models.SmallIntegerField(u'cpu核数')
136     memo = models.TextField(u'备注', null=True,blank=True)
137     create_date = models.DateTimeField(verbose_name=u'创建日期',auto_now_add=True)
138     update_date = models.DateTimeField(verbose_name=u'更新日期',blank=True,null=True)
139 
140     class Meta:
141         verbose_name = 'CPU部件'
142         verbose_name_plural = "CPU部件"
143 
144     def __str__(self):
145         return self.cpu_model
146 
147 class RAM(models.Model):
148     asset = models.ForeignKey('Asset', verbose_name=u'资产')  # 各个模块都当做asset的一个部件处理
149     sn = models.CharField(u'SN号', max_length=128, blank=True,null=True)
150     model =  models.CharField(u'内存型号', max_length=128)
151     slot = models.CharField(u'插槽', max_length=64)
152     capacity = models.IntegerField(u'内存大小(MB)')
153     memo = models.CharField(u'备注',max_length=128, blank=True,null=True)
154     create_date = models.DateTimeField(verbose_name=u'创建日期',blank=True, auto_now_add=True)
155     update_date = models.DateTimeField(verbose_name=u'更新日期',blank=True,null=True)
156 
157     class Meta:
158         verbose_name = 'RAM'
159         verbose_name_plural = "RAM"
160         unique_together = ("asset", "slot")
161     auto_create_fields = ['sn','slot','model','capacity']
162 
163     def __str__(self):
164         return '%s:%s:%s' % (self.asset_id, self.slot, self.capacity)
165 
166 class Disk(models.Model):
167     asset = models.ForeignKey('Asset')
168     sn = models.CharField(u'SN号', max_length=128, blank=True,null=True)
169     slot = models.CharField(u'插槽位',max_length=64)
170     manufactory = models.CharField(u'制造商', max_length=64,blank=True,null=True)
171     model = models.CharField(u'磁盘型号', max_length=128,blank=True,null=True)
172     capacity = models.FloatField(u'磁盘容量GB')
173     disk_iface_choice = (
174         ('SATA', 'SATA'),
175         ('SAS', 'SAS'),
176         ('SCSI', 'SCSI'),
177         ('SSD', 'SSD'),
178     )
179 
180     iface_type = models.CharField(u'接口类型', max_length=64,choices=disk_iface_choice,default='SAS')
181     memo = models.TextField(u'备注', blank=True,null=True)
182     create_date = models.DateTimeField(verbose_name=u'创建日期',blank=True, auto_now_add=True)
183     update_date = models.DateTimeField(verbose_name=u'更新日期',blank=True,null=True)
184 
185     auto_create_fields = ['sn','slot','manufactory','model','capacity','iface_type']
186 
187     class Meta:
188         unique_together = ("asset", "slot")
189         verbose_name = '硬盘'
190         verbose_name_plural = "硬盘"
191 
192     def __str__(self):
193         return '%s:slot:%s capacity:%s' % (self.asset_id,self.slot,self.capacity)
194 
195 class NIC(models.Model):
196     asset = models.ForeignKey('Asset')
197     name = models.CharField(u'网卡名', max_length=64, blank=True,null=True)
198     sn = models.CharField(u'SN号', max_length=128, blank=True,null=True)
199     model =  models.CharField(u'网卡型号', max_length=128, blank=True,null=True)
200     macaddress = models.CharField(u'MAC', max_length=64,unique=True)
201     ipaddress = models.GenericIPAddressField(u'IP', blank=True,null=True)
202     netmask = models.CharField(u'掩码',max_length=64,blank=True,null=True)
203     bonding = models.CharField(u'绑定',max_length=64,blank=True,null=True)
204     memo = models.CharField(u'备注',max_length=128, blank=True,null=True)
205     create_date = models.DateTimeField(verbose_name=u'创建日期',blank=True, auto_now_add=True)
206     update_date = models.DateTimeField(verbose_name=u'更新日期',blank=True,null=True)
207 
208     class Meta:
209         verbose_name = u'网卡'
210         verbose_name_plural = u"网卡"
211         #unique_together = ("asset_id", "slot")
212     auto_create_fields = ['name','sn','model','macaddress','ipaddress','netmask','bonding']
213 
214     def __str__(self):
215         return '%s:%s' % (self.asset_id, self.macaddress)
216 
217 class RaidAdaptor(models.Model):
218     asset = models.ForeignKey('Asset')
219     sn = models.CharField(u'SN号', max_length=128, blank=True,null=True)
220     slot = models.CharField(u'插口',max_length=64)
221     model = models.CharField(u'型号', max_length=64,blank=True,null=True)
222     memo = models.TextField(u'备注', blank=True,null=True)
223     create_date = models.DateTimeField(verbose_name=u'创建日期',blank=True, auto_now_add=True)
224     update_date = models.DateTimeField(verbose_name=u'更新日期',blank=True,null=True)
225 
226     class Meta:
227         unique_together = ("asset", "slot")
228 
229     def __str__(self):
230         return self.name
231 
232 class Manufactory(models.Model):
233     manufactory = models.CharField(u'厂商名称',max_length=64, unique=True)
234     support_num = models.CharField(u'支持电话',max_length=30,blank=True)
235     memo = models.CharField(u'备注',max_length=128,blank=True)
236 
237     class Meta:
238         verbose_name = '厂商'
239         verbose_name_plural = "厂商"
240 
241     def __str__(self):
242         return self.manufactory
243 
244 class BusinessUnit(models.Model):
245     parent_unit = models.ForeignKey('self',related_name='parent_level',blank=True,null=True)
246     name = models.CharField(u'业务线',max_length=64, unique=True)
247 
248     #contact = models.ForeignKey(UserProfile,default=None)
249     memo = models.CharField(u'备注',max_length=64, blank=True)
250 
251     class Meta:
252         verbose_name = '业务线'
253         verbose_name_plural = "业务线"
254 
255     def __str__(self):
256         return self.name
257 
258 class Contract(models.Model):
259     sn = models.CharField(u'合同号', max_length=128,unique=True)
260     name = models.CharField(u'合同名称', max_length=64 )
261     memo = models.TextField(u'备注', blank=True,null=True)
262     price = models.IntegerField(u'合同金额')
263     detail = models.TextField(u'合同详细',blank=True,null=True)
264     start_date = models.DateField(blank=True)
265     end_date = models.DateField(blank=True)
266     license_num = models.IntegerField(u'license数量',blank=True)
267     create_date = models.DateField(verbose_name=u'创建日期',auto_now_add=True)
268     update_date= models.DateField(verbose_name=u'更新日期',auto_now=True)
269 
270     class Meta:
271         verbose_name = '合同'
272         verbose_name_plural = "合同"
273 
274     def __str__(self):
275         return self.name
276 
277 class IDC(models.Model):
278     name = models.CharField(u'机房名称',max_length=64,unique=True)
279     memo = models.CharField(u'备注',max_length=128,blank=True,null=True)
280 
281     class Meta:
282         verbose_name = '机房'
283         verbose_name_plural = "机房"
284 
285     def __str__(self):
286         return self.name
287 
288 class Tag(models.Model):
289     name = models.CharField(u'标签名',max_length=32,unique=True )
290     creater = models.ForeignKey(UserProfile,verbose_name=u'创建人')
291     create_date = models.DateField(verbose_name=u'创建日期',auto_now_add=True)
292 
293     def __str__(self):
294         return self.name
295 
296 class EventLog(models.Model):
297     name = models.CharField(u'事件名称', max_length=100)
298     event_type_choices = (
299         (1,u'硬件变更'),
300         (2,u'新增配件'),
301         (3,u'设备下线'),
302         (4,u'设备上线'),
303         (5,u'定期维护'),
304         (6,u'业务上线更新变更'),
305         (7,u'其它'),
306     )
307     event_type = models.SmallIntegerField(u'事件类型', choices= event_type_choices)
308     asset = models.ForeignKey('Asset')
309     component = models.CharField('事件子项', max_length=255, blank=True,null=True)
310     detail = models.TextField(u'事件详情')
311     date = models.DateTimeField(u'事件时间', auto_now_add=True)
312     user = models.ForeignKey(UserProfile, verbose_name=u'事件源')
313     memo = models.TextField(u'备注', blank=True,null=True)
314 
315     def colored_event_type(self):
316         if self.event_type == 1:
317             cell_html = '<span style="background: orange;">%s</span>'
318         elif self.event_type == 2 :
319             cell_html = '<span style="background: yellowgreen;">%s</span>'
320         else:
321             cell_html = '<span >%s</span>'
322         return cell_html % self.get_event_type_display()
323     colored_event_type.allow_tags = True
324     colored_event_type.short_description = u'事件类型'
325 
326     class Meta:
327         verbose_name = '事件纪录'
328         verbose_name_plural = "事件纪录"
329 
330     def __str__(self):
331         return self.name
332 
333 class NewAssetApprovalZone(models.Model):
334     sn = models.CharField(u'资产SN号', max_length=128, unique=True)
335     asset_type_choices = (
336         ('server', u'服务器'),
337         ('switch', u'交换机'),
338         ('router', u'路由器'),
339         ('firewall', u'防火墙'),
340         ('storage', u'存储设备'),
341         ('NLB', u'NetScaler'),
342         ('wireless', u'无线AP'),
343         ('software', u'软件资产'),
344         ('others', u'其它类'),
345     )
346     asset_type = models.CharField(u'资产类型',choices=asset_type_choices,max_length=64,blank=True,null=True)
347     manufactory = models.CharField(u'厂商', max_length=64,blank=True,null=True)
348     model = models.CharField(u'型号',max_length=128,blank=True,null=True)
349     ram_size = models.IntegerField(blank=True,null=True)
350     cpu_model = models.CharField(max_length=128,blank=True,null=True)
351     cpu_count = models.IntegerField(blank=True,null=True)
352     cpu_core_count = models.IntegerField(blank=True,null=True)
353     os_distribution =  models.CharField(max_length=64,blank=True,null=True)
354     os_type =  models.CharField(max_length=64,blank=True,null=True)
355     os_release =  models.CharField(max_length=64,blank=True,null=True)
356     data = models.TextField(u'资产数据')
357     date = models.DateTimeField(u'汇报日期',auto_now_add=True)
358     approved = models.BooleanField(u'已批准',default=False)
359     approved_by = models.ForeignKey(UserProfile,verbose_name=u'批准人',blank=True,null=True)
360     approved_date = models.DateTimeField(u'批准日期',blank=True,null=True)
361 
362     class Meta:
363         verbose_name = '新上线待批准资产'
364         verbose_name_plural = "新上线待批准资产"
365 
366     def __str__(self):
367         return self.sn
数据表结构

自定义用户认证

https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#django.contrib.auth.models.PermissionsMixin.has_perms 

浅谈Restful API

理解RESTful架构 :http://www.ruanyifeng.com/blog/2011/09/restful 

RESTful API 设计指南 :http://www.ruanyifeng.com/blog/2014/05/restful_api.html

原文地址:https://www.cnblogs.com/suke99/p/5715767.html