querysets.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. if vm.cluster.site:
  74. if vm.cluster.site.region:
  75. q |= Q(
  76. scope_type=ContentType.objects.get_by_natural_key('dcim', 'region'),
  77. scope_id__in=vm.cluster.site.region.get_ancestors(include_self=True)
  78. )
  79. if vm.cluster.site.group:
  80. q |= Q(
  81. scope_type=ContentType.objects.get_by_natural_key('dcim', 'sitegroup'),
  82. scope_id__in=vm.cluster.site.group.get_ancestors(include_self=True)
  83. )
  84. q |= Q(
  85. scope_type=ContentType.objects.get_by_natural_key('dcim', 'site'),
  86. scope_id=vm.cluster.site_id
  87. )
  88. if vm.cluster.group:
  89. q |= Q(
  90. scope_type=ContentType.objects.get_by_natural_key('virtualization', 'clustergroup'),
  91. scope_id=vm.cluster.group_id
  92. )
  93. q |= Q(
  94. scope_type=ContentType.objects.get_by_natural_key('virtualization', 'cluster'),
  95. scope_id=vm.cluster_id
  96. )
  97. vlan_groups = VLANGroup.objects.filter(q)
  98. # Return all applicable VLANs
  99. q = (
  100. Q(group__in=vlan_groups) |
  101. Q(group__scope_id__isnull=True, site__isnull=True) | # Global group VLANs
  102. Q(group__isnull=True, site__isnull=True) # Global VLANs
  103. )
  104. if vm.cluster.site:
  105. q |= Q(site=vm.cluster.site)
  106. return self.filter(q)