Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 1 | from django.db import models |
Scott Baker | e1f72d1 | 2015-05-14 21:48:53 -0700 | [diff] [blame] | 2 | from core.models import Service, PlCoreBase, Slice, Sliver, Tenant, Node, Image, User, Flavor |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 3 | from core.models.plcorebase import StrippedCharField |
| 4 | import os |
| 5 | from django.db import models |
| 6 | from django.forms.models import model_to_dict |
| 7 | from django.db.models import Q |
| 8 | from operator import itemgetter, attrgetter, methodcaller |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 9 | import traceback |
Scott Baker | 7f8ef8f | 2015-04-20 14:24:29 -0700 | [diff] [blame] | 10 | from xos.exceptions import * |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 11 | |
| 12 | """ |
| 13 | import os |
| 14 | import sys |
| 15 | sys.path.append("/opt/xos") |
| 16 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings") |
| 17 | import django |
| 18 | from core.models import *
|
| 19 | from hpc.models import *
|
| 20 | from cord.models import *
|
| 21 | django.setup() |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 22 | |
Scott Baker | 323eca9 | 2015-04-20 09:48:34 -0700 | [diff] [blame] | 23 | t = VOLTTenant() |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 24 | t.caller = User.objects.all()[0] |
| 25 | t.save() |
| 26 | |
Scott Baker | dfc0bef | 2015-05-11 08:31:24 -0700 | [diff] [blame] | 27 | for v in VOLTTenant.get_tenant_objects().all(): |
Scott Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 28 | v.caller = User.objects.all()[0] |
| 29 | v.delete() |
| 30 | |
Scott Baker | dfc0bef | 2015-05-11 08:31:24 -0700 | [diff] [blame] | 31 | for v in VCPETenant.get_tenant_objects().all(): |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 32 | v.caller = User.objects.all()[0] |
| 33 | v.delete() |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 34 | |
Scott Baker | dfc0bef | 2015-05-11 08:31:24 -0700 | [diff] [blame] | 35 | for v in VOLTTenant.get_tenant_objects().all(): |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 36 | v.caller = User.objects.all()[0] |
| 37 | v.delete() |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 38 | |
Scott Baker | dfc0bef | 2015-05-11 08:31:24 -0700 | [diff] [blame] | 39 | for v in VOLTTenant.get_tenant_objects().all(): |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 40 | if not v.creator: |
| 41 | v.creator= User.objects.all()[0] |
| 42 | v.save() |
| 43 | |
Scott Baker | dfc0bef | 2015-05-11 08:31:24 -0700 | [diff] [blame] | 44 | for v in VCPETenant.get_tenant_objects().all(): |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 45 | if not v.creator: |
| 46 | v.creator= User.objects.all()[0] |
| 47 | v.save() |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 48 | """ |
| 49 | |
| 50 | class ConfigurationError(Exception): |
| 51 | pass |
| 52 | |
Scott Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 53 | # ------------------------------------------- |
| 54 | # VOLT |
| 55 | # ------------------------------------------- |
| 56 | |
| 57 | class VOLTService(Service): |
| 58 | KIND = "vOLT" |
| 59 | |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 60 | class Meta: |
Scott Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 61 | app_label = "cord" |
| 62 | verbose_name = "vOLT Service" |
| 63 | proxy = True |
| 64 | |
| 65 | class VOLTTenant(Tenant): |
| 66 | class Meta: |
| 67 | proxy = True |
| 68 | |
| 69 | KIND = "vOLT" |
| 70 | |
Scott Baker | 679f702 | 2015-04-20 11:50:09 -0700 | [diff] [blame] | 71 | default_attributes = {"vlan_id": None, } |
| 72 | |
Scott Baker | 323eca9 | 2015-04-20 09:48:34 -0700 | [diff] [blame] | 73 | 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 Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 79 | @property |
Scott Baker | 679f702 | 2015-04-20 11:50:09 -0700 | [diff] [blame] | 80 | 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 Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 88 | def vcpe(self): |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 89 | if getattr(self, "cached_vcpe", None): |
| 90 | return self.cached_vcpe |
Scott Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 91 | 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 Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 97 | vcpe=vcpes[0] |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 98 | vcpe.caller = self.creator |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 99 | self.cached_vcpe = vcpe |
| 100 | return vcpe |
Scott Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 101 | |
| 102 | @vcpe.setter |
| 103 | def vcpe(self, value): |
| 104 | if value: |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 105 | 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 Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 109 | |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 110 | @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 Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 132 | 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 Baker | 7f8ef8f | 2015-04-20 14:24:29 -0700 | [diff] [blame] | 141 | raise XOSConfigurationError("No VCPE Services available") |
Scott Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 142 | |
| 143 | vcpe = VCPETenant(provider_service = vcpeServices[0], |
| 144 | subscriber_tenant = self) |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 145 | vcpe.caller = self.creator |
Scott Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 146 | vcpe.save() |
| 147 | |
| 148 | try: |
| 149 | self.vcpe = vcpe |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 150 | super(VOLTTenant, self).save() |
Scott Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 151 | 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 Baker | 7f8ef8f | 2015-04-20 14:24:29 -0700 | [diff] [blame] | 161 | self.validate_unique_service_specific_id() |
| 162 | |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 163 | 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 Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 171 | 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 | |
| 182 | class VCPEService(Service): |
| 183 | KIND = "vCPE" |
| 184 | |
| 185 | class Meta: |
| 186 | app_label = "cord" |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 187 | verbose_name = "vCPE Service" |
Scott Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 188 | proxy = True |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 189 | |
| 190 | class VCPETenant(Tenant): |
| 191 | class Meta: |
| 192 | proxy = True |
| 193 | |
Scott Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 194 | KIND = "vCPE" |
| 195 | |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 196 | sync_attributes = ("firewall_enable", |
| 197 | "firewall_rules", |
| 198 | "url_filter_enable", |
| 199 | "url_filter_rules", |
| 200 | "cdn_enable") |
| 201 | |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 202 | default_attributes = {"firewall_enable": False, |
Scott Baker | 05eb497 | 2015-04-16 21:54:50 -0700 | [diff] [blame] | 203 | "firewall_rules": "accept all anywhere anywhere", |
| 204 | "url_filter_enable": False, |
| 205 | "url_filter_rules": "allow all", |
Scott Baker | 647d45d | 2015-05-14 20:29:04 -0700 | [diff] [blame] | 206 | "url_filter_level": "PG", |
Scott Baker | 05eb497 | 2015-04-16 21:54:50 -0700 | [diff] [blame] | 207 | "cdn_enable": False, |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 208 | "sliver_id": None} |
| 209 | |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 210 | def __init__(self, *args, **kwargs): |
| 211 | super(VCPETenant, self).__init__(*args, **kwargs) |
| 212 | self.cached_vbng=None |
| 213 | self.cached_sliver=None |
| 214 | |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 215 | @property |
| 216 | def image(self): |
Scott Baker | 8c0ae62 | 2015-04-20 20:12:59 -0700 | [diff] [blame] | 217 | 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 Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 226 | |
| 227 | @property |
| 228 | def sliver(self): |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 229 | if getattr(self, "cached_sliver", None): |
| 230 | return self.cached_sliver |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 231 | 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 Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 237 | sliver=slivers[0] |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 238 | sliver.caller = self.creator |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 239 | self.cached_sliver = sliver |
| 240 | return sliver |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 241 | |
| 242 | @sliver.setter |
| 243 | def sliver(self, value): |
| 244 | if value: |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 245 | 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 Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 251 | 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 Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 273 | 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 Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 283 | vbng.caller = self.creator |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 284 | 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 Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 294 | |
| 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 Baker | 05eb497 | 2015-04-16 21:54:50 -0700 | [diff] [blame] | 303 | @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 Baker | 647d45d | 2015-05-14 20:29:04 -0700 | [diff] [blame] | 320 | 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 Baker | 05eb497 | 2015-04-16 21:54:50 -0700 | [diff] [blame] | 328 | 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 Baker | 647d45d | 2015-05-14 20:29:04 -0700 | [diff] [blame] | 343 | @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 Baker | aa1e96d | 2015-05-15 14:59:47 -0700 | [diff] [blame^] | 356 | return {"cdn": self.cdn_enable, |
| 357 | "url_filter": self.url_filter_enable, |
| 358 | "firewall": self.firewall_enable} |
Scott Baker | 647d45d | 2015-05-14 20:29:04 -0700 | [diff] [blame] | 359 | |
| 360 | @services.setter |
| 361 | def services(self, value): |
| 362 | pass |
| 363 | |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 364 | 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 Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 372 | # Each VCPE object owns exactly one sliver. |
| 373 | |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 374 | if self.deleted: |
| 375 | return |
| 376 | |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 377 | if (self.sliver is not None) and (self.sliver.image != self.image): |
| 378 | self.sliver.delete() |
| 379 | self.sliver = None |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 380 | |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 381 | if self.sliver is None: |
| 382 | if not self.provider_service.slices.count(): |
Scott Baker | f6790db | 2015-05-06 15:46:34 -0700 | [diff] [blame] | 383 | raise XOSConfigurationError("The VCPE service has no slices") |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 384 | |
Scott Baker | e1f72d1 | 2015-05-14 21:48:53 -0700 | [diff] [blame] | 385 | flavors = Flavor.objects.filter(name="m1.small") |
| 386 | if not flavors: |
| 387 | raise XOSConfigurationError("No m1.small flavor") |
| 388 | |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 389 | node =self.pick_node() |
| 390 | sliver = Sliver(slice = self.provider_service.slices.all()[0], |
| 391 | node = node, |
| 392 | image = self.image, |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 393 | creator = self.creator, |
Scott Baker | e1f72d1 | 2015-05-14 21:48:53 -0700 | [diff] [blame] | 394 | deployment = node.site_deployment.deployment, |
| 395 | flavor = flavors[0]) |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 396 | sliver.save() |
| 397 | |
Scott Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 398 | try: |
| 399 | self.sliver = sliver |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 400 | super(VCPETenant, self).save() |
Scott Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 401 | except: |
| 402 | sliver.delete() |
| 403 | raise |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 404 | |
| 405 | def cleanup_sliver(self): |
| 406 | if self.sliver: |
| 407 | self.sliver.delete() |
| 408 | self.sliver = None |
| 409 | |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 410 | 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 Baker | 7f8ef8f | 2015-04-20 14:24:29 -0700 | [diff] [blame] | 419 | raise XOSConfigurationError("No VBNG Services available") |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 420 | |
| 421 | vbng = VBNGTenant(provider_service = vbngServices[0], |
| 422 | subscriber_tenant = self) |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 423 | vbng.caller = self.creator |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 424 | 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 Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 438 | def save(self, *args, **kwargs): |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 439 | 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 Baker | f6790db | 2015-05-06 15:46:34 -0700 | [diff] [blame] | 442 | raise XOSProgrammingError("VCPETenant's self.caller was not set") |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 443 | self.creator = self.caller |
| 444 | if not self.creator: |
Scott Baker | f6790db | 2015-05-06 15:46:34 -0700 | [diff] [blame] | 445 | raise XOSProgrammingError("VCPETenant's self.creator was not set") |
Scott Baker | c633dc9 | 2015-05-05 17:49:46 -0700 | [diff] [blame] | 446 | |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 447 | super(VCPETenant, self).save(*args, **kwargs) |
Scott Baker | d4b48c0 | 2015-04-15 20:59:15 -0700 | [diff] [blame] | 448 | self.manage_sliver() |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 449 | self.manage_vbng() |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 450 | |
| 451 | def delete(self, *args, **kwargs): |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 452 | self.cleanup_vbng() |
Scott Baker | e9ff7ce | 2015-04-14 17:19:16 -0700 | [diff] [blame] | 453 | self.cleanup_sliver() |
| 454 | super(VCPETenant, self).delete(*args, **kwargs) |
| 455 | |
Scott Baker | fa5cdd6 | 2015-04-20 09:16:17 -0700 | [diff] [blame] | 456 | #---------------------------------------------------------------------------- |
| 457 | # vBNG |
| 458 | #---------------------------------------------------------------------------- |
| 459 | |
| 460 | class VBNGService(Service): |
| 461 | KIND = "vBNG" |
| 462 | |
| 463 | class Meta: |
| 464 | app_label = "cord" |
| 465 | verbose_name = "vBNG Service" |
| 466 | proxy = True |
| 467 | |
| 468 | class 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) |