def test_get_static_mapping(self): name = factory.getRandomString() network = IPNetwork('192.12.0.1/30') dns_zone_config = DNSReverseZoneConfig(name, network=network) self.assertItemsEqual( [ ('0', '%s.' % generated_hostname('192.12.0.0', name)), ('1', '%s.' % generated_hostname('192.12.0.1', name)), ('2', '%s.' % generated_hostname('192.12.0.2', name)), ('3', '%s.' % generated_hostname('192.12.0.3', name)), ], dns_zone_config.get_static_mapping(), )
def test_get_static_mapping_multiple_networks(self): name = factory.getRandomString() networks = IPNetwork('11.11.11.11/31'), IPNetwork('22.22.22.22/31') dns_ip = factory.getRandomIPInNetwork(networks[0]) dns_zone_config = DNSForwardZoneConfig( name, networks=networks, dns_ip=dns_ip) self.assertItemsEqual( [ ('%s.' % name, dns_ip), (generated_hostname('11.11.11.10'), '11.11.11.10'), (generated_hostname('11.11.11.11'), '11.11.11.11'), (generated_hostname('22.22.22.22'), '22.22.22.22'), (generated_hostname('22.22.22.23'), '22.22.22.23'), ], dns_zone_config.get_static_mapping(), )
def test_get_static_mapping(self): name = factory.getRandomString() network = IPNetwork('192.12.0.1/30') dns_ip = factory.getRandomIPInNetwork(network) dns_zone_config = DNSForwardZoneConfig( name, networks=[network], dns_ip=dns_ip) self.assertItemsEqual( [ ('%s.' % name, dns_ip), (generated_hostname('192.12.0.0'), '192.12.0.0'), (generated_hostname('192.12.0.1'), '192.12.0.1'), (generated_hostname('192.12.0.2'), '192.12.0.2'), (generated_hostname('192.12.0.3'), '192.12.0.3'), ], dns_zone_config.get_static_mapping(), )
def test_add_nodegroup_creates_DNS_zone(self): self.patch(settings, "DNS_CONNECT", True) network = IPNetwork('192.168.7.1/24') ip = factory.getRandomIPInNetwork(network) nodegroup = factory.make_node_group( network=network, status=NODEGROUP_STATUS.ACCEPTED, management=NODEGROUPINTERFACE_MANAGEMENT.DHCP_AND_DNS) self.assertDNSMatches(generated_hostname(ip), nodegroup.name, ip)
def test_writes_dns_zone_config(self): target_dir = self.make_dir() self.patch(DNSForwardZoneConfig, 'target_dir', target_dir) domain = factory.getRandomString() hostname = factory.getRandomString() network = factory.getRandomNetwork() ip = factory.getRandomIPInNetwork(network) dns_zone_config = DNSForwardZoneConfig( domain, serial=random.randint(1, 100), mapping={hostname: ip}, networks=[network]) dns_zone_config.write_config() self.assertThat( os.path.join(target_dir, 'zone.%s' % domain), FileContains( matcher=ContainsAll( [ '%s IN CNAME %s' % (hostname, generated_hostname(ip)), '%s IN A %s' % (generated_hostname(ip), ip), ])))
def get_static_mapping(self): """Return the reverse generated mapping: (shortened) ip->fqdn. The reverse generated mapping is the mapping between the IP addresses and the generated hostnames for all the possible IP addresses in zone. """ byte_num = 4 - self.network.netmask.words.count(255) return ((shortened_reversed_ip(ip, byte_num), '%s.%s.' % (generated_hostname(ip), self.domain)) for ip in self.network)
def test_delete_nodegroup_disables_DNS_zone(self): self.patch(settings, "DNS_CONNECT", True) network = IPNetwork('192.168.7.1/24') ip = factory.getRandomIPInNetwork(network) nodegroup = factory.make_node_group( network=network, status=NODEGROUP_STATUS.ACCEPTED, management=NODEGROUPINTERFACE_MANAGEMENT.DHCP_AND_DNS) nodegroup.delete() self.assertEqual([''], self.dig_resolve(generated_hostname(ip))) self.assertEqual([''], self.dig_reverse_resolve(ip))
def get_static_mapping(self): """Return a generator with the mapping fqdn->ip for the generated ips. The generated mapping is the mapping between the generated hostnames and the IP addresses for all the possible IP addresses in zone. Note that we return a list of tuples instead of a dictionary in order to be able to return a generator. """ ips = imap(unicode, chain.from_iterable(self.networks)) static_mapping = ((generated_hostname(ip), ip) for ip in ips) # Add A record for the name server's IP. return chain([('%s.' % self.domain, self.dns_ip)], static_mapping)
def get_static_mapping(self): """Return a generator with the mapping fqdn->ip for the generated ips. The generated mapping is the mapping between the generated hostnames and the IP addresses for all the possible IP addresses in zone. Note that we return a list of tuples instead of a dictionary in order to be able to return a generator. """ ips = imap(unicode, chain.from_iterable(self.networks)) static_mapping = ((generated_hostname(ip), ip) for ip in ips) # Add A record for the name server's IP. return chain([('%s.' % self.domain, self.dns_ip)], static_mapping)
def get_static_mapping(self): """Return the reverse generated mapping: (shortened) ip->fqdn. The reverse generated mapping is the mapping between the IP addresses and the generated hostnames for all the possible IP addresses in zone. """ byte_num = 4 - self.network.netmask.words.count(255) return ( (shortened_reversed_ip(ip, byte_num), '%s.%s.' % (generated_hostname(ip), self.domain)) for ip in self.network )
def get_cname_mapping(self): """Return a generator with the mapping: hostname->generated hostname. The mapping only contains hosts for which the two host names differ. :return: A generator of tuples: (host name, generated host name). """ # We filter out cases where the two host names are identical: it # would be wrong to define a CNAME that maps to itself. for hostname, ip in self.mapping.items(): generated_name = generated_hostname(ip) if generated_name != hostname: yield (hostname, generated_name)
def get_cname_mapping(self): """Return a generator with the mapping: hostname->generated hostname. The mapping only contains hosts for which the two host names differ. :return: A generator of tuples: (host name, generated host name). """ # We filter out cases where the two host names are identical: it # would be wrong to define a CNAME that maps to itself. for hostname, ip in self.mapping.items(): generated_name = generated_hostname(ip) if generated_name != hostname: yield (hostname, generated_name)
def test_writes_reverse_dns_zone_config(self): target_dir = self.make_dir() self.patch(DNSReverseZoneConfig, 'target_dir', target_dir) domain = factory.getRandomString() network = IPNetwork('192.168.0.1/22') dns_zone_config = DNSReverseZoneConfig( domain, serial=random.randint(1, 100), network=network) dns_zone_config.write_config() reverse_file_name = 'zone.168.192.in-addr.arpa' expected = Contains( '10.0 IN PTR %s' % generated_hostname('192.168.0.10')) self.assertThat( os.path.join(target_dir, reverse_file_name), FileContains(matcher=expected))
def test_edit_nodegroupinterface_updates_DNS_zone(self): self.patch(settings, "DNS_CONNECT", True) old_network = IPNetwork('192.168.7.1/24') old_ip = factory.getRandomIPInNetwork(old_network) nodegroup = factory.make_node_group( network=old_network, status=NODEGROUP_STATUS.ACCEPTED, management=NODEGROUPINTERFACE_MANAGEMENT.DHCP_AND_DNS) interface = nodegroup.get_managed_interface() # Edit nodegroup's network information to '192.168.44.1/24' interface.ip = '192.168.44.7' interface.router_ip = '192.168.44.14' interface.broadcast_ip = '192.168.44.255' interface.netmask = '255.255.255.0' interface.ip_range_low = '192.168.44.0' interface.ip_range_high = '192.168.44.255' interface.save() ip = factory.getRandomIPInNetwork(IPNetwork('192.168.44.1/24')) # The ip from the old network does not resolve anymore. self.assertEqual([''], self.dig_resolve(generated_hostname(old_ip))) self.assertEqual([''], self.dig_reverse_resolve(old_ip)) # The ip from the new network resolves. self.assertDNSMatches(generated_hostname(ip), nodegroup.name, ip)
def test_forward_zone_get_cname_mapping_skips_identity(self): # We don't write cname records to map host names to themselves. # Without this, a node would get an invalid cname record upon # enlistment. zone = factory.make_name('zone') network = IPNetwork('10.250.99.0/24') ip = factory.getRandomIPInNetwork(network) generated_name = generated_hostname(ip) dns_zone_config = DNSForwardZoneConfig( zone, networks=[network], dns_ip=factory.getRandomIPInNetwork(network), mapping={generated_name: ip}) self.assertNotIn( generated_name, dict(dns_zone_config.get_cname_mapping()))
def assertDNSMatches(self, hostname, domain, ip): fqdn = "%s.%s" % (hostname, domain) autogenerated_hostname = '%s.' % generated_hostname(ip, domain) forward_lookup_result = self.dig_resolve(fqdn) if '%s.' % fqdn == autogenerated_hostname: # If the fqdn is an autogenerated hostname, it resolves to the IP # address (A record). expected_results = [ip] else: # If the fqdn is a custom hostname, it resolves to the # autogenerated hostname (CNAME record) and the IP address # (A record). expected_results = [autogenerated_hostname, ip] self.assertEqual( expected_results, forward_lookup_result, "Failed to resolve '%s' (results: '%s')." % (fqdn, ','.join(forward_lookup_result))) # A reverse lookup on the IP returns the autogenerated # hostname. reverse_lookup_result = self.dig_reverse_resolve(ip) self.assertEqual([autogenerated_hostname], reverse_lookup_result, "Failed to reverse resolve '%s' (results: '%s')." % (fqdn, ','.join(reverse_lookup_result)))
def test_generated_hostname_accepts_IPAddress(self): address = IPAddress("12.34.56.78") self.assertEqual("12-34-56-78", generated_hostname(address))
def test_generated_hostname_returns_hostname(self): self.assertEqual( '192-168-0-1', generated_hostname('192.168.0.1'))
def test_generated_hostname_accepts_IPAddress(self): address = IPAddress("12.34.56.78") self.assertEqual("12-34-56-78", generated_hostname(address))
def test_generated_hostname_returns_hostname_plus_domain(self): domain = factory.getRandomString() self.assertEqual('192-168-0-1.%s' % domain, generated_hostname('192.168.0.1', domain))
def test_generated_hostname_returns_hostname(self): self.assertEqual('192-168-0-1', generated_hostname('192.168.0.1'))
def test_generated_hostname_returns_hostname_plus_domain(self): domain = factory.getRandomString() self.assertEqual( '192-168-0-1.%s' % domain, generated_hostname('192.168.0.1', domain))