Omar Abdelkader | 6e806dc | 2017-08-30 23:56:48 -0600 | [diff] [blame] | 1 | from django.db import models, transaction |
| 2 | from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, NetworkParameter, NetworkParameterType, Port, AddressPool |
| 3 | from core.models.plcorebase import StrippedCharField |
| 4 | import os |
| 5 | from django.forms.models import model_to_dict |
| 6 | from django.db.models import * |
| 7 | from operator import itemgetter, attrgetter, methodcaller |
| 8 | from core.models import Tag |
| 9 | from core.models.service import LeastLoadedNodeScheduler |
| 10 | import traceback |
| 11 | from xos.exceptions import * |
| 12 | from xos.config import Config |
| 13 | |
| 14 | from models_decl import VEPCService_decl, VEPCTenant_decl |
| 15 | from services.vhss.models import VHSSService, VHSSTenant |
| 16 | from services.vmme.models import VMMEService, VMMETenant |
| 17 | from services.vmm.models import VMMService, VMMTenant |
| 18 | from services.vsm.models import VSMService, VSMTenant |
| 19 | from services.vsgwc.models import VSGWCService, VSGWCTenant |
| 20 | from services.vsgwu.models import VSGWUService, VSGWUTenant |
| 21 | from services.vpgwc.models import VPGWCService, VPGWCTenant |
| 22 | from services.vpgwu.models import VPGWUService, VPGWUTenant |
| 23 | |
| 24 | class VEPCService(VEPCService_decl): |
| 25 | class Meta: |
| 26 | proxy = True |
| 27 | |
| 28 | class VEPCTenant(VEPCTenant_decl): |
| 29 | class Meta: |
| 30 | proxy = True |
| 31 | |
| 32 | def __init__(self, *args, **kwargs): |
| 33 | vepcservices = VEPCService.get_service_objects().all() |
| 34 | if vepcservices: |
| 35 | self._meta.get_field("provider_service").default = vepcservices[0].id |
| 36 | super(VEPCTenant, self).__init__(*args, **kwargs) |
| 37 | self.cached_vhss = None |
| 38 | self.cached_vmme = None |
| 39 | self.cached_vmm = None |
| 40 | self.cached_vsm = None |
| 41 | self.cached_vsgwc = None |
| 42 | self.cached_vsgwu = None |
| 43 | self.cached_vpgwc = None |
| 44 | self.cached_vpgwu = None |
| 45 | |
| 46 | @property |
| 47 | def vhss(self): |
| 48 | vhss = self.get_newest_subscribed_tenant(VHSSTenant) |
| 49 | if not vhss: |
| 50 | return None |
| 51 | |
| 52 | if (self.cached_vhss) and (self.cached_vhss.id == vhss.id): |
| 53 | return self.cached_vhss |
| 54 | |
| 55 | vhss.caller = self.creator |
| 56 | self.cached_vhss = vhss |
| 57 | return vhss |
| 58 | |
| 59 | @vhss.setter |
| 60 | def vhss(self, value): |
| 61 | raise XOSConfigurationError("VEPCTenant.vhss setter is not implemented") |
| 62 | |
| 63 | def get_vhss_service(self): |
| 64 | vhssservices = VHSSService.get_service_objects().all() |
| 65 | if not vhssservices: |
| 66 | raise XOSConfigurationError("No VHSS Services available") |
| 67 | return vhssservices[0] |
| 68 | |
| 69 | def manage_vhss(self): |
| 70 | # Each vEPC object owns exactly one VHSSTenant object |
| 71 | if self.deleted: |
| 72 | return |
| 73 | |
| 74 | if self.has_vhss: |
| 75 | if self.vhss is None: |
| 76 | vhss = self.get_vhss_service().create_tenant(subscriber_tenant=self, creator=self.creator) |
| 77 | #vhss = self.get_vhss_service().create_tenant(subscriber_tenant=self, creator=self.creator, vhss_vendor=self.vhss_vendor) |
| 78 | else: |
| 79 | if self.vhss: |
| 80 | self.cleanup_vhss() |
| 81 | |
| 82 | def cleanup_vhss(self): |
| 83 | if self.vhss: |
| 84 | self.vhss.delete() |
| 85 | |
| 86 | @property |
| 87 | def vmme(self): |
| 88 | vmme = self.get_newest_subscribed_tenant(VMMETenant) |
| 89 | if not vmme: |
| 90 | return None |
| 91 | |
| 92 | if (self.cached_vmme) and (self.cached_vmme.id == vmme.id): |
| 93 | return self.cached_vmme |
| 94 | |
| 95 | vmme.caller = self.creator |
| 96 | self.cached_vmme = vmme |
| 97 | return vmme |
| 98 | |
| 99 | @vmme.setter |
| 100 | def vmme(self, value): |
| 101 | raise XOSConfigurationError("VEPCTenant.vmme setter is not implemented") |
| 102 | |
| 103 | def get_vmme_service(self): |
| 104 | vmmeservices = VMMEService.get_service_objects().all() |
| 105 | if not vmmeservices: |
| 106 | raise XOSConfigurationError("No VMME Services available") |
| 107 | return vmmeservices[0] |
| 108 | |
| 109 | def manage_vmme(self): |
| 110 | # Each vEPC object owns exactly one VMMETenant object |
| 111 | if self.deleted: |
| 112 | return |
| 113 | |
| 114 | if self.has_vmme: |
| 115 | if self.vmme is None: |
| 116 | vmme = self.get_vmme_service().create_tenant(subscriber_tenant=self, creator=self.creator) |
| 117 | #vmme = self.get_vmme_service().create_tenant(subscriber_tenant=self, creator=self.creator, vmme_vendor=self.vmme_vendor) |
| 118 | else: |
| 119 | if self.vmme: |
| 120 | self.cleanup_vmme() |
| 121 | |
| 122 | def cleanup_vmme(self): |
| 123 | if self.vmme: |
| 124 | self.vmme.delete() |
| 125 | |
| 126 | @property |
| 127 | def vmm(self): |
| 128 | vmm = self.get_newest_subscribed_tenant(VMMTenant) |
| 129 | if not vmm: |
| 130 | return None |
| 131 | |
| 132 | if (self.cached_vmm) and (self.cached_vmm.id == vmm.id): |
| 133 | return self.cached_vmm |
| 134 | |
| 135 | vmm.caller = self.creator |
| 136 | self.cached_vmm = vmm |
| 137 | return vmm |
| 138 | |
| 139 | @vmm.setter |
| 140 | def vmm(self, value): |
| 141 | raise XOSConfigurationError("VEPCTenant.vmm setter is not implemented") |
| 142 | |
| 143 | def get_vmm_service(self): |
| 144 | vmmservices = VMMService.get_service_objects().all() |
| 145 | if not vmmservices: |
| 146 | raise XOSConfigurationError("No VMM Services available") |
| 147 | return vmmservices[0] |
| 148 | |
| 149 | def manage_vmm(self): |
| 150 | # Each vEPC object owns exactly one VMMTenant object |
| 151 | if self.deleted: |
| 152 | return |
| 153 | |
| 154 | if self.has_vmm: |
| 155 | if self.vmm is None: |
| 156 | vmm = self.get_vmm_service().create_tenant(subscriber_tenant=self, creator=self.creator) |
| 157 | #vmm = self.get_vmm_service().create_tenant(subscriber_tenant=self, creator=self.creator, vmm_vendor=self.vmm_vendor) |
| 158 | else: |
| 159 | if self.vmm: |
| 160 | self.cleanup_vmm() |
| 161 | |
| 162 | def cleanup_vmm(self): |
| 163 | if self.vmm: |
| 164 | self.vmm.delete() |
| 165 | |
| 166 | @property |
| 167 | def vsm(self): |
| 168 | vsm = self.get_newest_subscribed_tenant(VSMTenant) |
| 169 | if not vsm: |
| 170 | return None |
| 171 | |
| 172 | if (self.cached_vsm) and (self.cached_vsm.id == vsm.id): |
| 173 | return self.cached_vsm |
| 174 | |
| 175 | vsm.caller = self.creator |
| 176 | self.cached_vsm = vsm |
| 177 | return vsm |
| 178 | |
| 179 | @vsm.setter |
| 180 | def vsm(self, value): |
| 181 | raise XOSConfigurationError("VEPCTenant.vsm setter is not implemented") |
| 182 | |
| 183 | def get_vsm_service(self): |
| 184 | vsmservices = VSMService.get_service_objects().all() |
| 185 | if not vsmservices: |
| 186 | raise XOSConfigurationError("No VSM Services available") |
| 187 | return vsmservices[0] |
| 188 | |
| 189 | def manage_vsm(self): |
| 190 | # Each vEPC object owns exactly one VSMTenant object |
| 191 | if self.deleted: |
| 192 | return |
| 193 | |
| 194 | if self.has_vsm: |
| 195 | if self.vsm is None: |
| 196 | vsm = self.get_vsm_service().create_tenant(subscriber_tenant=self, creator=self.creator) |
| 197 | #vsm = self.get_vsm_service().create_tenant(subscriber_tenant=self, creator=self.creator, vsm_vendor=self.vsm_vendor) |
| 198 | else: |
| 199 | if self.vsm: |
| 200 | self.cleanup_vsm() |
| 201 | |
| 202 | def cleanup_vsm(self): |
| 203 | if self.vsm: |
| 204 | self.vsm.delete() |
| 205 | |
| 206 | @property |
| 207 | def vsgwc(self): |
| 208 | vsgwc = self.get_newest_subscribed_tenant(VSGWCTenant) |
| 209 | if not vsgwc: |
| 210 | return None |
| 211 | |
| 212 | if (self.cached_vsgwc) and (self.cached_vsgwc.id == vsgwc.id): |
| 213 | return self.cached_vsgwc |
| 214 | |
| 215 | vsgwc.caller = self.creator |
| 216 | self.cached_vsgwc = vsgwc |
| 217 | return vsgwc |
| 218 | |
| 219 | @vsgwc.setter |
| 220 | def vsgwc(self, value): |
| 221 | raise XOSConfigurationError("VEPCTenant.vsgwc setter is not implemented") |
| 222 | |
| 223 | def get_vsgwc_service(self): |
| 224 | vsgwcservices = VSGWCService.get_service_objects().all() |
| 225 | if not vsgwcservices: |
| 226 | raise XOSConfigurationError("No VSGWC Services available") |
| 227 | return vsgwcservices[0] |
| 228 | |
| 229 | def manage_vsgwc(self): |
| 230 | # Each vEPC object owns exactly one VSGWCTenant object |
| 231 | if self.deleted: |
| 232 | return |
| 233 | |
| 234 | if self.has_vsgwc: |
| 235 | if self.vsgwc is None: |
| 236 | vsgwc = self.get_vsgwc_service().create_tenant(subscriber_tenant=self, creator=self.creator) |
| 237 | #vsgwc = self.get_vsgwc_service().create_tenant(subscriber_tenant=self, creator=self.creator, vsgwc_vendor=self.vsgwc_vendor) |
| 238 | else: |
| 239 | if self.vsgwc: |
| 240 | self.cleanup_vsgwc() |
| 241 | |
| 242 | def cleanup_vsgwc(self): |
| 243 | if self.vsgwc: |
| 244 | self.vsgwc.delete() |
| 245 | |
| 246 | @property |
| 247 | def vsgwu(self): |
| 248 | vsgwu = self.get_newest_subscribed_tenant(VSGWUTenant) |
| 249 | if not vsgwu: |
| 250 | return None |
| 251 | |
| 252 | if (self.cached_vsgwu) and (self.cached_vsgwu.id == vsgwu.id): |
| 253 | return self.cached_vsgwu |
| 254 | |
| 255 | vsgwu.caller = self.creator |
| 256 | self.cached_vsgwu = vsgwu |
| 257 | return vsgwu |
| 258 | |
| 259 | @vsgwu.setter |
| 260 | def vsgwu(self, value): |
| 261 | raise XOSConfigurationError("VEPCTenant.vsgwu setter is not implemented") |
| 262 | |
| 263 | def get_vsgwu_service(self): |
| 264 | vsgwuservices = VSGWUService.get_service_objects().all() |
| 265 | if not vsgwuservices: |
| 266 | raise XOSConfigurationError("No VSGWU Services available") |
| 267 | return vsgwuservices[0] |
| 268 | |
| 269 | def manage_vsgwu(self): |
| 270 | # Each vEPC object owns exactly one VSGWUTenant object |
| 271 | if self.deleted: |
| 272 | return |
| 273 | |
| 274 | if self.has_vsgwu: |
| 275 | if self.vsgwu is None: |
| 276 | vsgwu = self.get_vsgwu_service().create_tenant(subscriber_tenant=self, creator=self.creator) |
| 277 | #vsgwu = self.get_vsgwu_service().create_tenant(subscriber_tenant=self, creator=self.creator, vsgwu_vendor=self.vsgwu_vendor) |
| 278 | else: |
| 279 | if self.vsgwu: |
| 280 | self.cleanup_vsgwu() |
| 281 | |
| 282 | def cleanup_vsgwu(self): |
| 283 | if self.vsgwu: |
| 284 | self.vsgwu.delete() |
| 285 | |
| 286 | @property |
| 287 | def vpgwc(self): |
| 288 | vpgwc = self.get_newest_subscribed_tenant(VPGWCTenant) |
| 289 | if not vpgwc: |
| 290 | return None |
| 291 | |
| 292 | if (self.cached_vpgwc) and (self.cached_vpgwc.id == vpgwc.id): |
| 293 | return self.cached_vpgwc |
| 294 | |
| 295 | vpgwc.caller = self.creator |
| 296 | self.cached_vpgwc = vpgwc |
| 297 | return vpgwc |
| 298 | |
| 299 | @vpgwc.setter |
| 300 | def vpgwc(self, value): |
| 301 | raise XOSConfigurationError("VEPCTenant.vpgwc setter is not implemented") |
| 302 | |
| 303 | def get_vpgwc_service(self): |
| 304 | vpgwcservices = VPGWCService.get_service_objects().all() |
| 305 | if not vpgwcservices: |
| 306 | raise XOSConfigurationError("No VPGWC Services available") |
| 307 | return vpgwcservices[0] |
| 308 | |
| 309 | def manage_vpgwc(self): |
| 310 | # Each vEPC object owns exactly one VPGWCTenant object |
| 311 | if self.deleted: |
| 312 | return |
| 313 | |
| 314 | if self.has_vpgwc: |
| 315 | if self.vpgwc is None: |
| 316 | vpgwc = self.get_vpgwc_service().create_tenant(subscriber_tenant=self, creator=self.creator) |
| 317 | #vpgwc = self.get_vpgwc_service().create_tenant(subscriber_tenant=self, creator=self.creator, vpgwc_vendor=self.vpgwc_vendor) |
| 318 | else: |
| 319 | if self.vpgwc: |
| 320 | self.cleanup_vpgwc() |
| 321 | |
| 322 | def cleanup_vpgwc(self): |
| 323 | if self.vpgwc: |
| 324 | self.vpgwc.delete() |
| 325 | |
| 326 | @property |
| 327 | def vpgwu(self): |
| 328 | vpgwu = self.get_newest_subscribed_tenant(VPGWUTenant) |
| 329 | if not vpgwu: |
| 330 | return None |
| 331 | |
| 332 | if (self.cached_vpgwu) and (self.cached_vpgwu.id == vpgwu.id): |
| 333 | return self.cached_vpgwu |
| 334 | |
| 335 | vpgwu.caller = self.creator |
| 336 | self.cached_vpgwu = vpgwu |
| 337 | return vpgwu |
| 338 | |
| 339 | @vpgwu.setter |
| 340 | def vpgwu(self, value): |
| 341 | raise XOSConfigurationError("VEPCTenant.vpgwu setter is not implemented") |
| 342 | |
| 343 | def get_vpgwu_service(self): |
| 344 | vpgwuservices = VPGWUService.get_service_objects().all() |
| 345 | if not vpgwuservices: |
| 346 | raise XOSConfigurationError("No VPGWU Services available") |
| 347 | return vpgwuservices[0] |
| 348 | |
| 349 | def manage_vpgwu(self): |
| 350 | # Each vEPC object owns exactly one VPGWUTenant object |
| 351 | if self.deleted: |
| 352 | return |
| 353 | |
| 354 | if self.has_vpgwu: |
| 355 | if self.vpgwu is None: |
| 356 | vpgwu = self.get_vpgwu_service().create_tenant(subscriber_tenant=self, creator=self.creator) |
| 357 | #vpgwu = self.get_vpgwu_service().create_tenant(subscriber_tenant=self, creator=self.creator, vpgwu_vendor=self.vpgwu_vendor) |
| 358 | else: |
| 359 | if self.vpgwu: |
| 360 | self.cleanup_vpgwu() |
| 361 | |
| 362 | def cleanup_vpgwu(self): |
| 363 | if self.vpgwu: |
| 364 | self.vpgwu.delete() |
| 365 | |
| 366 | def cleanup_orphans(self): |
| 367 | # ensure vMME only has at most one of each service |
| 368 | cur_vhss = self.vhss |
| 369 | cur_vmme = self.vmme |
| 370 | cur_vmm = self.vmm |
| 371 | cur_vsm = self.vsm |
| 372 | cur_vsgwc = self.vsgwc |
| 373 | cur_vsgwu = self.vsgwu |
| 374 | cur_vpgwc = self.vpgwc |
| 375 | cur_vpgwu = self.vpgwu |
| 376 | |
| 377 | for vhss in list(self.get_subscribed_tenants(VHSSTenant)): |
| 378 | if (not cur_vhss) or (vhss.id != cur_vhss.id): |
| 379 | vhss.delete() |
| 380 | |
| 381 | for vmme in list(self.get_subscribed_tenants(VMMETenant)): |
| 382 | if (not cur_vmme) or (vmme.id != cur_vmme.id): |
| 383 | vmme.delete() |
| 384 | |
| 385 | for vmm in list(self.get_subscribed_tenants(VMMTenant)): |
| 386 | if (not cur_vmm) or (vmm.id != cur_vmm.id): |
| 387 | vmm.delete() |
| 388 | |
| 389 | for vsm in list(self.get_subscribed_tenants(VSMTenant)): |
| 390 | if (not cur_vsm) or (vsm.id != cur_vsm.id): |
| 391 | vsm.delete() |
| 392 | |
| 393 | for vsgwc in list(self.get_subscribed_tenants(VSGWCTenant)): |
| 394 | if (not cur_vsgwc) or (vsgwc.id != cur_vsgwc.id): |
| 395 | vsgwc.delete() |
| 396 | |
| 397 | for vsgwu in list(self.get_subscribed_tenants(VSGWUTenant)): |
| 398 | if (not cur_vsgwu) or (vsgwu.id != cur_vsgwu.id): |
| 399 | vsgwu.delete() |
| 400 | |
| 401 | for vpgwc in list(self.get_subscribed_tenants(VPGWCTenant)): |
| 402 | if (not cur_vpgwc) or (vpgwc.id != cur_vpgwc.id): |
| 403 | vpgwc.delete() |
| 404 | |
| 405 | for vpgwu in list(self.get_subscribed_tenants(VPGWUTenant)): |
| 406 | if (not cur_vpgwu) or (vpgwu.id != cur_vpgwu.id): |
| 407 | vpgwu.delete() |
| 408 | |
| 409 | def save(self, *args, **kwargs): |
| 410 | #https://stackoverflow.com/questions/31831620/can-i-make-at-least-one-field-a-requirement-on-a-django-model |
| 411 | if not (self.has_vhss or self.has_vmme or self.has_vmm or self.has_vsm or self.has_vsgwc or self.has_vsgwu or self.has_vpgwc or self.has_vpgwu): |
| 412 | raise XOSConfigurationError("Cannot have an empty service chain") |
| 413 | |
| 414 | super(VEPCTenant, self).save(*args, **kwargs) |
| 415 | # This call needs to happen so that an instance is created for this |
| 416 | # tenant is created in the slice. One instance is created per tenant. |
| 417 | model_policy_vepctenant(self.pk) |
| 418 | |
| 419 | def delete(self, *args, **kwargs): |
| 420 | # Delete the dependent instances on this service chain tenant |
| 421 | self.cleanup_vhss() |
| 422 | self.cleanup_vmme() |
| 423 | self.cleanup_vmm() |
| 424 | self.cleanup_vsm() |
| 425 | self.cleanup_vsgwc() |
| 426 | self.cleanup_vsgwu() |
| 427 | self.cleanup_vpgwc() |
| 428 | self.cleanup_vpgwu() |
| 429 | super(VEPCTenant, self).delete(*args, **kwargs) |
| 430 | |
| 431 | def model_policy_vepctenant(pk): |
| 432 | # TODO: this should be made in to a real model_policy |
| 433 | with transaction.atomic(): |
| 434 | tenant = VEPCTenant.objects.select_for_update().filter(pk=pk) |
| 435 | if not tenant: |
| 436 | return |
| 437 | tenant = tenant[0] |
| 438 | tenant.manage_vhss() |
| 439 | tenant.manage_vmme() |
| 440 | tenant.manage_vmm() |
| 441 | tenant.manage_vsm() |
| 442 | tenant.manage_vsgwc() |
| 443 | tenant.manage_vsgwu() |
| 444 | tenant.manage_vpgwc() |
| 445 | tenant.manage_vpgwu() |
| 446 | tenant.cleanup_orphans() |
| 447 | |