renderers.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import json
  2. from rest_framework import renderers
  3. # IP address family designations
  4. AF = {
  5. 4: 'A',
  6. 6: 'AAAA',
  7. }
  8. class FormlessBrowsableAPIRenderer(renderers.BrowsableAPIRenderer):
  9. """
  10. An instance of the browseable API with forms suppressed. Useful for POST endpoints that don't create objects.
  11. """
  12. def show_form_for_method(self, *args, **kwargs):
  13. return False
  14. class BINDZoneRenderer(renderers.BaseRenderer):
  15. """
  16. Generate a BIND zone file from a list of DNS records.
  17. Required fields: `name`, `primary_ip`
  18. """
  19. media_type = 'text/plain'
  20. format = 'bind-zone'
  21. def render(self, data, media_type=None, renderer_context=None):
  22. records = []
  23. for record in data:
  24. if record.get('name') and record.get('primary_ip'):
  25. try:
  26. records.append("{} IN {} {}".format(
  27. record['name'],
  28. AF[record['primary_ip']['family']],
  29. record['primary_ip']['address'].split('/')[0],
  30. ))
  31. except KeyError:
  32. pass
  33. return '\n'.join(records)
  34. class FlatJSONRenderer(renderers.BaseRenderer):
  35. """
  36. Flattens a nested JSON response.
  37. """
  38. format = 'json_flat'
  39. media_type = 'application/json'
  40. def render(self, data, media_type=None, renderer_context=None):
  41. def flatten(entry):
  42. for key, val in entry.items():
  43. if isinstance(val, dict):
  44. for child_key, child_val in flatten(val):
  45. yield "{}_{}".format(key, child_key), child_val
  46. else:
  47. yield key, val
  48. return json.dumps([dict(flatten(i)) for i in data])
  49. class FreeRADIUSClientsRenderer(renderers.BaseRenderer):
  50. """
  51. Generate a FreeRADIUS clients.conf file from a list of Secrets.
  52. """
  53. media_type = 'text/plain'
  54. format = 'freeradius'
  55. CLIENT_TEMPLATE = """client {name} {{
  56. ipaddr = {ip}
  57. secret = {secret}
  58. }}"""
  59. def render(self, data, media_type=None, renderer_context=None):
  60. clients = []
  61. try:
  62. for secret in data:
  63. if secret['device']['primary_ip'] and secret['plaintext']:
  64. client = self.CLIENT_TEMPLATE.format(
  65. name=secret['device']['name'],
  66. ip=secret['device']['primary_ip']['address'].split('/')[0],
  67. secret=secret['plaintext']
  68. )
  69. clients.append(client)
  70. except:
  71. pass
  72. return '\n'.join(clients)