def test_adds_connected_multiple_racks_ipv6(self): rack1 = factory.make_RackController() factory.make_RegionRackRPCConnection(rack1) rack2 = factory.make_RackController() factory.make_RegionRackRPCConnection(rack2) network = factory.make_ipv6_network() subnet = factory.make_Subnet(cidr=str(network.cidr)) static_ip1 = factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.AUTO, ip=factory.pick_ip_in_Subnet(subnet), subnet=subnet, interface=rack1.get_boot_interface(), ) static_ip2 = factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.AUTO, ip=factory.pick_ip_in_Subnet(subnet), subnet=subnet, interface=rack2.get_boot_interface(), ) domain = get_internal_domain() self.assertEqual(get_resource_name_for_subnet(subnet), domain.resources[0].name) self.assertThat( domain.resources[0].records, MatchesSetwise( Equals( InternalDomainResourseRecord(rrtype="AAAA", rrdata=static_ip1.ip)), Equals( InternalDomainResourseRecord(rrtype="AAAA", rrdata=static_ip2.ip)), ), )
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)
def test_prefers_static_ip_over_dhcp(self): rack = factory.make_RackController() factory.make_RegionRackRPCConnection(rack) nic = rack.get_boot_interface() network = factory.make_ipv4_network() subnet = factory.make_Subnet(cidr=str(network.cidr)) static_ip = factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.AUTO, ip=factory.pick_ip_in_Subnet(subnet), subnet=subnet, interface=nic, ) factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.DHCP, ip=factory.pick_ip_in_Subnet(subnet), subnet=subnet, interface=nic, ) domain = get_internal_domain() self.assertThat(domain.resources, HasLength(1)) self.assertEqual(get_resource_name_for_subnet(subnet), domain.resources[0].name) self.assertEqual( InternalDomainResourseRecord(rrtype="A", rrdata=static_ip.ip), domain.resources[0].records[0], )
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 test__adds_connected_rack_ipv6(self): rack = factory.make_RackController() factory.make_RegionRackRPCConnection(rack) nic = rack.get_boot_interface() network = factory.make_ipv6_network() subnet = factory.make_Subnet(cidr=str(network.cidr)) static_ip = factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.AUTO, ip=factory.pick_ip_in_Subnet(subnet), subnet=subnet, interface=nic) domain = get_internal_domain() self.assertEqual( get_resource_name_for_subnet(subnet), domain.resources[0].name) self.assertEqual( InternalDomainResourseRecord(rrtype='AAAA', rrdata=static_ip.ip), domain.resources[0].records[0])