__init__.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. from copy import deepcopy
  2. import json
  3. import logging
  4. import urllib2
  5. from .alfred import AlfredParser
  6. from .batman import BatmanParser
  7. from .dashing import DashingClient
  8. from .graphite import GraphitePush
  9. from .server import ApiServer
  10. from .storage import Storage
  11. __all__ = [
  12. 'AlfredParser', 'BatmanParser',
  13. 'DashingClient', 'GraphitePush',
  14. 'Storage', 'ApiServer',
  15. 'dict_merge', 'merge_alfred_batman',
  16. 'resolve_ipblock', 'mac2id',
  17. ]
  18. logger = logging.getLogger('ffstatus')
  19. def mac2id(mac):
  20. return mac.lower().replace(':', '')
  21. def dict_merge(a, b):
  22. '''recursively merges dict's. not just simple a['key'] = b['key'], if
  23. both a and bhave a key who's value is a dict then dict_merge is called
  24. on both values and the result stored in the returned dictionary.'''
  25. if not isinstance(b, dict):
  26. return b
  27. result = deepcopy(a)
  28. for k, v in b.iteritems():
  29. if k in result and isinstance(result[k], dict):
  30. result[k] = dict_merge(result[k], v)
  31. elif k in result and isinstance(result[k], list):
  32. result[k] = result[k] + [ deepcopy(x) for x in v if x not in result[k] ]
  33. else:
  34. result[k] = deepcopy(v)
  35. return result
  36. def merge_alfred_batman(alfreddata, batmandata):
  37. merged = {}
  38. batlookup = {}
  39. for nodeid in batmandata:
  40. batlookup[nodeid] = nodeid
  41. for bda in batmandata[nodeid]['aliases']:
  42. batlookup[bda] = nodeid
  43. for nodeid in alfreddata:
  44. nodeinfo = alfreddata[nodeid]
  45. candidates = set()
  46. candidates.add(nodeid)
  47. if 'mac' in nodeinfo: candidates.add(mac2id(nodeinfo['mac']))
  48. if 'macs' in nodeinfo:
  49. for mac in nodeinfo['macs']:
  50. candidates.add(mac2id(mac))
  51. if 'network' in nodeinfo:
  52. n = nodeinfo['network']
  53. if 'mac' in n: candidates.add(mac2id(n['mac']))
  54. if 'mesh_interfaces' in n:
  55. for mac in n['mesh_interfaces']:
  56. candidates.add(mac2id(mac))
  57. if not 'neighbours' in nodeinfo: nodeinfo['neighbours'] = []
  58. for candidate_raw in candidates:
  59. candidate = batlookup[candidate_raw] if candidate_raw in batlookup else candidate_raw
  60. if candidate in batmandata:
  61. nodeinfo = dict_merge(nodeinfo, batmandata[candidate])
  62. merged[nodeid] = nodeinfo
  63. return merged
  64. def resolve_ipblock(ipaddr):
  65. url = 'http://rest.db.ripe.net/search.json?query-string=' + str(ipaddr)
  66. try:
  67. response = json.load(urllib2.urlopen(url))
  68. assert isinstance(response, dict)
  69. obj = [x for x in response['objects']['object'] if x['type'] in ['inetnum','inet6num']][0]
  70. attrib = obj['attributes']['attribute']
  71. netname = '\n'.join([x['value'] for x in attrib if x['name'] == 'netname'])
  72. netblock = '\n'.join([x['value'] for x in attrib if x['name'] in ['inetnum','inet6num']])
  73. desc = '\n'.join([x['value'] for x in attrib if x['name'] == 'descr'])
  74. return {
  75. 'name': netname,
  76. 'block': netblock,
  77. 'description': desc,
  78. }
  79. except urllib2.URLError as err:
  80. logger.error('Error querying ip \'{0}\' from RIPE API: {1}'.format(ipaddr, err))
  81. return None