4d89d9fac5479b20e4f3ac77621668dce1dc5e02
[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 from monitor import driver as monitor
18
19 config = Config()
20
21 def get_default_flavor(controller = None):
22     # Find a default flavor that can be used for a sliver. This is particularly
23     # useful in evolution. It's also intended this helper function can be used
24     # for admin.py when users
25
26     if controller:
27         flavors = controller.flavors.all()
28     else:
29         flavors = Flavor.objects.all()
30
31     if not flavors:
32         return None
33
34     for flavor in flavors:
35         if flavor.default:
36             return flavor
37
38     return flavors[0]
39
40 class SliverDeletionManager(PlCoreBaseDeletionManager):
41     def get_queryset(self):
42         parent=super(SliverDeletionManager, self)
43         try:
44             backend_type = config.observer_backend_type
45         except AttributeError:
46             backend_type = None
47
48         parent_queryset = parent.get_queryset() if hasattr(parent, "get_queryset") else parent.get_query_set()
49         if (backend_type):
50             return parent_queryset.filter(Q(node__controller__backend_type=backend_type))
51         else:
52             return parent_queryset
53
54     # deprecated in django 1.7 in favor of get_queryset().
55     def get_query_set(self):
56         return self.get_queryset()
57
58
59 class SliverManager(PlCoreBaseManager):
60     def get_queryset(self):
61         parent=super(SliverManager, self)
62
63         try:
64             backend_type = config.observer_backend_type
65         except AttributeError:
66             backend_type = None
67
68         parent_queryset = parent.get_queryset() if hasattr(parent, "get_queryset") else parent.get_query_set()
69
70         if backend_type:
71             return parent_queryset.filter(Q(node__controller__backend_type=backend_type))
72         else:
73             return parent_queryset
74
75     # deprecated in django 1.7 in favor of get_queryset().
76     def get_query_set(self):
77         return self.get_queryset()
78
79 # Create your models here.
80 class Sliver(PlCoreBase):
81     objects = SliverManager()
82     deleted_objects = SliverDeletionManager()
83     instance_id = models.CharField(null=True, blank=True, max_length=200, help_text="Nova instance id")
84     name = models.CharField(max_length=200, help_text="Sliver name")
85     instance_name = models.CharField(blank=True, null=True, max_length=200, help_text="OpenStack generated name")
86     ip = models.GenericIPAddressField(help_text="Sliver ip address", blank=True, null=True)
87     image = models.ForeignKey(Image, related_name='slivers')
88     #key = models.ForeignKey(Key, related_name='slivers')
89     creator = models.ForeignKey(User, related_name='slivers', blank=True, null=True)
90     slice = models.ForeignKey(Slice, related_name='slivers')
91     deployment = models.ForeignKey(Deployment, verbose_name='deployment', related_name='sliver_deployment')
92     node = models.ForeignKey(Node, related_name='slivers')
93     numberCores = models.IntegerField(verbose_name="Number of Cores", help_text="Number of cores for sliver", default=0)
94     flavor = models.ForeignKey(Flavor, help_text="Flavor of this instance", default=get_default_flavor)
95     tags = generic.GenericRelation(Tag)
96     userData = models.TextField(blank=True, null=True, help_text="user_data passed to instance during creation")
97
98     def __unicode__(self):
99         if self.instance_name:
100             return u'%s' % (self.instance_name)
101         elif self.id:
102             return u'uninstantiated-%s' % str(self.id)
103         elif self.slice:
104             return u'unsaved-sliver on %s' % self.slice.name
105         else:
106             return u'unsaved-sliver'
107
108     def save(self, *args, **kwds):
109         self.name = self.slice.name
110         if not self.creator and hasattr(self, 'caller'):
111             self.creator = self.caller
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
145
146     def get_cpu_stats(self):
147         filter = 'instance_id=%s'%self.sliver_id
148         return monitor.get_meter('cpu',filter,None)
149
150     def get_bw_stats(self):
151         filter = 'instance_id=%s'%self.sliver_id
152         return monitor.get_meter('network.outgoing.bytes',filter,None)
153
154     def get_node_stats(self):
155         # Note sure what should go back here
156         return 1