refactor and bug fixes
[plstackapi.git] / planetstack / core / models / sliver.py
1 import os
2 from django.db import models
3 from django.db.models import Q
4 from django.core import exceptions
5 from core.models import PlCoreBase,PlCoreBaseManager,PlCoreBaseDeletionManager
6 from core.models import Image
7 from core.models import Slice
8 from core.models import Node
9 from core.models import Site
10 from core.models import Deployment
11 from core.models import Controller
12 from core.models import User
13 from core.models import Tag
14 from core.models import Flavor
15 from django.contrib.contenttypes import generic
16 from planetstack.config import Config
17
18 config = Config()
19
20 def get_default_flavor(controller = None):
21     # Find a default flavor that can be used for a sliver. This is particularly
22     # useful in evolution. It's also intended this helper function can be used
23     # for admin.py when users
24
25     if controller:
26         flavors = controller.flavors.all()
27     else:
28         flavors = Flavor.objects.all()
29
30     if not flavors:
31         return None
32
33     for flavor in flavors:
34         if flavor.default:
35             return flavor
36
37     return flavors[0]
38
39 class SliverDeletionManager(PlCoreBaseDeletionManager):
40     def get_queryset(self):
41         parent=super(SliverDeletionManager, self)
42         try:
43             backend_type = config.observer_backend_type
44         except AttributeError:
45             backend_type = None
46
47         parent_queryset = parent.get_queryset() if hasattr(parent, "get_queryset") else parent.get_query_set()
48         if (backend_type):
49             return parent_queryset.filter(Q(node__controller__backend_type=backend_type))
50         else:
51             return parent_queryset
52
53     # deprecated in django 1.7 in favor of get_queryset().
54     def get_query_set(self):
55         return self.get_queryset()
56
57
58 class SliverManager(PlCoreBaseManager):
59     def get_queryset(self):
60         parent=super(SliverManager, self)
61
62         try:
63             backend_type = config.observer_backend_type
64         except AttributeError:
65             backend_type = None
66
67         parent_queryset = parent.get_queryset() if hasattr(parent, "get_queryset") else parent.get_query_set()
68
69         if backend_type:
70             return parent_queryset.filter(Q(node__controller__backend_type=backend_type))
71         else:
72             return parent_queryset
73
74     # deprecated in django 1.7 in favor of get_queryset().
75     def get_query_set(self):
76         return self.get_queryset()
77
78 # Create your models here.
79 class Sliver(PlCoreBase):
80     objects = SliverManager()
81     deleted_objects = SliverDeletionManager()
82     instance_id = models.CharField(null=True, blank=True, max_length=200, help_text="Nova instance id")
83     name = models.CharField(max_length=200, help_text="Sliver name")
84     instance_name = models.CharField(blank=True, null=True, max_length=200, help_text="OpenStack generated name")
85     ip = models.GenericIPAddressField(help_text="Sliver ip address", blank=True, null=True)
86     image = models.ForeignKey(Image, related_name='slivers')
87     #key = models.ForeignKey(Key, related_name='slivers')
88     creator = models.ForeignKey(User, related_name='slivers', blank=True, null=True)
89     slice = models.ForeignKey(Slice, related_name='slivers')
90     node = models.ForeignKey(Node, related_name='slivers')
91     controllerNetwork = models.ForeignKey(Controller, verbose_name='controller', related_name='sliver_controllerNetwork')
92     numberCores = models.IntegerField(verbose_name="Number of Cores", help_text="Number of cores for sliver", default=0)
93     flavor = models.ForeignKey(Flavor, help_text="Flavor of this instance", default=get_default_flavor)
94     tags = generic.GenericRelation(Tag)
95     userData = models.TextField(blank=True, null=True, help_text="user_data passed to instance during creation")
96
97     def __unicode__(self):
98         if self.instance_name:
99             return u'%s' % (self.instance_name)
100         elif self.id:
101             return u'uninstantiated-%s' % str(self.id)
102         elif self.slice:
103             return u'unsaved-sliver on %s' % self.slice.name
104         else:
105             return u'unsaved-sliver'
106
107     def save(self, *args, **kwds):
108         self.name = self.slice.slicename
109         if not self.creator and hasattr(self, 'caller'):
110             self.creator = self.caller
111         self.controllerNetwork = self.node.controller
112
113 # XXX smbaker - disabled for now, was causing fault in tenant view create slice
114 #        if not self.controllerNetwork.test_acl(slice=self.slice):
115 #            raise exceptions.ValidationError("Deployment %s's ACL does not allow any of this slice %s's users" % (self.controllerNetwork.name, self.slice.name))
116
117         super(Sliver, self).save(*args, **kwds)
118
119     def can_update(self, user):
120         return self.slice.can_update(user)
121
122     def all_ips(self):
123         ips={}
124         for ns in self.networksliver_set.all():
125            ips[ns.network.name] = ns.ip
126         return ips
127
128     def all_ips_string(self):
129         result = []
130         ips = self.all_ips()
131         for key in sorted(ips.keys()):
132             #result.append("%s = %s" % (key, ips[key]))
133             result.append(ips[key])
134         return ", ".join(result)
135     all_ips_string.short_description = "addresses"
136
137     @staticmethod
138     def select_by_user(user):
139         if user.is_admin:
140             qs = Sliver.objects.all()
141         else:
142             slices = Slice.select_by_user(user)
143             qs = Sliver.objects.filter(slice__in=slices)
144         return qs