Statistics
| Branch: | Tag: | Revision:

root / db / models.py @ 04a6d900

History | View | Annotate | Download (6 kB)

1
# vim: ts=4 sts=4 et ai sw=4 fileencoding=utf-8
2

    
3
from django.conf import settings
4
from django.db import models
5
from django.contrib.auth.models import User
6
from django.utils.translation import gettext_lazy as _
7

    
8
import datetime
9

    
10
import vocabs
11

    
12
backend_prefix_id = settings.BACKEND_PREFIX_ID
13

    
14
#this needs to be called not only from inside VirtualMachine. 
15
#atm it is not working with the current ganeti naming - machine1, machine2
16
def id_from_instance_name(name):
17
    """ Returns VirtualMachine's Django id, given a ganeti machine name.
18

19
    Strips the ganeti prefix atm. Needs a better name!
20
    """
21
    return '%s' % (str(name).strip(backend_prefix_id))
22

    
23

    
24
class Limit(models.Model):
25
    description = models.CharField(max_length=45)
26
    
27
    class Meta:
28
        verbose_name = u'User limit'
29
    
30
    def __unicode__(self):
31
        return self.description
32

    
33

    
34
class OceanUser(models.Model):
35
    name = models.CharField(max_length=255)
36
    credit = models.IntegerField()
37
    quota = models.IntegerField()
38
    created = models.DateField()
39
    monthly_rate = models.IntegerField()
40
    #user = models.ForeignKey(User, unique=True)
41
    limits = models.ManyToManyField(Limit, through='UserLimit')
42
    
43
    class Meta:
44
        verbose_name = u'Ocean User'
45
    
46
    def __unicode__(self):
47
        return self.name
48
    
49
    def charge_credits(self, cost):
50
        """Reduce user credits for the specified cost. 
51
        Returns amount of credits remaining. Negative if the user surpassed his limit."""
52
        self.credit = self.credit - cost
53
        rcredit = self.credit
54
                
55
        if self.credit < 0:
56
            self.credit = 0
57
        
58
        return rcredit        
59
    
60
    def allocate_credits(self):
61
        """Allocate credits. Add monthly rate to user credit reserve."""
62
        self.credit = self.credit + self.monthly_rate
63
        
64
        # ensure that the user has not more credits than his quota
65
        if self.credit > self.quota:
66
            self.credit = self.quota
67

    
68

    
69
class UserLimit(models.Model):
70
    user = models.ForeignKey(OceanUser)
71
    limit = models.ForeignKey(Limit)
72
    value = models.IntegerField()
73
    
74
    class Meta:
75
        unique_together = ('user', 'limit')
76
        verbose_name = u'Enforced limit for user'
77
    
78
    def __unicode__(self):
79
        return u'Limit %s for user %s: %d' % (self.limit, self.user, self.value)
80

    
81

    
82
class Flavor(models.Model):
83
    cpu = models.IntegerField(default=0)
84
    ram = models.IntegerField(default=0)
85
    disk = models.IntegerField(default=0)
86
    
87
    class Meta:
88
        verbose_name = u'Virtual machine flavor'
89
            
90
    def _get_name(self):
91
        """Returns flavor name"""
92
        return u'C%dR%dD%d' % ( self.cpu, self.ram, self.disk )
93

    
94
    def _get_cost_inactive(self):
95
        self._update_costs()
96
        return self._cost_inactive
97

    
98
    def _get_cost_active(self):
99
        self._update_costs()
100
        return self._cost_active
101
    
102
    def _update_costs(self):
103
        # if _cost
104
        if '_cost_active' not in dir(self):
105
            fch = FlavorCostHistory.objects.filter(flavor=self).order_by('-effective_from')[0]
106
            self._cost_active = fch.cost_active
107
            self._cost_inactive = fch.cost_inactive
108

    
109
    name = property(_get_name)
110
    cost_active = property(_get_cost_active)
111
    cost_inactive = property(_get_cost_inactive)
112

    
113
    def __unicode__(self):
114
        return self.name
115

    
116

    
117
class FlavorCostHistory(models.Model):
118
    cost_active = models.PositiveIntegerField()
119
    cost_inactive = models.PositiveIntegerField()
120
    effective_from = models.DateField()
121
    flavor = models.ForeignKey(Flavor)
122
    
123
    class Meta:
124
        verbose_name = u'Pricing history for flavors'
125
    
126
    def __unicode__(self):
127
        return u'Costs (up, down)=(%d, %d) for %s since %s' % ( cost_active, cost_inactive, flavor.name, effective_from )
128

    
129

    
130
class VirtualMachine(models.Model):
131
    name = models.CharField(max_length=255)
132
    created = models.DateTimeField()
133
    state = models.CharField(choices=vocabs.STATES, max_length=30)
134
    charged = models.DateTimeField()
135
    imageid = models.IntegerField()
136
    hostid = models.CharField(max_length=100)
137
    server_label = models.CharField(max_length=100)
138
    image_version = models.CharField(max_length=100)
139
    ipfour = models.IPAddressField()
140
    ipsix = models.CharField(max_length=100)
141
    owner = models.ForeignKey(OceanUser)
142
    flavor = models.ForeignKey(Flavor)
143
    
144
    class Meta:
145
        verbose_name = u'Virtual machine instance'
146
        get_latest_by = 'created'
147
    
148
    def __unicode__(self):
149
        return self.name
150

    
151
    def _get_backend_id(self):
152
        """Returns the backend id for this VM by prepending backend-prefix."""
153
        return '%s%s' % (backend_prefix_id, str(self.id))
154

    
155
    backend_id = property(_get_backend_id)
156

    
157

    
158
class VirtualMachineMetadata(models.Model):
159
    meta_key = models.CharField(max_length=50)
160
    meta_value = models.CharField(max_length=500)
161
    vm = models.ForeignKey(VirtualMachine)
162
    
163
    class Meta:
164
        verbose_name = u'Key-value pair of metadata for a VM.'
165
    
166
    def __unicode__(self):
167
        return u'%s, %s for %s' % ( self.key, self.value, self.vm.name )
168

    
169

    
170
class AccountingLog(models.Model):
171
    vm = models.ForeignKey(VirtualMachine)
172
    date = models.DateTimeField()
173
    state = models.CharField(choices=vocabs.STATES, max_length=30)
174
    
175
    class Meta:
176
        verbose_name = u'Accounting log'
177

    
178
    def __unicode__(self):
179
        return u'%s %s %s' % ( self.vm.name, self.date, self.state )
180

    
181

    
182
class Image(models.Model):
183
    name = models.CharField(max_length=255, help_text=_('description'))
184
    updated = models.DateTimeField(help_text=_("Image update date"))
185
    created = models.DateTimeField(help_text=_("Image creation date"), default=datetime.datetime.now)
186
    state = models.CharField(choices=vocabs.STATES, max_length=30)
187
    description = models.TextField(help_text=_('description'))
188
    serverid = models.IntegerField(help_text=_('description'))
189
    vm = models.ForeignKey(VirtualMachine)
190
    
191
    class Meta:
192
        verbose_name = u'Image'
193

    
194
    def __unicode__(self):
195
        return u'%s' % ( self.name )