No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

views.py 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. # This file is part of dnmgmt, a number resource management system
  2. # Licensed under GNU General Public License v3 or later
  3. # Written by Sebastian Lohff (seba@someserver.de)
  4. #from django.shortcuts import render
  5. from django.http import JsonResponse
  6. from django.core.exceptions import ValidationError
  7. from django.contrib.auth.views import login_required
  8. from django.db.models import Q
  9. from whoisdb.models import ASBlock, ASNumber, InetNum
  10. from domains.models import Domain, ReverseZone
  11. from dnmgmt.settings import TLD_NAMESERVERS
  12. from .dnshelper import checkDomain as helperCheckDomain
  13. import ipaddress
  14. @login_required
  15. def asblockFreeAS(request):
  16. ret = {
  17. "success": False,
  18. "errorMsg": None,
  19. "number": -1,
  20. }
  21. try:
  22. blockName = request.GET.get('block', None)
  23. if not blockName:
  24. raise ValidationError("No block given")
  25. try:
  26. mnts = request.user.maintainer_set.all()
  27. block = ASBlock.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct().get(handle=blockName)
  28. if block.asblock_set.count() > 0:
  29. raise ValidationError("AS Block already has sub AS Blocks")
  30. if block.asnumber_set.count() > 0:
  31. num = block.asnumber_set.order_by("-number")[0].number + 1
  32. if num > block.asEnd:
  33. num = None
  34. for n in range(block.asBegin, block.asEnd + 1):
  35. try:
  36. ASNumber.objects.get(number=n)
  37. except ASNumber.DoesNotExist:
  38. num = n
  39. break
  40. if not num:
  41. raise ValidationError("No free AS Number in block")
  42. ret["number"] = num
  43. else:
  44. ret["number"] = block.asBegin
  45. except ASBlock.DoesNotExist:
  46. raise ValidationError("Could not get AS Block")
  47. ret["success"] = True
  48. except ValidationError as e:
  49. ret["errorMsg"] = e.message
  50. return JsonResponse(ret)
  51. @login_required
  52. def freeSubnet(request):
  53. ret = {
  54. "success": False,
  55. "errorMsg": None,
  56. "network": None,
  57. }
  58. try:
  59. parentRangeName = request.GET.get('parentRange', None)
  60. if not parentRangeName:
  61. raise ValidationError("No subnet given")
  62. parentRange = None
  63. try:
  64. mnts = request.user.maintainer_set.all()
  65. parentRange = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct().get(handle=parentRangeName)
  66. except InetNum.DoesNotExist:
  67. raise ValidationError("Parent range does not exist / is not maintained by you")
  68. prefixLen = 0
  69. try:
  70. prefixLen = request.GET.get("prefixLen", None)
  71. if not prefixLen:
  72. if parentRange.protocol == InetNum.IPv4:
  73. prefixLen = 27
  74. else:
  75. prefixLen = 60
  76. prefixLen = int(prefixLen)
  77. if prefixLen < 8 or \
  78. (parentRange.protocol == InetNum.IPv4 and prefixLen > 32) or \
  79. (parentRange.protocol == InetNum.IPv6 and prefixLen > 128):
  80. raise ValidationError("Given prefix length is out of range")
  81. except ValueError:
  82. raise ValidationError("PrefixLen is not a number")
  83. usableNet = None
  84. # FIXME: use first biggest usable netblock...
  85. #biggestNet = parentRange.inetnum_set.order_by("-address")
  86. #if biggestNet
  87. # candidateNet =
  88. # and (biggestNet.getNetwork().broadcast_address.:
  89. # try using next network in range
  90. # ordering does not work, as order_by sorts alphabetically
  91. # ==> the set is short, we can iterate through all. no sense in unpacking the SQL magic
  92. #biggestNets = parentRange.inetnum_set.order_by("-address")
  93. biggestNet = None
  94. for ipRange in parentRange.inetnum_set.all():
  95. if not biggestNet or ipRange.getNetwork() > biggestNet:
  96. biggestNet = ipRange.getNetwork()
  97. if biggestNet:
  98. candidateNet = ipaddress.ip_network("%s/%s" % (biggestNet.broadcast_address + 1, biggestNet.prefixlen))
  99. print("biggest net", biggestNet, "candidate", candidateNet)
  100. if candidateNet.network_address in parentRange.getNetwork():
  101. usableNet = candidateNet
  102. # check if there are still networks left in range
  103. if not usableNet:
  104. # search for free network
  105. nets = list(parentRange.getNetwork().subnets())
  106. for subRange in parentRange.inetnum_set.all():
  107. newNet = None
  108. for net in nets:
  109. if subRange.getNetwork().network_address in net:
  110. newNet = net
  111. if not newNet:
  112. # critical error, we want a 500 here
  113. raise ValueError("Subnet not in range")
  114. nets.remove(newNet)
  115. nets.extend(newNet.address_exclude(subRange.getNetwork()))
  116. nets = sorted(nets)
  117. for net in nets:
  118. if net.prefixlen <= prefixLen:
  119. usableNet = net
  120. break
  121. if not usableNet:
  122. raise ValidationError("No space left in given range")
  123. ret["network"] = "%s/%s" % (usableNet.network_address, prefixLen)
  124. ret["success"] = True
  125. except ValidationError as e:
  126. ret["errorMsg"] = e.message
  127. return JsonResponse(ret)
  128. @login_required
  129. def getSubnet(request):
  130. ret = {
  131. "success": False,
  132. "errorMsg": None,
  133. "network": None,
  134. }
  135. try:
  136. netName = request.GET.get('net', None)
  137. mnts = request.user.maintainer_set.all()
  138. nets = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
  139. net = nets.get(handle=netName)
  140. ret["success"] = True
  141. ret["network"] = net.prefix()
  142. except InetNum.DoesNotExist:
  143. ret["errorMsg"] = "Chosen network does not exist"
  144. return JsonResponse(ret)
  145. @login_required
  146. def checkDomain(request):
  147. ret = {
  148. "success": False,
  149. "errorMsg": None,
  150. "domain": None,
  151. "result": None,
  152. }
  153. try:
  154. domainName = Domain.fixName(request.GET.get('domain', ''))
  155. domain = Domain.objects.get(name=domainName)
  156. #if not domain.canEdit(request.user):
  157. # raise Domain.DoesNotExist()
  158. ret["success"] = True
  159. ret["domain"] = domain.name
  160. # FIXME: change this if we ever have more than one...
  161. ret["result"] = helperCheckDomain(domain.name, TLD_NAMESERVERS[0], domain.nameservers.all())
  162. except Domain.DoesNotExist:
  163. ret["errorMsg"] = "Domain does not exist"
  164. return JsonResponse(ret)
  165. @login_required
  166. def checkRzone(request):
  167. ret = {
  168. "success": False,
  169. "errorMsg": None,
  170. "domain": None,
  171. "result": None,
  172. }
  173. try:
  174. rzonePk = int(request.GET.get('domain', ''))
  175. rzone = ReverseZone.objects.get(pk=rzonePk)
  176. #if not rzone.canEdit(request.user):
  177. # raise ReverseZone.DoesNotExist()
  178. ret["success"] = True
  179. # FIXME: change this if we ever have more than one...
  180. ret["result"] = helperCheckDomain(rzone.getZone(), TLD_NAMESERVERS[0], rzone.nameservers.all())
  181. except (ReverseZone.DoesNotExist, ValueError):
  182. ret["errorMsg"] = "ReverseZone does not exist"
  183. return JsonResponse(ret)
  184. def getROA(request):
  185. roa = {}
  186. for asn in ASNumber.objects.all():
  187. nets = []
  188. for net in asn.inetnum_set.all():
  189. nets.append(net.prefix())
  190. if nets:
  191. roa[asn.number] = nets
  192. return JsonResponse(roa)