Ability to pull Sliver stats
[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 User
12 from core.models import Tag
13 from core.models import Flavor
14 from django.contrib.contenttypes import generic
15 from planetstack.config import Config
16 from monitor import driver as monitor
17
18 config = Config()
19
20 def get_default_flavor(deployment = 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 deployment:
26         flavors = deployment.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__deployment__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__deployment__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     deploymentNetwork = models.ForeignKey(Deployment, verbose_name='deployment', related_name='sliver_deploymentNetwork')
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.deploymentNetwork = self.node.deployment
112
113 # XXX smbaker - disabled for now, was causing fault in tenant view create slice
114 #        if not self.deploymentNetwork.test_acl(slice=self.slice):
115 #            raise exceptions.ValidationError("Deployment %s's ACL does not allow any of this slice %s's users" % (self.deploymentNetwork.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