blob: 4bb78b3ff2a0926bed86a0c073b9d745fd369fb2 [file] [log] [blame]
Scott Bakere9ff7ce2015-04-14 17:19:16 -07001from django.db import models
Scott Bakere1f72d12015-05-14 21:48:53 -07002from core.models import Service, PlCoreBase, Slice, Sliver, Tenant, Node, Image, User, Flavor
Scott Bakere9ff7ce2015-04-14 17:19:16 -07003from core.models.plcorebase import StrippedCharField
4import os
5from django.db import models
6from django.forms.models import model_to_dict
7from django.db.models import Q
8from operator import itemgetter, attrgetter, methodcaller
Scott Bakerfa5cdd62015-04-20 09:16:17 -07009import traceback
Scott Baker7f8ef8f2015-04-20 14:24:29 -070010from xos.exceptions import *
Scott Bakere9ff7ce2015-04-14 17:19:16 -070011
12"""
13import os
14import sys
15sys.path.append("/opt/xos")
16os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
17import django
18from core.models import *
19from hpc.models import *
20from cord.models import *
21django.setup()
Scott Bakere9ff7ce2015-04-14 17:19:16 -070022
Scott Baker323eca92015-04-20 09:48:34 -070023t = VOLTTenant()
Scott Bakere9ff7ce2015-04-14 17:19:16 -070024t.caller = User.objects.all()[0]
25t.save()
26
Scott Bakerdfc0bef2015-05-11 08:31:24 -070027for v in VOLTTenant.get_tenant_objects().all():
Scott Bakerd4b48c02015-04-15 20:59:15 -070028 v.caller = User.objects.all()[0]
29 v.delete()
30
Scott Bakerdfc0bef2015-05-11 08:31:24 -070031for v in VCPETenant.get_tenant_objects().all():
Scott Bakere9ff7ce2015-04-14 17:19:16 -070032 v.caller = User.objects.all()[0]
33 v.delete()
Scott Bakerfa5cdd62015-04-20 09:16:17 -070034
Scott Bakerdfc0bef2015-05-11 08:31:24 -070035for v in VOLTTenant.get_tenant_objects().all():
Scott Bakerfa5cdd62015-04-20 09:16:17 -070036 v.caller = User.objects.all()[0]
37 v.delete()
Scott Bakerc633dc92015-05-05 17:49:46 -070038
Scott Bakerdfc0bef2015-05-11 08:31:24 -070039for v in VOLTTenant.get_tenant_objects().all():
Scott Bakerc633dc92015-05-05 17:49:46 -070040 if not v.creator:
41 v.creator= User.objects.all()[0]
42 v.save()
43
Scott Bakerdfc0bef2015-05-11 08:31:24 -070044for v in VCPETenant.get_tenant_objects().all():
Scott Bakerc633dc92015-05-05 17:49:46 -070045 if not v.creator:
46 v.creator= User.objects.all()[0]
47 v.save()
Scott Bakere9ff7ce2015-04-14 17:19:16 -070048"""
49
50class ConfigurationError(Exception):
51 pass
52
Scott Bakerd4b48c02015-04-15 20:59:15 -070053# -------------------------------------------
54# VOLT
55# -------------------------------------------
56
57class VOLTService(Service):
58 KIND = "vOLT"
59
Scott Bakere9ff7ce2015-04-14 17:19:16 -070060 class Meta:
Scott Bakerd4b48c02015-04-15 20:59:15 -070061 app_label = "cord"
62 verbose_name = "vOLT Service"
63 proxy = True
64
65class VOLTTenant(Tenant):
66 class Meta:
67 proxy = True
68
69 KIND = "vOLT"
70
Scott Baker679f7022015-04-20 11:50:09 -070071 default_attributes = {"vlan_id": None, }
72
Scott Baker323eca92015-04-20 09:48:34 -070073 def __init__(self, *args, **kwargs):
74 volt_services = VOLTService.get_service_objects().all()
75 if volt_services:
76 self._meta.get_field("provider_service").default = volt_services[0].id
77 super(VOLTTenant, self).__init__(*args, **kwargs)
78
Scott Bakerd4b48c02015-04-15 20:59:15 -070079 @property
Scott Baker679f7022015-04-20 11:50:09 -070080 def vlan_id(self):
81 return self.get_attribute("vlan_id", self.default_attributes["vlan_id"])
82
83 @vlan_id.setter
84 def vlan_id(self, value):
85 self.set_attribute("vlan_id", value)
86
87 @property
Scott Bakerd4b48c02015-04-15 20:59:15 -070088 def vcpe(self):
Scott Bakerfa5cdd62015-04-20 09:16:17 -070089 if getattr(self, "cached_vcpe", None):
90 return self.cached_vcpe
Scott Bakerd4b48c02015-04-15 20:59:15 -070091 vcpe_id=self.get_attribute("vcpe_id")
92 if not vcpe_id:
93 return None
94 vcpes=VCPETenant.objects.filter(id=vcpe_id)
95 if not vcpes:
96 return None
Scott Bakerfa5cdd62015-04-20 09:16:17 -070097 vcpe=vcpes[0]
Scott Bakerc633dc92015-05-05 17:49:46 -070098 vcpe.caller = self.creator
Scott Bakerfa5cdd62015-04-20 09:16:17 -070099 self.cached_vcpe = vcpe
100 return vcpe
Scott Bakerd4b48c02015-04-15 20:59:15 -0700101
102 @vcpe.setter
103 def vcpe(self, value):
104 if value:
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700105 value = value.id
106 if (value != self.get_attribute("vcpe_id", None)):
107 self.cached_vcpe=None
108 self.set_attribute("vcpe_id", value)
Scott Bakerd4b48c02015-04-15 20:59:15 -0700109
Scott Bakerc633dc92015-05-05 17:49:46 -0700110 @property
111 def creator(self):
112 if getattr(self, "cached_creator", None):
113 return self.cached_creator
114 creator_id=self.get_attribute("creator_id")
115 if not creator_id:
116 return None
117 users=User.objects.filter(id=creator_id)
118 if not users:
119 return None
120 user=users[0]
121 self.cached_creator = users[0]
122 return user
123
124 @creator.setter
125 def creator(self, value):
126 if value:
127 value = value.id
128 if (value != self.get_attribute("creator_id", None)):
129 self.cached_creator=None
130 self.set_attribute("creator_id", value)
131
Scott Bakerd4b48c02015-04-15 20:59:15 -0700132 def manage_vcpe(self):
133 # Each VOLT object owns exactly one VCPE object
134
135 if self.deleted:
136 return
137
138 if self.vcpe is None:
139 vcpeServices = VCPEService.get_service_objects().all()
140 if not vcpeServices:
Scott Baker7f8ef8f2015-04-20 14:24:29 -0700141 raise XOSConfigurationError("No VCPE Services available")
Scott Bakerd4b48c02015-04-15 20:59:15 -0700142
143 vcpe = VCPETenant(provider_service = vcpeServices[0],
144 subscriber_tenant = self)
Scott Bakerc633dc92015-05-05 17:49:46 -0700145 vcpe.caller = self.creator
Scott Bakerd4b48c02015-04-15 20:59:15 -0700146 vcpe.save()
147
148 try:
149 self.vcpe = vcpe
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700150 super(VOLTTenant, self).save()
Scott Bakerd4b48c02015-04-15 20:59:15 -0700151 except:
152 vcpe.delete()
153 raise
154
155 def cleanup_vcpe(self):
156 if self.vcpe:
157 self.vcpe.delete()
158 self.vcpe = None
159
160 def save(self, *args, **kwargs):
Scott Baker7f8ef8f2015-04-20 14:24:29 -0700161 self.validate_unique_service_specific_id()
162
Scott Bakerc633dc92015-05-05 17:49:46 -0700163 if not self.creator:
164 if not getattr(self, "caller", None):
165 # caller must be set when creating a vCPE since it creates a slice
166 raise XOSProgrammingError("VOLTTenant's self.caller was not set")
167 self.creator = self.caller
168 if not self.creator:
169 raise XOSProgrammingError("VOLTTenant's self.creator was not set")
170
Scott Bakerd4b48c02015-04-15 20:59:15 -0700171 super(VOLTTenant, self).save(*args, **kwargs)
172 self.manage_vcpe()
173
174 def delete(self, *args, **kwargs):
175 self.cleanup_vcpe()
176 super(VOLTTenant, self).delete(*args, **kwargs)
177
178# -------------------------------------------
179# VCPE
180# -------------------------------------------
181
182class VCPEService(Service):
183 KIND = "vCPE"
184
185 class Meta:
186 app_label = "cord"
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700187 verbose_name = "vCPE Service"
Scott Bakerd4b48c02015-04-15 20:59:15 -0700188 proxy = True
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700189
190class VCPETenant(Tenant):
191 class Meta:
192 proxy = True
193
Scott Bakerd4b48c02015-04-15 20:59:15 -0700194 KIND = "vCPE"
195
Scott Bakerc633dc92015-05-05 17:49:46 -0700196 sync_attributes = ("firewall_enable",
197 "firewall_rules",
198 "url_filter_enable",
199 "url_filter_rules",
200 "cdn_enable")
201
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700202 default_attributes = {"firewall_enable": False,
Scott Baker05eb4972015-04-16 21:54:50 -0700203 "firewall_rules": "accept all anywhere anywhere",
204 "url_filter_enable": False,
205 "url_filter_rules": "allow all",
Scott Baker647d45d2015-05-14 20:29:04 -0700206 "url_filter_level": "PG",
Scott Baker05eb4972015-04-16 21:54:50 -0700207 "cdn_enable": False,
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700208 "sliver_id": None}
209
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700210 def __init__(self, *args, **kwargs):
211 super(VCPETenant, self).__init__(*args, **kwargs)
212 self.cached_vbng=None
213 self.cached_sliver=None
214
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700215 @property
216 def image(self):
Scott Baker8c0ae622015-04-20 20:12:59 -0700217 LOOK_FOR_IMAGES=["Ubuntu 14.04 LTS", # portal
218 "Ubuntu-14.04-LTS", # ONOS demo machine
219 ]
220 for image_name in LOOK_FOR_IMAGES:
221 images = Image.objects.filter(name = image_name)
222 if images:
223 return images[0]
224
225 raise XOSProgrammingError("No VPCE image (looked for %s)" % str(LOOK_FOR_IMAGES))
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700226
227 @property
228 def sliver(self):
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700229 if getattr(self, "cached_sliver", None):
230 return self.cached_sliver
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700231 sliver_id=self.get_attribute("sliver_id")
232 if not sliver_id:
233 return None
234 slivers=Sliver.objects.filter(id=sliver_id)
235 if not slivers:
236 return None
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700237 sliver=slivers[0]
Scott Bakerc633dc92015-05-05 17:49:46 -0700238 sliver.caller = self.creator
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700239 self.cached_sliver = sliver
240 return sliver
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700241
242 @sliver.setter
243 def sliver(self, value):
244 if value:
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700245 value = value.id
246 if (value != self.get_attribute("sliver_id", None)):
247 self.cached_sliver=None
248 self.set_attribute("sliver_id", value)
249
250 @property
Scott Bakerc633dc92015-05-05 17:49:46 -0700251 def creator(self):
252 if getattr(self, "cached_creator", None):
253 return self.cached_creator
254 creator_id=self.get_attribute("creator_id")
255 if not creator_id:
256 return None
257 users=User.objects.filter(id=creator_id)
258 if not users:
259 return None
260 user=users[0]
261 self.cached_creator = users[0]
262 return user
263
264 @creator.setter
265 def creator(self, value):
266 if value:
267 value = value.id
268 if (value != self.get_attribute("creator_id", None)):
269 self.cached_creator=None
270 self.set_attribute("creator_id", value)
271
272 @property
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700273 def vbng(self):
274 if getattr(self, "cached_vbng", None):
275 return self.cached_vbng
276 vbng_id=self.get_attribute("vbng_id")
277 if not vbng_id:
278 return None
279 vbngs=VBNGTenant.objects.filter(id=vbng_id)
280 if not vbngs:
281 return None
282 vbng=vbngs[0]
Scott Bakerc633dc92015-05-05 17:49:46 -0700283 vbng.caller = self.creator
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700284 self.cached_vbng = vbng
285 return vbng
286
287 @vbng.setter
288 def vbng(self, value):
289 if value:
290 value = value.id
291 if (value != self.get_attribute("vbng_id", None)):
292 self.cached_vbng=None
293 self.set_attribute("vbng_id", value)
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700294
295 @property
296 def firewall_enable(self):
297 return self.get_attribute("firewall_enable", self.default_attributes["firewall_enable"])
298
299 @firewall_enable.setter
300 def firewall_enable(self, value):
301 self.set_attribute("firewall_enable", value)
302
Scott Baker05eb4972015-04-16 21:54:50 -0700303 @property
304 def firewall_rules(self):
305 return self.get_attribute("firewall_rules", self.default_attributes["firewall_rules"])
306
307 @firewall_rules.setter
308 def firewall_rules(self, value):
309 self.set_attribute("firewall_rules", value)
310
311 @property
312 def url_filter_enable(self):
313 return self.get_attribute("url_filter_enable", self.default_attributes["url_filter_enable"])
314
315 @url_filter_enable.setter
316 def url_filter_enable(self, value):
317 self.set_attribute("url_filter_enable", value)
318
319 @property
Scott Baker647d45d2015-05-14 20:29:04 -0700320 def url_filter_level(self):
321 return self.get_attribute("url_filter_level", self.default_attributes["url_filter_level"])
322
323 @url_filter_level.setter
324 def url_filter_level(self, value):
325 self.set_attribute("url_filter_level", value)
326
327 @property
Scott Baker05eb4972015-04-16 21:54:50 -0700328 def url_filter_rules(self):
329 return self.get_attribute("url_filter_rules", self.default_attributes["url_filter_rules"])
330
331 @url_filter_rules.setter
332 def url_filter_rules(self, value):
333 self.set_attribute("url_filter_rules", value)
334
335 @property
336 def cdn_enable(self):
337 return self.get_attribute("cdn_enable", self.default_attributes["cdn_enable"])
338
339 @cdn_enable.setter
340 def cdn_enable(self, value):
341 self.set_attribute("cdn_enable", value)
342
Scott Baker647d45d2015-05-14 20:29:04 -0700343 @property
344 def users(self):
345 return [ {"name": "mom", "id": 1, "role": "admin"},
346 {"name": "dad", "id": 2, "role": "admin"},
347 {"name": "kid1", "id": 3, "role": "user"},
348 {"name": "kid2", "id": 4, "role": "user"} ]
349
350 @users.setter
351 def users(self, value):
352 pass
353
354 @property
355 def services(self):
Scott Bakeraa1e96d2015-05-15 14:59:47 -0700356 return {"cdn": self.cdn_enable,
357 "url_filter": self.url_filter_enable,
358 "firewall": self.firewall_enable}
Scott Baker647d45d2015-05-14 20:29:04 -0700359
360 @services.setter
361 def services(self, value):
362 pass
363
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700364 def pick_node(self):
365 nodes = list(Node.objects.all())
366 # TODO: logic to filter nodes by which nodes are up, and which
367 # nodes the slice can instantiate on.
368 nodes = sorted(nodes, key=lambda node: node.slivers.all().count())
369 return nodes[0]
370
371 def manage_sliver(self):
Scott Bakerd4b48c02015-04-15 20:59:15 -0700372 # Each VCPE object owns exactly one sliver.
373
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700374 if self.deleted:
375 return
376
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700377 if (self.sliver is not None) and (self.sliver.image != self.image):
378 self.sliver.delete()
379 self.sliver = None
Scott Bakerc633dc92015-05-05 17:49:46 -0700380
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700381 if self.sliver is None:
382 if not self.provider_service.slices.count():
Scott Bakerf6790db2015-05-06 15:46:34 -0700383 raise XOSConfigurationError("The VCPE service has no slices")
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700384
Scott Bakere1f72d12015-05-14 21:48:53 -0700385 flavors = Flavor.objects.filter(name="m1.small")
386 if not flavors:
387 raise XOSConfigurationError("No m1.small flavor")
388
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700389 node =self.pick_node()
390 sliver = Sliver(slice = self.provider_service.slices.all()[0],
391 node = node,
392 image = self.image,
Scott Bakerc633dc92015-05-05 17:49:46 -0700393 creator = self.creator,
Scott Bakere1f72d12015-05-14 21:48:53 -0700394 deployment = node.site_deployment.deployment,
395 flavor = flavors[0])
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700396 sliver.save()
397
Scott Bakerd4b48c02015-04-15 20:59:15 -0700398 try:
399 self.sliver = sliver
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700400 super(VCPETenant, self).save()
Scott Bakerd4b48c02015-04-15 20:59:15 -0700401 except:
402 sliver.delete()
403 raise
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700404
405 def cleanup_sliver(self):
406 if self.sliver:
407 self.sliver.delete()
408 self.sliver = None
409
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700410 def manage_vbng(self):
411 # Each vCPE object owns exactly one vBNG object
412
413 if self.deleted:
414 return
415
416 if self.vbng is None:
417 vbngServices = VBNGService.get_service_objects().all()
418 if not vbngServices:
Scott Baker7f8ef8f2015-04-20 14:24:29 -0700419 raise XOSConfigurationError("No VBNG Services available")
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700420
421 vbng = VBNGTenant(provider_service = vbngServices[0],
422 subscriber_tenant = self)
Scott Bakerc633dc92015-05-05 17:49:46 -0700423 vbng.caller = self.creator
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700424 vbng.save()
425
426 try:
427 self.vbng = vbng
428 super(VCPETenant, self).save()
429 except:
430 vbng.delete()
431 raise
432
433 def cleanup_vbng(self):
434 if self.vbng:
435 self.vbng.delete()
436 self.vbng = None
437
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700438 def save(self, *args, **kwargs):
Scott Bakerc633dc92015-05-05 17:49:46 -0700439 if not self.creator:
440 if not getattr(self, "caller", None):
441 # caller must be set when creating a vCPE since it creates a slice
Scott Bakerf6790db2015-05-06 15:46:34 -0700442 raise XOSProgrammingError("VCPETenant's self.caller was not set")
Scott Bakerc633dc92015-05-05 17:49:46 -0700443 self.creator = self.caller
444 if not self.creator:
Scott Bakerf6790db2015-05-06 15:46:34 -0700445 raise XOSProgrammingError("VCPETenant's self.creator was not set")
Scott Bakerc633dc92015-05-05 17:49:46 -0700446
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700447 super(VCPETenant, self).save(*args, **kwargs)
Scott Bakerd4b48c02015-04-15 20:59:15 -0700448 self.manage_sliver()
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700449 self.manage_vbng()
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700450
451 def delete(self, *args, **kwargs):
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700452 self.cleanup_vbng()
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700453 self.cleanup_sliver()
454 super(VCPETenant, self).delete(*args, **kwargs)
455
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700456#----------------------------------------------------------------------------
457# vBNG
458#----------------------------------------------------------------------------
459
460class VBNGService(Service):
461 KIND = "vBNG"
462
463 class Meta:
464 app_label = "cord"
465 verbose_name = "vBNG Service"
466 proxy = True
467
468class VBNGTenant(Tenant):
469 class Meta:
470 proxy = True
471
472 KIND = "vBNG"
473
474 default_attributes = {"routeable_subnet": ""}
475
476 @property
477 def routeable_subnet(self):
478 return self.get_attribute("routeable_subnet", self.default_attributes["routeable_subnet"])
479
480 @routeable_subnet.setter
481 def routeable_subnet(self, value):
482 self.set_attribute("routeable_subnet", value)