Beispiel #1
0
    def test_tftp_service_does_not_bind_to_link_local_addresses(self):
        # Initial set of interfaces to bind to.
        ipv4_test_net_3 = IPNetwork("203.0.113.0/24")  # RFC 5737
        normal_addresses = {
            factory.pick_ip_in_network(ipv4_test_net_3),
            factory.make_ipv6_address(),
        }
        link_local_addresses = {
            factory.pick_ip_in_network(IPV4_LINK_LOCAL),
            factory.pick_ip_in_network(IPV6_LINK_LOCAL),
        }
        self.patch(
            tftp_module,
            "get_all_interface_addresses",
            lambda: normal_addresses | link_local_addresses,
        )

        tftp_service = TFTPService(
            resource_root=self.make_dir(),
            client_service=Mock(),
            port=factory.pick_port(),
        )
        tftp_service.updateServers()

        # Only the "normal" addresses have been used.
        self.assertEqual(
            normal_addresses,
            {server.name for server in tftp_service.getServers()},
        )
Beispiel #2
0
 def test_get_ptr_mapping_drops_IPs_not_in_network(self):
     name = factory.make_string()
     network = IPNetwork("192.12.0.1/30")
     in_network_mapping = {
         factory.make_string(): factory.pick_ip_in_network(network),
         factory.make_string(): factory.pick_ip_in_network(network),
     }
     expected = [
         (
             IPAddress(ip).reverse_dns.split(".")[0],
             30,
             "%s.%s." % (hostname, name),
         )
         for hostname, ip in in_network_mapping.items()
     ]
     mapping = {
         "%s.%s" % (hostname, name): HostnameIPMapping(None, 30, [ip])
         for hostname, ip in in_network_mapping.items()
     }
     extra_mapping = {
         factory.make_string(): HostnameIPMapping(None, 30, ["192.50.0.2"]),
         factory.make_string(): HostnameIPMapping(None, 30, ["192.70.0.2"]),
     }
     mapping.update(extra_mapping)
     self.assertItemsEqual(
         expected, DNSReverseZoneConfig.get_PTR_mapping(mapping, network)
     )
Beispiel #3
0
    def test_bind_write_zones_writes_file(self):
        domain = factory.make_string()
        network = IPNetwork("192.168.0.3/24")
        dns_ip_list = [factory.pick_ip_in_network(network)]
        ip = factory.pick_ip_in_network(network)
        ttl = random.randint(10, 1000)
        forward_zone = DNSForwardZoneConfig(
            domain,
            serial=random.randint(1, 100),
            mapping={
                factory.make_string(): HostnameIPMapping(None, ttl, {ip})
            },
            dns_ip_list=dns_ip_list,
        )
        reverse_zone = DNSReverseZoneConfig(
            domain, serial=random.randint(1, 100), network=network
        )
        actions.bind_write_zones(zones=[forward_zone, reverse_zone])

        forward_file_name = "zone.%s" % domain
        reverse_file_name = "zone.0.168.192.in-addr.arpa"
        expected_files = [
            join(self.dns_conf_dir, forward_file_name),
            join(self.dns_conf_dir, reverse_file_name),
        ]
        self.assertThat(expected_files, AllMatch(FileExists()))
Beispiel #4
0
def make_subnet_config(
    network=None,
    pools=None,
    ipv6=False,
    dhcp_snippets=None,
    disabled_boot_architectures=None,
):
    """Return complete DHCP configuration dict for a subnet."""
    if network is None:
        if ipv6 is True:
            network = factory.make_ipv6_network(
                # The dynamic range must be at least 256 hosts in size.
                slash=random.randint(112, 120))
        else:
            network = factory.make_ipv4_network()
    if pools is None:
        pools = [make_subnet_pool(network)]
    if dhcp_snippets is None:
        dhcp_snippets = make_subnet_dhcp_snippets()
    domain_name = "%s.example.com" % factory.make_name("domain")
    return {
        "subnet":
        str(IPAddress(network.first)),
        "subnet_mask":
        str(network.netmask),
        "subnet_cidr":
        str(network.cidr),
        "broadcast_ip":
        str(network.broadcast),
        "dns_servers": [
            IPAddress(factory.pick_ip_in_network(network)),
            IPAddress(factory.pick_ip_in_network(network)),
        ],
        "ntp_servers": [
            factory.make_ipv4_address(),
            factory.make_ipv6_address(),
            factory.make_name("ntp-server"),
        ],
        "domain_name":
        domain_name,
        "search_list": [domain_name],
        "router_ip":
        factory.pick_ip_in_network(network),
        "pools":
        pools,
        "dhcp_snippets":
        dhcp_snippets,
        "disabled_boot_architectures":
        disabled_boot_architectures if disabled_boot_architectures else [],
    }
Beispiel #5
0
 def test_handles_slash_32_dynamic_range(self):
     target_dir = patch_dns_config_path(self)
     domain = factory.make_string()
     network = factory.make_ipv4_network()
     ipv4_hostname = factory.make_name("host")
     ipv4_ip = factory.pick_ip_in_network(network)
     range_ip = factory.pick_ip_in_network(network, but_not={ipv4_ip})
     ipv6_hostname = factory.make_name("host")
     ipv6_ip = factory.make_ipv6_address()
     ttl = random.randint(10, 300)
     mapping = {
         ipv4_hostname: HostnameIPMapping(None, ttl, {ipv4_ip}),
         ipv6_hostname: HostnameIPMapping(None, ttl, {ipv6_ip}),
     }
     dynamic_range = IPRange(IPAddress(range_ip), IPAddress(range_ip))
     expected_generate_directives = (
         DNSForwardZoneConfig.get_GENERATE_directives(dynamic_range)
     )
     other_mapping = {
         ipv4_hostname: HostnameRRsetMapping(None, {(ttl, "MX", "10 bar")})
     }
     dns_zone_config = DNSForwardZoneConfig(
         domain,
         serial=random.randint(1, 100),
         other_mapping=other_mapping,
         default_ttl=ttl,
         mapping=mapping,
         dynamic_ranges=[dynamic_range],
     )
     dns_zone_config.write_config()
     self.assertThat(
         os.path.join(target_dir, "zone.%s" % domain),
         FileContains(
             matcher=ContainsAll(
                 [
                     "$TTL %d" % ttl,
                     "%s %d IN A %s" % (ipv4_hostname, ttl, ipv4_ip),
                     "%s %d IN AAAA %s" % (ipv6_hostname, ttl, ipv6_ip),
                     "%s %d IN MX 10 bar" % (ipv4_hostname, ttl),
                 ]
                 + [
                     "$GENERATE %s %s IN A %s"
                     % (iterator_values, reverse_dns, hostname)
                     for iterator_values, reverse_dns, hostname in expected_generate_directives
                 ]
             )
         ),
     )
Beispiel #6
0
 def test_ignores_generate_directives_for_v6_dynamic_ranges(self):
     patch_dns_config_path(self)
     domain = factory.make_string()
     network = factory.make_ipv4_network()
     ipv4_hostname = factory.make_name("host")
     ipv4_ip = factory.pick_ip_in_network(network)
     ipv6_hostname = factory.make_name("host")
     ipv6_ip = factory.make_ipv6_address()
     ipv6_network = factory.make_ipv6_network()
     dynamic_range = IPRange(ipv6_network.first, ipv6_network.last)
     ttl = random.randint(10, 300)
     mapping = {
         ipv4_hostname: HostnameIPMapping(None, ttl, {ipv4_ip}),
         ipv6_hostname: HostnameIPMapping(None, ttl, {ipv6_ip}),
     }
     dns_zone_config = DNSForwardZoneConfig(
         domain,
         serial=random.randint(1, 100),
         mapping=mapping,
         default_ttl=ttl,
         dynamic_ranges=[dynamic_range],
     )
     get_generate_directives = self.patch(dns_zone_config,
                                          "get_GENERATE_directives")
     dns_zone_config.write_config()
     self.assertThat(get_generate_directives, MockNotCalled())
Beispiel #7
0
 def test_parse_route_with_proto_and_metric(self):
     network = factory.make_ipv4_network()
     subnet = str(network.cidr)
     gateway = factory.pick_ip_in_network(network)
     interface = factory.make_name("nic")
     proto = factory.make_name("proto")
     metric = random.randint(50, 100)
     route_line = "%s via %s dev %s proto %s metric %d" % (
         subnet,
         gateway,
         interface,
         proto,
         metric,
     )
     self.assertEquals(
         (
             subnet,
             {
                 "via": gateway,
                 "dev": interface,
                 "proto": proto,
                 "metric": metric,
             },
         ),
         _parse_route_definition(route_line),
     )
Beispiel #8
0
 def test_get_ptr_mapping(self):
     name = factory.make_string()
     network = IPNetwork('192.12.0.1/30')
     hosts = {
         factory.make_string(): factory.pick_ip_in_network(network),
         factory.make_string(): factory.pick_ip_in_network(network),
     }
     expected = [(IPAddress(ip).reverse_dns.split('.')[0], 30,
                  '%s.%s.' % (hostname, name))
                 for hostname, ip in hosts.items()]
     mapping = {
         "%s.%s" % (hostname, name): HostnameIPMapping(None, 30, {ip})
         for hostname, ip in hosts.items()
     }
     self.assertItemsEqual(
         expected, DNSReverseZoneConfig.get_PTR_mapping(mapping, network))
Beispiel #9
0
 def make_route_line(self, subnet=None):
     network = factory.make_ipv4_network()
     gateway = factory.pick_ip_in_network(network)
     if subnet is None:
         subnet = str(network.cidr)
     interface = factory.make_name("nic")
     route_line = "%s via %s dev %s" % (subnet, gateway, interface)
     return route_line, {subnet: {"via": gateway, "dev": interface}}
Beispiel #10
0
def make_subnet_config(network=None,
                       pools=None,
                       ipv6=False,
                       dhcp_snippets=None):
    """Return complete DHCP configuration dict for a subnet."""
    if network is None:
        if ipv6 is True:
            network = factory.make_ipv6_network(
                # The dynamic range must be at least 256 hosts in size.
                slash=random.randint(112, 120))
        else:
            network = factory.make_ipv4_network()
    if pools is None:
        pools = [make_subnet_pool(network)]
    if dhcp_snippets is None:
        dhcp_snippets = make_subnet_dhcp_snippets()
    domain_name = '%s.example.com' % factory.make_name('domain')
    return {
        'subnet':
        str(IPAddress(network.first)),
        'subnet_mask':
        str(network.netmask),
        'subnet_cidr':
        str(network.cidr),
        'broadcast_ip':
        str(network.broadcast),
        'dns_servers': [
            IPAddress(factory.pick_ip_in_network(network)),
            IPAddress(factory.pick_ip_in_network(network)),
        ],
        'ntp_servers': [
            factory.make_ipv4_address(),
            factory.make_ipv6_address(),
            factory.make_name("ntp-server"),
        ],
        'domain_name':
        domain_name,
        'search_list': [domain_name],
        'router_ip':
        factory.pick_ip_in_network(network),
        'pools':
        pools,
        'dhcp_snippets':
        dhcp_snippets,
    }
Beispiel #11
0
 def test_parse_route_without_proto_or_metric(self):
     network = factory.make_ipv4_network()
     subnet = str(network.cidr)
     gateway = factory.pick_ip_in_network(network)
     interface = factory.make_name("nic")
     route_line = "%s via %s dev %s" % (subnet, gateway, interface)
     self.assertEquals(
         (subnet, {"via": gateway, "dev": interface}),
         _parse_route_definition(route_line),
     )
Beispiel #12
0
 def test__includes_next_server_in_config_from_all_addresses(self):
     params = make_sample_params(self, ipv6=False)
     subnet = params['shared_networks'][0]['subnets'][0]
     next_server_ip = factory.pick_ip_in_network(
         netaddr.IPNetwork(subnet['subnet_cidr']))
     self.patch(net_utils, 'get_all_interface_addresses').return_value = [
         next_server_ip
     ]
     config_output = config.get_config('dhcpd.conf.template', **params)
     validate_dhcpd_configuration(self, config_output, False)
     self.assertThat(
         config_output, Contains('next-server %s;' % next_server_ip))
Beispiel #13
0
 def test_includes_next_server_in_config_from_interface_addresses(self):
     params = make_sample_params(self, ipv6=False, with_interface=True)
     subnet = params["shared_networks"][0]["subnets"][0]
     next_server_ip = factory.pick_ip_in_network(
         netaddr.IPNetwork(subnet["subnet_cidr"]))
     self.patch(
         net_utils,
         "get_all_addresses_for_interface").return_value = [next_server_ip]
     config_output = config.get_config("dhcpd.conf.template", **params)
     validate_dhcpd_configuration(self, config_output, False)
     self.assertThat(config_output,
                     Contains("next-server %s;" % next_server_ip))
Beispiel #14
0
 def test_write_config_writes_config(self):
     target_dir = patch_dns_config_path(self)
     domain = factory.make_string()
     network = IPNetwork('192.168.0.3/24')
     ip = factory.pick_ip_in_network(network)
     forward_zone = DNSForwardZoneConfig(
         domain, mapping={factory.make_string(): ip})
     reverse_zone = DNSReverseZoneConfig(domain, network=network)
     dnsconfig = DNSConfig((forward_zone, reverse_zone))
     dnsconfig.write_config()
     self.assertThat(
         os.path.join(target_dir, MAAS_NAMED_CONF_NAME),
         FileContains(matcher=ContainsAll([
             'zone.%s' % domain,
             'zone.0.168.192.in-addr.arpa',
             MAAS_NAMED_RNDC_CONF_NAME,
         ])))
Beispiel #15
0
 def test_fields(self):
     domain = factory.make_string()
     serial = random.randint(1, 200)
     hostname = factory.make_string()
     network = factory.make_ipv4_network()
     ip = factory.pick_ip_in_network(network)
     default_ttl = random.randint(10, 300)
     mapping = {hostname: [ip]}
     dns_zone_config = DNSForwardZoneConfig(
         domain, serial=serial, default_ttl=default_ttl, mapping=mapping
     )
     self.assertThat(
         dns_zone_config,
         MatchesStructure.byEquality(
             domain=domain,
             serial=serial,
             _mapping=mapping,
             default_ttl=default_ttl,
         ),
     )
Beispiel #16
0
 def test_writes_dns_zone_config(self):
     target_dir = patch_dns_config_path(self)
     domain = factory.make_string()
     network = factory.make_ipv4_network()
     ipv4_hostname = factory.make_name('host')
     ipv4_ip = factory.pick_ip_in_network(network)
     ipv6_hostname = factory.make_name('host')
     ipv6_ip = factory.make_ipv6_address()
     ttl = random.randint(10, 300)
     mapping = {
         ipv4_hostname: HostnameIPMapping(None, ttl, {ipv4_ip}),
         ipv6_hostname: HostnameIPMapping(None, ttl, {ipv6_ip}),
     }
     expected_generate_directives = (
         DNSForwardZoneConfig.get_GENERATE_directives(network))
     other_mapping = {
         ipv4_hostname: HostnameRRsetMapping(None, {(ttl, 'MX', '10 bar')})
     }
     dns_zone_config = DNSForwardZoneConfig(
         domain,
         serial=random.randint(1, 100),
         other_mapping=other_mapping,
         default_ttl=ttl,
         mapping=mapping,
         dynamic_ranges=[IPRange(network.first, network.last)])
     dns_zone_config.write_config()
     self.assertThat(
         os.path.join(target_dir, 'zone.%s' % domain),
         FileContains(matcher=ContainsAll([
             '$TTL %d' % ttl,
             '%s %d IN A %s' % (ipv4_hostname, ttl, ipv4_ip),
             '%s %d IN AAAA %s' % (ipv6_hostname, ttl, ipv6_ip),
             '%s %d IN MX 10 bar' % (ipv4_hostname, ttl),
         ] + [
             '$GENERATE %s %s IN A %s' %
             (iterator_values, reverse_dns, hostname) for iterator_values,
             reverse_dns, hostname in expected_generate_directives
         ])))
Beispiel #17
0
 def test_pick_ip_in_network_for_ipv6(self):
     # For IPv6, pick_ip_in_network will not consider the very first
     # address in a network because this is reserved for routers.
     network = factory.make_ipv6_network(slash=126)
     ip = factory.pick_ip_in_network(network)
     self.assertTrue(network.first < IPAddress(ip).value <= network.last)
Beispiel #18
0
 def test_pick_ip_in_network_for_ipv4_slash_30(self):
     network = factory.make_ipv4_network(slash=30)
     ip = factory.pick_ip_in_network(network)
     self.assertTrue(network.first < IPAddress(ip).value < network.last)