def test_yields_internal_forward_zones(self): default_domain = Domain.objects.get_default_domain() subnet = factory.make_Subnet(cidr=str(IPNetwork("10/29").cidr)) domains = [] for _ in range(3): record = InternalDomainResourseRecord( rrtype='A', rrdata=factory.pick_ip_in_Subnet(subnet)) resource = InternalDomainResourse( name=factory.make_name('resource'), records=[record]) domain = InternalDomain(name=factory.make_name('domain'), ttl=random.randint(15, 300), resources=[resource]) domains.append(domain) zones = ZoneGenerator([], [subnet], serial=random.randint(0, 65535), internal_domains=domains).as_list() self.assertThat( zones, MatchesSetwise(*[ MatchesAll( forward_zone(domain.name), MatchesStructure(_other_mapping=MatchesDict({ domain.resources[0].name: MatchesStructure(rrset=MatchesSetwise( Equals((domain.ttl, domain.resources[0].records[0].rrtype, domain.resources[0].records[0].rrdata)))) }))) for domain in domains ] + [ reverse_zone(default_domain.name, "10/29"), reverse_zone(default_domain.name, "10/24") ]))
def get_internal_domain(): """Calculate the zone description for the internal domain. This constructs the zone with a resource per subnet that is connected to rack controllers. Each resource gets A and AAAA records for the rack controllers that have a connection to that subnet. Note: Rack controllers that have no registered RPC connections are not included in the calculation. Those rack controllers are dead and no traffic should be directed to them. """ # `connections__isnull` verifies that only rack controllers with atleast # one connection are used in the calculation. controllers = RackController.objects.filter(connections__isnull=False) controllers = controllers.prefetch_related( 'interface_set__ip_addresses__subnet') # Group the IP addresses on controllers by the connected subnets. ips_by_resource = defaultdict(set) for controller in controllers: for interface in controller.interface_set.all(): for ip_address in interface.ip_addresses.all(): if ip_address.ip: resource_name = (get_resource_name_for_subnet( ip_address.subnet)) ips_by_resource[resource_name].add(ip_address.ip) # Map the subnet IP address to the model required for zone generation. resources = [] for resource_name, ip_addresses in ips_by_resource.items(): records = [] for ip_address in ip_addresses: if IPAddress(ip_address).version == 4: records.append( InternalDomainResourseRecord(rrtype='A', rrdata=ip_address)) else: records.append( InternalDomainResourseRecord(rrtype='AAAA', rrdata=ip_address)) resources.append( InternalDomainResourse( name=resource_name, records=records, )) return InternalDomain( name=Config.objects.get_config('maas_internal_domain'), ttl=15, resources=resources)