auroraresearchlab/netbox-dns

Error creating a new zone: "expecting an integer" instead of SOA

fabricat opened this issue ยท 6 comments

I am facing an error while calling netbox-dns API (leveraging the Ansible uri module) in order to create a new zone.

Actually, Ansible sends a POST request to /api/plugins/netbox-dns/zones/ with the following body:

{
	"default_ttl": 3600,
	"name": "REDACTED.net",
	"soa_expire": 86400,
	"soa_minimum": 3600,
	"soa_mname": 3,
	"soa_refresh": 900,
	"soa_retry": 600,
	"soa_rname": "hostmaster@REDACTED.local",
	"soa_serial_auto": false,
	"soa_ttl": 3600,
	"tags": [{"slug": "auto-sync"},{"slug": "private"}],
	"view": "1"
}

I get a 500 Internal error response code, with the following body:

{
    "error": "{'value': ['Record value (REDACTED.local. hostmaster@REDACTED.local. None 900 600 86400 3600) is malformed: expecting an integer.']}",
    "exception": "ValidationError",
    "netbox_version": "3.2.4",
    "python_version": "3.9.5"
}

Similar API calls previously worked ok on former versions of Netbox and netbox-dns (I don't remember exactly which versions, but it was more than 90 days ago): the only difference is now I am using the "view", but I also tested without that parameter, and I get the same error.

Hi @fabricat, thanks for reporting this.

Unfortunately I'm currently on a business trip with limited access to my test environment so I won't be able to look into this more deeply until tomorrow, but it would help if you could try one thing which might resolve part of the issue.

There are two problems: One is that dnspython dislikes the SOA record generated for the zone you are trying to create, the other is that the issue causing it is not caught earier. You do not provide a SERIAL in your request, but soa_serial_auto is specified as false. This results in no serial number being created automatically, but the SOA record needs one to be valid, but gets a None value instead.

Since 0.11 started validating all records including SOA before accepting them, the resulting invalid SOA record is not accepted and leads to a server error (which it shouldn't, the error should have been caught earlier on) telling you that the SOA record is invalid. That request would have succeeded with 0.10 and before, but the SOA would still have been invalid and caused problems with the zone.

So can you please try the same request with either a soa_serial parameter set to the desired SERIAL for the zone in its data or with soa_serial_auto set to true so the serial is auto-created?

I'll see to NetBox DNS' failure to report the missing serial/no autogeneration issue with a clearer error message as soon as I can.

Fixed that. Your request still won't work because it's invalid, but now you'll be told the real reason why :-)

Hi @peteeckel and thanks for your prompt response.

Record validation is a great thing ๐Ÿ‘ It's just that I never had issues with invalid SOA serial, since I am currently testing your plugin just in pull mode (fetch and inventory DNS records from server), and not for pushing configuration to name server.

I have now fixed my call, adding a fake serial number... and all works fine.
Thank you for the support and also for the new features ("views" and validation): really appreciated ๐Ÿ˜‰

Hi @fabricat, thanks for testing and confirming that it worked!

I'm thinking about your use case of pulling data from the name server and pushing it to NetBox DNS ... there are obviously two problems with that: Importing SOA and NS records does not really work as they are generated from zone object data.

While it does not make too much sense to do this on the GUI level, I'm considering if an API function to import SOA and NS records would. This is a bit more complicated than with other record types, but the following algorithm should do the trick:

# Import SOA record
if record.type == "SOA" and record.name == zone.name:
    parse SOA record for its fields
    set record.zone.soa_serial_auto to False
    if no nameserver object with the name of MNAME exists:
        create nameserver object
    update record.zone.soa_* fields

# Import NS record
elif record.type == "NS" and record.name == zone.name:
    parse NS record for its fields
    if no nameserver object with matching name exists:
        create nameserver object
    update zone.nameservers

else:
    import record as provided

The first two cases update the zone object and optionally create missing nameserver objects, which would recreate the SOA/NS records using the existing automatism, the third case would be the same as now.

Update: Thinking about it more thoroughly, you can actually import NS and SOA records just fine as long as they don't refer to the zone itself (although in the case of SOA I don't see a reason why anyone should want to do that, but anyway). Updated the algorithm to reflect that.

Would that help you with your task? If so, I'll open a ticket and start working on it as soon as a time slot turns up.

Hi @peteeckel, and thanks for your additional feedback.
To be honest, I am not caring about the "managed records", since I am focused on the rest of the records (indeed, I am currently putting fake data into SOA and NS).

In my specific case, I find netbox-dns useful in order to:

  • have a structured inventory of all the DNS records from our zones
  • attach further info to each record, leveraging Netbox custom fields (e.g. reference to our ticketing system)

I know that I am not using Netbox as source-of-thruth ๐Ÿค“ ...but I love its flexibility: once again, it allows me to do what I need ๐Ÿ˜Š
I don't need any additional feature from you... for the moment.

Hi @fabricat, thanks again for your input.

I'll keep the feature in the back of my head for the time being as (as you already suggested) importing real life data is not the typical use case for NetBox/NetBox DNS as it is designed ... but anyway, when I come to revisit the API serializer code sooner or later I might add it anyway as it doesn't really hurt to have the feature around.