from django.db import models from django.db.models import Q # Create your models here. class ConfigHost(models.Model): CHECK_CHOICES = ( ('CMK', "Check MK"), ('PLAIN', "Plain"), ) # asno, ip, check method, name = models.CharField(max_length=50) number = models.IntegerField() ip = models.GenericIPAddressField() checkMethod = models.CharField(max_length=4, choices=CHECK_CHOICES) def __unicode__(self): return u"%s (%s / %s)" % (self.name, self.number, self.ip) class CrawlRun(models.Model): # time start, time end, startTime = models.DateTimeField() endTime = models.DateTimeField(null=True, blank=True) def __unicode__(self): return u"Run %d - %s to %s" % (self.pk, self.startTime, self.endTime if self.endTime else "?") class CrawlLog(models.Model): INFO = 'INFO' ERROR = 'ERROR' DEBUG = 'DEBUG' WARN = 'WARN' SEVERITY = ( (INFO, 'info'), (ERROR, 'error'), (DEBUG, 'debug'), (WARN, 'warning'), ) crawl = models.ForeignKey(CrawlRun) host = models.ForeignKey(ConfigHost, null=True, blank=True, on_delete=models.SET_NULL) logtime = models.DateTimeField(auto_now_add=True) severity = models.CharField(max_length=10, choices=SEVERITY) message = models.TextField() @staticmethod def log(crawl, msg, severity=None, host=None): if not severity: severity = CrawlLog.ERROR log = CrawlLog() log.crawl = crawl log.message = msg log.severity = severity log.host = host log.save() def __unicode__(self): host = "host %s - " % self.host.name if self.host else "" return u"Log %s %s: %s%s" % (self.get_severity_display(), self.logtime, host, self.message) class AS(models.Model): # asno crawl = models.ForeignKey(CrawlRun) number = models.IntegerField() directlyCrawled = models.BooleanField(default=False) online = models.BooleanField(default=True) lastSeen = models.ForeignKey(CrawlRun, blank=True, null=True, default=None, related_name='as_lastseen') def __unicode__(self): return u"AS %s (crawl %d)" % (self.number, self.crawl.pk) def getPeerings(self): return Peering.objects.filter(Q(as1=self)|Q(as2=self)) class BorderRouter(models.Model): # as id, ip, check method, pingable, reachable # unique: (crawl_id, asno, as id) AS = models.ForeignKey(AS) routerID = models.GenericIPAddressField() pingable = models.BooleanField(default=False) reachable = models.BooleanField(default=False) def __unicode__(self): p = "p" if self.pingable else "!p" r = "r" if self.reachable else "!r" return u"Router %s (AS %s, %s%s)" % (self.routerID, self.AS.number, p, r) class Announcement(models.Model): router = models.ForeignKey(BorderRouter) ip = models.GenericIPAddressField() prefix = models.IntegerField() # NOTE: increase length for longer pathes (currently supports a length of ~85) ASPath = models.CharField(max_length=512) nextHop = models.GenericIPAddressField() originAS = models.ForeignKey(AS) def __unicode__(self): return u"%s/%s via %s (crawl %s)" % (self.ip, self.prefix, self.ASPath, self.router.AS.crawl.pk) class Peering(models.Model): DIRECT = 'direct' PATH = 'path' ORIGIN = ( (PATH, 'BGP Path'), (DIRECT, 'Direct Connection'), ) as1 = models.ForeignKey(AS, related_name='peering1') as2 = models.ForeignKey(AS, related_name='peering2') origin = models.CharField(max_length=10, choices=ORIGIN) def __unicode__(self): return u"AS %s <--> AS %s (%s, crawl %s)" % (self.as1.number, self.as2.number, self.get_origin_display(), self.as1.crawl.pk) def containsAS(self, AS): return AS in (self.as1, self.as2) @staticmethod def getPeering(as1, as2): """ Find matching peering """ try: return Peering.objects.get(as1=as1, as2=as2) except Peering.DoesNotExist: return Peering.objects.get(as1=as2, as2=as1) class BorderRouterPair(models.Model): peering = models.ForeignKey(Peering) router1 = models.ForeignKey(BorderRouter, default=None, blank=True, null=True, related_name='routerpair1') router2 = models.ForeignKey(BorderRouter, default=None, blank=True, null=True, related_name='routerpair2') def __unicode__(self): return u"%s <--> %s (crawl %d)" % (self.router1, self.router2, self.router1.AS.crawl.pk) @staticmethod def getPairing(peering, router1, router2): try: return BorderRouterPair.objects.get(peering=peering, router1=router1, router2=router2) except BorderRouterPair.DoesNotExist: return BorderRouterPair.objects.get(peering=peering, router1=router2, router2=router1)