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.

models.py 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. # This file is part of dnmapper, an AS--level mapping tool
  2. # Licensed under GNU General Public License v3 or later
  3. # Written by Sebastian Lohff (seba@someserver.de)
  4. from django.db import models
  5. from django.db.models import Q
  6. # Create your models here.
  7. class ConfigHost(models.Model):
  8. CHECK_CHOICES = (
  9. ('CMK', "Check MK"),
  10. ('PLAIN', "Plain"),
  11. )
  12. # asno, ip, check method,
  13. name = models.CharField(max_length=50)
  14. number = models.IntegerField()
  15. ip = models.GenericIPAddressField()
  16. checkMethod = models.CharField(max_length=4, choices=CHECK_CHOICES)
  17. def __unicode__(self):
  18. return u"%s (%s / %s)" % (self.name, self.number, self.ip)
  19. class CrawlRun(models.Model):
  20. # time start, time end,
  21. startTime = models.DateTimeField()
  22. endTime = models.DateTimeField(null=True, blank=True)
  23. hostsCrawled = models.ManyToManyField(ConfigHost, null=True, blank=True)
  24. asCount = models.IntegerField(default=0)
  25. asOnlineCount = models.IntegerField(default=0)
  26. asOfflineCount = models.IntegerField(default=0)
  27. peeringCount = models.IntegerField(default=0)
  28. def __unicode__(self):
  29. return u"Run %d - %s to %s" % (self.pk, self.startTime, self.endTime if self.endTime else "?")
  30. def countAS(self):
  31. return self.asCount
  32. def countASOnline(self):
  33. return self.asOnlineCount
  34. def countASOffline(self):
  35. return self.asOfflineCount
  36. #return self.as_set.filter(online=False).count()
  37. def countPeerings(self):
  38. return self.peeringCount
  39. #return Peering.objects.filter(Q(as1__crawl=self)|Q(as2__crawl=self)).count()
  40. class CrawlLog(models.Model):
  41. INFO = 'INFO'
  42. ERROR = 'ERROR'
  43. DEBUG = 'DEBUG'
  44. WARN = 'WARN'
  45. SEVERITY = (
  46. (INFO, 'info'),
  47. (ERROR, 'error'),
  48. (DEBUG, 'debug'),
  49. (WARN, 'warning'),
  50. )
  51. crawl = models.ForeignKey(CrawlRun)
  52. host = models.ForeignKey(ConfigHost, null=True, blank=True, on_delete=models.SET_NULL)
  53. logtime = models.DateTimeField(auto_now_add=True)
  54. severity = models.CharField(max_length=10, choices=SEVERITY)
  55. message = models.TextField()
  56. @staticmethod
  57. def log(crawl, msg, severity=None, host=None):
  58. if not severity:
  59. severity = CrawlLog.ERROR
  60. log = CrawlLog()
  61. log.crawl = crawl
  62. log.message = msg
  63. log.severity = severity
  64. log.host = host
  65. log.save()
  66. def __unicode__(self):
  67. host = "host %s - " % self.host.name if self.host else ""
  68. return u"Log %s %s: %s%s" % (self.get_severity_display(), self.logtime, host, self.message)
  69. class AS(models.Model):
  70. # asno
  71. crawl = models.ForeignKey(CrawlRun)
  72. number = models.IntegerField(db_index=True)
  73. directlyCrawled = models.BooleanField(default=False)
  74. online = models.BooleanField(default=True, db_index=True)
  75. lastSeen = models.ForeignKey(CrawlRun, blank=True, null=True, default=None, related_name='as_lastseen')
  76. class Meta:
  77. unique_together = (('crawl', 'number'),)
  78. index_together = (
  79. ('crawl', 'number'),
  80. )
  81. def __unicode__(self):
  82. return u"AS %s (crawl %d)" % (self.number, self.crawl.pk)
  83. def setOnline(self):
  84. if not self.online:
  85. self.online = True
  86. self.lastSeen = None
  87. self.save()
  88. def getPeerings(self):
  89. return Peering.objects.filter(Q(as1=self)|Q(as2=self))
  90. def getAnnouncedPrefixes(self):
  91. return list(set(map(lambda _x: "%(ip)s/%(prefix)s" % _x, self.announcement_set.all().values('ip', 'prefix'))))
  92. def formatLastSeen(self):
  93. if self.lastSeen:
  94. return self.lastSeen.startTime.strftime("%d.%m.%Y %H:%I")
  95. class BorderRouter(models.Model):
  96. # as id, ip, check method, pingable, reachable
  97. # unique: (crawl_id, asno, as id)
  98. AS = models.ForeignKey(AS)
  99. routerID = models.GenericIPAddressField()
  100. pingable = models.BooleanField(default=False)
  101. reachable = models.BooleanField(default=False)
  102. def __unicode__(self):
  103. p = "p" if self.pingable else "!p"
  104. r = "r" if self.reachable else "!r"
  105. return u"Router %s (AS %s, %s%s)" % (self.routerID, self.AS.number, p, r)
  106. class Announcement(models.Model):
  107. router = models.ForeignKey(BorderRouter)
  108. ip = models.GenericIPAddressField()
  109. prefix = models.IntegerField()
  110. # NOTE: increase length for longer pathes (currently supports a length of ~85)
  111. ASPath = models.CharField(max_length=512)
  112. nextHop = models.GenericIPAddressField()
  113. originAS = models.ForeignKey(AS, null=True)
  114. crawlAS = models.ForeignKey(AS, related_name='crawl_as', null=True)
  115. def __unicode__(self):
  116. return u"%s/%s via %s (crawl %s)" % (self.ip, self.prefix, self.ASPath, self.router.AS.crawl.pk)
  117. class Peering(models.Model):
  118. DIRECT = 'direct'
  119. PATH = 'path'
  120. ORIGIN = (
  121. (PATH, 'BGP Path'),
  122. (DIRECT, 'Direct Connection'),
  123. )
  124. index_together = (
  125. ('as1', 'as2'),
  126. )
  127. as1 = models.ForeignKey(AS, related_name='peering1')
  128. as2 = models.ForeignKey(AS, related_name='peering2')
  129. origin = models.CharField(max_length=10, choices=ORIGIN)
  130. def __unicode__(self):
  131. return u"AS %s <--> AS %s (%s, crawl %s)" % (self.as1.number, self.as2.number, self.get_origin_display(), self.as1.crawl.pk)
  132. def containsAS(self, AS):
  133. return AS in (self.as1, self.as2)
  134. @staticmethod
  135. def getPeering(as1, as2):
  136. """ Find matching peering """
  137. try:
  138. return Peering.objects.get(as1=as1, as2=as2)
  139. except Peering.DoesNotExist:
  140. return Peering.objects.get(as1=as2, as2=as1)
  141. class BorderRouterPair(models.Model):
  142. peering = models.ForeignKey(Peering)
  143. router1 = models.ForeignKey(BorderRouter, default=None, blank=True, null=True, related_name='routerpair1')
  144. router2 = models.ForeignKey(BorderRouter, default=None, blank=True, null=True, related_name='routerpair2')
  145. def __unicode__(self):
  146. return u"%s <--> %s (crawl %d)" % (self.router1, self.router2, self.router1.AS.crawl.pk)
  147. @staticmethod
  148. def getPairing(peering, router1, router2):
  149. try:
  150. return BorderRouterPair.objects.get(peering=peering, router1=router1, router2=router2)
  151. except BorderRouterPair.DoesNotExist:
  152. return BorderRouterPair.objects.get(peering=peering, router1=router2, router2=router1)