Add Nullable Lab Field to Resources
[pharos-tools.git] / dashboard / src / dashboard / models.py
1 ##############################################################################
2 # Copyright (c) 2016 Max Breitenfeldt and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10
11 from datetime import timedelta
12
13 from django.contrib.auth.models import User
14 from django.db import models
15 from django.utils import timezone
16
17 from jenkins.models import JenkinsSlave
18 from account.models import Lab
19
20
21 class Resource(models.Model):
22     id = models.AutoField(primary_key=True)
23     name = models.CharField(max_length=100, unique=True)
24     description = models.CharField(max_length=300, blank=True, null=True)
25     url = models.CharField(max_length=100, blank=True, null=True)
26     resource_lab = models.ForeignKey(Lab, related_name='lab_resource_set', null=True, blank=True)
27     owner = models.ForeignKey(User, related_name='user_lab_owner', null=True, blank=True)
28     vpn_users = models.ManyToManyField(User, related_name='user_vpn_users', blank=True)
29     slave = models.ForeignKey(JenkinsSlave, on_delete=models.DO_NOTHING, null=True, blank=True)
30     dev_pod = models.BooleanField(default=False)
31
32     def get_booking_utilization(self, weeks):
33         """
34         Return a dictionary containing the count of booked and free seconds for a resource in the
35         range [now,now + weeks] if weeks is positive,
36         or [now-weeks, now] if weeks is negative
37         """
38
39         length = timedelta(weeks=abs(weeks))
40         now = timezone.now()
41
42         start = now
43         end = now + length
44         if weeks < 0:
45             start = now - length
46             end = now
47
48         bookings = self.booking_set.filter(start__lt=start + length, end__gt=start)
49
50         booked_seconds = 0
51         for booking in bookings:
52             booking_start = booking.start
53             booking_end = booking.end
54             if booking_start < start:
55                 booking_start = start
56             if booking_end > end:
57                 booking_end = start + length
58             total = booking_end - booking_start
59             booked_seconds += total.total_seconds()
60
61         return {'booked_seconds': booked_seconds,
62                 'available_seconds': length.total_seconds() - booked_seconds}
63
64     class Meta:
65         db_table = 'resource'
66
67     def __str__(self):
68         return self.name
69
70 class Server(models.Model):
71     id = models.AutoField(primary_key=True)
72     resource = models.ForeignKey(Resource, on_delete=models.CASCADE)
73     name = models.CharField(max_length=100, blank=True)
74     model = models.CharField(max_length=100, blank=True)
75     cpu = models.CharField(max_length=100, blank=True)
76     ram = models.CharField(max_length=100, blank=True)
77     storage = models.CharField(max_length=100, blank=True)
78
79     class Meta:
80         db_table = 'server'
81
82     def __str__(self):
83         return self.name
84
85 class ResourceStatus(models.Model):
86     id = models.AutoField(primary_key=True)
87     resource = models.ForeignKey(Resource, on_delete=models.CASCADE)
88     timestamp = models.DateTimeField(auto_now_add=True)
89     type = models.CharField(max_length=20)
90     title = models.CharField(max_length=50)
91     content = models.CharField(max_length=5000)
92
93     class Meta:
94         db_table = 'resource_status'
95
96     def __str__(self):
97         return self.resource.name + ': ' + self.title + ' ' + str(self.timestamp)