def test_make_ipv4_network_returns_network_disjoint_from(self): existing_network = factory.make_ipv4_network() new_network = factory.make_ipv4_network( disjoint_from=[existing_network]) self.assertNotEqual(existing_network, new_network) self.assertNotIn(new_network, existing_network) self.assertNotIn(existing_network, new_network)
def test_round_trips_ipv4_address(self): network = factory.make_ipv4_network() encoded = self.argument.toString(network) self.assertThat(encoded, IsInstance(bytes)) self.assertThat(encoded, HasLength(5)) decoded = self.argument.fromString(encoded) self.assertThat(decoded, Equals(network))
def test_make_ipv4_network_may_overlap_but_not(self): self.patch(factory, 'make_ipv4_address').return_value = IPAddress('10.1.1.0') self.assertEqual( IPNetwork('10.1.1.0/24'), factory.make_ipv4_network(slash=24, but_not=[IPNetwork('10.1.0.0/16')]))
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())
def make_cidrs(self): return frozenset( { str(factory.make_ipv4_network()), str(factory.make_ipv6_network()), } )
def test__adds_tcp_stop(self): cidr = factory.make_ipv4_network() config.write_config([cidr]) matcher = Contains(':inputname, isequal, "imtcp" stop') self.assertThat( "%s/%s" % (self.tmpdir, config.MAAS_SYSLOG_CONF_NAME), FileContains(matcher=matcher))
def test_without_use_peer_proxy(self): cidr = factory.make_ipv4_network() config.write_config([cidr]) with self.proxy_path.open() as proxy_file: lines = [line.strip() for line in proxy_file.readlines()] self.assertNotIn("never_direct allow all", lines) self.assertNotIn("cache_peer", lines)
def test_port_changes_port(self): cidr = factory.make_ipv4_network() port = random.randint(1, 65535) config.write_config([cidr], maas_proxy_port=port) with self.proxy_path.open() as proxy_file: lines = [line.strip() for line in proxy_file.readlines()] self.assertIn("http_port %s" % port, lines)
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), )
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}}
def test_make_ipv4_network_may_overlap_but_not(self): self.patch(factory, "make_ipv4_address").return_value = IPAddress("10.1.1.0") self.assertEqual( IPNetwork("10.1.1.0/24"), factory.make_ipv4_network(slash=24, but_not=[IPNetwork("10.1.0.0/16")]), )
def test_adds_cidr(self): cidr = factory.make_ipv4_network() config.write_config([cidr]) matcher = Contains("acl localnet src %s" % cidr) self.assertThat( "%s/%s" % (self.tmpdir, config.MAAS_PROXY_CONF_NAME), FileContains(matcher=matcher), )
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), )
def test_reverse_config_file_is_world_readable(self): patch_dns_config_path(self) dns_zone_config = DNSReverseZoneConfig( factory.make_string(), serial=random.randint(1, 100), network=factory.make_ipv4_network()) dns_zone_config.write_config() for tgt in [zi.target_path for zi in dns_zone_config.zone_info]: filepath = FilePath(tgt) self.assertTrue(filepath.getPermissions().other.read)
def test_make_ipv4_address_but_not(self): # We want to look for clashes between identical IPs and/or netmasks. # Narrow down the range of randomness so we have a decent chance of # triggering a clash, but not so far that we'll loop for very long # trying to find a network we haven't seen already. self.patch(factory, "make_ipv4_address", lambda: "10.%d.0.0" % randint(1, 200)) networks = [] for _ in range(100): networks.append(factory.make_ipv4_network(but_not=networks)) self.assertEqual(len(networks), len(set(networks)))
def test_returns_256_entries_for_slash_16_network(self): network = IPNetwork(factory.make_ipv4_network(slash=16)) reverse = IPAddress(network.first).reverse_dns.split(".")[2:-1] reverse = ".".join(reverse) domain = factory.make_string() expected_generate_directives = self.get_expected_generate_directives( network, domain) directives = DNSReverseZoneConfig.get_GENERATE_directives( network, domain, DomainInfo(network, reverse)) self.expectThat(directives, HasLength(256)) self.assertItemsEqual(expected_generate_directives, directives)
def test_peer_proxies(self): cidr = factory.make_ipv4_network() peer_proxies = ["http://example.com:8000/", "http://other.com:8001/"] config.write_config([cidr], peer_proxies=peer_proxies) cache_peer1_line = ( "cache_peer example.com parent 8000 0 no-query default") cache_peer2_line = ( "cache_peer other.com parent 8001 0 no-query default") with self.proxy_path.open() as proxy_file: lines = [line.strip() for line in proxy_file.readlines()] self.assertIn("never_direct allow all", lines) self.assertIn(cache_peer1_line, lines) self.assertIn(cache_peer2_line, lines)
def test_bind_write_configuration_writes_file(self): domain = factory.make_string() zones = [ DNSReverseZoneConfig(domain, serial=random.randint(1, 100), network=factory.make_ipv4_network()), DNSReverseZoneConfig(domain, serial=random.randint(1, 100), network=factory.make_ipv6_network()), ] actions.bind_write_configuration(zones=zones, trusted_networks=[]) self.assertThat(os.path.join(self.dns_conf_dir, MAAS_NAMED_CONF_NAME), FileExists())
def test_writes_dns_zone_config_with_NS_record(self): target_dir = patch_dns_config_path(self) network = factory.make_ipv4_network() ns_host_name = factory.make_name("ns") dns_zone_config = DNSReverseZoneConfig(factory.make_string(), serial=random.randint(1, 100), ns_host_name=ns_host_name, network=network) dns_zone_config.write_config() for zone_name in [zi.zone_name for zi in dns_zone_config.zone_info]: self.assertThat( os.path.join(target_dir, 'zone.%s' % zone_name), FileContains(matcher=Contains('30 IN NS %s.' % ns_host_name)))
def test_fields(self): domain = factory.make_string() serial = random.randint(1, 200) network = factory.make_ipv4_network() dns_zone_config = DNSReverseZoneConfig(domain, serial=serial, network=network) self.assertThat( dns_zone_config, MatchesStructure.byEquality(domain=domain, serial=serial, _network=network), )
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 [], }
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 ] ) ), )
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, }
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, ), )
def test_bind_write_configuration_writes_file_with_acl(self): trusted_networks = [ factory.make_ipv4_network(), factory.make_ipv6_network(), ] actions.bind_write_configuration(zones=[], trusted_networks=trusted_networks) expected_file = os.path.join(self.dns_conf_dir, MAAS_NAMED_CONF_NAME) self.assertThat(expected_file, FileExists()) expected_content = dedent("""\ acl "trusted" { %s; %s; localnets; localhost; }; """) expected_content %= tuple(trusted_networks) self.assertThat(expected_file, FileContains(matcher=Contains(expected_content)))
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 ])))
def test_with_prefer_v4_proxy_True(self): cidr = factory.make_ipv4_network() config.write_config([cidr], prefer_v4_proxy=True) with self.proxy_path.open() as proxy_file: lines = [line.strip() for line in proxy_file.readlines()] self.assertIn("dns_v4_first on", lines)
def test_make_ipv4_network(self): network = factory.make_ipv4_network() self.assertIsInstance(network, IPNetwork)
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)