models for VBNG; cache linked models; set caller
diff --git a/xos/cord/models.py b/xos/cord/models.py
index 594eb31..2ae2b72 100644
--- a/xos/cord/models.py
+++ b/xos/cord/models.py
@@ -6,6 +6,7 @@
from django.forms.models import model_to_dict
from django.db.models import Q
from operator import itemgetter, attrgetter, methodcaller
+import traceback
"""
import os
@@ -30,6 +31,10 @@
for v in VCPETenant.objects.all():
v.caller = User.objects.all()[0]
v.delete()
+
+for v in VOLTTenant.objects.all():
+ v.caller = User.objects.all()[0]
+ v.delete()
"""
class ConfigurationError(Exception):
@@ -55,20 +60,26 @@
@property
def vcpe(self):
+ if getattr(self, "cached_vcpe", None):
+ return self.cached_vcpe
vcpe_id=self.get_attribute("vcpe_id")
if not vcpe_id:
return None
vcpes=VCPETenant.objects.filter(id=vcpe_id)
if not vcpes:
return None
- return vcpes[0]
+ vcpe=vcpes[0]
+ vcpe.caller = getattr(self, "caller", None)
+ self.cached_vcpe = vcpe
+ return vcpe
@vcpe.setter
def vcpe(self, value):
if value:
- self.set_attribute("vcpe_id", value.id)
- else:
- self.set_attribute("vcpe_id", None)
+ value = value.id
+ if (value != self.get_attribute("vcpe_id", None)):
+ self.cached_vcpe=None
+ self.set_attribute("vcpe_id", value)
def manage_vcpe(self):
# Each VOLT object owns exactly one VCPE object
@@ -88,7 +99,7 @@
try:
self.vcpe = vcpe
- self.save()
+ super(VOLTTenant, self).save()
except:
vcpe.delete()
raise
@@ -133,6 +144,11 @@
"cdn_enable": False,
"sliver_id": None}
+ def __init__(self, *args, **kwargs):
+ super(VCPETenant, self).__init__(*args, **kwargs)
+ self.cached_vbng=None
+ self.cached_sliver=None
+
@property
def image(self):
# TODO: logic to pick an image based on the feature set
@@ -141,20 +157,49 @@
@property
def sliver(self):
+ if getattr(self, "cached_sliver", None):
+ return self.cached_sliver
sliver_id=self.get_attribute("sliver_id")
if not sliver_id:
return None
slivers=Sliver.objects.filter(id=sliver_id)
if not slivers:
return None
- return slivers[0]
+ sliver=slivers[0]
+ sliver.caller = getattr(self, "caller", None)
+ self.cached_sliver = sliver
+ return sliver
@sliver.setter
def sliver(self, value):
if value:
- self.set_attribute("sliver_id", value.id)
- else:
- self.set_attribute("sliver_id", None)
+ value = value.id
+ if (value != self.get_attribute("sliver_id", None)):
+ self.cached_sliver=None
+ self.set_attribute("sliver_id", value)
+
+ @property
+ def vbng(self):
+ if getattr(self, "cached_vbng", None):
+ return self.cached_vbng
+ vbng_id=self.get_attribute("vbng_id")
+ if not vbng_id:
+ return None
+ vbngs=VBNGTenant.objects.filter(id=vbng_id)
+ if not vbngs:
+ return None
+ vbng=vbngs[0]
+ vbng.caller = getattr(self, "caller", None)
+ self.cached_vbng = vbng
+ return vbng
+
+ @vbng.setter
+ def vbng(self, value):
+ if value:
+ value = value.id
+ if (value != self.get_attribute("vbng_id", None)):
+ self.cached_vbng=None
+ self.set_attribute("vbng_id", value)
@property
def firewall_enable(self):
@@ -226,7 +271,7 @@
try:
self.sliver = sliver
- self.save()
+ super(VCPETenant, self).save()
except:
sliver.delete()
raise
@@ -236,13 +281,70 @@
self.sliver.delete()
self.sliver = None
+ def manage_vbng(self):
+ # Each vCPE object owns exactly one vBNG object
+
+ if self.deleted:
+ return
+
+ if self.vbng is None:
+ vbngServices = VBNGService.get_service_objects().all()
+ if not vbngServices:
+ raise ConfigurationError("No VBNG Services available")
+
+ vbng = VBNGTenant(provider_service = vbngServices[0],
+ subscriber_tenant = self)
+ vbng.caller = self.caller
+ vbng.save()
+
+ try:
+ self.vbng = vbng
+ super(VCPETenant, self).save()
+ except:
+ vbng.delete()
+ raise
+
+ def cleanup_vbng(self):
+ if self.vbng:
+ self.vbng.delete()
+ self.vbng = None
+
def save(self, *args, **kwargs):
if not getattr(self, "caller", None):
raise TypeError("VCPETenant's self.caller was not set")
super(VCPETenant, self).save(*args, **kwargs)
self.manage_sliver()
+ self.manage_vbng()
def delete(self, *args, **kwargs):
+ self.cleanup_vbng()
self.cleanup_sliver()
super(VCPETenant, self).delete(*args, **kwargs)
+#----------------------------------------------------------------------------
+# vBNG
+#----------------------------------------------------------------------------
+
+class VBNGService(Service):
+ KIND = "vBNG"
+
+ class Meta:
+ app_label = "cord"
+ verbose_name = "vBNG Service"
+ proxy = True
+
+class VBNGTenant(Tenant):
+ class Meta:
+ proxy = True
+
+ KIND = "vBNG"
+
+ default_attributes = {"routeable_subnet": ""}
+
+ @property
+ def routeable_subnet(self):
+ return self.get_attribute("routeable_subnet", self.default_attributes["routeable_subnet"])
+
+ @routeable_subnet.setter
+ def routeable_subnet(self, value):
+ self.set_attribute("routeable_subnet", value)