blob: 483b76b9bdcef68d8e08327587846f8487abb5a9 [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 Baker1f050df2015-05-28 17:12:00 -070071 default_attributes = {"vlan_id": None,
72 "is_demo_user": False }
Scott Baker679f7022015-04-20 11:50:09 -070073
Scott Baker323eca92015-04-20 09:48:34 -070074 def __init__(self, *args, **kwargs):
75 volt_services = VOLTService.get_service_objects().all()
76 if volt_services:
77 self._meta.get_field("provider_service").default = volt_services[0].id
78 super(VOLTTenant, self).__init__(*args, **kwargs)
79
Scott Bakerd4b48c02015-04-15 20:59:15 -070080 @property
Scott Baker679f7022015-04-20 11:50:09 -070081 def vlan_id(self):
82 return self.get_attribute("vlan_id", self.default_attributes["vlan_id"])
83
84 @vlan_id.setter
85 def vlan_id(self, value):
86 self.set_attribute("vlan_id", value)
87
88 @property
Scott Bakerd4b48c02015-04-15 20:59:15 -070089 def vcpe(self):
Scott Bakerfa5cdd62015-04-20 09:16:17 -070090 if getattr(self, "cached_vcpe", None):
91 return self.cached_vcpe
Scott Bakerd4b48c02015-04-15 20:59:15 -070092 vcpe_id=self.get_attribute("vcpe_id")
93 if not vcpe_id:
94 return None
95 vcpes=VCPETenant.objects.filter(id=vcpe_id)
96 if not vcpes:
97 return None
Scott Bakerfa5cdd62015-04-20 09:16:17 -070098 vcpe=vcpes[0]
Scott Bakerc633dc92015-05-05 17:49:46 -070099 vcpe.caller = self.creator
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700100 self.cached_vcpe = vcpe
101 return vcpe
Scott Bakerd4b48c02015-04-15 20:59:15 -0700102
103 @vcpe.setter
104 def vcpe(self, value):
105 if value:
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700106 value = value.id
107 if (value != self.get_attribute("vcpe_id", None)):
108 self.cached_vcpe=None
109 self.set_attribute("vcpe_id", value)
Scott Bakerd4b48c02015-04-15 20:59:15 -0700110
Scott Bakerc633dc92015-05-05 17:49:46 -0700111 @property
112 def creator(self):
113 if getattr(self, "cached_creator", None):
114 return self.cached_creator
115 creator_id=self.get_attribute("creator_id")
116 if not creator_id:
117 return None
118 users=User.objects.filter(id=creator_id)
119 if not users:
120 return None
121 user=users[0]
122 self.cached_creator = users[0]
123 return user
124
125 @creator.setter
126 def creator(self, value):
127 if value:
128 value = value.id
129 if (value != self.get_attribute("creator_id", None)):
130 self.cached_creator=None
131 self.set_attribute("creator_id", value)
132
Scott Baker1f050df2015-05-28 17:12:00 -0700133 @property
134 def is_demo_user(self):
135 return self.get_attribute("is_demo_user", self.default_attributes["is_demo_user"])
136
137 @is_demo_user.setter
138 def is_demo_user(self, value):
139 self.set_attribute("is_demo_user", value)
140
Scott Bakerd4b48c02015-04-15 20:59:15 -0700141 def manage_vcpe(self):
142 # Each VOLT object owns exactly one VCPE object
143
144 if self.deleted:
145 return
146
147 if self.vcpe is None:
148 vcpeServices = VCPEService.get_service_objects().all()
149 if not vcpeServices:
Scott Baker7f8ef8f2015-04-20 14:24:29 -0700150 raise XOSConfigurationError("No VCPE Services available")
Scott Bakerd4b48c02015-04-15 20:59:15 -0700151
152 vcpe = VCPETenant(provider_service = vcpeServices[0],
153 subscriber_tenant = self)
Scott Bakerc633dc92015-05-05 17:49:46 -0700154 vcpe.caller = self.creator
Scott Bakerd4b48c02015-04-15 20:59:15 -0700155 vcpe.save()
156
157 try:
158 self.vcpe = vcpe
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700159 super(VOLTTenant, self).save()
Scott Bakerd4b48c02015-04-15 20:59:15 -0700160 except:
161 vcpe.delete()
162 raise
163
164 def cleanup_vcpe(self):
165 if self.vcpe:
166 self.vcpe.delete()
167 self.vcpe = None
168
169 def save(self, *args, **kwargs):
Scott Baker7f8ef8f2015-04-20 14:24:29 -0700170 self.validate_unique_service_specific_id()
171
Scott Bakerc633dc92015-05-05 17:49:46 -0700172 if not self.creator:
173 if not getattr(self, "caller", None):
174 # caller must be set when creating a vCPE since it creates a slice
175 raise XOSProgrammingError("VOLTTenant's self.caller was not set")
176 self.creator = self.caller
177 if not self.creator:
178 raise XOSProgrammingError("VOLTTenant's self.creator was not set")
179
Scott Bakerd4b48c02015-04-15 20:59:15 -0700180 super(VOLTTenant, self).save(*args, **kwargs)
181 self.manage_vcpe()
182
183 def delete(self, *args, **kwargs):
184 self.cleanup_vcpe()
185 super(VOLTTenant, self).delete(*args, **kwargs)
186
187# -------------------------------------------
188# VCPE
189# -------------------------------------------
190
191class VCPEService(Service):
192 KIND = "vCPE"
193
194 class Meta:
195 app_label = "cord"
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700196 verbose_name = "vCPE Service"
Scott Bakerd4b48c02015-04-15 20:59:15 -0700197 proxy = True
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700198
Scott Baker4e6d60d2015-05-20 20:45:11 -0700199 def allocate_bbs_account(self):
200 vcpes = VCPETenant.get_tenant_objects().all()
201 bbs_accounts = [vcpe.bbs_account for vcpe in vcpes]
202
203 # There's a bit of a race here; some other user could be trying to
204 # allocate a bbs_account at the same time we are.
205
206 for i in range(1,21):
207 account_name = "bbs%02d@onlab.us" % i
208 if (account_name not in bbs_accounts):
209 return account_name
210
211 raise XOSConfigurationError("We've run out of available broadbandshield accounts. Delete some vcpe and try again.")
212
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700213class VCPETenant(Tenant):
214 class Meta:
215 proxy = True
216
Scott Bakerd4b48c02015-04-15 20:59:15 -0700217 KIND = "vCPE"
218
Scott Bakerc633dc92015-05-05 17:49:46 -0700219 sync_attributes = ("firewall_enable",
220 "firewall_rules",
221 "url_filter_enable",
222 "url_filter_rules",
Scott Baker0c8512b2015-05-20 08:41:38 -0700223 "cdn_enable",
224 "nat_ip",
225 "lan_ip",
226 "wan_ip",
Scott Baker281b1af2015-06-04 10:26:44 -0700227 "private_ip",
Scott Baker4f972592015-06-05 12:08:34 -0700228 "hpc_client_ip",
229 "wan_mac")
Scott Bakerc633dc92015-05-05 17:49:46 -0700230
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700231 default_attributes = {"firewall_enable": False,
Scott Baker05eb4972015-04-16 21:54:50 -0700232 "firewall_rules": "accept all anywhere anywhere",
233 "url_filter_enable": False,
234 "url_filter_rules": "allow all",
Scott Baker647d45d2015-05-14 20:29:04 -0700235 "url_filter_level": "PG",
Scott Baker05eb4972015-04-16 21:54:50 -0700236 "cdn_enable": False,
Scott Baker20952552015-05-20 16:31:58 -0700237 "sliver_id": None,
Scott Baker4e6d60d2015-05-20 20:45:11 -0700238 "users": [],
239 "bbs_account": None}
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700240
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700241 def __init__(self, *args, **kwargs):
242 super(VCPETenant, self).__init__(*args, **kwargs)
243 self.cached_vbng=None
244 self.cached_sliver=None
245
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700246 @property
247 def image(self):
Scott Baker721c9b72015-06-04 10:02:09 -0700248 LOOK_FOR_IMAGES=["ubuntu-vcpe2", # ONOS demo machine -- preferred vcpe image
Scott Baker866575c2015-06-02 16:03:30 -0700249 "Ubuntu 14.04 LTS", # portal
Scott Baker8c0ae622015-04-20 20:12:59 -0700250 "Ubuntu-14.04-LTS", # ONOS demo machine
251 ]
252 for image_name in LOOK_FOR_IMAGES:
253 images = Image.objects.filter(name = image_name)
254 if images:
255 return images[0]
256
257 raise XOSProgrammingError("No VPCE image (looked for %s)" % str(LOOK_FOR_IMAGES))
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700258
259 @property
260 def sliver(self):
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700261 if getattr(self, "cached_sliver", None):
262 return self.cached_sliver
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700263 sliver_id=self.get_attribute("sliver_id")
264 if not sliver_id:
265 return None
266 slivers=Sliver.objects.filter(id=sliver_id)
267 if not slivers:
268 return None
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700269 sliver=slivers[0]
Scott Bakerc633dc92015-05-05 17:49:46 -0700270 sliver.caller = self.creator
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700271 self.cached_sliver = sliver
272 return sliver
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700273
274 @sliver.setter
275 def sliver(self, value):
276 if value:
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700277 value = value.id
278 if (value != self.get_attribute("sliver_id", None)):
279 self.cached_sliver=None
280 self.set_attribute("sliver_id", value)
281
282 @property
Scott Bakerc633dc92015-05-05 17:49:46 -0700283 def creator(self):
284 if getattr(self, "cached_creator", None):
285 return self.cached_creator
286 creator_id=self.get_attribute("creator_id")
287 if not creator_id:
288 return None
289 users=User.objects.filter(id=creator_id)
290 if not users:
291 return None
292 user=users[0]
293 self.cached_creator = users[0]
294 return user
295
296 @creator.setter
297 def creator(self, value):
298 if value:
299 value = value.id
300 if (value != self.get_attribute("creator_id", None)):
301 self.cached_creator=None
302 self.set_attribute("creator_id", value)
303
304 @property
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700305 def vbng(self):
306 if getattr(self, "cached_vbng", None):
307 return self.cached_vbng
308 vbng_id=self.get_attribute("vbng_id")
309 if not vbng_id:
310 return None
311 vbngs=VBNGTenant.objects.filter(id=vbng_id)
312 if not vbngs:
313 return None
314 vbng=vbngs[0]
Scott Bakerc633dc92015-05-05 17:49:46 -0700315 vbng.caller = self.creator
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700316 self.cached_vbng = vbng
317 return vbng
318
319 @vbng.setter
320 def vbng(self, value):
321 if value:
322 value = value.id
323 if (value != self.get_attribute("vbng_id", None)):
324 self.cached_vbng=None
325 self.set_attribute("vbng_id", value)
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700326
327 @property
328 def firewall_enable(self):
329 return self.get_attribute("firewall_enable", self.default_attributes["firewall_enable"])
330
331 @firewall_enable.setter
332 def firewall_enable(self, value):
333 self.set_attribute("firewall_enable", value)
334
Scott Baker05eb4972015-04-16 21:54:50 -0700335 @property
336 def firewall_rules(self):
337 return self.get_attribute("firewall_rules", self.default_attributes["firewall_rules"])
338
339 @firewall_rules.setter
340 def firewall_rules(self, value):
341 self.set_attribute("firewall_rules", value)
342
343 @property
344 def url_filter_enable(self):
345 return self.get_attribute("url_filter_enable", self.default_attributes["url_filter_enable"])
346
347 @url_filter_enable.setter
348 def url_filter_enable(self, value):
349 self.set_attribute("url_filter_enable", value)
350
351 @property
Scott Baker647d45d2015-05-14 20:29:04 -0700352 def url_filter_level(self):
353 return self.get_attribute("url_filter_level", self.default_attributes["url_filter_level"])
354
355 @url_filter_level.setter
356 def url_filter_level(self, value):
357 self.set_attribute("url_filter_level", value)
358
359 @property
Scott Baker05eb4972015-04-16 21:54:50 -0700360 def url_filter_rules(self):
361 return self.get_attribute("url_filter_rules", self.default_attributes["url_filter_rules"])
362
363 @url_filter_rules.setter
364 def url_filter_rules(self, value):
365 self.set_attribute("url_filter_rules", value)
366
367 @property
368 def cdn_enable(self):
369 return self.get_attribute("cdn_enable", self.default_attributes["cdn_enable"])
370
371 @cdn_enable.setter
372 def cdn_enable(self, value):
373 self.set_attribute("cdn_enable", value)
374
Scott Baker647d45d2015-05-14 20:29:04 -0700375 @property
376 def users(self):
Scott Baker20952552015-05-20 16:31:58 -0700377 return self.get_attribute("users", self.default_attributes["users"])
Scott Baker647d45d2015-05-14 20:29:04 -0700378
379 @users.setter
380 def users(self, value):
Scott Baker20952552015-05-20 16:31:58 -0700381 self.set_attribute("users", value)
382
Scott Baker4e6d60d2015-05-20 20:45:11 -0700383 @property
384 def bbs_account(self):
385 return self.get_attribute("bbs_account", self.default_attributes["bbs_account"])
386
387 @bbs_account.setter
388 def bbs_account(self, value):
389 return self.set_attribute("bbs_account", value)
390
Scott Baker3415ac72015-06-04 16:24:20 -0700391 @property
392 def ssh_command(self):
393 if self.sliver:
394 return self.sliver.get_ssh_command()
395 else:
396 return "no-sliver"
397
398 @ssh_command.setter
399 def ssh_command(self, value):
400 pass
401
Scott Baker20952552015-05-20 16:31:58 -0700402 def find_user(self, uid):
403 uid = int(uid)
404 for user in self.users:
405 if user["id"] == uid:
406 return user
407 return None
408
409 def update_user(self, uid, **kwargs):
410 # kwargs may be "level" or "mac"
411 # Setting one of these to None will cause None to be stored in the db
412 uid = int(uid)
413 users = self.users
414 for user in users:
415 if user["id"] == uid:
416 for arg in kwargs.keys():
417 user[arg] = kwargs[arg]
418 self.users = users
Scott Baker9e362d32015-06-01 20:34:03 -0700419 return user
Scott Baker20952552015-05-20 16:31:58 -0700420 raise ValueError("User %d not found" % uid)
421
422 def create_user(self, **kwargs):
Scott Bakerf1e80042015-05-28 19:44:20 -0700423 if "name" not in kwargs:
424 raise XOSMissingField("The name field is required")
425
426 for user in self.users:
427 if kwargs["name"] == user["name"]:
428 raise XOSDuplicateKey("User %s already exists" % kwargs["name"])
429
Scott Baker20952552015-05-20 16:31:58 -0700430 uids = [x["id"] for x in self.users]
431 if uids:
432 uid = max(uids)+1
433 else:
434 uid = 0
435 newuser = kwargs.copy()
436 newuser["id"] = uid
437
438 users = self.users
439 users.append(newuser)
440 self.users = users
441
442 return newuser
443
444 def delete_user(self, uid):
445 uid = int(uid)
446 users = self.users
447 for user in users:
448 if user["id"]==uid:
449 users.remove(user)
450 self.users = users
451 return
452
453 raise ValueError("Users %d not found" % uid)
Scott Baker647d45d2015-05-14 20:29:04 -0700454
455 @property
456 def services(self):
Scott Bakeraa1e96d2015-05-15 14:59:47 -0700457 return {"cdn": self.cdn_enable,
458 "url_filter": self.url_filter_enable,
459 "firewall": self.firewall_enable}
Scott Baker647d45d2015-05-14 20:29:04 -0700460
461 @services.setter
462 def services(self, value):
463 pass
464
Scott Baker5571c692015-05-20 08:19:25 -0700465 @property
466 def addresses(self):
467 if not self.sliver:
468 return {}
469
470 addresses = {}
471 for ns in self.sliver.networkslivers.all():
472 if "lan" in ns.network.name.lower():
473 addresses["lan"] = ns.ip
474 elif "wan" in ns.network.name.lower():
475 addresses["wan"] = ns.ip
476 elif "private" in ns.network.name.lower():
477 addresses["private"] = ns.ip
478 elif "nat" in ns.network.name.lower():
479 addresses["nat"] = ns.ip
Scott Baker281b1af2015-06-04 10:26:44 -0700480 elif "hpc_client" in ns.network.name.lower():
481 addresses["hpc_client"] = ns.ip
Scott Baker5571c692015-05-20 08:19:25 -0700482 return addresses
483
Scott Baker432d1402015-05-20 08:25:29 -0700484 @property
485 def nat_ip(self):
486 return self.addresses.get("nat",None)
487
488 @property
489 def lan_ip(self):
490 return self.addresses.get("lan",None)
491
492 @property
493 def wan_ip(self):
494 return self.addresses.get("wan",None)
495
496 @property
Scott Baker4f972592015-06-05 12:08:34 -0700497 def wan_mac(self):
498 ip = self.wan_ip
499 if not ip:
500 return None
501 try:
502 (a,b,c,d) = ip.split('.')
503 wan_mac = "02:42:%2x:%2x:%2x:%2x" % (int(a), int(b), int(c), int(d))
504 except:
505 wan_mac = "Exception"
506 return wan_mac
507
508 @property
Scott Baker432d1402015-05-20 08:25:29 -0700509 def private_ip(self):
510 return self.addresses.get("private",None)
511
Scott Baker281b1af2015-06-04 10:26:44 -0700512 @property
513 def hpc_client_ip(self):
514 return self.addresses.get("hpc_client",None)
515
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700516 def pick_node(self):
517 nodes = list(Node.objects.all())
518 # TODO: logic to filter nodes by which nodes are up, and which
519 # nodes the slice can instantiate on.
520 nodes = sorted(nodes, key=lambda node: node.slivers.all().count())
521 return nodes[0]
522
523 def manage_sliver(self):
Scott Bakerd4b48c02015-04-15 20:59:15 -0700524 # Each VCPE object owns exactly one sliver.
525
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700526 if self.deleted:
527 return
528
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700529 if (self.sliver is not None) and (self.sliver.image != self.image):
530 self.sliver.delete()
531 self.sliver = None
Scott Bakerc633dc92015-05-05 17:49:46 -0700532
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700533 if self.sliver is None:
534 if not self.provider_service.slices.count():
Scott Bakerf6790db2015-05-06 15:46:34 -0700535 raise XOSConfigurationError("The VCPE service has no slices")
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700536
Scott Bakere1f72d12015-05-14 21:48:53 -0700537 flavors = Flavor.objects.filter(name="m1.small")
538 if not flavors:
539 raise XOSConfigurationError("No m1.small flavor")
540
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700541 node =self.pick_node()
542 sliver = Sliver(slice = self.provider_service.slices.all()[0],
543 node = node,
544 image = self.image,
Scott Bakerc633dc92015-05-05 17:49:46 -0700545 creator = self.creator,
Scott Bakere1f72d12015-05-14 21:48:53 -0700546 deployment = node.site_deployment.deployment,
547 flavor = flavors[0])
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700548 sliver.save()
549
Scott Bakerd4b48c02015-04-15 20:59:15 -0700550 try:
551 self.sliver = sliver
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700552 super(VCPETenant, self).save()
Scott Bakerd4b48c02015-04-15 20:59:15 -0700553 except:
554 sliver.delete()
555 raise
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700556
557 def cleanup_sliver(self):
558 if self.sliver:
559 self.sliver.delete()
560 self.sliver = None
561
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700562 def manage_vbng(self):
563 # Each vCPE object owns exactly one vBNG object
564
565 if self.deleted:
566 return
567
568 if self.vbng is None:
569 vbngServices = VBNGService.get_service_objects().all()
570 if not vbngServices:
Scott Baker7f8ef8f2015-04-20 14:24:29 -0700571 raise XOSConfigurationError("No VBNG Services available")
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700572
573 vbng = VBNGTenant(provider_service = vbngServices[0],
574 subscriber_tenant = self)
Scott Bakerc633dc92015-05-05 17:49:46 -0700575 vbng.caller = self.creator
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700576 vbng.save()
577
578 try:
579 self.vbng = vbng
580 super(VCPETenant, self).save()
581 except:
582 vbng.delete()
583 raise
584
585 def cleanup_vbng(self):
586 if self.vbng:
587 self.vbng.delete()
588 self.vbng = None
589
Scott Baker4e6d60d2015-05-20 20:45:11 -0700590 def manage_bbs_account(self):
591 if self.deleted:
592 return
593
Scott Baker642126f2015-05-20 20:57:28 -0700594 if self.url_filter_enable:
595 if not self.bbs_account:
596 # make sure we use the proxied VCPEService object, not the generic Service object
597 vcpe_service = VCPEService.objects.get(id=self.provider_service.id)
598 self.bbs_account = vcpe_service.allocate_bbs_account()
599 super(VCPETenant, self).save()
600 else:
601 if self.bbs_account:
602 self.bbs_account = None
603 super(VCPETenant, self).save()
Scott Baker4e6d60d2015-05-20 20:45:11 -0700604
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700605 def save(self, *args, **kwargs):
Scott Bakerc633dc92015-05-05 17:49:46 -0700606 if not self.creator:
607 if not getattr(self, "caller", None):
608 # caller must be set when creating a vCPE since it creates a slice
Scott Bakerf6790db2015-05-06 15:46:34 -0700609 raise XOSProgrammingError("VCPETenant's self.caller was not set")
Scott Bakerc633dc92015-05-05 17:49:46 -0700610 self.creator = self.caller
611 if not self.creator:
Scott Bakerf6790db2015-05-06 15:46:34 -0700612 raise XOSProgrammingError("VCPETenant's self.creator was not set")
Scott Bakerc633dc92015-05-05 17:49:46 -0700613
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700614 super(VCPETenant, self).save(*args, **kwargs)
Scott Bakerd4b48c02015-04-15 20:59:15 -0700615 self.manage_sliver()
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700616 self.manage_vbng()
Scott Baker4e6d60d2015-05-20 20:45:11 -0700617 self.manage_bbs_account()
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700618
619 def delete(self, *args, **kwargs):
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700620 self.cleanup_vbng()
Scott Bakere9ff7ce2015-04-14 17:19:16 -0700621 self.cleanup_sliver()
622 super(VCPETenant, self).delete(*args, **kwargs)
623
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700624#----------------------------------------------------------------------------
625# vBNG
626#----------------------------------------------------------------------------
627
628class VBNGService(Service):
629 KIND = "vBNG"
630
631 class Meta:
632 app_label = "cord"
633 verbose_name = "vBNG Service"
634 proxy = True
635
636class VBNGTenant(Tenant):
637 class Meta:
638 proxy = True
639
640 KIND = "vBNG"
641
Scott Baker61c8e8d2015-06-02 14:34:04 -0700642 default_attributes = {"routeable_subnet": "",
Scott Bakercf155f42015-06-08 19:09:53 -0700643 "mapped_ip": "",
644 "mapped_mac": "",
645 "mapped_hostname": ""}
Scott Bakerfa5cdd62015-04-20 09:16:17 -0700646
647 @property
648 def routeable_subnet(self):
649 return self.get_attribute("routeable_subnet", self.default_attributes["routeable_subnet"])
650
651 @routeable_subnet.setter
652 def routeable_subnet(self, value):
653 self.set_attribute("routeable_subnet", value)
Scott Baker61c8e8d2015-06-02 14:34:04 -0700654
655 @property
656 def mapped_ip(self):
657 return self.get_attribute("mapped_ip", self.default_attributes["mapped_ip"])
658
659 @mapped_ip.setter
660 def mapped_ip(self, value):
661 self.set_attribute("mapped_ip", value)
Scott Bakercf155f42015-06-08 19:09:53 -0700662
663 @property
664 def mapped_mac(self):
665 return self.get_attribute("mapped_mac", self.default_attributes["mapped_mac"])
666
667 @mapped_mac.setter
668 def mapped_mac(self, value):
669 self.set_attribute("mapped_mac", value)
670
671 @property
672 def mapped_hostname(self):
673 return self.get_attribute("mapped_hostname", self.default_attributes["mapped_hostname"])
674
675 @mapped_hostname.setter
676 def mapped_hostname(self, value):
677 self.set_attribute("mapped_hostname", value)