querysets.py 4.3 KB

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