def test_create(self, client): back_network = mfactory.BackendNetworkFactory(operstate='PENDING') net = back_network.network net.state = 'ACTIVE' net.save() back1 = back_network.backend back_network2 = mfactory.BackendNetworkFactory(operstate='PENDING', network=net) back2 = back_network2.backend # Message from first backend network msg = self.create_msg(operation='OP_NETWORK_CONNECT', network=net.backend_id, cluster=back1.clustername) update_network(client, msg) self.assertTrue(client.basic_ack.called) back_net = BackendNetwork.objects.get(id=back_network.id) self.assertEqual(back_net.operstate, 'ACTIVE') db_net = Network.objects.get(id=net.id) self.assertEqual(db_net.state, 'ACTIVE') # msg from second backend network msg = self.create_msg(operation='OP_NETWORK_CONNECT', network=net.backend_id, cluster=back2.clustername) update_network(client, msg) self.assertTrue(client.basic_ack.called) db_net = Network.objects.get(id=net.id) self.assertEqual(db_net.state, 'ACTIVE') back_net = BackendNetwork.objects.get(id=back_network.id) self.assertEqual(back_net.operstate, 'ACTIVE')
def test_error_opcode(self, rapi, client): # Mock getting network, because code will lookup if network exists # in backend rapi().GetNetwork.return_value = {} mfactory.MacPrefixPoolTableFactory() mfactory.BridgePoolTableFactory() network = mfactory.NetworkFactory() mfactory.BackendNetworkFactory(network=network, operstate="ACTIVE") for state, _ in Network.OPER_STATES: bn = mfactory.BackendNetworkFactory(operstate="ACTIVE", network=network) bn.operstate = state bn.save() network = bn.network network.state = state network.save() for opcode, _ in BackendNetwork.BACKEND_OPCODES: if opcode in ['OP_NETWORK_REMOVE', 'OP_NETWORK_ADD']: continue msg = self.create_msg(operation=opcode, network=bn.network.backend_id, status='error', add_reserved_ips=[], remove_reserved_ips=[], cluster=bn.backend.clustername) with mocked_quotaholder(): update_network(client, msg) self.assertTrue(client.basic_ack.called) db_bnet = BackendNetwork.objects.get(id=bn.id) self.assertEqual(bn.operstate, db_bnet.operstate) self.assertEqual(bn.network.state, db_bnet.network.state)
def test_create_offline_backend(self, client): """Test network creation when a backend is offline""" net = mfactory.NetworkFactory(state='ACTIVE') bn1 = mfactory.BackendNetworkFactory(network=net) mfactory.BackendNetworkFactory(network=net, backend__offline=True) msg = self.create_msg(operation='OP_NETWORK_CONNECT', network=net.backend_id, cluster=bn1.backend.clustername) update_network(client, msg) self.assertTrue(client.basic_ack.called) new_net = Network.objects.get(id=net.id) self.assertEqual(new_net.state, 'ACTIVE')
def test_disconnect(self, client): bn1 = mfactory.BackendNetworkFactory(operstate='ACTIVE') net1 = bn1.network net1.state = "ACTIVE" net1.state = 'ACTIVE' net1.save() bn2 = mfactory.BackendNetworkFactory(operstate='ACTIVE', network=net1) msg = self.create_msg(operation='OP_NETWORK_DISCONNECT', network=net1.backend_id, cluster=bn2.backend.clustername) update_network(client, msg) client.basic_ack.assert_called_once() self.assertEqual(Network.objects.get(id=net1.id).state, 'ACTIVE') self.assertEqual( BackendNetwork.objects.get(id=bn2.id).operstate, 'PENDING')
def test_remove(self, client): mfactory.MacPrefixPoolTableFactory() mfactory.BridgePoolTableFactory() bn = mfactory.BackendNetworkFactory(operstate='ACTIVE') for old_state in ['success', 'canceled', 'error']: for flavor in Network.FLAVORS.keys(): bn.operstate = old_state bn.save() net = bn.network net.state = 'ACTIVE' net.flavor = flavor if flavor == 'PHYSICAL_VLAN': net.link = allocate_resource('bridge') if flavor == 'MAC_FILTERED': net.mac_prefix = allocate_resource('mac_prefix') net.save() msg = self.create_msg(operation='OP_NETWORK_REMOVE', network=net.backend_id, cluster=bn.backend.clustername) with mocked_quotaholder(): update_network(client, msg) self.assertTrue(client.basic_ack.called) self.assertFalse(BackendNetwork.objects.filter(id=bn.id) .exists()) db_net = Network.objects.get(id=net.id) self.assertEqual(db_net.state, 'DELETED', flavor) self.assertTrue(db_net.deleted) if flavor == 'PHYSICAL_VLAN': pool = BridgePoolTable.get_pool() self.assertTrue(pool.is_available(net.link)) if flavor == 'MAC_FILTERED': pool = MacPrefixPoolTable.get_pool() self.assertTrue(pool.is_available(net.mac_prefix))
def test_ips(self, client): network = mfactory.NetworkFactory(subnet='10.0.0.0/24') bn = mfactory.BackendNetworkFactory(network=network) msg = self.create_msg(operation='OP_NETWORK_SET_PARAMS', network=network.backend_id, cluster=bn.backend.clustername, status='success', add_reserved_ips=['10.0.0.10', '10.0.0.20'], remove_reserved_ips=[]) update_network(client, msg) client.basic_ack.assert_called_once() pool = network.get_pool() self.assertTrue(pool.is_reserved('10.0.0.10')) self.assertTrue(pool.is_reserved('10.0.0.20')) pool.save() # Release them msg = self.create_msg(operation='OP_NETWORK_SET_PARAMS', network=network.backend_id, cluster=bn.backend.clustername, add_reserved_ips=[], remove_reserved_ips=['10.0.0.10', '10.0.0.20']) update_network(client, msg) client.basic_ack.assert_called_once() pool = network.get_pool() self.assertFalse(pool.is_reserved('10.0.0.10')) self.assertFalse(pool.is_reserved('10.0.0.20'))
def test_error_opcode(self, client): mfactory.MacPrefixPoolTableFactory() mfactory.BridgePoolTableFactory() for state, _ in Network.OPER_STATES: bn = mfactory.BackendNetworkFactory(operstate="ACTIVE") bn.operstate = state bn.save() network = bn.network network.state = state network.save() for opcode, _ in BackendNetwork.BACKEND_OPCODES: if opcode in ['OP_NETWORK_REMOVE', 'OP_NETWORK_ADD']: continue msg = self.create_msg(operation=opcode, network=bn.network.backend_id, status='error', add_reserved_ips=[], remove_reserved_ips=[], cluster=bn.backend.clustername) with mocked_quotaholder(): update_network(client, msg) client.basic_ack.assert_called_once() db_bnet = BackendNetwork.objects.get(id=bn.id) self.assertEqual(bn.operstate, db_bnet.operstate) self.assertEqual(bn.network.state, db_bnet.network.state)
def test_ips(self, client): network = mfactory.NetworkWithSubnetFactory(subnet__cidr='10.0.0.0/24', subnet__gateway="10.0.0.1") bn = mfactory.BackendNetworkFactory(network=network) msg = self.create_msg(operation='OP_NETWORK_SET_PARAMS', network=network.backend_id, cluster=bn.backend.clustername, status='success', job_fields={"add_reserved_ips": ["10.0.0.10", "10.0.0.20"]}) update_network(client, msg) self.assertTrue(client.basic_ack.called) pool = network.get_ip_pools()[0] self.assertTrue(pool.is_reserved('10.0.0.10')) self.assertTrue(pool.is_reserved('10.0.0.20')) pool.save() # Check that they are not released msg = self.create_msg(operation='OP_NETWORK_SET_PARAMS', network=network.backend_id, cluster=bn.backend.clustername, job_fields={ "remove_reserved_ips": ["10.0.0.10", "10.0.0.20"]}) update_network(client, msg) pool = network.get_ip_pools()[0] self.assertTrue(pool.is_reserved('10.0.0.10')) self.assertTrue(pool.is_reserved('10.0.0.20'))
def test_remove_offline_backend(self, client): """Test network removing when a backend is offline""" mfactory.BridgePoolTableFactory() net = mfactory.NetworkFactory(flavor='PHYSICAL_VLAN', state='ACTIVE', link='prv12') bn1 = mfactory.BackendNetworkFactory(network=net) mfactory.BackendNetworkFactory(network=net, operstate="ACTIVE", backend__offline=True) msg = self.create_msg(operation='OP_NETWORK_REMOVE', network=net.backend_id, cluster=bn1.backend.clustername) with mocked_quotaholder(): update_network(client, msg) self.assertTrue(client.basic_ack.called) new_net = Network.objects.get(id=net.id) self.assertEqual(new_net.state, 'ACTIVE') self.assertFalse(new_net.deleted)
def test_connect_network(self, mrapi): # Common connect for dhcp in [True, False]: subnet = mfactory.IPv4SubnetFactory(network__flavor="CUSTOM", cidr="192.168.2.0/24", gateway="192.168.2.1", dhcp=dhcp) net = subnet.network vm = mfactory.VirtualMachineFactory(operstate="STARTED") mfactory.BackendNetworkFactory(network=net, backend=vm.backend) mrapi().ModifyInstance.return_value = 42 with override_settings(settings, GANETI_USE_HOTPLUG=True): with transaction.atomic(): port = servers._create_port(vm.userid, net) servers.connect_port(vm, net, port) pool = net.get_ip_pools(locked=False)[0] self.assertFalse(pool.is_available("192.168.2.2")) args, kwargs = mrapi().ModifyInstance.call_args nics = kwargs["nics"][0] self.assertEqual(kwargs["instance"], vm.backend_vm_id) self.assertEqual(nics[0], "add") self.assertEqual(nics[1], "-1") self.assertEqual(nics[2]["ip"], "192.168.2.2") self.assertEqual(nics[2]["network"], net.backend_id) # Test connect to IPv6 only network vm = mfactory.VirtualMachineFactory(operstate="STARTED") subnet = mfactory.IPv6SubnetFactory(cidr="2000::/64", gateway="2000::1") net = subnet.network mfactory.BackendNetworkFactory(network=net, backend=vm.backend) with override_settings(settings, GANETI_USE_HOTPLUG=True): with transaction.atomic(): port = servers._create_port(vm.userid, net) servers.connect_port(vm, net, port) args, kwargs = mrapi().ModifyInstance.call_args nics = kwargs["nics"][0] self.assertEqual(kwargs["instance"], vm.backend_vm_id) self.assertEqual(nics[0], "add") self.assertEqual(nics[1], "-1") self.assertEqual(nics[2]["ip"], None) self.assertEqual(nics[2]["network"], net.backend_id)
def test_create_server(self, mrapi, mimage): """Test if the create server call returns the expected response if a valid request has been speficied.""" mimage.return_value = { 'location': 'pithos://foo', 'checksum': '1234', "id": 1, "name": "test_image", 'disk_format': 'diskdump' } mrapi().CreateInstance.return_value = 12 flavor = mfactory.FlavorFactory() # Create public network and backend network = mfactory.NetworkFactory(public=True) backend = mfactory.BackendFactory() mfactory.BackendNetworkFactory(network=network, backend=backend) request = { "server": { "name": "new-server-test", "userid": "test_user", "imageRef": 1, "flavorRef": flavor.id, "metadata": { "My Server Name": "Apache1" }, "personality": [] } } with mocked_quotaholder(): response = self.mypost('servers', 'test_user', json.dumps(request), 'json') self.assertEqual(response.status_code, 202) mrapi().CreateInstance.assert_called_once() api_server = json.loads(response.content)['server'] self.assertEqual(api_server['status'], "BUILD") self.assertEqual(api_server['progress'], 0) self.assertEqual(api_server['metadata'], {"My Server Name": "Apache1"}) self.assertTrue('adminPass' in api_server) db_vm = VirtualMachine.objects.get(userid='test_user') self.assertEqual(api_server['name'], db_vm.name) self.assertEqual(api_server['status'], db_vm.operstate) # Test drained flag in Network: network.drained = True network.save() with mocked_quotaholder(): response = self.mypost('servers', 'test_user', json.dumps(request), 'json') self.assertEqual(response.status_code, 503, "serviceUnavailable")
def test_stale_network(self, mrapi): # Test that stale network will be deleted from DB, if network action is # destroy net1 = mfactory.NetworkWithSubnetFactory(public=False, flavor="IP_LESS_ROUTED", action="DESTROY", deleted=False) bn1 = mfactory.BackendNetworkFactory(network=net1, backend=self.backend, operstate="ACTIVE") mrapi().GetNetworks.return_value = [] self.assertFalse(net1.deleted) with mocked_quotaholder(): self.reconciler.reconcile_networks() net1 = Network.objects.get(id=net1.id) self.assertTrue(net1.deleted) self.assertFalse(net1.backend_networks.filter(id=bn1.id).exists()) # But not if action is not DESTROY net2 = mfactory.NetworkWithSubnetFactory(public=False, action="CREATE") mfactory.BackendNetworkFactory(network=net2, backend=self.backend) self.assertFalse(net2.deleted) self.reconciler.reconcile_networks() self.assertFalse(net2.deleted)
def test_delete_backend(self): vm = mfact.VirtualMachineFactory(backend=self.backend, deleted=True) bnet = mfact.BackendNetworkFactory(backend=self.backend) self.backend.delete() self.assertRaises(Backend.DoesNotExist, Backend.objects.get, id=self.backend.id) # Test that VM is not deleted vm2 = VirtualMachine.objects.get(id=vm.id) self.assertEqual(vm2.backend, None) # Test tha backend networks are deleted, but not the network self.assertRaises(BackendNetwork.DoesNotExist, BackendNetwork.objects.get, id=bnet.id) Network.objects.get(id=bnet.network.id)
def test_remove_error(self, rapi, client): mfactory.MacPrefixPoolTableFactory() mfactory.BridgePoolTableFactory() bn = mfactory.BackendNetworkFactory(operstate='ACTIVE') network = bn.network msg = self.create_msg(operation='OP_NETWORK_REMOVE', network=network.backend_id, status="error", cluster=bn.backend.clustername) rapi().GetNetwork.return_value = {} update_network(client, msg) bn = BackendNetwork.objects.get(id=bn.id) self.assertNotEqual(bn.operstate, "DELETED") rapi().GetNetwork.side_effect = GanetiApiError(msg="foo", code=404) with mocked_quotaholder(): update_network(client, msg) self.assertFalse(BackendNetwork.objects.filter(id=bn.id) .exists())
def test_unsynced_networks(self, mrapi): net = mfactory.NetworkWithSubnetFactory(public=False, state="PENDING", action="CREATE", deleted=False) bn = mfactory.BackendNetworkFactory(network=net, backend=self.backend, operstate="PENDING") mrapi().GetNetworks.return_value = [{ "name": net.backend_id, "group_list": [], "network": net.subnet4.cidr, "map": "....", "external_reservations": "" }] self.assertEqual(bn.operstate, "PENDING") self.reconciler.reconcile_networks() bn = BackendNetwork.objects.get(id=bn.id) self.assertEqual(bn.operstate, "ACTIVE")
def test_mac_prefix(self): network = mfact.NetworkFactory(mac_prefix='aa:bb:c') backend = mfact.BackendFactory() bnet = mfact.BackendNetworkFactory(network=network, backend=backend) self.assertTrue(backend.index < 10) self.assertEqual(bnet.mac_prefix, 'aa:bb:c%s' % backend.index)
def test_missing_network(self, mrapi): net2 = mfactory.NetworkWithSubnetFactory(public=False, action="CREATE") mfactory.BackendNetworkFactory(network=net2, backend=self.backend) mrapi().GetNetworks.return_value = [] self.reconciler.reconcile_networks() self.assertEqual(len(mrapi().CreateNetwork.mock_calls), 1)