network_inventory/docs/docs.org

10 KiB

Andreas Zweili

Models

Models define the database layout in a django application. Each class represents a table in the database. A lot the models in this project are very small because they exist mainly to keep the information unified.

Device

The "Device" model represents a generel device about which I don't have that much information. It might represent an IOT device or something similarly closed.

from django.db import models


class Device(models.Model):
    name = models.CharField(max_length=50)
    description = models.TextField()

    def __str__(self):
        return self.name

Weekday, DayOfMonth and Month

These models contain all the days of the week the days in a month and all month in a year.

class Weekday(models.Model):
    name = models.CharField(max_length=50)
    value = models.IntegerField()

    def __str__(self):
        return self.name


class DayOfMonth(models.Model):
    name = models.CharField(max_length=50)
    value = models.IntegerField()

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "Days of Month"


class Month(models.Model):
    name = models.CharField(max_length=50)
    value = models.IntegerField()

    def __str__(self):
        return self.name

RamType, Ram

"RamType" and "Ram" are ment to specify a ram module. "RamType" stands for the DDR verions.

class RamType(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "Types of RAM Modules"


class Ram(models.Model):
    type = models.ForeignKey(RamType, on_delete=models.CASCADE)
    size_in_gb = models.IntegerField()
    ecc = models.BooleanField(default=False)

    def __str__(self):
        return '{} {} GB'.format(self.type, self.size_in_gb)

    class Meta:
        verbose_name_plural = "RAM Modules"

DiskType, DiskSize, Disk

This three models together represent the various disk types I'm using. The idea is that you define the type then enter a common sizes you're using and then connect everything together in the "Disk" model. This way you have a set of disks you can "insert" into "Computer" models.

class DiskType(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "Types of disks"


class DiskSize(models.Model):
    size = models.IntegerField()

    def __str__(self):
        return str(self.size) + " GB"

    class Meta:
        verbose_name_plural = "Disk sizes"


class Disk(models.Model):
    type = models.ForeignKey(DiskType, on_delete=models.CASCADE)
    size_in_gb = models.ForeignKey(DiskSize, on_delete=models.CASCADE)

    def __str__(self):
        return '{} {}'.format(self.type, self.size_in_gb)

Architecture, CpuManufacturer and Cpu

"Architecture", "CpuManufacturer" and "Cpu" are the models which together specifiy the properties of a CPU.

class Architecture(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name


class CpuManufacturer(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "CPU Manufacturers"


class Cpu(models.Model):
    name = models.CharField(max_length=50)
    manufacturer = models.ForeignKey(CpuManufacturer, on_delete=models.PROTECT)
    number_of_cores = models.IntegerField()
    frequency = models.FloatField()
    architecture = models.ForeignKey(Architecture, on_delete=models.PROTECT)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "CPUs"

OperatingSystem

A simple model to save operating system names.

class OperatingSystem(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "Operating Systems"

Raid

A model to store the various RAID configurations.

class Raid(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "Types of RAID"

Computer

This model represents a complete computer, server or virtual machine. It's inheritated from the "Device" model. So that one can link it to a warranty.

class Computer(Device):
    hostname = models.CharField(max_length=20, unique=True)
    os = models.ForeignKey(OperatingSystem, on_delete=models.PROTECT)
    cpu = models.ManyToManyField(Cpu, through='ComputerCpuRelation')
    ram = models.ManyToManyField(Ram, through='ComputerRamRelation')
    ip = models.CharField(max_length=15)
    disks = models.ManyToManyField(Disk, through='ComputerDiskRelation')
    host = models.ForeignKey('self', null=True, blank=True,
                             on_delete=models.PROTECT)

    def __str__(self):
        return str(self.hostname)

ComputerDiskRelation, ComputerRamRelation and ComputerCpuRelation

These models are required to link RAM modules, disks and CPUs to a computer. Without these models it wouldn't be possible to specifiy the used amount.

class ComputerDiskRelation(models.Model):
    disk = models.ForeignKey(Disk, on_delete=models.CASCADE)
    computer = models.ForeignKey(Computer, on_delete=models.CASCADE)
    amount = models.IntegerField()
    raid = models.ForeignKey(Raid, null=True, blank=True,
                             on_delete=models.PROTECT)

    def __str__(self):
        return self.computer.hostname

    class Meta:
        verbose_name_plural = "Disks in Computer"


class ComputerRamRelation(models.Model):
    ram = models.ForeignKey(Ram, on_delete=models.CASCADE)
    computer = models.ForeignKey(Computer, on_delete=models.CASCADE)
    amount = models.IntegerField()

    def __str__(self):
        return self.computer.hostname

    class Meta:
        verbose_name_plural = "RAM Modules in Computer"


class ComputerCpuRelation(models.Model):
    cpu = models.ForeignKey(Cpu, on_delete=models.CASCADE)
    computer = models.ForeignKey(Computer, on_delete=models.CASCADE)
    amount = models.IntegerField()

    def __str__(self):
        return self.computer.hostname

    class Meta:
        verbose_name_plural = "CPUs in Computer"

Warranty

As the name suggests this model is for storing warranty informations. In addition it has an attribute for a file so that one can attach a scan of the warranty paper.

class Warranty(models.Model):
    device = models.ForeignKey(Device, on_delete=models.CASCADE)
    files = models.FileField()
    valid_until = models.DateField()

    def __str__(self):
        return self.device

    class Meta:
        verbose_name_plural = "Warranties"

CronJob

This model represents a cron job running on a host. It contains all the information that one would write in a crontab file.

class CronJob(models.Model):
    name = models.CharField(max_length=50)
    host = models.ForeignKey(Computer, on_delete=models.CASCADE)
    command = models.CharField(max_length=50)
    time = models.TimeField()
    weekday = models.ForeignKey(Weekday, on_delete=models.CASCADE)
    month = models.ForeignKey(Month, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "Cron Jobs"

Admin

The admin file specifies which models are visible and in which way the get shown in the admin interface.

We have to import each model we want to use.

from django.contrib import admin
from inventory.models import (Device, Weekday, Month, RamType, Ram,
                              DiskType, DiskSize, Disk, Architecture,
                              CpuManufacturer, Cpu, OperatingSystem,
                              Raid, Computer, ComputerDiskRelation,
                              ComputerCpuRelation,
                              ComputerRamRelation, Warranty, CronJob)

InLine classes

I made an inline class for both RAM and disks and extended the "Computer" admin form with them. This makes it easier to add RAM modules and disks to a computer.

class RamInLine(admin.StackedInline):
    model = ComputerRamRelation
    verbose_name_plural = 'RAM Modules'


class DiskInLine(admin.StackedInline):
    model = ComputerDiskRelation
    verbose_name_plural = 'Disks'


class CpusInLine(admin.StackedInline):
    model = ComputerCpuRelation
    verbose_name_plural = 'CPUs'


class ComputerAdmin(admin.ModelAdmin):
    inlines = (CpusInLine, RamInLine, DiskInLine,)

Registering models

In order for the models to show up in the admin interface we have to register them in addition to importing them in the admin.py file. In addition we have to define which admin form they should use if we want to use something different than the default one.

admin.site.register(Device)
admin.site.register(Weekday)
admin.site.register(Month)
admin.site.register(RamType)
admin.site.register(Ram)
admin.site.register(DiskType)
admin.site.register(DiskSize)
admin.site.register(Disk)
admin.site.register(Architecture)
admin.site.register(CpuManufacturer)
admin.site.register(Cpu)
admin.site.register(OperatingSystem)
admin.site.register(Raid)
admin.site.register(Computer)
admin.site.register(ComputerDiskRelation)
admin.site.register(ComputerRamRelation)
admin.site.register(Warranty)
admin.site.register(CronJob)

Views

#!/usr/bin/python3
from django.shortcuts import get_object_or_404, render