Add unique constraint on (dns_name, family) #2865

Closed
opened 2025-12-29 18:22:55 +01:00 by adam · 3 comments
Owner

Originally created by @candlerb on GitHub (Sep 9, 2019).

Environment

  • Python version: 3.5.2
  • NetBox version: 2.6.3

Proposed Functionality

On ipam_ipaddress, add a unique constraint on (dns_name, family)

Use Case

As I understand it, the dns_name field is intended to be used as the "primary" DNS name for an IP address: the one which the PTR record points to.

Each IP address can have only one such primary name, and there will be a matching forward A/AAAA record. You can of course have other A/AAAA records pointing to the same IP address, but they would be managed outside of Netbox.

Having one IPv4 address and one IPv6 share the same primary dns_name is also fine, for a dual-stacked host.

However, Netbox currently allows multiple addresses of the same family to point to the same dns_name. If you do this, the primary forward name will have multiple A or AAAA records. Whilst this is not technically invalid, it's almost certainly not what you want, as you will get an answer selected at random for queries to the primary name.

Therefore, I would like to prevent this. A uniqueness constraint on (dns_name, family) will achieve this, whilst still allowing one IPv4 and one IPv6 address to point to the same name. If dns_name is null, postgres ignores the uniqueness constraint, which is also what we want.

Aside: in those cases where you do want round-robin DNS, it would be done by adding additional A/AAAA records outside of netbox. e.g.

  • address 192.0.2.1/24 has name server1.example.com
  • address 192.0.2.2/24 has name server2.example.com
  • www.example.com has A records 192.0.2.1 and 192.0.2.2

This means that the reverse for each host correctly points to its own name.

Database Changes

As above - new constraint in model / database

External Dependencies

None

Originally created by @candlerb on GitHub (Sep 9, 2019). ### Environment * Python version: 3.5.2 * NetBox version: 2.6.3 ### Proposed Functionality On ipam_ipaddress, add a unique constraint on `(dns_name, family)` ### Use Case As I understand it, the `dns_name` field is intended to be used as the "primary" DNS name for an IP address: the one which the PTR record points to. Each IP address can have only one such primary name, and there will be a matching forward A/AAAA record. You can of course have other A/AAAA records pointing to the same IP address, but they would be managed outside of Netbox. Having one IPv4 address and one IPv6 share the same primary dns_name is also fine, for a dual-stacked host. However, Netbox currently allows multiple addresses of the same family to point to the same dns_name. If you do this, the primary forward name will have multiple A or AAAA records. Whilst this is not technically invalid, it's almost certainly not what you want, as you will get an answer selected at random for queries to the primary name. Therefore, I would like to prevent this. A uniqueness constraint on `(dns_name, family)` will achieve this, whilst still allowing one IPv4 and one IPv6 address to point to the same name. If `dns_name` is null, postgres ignores the uniqueness constraint, which is also what we want. Aside: in those cases where you do want round-robin DNS, it would be done by adding additional A/AAAA records outside of netbox. e.g. * address `192.0.2.1/24` has name `server1.example.com` * address `192.0.2.2/24` has name `server2.example.com` * `www.example.com` has A records `192.0.2.1` and `192.0.2.2` This means that the reverse for each host correctly points to its own name. ### Database Changes As above - new constraint in model / database ### External Dependencies None
adam added the type: feature label 2025-12-29 18:22:55 +01:00
adam closed this issue 2025-12-29 18:22:55 +01:00
Author
Owner

@DanSheps commented on GitHub (Sep 12, 2019):

Whilst this is not technically invalid, it's almost certainly not what you want, as you will get an answer selected at random for queries to the primary name.

I think the problem is right here, and even more so. It isn't invalid and even there are cases where multiple A/AAAA/etc records are desired for the round-robin DNS load-balancing.

Consider this scenario:

A 2 load balancers (or any device for that matter) (lb1.my.net : 192.0.2.251 [Primary])(lb2.my.net : 192.0.2.252 [Primary]) with 7 additional ips on outside interfaces:

www.my.net:192.0.2.1
www.my.net:192.0.2.2
www.my.net:192.0.2.3

www.my.net:192.0.2.4
www.my.net:192.0.2.5
www.my.net:192.0.2.6

Or perhaps this scenario:

2 servers peering with routers both advertising 192.0.2.23/32 into eBGP/iBGP. You would want to document these prefixes somewhere (Loopback perhaps) and each would have a duplicate IP and a duplicate hostname.

These would be a perfectly valid configuration and you may want to model that in Netbox. I don't think we should be putting constraints in place where there might be a valid use-case for it. Why might you want to do this? I can't personally think of a reason when you already have a load balancer.

@DanSheps commented on GitHub (Sep 12, 2019): > Whilst this is not technically invalid, it's almost certainly not what you want, as you will get an answer selected at random for queries to the primary name. I think the problem is right here, and even more so. It isn't invalid and even there are cases where multiple A/AAAA/etc records are desired for the round-robin DNS load-balancing. Consider this scenario: A 2 load balancers (or any device for that matter) (lb1.my.net : 192.0.2.251 [Primary])(lb2.my.net : 192.0.2.252 [Primary]) with 7 additional ips on outside interfaces: www.my.net:192.0.2.1 www.my.net:192.0.2.2 www.my.net:192.0.2.3 www.my.net:192.0.2.4 www.my.net:192.0.2.5 www.my.net:192.0.2.6 Or perhaps this scenario: 2 servers peering with routers both advertising 192.0.2.23/32 into eBGP/iBGP. You would want to document these prefixes somewhere (Loopback perhaps) and each would have a duplicate IP **and** a duplicate hostname. These would be a perfectly valid configuration and you may want to model that in Netbox. I don't think we should be putting constraints in place where there might be a valid use-case for it. Why might you want to do this? I can't personally think of a reason when you already have a load balancer.
Author
Owner

@candlerb commented on GitHub (Sep 16, 2019):

Certainly round-robin DNS is something you may want to do. What I'm saying is, you shouldn't use the dns_name attribute of the ipam.ipaddress object to configure it.

In my opinion, the following would be a bad configuration:

www.my.net. A 192.0.2.1
www.my.net. A 192.0.2.2
www.my.net. A 192.0.2.3

1.2.0.192.in-addr.arpa. PTR www.my.net.
2.2.0.192.in-addr.arpa. PTR www.my.net.
3.2.0.192.in-addr.arpa. PTR www.my.net.

The right way would be:

www.my.net. A 192.0.2.1
www.my.net. A 192.0.2.2
www.my.net. A 192.0.2.3

www1.my.net. A 192.0.2.1
www2.my.net. A 192.0.2.2
www3.my.net. A 192.0.2.3

1.2.0.192.in-addr.arpa. PTR www1.my.net.
2.2.0.192.in-addr.arpa. PTR www2.my.net.
3.2.0.192.in-addr.arpa. PTR www3.my.net.

The latter is better for several reasons. It gives each address a unique name so that when you do a reverse query for (say) 192.0.2.2, you can see which host it belongs to. More importantly, from an operational point of view, you can remove an individual host from the "www" group (e.g. for maintenance) without breaking that host's forward/reverse DNS. You can also have a short TTL for "www" for operational reasons, but longer TTLs for "www1", "www2", "www3".

If you take the second approach in Netbox, then:

  • 192.0.2.1 has dns_name "www1.my.net": generates forward and reverse
  • 192.0.2.2 has dns_name "www2.my.net": ditto
  • 192.0.2.3 has dns_name "www3.my.net": ditto
  • The DNS records for "www" are forward-only, and added separately into the DNS

As for the second example you give: announcing the same loopback from multiple devices. I think that normally in Netbox you would create a single ipam.ipaddress object for 192.0.2.23/32, with role "Loopback" or "VIP" if it is shared between multiple hosts.

If you decide to add the same IP separately to multiple devices in Netbox then you have to turn off the IP uniqueness checking; that in turn increases the risk of other inconsistencies being introduced.

@candlerb commented on GitHub (Sep 16, 2019): Certainly round-robin DNS is something you may want to do. What I'm saying is, you shouldn't use the `dns_name` attribute of the `ipam.ipaddress` object to configure it. In my opinion, the following would be a bad configuration: ``` www.my.net. A 192.0.2.1 www.my.net. A 192.0.2.2 www.my.net. A 192.0.2.3 1.2.0.192.in-addr.arpa. PTR www.my.net. 2.2.0.192.in-addr.arpa. PTR www.my.net. 3.2.0.192.in-addr.arpa. PTR www.my.net. ``` The right way would be: ``` www.my.net. A 192.0.2.1 www.my.net. A 192.0.2.2 www.my.net. A 192.0.2.3 www1.my.net. A 192.0.2.1 www2.my.net. A 192.0.2.2 www3.my.net. A 192.0.2.3 1.2.0.192.in-addr.arpa. PTR www1.my.net. 2.2.0.192.in-addr.arpa. PTR www2.my.net. 3.2.0.192.in-addr.arpa. PTR www3.my.net. ``` The latter is better for several reasons. It gives each address a unique name so that when you do a reverse query for (say) 192.0.2.2, you can see which host it belongs to. More importantly, from an operational point of view, you can remove an individual host from the "www" group (e.g. for maintenance) without breaking that host's forward/reverse DNS. You can also have a short TTL for "www" for operational reasons, but longer TTLs for "www1", "www2", "www3". If you take the second approach in Netbox, then: * 192.0.2.1 has dns_name "www1.my.net": generates forward and reverse * 192.0.2.2 has dns_name "www2.my.net": ditto * 192.0.2.3 has dns_name "www3.my.net": ditto * The DNS records for "www" are forward-only, and added separately into the DNS As for the second example you give: announcing the same loopback from multiple devices. I think that normally in Netbox you would create a single `ipam.ipaddress` object for 192.0.2.23/32, with role "Loopback" or "VIP" if it is shared between multiple hosts. If you decide to add the same IP separately to multiple devices in Netbox then you have to turn off the IP uniqueness checking; that in turn increases the risk of other inconsistencies being introduced.
Author
Owner

@DanSheps commented on GitHub (Sep 23, 2019):

In my opinion, the following would be a bad configuration:

www.my.net. A 192.0.2.1
www.my.net. A 192.0.2.2
www.my.net. A 192.0.2.3

1.2.0.192.in-addr.arpa. PTR www.my.net.
2.2.0.192.in-addr.arpa. PTR www.my.net.
3.2.0.192.in-addr.arpa. PTR www.my.net.

The right way would be:

www.my.net. A 192.0.2.1
www.my.net. A 192.0.2.2
www.my.net. A 192.0.2.3

www1.my.net. A 192.0.2.1
www2.my.net. A 192.0.2.2
www3.my.net. A 192.0.2.3

1.2.0.192.in-addr.arpa. PTR www1.my.net.
2.2.0.192.in-addr.arpa. PTR www2.my.net.
3.2.0.192.in-addr.arpa. PTR www3.my.net.

...

As for the second example you give: announcing the same loopback from multiple devices. I think that normally in Netbox you would create a single ipam.ipaddress object for 192.0.2.23/32, with role "Loopback" or "VIP" if it is shared between multiple hosts.

That might be how you would model it, not everyone will model it this way and for that reason I don't think name uniqueness should be a thing we enforce. The right way for you to model something is not the right way for someone else to model something. There are valid cases on both sides and if name uniqueness is something you desire, that is probably better suited in a report that you manually run rather then being backed in.

Constraining the end-user in the database too much is going to result in the product not being usable for them whereas reports are the correct "soft-enforcement" method in this particular instance.

If you decide to add the same IP separately to multiple devices in Netbox then you have to turn off the IP uniqueness checking; that in turn increases the risk of other inconsistencies being introduced.

Or you just choose the "HSRP, GLBP, CARP, VRRP, VIP or Anycast" role, which disables the uniqueness checking for that specific address.

I think for now I am going to close this out, I don't see any benefit to doing this and as people have already been using this in production it would be a breaking change.

@DanSheps commented on GitHub (Sep 23, 2019): > In my opinion, the following would be a bad configuration: > > ``` > www.my.net. A 192.0.2.1 > www.my.net. A 192.0.2.2 > www.my.net. A 192.0.2.3 > > 1.2.0.192.in-addr.arpa. PTR www.my.net. > 2.2.0.192.in-addr.arpa. PTR www.my.net. > 3.2.0.192.in-addr.arpa. PTR www.my.net. > ``` > > The right way would be: > > ``` > www.my.net. A 192.0.2.1 > www.my.net. A 192.0.2.2 > www.my.net. A 192.0.2.3 > > www1.my.net. A 192.0.2.1 > www2.my.net. A 192.0.2.2 > www3.my.net. A 192.0.2.3 > > 1.2.0.192.in-addr.arpa. PTR www1.my.net. > 2.2.0.192.in-addr.arpa. PTR www2.my.net. > 3.2.0.192.in-addr.arpa. PTR www3.my.net. > ``` > > ... > > As for the second example you give: announcing the same loopback from multiple devices. I think that normally in Netbox you would create a single `ipam.ipaddress` object for 192.0.2.23/32, with role "Loopback" or "VIP" if it is shared between multiple hosts. That might be how you would model it, not everyone will model it this way and for that reason I don't think name uniqueness should be a thing we enforce. The right way for you to model something is not the right way for someone else to model something. There are valid cases on both sides and if name uniqueness is something you desire, that is probably better suited in a report that you manually run rather then being backed in. Constraining the end-user in the database too much is going to result in the product not being usable for them whereas reports are the correct "soft-enforcement" method in this particular instance. > If you decide to add the same IP separately to multiple devices in Netbox then you have to turn off the IP uniqueness checking; that in turn increases the risk of other inconsistencies being introduced. Or you just choose the "HSRP, GLBP, CARP, VRRP, VIP or Anycast" role, which disables the uniqueness checking for that specific address. I think for now I am going to close this out, I don't see any benefit to doing this and as people have already been using this in production it would be a breaking change.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#2865