def test_prefers_closest_addresses(self): subnet4 = factory.make_Subnet(version=4) subnet6 = factory.make_Subnet(version=6) # Separate subnets but sharing the VLAN, hence routable. subnet4v = factory.make_Subnet(version=4, vlan=subnet4.vlan) subnet6v = factory.make_Subnet(version=6, vlan=subnet6.vlan) # Create a node with an address in the first two subnets... node = self.make_node() populate_node_with_addresses(node, {subnet4, subnet6}) # ... and a server with an address in every subnet. server = self.make_server() populate_node_with_addresses( server, {subnet4, subnet6, subnet4v, subnet6v} ) # The NTP server addresses chosen will be those that are "closest" to # the node, and same-subnet wins in this over same-VLAN. No additional # preference is made between IPv4 or IPv6, hence we allow for either. preferred_subnets = subnet4, subnet6 preferred_networks = IPSet( subnet.get_ipnetwork() for subnet in preferred_subnets ) servers = get_servers_for(node) self.assertThat(servers, Not(HasLength(0))) self.assertThat(preferred_networks, ContainsAll(servers))
def generate_ntp_configuration(node): """Generate cloud-init configuration for NTP servers. cloud-init supports:: ntp: pools: - 0.mypool.pool.ntp.org - 1.myotherpool.pool.ntp.org servers: - 102.10.10.10 - ntp.ubuntu.com MAAS assumes that IP addresses are "servers" and hostnames/FQDNs "pools". """ ntp_servers = ntp.get_servers_for(node) if len(ntp_servers) >= 1: # Separate out IP addresses from the rest. addrs, other = set(), set() for ntp_server in map(normalise_address, ntp_servers): bucket = addrs if isinstance(ntp_server, IPAddress) else other bucket.add(ntp_server) servers = [addr.format() for addr in sorted(addrs)] pools = sorted(other) # Hostnames and FQDNs only. yield "ntp", {"servers": servers, "pools": pools}
def test_yields_boot_rack_addresses_when_machine_has_booted(self): machine = factory.make_Machine() address = factory.make_StaticIPAddress( interface=factory.make_Interface(node=machine)) rack_primary = factory.make_RackController() rack_primary_address = factory.make_StaticIPAddress( interface=factory.make_Interface(node=rack_primary), subnet=address.subnet, ) rack_secondary = factory.make_RackController() rack_secondary_address = factory.make_StaticIPAddress( interface=factory.make_Interface(node=rack_secondary), subnet=address.subnet, ) rack_other = factory.make_RackController() rack_other_address = factory.make_StaticIPAddress( # noqa interface=factory.make_Interface(node=rack_other), subnet=address.subnet, ) vlan = address.subnet.vlan vlan.primary_rack = rack_primary vlan.secondary_rack = rack_secondary vlan.dhcp_on = True vlan.save() servers = get_servers_for(machine) self.assertThat( servers, IsSetOfServers( {rack_primary_address.ip, rack_secondary_address.ip}), )
def _getConfiguration(self): """Return NTP server configuration. The configuration object returned is comparable with previous and subsequently obtained configuration objects, allowing this service to determine whether a change needs to be applied to the NTP server. """ try: this_region = RegionController.objects.get_running_controller() except RegionController.DoesNotExist: # Treat this as a transient error. references = ntp.get_servers_for(None) peers = ntp.get_peers_for(None) else: references = ntp.get_servers_for(this_region) peers = ntp.get_peers_for(this_region) return _Configuration(references, peers)
def get_time_configuration(system_id): """Get settings to use for configuring NTP for the given node. :param system_id: system_id of node. :return: See `GetTimeConfiguration`. """ try: node = Node.objects.get(system_id=system_id) except Node.DoesNotExist: raise NoSuchNode.from_system_id(system_id) else: return { "servers": ntp.get_servers_for(node), "peers": ntp.get_peers_for(node), }
def test_yields_rack_addresses(self): device = factory.make_Device() address = factory.make_StaticIPAddress( interface=factory.make_Interface(node=device)) rack1 = factory.make_RackController() rack1_address = factory.make_StaticIPAddress( interface=factory.make_Interface(node=rack1), subnet=address.subnet) rack2 = factory.make_RackController() rack2_address = factory.make_StaticIPAddress( interface=factory.make_Interface(node=rack2), subnet=address.subnet) servers = get_servers_for(device) self.assertThat(servers, IsSetOfServers({rack1_address.ip, rack2_address.ip}))
def test_yields_rack_addresses_before_first_boot(self): machine = factory.make_Machine() machine.boot_cluster_ip = None machine.save() address = factory.make_StaticIPAddress( interface=factory.make_Interface(node=machine)) rack1 = factory.make_RackController() rack1_address = factory.make_StaticIPAddress( interface=factory.make_Interface(node=rack1), subnet=address.subnet) rack2 = factory.make_RackController() rack2_address = factory.make_StaticIPAddress( interface=factory.make_Interface(node=rack2), subnet=address.subnet) servers = get_servers_for(machine) self.assertThat(servers, IsSetOfServers({rack1_address.ip, rack2_address.ip}))
def test_yields_region_addresses(self): Config.objects.set_config("ntp_external_only", False) rack = factory.make_RackController() address = factory.make_StaticIPAddress( interface=factory.make_Interface(node=rack)) region1 = factory.make_RegionController() region1_address = factory.make_StaticIPAddress( interface=factory.make_Interface(node=region1), subnet=address.subnet, ) region2 = factory.make_RegionController() region2_address = factory.make_StaticIPAddress( interface=factory.make_Interface(node=region2), subnet=address.subnet, ) servers = get_servers_for(rack) self.assertThat( servers, IsSetOfServers({region1_address.ip, region2_address.ip}))
def test_yields_nothing_when_no_ntp_servers_defined(self): Config.objects.set_config("ntp_servers", "") servers = get_servers_for(node=self.make_node()) self.assertThat(servers, IsEmptySet)
def test_yields_all_ntp_servers_when_defined(self): ntp_servers = factory.make_hostname(), factory.make_hostname() Config.objects.set_config("ntp_servers", " ".join(ntp_servers)) servers = get_servers_for(node=self.make_node()) self.assertThat(servers, IsSetOfServers(ntp_servers))