zouruncheng

CMDB之数据库表设计

1.开发CMDB的背景
很多公司还在用Excel维护资产信息,当服务器数量变多时,难以保证excel表格的正确性,而且不同部门之间交换信息不方便。实现自动采集资产,自动汇报,并自动保存变更记录。
2.CMDB架构
- 资产采集(资产采集)
- API(接受数据保存入库,对外提供数据接口)
- 后台管理

3.资产采集方式
三种方案
- agent
- paramiko
- saltstack

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

分类:

技术点:

相关文章: