Merge ~ddstreet/maas:lp1896684-28 into maas:2.8

Proposed by Dan Streetman
Status: Merged
Approved by: Lee Trager
Approved revision: 843b1c54a4c01853dbdf7ae37929c92483d410fd
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~ddstreet/maas:lp1896684-28
Merge into: maas:2.8
Diff against target: 364 lines (+158/-43)
6 files modified
src/maasserver/dhcp.py (+13/-1)
src/maasserver/models/node.py (+6/-11)
src/maasserver/models/tests/test_node.py (+20/-0)
src/maasserver/preseed_network.py (+26/-21)
src/maasserver/tests/test_dhcp.py (+44/-10)
src/maasserver/tests/test_preseed_network.py (+49/-0)
Reviewer Review Type Date Requested Status
Lee Trager (community) Approve
MAAS Lander Approve
Review via email: mp+392313@code.launchpad.net

Commit message

LP: #1896684 - If no subnet gateway, only use in-subnet dns addresses

If DHCP is not providing any gateway, it should not provide any
DNS server addresses that aren't directly reachable.

Similarly, if the network preseed is not configuring any gateway,
it should not provide per-interface DNS server addresses, nor default
dns server addresses, that aren't directly reachable.

Only apply rack DNS server address if subnet.allow_dns == True

To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b lp1896684-28 lp:~ddstreet/maas/+git/maas into -b 2.8 lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 843b1c54a4c01853dbdf7ae37929c92483d410fd

review: Approve
Revision history for this message
Lee Trager (ltrager) :
review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNABLE TO START LANDING

STATUS: MISSING COMMIT MESSAGE

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/src/maasserver/dhcp.py b/src/maasserver/dhcp.py
index 848ff1b..05e9f7a 100644
--- a/src/maasserver/dhcp.py
+++ b/src/maasserver/dhcp.py
@@ -438,7 +438,15 @@ def make_subnet_config(
438 dns_servers = []438 dns_servers = []
439 if subnet.allow_dns and default_dns_servers:439 if subnet.allow_dns and default_dns_servers:
440 # If the MAAS DNS server is enabled make sure that is used first.440 # If the MAAS DNS server is enabled make sure that is used first.
441 dns_servers += default_dns_servers441 if subnet.gateway_ip:
442 dns_servers += default_dns_servers
443 else:
444 # if there is no gateway, only provide in-subnet dns servers
445 dns_servers += [
446 ipaddress
447 for ipaddress in default_dns_servers
448 if ipaddress in ip_network
449 ]
442 if subnet.dns_servers:450 if subnet.dns_servers:
443 # Add DNS user defined DNS servers451 # Add DNS user defined DNS servers
444 dns_servers += [IPAddress(server) for server in subnet.dns_servers]452 dns_servers += [IPAddress(server) for server in subnet.dns_servers]
@@ -557,6 +565,10 @@ def get_default_dns_servers(rack_controller, subnet, use_rack_proxy=True):
557 :param use_rack_proxy: Whether to proxy DNS through the rack controller565 :param use_rack_proxy: Whether to proxy DNS through the rack controller
558 or not.566 or not.
559 """567 """
568 if not subnet.allow_dns:
569 # This subnet isn't allowed to use region or rack addresses for dns
570 return []
571
560 ip_version = subnet.get_ip_version()572 ip_version = subnet.get_ip_version()
561 default_region_ip = get_source_address(subnet.get_ipnetwork())573 default_region_ip = get_source_address(subnet.get_ipnetwork())
562 try:574 try:
diff --git a/src/maasserver/models/node.py b/src/maasserver/models/node.py
index 7e867cd..1d371f4 100644
--- a/src/maasserver/models/node.py
+++ b/src/maasserver/models/node.py
@@ -4905,6 +4905,8 @@ class Node(CleanSave, TimestampedModel):
4905 if ipv4 and gateways.ipv4 is not None:4905 if ipv4 and gateways.ipv4 is not None:
4906 subnet = Subnet.objects.get(id=gateways.ipv4.subnet_id)4906 subnet = Subnet.objects.get(id=gateways.ipv4.subnet_id)
4907 if subnet.dns_servers:4907 if subnet.dns_servers:
4908 if not subnet.allow_dns:
4909 return subnet.dns_servers
4908 rack_dns = []4910 rack_dns = []
4909 for rack in {4911 for rack in {
4910 self.get_boot_primary_rack_controller(),4912 self.get_boot_primary_rack_controller(),
@@ -4931,6 +4933,8 @@ class Node(CleanSave, TimestampedModel):
4931 if ipv6 and gateways.ipv6 is not None:4933 if ipv6 and gateways.ipv6 is not None:
4932 subnet = Subnet.objects.get(id=gateways.ipv6.subnet_id)4934 subnet = Subnet.objects.get(id=gateways.ipv6.subnet_id)
4933 if subnet.dns_servers:4935 if subnet.dns_servers:
4936 if not subnet.allow_dns:
4937 return subnet.dns_servers
4934 rack_dns = []4938 rack_dns = []
4935 for rack in {4939 for rack in {
4936 self.get_boot_primary_rack_controller(),4940 self.get_boot_primary_rack_controller(),
@@ -4977,18 +4981,9 @@ class Node(CleanSave, TimestampedModel):
4977 if filtered_addresses:4981 if filtered_addresses:
4978 routable_addrs_map[node] = filtered_addresses4982 routable_addrs_map[node] = filtered_addresses
49794983
4980 # No default gateway subnet has specific DNS servers defined, so
4981 # use MAAS for the default DNS server.
4982 if gateways.ipv4 is None and gateways.ipv6 is None:4984 if gateways.ipv4 is None and gateways.ipv6 is None:
4983 # If there are no default gateways, the default is the MAAS4985 # node with no gateway can only use routable addrs
4984 # region IP address.4986 maas_dns_servers = []
4985 maas_dns_servers = get_dns_server_addresses(
4986 rack_controller=self.get_boot_rack_controller(),
4987 ipv4=ipv4,
4988 ipv6=ipv6,
4989 include_alternates=True,
4990 default_region_ip=default_region_ip,
4991 )
4992 routable_addrs_map = {4987 routable_addrs_map = {
4993 node: [4988 node: [
4994 address4989 address
diff --git a/src/maasserver/models/tests/test_node.py b/src/maasserver/models/tests/test_node.py
index 3b9a6fb..6121686 100644
--- a/src/maasserver/models/tests/test_node.py
+++ b/src/maasserver/models/tests/test_node.py
@@ -8132,6 +8132,26 @@ class TestGetDefaultDNSServers(MAASServerTestCase):
8132 node.get_default_dns_servers(), [ipv6_subnet_dns]8132 node.get_default_dns_servers(), [ipv6_subnet_dns]
8133 )8133 )
81348134
8135 def test_ignores_other_unroutable_rack_controllers_ipv4(self):
8136 # Regression test for LP:1896684
8137 rack_v4, rack_v6, node = self.make_Node_with_RackController(
8138 ipv4=True, ipv4_gateway=False, ipv6=False, ipv6_gateway=False
8139 )
8140 vlan = node.boot_interface.vlan
8141 rack = vlan.primary_rack
8142 rackif = rack.interface_set.first()
8143 rack_ips = [rack_v4]
8144 for _ in range(3):
8145 subnet = factory.make_Subnet(vlan=vlan, version=4)
8146 ip = factory.make_StaticIPAddress(subnet=subnet, interface=rackif)
8147 rack_ips.append(ip.ip)
8148 rack.save()
8149 resolve_hostname = self.patch(server_address, "resolve_hostname")
8150 resolve_hostname.side_effect = lambda hostname, version: set(
8151 map(IPAddress, rack_ips)
8152 )
8153 self.assertItemsEqual(node.get_default_dns_servers(), [rack_v4])
8154
81358155
8136class TestNode_Start(MAASTransactionServerTestCase):8156class TestNode_Start(MAASTransactionServerTestCase):
8137 """Tests for Node.start()."""8157 """Tests for Node.start()."""
diff --git a/src/maasserver/preseed_network.py b/src/maasserver/preseed_network.py
index 779d1a6..99a3ce3 100644
--- a/src/maasserver/preseed_network.py
+++ b/src/maasserver/preseed_network.py
@@ -373,32 +373,37 @@ class InterfaceConfiguration:
373 if "addresses" not in v2_nameservers:373 if "addresses" not in v2_nameservers:
374 v2_nameservers["addresses"] = []374 v2_nameservers["addresses"] = []
375375
376 for ip in StaticIPAddress.objects.filter(376 if subnet.allow_dns:
377 interface__node__in=[377 for ip in StaticIPAddress.objects.filter(
378 subnet.vlan.primary_rack,378 interface__node__in=[
379 subnet.vlan.secondary_rack,379 subnet.vlan.primary_rack,
380 ],380 subnet.vlan.secondary_rack,
381 subnet__vlan=subnet.vlan,381 ],
382 alloc_type__in=[382 subnet__vlan=subnet.vlan,
383 IPADDRESS_TYPE.AUTO,383 alloc_type__in=[
384 IPADDRESS_TYPE.STICKY,384 IPADDRESS_TYPE.AUTO,
385 ],385 IPADDRESS_TYPE.STICKY,
386 ).exclude(ip=None):386 ],
387 if (387 ).exclude(ip=None):
388 IPAddress(ip.get_ip()).version388 if ip.ip in v2_nameservers["addresses"]:
389 == subnet.get_ip_version()389 continue
390 and ip.get_ip() not in v2_nameservers["addresses"]390 ip_address = IPAddress(ip.ip)
391 ):391 if ip_address.version != subnet.get_ip_version():
392 continue
393 if not subnet.gateway_ip:
394 if ip_address not in subnet.get_ipnetwork():
395 # without gateway, only use in-subnet addrs
396 continue
392 v1_subnet_operation["dns_nameservers"].append(397 v1_subnet_operation["dns_nameservers"].append(
393 ip.ip398 ip.ip
394 )399 )
395 v2_nameservers["addresses"].append(ip.ip)400 v2_nameservers["addresses"].append(ip.ip)
396401
397 if subnet.dns_servers:402 for ip in subnet.dns_servers:
398 v1_subnet_operation[403 if ip in v2_nameservers["addresses"]:
399 "dns_nameservers"404 continue
400 ] += subnet.dns_servers405 v1_subnet_operation["dns_nameservers"].append(ip)
401 v2_nameservers["addresses"] += subnet.dns_servers406 v2_nameservers["addresses"].append(ip)
402407
403 if len(matching_subnet_routes) > 0 and version == 1:408 if len(matching_subnet_routes) > 0 and version == 1:
404 # For the v1 YAML, the list of routes is rendered409 # For the v1 YAML, the list of routes is rendered
diff --git a/src/maasserver/tests/test_dhcp.py b/src/maasserver/tests/test_dhcp.py
index d53f8bb..f445146 100644
--- a/src/maasserver/tests/test_dhcp.py
+++ b/src/maasserver/tests/test_dhcp.py
@@ -1158,7 +1158,7 @@ class TestMakeSubnetConfig(MAASServerTestCase):
1158 config = dhcp.make_subnet_config(1158 config = dhcp.make_subnet_config(
1159 rack_controller,1159 rack_controller,
1160 subnet,1160 subnet,
1161 [factory.make_name("dns")],1161 [factory.make_ipv4_address()],
1162 [factory.make_name("ntp")],1162 [factory.make_name("ntp")],
1163 default_domain,1163 default_domain,
1164 search_list=default_domain.name,1164 search_list=default_domain.name,
@@ -1457,7 +1457,7 @@ class TestMakeSubnetConfig(MAASServerTestCase):
1457 config = dhcp.make_subnet_config(1457 config = dhcp.make_subnet_config(
1458 rack_controller,1458 rack_controller,
1459 subnet,1459 subnet,
1460 [factory.make_name("dns")],1460 [factory.make_ipv4_address()],
1461 [factory.make_name("ntp")],1461 [factory.make_name("ntp")],
1462 default_domain,1462 default_domain,
1463 )1463 )
@@ -1474,7 +1474,7 @@ class TestMakeSubnetConfig(MAASServerTestCase):
1474 config = dhcp.make_subnet_config(1474 config = dhcp.make_subnet_config(
1475 rack_controller,1475 rack_controller,
1476 subnet,1476 subnet,
1477 [factory.make_name("dns")],1477 [factory.make_ipv4_address()],
1478 [factory.make_name("ntp")],1478 [factory.make_name("ntp")],
1479 default_domain,1479 default_domain,
1480 )1480 )
@@ -1495,7 +1495,7 @@ class TestMakeSubnetConfig(MAASServerTestCase):
1495 config = dhcp.make_subnet_config(1495 config = dhcp.make_subnet_config(
1496 rack_controller,1496 rack_controller,
1497 subnet,1497 subnet,
1498 [factory.make_name("dns")],1498 [factory.make_ipv4_address()],
1499 [factory.make_name("ntp")],1499 [factory.make_name("ntp")],
1500 default_domain,1500 default_domain,
1501 )1501 )
@@ -1518,7 +1518,7 @@ class TestMakeSubnetConfig(MAASServerTestCase):
1518 config = dhcp.make_subnet_config(1518 config = dhcp.make_subnet_config(
1519 rack_controller,1519 rack_controller,
1520 subnet,1520 subnet,
1521 [factory.make_name("dns")],1521 [factory.make_ipv4_address()],
1522 [factory.make_name("ntp")],1522 [factory.make_name("ntp")],
1523 default_domain,1523 default_domain,
1524 search_list=search_list,1524 search_list=search_list,
@@ -1546,7 +1546,7 @@ class TestMakeSubnetConfig(MAASServerTestCase):
1546 config = dhcp.make_subnet_config(1546 config = dhcp.make_subnet_config(
1547 rack_controller,1547 rack_controller,
1548 subnet,1548 subnet,
1549 [factory.make_name("dns")],1549 [factory.make_ipv6_address()],
1550 [factory.make_name("ntp")],1550 [factory.make_name("ntp")],
1551 default_domain,1551 default_domain,
1552 search_list=search_list,1552 search_list=search_list,
@@ -1581,7 +1581,7 @@ class TestMakeSubnetConfig(MAASServerTestCase):
1581 config = dhcp.make_subnet_config(1581 config = dhcp.make_subnet_config(
1582 rack_controller,1582 rack_controller,
1583 subnet,1583 subnet,
1584 [factory.make_name("dns")],1584 [factory.make_ipv4_address()],
1585 [factory.make_name("ntp")],1585 [factory.make_name("ntp")],
1586 default_domain,1586 default_domain,
1587 )1587 )
@@ -1609,7 +1609,7 @@ class TestMakeSubnetConfig(MAASServerTestCase):
1609 config = dhcp.make_subnet_config(1609 config = dhcp.make_subnet_config(
1610 rack_controller,1610 rack_controller,
1611 subnet,1611 subnet,
1612 [factory.make_name("dns")],1612 [factory.make_ipv4_address()],
1613 [factory.make_name("ntp")],1613 [factory.make_name("ntp")],
1614 default_domain,1614 default_domain,
1615 failover_peer=failover_peer,1615 failover_peer=failover_peer,
@@ -1643,7 +1643,7 @@ class TestMakeSubnetConfig(MAASServerTestCase):
1643 config = dhcp.make_subnet_config(1643 config = dhcp.make_subnet_config(
1644 rack_controller,1644 rack_controller,
1645 subnet,1645 subnet,
1646 [factory.make_name("dns")],1646 [factory.make_ipv4_address()],
1647 [factory.make_name("ntp")],1647 [factory.make_name("ntp")],
1648 default_domain,1648 default_domain,
1649 )1649 )
@@ -1664,7 +1664,7 @@ class TestMakeSubnetConfig(MAASServerTestCase):
1664 config = dhcp.make_subnet_config(1664 config = dhcp.make_subnet_config(
1665 rack_controller,1665 rack_controller,
1666 subnet,1666 subnet,
1667 [factory.make_name("dns")],1667 [factory.make_ipv4_address()],
1668 [factory.make_name("ntp")],1668 [factory.make_name("ntp")],
1669 default_domain,1669 default_domain,
1670 subnets_dhcp_snippets=dhcp_snippets,1670 subnets_dhcp_snippets=dhcp_snippets,
@@ -1681,6 +1681,40 @@ class TestMakeSubnetConfig(MAASServerTestCase):
1681 config["dhcp_snippets"],1681 config["dhcp_snippets"],
1682 )1682 )
16831683
1684 def test_subnet_without_gateway_restricts_nameservers(self):
1685 network1 = IPNetwork("10.9.8.0/24")
1686 network2 = IPNetwork("10.9.9.0/24")
1687 rackip1 = "10.9.8.1"
1688 rackip2 = "10.9.9.1"
1689 rack_controller = factory.make_RackController(interface=False)
1690 vlan = factory.make_VLAN()
1691 subnet1 = factory.make_Subnet(cidr=str(network1.cidr), vlan=vlan)
1692 subnet2 = factory.make_Subnet(
1693 cidr=str(network2.cidr), vlan=vlan, gateway_ip=None
1694 )
1695 factory.make_Interface(
1696 INTERFACE_TYPE.PHYSICAL, vlan=vlan, node=rack_controller
1697 )
1698 default_domain = Domain.objects.get_default_domain()
1699 config = dhcp.make_subnet_config(
1700 rack_controller,
1701 subnet1,
1702 [rackip1, rackip2],
1703 [factory.make_name("ntp")],
1704 default_domain,
1705 )
1706 self.assertIn(rackip1, config["dns_servers"])
1707 self.assertIn(rackip2, config["dns_servers"])
1708 config = dhcp.make_subnet_config(
1709 rack_controller,
1710 subnet2,
1711 [rackip1, rackip2],
1712 [factory.make_name("ntp")],
1713 default_domain,
1714 )
1715 self.assertNotIn(rackip1, config["dns_servers"])
1716 self.assertIn(rackip2, config["dns_servers"])
1717
16841718
1685class TestMakeHostsForSubnet(MAASServerTestCase):1719class TestMakeHostsForSubnet(MAASServerTestCase):
1686 def tests__returns_defined_hosts(self):1720 def tests__returns_defined_hosts(self):
diff --git a/src/maasserver/tests/test_preseed_network.py b/src/maasserver/tests/test_preseed_network.py
index 9c3a326..5fa1dd5 100644
--- a/src/maasserver/tests/test_preseed_network.py
+++ b/src/maasserver/tests/test_preseed_network.py
@@ -1737,6 +1737,55 @@ class TestNetplan(MAASServerTestCase):
1737 v2["network"]["ethernets"][iface.name]["nameservers"],1737 v2["network"]["ethernets"][iface.name]["nameservers"],
1738 )1738 )
17391739
1740 def test_allow_dns_false_does_not_include_rack_controllers(self):
1741 # Regression test for LP:1896684
1742 vlan = factory.make_VLAN()
1743 nameserver = "1.1.1.1"
1744 subnet = factory.make_Subnet(
1745 dns_servers=[nameserver], vlan=vlan, allow_dns=False
1746 )
1747 rack = factory.make_RackController(subnet=subnet)
1748 rack_iface = rack.interface_set.first()
1749 factory.make_StaticIPAddress(subnet=subnet, interface=rack_iface)
1750 vlan.primary_rack = rack
1751 vlan.save()
1752 node = factory.make_Node_with_Interface_on_Subnet(
1753 status=NODE_STATUS.DEPLOYING, subnet=subnet
1754 )
1755 iface = node.interface_set.first()
1756 factory.make_StaticIPAddress(subnet=subnet, interface=iface)
1757 v2 = self._render_netplan_dict(node)
1758 self.assertDictEqual(
1759 {"search": ["maas"], "addresses": [nameserver]},
1760 v2["network"]["ethernets"][iface.name]["nameservers"],
1761 )
1762
1763 def test_no_gateway_does_not_include_unroutable_controllers(self):
1764 # Regression test for LP:1896684
1765 vlan = factory.make_VLAN()
1766 subnet1 = factory.make_Subnet(
1767 dns_servers=[], vlan=vlan, version=4, gateway_ip=None
1768 )
1769 subnet2 = factory.make_Subnet(dns_servers=[], vlan=vlan, version=4)
1770 rack = factory.make_RackController(subnet=subnet1)
1771 rack_iface = rack.interface_set.first()
1772 rack_ip1 = factory.make_StaticIPAddress(
1773 subnet=subnet1, interface=rack_iface
1774 )
1775 factory.make_StaticIPAddress(subnet=subnet2, interface=rack_iface)
1776 vlan.primary_rack = rack
1777 vlan.save()
1778 node = factory.make_Node_with_Interface_on_Subnet(
1779 status=NODE_STATUS.DEPLOYING, subnet=subnet1
1780 )
1781 iface = node.interface_set.first()
1782 factory.make_StaticIPAddress(subnet=subnet1, interface=iface)
1783 v2 = self._render_netplan_dict(node)
1784 self.assertDictEqual(
1785 {"search": ["maas"], "addresses": [rack_ip1.ip]},
1786 v2["network"]["ethernets"][iface.name]["nameservers"],
1787 )
1788
1740 def test_commissioning_dhcp_config(self):1789 def test_commissioning_dhcp_config(self):
1741 # Verifies dhcp config is given when commissioning has run1790 # Verifies dhcp config is given when commissioning has run
1742 # or just run and no AUTOIP has been acquired.1791 # or just run and no AUTOIP has been acquired.

Subscribers

People subscribed via source and target branches