client.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import json
  2. import logging
  3. from urllib2 import urlopen, URLError
  4. class BatcaveClient(object):
  5. def __init__(self, url):
  6. assert url.startswith("http://") or url.startswith("https://"), \
  7. "BATCAVE URL must use http(s) protocol"
  8. assert url.endswith("/"), "BATCAVE URL must end with slash."
  9. self.base_url = url
  10. self.logger = logging.getLogger("BATCAVE")
  11. def __load_response(self, url, error_context):
  12. raw_data = None
  13. try:
  14. raw_data = urlopen(self.base_url + url)
  15. except URLError as err:
  16. self.logger.error("Failed to contact BATCAVE for %s: %s",
  17. error_context, err)
  18. return None
  19. try:
  20. return json.load(raw_data)
  21. except ValueError as err:
  22. self.logger.error("Could not parse response for %s: %s",
  23. error_context, err)
  24. return None
  25. def get_nodes(self):
  26. url = 'nodes.json'
  27. response = self.__load_response(url, 'nodes')
  28. return response.get('nodes') if response is not None else None
  29. def get_node(self, nodeid):
  30. """Query the given node's data from the BATCAVE."""
  31. url = 'node/{0}.json'.format(nodeid)
  32. return self.__load_response(url, 'node \'' + nodeid + '\'')
  33. def find_node_by_name(self, name, fuzzymatch=True, single_match_only=True):
  34. """Tries to find a node by given name."""
  35. url = 'find?name=' + name + '&fuzzy=' + ('1' if fuzzymatch else '0')
  36. matches = self.__load_response(url, 'find_name=' + name)
  37. if matches is None:
  38. return None
  39. if single_match_only:
  40. if len(matches) == 1:
  41. return matches[0]
  42. else:
  43. return None
  44. return matches
  45. def find_node_by_mac(self, mac, single_match_only=True):
  46. """Tries to find a node by given MAC address."""
  47. url = 'find?mac=' + mac
  48. matches = self.__load_response(url, 'find_mac=' + mac)
  49. if matches is None:
  50. return None
  51. if single_match_only:
  52. if len(matches) == 1:
  53. return matches[0]
  54. else:
  55. return None
  56. return matches
  57. def get_nodefield(self, nodeid, field):
  58. """Query the given field for the given nodeid from the BATCAVE."""
  59. url = 'node/{0}/{1}'.format(nodeid, field)
  60. ctx = "node '{0}'->'{1}'".format(nodeid, field)
  61. return self.__load_response(url, ctx)
  62. def get_providers(self):
  63. url = 'providers?format=json'
  64. return self.__load_response(url, 'providers')
  65. def get_status(self):
  66. url = 'status.json'
  67. return self.__load_response(url, 'status')
  68. def identify(self, ident):
  69. url = 'identify?ident=' + str(ident)
  70. return self.__load_response(url, 'identify \'' + ident + '\'')