querysets.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. from django.contrib.contenttypes.models import ContentType
  2. from django.db.models import Q
  3. from django.db.models.expressions import RawSQL
  4. from utilities.querysets import RestrictedQuerySet
  5. class PrefixQuerySet(RestrictedQuerySet):
  6. def annotate_hierarchy(self):
  7. """
  8. Annotate the depth and number of child prefixes for each Prefix. Cast null VRF values to zero for
  9. comparison. (NULL != NULL).
  10. """
  11. return self.annotate(
  12. hierarchy_depth=RawSQL(
  13. 'SELECT COUNT(DISTINCT U0."prefix") AS "c" '
  14. 'FROM "ipam_prefix" U0 '
  15. 'WHERE (U0."prefix" >> "ipam_prefix"."prefix" '
  16. 'AND COALESCE(U0."vrf_id", 0) = COALESCE("ipam_prefix"."vrf_id", 0))',
  17. ()
  18. ),
  19. hierarchy_children=RawSQL(
  20. 'SELECT COUNT(U1."prefix") AS "c" '
  21. 'FROM "ipam_prefix" U1 '
  22. 'WHERE (U1."prefix" << "ipam_prefix"."prefix" '
  23. 'AND COALESCE(U1."vrf_id", 0) = COALESCE("ipam_prefix"."vrf_id", 0))',
  24. ()
  25. )
  26. )
  27. class VLANQuerySet(RestrictedQuerySet):
  28. def get_for_device(self, device):
  29. """
  30. Return all VLANs available to the specified Device.
  31. """
  32. from .models import VLANGroup
  33. # Find all relevant VLANGroups
  34. q = Q()
  35. if device.site.region:
  36. q |= Q(
  37. scope_type=ContentType.objects.get_by_natural_key('dcim', 'region'),
  38. scope_id__in=device.site.region.get_ancestors(include_self=True)
  39. )
  40. if device.site.group:
  41. q |= Q(
  42. scope_type=ContentType.objects.get_by_natural_key('dcim', 'sitegroup'),
  43. scope_id__in=device.site.group.get_ancestors(include_self=True)
  44. )
  45. q |= Q(
  46. scope_type=ContentType.objects.get_by_natural_key('dcim', 'site'),
  47. scope_id=device.site_id
  48. )
  49. if device.location:
  50. q |= Q(
  51. scope_type=ContentType.objects.get_by_natural_key('dcim', 'location'),
  52. scope_id__in=device.location.get_ancestors(include_self=True)
  53. )
  54. if device.rack:
  55. q |= Q(
  56. scope_type=ContentType.objects.get_by_natural_key('dcim', 'rack'),
  57. scope_id=device.rack_id
  58. )
  59. # Return all applicable VLANs
  60. return self.filter(
  61. Q(group__in=VLANGroup.objects.filter(q)) |
  62. Q(site=device.site) |
  63. Q(group__scope_id__isnull=True, site__isnull=True) | # Global group VLANs
  64. Q(group__isnull=True, site__isnull=True) # Global VLANs
  65. )
  66. def get_for_virtualmachine(self, vm):
  67. """
  68. Return all VLANs available to the specified VirtualMachine.
  69. """
  70. from .models import VLANGroup
  71. # Find all relevant VLANGroups
  72. q = Q()
  73. site = vm.site or vm.cluster.site
  74. if vm.cluster:
  75. # Add VLANGroups scoped to the assigned cluster (or its group)
  76. q |= Q(
  77. scope_type=ContentType.objects.get_by_natural_key('virtualization', 'cluster'),
  78. scope_id=vm.cluster_id
  79. )
  80. if vm.cluster.group:
  81. q |= Q(
  82. scope_type=ContentType.objects.get_by_natural_key('virtualization', 'clustergroup'),
  83. scope_id=vm.cluster.group_id
  84. )
  85. if site:
  86. # Add VLANGroups scoped to the assigned site (or its group or region)
  87. q |= Q(
  88. scope_type=ContentType.objects.get_by_natural_key('dcim', 'site'),
  89. scope_id=site.pk
  90. )
  91. if site.region:
  92. q |= Q(
  93. scope_type=ContentType.objects.get_by_natural_key('dcim', 'region'),
  94. scope_id__in=site.region.get_ancestors(include_self=True)
  95. )
  96. if site.group:
  97. q |= Q(
  98. scope_type=ContentType.objects.get_by_natural_key('dcim', 'sitegroup'),
  99. scope_id__in=site.group.get_ancestors(include_self=True)
  100. )
  101. vlan_groups = VLANGroup.objects.filter(q)
  102. # Return all applicable VLANs
  103. q = (
  104. Q(group__in=vlan_groups) |
  105. Q(group__scope_id__isnull=True, site__isnull=True) | # Global group VLANs
  106. Q(group__isnull=True, site__isnull=True) # Global VLANs
  107. )
  108. if site:
  109. q |= Q(site=site)
  110. return self.filter(q)