blob: e5930974409978055a7fb066c979ad7db7996f98 [file] [log] [blame]
Scott Baker1b241612015-04-14 17:19:16 -07001from django.db import models
Scott Bakerac60d5f2015-05-14 21:48:53 -07002from core.models import Service, PlCoreBase, Slice, Sliver, Tenant, Node, Image, User, Flavor
Scott Baker1b241612015-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 Baker697fb0b2015-04-20 09:16:17 -07009import traceback
Scott Bakerd921e1c2015-04-20 14:24:29 -070010from xos.exceptions import *
Scott Baker1b241612015-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 Baker1b241612015-04-14 17:19:16 -070022
Scott Baker557aada2015-04-20 09:48:34 -070023t = VOLTTenant()
Scott Baker1b241612015-04-14 17:19:16 -070024t.caller = User.objects.all()[0]
25t.save()
26
Scott Baker2b29a312015-05-11 08:31:24 -070027for v in VOLTTenant.get_tenant_objects().all():
Scott Baker39b0d892015-04-15 20:59:15 -070028 v.caller = User.objects.all()[0]
29 v.delete()
30
Scott Baker2b29a312015-05-11 08:31:24 -070031for v in VCPETenant.get_tenant_objects().all():
Scott Baker1b241612015-04-14 17:19:16 -070032 v.caller = User.objects.all()[0]
33 v.delete()
Scott Baker697fb0b2015-04-20 09:16:17 -070034
Scott Baker2b29a312015-05-11 08:31:24 -070035for v in VOLTTenant.get_tenant_objects().all():
Scott Baker697fb0b2015-04-20 09:16:17 -070036 v.caller = User.objects.all()[0]
37 v.delete()
Scott Baker9c8a2c72015-05-05 17:49:46 -070038
Scott Baker2b29a312015-05-11 08:31:24 -070039for v in VOLTTenant.get_tenant_objects().all():
Scott Baker9c8a2c72015-05-05 17:49:46 -070040 if not v.creator:
41 v.creator= User.objects.all()[0]
42 v.save()
43
Scott Baker2b29a312015-05-11 08:31:24 -070044for v in VCPETenant.get_tenant_objects().all():
Scott Baker9c8a2c72015-05-05 17:49:46 -070045 if not v.creator:
46 v.creator= User.objects.all()[0]
47 v.save()
Scott Baker1b241612015-04-14 17:19:16 -070048"""
49
50class ConfigurationError(Exception):
51 pass
52
Scott Baker39b0d892015-04-15 20:59:15 -070053# -------------------------------------------
54# VOLT
55# -------------------------------------------
56
57class VOLTService(Service):
58 KIND = "vOLT"
59
Scott Baker1b241612015-04-14 17:19:16 -070060 class Meta:
Scott Baker39b0d892015-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 Baker664c4282015-05-28 17:12:00 -070071 default_attributes = {"vlan_id": None,
72 "is_demo_user": False }
Scott Bakere744c7b2015-04-20 11:50:09 -070073
Scott Baker557aada2015-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 Baker39b0d892015-04-15 20:59:15 -070080 @property
Scott Bakere744c7b2015-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 Baker39b0d892015-04-15 20:59:15 -070089 def vcpe(self):
Scott Baker697fb0b2015-04-20 09:16:17 -070090 if getattr(self, "cached_vcpe", None):
91 return self.cached_vcpe
Scott Baker39b0d892015-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 Baker697fb0b2015-04-20 09:16:17 -070098 vcpe=vcpes[0]
Scott Baker9c8a2c72015-05-05 17:49:46 -070099 vcpe.caller = self.creator
Scott Baker697fb0b2015-04-20 09:16:17 -0700100 self.cached_vcpe = vcpe
101 return vcpe
Scott Baker39b0d892015-04-15 20:59:15 -0700102
103 @vcpe.setter
104 def vcpe(self, value):
105 if value:
Scott Baker697fb0b2015-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 Baker39b0d892015-04-15 20:59:15 -0700110
Scott Baker9c8a2c72015-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 Baker664c4282015-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 Baker39b0d892015-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 Bakerd921e1c2015-04-20 14:24:29 -0700150 raise XOSConfigurationError("No VCPE Services available")
Scott Baker39b0d892015-04-15 20:59:15 -0700151
152 vcpe = VCPETenant(provider_service = vcpeServices[0],
153 subscriber_tenant = self)
Scott Baker9c8a2c72015-05-05 17:49:46 -0700154 vcpe.caller = self.creator
Scott Baker39b0d892015-04-15 20:59:15 -0700155 vcpe.save()
156
157 try:
158 self.vcpe = vcpe
Scott Baker697fb0b2015-04-20 09:16:17 -0700159 super(VOLTTenant, self).save()
Scott Baker39b0d892015-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 Bakerd921e1c2015-04-20 14:24:29 -0700170 self.validate_unique_service_specific_id()
171
Scott Baker9c8a2c72015-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 Baker39b0d892015-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 Baker1b241612015-04-14 17:19:16 -0700196 verbose_name = "vCPE Service"
Scott Baker39b0d892015-04-15 20:59:15 -0700197 proxy = True
Scott Baker1b241612015-04-14 17:19:16 -0700198
Scott Baker5c8abf82015-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
Scott Bakerf4f61ca2015-06-09 12:03:56 -0700206 for i in range(2,21):
Scott Baker5c8abf82015-05-20 20:45:11 -0700207 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 Baker1b241612015-04-14 17:19:16 -0700213class VCPETenant(Tenant):
214 class Meta:
215 proxy = True
216
Scott Baker39b0d892015-04-15 20:59:15 -0700217 KIND = "vCPE"
218
Scott Baker9c8a2c72015-05-05 17:49:46 -0700219 sync_attributes = ("firewall_enable",
220 "firewall_rules",
221 "url_filter_enable",
222 "url_filter_rules",
Scott Bakerc7a96c82015-05-20 08:41:38 -0700223 "cdn_enable",
224 "nat_ip",
225 "lan_ip",
226 "wan_ip",
Scott Baker710ad052015-06-04 10:26:44 -0700227 "private_ip",
Scott Baker3f4fe402015-06-05 12:08:34 -0700228 "hpc_client_ip",
229 "wan_mac")
Scott Baker9c8a2c72015-05-05 17:49:46 -0700230
Scott Baker1b241612015-04-14 17:19:16 -0700231 default_attributes = {"firewall_enable": False,
Scott Baker0bcbb962015-04-16 21:54:50 -0700232 "firewall_rules": "accept all anywhere anywhere",
233 "url_filter_enable": False,
234 "url_filter_rules": "allow all",
Scott Baker8d13a982015-05-14 20:29:04 -0700235 "url_filter_level": "PG",
Scott Baker0bcbb962015-04-16 21:54:50 -0700236 "cdn_enable": False,
Scott Bakera0cf9612015-05-20 16:31:58 -0700237 "sliver_id": None,
Scott Baker5c8abf82015-05-20 20:45:11 -0700238 "users": [],
Scott Bakerd40a42d2015-06-09 12:22:29 -0700239 "bbs_account": None,
240 "last_ansible_hash": None}
Scott Baker1b241612015-04-14 17:19:16 -0700241
Scott Baker697fb0b2015-04-20 09:16:17 -0700242 def __init__(self, *args, **kwargs):
243 super(VCPETenant, self).__init__(*args, **kwargs)
244 self.cached_vbng=None
245 self.cached_sliver=None
246
Scott Baker1b241612015-04-14 17:19:16 -0700247 @property
248 def image(self):
Scott Bakerfd1f6962015-06-04 10:02:09 -0700249 LOOK_FOR_IMAGES=["ubuntu-vcpe2", # ONOS demo machine -- preferred vcpe image
Scott Baker2c4f1eb2015-06-02 16:03:30 -0700250 "Ubuntu 14.04 LTS", # portal
Scott Baker4f751bd2015-04-20 20:12:59 -0700251 "Ubuntu-14.04-LTS", # ONOS demo machine
252 ]
253 for image_name in LOOK_FOR_IMAGES:
254 images = Image.objects.filter(name = image_name)
255 if images:
256 return images[0]
257
258 raise XOSProgrammingError("No VPCE image (looked for %s)" % str(LOOK_FOR_IMAGES))
Scott Baker1b241612015-04-14 17:19:16 -0700259
260 @property
261 def sliver(self):
Scott Baker697fb0b2015-04-20 09:16:17 -0700262 if getattr(self, "cached_sliver", None):
263 return self.cached_sliver
Scott Baker1b241612015-04-14 17:19:16 -0700264 sliver_id=self.get_attribute("sliver_id")
265 if not sliver_id:
266 return None
267 slivers=Sliver.objects.filter(id=sliver_id)
268 if not slivers:
269 return None
Scott Baker697fb0b2015-04-20 09:16:17 -0700270 sliver=slivers[0]
Scott Baker9c8a2c72015-05-05 17:49:46 -0700271 sliver.caller = self.creator
Scott Baker697fb0b2015-04-20 09:16:17 -0700272 self.cached_sliver = sliver
273 return sliver
Scott Baker1b241612015-04-14 17:19:16 -0700274
275 @sliver.setter
276 def sliver(self, value):
277 if value:
Scott Baker697fb0b2015-04-20 09:16:17 -0700278 value = value.id
279 if (value != self.get_attribute("sliver_id", None)):
280 self.cached_sliver=None
281 self.set_attribute("sliver_id", value)
282
283 @property
Scott Baker9c8a2c72015-05-05 17:49:46 -0700284 def creator(self):
285 if getattr(self, "cached_creator", None):
286 return self.cached_creator
287 creator_id=self.get_attribute("creator_id")
288 if not creator_id:
289 return None
290 users=User.objects.filter(id=creator_id)
291 if not users:
292 return None
293 user=users[0]
294 self.cached_creator = users[0]
295 return user
296
297 @creator.setter
298 def creator(self, value):
299 if value:
300 value = value.id
301 if (value != self.get_attribute("creator_id", None)):
302 self.cached_creator=None
303 self.set_attribute("creator_id", value)
304
305 @property
Scott Baker697fb0b2015-04-20 09:16:17 -0700306 def vbng(self):
307 if getattr(self, "cached_vbng", None):
308 return self.cached_vbng
309 vbng_id=self.get_attribute("vbng_id")
310 if not vbng_id:
311 return None
312 vbngs=VBNGTenant.objects.filter(id=vbng_id)
313 if not vbngs:
314 return None
315 vbng=vbngs[0]
Scott Baker9c8a2c72015-05-05 17:49:46 -0700316 vbng.caller = self.creator
Scott Baker697fb0b2015-04-20 09:16:17 -0700317 self.cached_vbng = vbng
318 return vbng
319
320 @vbng.setter
321 def vbng(self, value):
322 if value:
323 value = value.id
324 if (value != self.get_attribute("vbng_id", None)):
325 self.cached_vbng=None
326 self.set_attribute("vbng_id", value)
Scott Baker1b241612015-04-14 17:19:16 -0700327
328 @property
329 def firewall_enable(self):
330 return self.get_attribute("firewall_enable", self.default_attributes["firewall_enable"])
331
332 @firewall_enable.setter
333 def firewall_enable(self, value):
334 self.set_attribute("firewall_enable", value)
335
Scott Baker0bcbb962015-04-16 21:54:50 -0700336 @property
337 def firewall_rules(self):
338 return self.get_attribute("firewall_rules", self.default_attributes["firewall_rules"])
339
340 @firewall_rules.setter
341 def firewall_rules(self, value):
342 self.set_attribute("firewall_rules", value)
343
344 @property
345 def url_filter_enable(self):
346 return self.get_attribute("url_filter_enable", self.default_attributes["url_filter_enable"])
347
348 @url_filter_enable.setter
349 def url_filter_enable(self, value):
350 self.set_attribute("url_filter_enable", value)
351
352 @property
Scott Baker8d13a982015-05-14 20:29:04 -0700353 def url_filter_level(self):
354 return self.get_attribute("url_filter_level", self.default_attributes["url_filter_level"])
355
356 @url_filter_level.setter
357 def url_filter_level(self, value):
358 self.set_attribute("url_filter_level", value)
359
360 @property
Scott Baker0bcbb962015-04-16 21:54:50 -0700361 def url_filter_rules(self):
362 return self.get_attribute("url_filter_rules", self.default_attributes["url_filter_rules"])
363
364 @url_filter_rules.setter
365 def url_filter_rules(self, value):
366 self.set_attribute("url_filter_rules", value)
367
368 @property
369 def cdn_enable(self):
370 return self.get_attribute("cdn_enable", self.default_attributes["cdn_enable"])
371
372 @cdn_enable.setter
373 def cdn_enable(self, value):
374 self.set_attribute("cdn_enable", value)
375
Scott Baker8d13a982015-05-14 20:29:04 -0700376 @property
377 def users(self):
Scott Bakera0cf9612015-05-20 16:31:58 -0700378 return self.get_attribute("users", self.default_attributes["users"])
Scott Baker8d13a982015-05-14 20:29:04 -0700379
380 @users.setter
381 def users(self, value):
Scott Bakera0cf9612015-05-20 16:31:58 -0700382 self.set_attribute("users", value)
383
Scott Baker5c8abf82015-05-20 20:45:11 -0700384 @property
385 def bbs_account(self):
386 return self.get_attribute("bbs_account", self.default_attributes["bbs_account"])
387
388 @bbs_account.setter
389 def bbs_account(self, value):
390 return self.set_attribute("bbs_account", value)
391
Scott Baker11981a92015-06-04 16:24:20 -0700392 @property
Scott Bakerd40a42d2015-06-09 12:22:29 -0700393 def last_ansible_hash(self):
394 return self.get_attribute("last_ansible_hash", self.default_attributes["last_ansible_hash"])
395
396 @last_ansible_hash.setter
397 def last_ansible_hash(self, value):
398 return self.set_attribute("last_ansible_hash", value)
399
400 @property
Scott Baker11981a92015-06-04 16:24:20 -0700401 def ssh_command(self):
402 if self.sliver:
403 return self.sliver.get_ssh_command()
404 else:
405 return "no-sliver"
406
407 @ssh_command.setter
408 def ssh_command(self, value):
409 pass
410
Scott Bakera0cf9612015-05-20 16:31:58 -0700411 def find_user(self, uid):
412 uid = int(uid)
413 for user in self.users:
414 if user["id"] == uid:
415 return user
416 return None
417
418 def update_user(self, uid, **kwargs):
419 # kwargs may be "level" or "mac"
420 # Setting one of these to None will cause None to be stored in the db
421 uid = int(uid)
422 users = self.users
423 for user in users:
424 if user["id"] == uid:
425 for arg in kwargs.keys():
426 user[arg] = kwargs[arg]
427 self.users = users
Scott Bakerac731702015-06-01 20:34:03 -0700428 return user
Scott Bakera0cf9612015-05-20 16:31:58 -0700429 raise ValueError("User %d not found" % uid)
430
431 def create_user(self, **kwargs):
Scott Baker7c796302015-05-28 19:44:20 -0700432 if "name" not in kwargs:
433 raise XOSMissingField("The name field is required")
434
435 for user in self.users:
436 if kwargs["name"] == user["name"]:
437 raise XOSDuplicateKey("User %s already exists" % kwargs["name"])
438
Scott Bakera0cf9612015-05-20 16:31:58 -0700439 uids = [x["id"] for x in self.users]
440 if uids:
441 uid = max(uids)+1
442 else:
443 uid = 0
444 newuser = kwargs.copy()
445 newuser["id"] = uid
446
447 users = self.users
448 users.append(newuser)
449 self.users = users
450
451 return newuser
452
453 def delete_user(self, uid):
454 uid = int(uid)
455 users = self.users
456 for user in users:
457 if user["id"]==uid:
458 users.remove(user)
459 self.users = users
460 return
461
462 raise ValueError("Users %d not found" % uid)
Scott Baker8d13a982015-05-14 20:29:04 -0700463
464 @property
465 def services(self):
Scott Bakerf4c3ad42015-05-15 14:59:47 -0700466 return {"cdn": self.cdn_enable,
467 "url_filter": self.url_filter_enable,
468 "firewall": self.firewall_enable}
Scott Baker8d13a982015-05-14 20:29:04 -0700469
470 @services.setter
471 def services(self, value):
472 pass
473
Scott Baker706bf972015-05-20 08:19:25 -0700474 @property
475 def addresses(self):
476 if not self.sliver:
477 return {}
478
479 addresses = {}
480 for ns in self.sliver.networkslivers.all():
481 if "lan" in ns.network.name.lower():
482 addresses["lan"] = ns.ip
483 elif "wan" in ns.network.name.lower():
484 addresses["wan"] = ns.ip
485 elif "private" in ns.network.name.lower():
486 addresses["private"] = ns.ip
487 elif "nat" in ns.network.name.lower():
488 addresses["nat"] = ns.ip
Scott Baker710ad052015-06-04 10:26:44 -0700489 elif "hpc_client" in ns.network.name.lower():
490 addresses["hpc_client"] = ns.ip
Scott Baker706bf972015-05-20 08:19:25 -0700491 return addresses
492
Scott Bakera6a7e032015-05-20 08:25:29 -0700493 @property
494 def nat_ip(self):
495 return self.addresses.get("nat",None)
496
497 @property
498 def lan_ip(self):
499 return self.addresses.get("lan",None)
500
501 @property
502 def wan_ip(self):
503 return self.addresses.get("wan",None)
504
505 @property
Scott Baker3f4fe402015-06-05 12:08:34 -0700506 def wan_mac(self):
507 ip = self.wan_ip
508 if not ip:
509 return None
510 try:
511 (a,b,c,d) = ip.split('.')
512 wan_mac = "02:42:%2x:%2x:%2x:%2x" % (int(a), int(b), int(c), int(d))
513 except:
514 wan_mac = "Exception"
515 return wan_mac
516
517 @property
Scott Bakera6a7e032015-05-20 08:25:29 -0700518 def private_ip(self):
519 return self.addresses.get("private",None)
520
Scott Baker710ad052015-06-04 10:26:44 -0700521 @property
522 def hpc_client_ip(self):
523 return self.addresses.get("hpc_client",None)
524
Scott Baker1b241612015-04-14 17:19:16 -0700525 def pick_node(self):
526 nodes = list(Node.objects.all())
527 # TODO: logic to filter nodes by which nodes are up, and which
528 # nodes the slice can instantiate on.
529 nodes = sorted(nodes, key=lambda node: node.slivers.all().count())
530 return nodes[0]
531
532 def manage_sliver(self):
Scott Baker39b0d892015-04-15 20:59:15 -0700533 # Each VCPE object owns exactly one sliver.
534
Scott Baker1b241612015-04-14 17:19:16 -0700535 if self.deleted:
536 return
537
Scott Baker1b241612015-04-14 17:19:16 -0700538 if (self.sliver is not None) and (self.sliver.image != self.image):
539 self.sliver.delete()
540 self.sliver = None
Scott Baker9c8a2c72015-05-05 17:49:46 -0700541
Scott Baker1b241612015-04-14 17:19:16 -0700542 if self.sliver is None:
543 if not self.provider_service.slices.count():
Scott Bakeree0c2802015-05-06 15:46:34 -0700544 raise XOSConfigurationError("The VCPE service has no slices")
Scott Baker1b241612015-04-14 17:19:16 -0700545
Scott Bakerac60d5f2015-05-14 21:48:53 -0700546 flavors = Flavor.objects.filter(name="m1.small")
547 if not flavors:
548 raise XOSConfigurationError("No m1.small flavor")
549
Scott Baker1b241612015-04-14 17:19:16 -0700550 node =self.pick_node()
551 sliver = Sliver(slice = self.provider_service.slices.all()[0],
552 node = node,
553 image = self.image,
Scott Baker9c8a2c72015-05-05 17:49:46 -0700554 creator = self.creator,
Scott Bakerac60d5f2015-05-14 21:48:53 -0700555 deployment = node.site_deployment.deployment,
556 flavor = flavors[0])
Scott Baker1b241612015-04-14 17:19:16 -0700557 sliver.save()
558
Scott Baker39b0d892015-04-15 20:59:15 -0700559 try:
560 self.sliver = sliver
Scott Baker697fb0b2015-04-20 09:16:17 -0700561 super(VCPETenant, self).save()
Scott Baker39b0d892015-04-15 20:59:15 -0700562 except:
563 sliver.delete()
564 raise
Scott Baker1b241612015-04-14 17:19:16 -0700565
566 def cleanup_sliver(self):
567 if self.sliver:
568 self.sliver.delete()
569 self.sliver = None
570
Scott Baker697fb0b2015-04-20 09:16:17 -0700571 def manage_vbng(self):
572 # Each vCPE object owns exactly one vBNG object
573
574 if self.deleted:
575 return
576
577 if self.vbng is None:
578 vbngServices = VBNGService.get_service_objects().all()
579 if not vbngServices:
Scott Bakerd921e1c2015-04-20 14:24:29 -0700580 raise XOSConfigurationError("No VBNG Services available")
Scott Baker697fb0b2015-04-20 09:16:17 -0700581
582 vbng = VBNGTenant(provider_service = vbngServices[0],
583 subscriber_tenant = self)
Scott Baker9c8a2c72015-05-05 17:49:46 -0700584 vbng.caller = self.creator
Scott Baker697fb0b2015-04-20 09:16:17 -0700585 vbng.save()
586
587 try:
588 self.vbng = vbng
589 super(VCPETenant, self).save()
590 except:
591 vbng.delete()
592 raise
593
594 def cleanup_vbng(self):
595 if self.vbng:
596 self.vbng.delete()
597 self.vbng = None
598
Scott Baker5c8abf82015-05-20 20:45:11 -0700599 def manage_bbs_account(self):
600 if self.deleted:
601 return
602
Scott Bakere2570112015-05-20 20:57:28 -0700603 if self.url_filter_enable:
604 if not self.bbs_account:
605 # make sure we use the proxied VCPEService object, not the generic Service object
606 vcpe_service = VCPEService.objects.get(id=self.provider_service.id)
Scott Bakerf4f61ca2015-06-09 12:03:56 -0700607 if self.service_specific_id=="SYNCME":
608 self.bbs_account = "bbs01@onlab.us"
609 else:
610 self.bbs_account = vcpe_service.allocate_bbs_account()
Scott Bakere2570112015-05-20 20:57:28 -0700611 super(VCPETenant, self).save()
612 else:
613 if self.bbs_account:
614 self.bbs_account = None
615 super(VCPETenant, self).save()
Scott Baker5c8abf82015-05-20 20:45:11 -0700616
Scott Baker1b241612015-04-14 17:19:16 -0700617 def save(self, *args, **kwargs):
Scott Baker9c8a2c72015-05-05 17:49:46 -0700618 if not self.creator:
619 if not getattr(self, "caller", None):
620 # caller must be set when creating a vCPE since it creates a slice
Scott Bakeree0c2802015-05-06 15:46:34 -0700621 raise XOSProgrammingError("VCPETenant's self.caller was not set")
Scott Baker9c8a2c72015-05-05 17:49:46 -0700622 self.creator = self.caller
623 if not self.creator:
Scott Bakeree0c2802015-05-06 15:46:34 -0700624 raise XOSProgrammingError("VCPETenant's self.creator was not set")
Scott Baker9c8a2c72015-05-05 17:49:46 -0700625
Scott Baker1b241612015-04-14 17:19:16 -0700626 super(VCPETenant, self).save(*args, **kwargs)
Scott Baker39b0d892015-04-15 20:59:15 -0700627 self.manage_sliver()
Scott Baker697fb0b2015-04-20 09:16:17 -0700628 self.manage_vbng()
Scott Baker5c8abf82015-05-20 20:45:11 -0700629 self.manage_bbs_account()
Scott Baker1b241612015-04-14 17:19:16 -0700630
631 def delete(self, *args, **kwargs):
Scott Baker697fb0b2015-04-20 09:16:17 -0700632 self.cleanup_vbng()
Scott Baker1b241612015-04-14 17:19:16 -0700633 self.cleanup_sliver()
634 super(VCPETenant, self).delete(*args, **kwargs)
635
Scott Baker697fb0b2015-04-20 09:16:17 -0700636#----------------------------------------------------------------------------
637# vBNG
638#----------------------------------------------------------------------------
639
640class VBNGService(Service):
641 KIND = "vBNG"
642
643 class Meta:
644 app_label = "cord"
645 verbose_name = "vBNG Service"
646 proxy = True
647
648class VBNGTenant(Tenant):
649 class Meta:
650 proxy = True
651
652 KIND = "vBNG"
653
Scott Baker99ff5512015-06-02 14:34:04 -0700654 default_attributes = {"routeable_subnet": "",
Scott Baker790613c2015-06-08 19:09:53 -0700655 "mapped_ip": "",
656 "mapped_mac": "",
657 "mapped_hostname": ""}
Scott Baker697fb0b2015-04-20 09:16:17 -0700658
659 @property
660 def routeable_subnet(self):
661 return self.get_attribute("routeable_subnet", self.default_attributes["routeable_subnet"])
662
663 @routeable_subnet.setter
664 def routeable_subnet(self, value):
665 self.set_attribute("routeable_subnet", value)
Scott Baker99ff5512015-06-02 14:34:04 -0700666
667 @property
668 def mapped_ip(self):
669 return self.get_attribute("mapped_ip", self.default_attributes["mapped_ip"])
670
671 @mapped_ip.setter
672 def mapped_ip(self, value):
673 self.set_attribute("mapped_ip", value)
Scott Baker790613c2015-06-08 19:09:53 -0700674
675 @property
676 def mapped_mac(self):
677 return self.get_attribute("mapped_mac", self.default_attributes["mapped_mac"])
678
679 @mapped_mac.setter
680 def mapped_mac(self, value):
681 self.set_attribute("mapped_mac", value)
682
683 @property
684 def mapped_hostname(self):
685 return self.get_attribute("mapped_hostname", self.default_attributes["mapped_hostname"])
686
687 @mapped_hostname.setter
688 def mapped_hostname(self, value):
689 self.set_attribute("mapped_hostname", value)