1.開發CMDB的背景
不少公司還在用Excel維護資產信息,當服務器數量變多時,難以保證excel表格的正確性,並且不一樣部門之間交換信息不方便。實現自動採集資產,自動彙報,並自動保存變動記錄。
2.CMDB架構
- 資產採集(資產採集)
- API(接受數據保存入庫,對外提供數據接口)
- 後臺管理數據庫
3.資產採集方式
三種方案
- agent
- paramiko
- saltstackdjango
4.服務器的惟一標識
a.不須要採集虛擬機
- 採用主板的SN號做爲惟一標識。
b.須要採集虛擬機
- 對服務器進行標準化,惟一標識選用hostname服務器
5.CMDB流程
- 裝機同時,主機名在CMDB中設置
- 第一次採集,將主機名寫入文件,發送到API
- 第N次採集,主機名從直接從文件名中獲取。網絡
6.表結構圖示架構
7.django-models結構設計
from django.db import models class UserProfile(models.Model): """ 用戶信息 """ name = models.CharField(u'姓名', max_length=32) email = models.EmailField(u'郵箱') phone = models.CharField(u'座機', max_length=32) mobile = models.CharField(u'手機', max_length=32) class Meta: verbose_name_plural = "用戶表" def __str__(self): return self.name class AdminInfo(models.Model): """ 用戶登錄相關信息 """ user_info = models.OneToOneField("UserProfile") username = models.CharField(u'用戶名', max_length=64) password = models.CharField(u'密碼', max_length=64) class Meta: verbose_name_plural = "管理員表" def __str__(self): return self.user_info.name class UserGroup(models.Model): """ 用戶組 """ name = models.CharField(max_length=32, unique=True) users = models.ManyToManyField('UserProfile') class Meta: verbose_name_plural = "用戶組表" def __str__(self): return self.name class BusinessUnit(models.Model): """ 業務線,業務聯繫人和系統管理員 """ name = models.CharField('業務線', max_length=64, unique=True) contact = models.ForeignKey('UserGroup', verbose_name='業務聯繫人', related_name='c') manager = models.ForeignKey('UserGroup', verbose_name='系統管理員', related_name='m') class Meta: verbose_name_plural = "業務線表" def __str__(self): return self.name class IDC(models.Model): """ 機房信息 """ name = models.CharField('機房', max_length=32) floor = models.IntegerField('樓層', default=1) class Meta: verbose_name_plural = "機房表" def __str__(self): return self.name class Tag(models.Model): """ 資產標籤 """ name = models.CharField('標籤', max_length=32, unique=True) class Meta: verbose_name_plural = "標籤表" def __str__(self): return self.name class Asset(models.Model): """ 資產信息表,全部資產公共信息(交換機,服務器,防火牆等) """ device_type_choices = ( (1, '服務器'), (2, '交換機'), (3, '防火牆'), ) device_status_choices = ( (1, '上架'), (2, '在線'), (3, '離線'), (4, '下架'), ) device_type_id = models.IntegerField(choices=device_type_choices, default=1) device_status_id = models.IntegerField(choices=device_status_choices, default=1) cabinet_num = models.CharField('機櫃號', max_length=30, null=True, blank=True) cabinet_order = models.CharField('機櫃中序號', max_length=30, null=True, blank=True) idc = models.ForeignKey('IDC', verbose_name='IDC機房', null=True, blank=True) business_unit = models.ForeignKey('BusinessUnit', verbose_name='屬於的業務線', null=True, blank=True) tag = models.ManyToManyField('Tag') latest_date = models.DateField(null=True) create_at = models.DateTimeField(auto_now_add=True) class Meta: verbose_name_plural = "資產表" def __str__(self): return "%s-%s-%s" % (self.idc.name, self.cabinet_num, self.cabinet_order) class Server(models.Model): """ 服務器信息 """ asset = models.OneToOneField('Asset') hostname = models.CharField(max_length=128, unique=True) sn = models.CharField('SN號', max_length=64, db_index=True) manufacturer = models.CharField(verbose_name='製造商', max_length=64, null=True, blank=True) model = models.CharField('型號', max_length=64, null=True, blank=True) manage_ip = models.GenericIPAddressField('管理IP', null=True, blank=True) os_platform = models.CharField('系統', max_length=16, null=True, blank=True) os_version = models.CharField('系統版本', max_length=16, 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=128, null=True, blank=True) create_at = models.DateTimeField(auto_now_add=True, blank=True) class Meta: verbose_name_plural = "服務器表" def __str__(self): return self.hostname class NetworkDevice(models.Model): asset = models.OneToOneField('Asset') management_ip = models.CharField('管理IP', max_length=64, blank=True, null=True) vlan_ip = models.CharField('VlanIP', max_length=64, blank=True, null=True) intranet_ip = models.CharField('內網IP', max_length=128, blank=True, null=True) sn = models.CharField('SN號', max_length=64, unique=True) manufacture = models.CharField(verbose_name=u'製造商', max_length=128, null=True, blank=True) model = models.CharField('型號', max_length=128, null=True, blank=True) port_num = models.SmallIntegerField('端口個數', null=True, blank=True) device_detail = models.CharField('設置詳細配置', max_length=255, null=True, blank=True) class Meta: verbose_name_plural = "網絡設備" class Disk(models.Model): """ 硬盤信息 """ slot = models.CharField('插槽位', max_length=8) model = models.CharField('磁盤型號', max_length=32) capacity = models.FloatField('磁盤容量GB') pd_type = models.CharField('磁盤類型', max_length=32) server_obj = models.ForeignKey('Server',related_name='disk') class Meta: verbose_name_plural = "硬盤表" def __str__(self): return self.slot class NIC(models.Model): """ 網卡信息 """ name = models.CharField('網卡名稱', max_length=128) hwaddr = models.CharField('網卡mac地址', max_length=64) netmask = models.CharField(max_length=64) ipaddrs = models.CharField('ip地址', max_length=256) up = models.BooleanField(default=False) server_obj = models.ForeignKey('Server',related_name='nic') class Meta: verbose_name_plural = "網卡表" def __str__(self): return self.name class Memory(models.Model): """ 內存信息 """ slot = models.CharField('插槽位', max_length=32) manufacturer = models.CharField('製造商', max_length=32, null=True, blank=True) model = models.CharField('型號', max_length=64) capacity = models.FloatField('容量', null=True, blank=True) sn = models.CharField('內存SN號', max_length=64, null=True, blank=True) speed = models.CharField('速度', max_length=16, null=True, blank=True) server_obj = models.ForeignKey('Server',related_name='memory') class Meta: verbose_name_plural = "內存表" def __str__(self): return self.slot class AssetRecord(models.Model): """ 資產變動記錄,creator爲空時,表示是資產彙報的數據。 """ asset_obj = models.ForeignKey('Asset', related_name='ar') content = models.TextField(null=True)# 新增硬盤 creator = models.ForeignKey('UserProfile', null=True, blank=True) # create_at = models.DateTimeField(auto_now_add=True) class Meta: verbose_name_plural = "資產記錄表" def __str__(self): return "%s-%s-%s" % (self.asset_obj.idc.name, self.asset_obj.cabinet_num, self.asset_obj.cabinet_order) class ErrorLog(models.Model): """ 錯誤日誌,如:agent採集數據錯誤 或 運行錯誤 """ asset_obj = models.ForeignKey('Asset', null=True, blank=True) title = models.CharField(max_length=16) content = models.TextField() create_at = models.DateTimeField(auto_now_add=True) class Meta: verbose_name_plural = "錯誤日誌表" def __str__(self): return self.title