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'事件類型'
	'''
	自定義后台
	'''

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM