def test_get(self): user = factory.make_User() handler = VLANHandler(user, {}) vlan = factory.make_VLAN(space=factory.make_Space()) for _ in range(3): factory.make_Subnet(vlan=vlan) for _ in range(3): node = factory.make_Node(interface=True) interface = node.get_boot_interface() interface.vlan = vlan interface.save() self.assertEqual(self.dehydrate_vlan(vlan), handler.get({"id": vlan.id}))
def test_update_turns_dhcp_on(self): vlan = factory.make_VLAN() factory.make_ipv4_Subnet_with_IPRanges(vlan=vlan) rack = factory.make_RackController(vlan=vlan) vlan.primary_rack = rack vlan.save() form = VLANForm(instance=reload_object(vlan), data={ "dhcp_on": "true", }) self.assertTrue(form.is_valid(), form.errors) form.save() vlan = reload_object(vlan) self.assertTrue(vlan.dhcp_on)
def test__configure_dhcp_with_duplicate_raises(self): user = factory.make_admin() handler = VLANHandler(user, {}) vlan = factory.make_VLAN() rack = factory.make_RackController() factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=rack, vlan=vlan) factory.make_ipv4_Subnet_with_IPRanges(vlan=vlan) with ExpectedException(HandlerValidationError): handler.configure_dhcp({ "id": vlan.id, "controllers": [rack.system_id, rack.system_id] })
def test__error_for_unknown_vid_in_default_fabric(self): fabric = factory.make_Fabric() vlan = factory.make_VLAN(fabric=fabric) network = factory.make_ip4_or_6_network() cidr = str(network.cidr) form = SubnetForm({ "cidr": cidr, "vid": vlan.vid, }) self.assertFalse(form.is_valid(), form.errors) self.assertEqual( {"vid": ["No VLAN with vid %s in default fabric." % vlan.vid]}, form.errors)
def test_interfaces_are_reconnected_when_vlan_is_deleted(self): node = factory.make_Node() vlan = factory.make_VLAN() fabric = vlan.fabric interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node, vlan=vlan) vlan.delete() reconnected_interfaces = PhysicalInterface.objects.filter( id=interface.id) self.assertItemsEqual([interface], reconnected_interfaces) reconnected_interface = reconnected_interfaces[0] self.assertEqual(reconnected_interface.vlan, fabric.get_default_vlan())
def test_update_setting_secondary_fails_when_primary_dead(self): vlan = factory.make_VLAN() rack = factory.make_RackController(vlan=vlan) vlan.primary_rack = rack vlan.save() service = Service.objects.get(node=rack, name="rackd") service.status = SERVICE_STATUS.DEAD service.save() second_rack = factory.make_RackController(vlan=vlan) form = VLANForm( instance=vlan, data={"secondary_rack": second_rack.system_id} ) self.assertFalse(form.is_valid())
def test_DELETE_cannot_delete_if_primary_rack(self): self.become_admin() vlan = factory.make_VLAN() rack = factory.make_RackController(vlan=vlan) vlan.dhcp_on = True vlan.primary_rack = rack vlan.save() response = self.client.delete(self.get_rack_uri(rack)) self.assertEqual( http.client.BAD_REQUEST, response.status_code, explain_unexpected_response(http.client.BAD_REQUEST, response), )
def test_configure_dhcp_with_one_parameter(self): user = factory.make_admin() handler = VLANHandler(user, {}, None) vlan = factory.make_VLAN() rack = factory.make_RackController() factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=rack, vlan=vlan) factory.make_ipv4_Subnet_with_IPRanges(vlan=vlan) handler.configure_dhcp( {"id": vlan.id, "controllers": [rack.system_id]} ) vlan = reload_object(vlan) self.assertThat(vlan.dhcp_on, Equals(True)) self.assertThat(vlan.primary_rack, Equals(rack))
def test_update_blank_primary_sets_to_secondary(self): vlan = factory.make_VLAN() primary_rack = factory.make_RackController(vlan=vlan) secondary_rack = factory.make_RackController(vlan=vlan) vlan.primary_rack = primary_rack vlan.secondary_rack = secondary_rack vlan.save() form = VLANForm(instance=reload_object(vlan), data={"primary_rack": ""}) self.assertTrue(form.is_valid(), form.errors) form.save() vlan = reload_object(vlan) self.assertEqual(secondary_rack, vlan.primary_rack) self.assertEqual(None, vlan.secondary_rack)
def test_read(self): class_type = factory.make_name("class") fabric = factory.make_Fabric(class_type=class_type) for vid in range(1, 4): factory.make_VLAN(fabric=fabric, vid=vid).id uri = get_fabric_uri(fabric) response = self.client.get(uri) self.assertEqual(http.client.OK, response.status_code, response.content) parsed_fabric = json_load_bytes(response.content) self.assertThat( parsed_fabric, ContainsDict({ "id": Equals(fabric.id), "name": Equals(fabric.get_name()), "class_type": Equals(class_type), }), ) self.assertItemsEqual( [vlan.id for vlan in fabric.vlan_set.all()], [vlan["id"] for vlan in parsed_fabric["vlans"]], )
def test__non_superuser_reloads_user(self): user = factory.make_admin() handler = VLANHandler(user, {}) user.is_superuser = False user.save() rack = factory.make_RackController() vlan = factory.make_VLAN() factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=rack, vlan=vlan) vlan.dhcp_on = True vlan.primary_rack = rack vlan.save() factory.make_ipv4_Subnet_with_IPRanges(vlan=vlan) with ExpectedException(AssertionError, "Permission denied."): handler.configure_dhcp({"id": vlan.id, "controllers": []})
def test_update_with_undefined_space_clears_space(self): self.become_admin() fabric = factory.make_Fabric() vlan = factory.make_VLAN(fabric=fabric, space=RANDOM) self.assertThat(vlan.space, Not(Is(None))) uri = get_vlan_uri(vlan, fabric) response = self.client.put(uri, {"space": Space.UNDEFINED}) self.assertEqual(http.client.OK, response.status_code, response.content) parsed_vlan = json.loads( response.content.decode(settings.DEFAULT_CHARSET)) vlan = reload_object(vlan) self.assertThat(vlan.space, Is(None)) self.assertThat(parsed_vlan["space"], Equals(Space.UNDEFINED))
def test__creates_subnet_name_equal_to_cidr(self): vlan = factory.make_VLAN() network = factory.make_ip4_or_6_network() cidr = str(network.cidr) form = SubnetForm({ "vlan": vlan.id, "cidr": cidr, }) self.assertTrue(form.is_valid(), dict(form.errors)) subnet = form.save() self.assertThat( subnet, MatchesStructure.byEquality(name=cidr, vlan=vlan, cidr=cidr))
def test_creates_subnet_in_fabric_with_vid(self): fabric = factory.make_Fabric() vlan = factory.make_VLAN(fabric=fabric) network = factory.make_ip4_or_6_network() cidr = str(network.cidr) form = SubnetForm( {"cidr": cidr, "fabric": fabric.id, "vid": vlan.vid, "vlan": None} ) self.assertTrue(form.is_valid(), dict(form.errors)) subnet = form.save() self.assertThat( subnet, MatchesStructure.byEquality(name=cidr, cidr=cidr, vlan=vlan), )
def test__error_for_vlan_not_in_fabric(self): fabric = factory.make_Fabric() vlan = factory.make_VLAN(fabric=Fabric.objects.get_default_fabric()) network = factory.make_ip4_or_6_network() cidr = str(network.cidr) form = SubnetForm({ "cidr": cidr, "fabric": fabric.id, "vlan": vlan.id, }) self.assertFalse(form.is_valid(), dict(form.errors)) self.assertEqual( {"vlan": ["VLAN %s is not in fabric %s." % (vlan, fabric)]}, dict(form.errors))
def test__error_for_unknown_vid_in_fabric(self): fabric = factory.make_Fabric() vlan = factory.make_VLAN(fabric=Fabric.objects.get_default_fabric()) network = factory.make_ip4_or_6_network() cidr = str(network.cidr) form = SubnetForm({"cidr": cidr, "fabric": fabric.id, "vid": vlan.vid}) self.assertFalse(form.is_valid(), dict(form.errors)) self.assertEqual( { "vid": ["No VLAN with vid %s in fabric %s." % (vlan.vid, fabric)] }, dict(form.errors), )
def test_update_setting_secondary_allowed_when_primary_on(self): vlan = factory.make_VLAN() rack = factory.make_RackController(vlan=vlan) vlan.primary_rack = rack vlan.save() service = Service.objects.get(node=rack, name="rackd") service.status = SERVICE_STATUS.RUNNING service.save() second_rack = factory.make_RackController(vlan=vlan) form = VLANForm(instance=vlan, data={"secondary_rack": second_rack.system_id}) self.assertTrue(form.is_valid()) form.save() vlan = reload_object(vlan) self.assertEqual(second_rack, vlan.secondary_rack)
def test_pod_DELETE_delete_without_force(self): self.become_admin() vlan = factory.make_VLAN() subnet = factory.make_Subnet(vlan=vlan) region = factory.make_Node_with_Interface_on_Subnet( node_type=NODE_TYPE.REGION_CONTROLLER, subnet=subnet, vlan=vlan) ip = factory.make_StaticIPAddress( interface=region.interface_set.first()) factory.make_Pod(ip_address=ip) mock_async_delete = self.patch(Pod, "async_delete") response = self.client.delete(self.get_region_uri(region)) self.assertEqual( http.client.BAD_REQUEST, response.status_code, explain_unexpected_response(http.client.BAD_REQUEST, response)) self.assertThat(mock_async_delete, MockNotCalled())
def test__creates_subnet_in_default_fabric_with_vid(self): vlan = factory.make_VLAN(fabric=Fabric.objects.get_default_fabric()) network = factory.make_ip4_or_6_network() cidr = str(network.cidr) form = SubnetForm({ "cidr": cidr, "vid": vlan.vid, "vlan": None, }) self.assertTrue(form.is_valid(), form.errors) subnet = form.save() self.assertThat( subnet, MatchesStructure.byEquality(name=cidr, cidr=cidr, vlan=vlan))
def test_DELETE_force_not_required_for_pod_region_rack(self): self.become_admin() vlan = factory.make_VLAN() factory.make_Subnet(vlan=vlan) rack = factory.make_RegionRackController(vlan=vlan) ip = factory.make_StaticIPAddress(interface=rack.interface_set.first()) factory.make_Pod(ip_address=ip) mock_async_delete = self.patch(Pod, "async_delete") response = self.client.delete(self.get_region_uri(rack), QUERY_STRING=urlencode({'force': 'true'}, doseq=True)) self.assertEqual( http.client.NO_CONTENT, response.status_code, explain_unexpected_response(http.client.NO_CONTENT, response)) self.assertThat(mock_async_delete, MockNotCalled())
def test_configure_dhcp_with_no_parameters_disables_dhcp(self): user = factory.make_admin() handler = VLANHandler(user, {}, None) rack = factory.make_RackController() vlan = factory.make_VLAN() factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=rack, vlan=vlan) vlan.dhcp_on = True vlan.primary_rack = rack vlan.save() factory.make_ipv4_Subnet_with_IPRanges(vlan=vlan) handler.configure_dhcp({"id": vlan.id, "controllers": []}) vlan = reload_object(vlan) self.assertThat(vlan.dhcp_on, Equals(False)) self.assertThat(vlan.primary_rack, Is(None)) self.assertThat(vlan.secondary_rack, Is(None))
def test__changes_boot_interface_vlan_not_relayed_through_rack(self): rack_controller = factory.make_RackController() rack_fabric = factory.make_Fabric() rack_vlan = rack_fabric.get_default_vlan() rack_interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=rack_controller, vlan=rack_vlan) rack_subnet = factory.make_Subnet(vlan=rack_vlan) rack_ip = factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.STICKY, subnet=rack_subnet, interface=rack_interface) other_vlan = factory.make_VLAN() relay_vlan = factory.make_VLAN(relay_vlan=other_vlan) remote_ip = factory.make_ip_address() node = self.make_node(vlan=relay_vlan) mac = node.get_boot_interface().mac_address get_config(rack_controller.system_id, rack_ip.ip, remote_ip, mac=mac, query_count=27) self.assertEqual(rack_vlan, reload_object(node).get_boot_interface().vlan)
def test_create(self): self.become_admin() subnet_name = factory.make_name("subnet") vlan = factory.make_VLAN() network = factory.make_ip4_or_6_network() cidr = str(network.cidr) rdns_mode = factory.pick_choice(RDNS_MODE_CHOICES) allow_proxy = factory.pick_bool() allow_dns = factory.pick_bool() gateway_ip = factory.pick_ip_in_network(network) managed = factory.pick_bool() dns_servers = [] for _ in range(2): dns_servers.append( factory.pick_ip_in_network( network, but_not=[gateway_ip] + dns_servers ) ) uri = get_subnets_uri() response = self.client.post( uri, { "name": subnet_name, "vlan": vlan.id, "cidr": cidr, "gateway_ip": gateway_ip, "dns_servers": ",".join(dns_servers), "rdns_mode": rdns_mode, "allow_proxy": allow_proxy, "allow_dns": allow_dns, "managed": managed, }, ) self.assertEqual( http.client.OK, response.status_code, response.content ) created_subnet = json.loads( response.content.decode(settings.DEFAULT_CHARSET) ) self.assertEqual(subnet_name, created_subnet["name"]) self.assertEqual(vlan.vid, created_subnet["vlan"]["vid"]) self.assertEqual(cidr, created_subnet["cidr"]) self.assertEqual(gateway_ip, created_subnet["gateway_ip"]) self.assertEqual(dns_servers, created_subnet["dns_servers"]) self.assertEqual(rdns_mode, created_subnet["rdns_mode"]) self.assertEqual(allow_proxy, created_subnet["allow_proxy"]) self.assertEqual(allow_dns, created_subnet["allow_dns"]) self.assertEqual(managed, created_subnet["managed"])
def test_pod_DELETE_delete_without_force(self): self.become_admin() vlan = factory.make_VLAN() factory.make_Subnet(vlan=vlan) rack = factory.make_RackController(vlan=vlan) ip = factory.make_StaticIPAddress(interface=rack.interface_set.first()) factory.make_Pod(ip_address=ip) vlan.dhcp_on = True vlan.primary_rack = rack vlan.save() mock_async_delete = self.patch(Pod, "async_delete") response = self.client.delete(self.get_rack_uri(rack)) self.assertEqual( http.client.BAD_REQUEST, response.status_code, explain_unexpected_response(http.client.BAD_REQUEST, response)) self.assertThat(mock_async_delete, MockNotCalled())
def test_DELETE_delete_with_force(self): self.become_admin() vlan = factory.make_VLAN() subnet = factory.make_Subnet(vlan=vlan) region = factory.make_Node_with_Interface_on_Subnet( node_type=NODE_TYPE.REGION_CONTROLLER, subnet=subnet, vlan=vlan) ip = factory.make_StaticIPAddress( interface=region.interface_set.first()) factory.make_Pod(ip_address=ip) mock_async_delete = self.patch(Pod, "async_delete") response = self.client.delete(self.get_region_uri(region), QUERY_STRING=urlencode({'force': 'true'}, doseq=True)) self.assertEqual( http.client.NO_CONTENT, response.status_code, explain_unexpected_response(http.client.NO_CONTENT, response)) self.assertThat(mock_async_delete, MockCallsMatch(call()))
def test__has_enlistment_preseed_url_internal_domain(self): rack_controller = factory.make_RackController() vlan = factory.make_VLAN(dhcp_on=True, primary_rack=rack_controller) subnet = factory.make_Subnet(vlan=vlan) subnet.dns_servers = [] subnet.save() local_ip = factory.pick_ip_in_Subnet(subnet) remote_ip = factory.make_ip_address() factory.make_default_ubuntu_release_bootable() observed_config = get_config( rack_controller.system_id, local_ip, remote_ip) self.assertEqual( compose_enlistment_preseed_url( base_url='http://%s.%s:5248/' % ( get_resource_name_for_subnet(subnet), Config.objects.get_config('maas_internal_domain'))), observed_config["preseed_url"])
def test_get_with_pod_host_determines_vlan_boot_status(self): admin = factory.make_admin() handler = PodHandler(admin, {}, None) vlan = factory.make_VLAN(dhcp_on=False) subnet = factory.make_Subnet(vlan=vlan) node = factory.make_Node_with_Interface_on_Subnet(subnet=subnet) ip = factory.make_StaticIPAddress(interface=node.boot_interface, subnet=subnet) pod = self.make_pod_with_hints(ip_address=ip) expected_data = handler.full_dehydrate(pod) result = handler.get({"id": pod.id}) self.assertItemsEqual(expected_data.keys(), result.keys()) for key in expected_data: self.assertEqual(expected_data[key], result[key], key) self.assertThat(result, Equals(expected_data)) self.assertThat(result["attached_vlans"], Equals([subnet.vlan_id])) self.assertThat(result["boot_vlans"], Equals([]))
def test_update_with_fabric(self): self.become_admin() fabric = factory.make_Fabric() vlan = factory.make_VLAN(fabric=fabric) uri = get_vlan_uri(vlan, fabric) new_name = factory.make_name("vlan") new_vid = random.randint(1, 1000) response = self.client.put(uri, {"name": new_name, "vid": new_vid}) self.assertEqual(http.client.OK, response.status_code, response.content) parsed_vlan = json.loads( response.content.decode(settings.DEFAULT_CHARSET)) vlan = reload_object(vlan) self.assertEqual(new_name, parsed_vlan["name"]) self.assertEqual(new_name, vlan.name) self.assertEqual(new_vid, parsed_vlan["vid"]) self.assertEqual(new_vid, vlan.vid)
def test_includes_vlan_objects(self): space = factory.make_Space() vlan = factory.make_VLAN(space=space) uri = get_space_uri(space) response = self.client.get(uri) self.assertEqual(http.client.OK, response.status_code, response.content) parsed_space = json.loads( response.content.decode(settings.DEFAULT_CHARSET)) parsed_vlan = parsed_space['vlans'][0] self.assertThat( parsed_vlan, ContainsDict({ "id": Equals(vlan.id), "vid": Equals(vlan.vid), "fabric_id": Equals(vlan.fabric_id), }))
def test_read_without_space_returns_undefined_space(self): vlan = factory.make_VLAN(space=None) uri = get_vlan_uri(vlan, vlan.fabric) response = self.client.get(uri) self.assertEqual(http.client.OK, response.status_code, response.content) parsed_vlan = json.loads( response.content.decode(settings.DEFAULT_CHARSET)) self.assertThat( parsed_vlan, ContainsDict({ "id": Equals(vlan.id), "name": Equals(vlan.get_name()), "vid": Equals(vlan.vid), "space": Equals(Space.UNDEFINED), "resource_uri": Equals(get_vlan_uri(vlan)), }))