Revision 54ae949d snf-app/synnefo/db/models.py
b/snf-app/synnefo/db/models.py | ||
---|---|---|
52 | 52 |
name = models.CharField('Synnefo Username', max_length=255, default='') |
53 | 53 |
realname = models.CharField('Real Name', max_length=255, default='') |
54 | 54 |
uniq = models.CharField('External Unique ID', max_length=255,null=True) |
55 |
credit = models.IntegerField('Credit Balance') |
|
56 | 55 |
auth_token = models.CharField('Authentication Token', max_length=32, |
57 | 56 |
null=True) |
58 | 57 |
auth_token_created = models.DateTimeField('Time of auth token creation', |
... | ... | |
69 | 68 |
max_length=30, default='ACTIVE') |
70 | 69 |
created = models.DateTimeField('Time of creation', auto_now_add=True) |
71 | 70 |
updated = models.DateTimeField('Time of last update', auto_now=True) |
72 |
max_invitations = models.IntegerField('Max number of invitations', |
|
73 |
null=True) |
|
74 | 71 |
|
75 | 72 |
def __unicode__(self): |
76 | 73 |
return self.name |
77 | 74 |
|
78 |
def get_limit(self, limit_name): |
|
79 |
"""Returns the limit value for the specified limit""" |
|
80 |
limit_objs = Limit.objects.filter(name=limit_name, user=self) |
|
81 |
if len(limit_objs) == 1: |
|
82 |
return limit_objs[0].value |
|
83 |
return 0 |
|
84 |
|
|
85 |
@property |
|
86 |
def credit_quota(self): |
|
87 |
"""Internal getter function for credit quota""" |
|
88 |
return self.get_limit('QUOTA_CREDIT') |
|
89 |
|
|
90 |
@property |
|
91 |
def monthly_rate(self): |
|
92 |
"""Internal getter function for monthly credit issue rate""" |
|
93 |
return self.get_limit('MONTHLY_RATE') |
|
94 |
|
|
95 |
@property |
|
96 |
def min_credits(self): |
|
97 |
"""Internal getter function for maximum number of violations""" |
|
98 |
return self.get_limit('MIN_CREDITS') |
|
99 |
|
|
100 | 75 |
|
101 | 76 |
class Image(models.Model): |
102 | 77 |
IMAGE_STATES = ( |
... | ... | |
143 | 118 |
return u'%s: %s' % (self.meta_key, self.meta_value) |
144 | 119 |
|
145 | 120 |
|
146 |
class Limit(models.Model): |
|
147 |
LIMITS = ( |
|
148 |
('QUOTA_CREDIT', 'Maximum amount of credits per user'), |
|
149 |
('MIN_CREDITS', 'Minimum amount of credits per user'), |
|
150 |
('MONTHLY_RATE', 'Monthly credit issue rate') |
|
151 |
) |
|
152 |
user = models.ForeignKey(SynnefoUser) |
|
153 |
name = models.CharField('Limit key name', choices=LIMITS, max_length=30, |
|
154 |
null=False) |
|
155 |
value = models.IntegerField('Limit current value') |
|
156 |
|
|
157 |
class Meta: |
|
158 |
verbose_name = u'Enforced limit for user' |
|
159 |
|
|
160 |
def __unicode__(self): |
|
161 |
return u'Limit %s for user %s: %d' % (self.value, self.user, |
|
162 |
self.value) |
|
163 |
|
|
164 |
|
|
165 | 121 |
class Flavor(models.Model): |
166 | 122 |
cpu = models.IntegerField('Number of CPUs', default=0) |
167 | 123 |
ram = models.IntegerField('RAM size in MiB', default=0) |
... | ... | |
178 | 134 |
def name(self): |
179 | 135 |
"""Returns flavor name (generated)""" |
180 | 136 |
return u'C%dR%dD%d' % (self.cpu, self.ram, self.disk) |
181 |
|
|
182 |
def _current_cost(self, active): |
|
183 |
"""Returns active/inactive cost value |
|
184 |
|
|
185 |
set active = True to get active cost and False for the inactive. |
|
186 |
""" |
|
187 |
|
|
188 |
costs = FlavorCost.objects.filter(flavor=self) |
|
189 |
fch_list = costs.order_by('-effective_from') |
|
190 |
if len(fch_list) > 0: |
|
191 |
if active: |
|
192 |
return fch_list[0].cost_active |
|
193 |
else: |
|
194 |
return fch_list[0].cost_inactive |
|
195 |
|
|
196 |
return 0 |
|
197 |
|
|
198 |
@property |
|
199 |
def current_cost_active(self): |
|
200 |
"""Returns current active cost (property method)""" |
|
201 |
return self._current_cost(True) |
|
202 |
|
|
203 |
@property |
|
204 |
def current_cost_inactive(self): |
|
205 |
"""Returns current inactive cost (property method)""" |
|
206 |
return self._current_cost(False) |
|
207 | 137 |
|
208 | 138 |
def __unicode__(self): |
209 | 139 |
return self.name |
210 | 140 |
|
211 | 141 |
|
212 |
class FlavorCost(models.Model): |
|
213 |
cost_active = models.PositiveIntegerField('Active Cost') |
|
214 |
cost_inactive = models.PositiveIntegerField('Inactive Cost') |
|
215 |
effective_from = models.DateTimeField() |
|
216 |
flavor = models.ForeignKey(Flavor) |
|
217 |
|
|
218 |
class Meta: |
|
219 |
verbose_name = u'Pricing history for flavors' |
|
220 |
|
|
221 |
def __unicode__(self): |
|
222 |
return u'Costs (up, down)=(%d, %d) for %s since %s' % ( |
|
223 |
int(self.cost_active), int(self.cost_inactive), |
|
224 |
self.flavor.name, self.effective_from) |
|
225 |
|
|
226 |
|
|
227 | 142 |
class VirtualMachine(models.Model): |
228 | 143 |
# The list of possible actions for a VM |
229 | 144 |
ACTIONS = ( |
... | ... | |
396 | 311 |
return self.name |
397 | 312 |
|
398 | 313 |
|
399 |
class VirtualMachineGroup(models.Model): |
|
400 |
"""Groups of VMs for SynnefoUsers""" |
|
401 |
name = models.CharField(max_length=255) |
|
402 |
created = models.DateTimeField('Time of creation', auto_now_add=True) |
|
403 |
updated = models.DateTimeField('Time of last update', auto_now=True) |
|
404 |
owner = models.ForeignKey(SynnefoUser) |
|
405 |
machines = models.ManyToManyField(VirtualMachine) |
|
406 |
|
|
407 |
class Meta: |
|
408 |
verbose_name = u'Virtual Machine Group' |
|
409 |
verbose_name_plural = 'Virtual Machine Groups' |
|
410 |
ordering = ['name'] |
|
411 |
|
|
412 |
def __unicode__(self): |
|
413 |
return self.name |
|
414 |
|
|
415 |
|
|
416 | 314 |
class VirtualMachineMetadata(models.Model): |
417 | 315 |
meta_key = models.CharField(max_length=50) |
418 | 316 |
meta_value = models.CharField(max_length=500) |
... | ... | |
426 | 324 |
return u'%s: %s' % (self.meta_key, self.meta_value) |
427 | 325 |
|
428 | 326 |
|
429 |
class Debit(models.Model): |
|
430 |
when = models.DateTimeField() |
|
431 |
user = models.ForeignKey(SynnefoUser) |
|
432 |
vm = models.ForeignKey(VirtualMachine) |
|
433 |
description = models.TextField() |
|
434 |
|
|
435 |
class Meta: |
|
436 |
verbose_name = u'Accounting log' |
|
437 |
|
|
438 |
def __unicode__(self): |
|
439 |
return u'%s - %s - %s - %s' % (self.user.id, self.vm.name, |
|
440 |
self.when, self.description) |
|
441 |
|
|
442 |
|
|
443 | 327 |
class Disk(models.Model): |
444 | 328 |
name = models.CharField(max_length=255) |
445 | 329 |
created = models.DateTimeField('Time of creation', auto_now_add=True) |
... | ... | |
475 | 359 |
return self.name |
476 | 360 |
|
477 | 361 |
|
478 |
class Invitations(models.Model): |
|
479 |
source = models.ForeignKey(SynnefoUser, related_name="source") |
|
480 |
target = models.ForeignKey(SynnefoUser, related_name="target") |
|
481 |
accepted = models.BooleanField('Is the invitation accepted?', |
|
482 |
default=False) |
|
483 |
created = models.DateTimeField(auto_now_add=True) |
|
484 |
updated = models.DateTimeField(auto_now=True) |
|
485 |
level = models.IntegerField('Invitation depth level', null=True) |
|
486 |
|
|
487 |
def __unicode__(self): |
|
488 |
return "From: %s, To: %s" % (self.source, self.target) |
|
489 |
|
|
490 |
|
|
491 | 362 |
class NetworkInterface(models.Model): |
492 | 363 |
FIREWALL_PROFILES = ( |
493 | 364 |
('ENABLED', 'Enabled'), |
Also available in: Unified diff