2017-12-22 07:40:13 +01:00
|
|
|
#+TITLE: Andreas Zweili
|
|
|
|
#+AUTHOR: Andreas Zweili
|
2017-12-25 00:12:07 +01:00
|
|
|
#+LaTeX_HEADER: \input{/home/andreas/git_repos/notes/settings/latex/style}
|
|
|
|
#+SETUPFILE: ~/git_repos/notes/settings/html_theme/setup/theme-readtheorg.setup
|
2017-12-22 14:13:51 +01:00
|
|
|
|
|
|
|
* Models
|
|
|
|
|
2017-12-22 23:32:26 +01:00
|
|
|
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
|
|
|
|
|
2017-12-25 16:23:42 +01:00
|
|
|
The "Device" class is only used as an abstract class.
|
2017-12-22 23:32:26 +01:00
|
|
|
|
2017-12-22 17:02:24 +01:00
|
|
|
#+BEGIN_SRC python :tangle ../inventory/models.py
|
2017-12-22 14:13:51 +01:00
|
|
|
from django.db import models
|
2017-12-22 17:02:24 +01:00
|
|
|
|
|
|
|
|
|
|
|
class Device(models.Model):
|
|
|
|
name = models.CharField(max_length=50)
|
|
|
|
description = models.TextField()
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
2017-12-22 23:34:40 +01:00
|
|
|
#+END_SRC
|
|
|
|
|
2017-12-25 16:23:42 +01:00
|
|
|
** GeneralDevice
|
|
|
|
|
|
|
|
The "GeneralDevice" model is used to describe devices which are very
|
|
|
|
simple or I don't have much control over.
|
|
|
|
|
2017-12-27 16:37:52 +01:00
|
|
|
#+BEGIN_SRC python :tangle ../inventory/models.py :padline 2
|
2017-12-25 16:23:42 +01:00
|
|
|
class GeneralDevice(Device):
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
|
|
|
#+END_SRC
|
|
|
|
|
2017-12-22 23:35:08 +01:00
|
|
|
** Weekday, DayOfMonth and Month
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-22 23:35:08 +01:00
|
|
|
These models contain all the days of the week the days in a month and
|
|
|
|
all month in a year.
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-22 23:38:34 +01:00
|
|
|
#+BEGIN_SRC python :tangle ../inventory/models.py :padline 2
|
2017-12-26 18:13:06 +01:00
|
|
|
class HoursInDay(models.Model):
|
|
|
|
name = models.IntegerField()
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return str(self.name)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "Hours"
|
|
|
|
ordering = ['name']
|
|
|
|
|
|
|
|
|
|
|
|
class MinutesInHour(models.Model):
|
|
|
|
name = models.IntegerField()
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return str(self.name)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "Minutes"
|
|
|
|
ordering = ['name']
|
|
|
|
|
|
|
|
|
2017-12-22 17:02:24 +01:00
|
|
|
class Weekday(models.Model):
|
|
|
|
name = models.CharField(max_length=50)
|
2017-12-22 23:47:18 +01:00
|
|
|
value = models.IntegerField()
|
2017-12-22 23:58:46 +01:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
|
|
|
|
2017-12-25 13:19:58 +01:00
|
|
|
class Meta:
|
|
|
|
ordering = ['value']
|
|
|
|
|
2017-12-22 23:58:46 +01:00
|
|
|
|
2017-12-22 23:43:10 +01:00
|
|
|
class DayOfMonth(models.Model):
|
2017-12-26 11:33:41 +01:00
|
|
|
name = models.IntegerField()
|
2017-12-22 17:02:24 +01:00
|
|
|
|
|
|
|
def __str__(self):
|
2017-12-26 11:33:41 +01:00
|
|
|
return str(self.name)
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-24 23:39:40 +01:00
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "Days of Month"
|
2017-12-26 11:33:41 +01:00
|
|
|
ordering = ['name']
|
2017-12-24 23:39:40 +01:00
|
|
|
|
2017-12-22 17:02:24 +01:00
|
|
|
|
|
|
|
class Month(models.Model):
|
|
|
|
name = models.CharField(max_length=50)
|
2017-12-22 23:47:18 +01:00
|
|
|
value = models.IntegerField()
|
2017-12-22 17:02:24 +01:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
2017-12-25 13:19:58 +01:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
ordering = ['value']
|
2017-12-22 23:38:34 +01:00
|
|
|
#+END_SRC
|
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
** RamType, Ram
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
"RamType" and "Ram" are ment to specify a ram module. "RamType" stands
|
|
|
|
for the DDR verions.
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-22 23:38:34 +01:00
|
|
|
#+BEGIN_SRC python :tangle ../inventory/models.py :padline 2
|
2017-12-22 17:02:24 +01:00
|
|
|
class RamType(models.Model):
|
|
|
|
name = models.CharField(max_length=50)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
|
|
|
|
2017-12-24 23:39:40 +01:00
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "Types of RAM Modules"
|
|
|
|
|
2017-12-22 17:02:24 +01:00
|
|
|
|
|
|
|
class Ram(models.Model):
|
|
|
|
type = models.ForeignKey(RamType, on_delete=models.CASCADE)
|
2017-12-24 23:41:15 +01:00
|
|
|
size_in_gb = models.IntegerField()
|
2017-12-22 23:42:06 +01:00
|
|
|
ecc = models.BooleanField(default=False)
|
2017-12-22 17:02:24 +01:00
|
|
|
|
|
|
|
def __str__(self):
|
2017-12-24 23:43:41 +01:00
|
|
|
return '{} {} GB'.format(self.type, self.size_in_gb)
|
2017-12-24 23:39:40 +01:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "RAM Modules"
|
2017-12-22 23:38:34 +01:00
|
|
|
#+END_SRC
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
** DiskType, DiskSize, Disk
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
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.
|
2017-12-22 23:38:34 +01:00
|
|
|
|
|
|
|
#+BEGIN_SRC python :tangle ../inventory/models.py :padline 2
|
2017-12-22 17:02:24 +01:00
|
|
|
class DiskType(models.Model):
|
|
|
|
name = models.CharField(max_length=50)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
|
|
|
|
2017-12-24 23:39:40 +01:00
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "Types of disks"
|
|
|
|
|
2017-12-22 17:02:24 +01:00
|
|
|
|
|
|
|
class DiskSize(models.Model):
|
2017-12-24 23:41:15 +01:00
|
|
|
size = models.IntegerField()
|
2017-12-22 17:02:24 +01:00
|
|
|
|
|
|
|
def __str__(self):
|
2017-12-24 23:44:27 +01:00
|
|
|
return str(self.size) + " GB"
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-24 23:39:40 +01:00
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "Disk sizes"
|
|
|
|
|
2017-12-22 17:02:24 +01:00
|
|
|
|
|
|
|
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):
|
2017-12-24 23:47:53 +01:00
|
|
|
return '{} {}'.format(self.type, self.size_in_gb)
|
2017-12-27 17:12:47 +01:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
ordering = ['type']
|
2017-12-22 23:38:34 +01:00
|
|
|
#+END_SRC
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
** Architecture, CpuManufacturer and Cpu
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
"Architecture", "CpuManufacturer" and "Cpu" are the models which
|
|
|
|
together specifiy the properties of a CPU.
|
|
|
|
|
|
|
|
#+BEGIN_SRC python :tangle ../inventory/models.py :padline 2
|
2017-12-22 17:02:24 +01:00
|
|
|
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
|
|
|
|
|
2017-12-24 23:39:40 +01:00
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "CPU Manufacturers"
|
|
|
|
|
2017-12-22 17:02:24 +01:00
|
|
|
|
|
|
|
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
|
2017-12-24 23:39:40 +01:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "CPUs"
|
2017-12-22 23:38:34 +01:00
|
|
|
#+END_SRC
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
** OperatingSystem
|
|
|
|
|
|
|
|
A simple model to save operating system names.
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-22 23:38:34 +01:00
|
|
|
#+BEGIN_SRC python :tangle ../inventory/models.py :padline 2
|
2017-12-22 17:02:24 +01:00
|
|
|
class OperatingSystem(models.Model):
|
|
|
|
name = models.CharField(max_length=50)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
2017-12-24 23:39:40 +01:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "Operating Systems"
|
2017-12-22 23:38:34 +01:00
|
|
|
#+END_SRC
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
** Raid
|
|
|
|
|
|
|
|
A model to store the various RAID configurations.
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-22 23:38:34 +01:00
|
|
|
#+BEGIN_SRC python :tangle ../inventory/models.py :padline 2
|
2017-12-22 17:02:24 +01:00
|
|
|
class Raid(models.Model):
|
|
|
|
name = models.CharField(max_length=50)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
2017-12-24 23:39:40 +01:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "Types of RAID"
|
2017-12-22 23:38:34 +01:00
|
|
|
#+END_SRC
|
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
** Computer
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
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.
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-22 23:38:34 +01:00
|
|
|
#+BEGIN_SRC python :tangle ../inventory/models.py :padline 2
|
2017-12-22 17:02:24 +01:00
|
|
|
class Computer(Device):
|
|
|
|
os = models.ForeignKey(OperatingSystem, on_delete=models.PROTECT)
|
2017-12-24 23:57:30 +01:00
|
|
|
cpu = models.ManyToManyField(Cpu, through='ComputerCpuRelation')
|
2017-12-22 17:02:24 +01:00
|
|
|
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):
|
2017-12-25 14:07:51 +01:00
|
|
|
return str(self.name)
|
2017-12-22 23:38:34 +01:00
|
|
|
#+END_SRC
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-24 23:57:30 +01:00
|
|
|
** ComputerDiskRelation, ComputerRamRelation and ComputerCpuRelation
|
2017-12-23 00:00:37 +01:00
|
|
|
|
2017-12-24 23:57:30 +01:00
|
|
|
These models are required to link RAM modules, disks and CPUs to a computer.
|
2017-12-23 00:00:37 +01:00
|
|
|
Without these models it wouldn't be possible to specifiy the used amount.
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-22 23:38:34 +01:00
|
|
|
#+BEGIN_SRC python :tangle ../inventory/models.py :padline 2
|
2017-12-22 17:02:24 +01:00
|
|
|
class ComputerDiskRelation(models.Model):
|
|
|
|
disk = models.ForeignKey(Disk, on_delete=models.CASCADE)
|
|
|
|
computer = models.ForeignKey(Computer, on_delete=models.CASCADE)
|
|
|
|
amount = models.IntegerField()
|
2017-12-24 23:51:46 +01:00
|
|
|
raid = models.ForeignKey(Raid, null=True, blank=True,
|
|
|
|
on_delete=models.PROTECT)
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-25 00:00:26 +01:00
|
|
|
def __str__(self):
|
2017-12-25 14:07:51 +01:00
|
|
|
return self.computer.name
|
2017-12-25 00:00:26 +01:00
|
|
|
|
2017-12-24 23:59:10 +01:00
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "Disks in Computer"
|
|
|
|
|
2017-12-22 17:02:24 +01:00
|
|
|
|
|
|
|
class ComputerRamRelation(models.Model):
|
|
|
|
ram = models.ForeignKey(Ram, on_delete=models.CASCADE)
|
|
|
|
computer = models.ForeignKey(Computer, on_delete=models.CASCADE)
|
|
|
|
amount = models.IntegerField()
|
2017-12-24 23:39:40 +01:00
|
|
|
|
2017-12-25 00:00:26 +01:00
|
|
|
def __str__(self):
|
2017-12-25 14:07:51 +01:00
|
|
|
return self.computer.name
|
2017-12-24 23:39:40 +01:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "RAM Modules in Computer"
|
2017-12-24 23:57:30 +01:00
|
|
|
|
|
|
|
|
|
|
|
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):
|
2017-12-25 14:07:51 +01:00
|
|
|
return self.computer.name
|
2017-12-24 23:57:30 +01:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "CPUs in Computer"
|
2017-12-22 23:38:34 +01:00
|
|
|
#+END_SRC
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
** 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.
|
2017-12-22 23:38:34 +01:00
|
|
|
|
|
|
|
#+BEGIN_SRC python :tangle ../inventory/models.py :padline 2
|
2017-12-22 17:02:24 +01:00
|
|
|
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
|
2017-12-24 23:39:40 +01:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "Warranties"
|
2017-12-22 23:38:34 +01:00
|
|
|
#+END_SRC
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
** CronJob
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
This model represents a cron job running on a host. It contains all
|
|
|
|
the information that one would write in a crontab file.
|
2017-12-22 23:38:34 +01:00
|
|
|
|
|
|
|
#+BEGIN_SRC python :tangle ../inventory/models.py :padline 2
|
2017-12-22 17:02:24 +01:00
|
|
|
class CronJob(models.Model):
|
|
|
|
name = models.CharField(max_length=50)
|
|
|
|
host = models.ForeignKey(Computer, on_delete=models.CASCADE)
|
|
|
|
command = models.CharField(max_length=50)
|
2017-12-26 18:13:06 +01:00
|
|
|
minutes = models.ForeignKey(MinutesInHour, on_delete=models.CASCADE,
|
|
|
|
null=True, blank=True,)
|
|
|
|
hours = models.ForeignKey(HoursInDay, on_delete=models.CASCADE,
|
2017-12-27 15:52:43 +01:00
|
|
|
null=True, blank=True,)
|
2017-12-26 11:35:05 +01:00
|
|
|
weekday = models.ForeignKey(Weekday, on_delete=models.CASCADE,
|
|
|
|
null=True, blank=True,)
|
|
|
|
day = models.ForeignKey(DayOfMonth, on_delete=models.CASCADE,
|
|
|
|
null=True, blank=True,)
|
|
|
|
month = models.ForeignKey(Month, on_delete=models.CASCADE,
|
|
|
|
null=True, blank=True,)
|
2017-12-22 17:02:24 +01:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
2017-12-24 23:39:40 +01:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name_plural = "Cron Jobs"
|
2017-12-22 14:13:51 +01:00
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
* Admin
|
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
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.
|
|
|
|
|
2017-12-22 17:02:24 +01:00
|
|
|
#+BEGIN_SRC python :tangle ../inventory/admin.py
|
2017-12-22 14:13:51 +01:00
|
|
|
from django.contrib import admin
|
2017-12-26 18:13:06 +01:00
|
|
|
from inventory.models import (GeneralDevice, HoursInDay,
|
|
|
|
MinutesInHour, Weekday, DayOfMonth,
|
2017-12-26 11:33:41 +01:00
|
|
|
Month, RamType, Ram, DiskType, DiskSize,
|
|
|
|
Disk, Architecture, CpuManufacturer,
|
|
|
|
Cpu, OperatingSystem, Raid, Computer,
|
|
|
|
ComputerDiskRelation,
|
2017-12-24 23:57:30 +01:00
|
|
|
ComputerCpuRelation,
|
2017-12-22 17:02:24 +01:00
|
|
|
ComputerRamRelation, Warranty, CronJob)
|
2017-12-22 23:38:34 +01:00
|
|
|
#+END_SRC
|
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
** InLine classes
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-27 16:25:45 +01:00
|
|
|
I made an inline class for RAM, disks and CPUs and extended the
|
|
|
|
"Computer" admin form with them. This makes it easier to add theme to
|
|
|
|
a computer.
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-22 23:38:34 +01:00
|
|
|
#+BEGIN_SRC python :tangle ../inventory/admin.py :padline 2
|
2017-12-22 23:59:40 +01:00
|
|
|
class RamInLine(admin.StackedInline):
|
2017-12-22 17:02:24 +01:00
|
|
|
model = ComputerRamRelation
|
2017-12-25 00:07:19 +01:00
|
|
|
extra = 0
|
2017-12-25 00:02:13 +01:00
|
|
|
verbose_name_plural = 'RAM Modules'
|
2017-12-22 17:02:24 +01:00
|
|
|
|
|
|
|
|
2017-12-22 23:59:40 +01:00
|
|
|
class DiskInLine(admin.StackedInline):
|
2017-12-22 17:02:24 +01:00
|
|
|
model = ComputerDiskRelation
|
2017-12-25 00:07:19 +01:00
|
|
|
extra = 0
|
2017-12-22 17:02:24 +01:00
|
|
|
verbose_name_plural = 'Disks'
|
|
|
|
|
|
|
|
|
2017-12-24 23:57:30 +01:00
|
|
|
class CpusInLine(admin.StackedInline):
|
|
|
|
model = ComputerCpuRelation
|
2017-12-25 00:07:19 +01:00
|
|
|
extra = 0
|
2017-12-24 23:57:30 +01:00
|
|
|
verbose_name_plural = 'CPUs'
|
2017-12-27 16:28:38 +01:00
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
** Extended Admin Interfaces
|
|
|
|
|
|
|
|
This section contains the classes which extend the admin interface for
|
|
|
|
certain models in cases where the default form might not work for the task.
|
2017-12-24 23:57:30 +01:00
|
|
|
|
2017-12-27 16:28:38 +01:00
|
|
|
*** ComputerAdmin
|
2017-12-24 23:57:30 +01:00
|
|
|
|
2017-12-27 16:28:38 +01:00
|
|
|
The "ComputerAdmin" class extends the default "Computer" admin
|
|
|
|
interface.
|
|
|
|
For one it adds some columns to the list and adds three inline models
|
|
|
|
which allows to add them directly from the "Computer" form.
|
|
|
|
|
|
|
|
#+BEGIN_SRC python :tangle ../inventory/admin.py :padline 2
|
2017-12-22 17:02:24 +01:00
|
|
|
class ComputerAdmin(admin.ModelAdmin):
|
2017-12-25 14:07:51 +01:00
|
|
|
list_display = ('name', 'ip', 'host')
|
2017-12-24 23:57:30 +01:00
|
|
|
inlines = (CpusInLine, RamInLine, DiskInLine,)
|
2017-12-22 23:38:34 +01:00
|
|
|
#+END_SRC
|
2017-12-22 17:02:24 +01:00
|
|
|
|
2017-12-27 16:31:32 +01:00
|
|
|
*** CronJobAdmin
|
|
|
|
|
|
|
|
The "CronJobAdmin" extends the cron job admin list with two columns to
|
|
|
|
show to which host they belong.
|
|
|
|
|
|
|
|
#+BEGIN_SRC python :tangle ../inventory/admin.py :padline 2
|
|
|
|
class CronJobAdmin(admin.ModelAdmin):
|
|
|
|
list_display = ('name', 'host')
|
|
|
|
#+END_SRC
|
|
|
|
|
2017-12-23 00:00:37 +01:00
|
|
|
** 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.
|
2017-12-22 14:13:51 +01:00
|
|
|
|
2017-12-22 23:38:34 +01:00
|
|
|
#+BEGIN_SRC python :tangle ../inventory/admin.py :padline 2
|
2017-12-25 16:23:42 +01:00
|
|
|
admin.site.register(GeneralDevice)
|
2017-12-26 18:13:06 +01:00
|
|
|
admin.site.register(HoursInDay)
|
|
|
|
admin.site.register(MinutesInHour)
|
2017-12-22 17:02:24 +01:00
|
|
|
admin.site.register(Weekday)
|
2017-12-26 11:33:41 +01:00
|
|
|
admin.site.register(DayOfMonth)
|
2017-12-22 17:02:24 +01:00
|
|
|
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)
|
2017-12-25 00:09:41 +01:00
|
|
|
admin.site.register(Computer, ComputerAdmin)
|
2017-12-22 17:02:24 +01:00
|
|
|
admin.site.register(Warranty)
|
2017-12-27 16:31:32 +01:00
|
|
|
admin.site.register(CronJob, CronJobAdmin)
|
2017-12-22 14:13:51 +01:00
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
* Views
|
|
|
|
|
2017-12-25 16:23:42 +01:00
|
|
|
Views are used to get information from the database and send them to
|
|
|
|
the templates.
|
|
|
|
|
2017-12-22 17:02:24 +01:00
|
|
|
#+BEGIN_SRC python :tangle ../inventory/views.py
|
2017-12-22 14:13:51 +01:00
|
|
|
#!/usr/bin/python3
|
|
|
|
from django.shortcuts import get_object_or_404, render
|
2017-12-25 16:23:42 +01:00
|
|
|
from .models import (GeneralDevice, Computer, CronJob,
|
2017-12-25 13:33:28 +01:00
|
|
|
ComputerRamRelation,
|
|
|
|
ComputerDiskRelation,
|
|
|
|
ComputerCpuRelation)
|
2017-12-22 14:13:51 +01:00
|
|
|
|
2017-12-25 00:37:31 +01:00
|
|
|
|
2017-12-25 00:37:52 +01:00
|
|
|
def index(request):
|
2017-12-25 16:23:42 +01:00
|
|
|
device_list = GeneralDevice.objects.all()
|
2017-12-25 23:55:35 +01:00
|
|
|
computer_list = Computer.objects.all().order_by('ip')
|
2017-12-26 11:36:28 +01:00
|
|
|
cronjob_list = CronJob.objects.all().order_by('host')
|
2017-12-25 00:37:52 +01:00
|
|
|
|
|
|
|
return render(request,
|
|
|
|
'inventory/index.html',
|
2017-12-25 13:34:00 +01:00
|
|
|
{'device_list': device_list,
|
2017-12-26 11:36:28 +01:00
|
|
|
'computer_list': computer_list,
|
|
|
|
'cronjob_list': cronjob_list})
|
2017-12-25 13:35:09 +01:00
|
|
|
|
|
|
|
|
|
|
|
def device_details(request, device_id):
|
2017-12-25 16:23:42 +01:00
|
|
|
device = get_object_or_404(GeneralDevice, pk=device_id)
|
2017-12-25 13:35:09 +01:00
|
|
|
return render(request, 'inventory/device_details.html',
|
|
|
|
{'device': device})
|
|
|
|
|
|
|
|
|
2017-12-25 13:35:30 +01:00
|
|
|
def computer_details(request, computer_id):
|
|
|
|
computer = get_object_or_404(Computer, pk=computer_id)
|
2017-12-26 11:13:14 +01:00
|
|
|
disks_list = ComputerDiskRelation.objects.filter(computer=computer_id)
|
2017-12-25 13:35:30 +01:00
|
|
|
ram = ComputerRamRelation.objects.get(computer=computer_id)
|
|
|
|
cpu = ComputerCpuRelation.objects.get(computer=computer_id)
|
|
|
|
cronjob_list = CronJob.objects.filter(host=computer_id)
|
|
|
|
return render(request, 'inventory/computer_details.html',
|
|
|
|
{'computer': computer,
|
2017-12-26 11:13:14 +01:00
|
|
|
'disks_list': disks_list,
|
2017-12-25 13:35:30 +01:00
|
|
|
'ram': ram,
|
|
|
|
'cpu': cpu,
|
|
|
|
'cronjob_list': cronjob_list})
|
|
|
|
|
|
|
|
|
2017-12-25 13:36:03 +01:00
|
|
|
def cronjob_details(request, cronjob_id):
|
|
|
|
cronjob = get_object_or_404(CronJob, pk=cronjob_id)
|
|
|
|
return render(request, 'inventory/cronjob_details.html',
|
|
|
|
{'cronjob': cronjob})
|
|
|
|
#+END_SRC
|
|
|
|
|
2017-12-25 13:25:57 +01:00
|
|
|
* URLs
|
|
|
|
|
|
|
|
The urls.py files contain the definitions for the URLs. This means you
|
|
|
|
can define how your various pages get accessed.
|
|
|
|
|
|
|
|
** network_inventory/urls.py
|
|
|
|
|
|
|
|
This is the main URLs file. All the urls.py files need to get
|
|
|
|
registered in here in order to work.
|
|
|
|
|
|
|
|
#+BEGIN_SRC python :tangle ../network_inventory/urls.py
|
|
|
|
"""network_inventory URL Configuration
|
|
|
|
|
|
|
|
The `urlpatterns` list routes URLs to views. For more information please see:
|
|
|
|
https://docs.djangoproject.com/en/2.0/topics/http/urls/
|
|
|
|
Examples:
|
|
|
|
Function views
|
|
|
|
1. Add an import: from my_app import views
|
|
|
|
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
|
|
|
Class-based views
|
|
|
|
1. Add an import: from other_app.views import Home
|
|
|
|
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
|
|
|
Including another URLconf
|
|
|
|
1. Import the include() function: from django.urls import include, path
|
|
|
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
|
|
|
"""
|
|
|
|
from django.conf.urls import include, url
|
|
|
|
from django.contrib import admin
|
|
|
|
from django.urls import path
|
|
|
|
|
|
|
|
urlpatterns = [
|
|
|
|
url(r'', include('inventory.urls')),
|
|
|
|
path('admin/', admin.site.urls),
|
|
|
|
]
|
|
|
|
#+END_SRC
|
2017-12-25 13:31:29 +01:00
|
|
|
|
|
|
|
** inventory/urls.py
|
|
|
|
|
|
|
|
Contains the url definitions for the inventory application. For the
|
|
|
|
moment the inventory is my only application so all the URLs will start
|
|
|
|
from the root.
|
|
|
|
|
|
|
|
#+BEGIN_SRC python :tangle ../inventory/urls.py
|
|
|
|
from django.conf.urls import url
|
|
|
|
|
|
|
|
from . import views
|
|
|
|
|
|
|
|
urlpatterns = [
|
|
|
|
url(r'^$', views.index, name='index'),
|
|
|
|
url(r'^device/(?P<device_id>[0-9]+)/$',
|
|
|
|
views.device_details,
|
|
|
|
name='device'),
|
|
|
|
url(r'^computer/(?P<computer_id>[0-9]+)/$',
|
|
|
|
views.computer_details,
|
|
|
|
name='computer'),
|
|
|
|
url(r'^cronjob/(?P<cronjob_id>[0-9]+)/$',
|
|
|
|
views.cronjob_details,
|
|
|
|
name='cronjob'),
|
|
|
|
]
|
2017-12-25 00:37:52 +01:00
|
|
|
#+END_SRC
|
|
|
|
|
2017-12-25 00:37:31 +01:00
|
|
|
* Templates
|
|
|
|
|
|
|
|
Templates define the look of the application and where things get
|
|
|
|
positioned on the page.
|
|
|
|
|
2017-12-27 17:21:08 +01:00
|
|
|
** inventory.css
|
|
|
|
|
|
|
|
The inventory.css file get's loaded in the base.html file. It provides
|
|
|
|
some generel theming over the application.
|
|
|
|
|
|
|
|
*** Tables
|
|
|
|
|
|
|
|
Display a border around tables.
|
|
|
|
|
|
|
|
#+BEGIN_SRC css :tangle ../inventory/static/css/inventory.css
|
|
|
|
table, th, td {
|
|
|
|
border: 1px solid black;
|
|
|
|
}
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
Align table headers on the left side.
|
|
|
|
|
|
|
|
#+BEGIN_SRC css :tangle ../inventory/static/css/inventory.css
|
|
|
|
th {
|
|
|
|
text-align: left;
|
|
|
|
}
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
*** Body
|
|
|
|
|
|
|
|
Add a margin of a few pixels around the body.
|
|
|
|
|
|
|
|
#+BEGIN_SRC css :tangle ../inventory/static/css/inventory.css
|
|
|
|
body {
|
|
|
|
margin-top: 10px;
|
|
|
|
margin-bottom: 10px;
|
|
|
|
margin-right: 10px;
|
|
|
|
margin-left: 20px;
|
|
|
|
}
|
|
|
|
#+END_SRC
|
|
|
|
|
2017-12-25 00:37:31 +01:00
|
|
|
** base.html
|
|
|
|
|
|
|
|
The base.html file is the basis for all other html files and gets
|
|
|
|
extended by them.
|
|
|
|
|
|
|
|
#+BEGIN_SRC html :tangle ../inventory/templates/inventory/base.html
|
2017-12-25 23:54:37 +01:00
|
|
|
{% load staticfiles %}
|
2017-12-25 00:37:31 +01:00
|
|
|
<!DOCTYPE html>
|
|
|
|
<head>
|
2017-12-25 23:54:37 +01:00
|
|
|
<link rel="stylesheet" href="{% static 'css/inventory.css' %}">
|
2017-12-25 00:37:31 +01:00
|
|
|
</head>
|
|
|
|
<body>
|
2017-12-25 13:56:22 +01:00
|
|
|
<a href="{% url 'index' %}">Home</a>
|
2017-12-25 00:37:31 +01:00
|
|
|
<h1>{% block section_title %}Device Inventory{% endblock %}</h1>
|
|
|
|
{% block content %}{% endblock %}
|
|
|
|
</body>
|
|
|
|
<footer>
|
|
|
|
{% block footer %}
|
|
|
|
<p><font size="1">Created by Andreas Zweili licensed under GPL v3.0</font></p>
|
|
|
|
{% endblock %}
|
|
|
|
</footer>
|
|
|
|
</html>
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
** index.html
|
|
|
|
|
|
|
|
index.html is the landing page of the project. It gives a list
|
|
|
|
overview over the active devices. In addition it shows some useful
|
|
|
|
information about the devices like IP addresses and similar
|
|
|
|
information.
|
|
|
|
|
|
|
|
#+BEGIN_SRC html :tangle ../inventory/templates/inventory/index.html
|
|
|
|
{% extends "inventory/base.html" %}
|
|
|
|
{% block content %}
|
|
|
|
{% if device_list or computer_list %}
|
2017-12-25 23:55:07 +01:00
|
|
|
<h3>Device List</h3>
|
2017-12-25 00:37:31 +01:00
|
|
|
<ul>
|
|
|
|
{% for device in device_list %}
|
|
|
|
<li><a href="{% url 'device' device.id %}">{{ device.name }}</a></li>
|
|
|
|
{% endfor %}
|
2017-12-25 23:55:07 +01:00
|
|
|
</ul>
|
|
|
|
<h3>Computer List</h3>
|
2017-12-26 11:14:58 +01:00
|
|
|
<table cellpadding="10">
|
2017-12-25 23:55:07 +01:00
|
|
|
<tr>
|
|
|
|
<th>Hostname</th>
|
|
|
|
<th>IP</th>
|
|
|
|
</tr>
|
2017-12-25 00:37:31 +01:00
|
|
|
{% for computer in computer_list %}
|
2017-12-25 23:55:07 +01:00
|
|
|
<tr>
|
|
|
|
<td><a href="{% url 'computer' computer.id %}">{{ computer.name }}</a></td>
|
|
|
|
<td>{{ computer.ip }}</td>
|
|
|
|
</tr>
|
2017-12-25 00:37:31 +01:00
|
|
|
{% endfor %}
|
2017-12-25 23:55:07 +01:00
|
|
|
</table>
|
2017-12-25 00:37:31 +01:00
|
|
|
{% endif %}
|
2017-12-26 11:36:28 +01:00
|
|
|
{% if cronjob_list %}
|
|
|
|
<h3>Cron Job List</h3>
|
|
|
|
<table cellpadding="10">
|
|
|
|
<tr>
|
|
|
|
<th>Name</th>
|
|
|
|
<th>Hostname</th>
|
2017-12-27 16:33:53 +01:00
|
|
|
<th>Minute</th>
|
|
|
|
<th>Hour</th>
|
2017-12-26 11:36:28 +01:00
|
|
|
<th>Day of Week</th>
|
|
|
|
<th>Day of Month</th>
|
|
|
|
<th>Month</th>
|
|
|
|
</tr>
|
|
|
|
{% for cronjob in cronjob_list %}
|
|
|
|
<tr>
|
|
|
|
<td><a href="{% url 'cronjob' cronjob.id %}">{{ cronjob.name }}</a></td>
|
|
|
|
<td>{{ cronjob.host }}</td>
|
2017-12-27 16:33:53 +01:00
|
|
|
<td>{{ cronjob.minutes }}</td>
|
|
|
|
<td>{{ cronjob.hours }}</td>
|
2017-12-26 11:36:28 +01:00
|
|
|
<td>{{ cronjob.weekday }}</td>
|
|
|
|
<td>{{ cronjob.day }}</td>
|
|
|
|
<td>{{ cronjob.month }}</td>
|
|
|
|
</tr>
|
|
|
|
{% endfor %}
|
|
|
|
</table>
|
|
|
|
{% endif %}
|
2017-12-25 00:37:31 +01:00
|
|
|
{% endblock %}
|
2017-12-22 14:13:51 +01:00
|
|
|
#+END_SRC
|
2017-12-25 13:38:31 +01:00
|
|
|
|
2017-12-25 13:50:32 +01:00
|
|
|
** device_details.html
|
|
|
|
|
|
|
|
#+BEGIN_SRC html :tangle ../inventory/templates/inventory/device_details.html
|
|
|
|
{% extends "inventory/base.html" %}
|
|
|
|
{% block section_title %}{{ device.name }}{% endblock %}
|
|
|
|
{% block content %}
|
|
|
|
<h3>Description</h3>
|
|
|
|
<p>{{ device.description }}</p>
|
|
|
|
{% endblock %}
|
|
|
|
#+END_SRC
|
|
|
|
|
2017-12-25 13:38:31 +01:00
|
|
|
** computer_details.html
|
|
|
|
|
|
|
|
The computer details show all the known information about the selected computer.
|
|
|
|
|
|
|
|
#+BEGIN_SRC html :tangle ../inventory/templates/inventory/computer_details.html
|
|
|
|
{% extends "inventory/base.html" %}
|
|
|
|
{% block section_title %}{{ computer.name }}{% endblock %}
|
|
|
|
{% block content %}
|
|
|
|
<h3>Description</h3>
|
|
|
|
<p>{{ computer.description }}</p>
|
|
|
|
<p><b>OS:</b> {{ computer.os }}</p>
|
|
|
|
<p><b>CPU:</b> {{ cpu.cpu }}</p>
|
2017-12-26 11:14:27 +01:00
|
|
|
<p><b>RAM Modules: </b>{{ ram.amount }}x {{ ram.ram }}</p>
|
2017-12-25 13:38:31 +01:00
|
|
|
<p><b>IP:</b> {{ computer.ip }}</p>
|
2017-12-26 11:13:14 +01:00
|
|
|
{% if disks_list %}
|
|
|
|
<p><b>Disks:</b></p>
|
|
|
|
<p>
|
|
|
|
<ul>
|
|
|
|
{% for disk in disks_list %}
|
|
|
|
<li>{{ disk.amount }}x {{ disk.disk }}</li>
|
|
|
|
{% endfor %}
|
|
|
|
</ul>
|
|
|
|
</p>
|
|
|
|
{% endif %}
|
2017-12-25 13:38:31 +01:00
|
|
|
<p><b>Host:</b> {{ computer.host }}</p>
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
The list of cron jobs running on the computer get's only displayed if
|
|
|
|
there are any cron jobs.
|
|
|
|
|
2017-12-25 13:50:47 +01:00
|
|
|
#+BEGIN_SRC html :tangle ../inventory/templates/inventory/computer_details.html :padline 0
|
2017-12-25 13:38:31 +01:00
|
|
|
{% if cronjob_list %}
|
|
|
|
<p><b>Cron Jobs:</b></p>
|
|
|
|
<p>
|
|
|
|
<ul>
|
|
|
|
{% for cronjob in cronjob_list %}
|
2017-12-27 16:36:56 +01:00
|
|
|
<li><a href="{% url 'cronjob' cronjob.id %}">{{ cronjob.name }}</a></li>
|
2017-12-25 13:38:31 +01:00
|
|
|
{% endfor %}
|
|
|
|
</ul>
|
|
|
|
</p>
|
|
|
|
{% endif %}
|
|
|
|
{% endblock %}
|
|
|
|
#+END_SRC
|
|
|
|
|
2017-12-25 13:38:45 +01:00
|
|
|
** cronjob_details.html
|
|
|
|
|
2017-12-27 16:33:53 +01:00
|
|
|
The cron job details page shows all the information related to a cron job.
|
2017-12-25 13:38:45 +01:00
|
|
|
|
|
|
|
#+BEGIN_SRC html :tangle ../inventory/templates/inventory/cronjob_details.html
|
|
|
|
{% extends "inventory/base.html" %}
|
|
|
|
{% block section_title %}{{ cronjob.name }}{% endblock %}
|
|
|
|
{% block content %}
|
2017-12-27 16:33:53 +01:00
|
|
|
<h3>Description</h3>
|
2017-12-27 16:41:03 +01:00
|
|
|
<p><b>Host:</b> <a href="{% url 'computer' cronjob.host.id %}">{{ cronjob.host }}</a></p>
|
2017-12-27 16:33:53 +01:00
|
|
|
<p><b>Command: </b>{{ cronjob.command }}</p>
|
|
|
|
<table cellpadding="10">
|
|
|
|
<tr>
|
|
|
|
<th>Minute</th>
|
|
|
|
<th>Hour</th>
|
|
|
|
<th>Day of Week</th>
|
|
|
|
<th>Day of Month</th>
|
|
|
|
<th>Month</th>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>{{ cronjob.minutes }}</td>
|
|
|
|
<td>{{ cronjob.hours }}</td>
|
|
|
|
<td>{{ cronjob.weekday }}</td>
|
|
|
|
<td>{{ cronjob.day }}</td>
|
|
|
|
<td>{{ cronjob.month }}</td>
|
|
|
|
</tr>
|
|
|
|
</table>
|
2017-12-25 13:38:45 +01:00
|
|
|
{% endblock %}
|
|
|
|
#+END_SRC
|