コード例 #1
0
ファイル: record.py プロジェクト: azzamsa/RESTKnot
def get_other_data(record):
    try:
        rdata = model.get_one(table="rdata",
                              field="record_id",
                              value=record["id"])
        zone = model.get_one(table="zone", field="id", value=record["zone_id"])
        ttl = model.get_one(table="ttl", field="id", value=record["ttl_id"])
        type_ = model.get_one(table="type",
                              field="id",
                              value=record["type_id"])

        if rdata:
            rdata = helpers.exclude_keys(rdata, {"id", "record_id"})
            rdata = rdata.get("rdata")

        zone = helpers.exclude_keys(
            zone, {"id", "is_committed", "user_id", "record_id"})

        data = {
            "id": record["id"],
            "owner": record["owner"],
            "rdata": rdata,
            "zone": zone["zone"],
            "type": type_["type"],
            "ttl": ttl["ttl"],
        }

        return data
    except Exception as e:
        current_app.logger.error(f"{e}")
コード例 #2
0
def get_type_by_recordid(record_id):
    """Get record type by record id."""
    try:
        record = model.get_one(table="record", field="id", value=record_id)
        type_id = record["type_id"]

        type_ = model.get_one(table="type", field="id", value=type_id)
        return type_["type"]
    except Exception:
        raise ValueError("Unrecognized Record Type")
コード例 #3
0
ファイル: zone.py プロジェクト: w796933/RESTKnot
def get_zone_id(zone):
    zone = model.get_one(table="zone", field="zone", value=f"{zone}")
    if not zone:
        raise ValueError(f"Zone Not Found")

    zone_id = zone["id"]
    return zone_id
コード例 #4
0
ファイル: ttl.py プロジェクト: azzamsa/RESTKnot
def get_ttlid_by_ttl(ttl):
    """Get type id by record record type."""
    ttl_ = model.get_one(table="ttl", field="ttl", value=ttl)
    if not ttl_:
        raise ValueError("TTL Not Found")

    ttl_id = ttl_["id"]
    return ttl_id
コード例 #5
0
def get_typeid_by_rtype(rtype):
    """Get type id by record record type."""
    type_ = model.get_one(table="type", field="type", value=rtype.upper())
    if not type_:
        raise ValueError("Type Not Found")

    type_id = type_["id"]
    return type_id
コード例 #6
0
ファイル: zone.py プロジェクト: azzamsa/RESTKnot
def get_zone(zone_id):
    """Get zone name by ID"""
    zone = model.get_one(table="zone", field="id", value=f"{zone_id}")
    if not zone:
        raise ValueError("Zone Not Found")

    zone = zone["zone"]
    return zone
コード例 #7
0
ファイル: command.py プロジェクト: w796933/RESTKnot
def get_other_data(record_id):
    """Return other record data from given record id."""
    try:
        record = model.get_one(table="record", field="id", value=record_id)

        zone_id = record["zone_id"]
        type_id = record["type_id"]
        ttl_id = record["ttl_id"]

        zone = model.get_one(table="zone", field="id", value=zone_id)
        type_ = model.get_one(table="type", field="id", value=type_id)
        ttl = model.get_one(table="ttl", field="id", value=ttl_id)
        rdata = model.get_one(table="rdata",
                              field="record_id",
                              value=record_id)
        return (record, zone, type_, ttl, rdata)
    except Exception as error:
        raise ValueError(f"{error}")
コード例 #8
0
    def get(self):
        user_id = request.args.get("id")
        email = request.args.get("email")
        try:
            if not any((user_id, email)):
                return response(422, "Problems parsing parameters")

            if user_id:
                user = model.get_one(table="user", field="id", value=user_id)
            if email:
                user = model.get_one(table="user", field="email", value=email)
            if not user:
                return response(404)

            return response(200, data=user)
        except Exception as e:
            current_app.logger.error(f"{e}")
            return response(500)
コード例 #9
0
ファイル: ttl.py プロジェクト: w796933/RESTKnot
    def get(self, ttl_id):
        try:
            ttl = model.get_one(table="ttl", field="id", value=ttl_id)
            if not ttl:
                return response(404)

            return response(200, data=ttl)
        except Exception as e:
            return response(500, message=f"{e}")
コード例 #10
0
    def get(self, type_id):
        try:
            type_ = model.get_one(table="type", field="id", value=type_id)
            if not type_:
                return response(404)

            return response(200, data=type_)
        except Exception:
            return response(500)
コード例 #11
0
    def get(self, record_id):
        try:
            record = model.get_one(table="record", field="id", value=record_id)
            if not record:
                return response(404)

            data = record_model.get_other_data(record)
            return response(200, data=data)
        except Exception as e:
            current_app.logger.error(f"{e}")
            return response(500)
コード例 #12
0
    def get(self):
        zone_id = request.args.get("id")
        zone_name = request.args.get("name")

        if not any((zone_id, zone_name)):
            return response(422, "Problems parsing parameters")

        try:
            if zone_id:
                zone = model.get_one(table="zone", field="id", value=zone_id)

            if zone_name:
                zone = model.get_one(table="zone",
                                     field="zone",
                                     value=zone_name)

            if not zone:
                return response(404)

            data = domain_model.get_other_data(zone)
            return response(200, data=data)
        except Exception as e:
            current_app.logger.error(f"{e}")
            return response(500)
コード例 #13
0
    def post(self):
        """Add new domain (zone) with additional default record.

        note:
        SOA, NS, and CNAME records are added automatically when adding new domain
        """
        parser = reqparse.RequestParser()
        parser.add_argument("zone", type=str, required=True)
        parser.add_argument("user_id", type=int, required=True)
        args = parser.parse_args()
        zone = args["zone"]
        user_id = args["user_id"]

        # Validation
        if not model.is_unique(table="zone", field="zone", value=f"{zone}"):
            return response(409, message="Duplicate Zone")

        user = model.get_one(table="user", field="id", value=user_id)
        if not user:
            return response(404, message=f"User Not Found")

        try:
            validator.validate("ZONE", zone)
        except Exception as e:
            return response(422, message=f"{e}")

        try:
            zone_id = insert_zone(zone, user_id)

            # create zone config
            command.set_config(zone, zone_id, "conf-set")

            # create default records
            soa_record_id = insert_soa_default(zone_id)
            ns_record_ids = insert_ns_default(zone_id)
            cname_record_id = insert_cname_default(zone_id, zone)
            record_ids = [soa_record_id, *ns_record_ids, cname_record_id]
            command.set_default_zone(record_ids)

            command.delegate(zone, zone_id, "conf-set", "master")
            command.delegate(zone, zone_id, "conf-set", "slave")

            data_ = {"id": zone_id, "zone": zone}
            return response(201, data=data_)
        except Exception as e:
            current_app.logger.error(f"{e}")
            return response(500)
コード例 #14
0
def get_serial_resource(zone):
    soa_record = record_model.get_soa_record(zone)
    rdata_record = model.get_one(
        table="rdata", field="record_id", value=soa_record["id"]
    )
    rdatas = rdata_record["rdata"].split(" ")
    serial = rdatas[2]
    # `serial_counter` is the last two digit of serial value (YYYYMMDDnn)
    serial_counter = serial[-2:]
    serial_date = serial[:-2]

    return {
        "soa_record": soa_record,
        "rdata_record": rdata_record,
        "serial": serial,
        "serial_counter": serial_counter,
        "serial_date": serial_date,
    }
コード例 #15
0
    def is_duplicate(self, zone_id, type_id, owner, rdata, ttl_id):
        """Check duplicate record exists."""
        base_query = 'SELECT * FROM "record" WHERE "zone_id"=%(zone_id)s AND'
        query = (
            base_query +
            '"type_id"=%(type_id)s AND "owner"=%(owner)s AND "ttl_id"=%(ttl_id)s'
        )
        value = {
            "zone_id": zone_id,
            "type_id": type_id,
            "owner": owner,
            "ttl_id": ttl_id,
        }

        records = model.plain_get("record", query, value)
        for record in records:
            rdata_record = model.get_one(table="rdata",
                                         field="record_id",
                                         value=record["id"])
            if rdata == rdata_record["rdata"]:
                raise ValueError("The record already exists")
コード例 #16
0
def get_other_data(zone):
    if zone is None:
        return

    user = model.get_one(table="user", field="id", value=zone["user_id"])
    user = helpers.exclude_keys(user, {"created_at"})
    records = record_model.get_records_by_zone(zone["zone"])

    records_detail = []
    for record in records:
        record_detail = record_model.get_other_data(record)
        record_detail = helpers.exclude_keys(record_detail, {"zone"})
        records_detail.append(record_detail)

    data = {
        "zone_id": zone["id"],
        "zone": zone["zone"],
        "user": user,
        "records": records_detail,
    }

    return data
コード例 #17
0
    def put(self, record_id):
        parser = reqparse.RequestParser()
        parser.add_argument("zone", type=str, required=True)
        parser.add_argument("owner", type=str, required=True)
        parser.add_argument("rtype", type=str, required=True)
        parser.add_argument("rdata", type=str, required=True)
        parser.add_argument("ttl", type=str, required=True)
        args = parser.parse_args()
        owner = args["owner"].lower()
        rtype = args["rtype"].lower()
        rdata = args["rdata"]
        zone = args["zone"]
        ttl = args["ttl"]

        try:
            ttl_id = ttl_model.get_ttlid_by_ttl(ttl)
            record_model.is_exists(record_id)

            type_id = type_model.get_typeid_by_rtype(rtype)
            zone_id = zone_model.get_zone_id(zone)
        except Exception as e:
            return response(404, message=f"{e}")

        try:
            rules.check_edit(rtype, zone_id, type_id, owner, rdata, ttl_id, record_id)
        except Exception as e:
            return response(409, message=f"{e}")

        try:
            validator.validate(rtype, rdata)
            validator.validate("owner", owner)
        except Exception as e:
            return response(422, message=f"{e}")

        try:
            serial_resource = get_serial_resource(zone)
            check_serial_limit(serial_resource)
        except Exception as e:
            return response(429, message=f"{e}")

        try:
            data = {
                "where": {"id": record_id},
                "data": {
                    "owner": owner,
                    "zone_id": zone_id,
                    "type_id": type_id,
                    "ttl_id": ttl_id,
                },
            }
            content_data = {
                "where": {"record_id": record_id},
                "data": {"rdata": rdata, "record_id": record_id},
            }

            command.set_zone(record_id, "zone-unset")

            model.update("rdata", data=content_data)
            model.update("record", data=data)

            command.set_zone(record_id, "zone-set")

            # increment serial after adding new record
            rtype = type_model.get_type_by_recordid(record_id)
            if rtype != "SOA":
                update_serial(serial_resource, "02")

            record = model.get_one(table="record", field="id", value=record_id)
            data_ = record_model.get_other_data(record)
            return response(200, data=data_)
        except Exception as e:
            current_app.logger.error(f"{e}")
            return response(500)
コード例 #18
0
def is_exists(type_id):
    type_ = model.get_one(table="type", field="id", value=type_id)
    if not type_:
        raise ValueError("Type Not Found")
コード例 #19
0
ファイル: record.py プロジェクト: azzamsa/RESTKnot
def is_exists(record_id):
    record = model.get_one(table="record", field="id", value=record_id)
    if not record:
        raise ValueError("Record Not Found")
コード例 #20
0
ファイル: ttl.py プロジェクト: azzamsa/RESTKnot
def is_exists(ttl_id):
    ttl_ = model.get_one(table="ttl", field="id", value=ttl_id)
    if not ttl_:
        raise ValueError("TTL Not Found")
コード例 #21
0
ファイル: zone.py プロジェクト: w796933/RESTKnot
def get_zone_by_record(record_id):
    record = model.get_one(table="record", field="id", value=f"{record_id}")
    zone_id = record["zone_id"]
    zone = model.get_one(table="zone", field="id", value=f"{zone_id}")
    return zone
コード例 #22
0
    def post(self):
        """Add new record.

        note:
        Adding any record with other record is allowed. IETF best practice
        is not handled automatically.  Knot didn't handle this too, and let the
        user know the standards themselves.
        See https://tools.ietf.org/html/rfc1912
        """
        parser = reqparse.RequestParser()
        parser.add_argument("zone", type=str, required=True)
        parser.add_argument("owner", type=str, required=True)
        parser.add_argument("rtype", type=str, required=True)
        parser.add_argument("rdata", type=str, required=True)
        parser.add_argument("ttl", type=str, required=True)
        args = parser.parse_args()
        owner = args["owner"].lower()
        rtype = args["rtype"].lower()
        rdata = args["rdata"]
        zone = args["zone"]
        ttl = args["ttl"]

        try:
            ttl_id = ttl_model.get_ttlid_by_ttl(ttl)

            type_id = type_model.get_typeid_by_rtype(rtype)
            zone_id = zone_model.get_zone_id(zone)
        except Exception as e:
            return response(404, message=f"{e}")

        try:
            rules.check_add(rtype, zone_id, type_id, owner, rdata, ttl_id)
        except Exception as e:
            return response(409, message=f"{e}")

        try:
            # rtype no need to be validated & no need to check its length
            # `get_typeid` will raise error for non existing rtype
            validator.validate(rtype, rdata)
            validator.validate("owner", owner)
        except Exception as e:
            return response(422, message=f"{e}")

        try:
            serial_resource = get_serial_resource(zone)
            check_serial_limit(serial_resource)
        except Exception as e:
            return response(429, message=f"{e}")

        try:
            data = {
                "owner": owner,
                "zone_id": zone_id,
                "type_id": type_id,
                "ttl_id": ttl_id,
            }
            record_id = model.insert(table="record", data=data)

            content_data = {"rdata": rdata, "record_id": record_id}
            model.insert(table="rdata", data=content_data)

            command.set_zone(record_id, "zone-set")

            # increment serial after adding new record
            rtype = type_model.get_type_by_recordid(record_id)
            if rtype != "SOA":
                update_serial(serial_resource)

            record = model.get_one(table="record", field="id", value=record_id)
            data = record_model.get_other_data(record)
            return response(201, data=data)
        except Exception as e:
            current_app.logger.error(f"{e}")
            return response(500)