def test__renders_expected_output(self): # Force it to have a domain name in the middle of two others. This # will confirm that sorting is working correctly. factory.make_Domain('aaa') domain = factory.make_Domain('bbb') factory.make_Domain('ccc') node = factory.make_Node_with_Interface_on_Subnet(interface_count=2, domain=domain) for iface in node.interface_set.filter(enabled=True): factory.make_StaticIPAddress(interface=iface, subnet=iface.vlan.subnet_set.first()) iface.params = { "mtu": random.randint(600, 1400), "accept_ra": factory.pick_bool(), "autoconf": factory.pick_bool(), } iface.save() extra_interface = node.interface_set.all()[1] sip = factory.make_StaticIPAddress(alloc_type=IPADDRESS_TYPE.STICKY, ip="", subnet=None, interface=extra_interface) sip.subnet = None sip.save() factory.make_Interface(node=node) net_config = self.collect_interface_config(node) net_config += self.collect_dns_config(node) config = compose_curtin_network_config(node) self.assertNetworkConfig(net_config, config)
def get_curtin_yaml_config(request, node): """Return the curtin configration for the node.""" osystem = node.get_osystem() release = node.get_distro_series() main_config = get_curtin_config(request, node) cloud_config = compose_curtin_cloud_config(request, node) archive_config = compose_curtin_archive_config(request, node) reporter_config = compose_curtin_maas_reporter(request, node) swap_config = compose_curtin_swap_preseed(node) kernel_config = compose_curtin_kernel_preseed(node) verbose_config = compose_curtin_verbose_preseed() network_yaml_settings = get_network_yaml_settings(osystem, release) network_config = compose_curtin_network_config( node, version=network_yaml_settings.version, source_routing=network_yaml_settings.source_routing, ) if osystem not in ["ubuntu", "ubuntu-core", "centos", "rhel", "windows"]: maaslog.warning( "%s: Custom network configuration is not supported on '%s' " "('%s'). It is only supported on Ubuntu, Ubuntu-Core, CentOS, " "RHEL, and Windows. Please verify that this image supports custom " "network configuration." % (node.hostname, osystem, release)) if curtin_supports_custom_storage(): if osystem in ["windows", "ubuntu-core", "esxi"]: # Windows, ubuntu-core, and ESXi do not support custom storage. # Custom storage is still passed to allow Curtin to correctly # select the boot device. # # This also requires Curtin support. See (LP:1640301). If Curtin # doesn't support it, the storage config is not passed for # backwards compatibility. supports_custom_storage = curtin_supports_custom_storage_for_dd() elif osystem != "ubuntu": # CentOS/RHEL storage is now natively supported by Curtin. Other # GNU/Linux distributions may work as well. If Curtin lacks support # don't send storage configuration for backwards compatibility. supports_custom_storage = curtin_supports_centos_curthook() else: supports_custom_storage = True else: # Curtin has supported custom storage for Ubuntu since # 0.1.0~bzr275-0ubuntu1. supports_custom_storage = False if supports_custom_storage: storage_config = compose_curtin_storage_config(node) else: storage_config = [] maaslog.warning( "%s: cannot deploy '%s' ('%s') with custom storage config; " "missing support from Curtin. Default to flat storage layout." % (node.hostname, node.osystem, node.distro_series)) return (storage_config + archive_config + reporter_config + network_config + swap_config + kernel_config + verbose_config + cloud_config + [main_config])
def test__renders_expected_output(self): node = factory.make_Node_with_Interface_on_Subnet(interface_count=1) interfaces = node.interface_set.all() vlan_iface = factory.make_Interface(iftype=INTERFACE_TYPE.VLAN, node=node, parents=interfaces) subnet = factory.make_Subnet(vlan=vlan_iface.vlan) factory.make_StaticIPAddress(interface=vlan_iface, subnet=subnet) net_config = self.collect_interface_config(node, filter="physical") net_config += self.collect_interface_config(node, filter="vlan") net_config += self.collect_dns_config(node) config = compose_curtin_network_config(node) self.assertNetworkConfig(net_config, config)
def test__renders_expected_output(self): node = factory.make_Node_with_Interface_on_Subnet( interface_count=2) for iface in node.interface_set.filter(enabled=True): subnet = iface.vlan.subnet_set.first() factory.make_StaticRoute(source=subnet) factory.make_StaticIPAddress( interface=iface, subnet=subnet) net_config = self.collect_interface_config(node) net_config += self.collectRoutesConfig(node) net_config += self.collectDNSConfig(node) config = compose_curtin_network_config(node) self.assertNetworkConfig(net_config, config)
def get_curtin_yaml_config(node, default_region_ip=None): """Return the curtin configration for the node.""" main_config = get_curtin_config(node) cloud_config = compose_curtin_cloud_config(node) archive_config = compose_curtin_archive_config(node) reporter_config = compose_curtin_maas_reporter(node) swap_config = compose_curtin_swap_preseed(node) kernel_config = compose_curtin_kernel_preseed(node) verbose_config = compose_curtin_verbose_preseed() supports_custom_storage = True # Get the storage configration if curtin supports custom storage. if not curtin_supports_custom_storage(): maaslog.error( "%s: cannot deploy with custom storage config; missing support " "from curtin." % node.hostname) supports_custom_storage = False network_config = compose_curtin_network_config(node) if node.osystem != "ubuntu": maaslog.info("%s: custom storage options are only supported on " "Ubuntu. Using flat storage layout." % node.hostname) supports_custom_storage = False if (node.osystem == "windows" and curtin_supports_custom_storage_for_dd()): # Windows does not support custom storage, however we still pass # the storage config to ensure that curtin correctly selects the # boot device as the root device. # # This also requires curtin support. See (LP:1640301). supports_custom_storage = True if node.osystem == "custom": maaslog.info( "%s: deploying custom image '%s' with custom networking options. " "Please verify that this image supports custom network " "configuration." % (node.hostname, node.distro_series)) if supports_custom_storage: storage_config = compose_curtin_storage_config(node) else: storage_config = [] return (storage_config + [main_config] + archive_config + reporter_config + network_config + swap_config + kernel_config + verbose_config + cloud_config)
def test__renders_expected_output(self): node = factory.make_Node_with_Interface_on_Subnet(interface_count=2) interfaces = list(node.interface_set.all()) vlan = node.interface_set.first().vlan bond_iface = factory.make_Interface(iftype=INTERFACE_TYPE.BOND, node=node, vlan=vlan, parents=interfaces) bond_iface.params = { "bond_mode": "balance-rr", } bond_iface.save() factory.make_StaticIPAddress(interface=bond_iface, alloc_type=IPADDRESS_TYPE.STICKY, subnet=bond_iface.vlan.subnet_set.first()) net_config = self.collect_interface_config(node, filter="physical") net_config += self.collect_interface_config(node, filter="bond") net_config += self.collect_dns_config(node) config = compose_curtin_network_config(node) self.assertNetworkConfig(net_config, config)
def test__renders_expected_output(self): node = factory.make_Node_with_Interface_on_Subnet() boot_interface = node.get_boot_interface() vlan = boot_interface.vlan mac_address = factory.make_mac_address() bridge_iface = factory.make_Interface( iftype=INTERFACE_TYPE.BRIDGE, node=node, vlan=vlan, parents=[boot_interface], mac_address=mac_address) bridge_iface.params = { "bridge_fd": 0, "bridge_stp": True, } bridge_iface.save() factory.make_StaticIPAddress( interface=bridge_iface, alloc_type=IPADDRESS_TYPE.STICKY, subnet=bridge_iface.vlan.subnet_set.first()) net_config = self.collect_interface_config(node, filter="physical") net_config += self.collect_interface_config(node, filter="bridge") net_config += self.collectDNSConfig(node) config = compose_curtin_network_config(node) self.assertNetworkConfig(net_config, config)
def test__dhcp_configurations_rendered(self): node = factory.make_Node_with_Interface_on_Subnet( ip_version=self.ip_version) iface = node.interface_set.first() subnet = iface.vlan.subnet_set.first() factory.make_StaticIPAddress(ip=None, alloc_type=IPADDRESS_TYPE.DHCP, interface=iface, subnet=subnet) # Patch resolve_hostname() to return the appropriate network version # IP address for MAAS hostname. resolve_hostname = self.patch(maasserver.server_address, "resolve_hostname") if self.ip_version == 4: resolve_hostname.return_value = {IPAddress("127.0.0.1")} else: resolve_hostname.return_value = {IPAddress("::1")} config = compose_curtin_network_config(node) config_yaml = yaml.safe_load(config[0]) self.assertThat( config_yaml['network']['config'][0]['subnets'][0]['type'], Equals('dhcp' + str(IPNetwork(subnet.cidr).version)))
def test__renders_expected_output(self): node = factory.make_Node_with_Interface_on_Subnet( interface_count=2) phys_ifaces = list(node.interface_set.all()) phys_vlan = node.interface_set.first().vlan bond_iface = factory.make_Interface(iftype=INTERFACE_TYPE.BOND, node=node, vlan=phys_vlan, parents=phys_ifaces) bond_iface.params = { "bond_mode": "balance-rr", } bond_iface.save() vlan_iface = factory.make_Interface( iftype=INTERFACE_TYPE.VLAN, node=node, parents=[bond_iface]) subnet = factory.make_Subnet(vlan=vlan_iface.vlan) factory.make_StaticIPAddress(interface=vlan_iface, subnet=subnet) net_config = self.collect_interface_config(node, filter="physical") net_config += self.collect_interface_config(node, filter="bond") net_config += self.collect_interface_config(node, filter="vlan") net_config += self.collectDNSConfig(node) config = compose_curtin_network_config(node) self.assertNetworkConfig(net_config, config)