blob: ae73b3e4aafc0a02877cc37a4d2a6e9390cad707 [file] [log] [blame]
Scott Bakerfa8fd292015-09-09 17:31:22 -07001from django.db import models
Tony Mack32010062015-09-13 22:50:39 +00002from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, Subscriber
Scott Bakerfa8fd292015-09-09 17:31:22 -07003from core.models.plcorebase import StrippedCharField
4import os
5from django.db import models, transaction
6from django.forms.models import model_to_dict
7from django.db.models import Q
8from operator import itemgetter, attrgetter, methodcaller
9import traceback
10from xos.exceptions import *
Scott Bakerddf8a942015-09-10 17:07:21 -070011from core.models import SlicePrivilege, SitePrivilege
12from sets import Set
Scott Bakerfa8fd292015-09-09 17:31:22 -070013
14CEILOMETER_KIND = "ceilometer"
15
16class CeilometerService(Service):
17 KIND = CEILOMETER_KIND
18
19 class Meta:
20 app_label = "ceilometer"
21 verbose_name = "Ceilometer Service"
22 proxy = True
23
24class MonitoringChannel(TenantWithContainer): # aka 'CeilometerTenant'
25 class Meta:
26 proxy = True
27
28 KIND = CEILOMETER_KIND
29
svavilapaf911082015-10-13 23:50:03 -040030 sync_attributes = ("private_ip", "private_mac",
31 "ceilometer_ip", "ceilometer_mac",
svavilapb4594032015-11-16 00:27:06 -060032 "nat_ip", "nat_mac", "ceilometer_port",)
svavilapaf911082015-10-13 23:50:03 -040033
Scott Bakerfa8fd292015-09-09 17:31:22 -070034 default_attributes = {}
35 def __init__(self, *args, **kwargs):
36 ceilometer_services = CeilometerService.get_service_objects().all()
37 if ceilometer_services:
38 self._meta.get_field("provider_service").default = ceilometer_services[0].id
39 super(MonitoringChannel, self).__init__(*args, **kwargs)
svavilapb4594032015-11-16 00:27:06 -060040 self.set_attribute("use_same_instance_for_multiple_tenants", True)
Scott Bakerfa8fd292015-09-09 17:31:22 -070041
svavilap14249982015-11-21 13:52:02 -060042 def can_update(self, user):
43 #Allow creation of this model instances for non-admin users also
44 return True
45
Scott Bakerfa8fd292015-09-09 17:31:22 -070046 def save(self, *args, **kwargs):
47 if not self.creator:
48 if not getattr(self, "caller", None):
Srikanth Vavilapallie9247d82015-10-28 23:52:29 -040049 # caller must be set when creating a monitoring channel since it creates a slice
Scott Bakerfa8fd292015-09-09 17:31:22 -070050 raise XOSProgrammingError("MonitoringChannel's self.caller was not set")
51 self.creator = self.caller
52 if not self.creator:
53 raise XOSProgrammingError("MonitoringChannel's self.creator was not set")
54
Srikanth Vavilapallie9247d82015-10-28 23:52:29 -040055 if self.pk is None:
56 #Allow only one monitoring channel per user
57 channel_count = sum ( [1 for channel in MonitoringChannel.objects.filter(kind=CEILOMETER_KIND) if (channel.creator == self.creator)] )
58 if channel_count > 0:
59 raise XOSValidationError("Already %s channels exist for user Can only create max 1 MonitoringChannel instance per user" % str(channel_count))
60
Scott Bakerfa8fd292015-09-09 17:31:22 -070061 super(MonitoringChannel, self).save(*args, **kwargs)
62 model_policy_monitoring_channel(self.pk)
63
64 def delete(self, *args, **kwargs):
Scott Baker588caf92015-09-09 17:57:51 -070065 self.cleanup_container()
Scott Bakerfa8fd292015-09-09 17:31:22 -070066 super(MonitoringChannel, self).delete(*args, **kwargs)
67
Scott Bakerddf8a942015-09-10 17:07:21 -070068 @property
Scott Bakerb37a99a2015-09-10 17:36:58 -070069 def addresses(self):
svavilapb4594032015-11-16 00:27:06 -060070 if (not self.id) or (not self.instance):
Scott Bakerb37a99a2015-09-10 17:36:58 -070071 return {}
72
73 addresses = {}
Tony Mack32010062015-09-13 22:50:39 +000074 for ns in self.instance.ports.all():
Scott Bakerb37a99a2015-09-10 17:36:58 -070075 if "private" in ns.network.name.lower():
76 addresses["private"] = (ns.ip, ns.mac)
77 elif "nat" in ns.network.name.lower():
78 addresses["nat"] = (ns.ip, ns.mac)
Scott Bakera9cf9c42015-09-10 17:46:47 -070079 elif "ceilometer_client_access" in ns.network.labels.lower():
80 addresses["ceilometer"] = (ns.ip, ns.mac)
Scott Bakerb37a99a2015-09-10 17:36:58 -070081 return addresses
82
83 @property
svavilapaf911082015-10-13 23:50:03 -040084 def nat_ip(self):
85 return self.addresses.get("nat", (None, None))[0]
86
87 @property
88 def nat_mac(self):
89 return self.addresses.get("nat", (None, None))[1]
90
91 @property
Scott Bakerb37a99a2015-09-10 17:36:58 -070092 def private_ip(self):
93 return self.addresses.get("nat", (None, None))[0]
94
95 @property
svavilapaf911082015-10-13 23:50:03 -040096 def private_mac(self):
97 return self.addresses.get("nat", (None, None))[1]
98
99 @property
Scott Bakera9cf9c42015-09-10 17:46:47 -0700100 def ceilometer_ip(self):
101 return self.addresses.get("ceilometer", (None, None))[0]
102
103 @property
svavilapaf911082015-10-13 23:50:03 -0400104 def ceilometer_mac(self):
105 return self.addresses.get("ceilometer", (None, None))[1]
106
107 @property
Scott Bakerddf8a942015-09-10 17:07:21 -0700108 def site_tenant_list(self):
109 tenant_ids = Set()
110 for sp in SitePrivilege.objects.filter(user=self.creator):
111 site = sp.site
112 for cs in site.controllersite.all():
113 if cs.tenant_id:
114 tenant_ids.add(cs.tenant_id)
115 return tenant_ids
116
117 @property
118 def slice_tenant_list(self):
119 tenant_ids = Set()
120 for sp in SlicePrivilege.objects.filter(user=self.creator):
121 slice = sp.slice
122 for cs in slice.controllerslices.all():
123 if cs.tenant_id:
124 tenant_ids.add(cs.tenant_id)
125 for slice in Slice.objects.filter(creator=self.creator):
126 for cs in slice.controllerslices.all():
127 if cs.tenant_id:
128 tenant_ids.add(cs.tenant_id)
129 return tenant_ids
130
131 @property
132 def tenant_list(self):
133 return self.slice_tenant_list | self.site_tenant_list
134
135 @property
136 def tenant_list_str(self):
137 return ", ".join(self.tenant_list)
138
Scott Bakerb37a99a2015-09-10 17:36:58 -0700139 @property
svavilapb4594032015-11-16 00:27:06 -0600140 def ceilometer_port(self):
141 # TODO: Find a better logic to choose unique ceilometer port number for each instance
142 if not self.id:
143 return None
144 return 8888+self.id
145
146 @property
Scott Bakerb37a99a2015-09-10 17:36:58 -0700147 def ceilometer_url(self):
Scott Bakera9cf9c42015-09-10 17:46:47 -0700148 if not self.ceilometer_ip:
Scott Bakerb37a99a2015-09-10 17:36:58 -0700149 return None
svavilapb4594032015-11-16 00:27:06 -0600150 return "http://" + self.private_ip + ":" + str(self.ceilometer_port) + "/"
Scott Bakerddf8a942015-09-10 17:07:21 -0700151
Scott Bakerfa8fd292015-09-09 17:31:22 -0700152def model_policy_monitoring_channel(pk):
153 # TODO: this should be made in to a real model_policy
154 with transaction.atomic():
155 mc = MonitoringChannel.objects.select_for_update().filter(pk=pk)
156 if not mc:
157 return
158 mc = mc[0]
159 mc.manage_container()
160
161