import json from rest_framework import renderers # IP address family designations AF = { 4: 'A', 6: 'AAAA', } class FormlessBrowsableAPIRenderer(renderers.BrowsableAPIRenderer): """ An instance of the browseable API with forms suppressed. Useful for POST endpoints that don't create objects. """ def show_form_for_method(self, *args, **kwargs): return False class BINDZoneRenderer(renderers.BaseRenderer): """ Generate a BIND zone file from a list of DNS records. Required fields: `name`, `primary_ip` """ media_type = 'text/plain' format = 'bind-zone' def render(self, data, media_type=None, renderer_context=None): records = [] for record in data: if record.get('name') and record.get('primary_ip'): try: records.append("{} IN {} {}".format( record['name'], AF[record['primary_ip']['family']], record['primary_ip']['address'].split('/')[0], )) except KeyError: pass return '\n'.join(records) class FlatJSONRenderer(renderers.BaseRenderer): """ Flattens a nested JSON response. """ format = 'json_flat' media_type = 'application/json' def render(self, data, media_type=None, renderer_context=None): def flatten(entry): for key, val in entry.iteritems(): if isinstance(val, dict): for child_key, child_val in flatten(val): yield "{}_{}".format(key, child_key), child_val else: yield key, val return json.dumps([dict(flatten(i)) for i in data]) class FreeRADIUSClientsRenderer(renderers.BaseRenderer): """ Generate a FreeRADIUS clients.conf file from a list of Secrets. """ media_type = 'text/plain' format = 'freeradius' CLIENT_TEMPLATE = """client {name} {{ ipaddr = {ip} secret = {secret} }}""" def render(self, data, media_type=None, renderer_context=None): clients = [] try: for secret in data: if secret['device']['primary_ip'] and secret['plaintext']: client = self.CLIENT_TEMPLATE.format( name=secret['device']['name'], ip=secret['device']['primary_ip']['address'].split('/')[0], secret=secret['plaintext'] ) clients.append(client) except: pass return '\n'.join(clients)