def test_list_ignores_devices_with_parents(self): owner = factory.make_User() handler = DeviceHandler(owner, {}, None) device = self.make_device_with_ip_address(owner=owner) # Create a node. factory.make_Node(owner=owner) self.assertItemsEqual( [self.dehydrate_device(device, owner, for_list=True)], handler.list({}), )
def test_create_raises_validation_error_for_missing_macs(self): user = factory.make_User() handler = DeviceHandler(user, {}) params = { "hostname": factory.make_name("hostname"), } error = self.assertRaises(HandlerValidationError, handler.create, params) self.assertThat(error.message_dict, Equals({'mac_addresses': ['This field is required.']}))
def test_get_object_returns_device_if_super_user(self): admin = factory.make_admin() owner = factory.make_User() device = self.make_device_with_ip_address(owner=owner) handler = DeviceHandler(admin, {}) self.assertEqual( device.system_id, handler.get_object({ "system_id": device.system_id }).system_id)
def test_get_object_returns_node_if_owner(self): owner = factory.make_User() device = self.make_device_with_ip_address(owner=owner) handler = DeviceHandler(owner, {}, None) self.assertEqual( device.system_id, handler.get_object({ "system_id": device.system_id }).system_id, )
def test_delete_interface_non_admin(self): user = factory.make_User() node = factory.make_Node(owner=user, node_type=NODE_TYPE.DEVICE) handler = DeviceHandler(user, {}, None) interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node) handler.delete_interface({ "system_id": node.system_id, "interface_id": interface.id }) self.assertIsNone(reload_object(interface))
def test_list_returns_devices_only_viewable_by_user(self): user = factory.make_User() # Create another user. factory.make_User() device = self.make_device_with_ip_address(owner=user) # Create another device not ownered by user. self.make_device_with_ip_address() handler = DeviceHandler(user, {}) self.assertItemsEqual([ self.dehydrate_device(device, user, for_list=True), ], handler.list({}))
def test_update_owned_with_rbac(self): self.useFixture(RBACEnabled()) user = factory.make_User(is_local=False) node = factory.make_Node(owner=user, node_type=NODE_TYPE.DEVICE) handler = DeviceHandler(user, {}, None) new_hostname = factory.make_name("hostname") updated_node = handler.update({ "system_id": node.system_id, 'hostname': new_hostname }) self.assertEqual(updated_node['hostname'], new_hostname)
def test_action_performs_action(self): user = factory.make_admin() request = HttpRequest() request.user = user device = factory.make_Node(owner=user, node_type=NODE_TYPE.DEVICE) handler = DeviceHandler(user, {}, request) handler.action({ "request": request, "system_id": device.system_id, "action": "delete", }) self.assertIsNone(reload_object(device))
def test_not_available_action_raises_error(self): user = factory.make_User() device = self.make_device_with_ip_address(owner=user) handler = DeviceHandler(user, {}, None) self.assertRaises( NodeActionError, handler.action, { "system_id": device.system_id, "action": "unknown" }, )
def test_list_ignores_nodes(self): owner = factory.make_User() handler = DeviceHandler(owner, {}) device = self.make_device_with_ip_address(owner=owner) # Create a device with parent. node = factory.make_Node(owner=owner) device_with_parent = self.make_device_with_ip_address(owner=owner) device_with_parent.parent = node device_with_parent.save() self.assertItemsEqual( [self.dehydrate_device(device, owner, for_list=True)], handler.list({}))
def test_create_copes_with_mac_addresses_of_different_case(self): user = factory.make_User() handler = DeviceHandler(user, {}) mac = factory.make_mac_address() created_device = handler.create({ "hostname": factory.make_name("hostname"), "primary_mac": mac.lower(), # Lowercase. "interfaces": [{ "mac": mac.upper(), # Uppercase. "ip_assignment": DEVICE_IP_ASSIGNMENT_TYPE.DYNAMIC, }], }) self.assertThat(created_device["primary_mac"], Equals(mac))
def test_unlink_subnet(self): user = factory.make_admin() node = factory.make_Node(node_type=NODE_TYPE.DEVICE) handler = DeviceHandler(user, {}) interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node) link_ip = factory.make_StaticIPAddress( alloc_type=IPADDRESS_TYPE.AUTO, ip="", interface=interface) handler.delete_interface({ "system_id": node.system_id, "interface_id": interface.id, "link_id": link_ip.id, }) self.assertIsNone(reload_object(link_ip))
def test_create_copes_with_mac_addresses_of_different_forms(self): user = factory.make_User() handler = DeviceHandler(user, {}) mac = factory.make_mac_address(delimiter=":") created_device = handler.create({ "hostname": factory.make_name("hostname"), "primary_mac": mac, # Colons. "interfaces": [{ "mac": mac.replace(":", "-"), # Hyphens. "ip_assignment": DEVICE_IP_ASSIGNMENT_TYPE.DYNAMIC, }], }) self.assertThat(created_device["primary_mac"], Equals(mac))
def test_create_interface_raises_validation_error_for_missing_macs(self): user = factory.make_User() handler = DeviceHandler(user, {}) device = factory.make_Device(owner=user) params = { "system_id": device.system_id, } error = self.assertRaises( HandlerValidationError, handler.create_interface, params) self.assertThat(error.message_dict, Equals( {'mac_address': [ 'This field is required.', 'This field cannot be blank.']}))
def test_action_performs_action_passing_extra(self): user = factory.make_admin() device = self.make_device_with_ip_address(owner=user) zone = factory.make_Zone() handler = DeviceHandler(user, {}) handler.action({ "system_id": device.system_id, "action": "set-zone", "extra": { "zone_id": zone.id, }}) device = reload_object(device) self.expectThat(device.zone, Equals(zone))
def test_update_updates_node_non_admin_not_update_own(self): user1 = factory.make_User() user2 = factory.make_User() handler = DeviceHandler(user1, {}, None) node = factory.make_Node(owner=user2, interface=True, node_type=NODE_TYPE.DEVICE) node_data = self.dehydrate_device(node, user1) new_zone = factory.make_Zone() new_hostname = factory.make_name("hostname") node_data["hostname"] = new_hostname node_data["zone"] = {"name": new_zone.name} self.assertRaises(HandlerDoesNotExistError, handler.update, node_data)
def test_update_owned_with_rbac(self): rbac = self.useFixture(RBACEnabled()) user = factory.make_User(is_local=False) rbac.store.allow(user.username, factory.make_ResourcePool(), "admin-machines") node = factory.make_Node(owner=user, node_type=NODE_TYPE.DEVICE) handler = DeviceHandler(user, {}, None) new_hostname = factory.make_name("hostname") updated_node = handler.update({ "system_id": node.system_id, "hostname": new_hostname }) self.assertEqual(updated_node["hostname"], new_hostname)
def test_create_creates_device_with_static_and_external_ip(self): user = factory.make_User() handler = DeviceHandler(user, {}) hostname = factory.make_name("hostname") subnet = factory.make_Subnet() mac_static = factory.make_mac_address() static_ip_address = factory.pick_ip_in_Subnet(subnet) mac_external = factory.make_mac_address() external_ip_address = factory.make_ipv4_address() created_device = handler.create({ "hostname": hostname, "primary_mac": mac_static, "extra_macs": [ mac_external ], "interfaces": [ { "mac": mac_static, "ip_assignment": DEVICE_IP_ASSIGNMENT_TYPE.STATIC, "subnet": subnet.id, "ip_address": static_ip_address, }, { "mac": mac_external, "ip_assignment": DEVICE_IP_ASSIGNMENT_TYPE.EXTERNAL, "ip_address": external_ip_address, }, ], }) self.expectThat( created_device["primary_mac"], Equals(mac_static)) self.expectThat( created_device["extra_macs"], Equals([mac_external])) self.expectThat( created_device["ip_assignment"], Equals(DEVICE_IP_ASSIGNMENT_TYPE.STATIC)) self.expectThat( created_device["ip_address"], Equals(static_ip_address)) static_interface = Interface.objects.get(mac_address=MAC(mac_static)) observed_subnet = static_interface.ip_addresses.first().subnet self.expectThat( observed_subnet, Equals(subnet), "Static assignment to the subnet was not created.") self.expectThat( StaticIPAddress.objects.filter(ip=static_ip_address).count(), Equals(1), "Static StaticIPAddress was not created.") self.expectThat( StaticIPAddress.objects.filter(ip=external_ip_address).count(), Equals(1), "External StaticIPAddress was not created.")
def test_create_interface_creates_with_dynamic_ip_assignment(self): user = factory.make_User() handler = DeviceHandler(user, {}) device = factory.make_Device(owner=user) mac = factory.make_mac_address() updated_device = handler.create_interface({ "system_id": device.system_id, "mac_address": mac, "ip_assignment": DEVICE_IP_ASSIGNMENT_TYPE.DYNAMIC, }) self.expectThat(updated_device["primary_mac"], Equals(mac)) self.expectThat( updated_device["ip_assignment"], Equals(DEVICE_IP_ASSIGNMENT_TYPE.DYNAMIC))
def test_update_updates_node(self): user = factory.make_admin() handler = DeviceHandler(user, {}) node = factory.make_Node(interface=True, node_type=NODE_TYPE.DEVICE) node_data = self.dehydrate_device(node, user) new_zone = factory.make_Zone() new_hostname = factory.make_name("hostname") node_data["hostname"] = new_hostname node_data["zone"] = { "name": new_zone.name, } updated_node = handler.update(node_data) self.assertEqual(updated_node["hostname"], new_hostname) self.assertEqual(updated_node["zone"]["id"], new_zone.id)
def test_create_interface_creates_interface(self): user = factory.make_admin() node = factory.make_Node(interface=False, node_type=NODE_TYPE.DEVICE) handler = DeviceHandler(user, {}) name = factory.make_name("eth") mac_address = factory.make_mac_address() handler.create_interface({ "system_id": node.system_id, "name": name, "mac_address": mac_address, "ip_assignment": DEVICE_IP_ASSIGNMENT_TYPE.DYNAMIC, }) self.assertEqual( 1, node.interface_set.count(), "Should have one interface on the node.")
def test_get_num_queries_is_the_expected_number(self): owner = factory.make_User() handler = DeviceHandler(owner, {}) device = self.make_device_with_ip_address( owner=owner, ip_assignment=DEVICE_IP_ASSIGNMENT_TYPE.STATIC) queries, _ = count_queries(handler.get, {"system_id": device.system_id}) # This check is to notify the developer that a change was made that # affects the number of queries performed when doing a node get. # It is important to keep this number as low as possible. A larger # number means regiond has to do more work slowing down its process # and slowing down the client waiting for the response. self.assertEqual( queries, 19, "Number of queries has changed; make sure this is expected.")
def test_list_num_queries_is_independent_of_num_devices(self): owner = factory.make_User() handler = DeviceHandler(owner, {}) self.make_devices(10, owner=owner) query_10_count, _ = count_queries(handler.list, {}) self.make_devices(10, owner=owner) query_20_count, _ = count_queries(handler.list, {}) # This check is to notify the developer that a change was made that # affects the number of queries performed when doing a node listing. # It is important to keep this number as low as possible. A larger # number means regiond has to do more work slowing down its process # and slowing down the client waiting for the response. self.assertEqual( query_10_count, query_20_count, "Number of queries is not independent to the number of nodes.")
def test_update_interface_updates(self): user = factory.make_admin() node = factory.make_Node(interface=False, node_type=NODE_TYPE.DEVICE) handler = DeviceHandler(user, {}) name = factory.make_name("eth") mac_address = factory.make_mac_address() ip_assignment = factory.pick_enum(DEVICE_IP_ASSIGNMENT_TYPE) params = { "system_id": node.system_id, "name": name, "mac_address": mac_address, "ip_assignment": ip_assignment, } if ip_assignment == DEVICE_IP_ASSIGNMENT_TYPE.STATIC: subnet = factory.make_Subnet() params['subnet'] = subnet.id ip_address = str(IPAddress(IPNetwork(subnet.cidr).first)) params['ip_address'] = ip_address elif ip_assignment == DEVICE_IP_ASSIGNMENT_TYPE.EXTERNAL: ip_address = factory.make_ip_address() params['ip_address'] = ip_address handler.create_interface(params) interface = node.interface_set.first() self.assertIsNotNone(interface) new_name = factory.make_name("eth") new_ip_assignment = factory.pick_enum(DEVICE_IP_ASSIGNMENT_TYPE) new_params = { "system_id": node.system_id, "interface_id": interface.id, "name": new_name, "mac_address": mac_address, "ip_assignment": new_ip_assignment, } if new_ip_assignment == DEVICE_IP_ASSIGNMENT_TYPE.STATIC: new_subnet = factory.make_Subnet() new_params['subnet'] = new_subnet.id new_ip_address = str(IPAddress(IPNetwork(new_subnet.cidr).first)) new_params['ip_address'] = new_ip_address elif new_ip_assignment == DEVICE_IP_ASSIGNMENT_TYPE.EXTERNAL: new_ip_address = factory.make_ip_address() new_params['ip_address'] = new_ip_address handler.update_interface(new_params) data = self.dehydrate_device(node, user)['interfaces'] self.assertEqual(1, len(data)) self.assertEqual(data[0]['ip_assignment'], new_ip_assignment) if new_ip_assignment != DEVICE_IP_ASSIGNMENT_TYPE.DYNAMIC: self.assertEqual(data[0]['ip_address'], new_ip_address)
def test_update_updates_node_non_admin_update_own(self): user = factory.make_User() handler = DeviceHandler(user, {}, None) node = factory.make_Node(owner=user, interface=True, node_type=NODE_TYPE.DEVICE) node_data = self.dehydrate_device(node, user) new_zone = factory.make_Zone() new_hostname = factory.make_name("hostname") new_tags = [factory.make_name("tag") for _ in range(3)] node_data["hostname"] = new_hostname node_data["zone"] = {"name": new_zone.name} node_data["tags"] = new_tags updated_node = handler.update(node_data) self.assertEqual(updated_node["hostname"], new_hostname) self.assertEqual(updated_node["zone"]["id"], new_zone.id) self.assertItemsEqual(updated_node["tags"], new_tags)
def test_create_interface_creates_with_external_ip_assignment(self): user = factory.make_User() handler = DeviceHandler(user, {}) device = factory.make_Device(owner=user) mac = factory.make_mac_address() ip_address = factory.make_ipv4_address() updated_device = handler.create_interface({ "system_id": device.system_id, "mac_address": mac, "ip_assignment": DEVICE_IP_ASSIGNMENT_TYPE.EXTERNAL, "ip_address": ip_address, }) self.expectThat(updated_device["primary_mac"], Equals(mac)) self.expectThat( updated_device["ip_assignment"], Equals(DEVICE_IP_ASSIGNMENT_TYPE.EXTERNAL)) self.expectThat( StaticIPAddress.objects.filter(ip=ip_address).count(), Equals(1), "StaticIPAddress was not created.")
def test_create_interface_creates_external(self): user = factory.make_admin() node = factory.make_Node(interface=False, node_type=NODE_TYPE.DEVICE) handler = DeviceHandler(user, {}) name = factory.make_name("eth") mac_address = factory.make_mac_address() ip_address = factory.make_ip_address() handler.create_interface({ "system_id": node.system_id, "name": name, "mac_address": mac_address, "ip_assignment": DEVICE_IP_ASSIGNMENT_TYPE.EXTERNAL, "ip_address": ip_address, }) new_interface = node.interface_set.first() self.assertIsNotNone(new_interface) auto_ip = new_interface.ip_addresses.filter( alloc_type=IPADDRESS_TYPE.USER_RESERVED) self.assertIsNotNone(auto_ip) self.assertEqual(1, len(auto_ip))
def test_list_num_queries_is_independent_of_num_devices(self): # Prevent RBAC from making a query. self.useFixture(RBACForceOffFixture()) owner = factory.make_User() handler = DeviceHandler(owner, {}, None) ip_assignment = factory.pick_enum(DEVICE_IP_ASSIGNMENT_TYPE) self.make_devices(10, owner=owner, ip_assignment=ip_assignment) query_10_count, _ = count_queries(handler.list, {}) self.make_devices(10, owner=owner, ip_assignment=ip_assignment) query_20_count, _ = count_queries(handler.list, {}) # This check is to notify the developer that a change was made that # affects the number of queries performed when doing a node listing. # It is important to keep this number as low as possible. A larger # number means regiond has to do more work slowing down its process # and slowing down the client waiting for the response. self.assertEqual( query_10_count, query_20_count, "Number of queries is not independent to the number of nodes.")
def test_create_interface_creates_with_static_ip_assignment_implicit(self): user = factory.make_User() handler = DeviceHandler(user, {}) device = factory.make_Device(owner=user) mac = factory.make_mac_address() subnet = factory.make_Subnet() updated_device = handler.create_interface({ "system_id": device.system_id, "mac_address": mac, "ip_assignment": DEVICE_IP_ASSIGNMENT_TYPE.STATIC, "subnet": subnet.id, }) self.expectThat(updated_device["primary_mac"], Equals(mac)) self.expectThat( updated_device["ip_assignment"], Equals(DEVICE_IP_ASSIGNMENT_TYPE.STATIC)) static_interface = Interface.objects.get(mac_address=MAC(mac)) observed_subnet = static_interface.ip_addresses.first().subnet self.expectThat( observed_subnet, Equals(subnet), "Static assignment to the subnet was not created.")
def test_create_creates_device_with_dynamic_ip_assignment(self): user = factory.make_User() handler = DeviceHandler(user, {}) mac = factory.make_mac_address() hostname = factory.make_name("hostname") created_device = handler.create({ "hostname": hostname, "primary_mac": mac, "interfaces": [{ "mac": mac, "ip_assignment": DEVICE_IP_ASSIGNMENT_TYPE.DYNAMIC, }], }) self.expectThat(created_device["hostname"], Equals(hostname)) self.expectThat(created_device["primary_mac"], Equals(mac)) self.expectThat(created_device["extra_macs"], Equals([])) self.expectThat( created_device["ip_assignment"], Equals(DEVICE_IP_ASSIGNMENT_TYPE.DYNAMIC)) self.expectThat(created_device["ip_address"], Is(None)) self.expectThat(created_device["owner"], Equals(user.username))