def test_action_performs_action_passing_extra(self): user = factory.make_admin() request = HttpRequest() request.user = user device = self.make_device_with_ip_address(owner=user) zone = factory.make_Zone() handler = DeviceHandler(user, {}, request) handler.action({ "request": request, "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_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_copes_with_mac_addresses_of_different_forms(self): user = factory.make_User() request = HttpRequest() request.user = user handler = DeviceHandler(user, {}, request) 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_copes_with_mac_addresses_of_different_case(self): user = factory.make_User() request = HttpRequest() request.user = user handler = DeviceHandler(user, {}, request) 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_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_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() request = HttpRequest() request.user = user handler = DeviceHandler(user, {}, request) 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_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_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_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_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))
def test_update_interface_updates_non_admin(self): user = factory.make_User() node = factory.make_Node(owner=user, interface=False, node_type=NODE_TYPE.DEVICE) handler = DeviceHandler(user, {}, None) name = factory.make_name("eth") mac_address = factory.make_mac_address() ip_assignment = DEVICE_IP_ASSIGNMENT_TYPE.DYNAMIC params = { "system_id": node.system_id, "name": name, "mac_address": mac_address, "ip_assignment": ip_assignment, } handler.create_interface(params) interface = node.interface_set.first() self.assertIsNotNone(interface) new_mac_address = factory.make_mac_address() new_params = { "system_id": node.system_id, "interface_id": interface.id, "name": name, "mac_address": new_mac_address, "ip_assignment": ip_assignment, } handler.update_interface(new_params) data = self.dehydrate_device(node, user)["interfaces"] self.assertEqual(1, len(data)) self.assertEqual(data[0]["mac_address"], new_mac_address)
def test_create_creates_device_with_static_ip_assignment_explicit(self): user = factory.make_User() request = HttpRequest() request.user = user handler = DeviceHandler(user, {}, request) mac = factory.make_mac_address() hostname = factory.make_name("hostname") subnet = factory.make_Subnet() ip_address = factory.pick_ip_in_Subnet(subnet) created_device = handler.create( { "hostname": hostname, "primary_mac": mac, "interfaces": [ { "mac": mac, "ip_assignment": DEVICE_IP_ASSIGNMENT_TYPE.STATIC, "subnet": subnet.id, "ip_address": ip_address, } ], } ) self.expectThat( created_device["ip_assignment"], Equals(DEVICE_IP_ASSIGNMENT_TYPE.STATIC), ) self.expectThat(created_device["ip_address"], Equals(ip_address)) 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.", ) self.expectThat( StaticIPAddress.objects.filter(ip=ip_address).count(), Equals(1), "StaticIPAddress was not created.", )
def test_create_interface_creates_static(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() fabric = factory.make_Fabric() vlan = fabric.get_default_vlan() subnet = factory.make_Subnet(vlan=vlan) handler.create_interface({ "system_id": node.system_id, "name": name, "mac_address": mac_address, "ip_assignment": DEVICE_IP_ASSIGNMENT_TYPE.STATIC, "subnet": subnet.id, }) new_interface = node.interface_set.first() self.assertIsNotNone(new_interface) auto_ip = new_interface.ip_addresses.filter( alloc_type=IPADDRESS_TYPE.STICKY, subnet=subnet) self.assertIsNotNone(auto_ip) self.assertEqual(1, len(auto_ip))
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_create_creates_device_with_external_ip_assignment(self): user = factory.make_User() handler = DeviceHandler(user, {}) mac = factory.make_mac_address() hostname = factory.make_name("hostname") ip_address = factory.make_ipv4_address() created_device = handler.create({ "hostname": hostname, "primary_mac": mac, "interfaces": [{ "mac": mac, "ip_assignment": DEVICE_IP_ASSIGNMENT_TYPE.EXTERNAL, "ip_address": ip_address, }], }) self.expectThat( created_device["ip_assignment"], Equals(DEVICE_IP_ASSIGNMENT_TYPE.EXTERNAL)) self.expectThat(created_device["ip_address"], Equals(ip_address)) self.expectThat( StaticIPAddress.objects.filter(ip=ip_address).count(), Equals(1), "StaticIPAddress was not created.")
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_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_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): # 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_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_action_performs_action(self): user = factory.make_admin() device = factory.make_Node(owner=user, node_type=NODE_TYPE.DEVICE) handler = DeviceHandler(user, {}) handler.action({"system_id": device.system_id, "action": "delete"}) self.assertIsNone(reload_object(device))
def test_missing_action_raises_error(self): user = factory.make_User() device = self.make_device_with_ip_address(owner=user) handler = DeviceHandler(user, {}) with ExpectedException(NodeActionError): handler.action({"system_id": device.system_id})
def test_get_form_class_returns_DeviceWithMACsForm_for_create(self): user = factory.make_User() handler = DeviceHandler(user, {}, None) self.assertIs(DeviceWithMACsForm, handler.get_form_class("create"))
def test_get_form_class_raises_error_for_unknown_action(self): user = factory.make_User() handler = DeviceHandler(user, {}) self.assertRaises( HandlerError, handler.get_form_class, factory.make_name())
def test_get_form_class_returns_DeviceForm_for_update(self): user = factory.make_User() handler = DeviceHandler(user, {}) self.assertIs(DeviceForm, handler.get_form_class("update"))
def test_update_raise_permissions_error_for_non_admin(self): user = factory.make_User() handler = DeviceHandler(user, {}) self.assertRaises( HandlerPermissionError, handler.update, {})
def test_get_object_raises_exception_if_owner_by_another_user(self): user = factory.make_User() device = self.make_device_with_ip_address() handler = DeviceHandler(user, {}) with ExpectedException(HandlerDoesNotExistError): handler.get_object({"system_id": device.system_id})