Ejemplo n.º 1
0
    def get(self, request, zone_origin):
        """GET Method handler, used to retrieve all information about a zone.

        This endpoint recieve no JSON data, if there's any, it will be ignored.

        This endpoint will return the following JSON file:
        {
            "origin" : "zone_origin",
            "directives" : {
                "directive1": "value1",
                ...
            }
            "records" : [
                {
                    "name" : "record_name",
                    "rclass" : "record_rclass",
                    "ttl" : "record_ttl",
                    "rtype" : "record_rtype",
                    "rdata" : {
                        "rdata_name1" : "data",
                        ...
                    },
                },
                ...
            ]
        }
        """
        # handle the get request
        try:
            logger.debug('FILE_LOCATION: ' + str(FILE_LOCATION))
            logger.debug('ZONE_DICT: ' + str(ZONE_DICT))
            logger.debug("ZONE_DIR: " + str(ZONE_DIR))
            if not (zone_origin in FILE_LOCATION):
                raise ZoneError('Invalid Zone: ' + zone_origin)

            zone = DNSZone()
            zone.read_from_file(FILE_LOCATION[zone_origin])
            return HttpResponse(zone.toJSON())
        except ValueError as v_err:
            logger.warning(v_err.args)
            logger.warning(traceback.format_exc(2) + "\n\n\n")
            return HttpResponse('{"status" : "Invalid JSON arguments"}', status=500)
        except ZoneError as z_err:
            logger.error(z_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            return HttpResponse('{"status" : "'+str(z_err.args[0])+'"}', status=500)
        except BindError as b_err:
            logger.error(b_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            backup_restore_file('restore', 'zone', zone_origin, '.bak')
            backup_restore_file('restore', 'named', find_server(zone_origin), '.bak')
            return HttpResponse('{"status" : "'+str(b_err.args[0])+'"}', status=500)
        except Exception as b_err:
            logger.error(b_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            return HttpResponse('{"status" : "'+str(b_err)+'"}', status=500)
Ejemplo n.º 2
0
def reverse_record_delete(name, address, origin_zone):
    """Delete the associated reverse zone according to the address given."""
    reverse_zone_origin = find_reverse_zone(address)

    if not (reverse_zone_origin in FILE_LOCATION):
        raise ZoneError("Invalid Reverse Zone: " + reverse_zone_origin)

    reverse_zone = DNSZone()
    reverse_zone.read_from_file(FILE_LOCATION[reverse_zone_origin])
    record = reverse_zone.find_record(address.split('.')[3],
                                      rdata={'address': name + '.' +
                                             origin_zone + '.'})
    reverse_zone.delete_record(address.split('.')[3],
                               rdata={'address': name + '.' + origin_zone + '.'})
    backup_restore_file('backup','zone',reverse_zone_origin,'.bak')
    reverse_zone.write_to_file(FILE_LOCATION[reverse_zone_origin])
    logger.info("Deleted reverse record: " + str(record) +
                "\nOn zone: " + origin_zone)
    restart_bind(find_server(reverse_zone_origin))
Ejemplo n.º 3
0
def reverse_record_add(name, origin_zone, address, ttl=""):
    """Add the associated reverse zone according to the address given."""
    reverse_zone_origin = find_reverse_zone(address)

    if not (reverse_zone_origin in FILE_LOCATION):
        raise ZoneError("Invalid Reverse Zone: " + reverse_zone_origin)

    reverse_zone = DNSZone()
    reverse_zone.read_from_file(FILE_LOCATION[reverse_zone_origin])
    reverse_record = DNSResourceRecord()
    reverse_record.name = address.split('.')[3]
    reverse_record.ttl = ttl
    reverse_record.rclass = "IN"
    reverse_record.rtype = "PTR"
    reverse_record.rdata.address = name + '.' + origin_zone + '.'
    reverse_zone.add_record(reverse_record)
    backup_restore_file('backup','zone',reverse_zone_origin,'.bak')
    reverse_zone.write_to_file(FILE_LOCATION[reverse_zone_origin])
    logger.info("Created reverse record: " + str(reverse_record) +
                "\nOn zone: " + origin_zone)
    restart_bind(find_server(reverse_zone_origin))
Ejemplo n.º 4
0
    def get(self, request, zone_origin, record_name):
        """GET Method handler, used to retrieve all information about a record.

        This endpoint recieve the following JSON data as an optional search
        arguments
        {
            "rclass" : "record_rclass",
            "rtype" : "record_rtype",
            "rdata" : {
                "rdata_name1" : "data",
                ...
            },
        }
        This endpoint will return the following JSON file:
        {
            "name" : "record_name",
            "rclass" : "record_rclass",
            "ttl" : "record_ttl",
            "rtype" : "record_rtype",
            "rdata" : {
                "rdata_name1" : "data",
                ...
            },
        }

        And return {"status" : "notfound"} if the record file is not exist
        """
        try:
            if request.body.decode('utf-8'):
                payload = json.loads(request.body.decode('utf-8'))
                rclass = payload.get("rclass")
                rtype = payload.get("rtype")
                rdata = payload.get("rdata")
            else:
                rclass = rtype = rdata = None

            if not (zone_origin in FILE_LOCATION):
                raise ZoneError('Invalid Zone: ' + zone_origin)

            zone = DNSZone()
            zone.read_from_file(FILE_LOCATION[zone_origin])
            record = zone.find_record(record_name, rclass, rtype, rdata)

            logger.info("Get record: " + str(record) +
                        "\nOn zone: " + zone_origin)
            return HttpResponse(record.toJSON() if record
                                else '{"status" : "notfound"}')
        except ValueError as v_err:
            logger.warning(v_err.args)
            logger.warning(traceback.format_exc(2) + "\n\n\n")
            return HttpResponse('{"status" : "Invalid JSON arguments"}', status=500)
        except ZoneError as z_err:
            logger.error(z_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            return HttpResponse('{"status" : "'+str(z_err.args[0])+'"}', status=500)
        except BindError as b_err:
            logger.error(b_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            if b_err['file_type']:
                backup_restore_file('restore', b_err['file_type'], b_err['origin'], '.bak')
            return HttpResponse('{"status" : "'+str(b_err.args['msg'])+'"}', status=500)
        except Exception as b_err:
            logger.error(b_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            return HttpResponse('{"status" : "'+str(b_err)+'"}', status=500)
Ejemplo n.º 5
0
    def post(self, request, zone_origin, record_name=""):
        """POST Method handler, used to create a new resource record.

        This endpoint recieve the following JSON file:
        {
            "name" : "new_record_name",
            "rclass" : "new_record_rclass",
            "ttl" : "new_record_ttl",
            "rtype" : "new_record_rtype",
            "rdata" : {
                "rdata_name1" : "data",
                ...
            },
        }
        Note that rclass and TTL are optional.

        This endpoint will return { "status" : "ok" } if adding a new record is
        successfull and {"status" : "fail"} otherwise
        """
        try:
            payload = json.loads(request.body.decode('utf-8'))

            if not (zone_origin in FILE_LOCATION):
                raise ZoneError('Invalid Zone: ' + zone_origin)

            zone = DNSZone()
            zone.read_from_file(FILE_LOCATION[zone_origin])
            if (payload['rtype'] == "MX"):
                record_data = MXRecordData()
            elif (payload['rtype'] == "SOA"):
                record_data = SOARecordData()
            else:
                record_data = RecordData()
            new_record = DNSResourceRecord(rdata=record_data)
            new_record.fromJSON(payload)
            zone.add_record(new_record)
            backup_restore_file('backup','zone',zone_origin,'.bak')
            if new_record.rtype == "A" or new_record.rtype == "MX":
                reverse_record_add(new_record.name, zone_origin,
                                   new_record.rdata.address, new_record.ttl)

            zone.write_to_file(FILE_LOCATION[zone_origin])
            logger.info("Created record: " + str(new_record) +
                        "\nOn zone: " + zone_origin)
            # add reverse if rtype is A:

            restart_bind(find_server(zone_origin))
            return HttpResponse('{"status" : "ok"}')
        except ValueError as v_err:
            logger.warning(v_err.args)
            logger.warning(traceback.format_exc(2) + "\n\n\n")
            return HttpResponse('{"status" : "Invalid JSON arguments"}', status=500)
        except ZoneError as z_err:
            logger.error(z_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            return HttpResponse('{"status" : "'+str(z_err.args[0])+'"}', status=500)
        except BindError as b_err:
            logger.error(b_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            if b_err.args[0]['file_type']:
                backup_restore_file('restore', b_err.args[0]['file_type'], b_err.args[0]['origin'], '.bak')
            return HttpResponse('{"status" : "'+str(b_err.args[0]['msg'])+'"}', status=500)
        except Exception as b_err:
            logger.error(b_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            return HttpResponse('{"status" : "'+str(b_err)+'"}', status=500)
Ejemplo n.º 6
0
    def put(self, request, zone_origin, record_name):
        """GET Method handler, used to update a record.

        This endpoint recieve the following JSON file:
        {
            "rclass" : "record_rclass",
            "ttl" : "record_ttl",
            "rtype" : "record_rtype",
            "rdata" : {
                "rdata_name1" : "data",
                ...
            },
        }
        Note that all field is optional. You only need to use it if you want to
        update the value.

        This endpoint will return { "status" : "ok" } if updating a record is
        successfull and {"status" : "fail"} otherwise
        """
        try:
            payload = json.loads(request.body.decode('utf-8'))
            rtype = payload.get("rtype")
            rclass = None
            rdata = None
            
            if not (zone_origin in FILE_LOCATION):
                raise ZoneError('Invalid Zone: ' + zone_origin)

            zone = DNSZone()
            zone.read_from_file(FILE_LOCATION[zone_origin])
            record = zone.find_record(record_name, rclass, rtype, rdata)

            # delete old reverse record
            if (record.rtype == "A" or record.rtype == "MX"):
                reverse_record_delete(record.name, record.rdata.address,
                                      zone_origin)

            record.fromJSON(payload)
            backup_restore_file('backup','zone',zone_origin,'.bak')
            # create new reverse record
            if (record.rtype == "A" or record.rtype == "MX"):
                reverse_record_add(record.name, zone_origin,
                                   record.rdata.address, record.ttl)
            zone.write_to_file(FILE_LOCATION[zone_origin])
            logger.info("Updated record: " + str(record) +
                        "\nOn zone: " + zone_origin)

            restart_bind(find_server(zone_origin))
            return HttpResponse('{"status" : "ok"}')
        except ValueError as v_err:
            logger.warning(v_err.args)
            logger.warning(traceback.format_exc(2) + "\n\n\n")
            return HttpResponse('{"status" : "Invalid JSON arguments"}', status=500)
        except ZoneError as z_err:
            logger.error(z_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            return HttpResponse('{"status" : "'+str(z_err.args[0])+'"}', status=500)
        except BindError as b_err:
            logger.error(b_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            if b_err['file_type']:
                backup_restore_file('restore', b_err['file_type'], b_err['origin'], '.bak')
            return HttpResponse('{"status" : "'+str(b_err.args['msg'])+'"}', status=500)
        except Exception as b_err:
            logger.error(b_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            return HttpResponse('{"status" : "'+str(b_err)+'"}', status=500)
Ejemplo n.º 7
0
    def delete(self, request, zone_origin, record_name):
        """DELETW Method handler, used to delete a record.

        This endpoint recieve no JSON data. If there's any, it will be ignored.
        {
            "rclass" : "record_rclass",
            "rtype" : "record_rtype",
            "rdata" : {
                "rdata_name1" : "data",
                ...
            },
        }
        This endpoint will return { "status" : "ok" } if deleting a record is
        successfull and {"status" : "failed"} otherwise

        @TODO: Handle kalo ga nemu
        """
        # handle the post request
        try:
            if request.body.decode('utf-8'):
                payload = json.loads(request.body.decode('utf-8'))
                rclass = payload.get("rclass")
                rtype = payload.get("rtype")
                rdata = payload.get("rdata")
            else:
                rclass = rtype = rdata = None

            if not (zone_origin in FILE_LOCATION):
                raise ZoneError('Invalid Zone: ' + zone_origin)

            zone = DNSZone()
            zone.read_from_file(FILE_LOCATION[zone_origin])
            deleted_record = zone.find_record(record_name, rclass, rtype, rdata)
            zone.delete_record(record_name, rclass, rtype, rdata)
            backup_restore_file('backup','zone',zone_origin,'.bak')

            if deleted_record.rtype == "A" or deleted_record.rtype == "MX":
                reverse_record_delete(deleted_record.name,
                                      deleted_record.rdata.address, zone_origin)

            zone.write_to_file(FILE_LOCATION[zone_origin])

            logger.info("Deleted record: " + str(deleted_record) +
                        "\nOn zone: " + zone_origin)

            restart_bind(find_server(zone_origin))
            return HttpResponse('{"status" : "ok"}')
        except ValueError as v_err:
            logger.warning(v_err.args)
            logger.warning(traceback.format_exc(2) + "\n\n\n")
            return HttpResponse('{"status" : "Invalid JSON arguments"}', status=500)
        except ZoneError as z_err:
            logger.error(z_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            return HttpResponse('{"status" : "'+str(z_err.args[0])+'"}', status=500)
        except BindError as b_err:
            logger.error(b_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            if b_err['file_type']:
                backup_restore_file('restore', b_err['file_type'], b_err['origin'], '.bak')
            return HttpResponse('{"status" : "'+str(b_err.args['msg'])+'"}', status=500)
        except Exception as b_err:
            logger.error(b_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            return HttpResponse('{"status" : "'+str(b_err)+'"}', status=500)
Ejemplo n.º 8
0
    def post(self, request, dns_server):
        """POST Method handler, used to create a new zone record.

        This endpoint recieve the following JSON file:
        {
            "directives": {
                "directive1": "value1",
                ...
            }
            "soa_record": {
                "authoritative_server": "",
                "admin_email": "",
                "serial_no": "",
                "slv_refresh_period": "",
                "slv_retry": "",
                "slv_expire": "",
                "max_time_cache": ""
            }
            "zone": {
                "zone ZONENAME": {
                    "file": "ZONE_FILE_PATH",
                    "type": "TYPE"
                    ...
                }
            }
        }
        Note that rclass and TTL are optional.

        This endpoint will return { "status" : "ok" } if adding a new record is
        successfull and {"status" : "fail"} otherwise
        """
        try:
            # Load input parameters
            body = json.loads(request.body.decode('utf-8'))
            body_zone = body['zone']
            zone = str(body_zone.keys()[0])
            if "master" in body_zone[zone]['type']:
                body_directives = body['directives']
                body_soa = body['soa_record']


            # add_absolute_path(body_zone)
            named_file = str(LOCAL_MNT_DIR[dns_server]) + DEFAULT_CONF_FILENAME
            logger.debug("Write named file to directory " + named_file)
            # Add zone to named config file
            named_dict, named_keys = iscpy.ParseISCString(open(named_file).read())
            new_dict = iscpy.AddZone(body_zone, named_dict)
            iscpy.WriteToFile(new_dict, named_keys, named_file)

            # Make new zone file
            if "master" in body_zone[zone]['type']:
                soa = SOARecordData()
                soa.fromJSON(body_soa)
                soa_record = DNSResourceRecord("@", "", "", "SOA", soa)
                resourcerecord = []
                resourcerecord.append(soa_record)
                ns_record = DNSResourceRecord("@", "", "", "NS",
                                              RecordData(body_soa['authoritative_server']))
                resourcerecord.append(ns_record)
                new_zone = DNSZone(body_directives, resourcerecord)
                zone_file = body_zone[zone]['file'].split('"')[1]
                zone_file = ZONE_DIR[dns_server] + zone_file
                local_zone_file = zone_file.replace(REMOTE_MNT_DIR, LOCAL_MNT_DIR[dns_server], 1)
                logger.debug("Write zone file to directory " + local_zone_file)
                logger.debug("Zone to write: " + new_zone.toJSON())
                new_zone.write_to_file(local_zone_file)

            restart_bind(dns_server)

            init_data()
            return HttpResponse('{ "status" : "ok" }')
        except ValueError as v_err:
            logger.warning(v_err.args)
            logger.warning(traceback.format_exc(2) + "\n\n\n")
            return HttpResponse('{"status" : "Invalid JSON arguments"}', status=500)
        except ZoneError as z_err:
            logger.error(z_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            return HttpResponse('{"status" : "'+str(z_err.args[0])+'"}', status=500)
        except BindError as b_err:
            logger.error(b_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            if b_err.args[0]['file_type']:
                backup_restore_file('restore', b_err.args[0]['file_type'], b_err.args[0]['origin'], '.bak')
            return HttpResponse('{"status" : "'+str(b_err.args[0]['msg'])+'"}', status=500)
        except Exception as b_err:
            logger.error(b_err.args)
            logger.error(traceback.format_exc() + "\n\n\n")
            return HttpResponse('{"status" : "'+str(b_err)+'"}', status=500)