fastpinger.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. from django.db.models import Q, F
  2. from django.utils import timezone
  3. from services.models import IPResource, IPResourceState, ServiceAllocation
  4. import re
  5. from ipaddress import IPv4Address, AddressValueError
  6. import logging
  7. from itertools import groupby
  8. logger = logging.getLogger(__name__)
  9. def fastpinger_update(f):
  10. now = timezone.now()
  11. regex = re.compile('^(?P<ip>[0-9.]+)[ ]+: (?P<p1>([0-9]+.[0-9]+|-)) (?P<p2>([0-9]+.[0-9]+|-))'
  12. ' (?P<p3>([0-9]+.[0-9]+|-)) (?P<p4>([0-9]+.[0-9]+|-)) (?P<p5>([0-9]+.[0-9]+|-))$')
  13. up, down, unknown = set(), set(), set()
  14. for line in f:
  15. try:
  16. line = line.decode('utf-8')
  17. except UnicodeDecodeError:
  18. continue
  19. g = regex.match(line)
  20. if not g:
  21. continue
  22. try:
  23. ip = IPv4Address(g.group('ip'))
  24. except AddressValueError:
  25. continue
  26. p = [ g.group('p%d' % i) for i in [1, 2, 3, 4, 5] ]
  27. if all(map(lambda p: p == '-', p)):
  28. down.add(ip.compressed)
  29. else:
  30. up.add(ip.compressed)
  31. up = up - down # suppression des doublons
  32. leaves = {
  33. IPResourceState.STATE_DOWN: 0,
  34. IPResourceState.STATE_UP: 0,
  35. IPResourceState.STATE_UNKNOWN: 0,
  36. }
  37. become_down = IPResource.objects.exclude(last_state__state=IPResourceState.STATE_DOWN).filter(ip__in=down)
  38. for ip in become_down:
  39. leaves[ip.last_state.state] += 1
  40. if ip.last_state.state == IPResourceState.STATE_UP:
  41. ip.last_time_up = now
  42. ip.last_state = IPResourceState.objects.create(ip=ip, date=now, state=IPResourceState.STATE_DOWN)
  43. ip.save()
  44. become_up = IPResource.objects.exclude(last_state__state=IPResourceState.STATE_UP).filter(ip__in=up)
  45. for ip in become_up:
  46. leaves[ip.last_state.state] += 1
  47. ip.last_state = IPResourceState.objects.create(ip=ip, date=now, state=IPResourceState.STATE_UP)
  48. ip.save()
  49. become_unknown = IPResource.objects.exclude(last_state__state=IPResourceState.STATE_UNKNOWN).exclude(Q(pk__in=up) | Q(pk__in=down))
  50. for ip in become_unknown:
  51. leaves[ip.last_state.state] += 1
  52. if ip.last_state.state == IPResourceState.STATE_UP:
  53. ip.last_time_up = now
  54. ip.last_state = IPResourceState.objects.create(ip=ip, date=now, state=IPResourceState.STATE_UNKNOWN)
  55. ip.save()
  56. down_count = IPResource.objects.filter(last_state__state=IPResourceState.STATE_DOWN).count()
  57. up_count = IPResource.objects.filter(last_state__state=IPResourceState.STATE_UP).count()
  58. unknown_count = IPResource.objects.filter(last_state__state=IPResourceState.STATE_UNKNOWN).count()
  59. stats = "UP: %d (-%d+%d), DOWN: %d (-%d+%d), UNKNOWN: %d (-%d+%d)" \
  60. % (up_count, leaves[IPResourceState.STATE_UP], len(become_up), \
  61. down_count, leaves[IPResourceState.STATE_DOWN], len(become_down), \
  62. unknown_count, leaves[IPResourceState.STATE_UNKNOWN], len(become_unknown))
  63. return stats