def test__multiple_ethernet_interfaces_with_dns(self): node = factory.make_Node() vlan = factory.make_VLAN() subnet = factory.make_Subnet(cidr='10.0.0.0/24', gateway_ip='10.0.0.1', dns_servers=['10.0.0.2']) subnet2 = factory.make_Subnet(cidr='10.0.1.0/24', gateway_ip='10.0.1.1', dns_servers=['10.0.1.2']) eth0 = factory.make_Interface(node=node, name='eth0', mac_address="00:01:02:03:04:05", vlan=vlan) eth1 = factory.make_Interface(node=node, name='eth1', mac_address="02:01:02:03:04:05") node.boot_interface = eth0 node.save() factory.make_StaticIPAddress(interface=eth0, subnet=subnet, ip='10.0.0.4', alloc_type=IPADDRESS_TYPE.STICKY) factory.make_StaticIPAddress(interface=eth1, subnet=subnet2, ip='10.0.1.4', alloc_type=IPADDRESS_TYPE.STICKY) # Make sure we know when and where the default DNS server will be used. get_default_dns_servers_mock = self.patch(node, 'get_default_dns_servers') get_default_dns_servers_mock.return_value = ['127.0.0.2'] netplan = self._render_netplan_dict(node) expected_netplan = { 'network': { 'version': 2, 'ethernets': { 'eth0': { 'gateway': '10.0.0.1', 'nameservers': { 'addresses': ['10.0.0.2'] }, 'match': { 'macaddress': '00:01:02:03:04:05' }, 'mtu': 1500, 'set-name': 'eth0', 'addresses': ['10.0.0.4/24'], }, 'eth1': { 'match': { 'macaddress': '02:01:02:03:04:05' }, 'nameservers': { 'addresses': ['10.0.1.2'] }, 'mtu': 1500, 'set-name': 'eth1', 'addresses': ['10.0.1.4/24'], }, }, }, } self.expectThat(netplan, Equals(expected_netplan)) v1 = self._render_v1_dict(node) expected_v1 = { 'network': { 'version': 1, 'config': [{ 'id': 'eth0', 'mac_address': '00:01:02:03:04:05', 'mtu': 1500, 'name': 'eth0', 'subnets': [{ 'address': '10.0.0.4/24', 'dns_nameservers': ['10.0.0.2'], 'gateway': '10.0.0.1', 'type': 'static', }], 'type': 'physical' }, { 'id': 'eth1', 'mac_address': '02:01:02:03:04:05', 'mtu': 1500, 'name': 'eth1', 'subnets': [{ 'address': '10.0.1.4/24', 'dns_nameservers': ['10.0.1.2'], 'type': 'static', }], 'type': 'physical' }, { 'address': ['127.0.0.2'], 'search': ['maas'], 'type': 'nameserver' }], } } self.expectThat(v1, Equals(expected_v1))
def test_associates_known_subnet(self): rack = factory.make_RackController() iface = factory.make_Interface(node=rack) subnet = factory.make_Subnet(cidr="10.0.0.0/8", vlan=iface.vlan) factory.make_Discovery(interface=iface, ip="10.0.0.1") self.assertThat(Discovery.objects.first().subnet, Equals(subnet))
def test__ha__default_dns(self): node = factory.make_Node() mock_get_source_address = self.patch(preseed_network_module, 'get_source_address') mock_get_source_address.return_value = '10.0.0.1' vlan = factory.make_VLAN() r1 = factory.make_RegionRackController(interface=False) mock_get_maas_id = self.patch(server_address_module, 'get_maas_id') mock_get_maas_id.return_value = r1.system_id r2 = factory.make_RegionRackController(interface=False) interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, vlan=vlan, node=r2) subnet = factory.make_Subnet(cidr='10.0.0.0/24', gateway_ip='10.0.0.1', dns_servers=[]) r2_address = factory.make_StaticIPAddress( interface=interface, subnet=subnet, alloc_type=IPADDRESS_TYPE.STICKY) vlan = factory.make_VLAN() factory.make_Subnet(cidr='10.0.1.0/24', gateway_ip='10.0.1.1', dns_servers=[]) node_eth0 = factory.make_Interface(node=node, name='eth0', mac_address="00:01:02:03:04:05", vlan=vlan) node.boot_interface = node_eth0 node.save() factory.make_StaticIPAddress(interface=node_eth0, subnet=subnet, ip='10.0.0.4', alloc_type=IPADDRESS_TYPE.STICKY) # XXX: the netplan (v2) currently doesn't include default DNS servers. # See launchpad bug #1664806. v1 = self._render_v1_dict(node) expected_v1 = { 'network': { 'version': 1, 'config': [{ 'id': 'eth0', 'mac_address': '00:01:02:03:04:05', 'mtu': 1500, 'name': 'eth0', 'subnets': [{ 'address': '10.0.0.4/24', 'gateway': '10.0.0.1', 'type': 'static', }], 'type': 'physical' }, { 'address': ['10.0.0.1', r2_address.ip], 'search': ['maas'], 'type': 'nameserver' }], } } self.expectThat(v1, Equals(expected_v1))
def make_node_with_address(self, space, cidr): node = factory.make_Node() iface = factory.make_Interface(node=node) subnet = factory.make_Subnet(space=space, cidr=cidr) sip = factory.make_StaticIPAddress(interface=iface, subnet=subnet) return node, sip.get_ipaddress()
def test_mac_address_is_stored_normalized_and_loaded(self): interface = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, mac_address=' AA-bb-CC-dd-EE-Ff ') loaded_mac = Interface.objects.get(id=interface.id) self.assertEqual('aa:bb:cc:dd:ee:ff', loaded_mac.mac_address)
def create_interface(self, params=None): if params is None: params = {} return factory.make_Interface(INTERFACE_TYPE.PHYSICAL, **params)
def populate_main(): """Populate the main data all in one transaction.""" admin = factory.make_admin( username="******", password="******", completed_intro=False) # noqa user1, _ = factory.make_user_with_keys( username="******", password="******", completed_intro=False) user2, _ = factory.make_user_with_keys( username="******", password="******", completed_intro=False) # Physical zones. zones = [ factory.make_Zone(name="zone-north"), factory.make_Zone(name="zone-south"), ] # DNS domains. domains = [ Domain.objects.get_default_domain(), factory.make_Domain("sample"), factory.make_Domain("ubnt"), ] # Create the fabrics that will be used by the regions, racks, # machines, and devices. fabric0 = Fabric.objects.get_default_fabric() fabric0_untagged = fabric0.get_default_vlan() fabric0_vlan10 = factory.make_VLAN(fabric=fabric0, vid=10) fabric1 = factory.make_Fabric() fabric1_untagged = fabric1.get_default_vlan() fabric1_vlan42 = factory.make_VLAN(fabric=fabric1, vid=42) empty_fabric = factory.make_Fabric() # noqa # Create some spaces. space_mgmt = factory.make_Space("management") space_storage = factory.make_Space("storage") space_internal = factory.make_Space("internal") space_ipv6_testbed = factory.make_Space("ipv6-testbed") # Subnets used by regions, racks, machines, and devices. subnet_1 = factory.make_Subnet( cidr="172.16.1.0/24", gateway_ip="172.16.1.1", vlan=fabric0_untagged, space=space_mgmt) subnet_2 = factory.make_Subnet( cidr="172.16.2.0/24", gateway_ip="172.16.2.1", vlan=fabric1_untagged, space=space_mgmt) subnet_3 = factory.make_Subnet( cidr="172.16.3.0/24", gateway_ip="172.16.3.1", vlan=fabric0_vlan10, space=space_storage) subnet_4 = factory.make_Subnet( # noqa cidr="172.16.4.0/24", gateway_ip="172.16.4.1", vlan=fabric0_vlan10, space=space_internal) subnet_2001_db8_42 = factory.make_Subnet( # noqa cidr="2001:db8:42::/64", gateway_ip="", vlan=fabric1_vlan42, space=space_ipv6_testbed) ipv4_subnets = [subnet_1, subnet_2, subnet_3, subnet_4] # Static routes on subnets. factory.make_StaticRoute(source=subnet_1, destination=subnet_2) factory.make_StaticRoute(source=subnet_1, destination=subnet_3) factory.make_StaticRoute(source=subnet_1, destination=subnet_4) factory.make_StaticRoute(source=subnet_2, destination=subnet_1) factory.make_StaticRoute(source=subnet_2, destination=subnet_3) factory.make_StaticRoute(source=subnet_2, destination=subnet_4) factory.make_StaticRoute(source=subnet_3, destination=subnet_1) factory.make_StaticRoute(source=subnet_3, destination=subnet_2) factory.make_StaticRoute(source=subnet_3, destination=subnet_4) factory.make_StaticRoute(source=subnet_4, destination=subnet_1) factory.make_StaticRoute(source=subnet_4, destination=subnet_2) factory.make_StaticRoute(source=subnet_4, destination=subnet_3) # Load builtin scripts in the database so we can generate fake results # below. load_builtin_scripts() hostname = gethostname() region_rack = get_one(Node.objects.filter( node_type=NODE_TYPE.REGION_AND_RACK_CONTROLLER, hostname=hostname)) # If "make run" executes before "make sampledata", the rack may have # already registered. if region_rack is None: region_rack = factory.make_Node( node_type=NODE_TYPE.REGION_AND_RACK_CONTROLLER, hostname=hostname, interface=False) # Get list of mac addresses that should be used for the region # rack controller. This will make sure the RegionAdvertisingService # picks the correct region on first start-up and doesn't get multiple. mac_addresses = get_mac_addresses() def get_next_mac(): try: return mac_addresses.pop() except IndexError: return factory.make_mac_address() # Region and rack controller (hostname of dev machine) # eth0 - fabric 0 - untagged # eth1 - fabric 0 - untagged # eth2 - fabric 1 - untagged - 172.16.2.2/24 - static # bond0 - fabric 0 - untagged - 172.16.1.2/24 - static # bond0.10 - fabric 0 - 10 - 172.16.3.2/24 - static eth0 = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth0", node=region_rack, vlan=fabric0_untagged, mac_address=get_next_mac()) eth1 = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth1", node=region_rack, vlan=fabric0_untagged, mac_address=get_next_mac()) eth2 = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth2", node=region_rack, vlan=fabric1_untagged, mac_address=get_next_mac()) bond0 = factory.make_Interface( INTERFACE_TYPE.BOND, name="bond0", node=region_rack, vlan=fabric0_untagged, parents=[eth0, eth1], mac_address=eth0.mac_address) bond0_10 = factory.make_Interface( INTERFACE_TYPE.VLAN, node=region_rack, vlan=fabric0_vlan10, parents=[bond0]) factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.STICKY, ip="172.16.1.2", subnet=subnet_1, interface=bond0) factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.STICKY, ip="172.16.2.2", subnet=subnet_2, interface=eth2) factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.STICKY, ip="172.16.3.2", subnet=subnet_3, interface=bond0_10) fabric0_untagged.primary_rack = region_rack fabric0_untagged.save() fabric1_untagged.primary_rack = region_rack fabric1_untagged.save() fabric0_vlan10.primary_rack = region_rack fabric0_vlan10.save() # Rack controller (happy-rack) # eth0 - fabric 0 - untagged # eth1 - fabric 0 - untagged # eth2 - fabric 1 - untagged - 172.16.2.3/24 - static # bond0 - fabric 0 - untagged - 172.16.1.3/24 - static # bond0.10 - fabric 0 - 10 - 172.16.3.3/24 - static rack = factory.make_Node( node_type=NODE_TYPE.RACK_CONTROLLER, hostname="happy-rack", interface=False) eth0 = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth0", node=rack, vlan=fabric0_untagged) eth1 = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth1", node=rack, vlan=fabric0_untagged) eth2 = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth2", node=rack, vlan=fabric1_untagged) bond0 = factory.make_Interface( INTERFACE_TYPE.BOND, name="bond0", node=rack, vlan=fabric0_untagged, parents=[eth0, eth1]) bond0_10 = factory.make_Interface( INTERFACE_TYPE.VLAN, node=rack, vlan=fabric0_vlan10, parents=[bond0]) factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.STICKY, ip="172.16.1.3", subnet=subnet_1, interface=bond0) factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.STICKY, ip="172.16.2.3", subnet=subnet_2, interface=eth2) factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.STICKY, ip="172.16.3.3", subnet=subnet_3, interface=bond0_10) fabric0_untagged.secondary_rack = rack fabric0_untagged.save() fabric1_untagged.secondary_rack = rack fabric1_untagged.save() fabric0_vlan10.secondary_rack = rack fabric0_vlan10.save() # Region controller (happy-region) # eth0 - fabric 0 - untagged # eth1 - fabric 0 - untagged # eth2 - fabric 1 - untagged - 172.16.2.4/24 - static # bond0 - fabric 0 - untagged - 172.16.1.4/24 - static # bond0.10 - fabric 0 - 10 - 172.16.3.4/24 - static region = factory.make_Node( node_type=NODE_TYPE.REGION_CONTROLLER, hostname="happy-region", interface=False) eth0 = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth0", node=region, vlan=fabric0_untagged) eth1 = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth1", node=region, vlan=fabric0_untagged) eth2 = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth2", node=region, vlan=fabric1_untagged) bond0 = factory.make_Interface( INTERFACE_TYPE.BOND, name="bond0", node=region, vlan=fabric0_untagged, parents=[eth0, eth1]) bond0_10 = factory.make_Interface( INTERFACE_TYPE.VLAN, node=region, vlan=fabric0_vlan10, parents=[bond0]) factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.STICKY, ip="172.16.1.4", subnet=subnet_1, interface=bond0) factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.STICKY, ip="172.16.2.4", subnet=subnet_2, interface=eth2) factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.STICKY, ip="172.16.3.4", subnet=subnet_3, interface=bond0_10) # Create one machine for every status. Each machine has a random interface # and storage configration. node_statuses = [ status for status in map_enum(NODE_STATUS).items() if status not in [ NODE_STATUS.MISSING, NODE_STATUS.RESERVED, NODE_STATUS.RETIRED] ] machines = [] test_scripts = [ script.name for script in Script.objects.filter(script_type=SCRIPT_TYPE.TESTING)] for _, status in node_statuses: owner = None if status in ALLOCATED_NODE_STATUSES: owner = random.choice([admin, user1, user2]) elif status in [ NODE_STATUS.COMMISSIONING, NODE_STATUS.FAILED_RELEASING]: owner = admin machine = factory.make_Node( status=status, owner=owner, zone=random.choice(zones), interface=False, with_boot_disk=False, power_type='manual', domain=random.choice(domains), memory=random.choice([1024, 4096, 8192]), description=random.choice([ '', 'Scheduled for removeal', 'Firmware old', 'Earmarked for Project Fuse in April' ]), cpu_count=random.randint(2, 8)) machine.set_random_hostname() machines.append(machine) # Create random network configuration. RandomInterfaceFactory.create_random(machine) # Add random storage devices and set a random layout. for _ in range(random.randint(1, 5)): factory.make_PhysicalBlockDevice( node=machine, size=random.randint( LARGE_BLOCK_DEVICE, LARGE_BLOCK_DEVICE * 10)) if status in [ NODE_STATUS.READY, NODE_STATUS.ALLOCATED, NODE_STATUS.DEPLOYING, NODE_STATUS.DEPLOYED, NODE_STATUS.FAILED_DEPLOYMENT, NODE_STATUS.RELEASING, NODE_STATUS.FAILED_RELEASING]: machine.set_storage_layout( random.choice([ layout for layout in STORAGE_LAYOUTS.keys() if layout != 'vmfs6' ])) if status != NODE_STATUS.READY: machine._create_acquired_filesystems() # Add a random amount of events. for _ in range(random.randint(25, 100)): factory.make_Event(node=machine) # Add in commissioning and testing results. if status != NODE_STATUS.NEW: for _ in range(0, random.randint(1, 10)): css = ScriptSet.objects.create_commissioning_script_set( machine) scripts = set() for __ in range(1, len(test_scripts)): scripts.add(random.choice(test_scripts)) tss = ScriptSet.objects.create_testing_script_set( machine, list(scripts)) machine.current_commissioning_script_set = css machine.current_testing_script_set = tss machine.save() # Fill in historic results for script_set in machine.scriptset_set.all(): if script_set in [css, tss]: continue for script_result in script_set: # Can't use script_result.store_result as it will try to # process the result and fail on the fake data. script_result.exit_status = random.randint(0, 255) if script_result.exit_status == 0: script_result.status = SCRIPT_STATUS.PASSED else: script_result.status = random.choice(list( SCRIPT_STATUS_FAILED)) script_result.started = factory.make_date() script_result.ended = script_result.started + timedelta( seconds=random.randint(0, 10000)) script_result.stdout = Bin( factory.make_string().encode('utf-8')) script_result.stderr = Bin( factory.make_string().encode('utf-8')) script_result.output = Bin( factory.make_string().encode('utf-8')) script_result.save() # Only add in results in states where commissiong should be completed. if status not in [NODE_STATUS.NEW, NODE_STATUS.COMMISSIONING]: if status == NODE_STATUS.FAILED_COMMISSIONING: exit_status = random.randint(1, 255) script_status = random.choice(list(SCRIPT_STATUS_FAILED)) else: exit_status = 0 script_status = SCRIPT_STATUS.PASSED for script_result in css: # Can't use script_result.store_result as it will try to # process the result and fail on the fake data. script_result.status = script_status script_result.exit_status = exit_status script_result.started = factory.make_date() script_result.ended = script_result.started + timedelta( seconds=random.randint(0, 10000)) script_result.stdout = Bin( factory.make_string().encode('utf-8')) script_result.stderr = Bin( factory.make_string().encode('utf-8')) script_result.output = Bin( factory.make_string().encode('utf-8')) script_result.save() elif status == NODE_STATUS.COMMISSIONING: for script_result in css: script_result.status = random.choice(list( SCRIPT_STATUS_RUNNING_OR_PENDING)) if script_result.status != SCRIPT_STATUS.PENDING: script_result.started = factory.make_date() script_result.save() # Only add in results in states where testing should be completed. if status not in [NODE_STATUS.NEW, NODE_STATUS.TESTING]: if status == NODE_STATUS.FAILED_TESTING: exit_status = random.randint(1, 255) script_status = random.choice(list(SCRIPT_STATUS_FAILED)) else: exit_status = 0 script_status = SCRIPT_STATUS.PASSED for script_result in tss: # Can't use script_result.store_result as it will try to # process the result and fail on the fake data. script_result.status = script_status script_result.exit_status = exit_status script_result.started = factory.make_date() script_result.ended = script_result.started + timedelta( seconds=random.randint(0, 10000)) script_result.stdout = Bin( factory.make_string().encode('utf-8')) script_result.stderr = Bin( factory.make_string().encode('utf-8')) script_result.output = Bin( factory.make_string().encode('utf-8')) script_result.save() elif status == NODE_STATUS.TESTING: for script_result in tss: script_result.status = random.choice(list( SCRIPT_STATUS_RUNNING_OR_PENDING)) if script_result.status != SCRIPT_STATUS.PENDING: script_result.started = factory.make_date() script_result.save() # Add installation results. if status in [ NODE_STATUS.DEPLOYING, NODE_STATUS.DEPLOYED, NODE_STATUS.FAILED_DEPLOYMENT]: script_set = ScriptSet.objects.create_installation_script_set( machine) machine.current_installation_script_set = script_set machine.save() if status == NODE_STATUS.DEPLOYED: for script_result in machine.current_installation_script_set: stdout = factory.make_string().encode('utf-8') script_result.store_result(0, stdout) elif status == NODE_STATUS.FAILED_DEPLOYMENT: for script_result in machine.current_installation_script_set: exit_status = random.randint(1, 255) stdout = factory.make_string().encode('utf-8') stderr = factory.make_string().encode('utf-8') script_result.store_result(exit_status, stdout, stderr) # Add children devices to the deployed machine. if status == NODE_STATUS.DEPLOYED: boot_interface = machine.get_boot_interface() for _ in range(5): device = factory.make_Device( interface=True, domain=machine.domain, parent=machine, vlan=boot_interface.vlan) device.set_random_hostname() RandomInterfaceFactory.assign_ip( device.get_boot_interface(), alloc_type=IPADDRESS_TYPE.STICKY) # Create a few pods to and assign a random set of the machines to the pods. pods = [None] pod_storage_pools = defaultdict(list) machines_in_pods = defaultdict(list) for _ in range(3): subnet = random.choice(ipv4_subnets) ip = factory.pick_ip_in_Subnet(subnet) ip_address = factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.STICKY, ip=ip, subnet=subnet) power_address = "qemu+ssh://ubuntu@%s/system" % ip pod = factory.make_Pod(pod_type='virsh', parameters={ 'power_address': power_address, }, ip_address=ip_address, capabilities=[ Capabilities.DYNAMIC_LOCAL_STORAGE, Capabilities.COMPOSABLE]) for _ in range(3): pool = factory.make_PodStoragePool(pod) pod_storage_pools[pod].append(pool) pod.default_storage_pool = pool pod.save() pods.append(pod) for _ in range(3): subnet = random.choice(ipv4_subnets) ip = factory.pick_ip_in_Subnet(subnet) ip_address = factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.STICKY, ip=ip, subnet=subnet) power_address = "%s" % ip pod = factory.make_Pod(pod_type='rsd', parameters={ 'power_address': power_address, 'power_user': '******', 'power_pass': '******', }, ip_address=ip_address, capabilities=[ Capabilities.DYNAMIC_LOCAL_STORAGE, Capabilities.COMPOSABLE]) for _ in range(3): pool = factory.make_PodStoragePool(pod) pod_storage_pools[pod].append(pool) pod.default_storage_pool = pool pod.save() pods.append(pod) for machine in machines: # Add the machine to the pod if its lucky day! pod = random.choice(pods) if pod is not None: machine.bmc = pod machine.instance_power_parameters = { 'power_id': machine.hostname } machine.save() machines_in_pods[pod].append(machine) # Assign the block devices on the machine to a storage pool. for block_device in machine.physicalblockdevice_set.all(): block_device.storage_pool = ( random.choice(pod_storage_pools[pod])) block_device.save() # Update the pod attributes so that it has more available then used. for pod in pods[1:]: pod.cores = pod.get_used_cores() + random.randint(4, 8) pod.memory = ( pod.get_used_memory() + random.choice([1024, 2048, 4096, 4096 * 4, 4096 * 8])) pod.local_storage = sum( pool.storage for pool in pod_storage_pools[pod]) pod.save() # Create a few devices. for _ in range(10): device = factory.make_Device(interface=True) device.set_random_hostname() # Add some DHCP snippets. # - Global factory.make_DHCPSnippet( name="foo class", description="adds class for vender 'foo'", value=VersionedTextFile.objects.create(data=dedent("""\ class "foo" { match if substring ( option vendor-class-identifier, 0, 3) = "foo"; } """))) factory.make_DHCPSnippet( name="bar class", description="adds class for vender 'bar'", value=VersionedTextFile.objects.create(data=dedent("""\ class "bar" { match if substring ( option vendor-class-identifier, 0, 3) = "bar"; } """)), enabled=False) # - Subnet factory.make_DHCPSnippet( name="600 lease time", description="changes lease time to 600 secs.", value=VersionedTextFile.objects.create(data="default-lease-time 600;"), subnet=subnet_1) factory.make_DHCPSnippet( name="7200 max lease time", description="changes max lease time to 7200 secs.", value=VersionedTextFile.objects.create(data="max-lease-time 7200;"), subnet=subnet_2, enabled=False) # - Node factory.make_DHCPSnippet( name="boot from other server", description="instructs device to boot from other server", value=VersionedTextFile.objects.create(data=dedent("""\ filename "test-boot"; server-name "boot.from.me"; """)), node=device) # Add notifications for admins, users, and each individual user, and for # each notification category. factory.make_Notification( "Attention admins! Core critical! Meltdown imminent! Evacuate " "habitat immediately!", admins=True, category="error") factory.make_Notification( "Dear users, rumours of a core meltdown are unfounded. Please " "return to your home-pods and places of business.", users=True, category="warning") factory.make_Notification( "FREE! For the next 2 hours get FREE blueberry and iodine pellets " "at the nutri-dispensers.", users=True, category="success") for user in User.objects.all(): context = {"name": user.username.capitalize()} factory.make_Notification( "Greetings, {name}! Get away from the habitat for the weekend and " "visit the Mare Nubium with MAAS Tours. Use the code METAL to " "claim a special gift!", user=user, context=context, category="info")
def test_class_start_commissioning_with_interface_param(self): node = factory.make_Node(status=NODE_STATUS.READY, interface=False) commissioning_interface = factory.make_Interface(node=node) testing_interface = factory.make_Interface(node=node) user = factory.make_admin() commissioning_script = factory.make_Script( script_type=SCRIPT_TYPE.COMMISSIONING, parameters={"interface": { "type": "interface" }}, ) testing_script = factory.make_Script( script_type=SCRIPT_TYPE.TESTING, parameters={"interface": { "type": "interface" }}, ) mock_start_commissioning = self.patch_autospec(node, "start_commissioning") commissioning_input = random.choice([ str(commissioning_interface.id), commissioning_interface.name, str(commissioning_interface.mac_address), commissioning_interface.vendor, commissioning_interface.product, "%s:%s" % ( commissioning_interface.vendor, commissioning_interface.product, ), ] + commissioning_interface.tags) testing_input = random.choice([ str(testing_interface.id), testing_interface.name, str(testing_interface.mac_address), testing_interface.vendor, testing_interface.product, "%s:%s" % (testing_interface.vendor, testing_interface.product), ] + testing_interface.tags) form = CommissionForm( instance=node, user=user, data={ "commissioning_scripts": commissioning_script.name, "testing_scripts": testing_script.name, "%s_interface" % commissioning_script.name: commissioning_input, "%s_interface" % testing_script.name: testing_input, }, ) self.assertTrue(form.is_valid(), form.errors) node = form.save() self.assertIsNotNone(node) self.assertThat( mock_start_commissioning, MockCalledOnceWith( user, False, False, False, False, [commissioning_script.name], [testing_script.name], { commissioning_script.name: { "interface": commissioning_input }, testing_script.name: { "interface": testing_input }, }, ), )
def test_mode_is_case_insensitive(self): interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL) form = InterfaceLinkForm( instance=interface, data={"mode": INTERFACE_LINK_TYPE.DHCP.upper()}) self.assertTrue(form.is_valid(), form.errors)
def make_interface(self): # Precache the node. So a database query is not made in the event-loop. interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL) node = interface.node ignore_unused(node) return interface
def test_get_host_interfaces_sriov(self): admin = factory.make_admin() handler = PodHandler(admin, {}, None) node = factory.make_Machine() numa_node0 = node.default_numanode numa_node1 = factory.make_NUMANode(node=node) iface1 = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth0", numa_node=numa_node0, sriov_max_vf=8, ) iface2 = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, name="eth1", numa_node=numa_node1, sriov_max_vf=16, ) pod = self.make_pod_with_hints( pod_type="lxd", host=node, ) vm_machine0 = factory.make_Node(system_id="vm0") factory.make_Interface( INTERFACE_TYPE.PHYSICAL, node=vm_machine0, mac_address="11:11:11:11:11:11", ) vm_machine1 = factory.make_Node(system_id="vm1") factory.make_Interface( INTERFACE_TYPE.PHYSICAL, node=vm_machine1, mac_address="aa:aa:aa:aa:aa:aa", ) factory.make_Interface( INTERFACE_TYPE.PHYSICAL, node=vm_machine1, mac_address="bb:bb:bb:bb:bb:bb", ) vm0 = factory.make_VirtualMachine( bmc=pod, machine=vm_machine0, ) VirtualMachineInterface.objects.create( vm=vm0, mac_address="11:11:11:11:11:11", host_interface=iface1, attachment_type=InterfaceAttachType.SRIOV, ) vm1 = factory.make_VirtualMachine(bmc=pod, machine=vm_machine1) VirtualMachineInterface.objects.create( vm=vm1, mac_address="aa:aa:aa:aa:aa:aa", host_interface=iface1, attachment_type=InterfaceAttachType.SRIOV, ) VirtualMachineInterface.objects.create( vm=vm1, mac_address="bb:bb:bb:bb:bb:bb", host_interface=iface2, attachment_type=InterfaceAttachType.SRIOV, ) result = handler.get({"id": pod.id}) numa1, numa2 = result["resources"]["numa"] self.assertCountEqual(numa1["interfaces"], [iface1.id]) self.assertCountEqual(numa2["interfaces"], [iface2.id]) self.assertCountEqual( result["resources"]["interfaces"], [ { "id": iface1.id, "name": "eth0", "numa_index": 0, "virtual_functions": { "allocated_tracked": 2, "allocated_other": 0, "free": 6, }, }, { "id": iface2.id, "name": "eth1", "numa_index": 1, "virtual_functions": { "allocated_tracked": 1, "allocated_other": 0, "free": 15, }, }, ], )
def make_interface(self, node): return factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
def create_rack_interface(self): rack_controller = factory.make_RackController(interface=False) interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=rack_controller) return rack_controller, interface
def populate_node_with_addresses(node, subnets): iface = factory.make_Interface(node=node) for subnet in subnets: factory.make_StaticIPAddress(interface=iface, subnet=subnet)
def test__alternates_include_one_ip_address_per_region_and_maas_url(self): factory.make_Subnet(cidr='192.168.0.0/24') maas_url = 'http://192.168.0.254/MAAS' rack = factory.make_RackController(url=maas_url) r1 = factory.make_RegionController() factory.make_Interface(node=r1, ip='192.168.0.1') factory.make_Interface(node=r1, ip='192.168.0.254') r2 = factory.make_RegionController() factory.make_Interface(node=r2, ip='192.168.0.2') factory.make_Interface(node=r2, ip='192.168.0.3') r3 = factory.make_RegionController() factory.make_Interface(node=r3, ip='192.168.0.4') factory.make_Interface(node=r3, ip='192.168.0.5') # Make the "current" region controller r1. self.patch(server_address, 'get_maas_id').return_value = r1.system_id region_ips = get_maas_facing_server_addresses(rack, include_alternates=True) self.assertThat( region_ips, Equals([ IPAddress("192.168.0.254"), IPAddress("192.168.0.1"), IPAddress("192.168.0.2"), IPAddress("192.168.0.4"), ]))
def test_sets_subnet_queryset_to_subnets_on_interface_vlan(self): interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL) subnets = [factory.make_Subnet(vlan=interface.vlan) for _ in range(3)] form = InterfaceLinkForm(instance=interface, data={}) self.assertItemsEqual(subnets, form.fields["subnet"].queryset)
def test__alternates_support_ipv4_and_ipv6(self): factory.make_Subnet(cidr='192.168.0.0/24') factory.make_Subnet(cidr='192.168.1.0/24') factory.make_Subnet(cidr='2001:db8::/64') maas_url = 'http://maas.io/MAAS' self.patch_resolve_hostname(["192.168.0.1", "2001:db8::1"]) rack = factory.make_RackController(url=maas_url) r1 = factory.make_RegionController() factory.make_Interface(node=r1, ip='192.168.0.1') factory.make_Interface(node=r1, ip='2001:db8::1') factory.make_Interface(node=r1, ip='192.168.1.254') r2 = factory.make_RegionController() factory.make_Interface(node=r2, ip='192.168.0.2') factory.make_Interface(node=r2, ip='2001:db8::2') r3 = factory.make_RegionController() factory.make_Interface(node=r3, ip='192.168.0.4') factory.make_Interface(node=r3, ip='2001:db8::4') # Make the "current" region controller r1. self.patch(server_address, 'get_maas_id').return_value = r1.system_id region_ips = get_maas_facing_server_addresses(rack, include_alternates=True) self.assertThat( region_ips, Equals([ IPAddress("192.168.0.1"), IPAddress("2001:db8::1"), IPAddress("192.168.0.2"), IPAddress("192.168.0.4"), IPAddress("2001:db8::2"), IPAddress("2001:db8::4"), ]))
def test_AUTO_requires_subnet(self): interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL) form = InterfaceLinkForm(instance=interface, data={"mode": INTERFACE_LINK_TYPE.AUTO}) self.assertFalse(form.is_valid(), form.errors) self.assertEqual({"subnet": ["This field is required."]}, form.errors)
def create_unknown_interface(self, params=None): if params is None: params = {} return factory.make_Interface(INTERFACE_TYPE.UNKNOWN, **params)
def test_requires_id(self): interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL) form = InterfaceUnlinkForm(instance=interface, data={}) self.assertFalse(form.is_valid(), form.errors) self.assertEqual({"id": ["This field is required."]}, form.errors)
def test__yields_routes_with_lowest_metrics_first(self): space = factory.make_Space() # Ensure networks are disjoint but of the same family. networks = self.gen_disjoint_networks() # Create the node for the "left" that has two IP addresses, one in the # null space, one in a non-null space. origin = factory.make_Node(hostname="origin") origin_iface = factory.make_Interface(node=origin, link_connected=False) origin_subnet = factory.make_Subnet(space=space, cidr=next(networks)) origin_subnet_null_space = factory.make_Subnet(space=None, cidr=next(networks)) origin_sip = factory.make_StaticIPAddress(interface=origin_iface, subnet=origin_subnet) origin_sip_null_space = factory.make_StaticIPAddress( interface=origin_iface, subnet=origin_subnet_null_space) # Same subnet, different node. node_same_subnet = factory.make_Node(hostname="same-subnet") sip_same_subnet = factory.make_StaticIPAddress( interface=factory.make_Interface(node=node_same_subnet, link_connected=False), subnet=origin_subnet, ) # Same VLAN, different subnet, different node. node_same_vlan = factory.make_Node(hostname="same-vlan") sip_same_vlan = factory.make_StaticIPAddress( interface=factory.make_Interface(node=node_same_vlan, link_connected=False), subnet=factory.make_Subnet(space=space, vlan=origin_subnet.vlan, cidr=next(networks)), ) # Same space, different VLAN, subnet, and node. node_same_space = factory.make_Node(hostname="same-space") sip_same_space = factory.make_StaticIPAddress( interface=factory.make_Interface(node=node_same_space, link_connected=False), subnet=factory.make_Subnet(space=space, cidr=next(networks)), ) # Null space, different VLAN, subnet, and node. (won't be included) node_null_space = factory.make_Node(hostname="null-space") factory.make_StaticIPAddress( interface=factory.make_Interface(node=node_null_space, link_connected=False), subnet=factory.make_Subnet(space=None, cidr=next(networks)), ) # We'll search for routes between `lefts` and `rights`. lefts = [origin] rights = [ node_same_subnet, node_same_vlan, node_same_space, node_null_space, # Should not be included. ] # This is in order, lowest "metric" first. expected = [ ( origin, origin_sip.get_ipaddress(), node_same_subnet, sip_same_subnet.get_ipaddress(), ), ( origin, origin_sip.get_ipaddress(), node_same_vlan, sip_same_vlan.get_ipaddress(), ), ( origin, origin_sip.get_ipaddress(), node_same_space, sip_same_space.get_ipaddress(), ), ] self.assertThat( find_addresses_between_nodes(lefts, rights), AfterPreprocessing(list, Equals(expected)), ) # Same node, same space, different VLAN and subnet. We did not add # this earlier because its existence allows for a large number of # additional routes between the origin and the other nodes, which # would have obscured the test. origin_sip_2 = factory.make_StaticIPAddress( interface=factory.make_Interface(node=origin, link_connected=False), subnet=factory.make_Subnet(space=space, cidr=next(networks)), ) # Now the first addresses returned are between those addresses we # created on the same node, in no particular order. origin_ips = origin_sip.get_ipaddress(), origin_sip_2.get_ipaddress() expected_mutual = {(origin, ip1, origin, ip2) for ip1, ip2 in product(origin_ips, origin_ips)} # There's a mutual route for the null-space IP address too. expected_mutual.add(( origin, origin_sip_null_space.get_ipaddress(), origin, origin_sip_null_space.get_ipaddress(), )) observed_mutual = takewhile( (lambda route: route[0] == route[2]), # Route is mutual. find_addresses_between_nodes(lefts, [origin, *rights]), ) self.assertItemsEqual(expected_mutual, observed_mutual)
def test_doesnt_require_link_id_if_only_one_gateway_per_family(self): interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL) self.make_ip_family_link(interface, factory.make_ipv4_network()) self.make_ip_family_link(interface, factory.make_ipv6_network()) form = InterfaceSetDefaultGatwayForm(instance=interface, data={}) self.assertTrue(form.is_valid(), form.errors)
def test_django_serializes_MAC_to_JSON(self): interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL) query = Interface.objects.filter(id=interface.id) output = serializers.serialize('json', query) self.assertIn(json.dumps(interface.mac_address.get_raw()), output) self.assertIn('"%s"' % interface.mac_address.get_raw(), output)
def test_request_node_info_by_mac_address_returns_node_for_mac(self): interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL) node, boot_purpose = request_node_info_by_mac_address( interface.mac_address.get_raw()) self.assertEqual(node, interface.node)
def test__alternates_use_consistent_subnet(self): factory.make_Subnet(cidr="192.168.0.0/24") factory.make_Subnet(cidr="192.168.1.0/24") maas_url = "http://192.168.0.1/MAAS" rack = factory.make_RackController(url=maas_url) r1 = factory.make_RegionController() factory.make_Interface(node=r1, ip="192.168.0.1") factory.make_Interface(node=r1, ip="192.168.1.254") r2 = factory.make_RegionController() factory.make_Interface(node=r2, ip="192.168.0.2") factory.make_Interface(node=r2, ip="192.168.1.3") r3 = factory.make_RegionController() factory.make_Interface(node=r3, ip="192.168.0.4") factory.make_Interface(node=r3, ip="192.168.1.5") # Make the "current" region controller r1. self.patch(server_address, "get_maas_id").return_value = r1.system_id region_ips = get_maas_facing_server_addresses(rack, include_alternates=True) self.assertThat( region_ips, Equals([ IPAddress("192.168.0.1"), IPAddress("192.168.0.2"), IPAddress("192.168.0.4"), ]), )
def test_does_not_fail_if_cannot_find_subnet(self): rack = factory.make_RackController() iface = factory.make_Interface(node=rack) factory.make_Discovery(interface=iface, ip="10.0.0.1") self.assertThat(Discovery.objects.first().subnet, Is(None))