Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from django.db import models 

2from django.core.validators import RegexValidator, MinValueValidator, MaxValueValidator 

3from django.utils.functional import cached_property 

4from django.utils import timezone 

5from django.conf import settings 

6 

7 

8class PDU(models.Model): 

9 name = models.CharField(unique=True, help_text="Name of the PDU", max_length=80) 

10 

11 pdu_model = models.CharField(max_length=80, help_text="Model of the PDU you are using") 

12 config = models.JSONField(blank=True, default=dict, 

13 help_text="Opaque configuration needed to instanciate the PDU") 

14 

15 def __str__(self): 

16 return f"<PDU: {self.name}>" 

17 

18 

19class Machine(models.Model): 

20 # Naming and tagging 

21 base_name = models.CharField(max_length=50, 

22 help_text="Non-unique name that will form the basis for the full name") 

23 tags = models.JSONField(blank=True, null=True, default=list, 

24 help_text="List of tags that the machine has") 

25 

26 # Network 

27 mac_address = \ 

28 models.CharField(max_length=17, unique=True, blank=False, null=False, 

29 validators=[ 

30 RegexValidator( 

31 regex='^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$', code='invalid_format', 

32 message='Format: 60:6d:3c:51:c4:88', 

33 )]) 

34 ip_address = models.GenericIPAddressField(blank=False, null=False) 

35 

36 local_tty_device = \ 

37 models.CharField(max_length=16, blank=True, null=True, 

38 help_text=("Machine-local TTY device that can be used as a serial console. " 

39 "See the `console=` format at " 

40 "https://www.kernel.org/doc/html/latest/admin-guide/serial-console.html")) 

41 

42 # PDU 

43 pdu = models.ForeignKey(PDU, null=True, blank=True, on_delete=models.SET_NULL, 

44 help_text="PDU to which this machine is connected to") 

45 pdu_port_id = models.CharField(max_length=80, blank=True, null=True, 

46 help_text="ID of the port to which this machine is connected to") 

47 pdu_off_delay = models.PositiveSmallIntegerField(default=5, 

48 validators=[ 

49 MaxValueValidator(100), 

50 MinValueValidator(1) 

51 ], 

52 help_text="Number of seconds to wait in a ON->OFF->ON transition") 

53 

54 # Flags 

55 ready_for_service = models.BooleanField(blank=False, null=False, default=False, 

56 help_text="Is the machine fit for service?") 

57 is_retired = models.BooleanField(blank=False, null=False, default=False, 

58 help_text="Has the machine been retired?") 

59 

60 # Some statistics 

61 first_seen = models.DateTimeField(auto_now_add=True, 

62 help_text='When this MAC address was first seen') 

63 last_updated = models.DateTimeField(auto_now=True, 

64 help_text='When this machine was last modified') 

65 

66 class Meta: 

67 ordering = ['-id'] 

68 

69 @cached_property 

70 def full_name(self): 

71 if self.pk is None: 

72 raise ValueError("The Machine needs to be saved before a name can be generated") 

73 

74 idx = Machine.objects.filter(base_name=self.base_name, id__lte=self.id).count() 

75 return f"{settings.FARM_NAME}-{self.base_name}-{idx}" 

76 

77 def __str__(self): 

78 return f"<Machine: {self.full_name}>" 

79 

80 

81class Event(models.Model): 

82 machine = models.ForeignKey( 

83 Machine, 

84 on_delete=models.CASCADE, 

85 help_text='The machine this event originated from.') 

86 

87 CATEGORY_MACHINE_CREATED = 'machine-created' 

88 CATEGORY_MACHINE_UPDATED = 'machine-updated' 

89 CATEGORY_MACHINE_RETIRED = 'machine-retired' 

90 

91 CATEGORY_CHOICES = ( 

92 (CATEGORY_MACHINE_CREATED, 'Machine has been created'), 

93 (CATEGORY_MACHINE_UPDATED, 'Machine has been updated'), 

94 (CATEGORY_MACHINE_RETIRED, 'Machine has been retired'), 

95 ) 

96 

97 category = models.CharField( 

98 max_length=25, 

99 choices=CATEGORY_CHOICES, 

100 help_text='The category of the event.') 

101 date = models.DateTimeField( 

102 default=timezone.now, 

103 help_text='The time this event was created.') 

104 

105 diff = models.JSONField(blank=True, null=True, 

106 help_text="Dictionary of differences before and after the machine changed") 

107 

108 def __str__(self): 

109 return f"<Event id={self.id} machine={self.machine} category={self.category}>" 

110 

111 class Meta: 

112 ordering = ['-date']