def test_update_subnet_ip_version(self): """Update the IP version of a subnet, raises 400 BadRequest""" test_net = mf.NetworkFactory() test_sub = mf.IPv4SubnetFactory(network=test_net) request = {'subnet': {'ip_version': '6'}} url = join_urls(SUBNETS_URL, str(test_sub.id)) response = self.put(url, test_net.userid, json.dumps(request), "json") self.assertBadRequest(response)
def test_update_subnet_add_dns(self): """Update the dns nameservers of a subnet, raises 400 BadRequest""" test_net = mf.NetworkFactory() test_sub = mf.IPv4SubnetFactory(network=test_net) request = {'subnet': {'dns_nameservers': ['8.8.8.8']}} url = join_urls(SUBNETS_URL, str(test_sub.id)) response = self.put(url, test_net.userid, json.dumps(request), "json") self.assertBadRequest(response)
def test_update_subnet_cidr(self): """Update the cidr of a subnet, raises 400 BadRequest""" test_net = mf.NetworkFactory() test_sub = mf.IPv4SubnetFactory(network=test_net) request = {'subnet': {'cidr': '192.168.42.0/24'}} url = join_urls(SUBNETS_URL, str(test_sub.id)) response = self.put(url, test_net.userid, json.dumps(request), "json") self.assertBadRequest(response)
def test_list_subnets_data(self): """Test list subnets with data""" test_net = mf.NetworkFactory() test_subnet_ipv4 = mf.IPv4SubnetFactory(network=test_net) test_subnet_ipv6 = mf.IPv6SubnetFactory( network=test_net, ipversion=6, cidr='fd4b:638e:fd7a:f998::/64') response = self.get(SUBNETS_URL, user=test_net.userid) self.assertSuccess(response)
def setUp(self): """Common setup method for this suite. This setUp method creates a simple IP Pool from which IPs can be created. """ self.subnet = mfactory.IPv4SubnetFactory( network__floating_ip_pool=True) self.network = self.subnet.network
def test_update_subnet_with_invalid_name(self): """Update a subnet with an invalid name value""" test_net = mf.NetworkFactory() test_sub = mf.IPv4SubnetFactory(network=test_net) request = { 'subnet': { 'name': 'a' * 300} } url = join_urls(SUBNETS_URL, str(test_sub.id)) response = self.put(url, test_net.userid, json.dumps(request), "json") self.assertBadRequest(response)
def test_update_subnet_dhcp(self): """Update the dhcp flag of a subnet""" test_net = mf.NetworkFactory() test_sub = mf.IPv4SubnetFactory(network=test_net) request = { 'subnet': { 'enable_dhcp': False} } url = join_urls(SUBNETS_URL, str(test_sub.id)) response = self.put(url, test_net.userid, json.dumps(request), "json") self.assertBadRequest(response)
def test_create_network_settings(self, mrapi): mrapi().CreateInstance.return_value = 12 # User requested private networks # no public IPv4 network_settings = { "CYCLADES_DEFAULT_SERVER_NETWORKS": [], "CYCLADES_FORCED_SERVER_NETWORKS": ["SNF:ANY_PUBLIC_IPV4"] } with override_settings(settings, **network_settings): response = self.mypost('servers', "test", json.dumps(self.request), 'json') self.assertEqual(response.status_code, 503) # no public IPv4, IPv6 exists network_settings = { "CYCLADES_DEFAULT_SERVER_NETWORKS": [], "CYCLADES_FORCED_SERVER_NETWORKS": ["SNF:ANY_PUBLIC"] } with override_settings(settings, **network_settings): response = self.mypost('servers', "test", json.dumps(self.request), 'json') self.assertEqual(response.status_code, 202) server_id = json.loads(response.content)["server"]["id"] vm = VirtualMachine.objects.get(id=server_id) self.assertEqual(vm.nics.get().ipv4_address, None) # IPv4 exists mfactory.IPv4SubnetFactory(network__public=True, cidr="192.168.2.0/24", pool__offset=2, pool__size=1) with override_settings(settings, **network_settings): response = self.mypost('servers', "test", json.dumps(self.request), 'json') self.assertEqual(response.status_code, 202) server_id = json.loads(response.content)["server"]["id"] vm = VirtualMachine.objects.get(id=server_id) self.assertEqual(vm.nics.get().ipv4_address, "192.168.2.2") # Fixed networks net1 = mfactory.NetworkFactory(userid="test") net2 = mfactory.NetworkFactory(userid="test") net3 = mfactory.NetworkFactory(userid="test") network_settings = { "CYCLADES_DEFAULT_SERVER_NETWORKS": [], "CYCLADES_FORCED_SERVER_NETWORKS": [net1.id, [net2.id, net3.id], (net3.id, net2.id)] } with override_settings(settings, **network_settings): response = self.mypost('servers', "test", json.dumps(self.request), 'json') self.assertEqual(response.status_code, 202) server_id = json.loads(response.content)["server"]["id"] vm = VirtualMachine.objects.get(id=server_id) self.assertEqual(len(vm.nics.all()), 3)
def test_delete_network(self): test_net = dbmf.NetworkFactory(flavor="CUSTOM") dbmf.IPv4SubnetFactory(network=test_net) url = join_urls(NETWORKS_URL, str(test_net.id)) response = self.delete(url, user=test_net.userid) self.assertEqual(response.status_code, 204) # But not the public network!! test_net.public = True test_net.save() response = self.delete(url, user=test_net.userid) self.assertFault(response, 403, 'forbidden')
def test_update_subnet_gateway(self): """Update the gateway of a subnet""" test_net = mf.NetworkFactory() test_sub = mf.IPv4SubnetFactory(network=test_net) request = { 'subnet': { 'gateway_ip': str(IPv4Network(test_sub.gateway).network + 1)} } url = join_urls(SUBNETS_URL, str(test_sub.id)) response = self.put(url, test_net.userid, json.dumps(request), "json") self.assertBadRequest(response)
def test_update_subnet_name(self): """Update the name of a subnet""" test_net = mf.NetworkFactory() test_sub = mf.IPv4SubnetFactory(network=test_net) request = { 'subnet': { 'name': 'Updated Name'} } url = join_urls(SUBNETS_URL, str(test_sub.id)) response = self.put(url, test_net.userid, json.dumps(request), "json") self.assertSuccess(response)
def test_update_subnet_with_invalid_gateway(self): """Update a subnet with an invalid gateway value""" test_net = mf.NetworkFactory() test_sub = mf.IPv4SubnetFactory(network=test_net) request = { 'subnet': { 'gateway_ip': '192.168.200.0/24'} } url = join_urls(SUBNETS_URL, str(test_sub.id)) response = self.put(url, test_net.userid, json.dumps(request), "json") self.assertBadRequest(response)
def test_update_subnet_allocation_pools(self): """Update the allocation pools of a subnet, raises 400 BadRequest""" test_net = mf.NetworkFactory() test_sub = mf.IPv4SubnetFactory(network=test_net) request = { 'subnet': { 'allocation_pools': [{ 'start': '10.0.3.0', 'end': '10.0.3.255'} ]} } url = join_urls(SUBNETS_URL, str(test_sub.id)) response = self.put(url, test_net.userid, json.dumps(request), "json") self.assertBadRequest(response)
def test_create_subnet_with_same_ipversion(self): """ Create a subnet in a network with another subnet of the same ipversion type """ test_net = mf.NetworkFactory() test_sub = mf.IPv4SubnetFactory(network=test_net) request = { 'subnet': { 'network_id': test_net.id, 'cidr': '192.168.3.0/24'} } response = self.post(SUBNETS_URL, test_net.userid, json.dumps(request), "json") self.assertBadRequest(response)
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_port_private_net(self, mrapi): net = dbmf.NetworkFactory(public=False) dbmf.IPv4SubnetFactory(network=net) dbmf.IPv6SubnetFactory(network=net) sg1 = dbmf.SecurityGroupFactory() sg2 = dbmf.SecurityGroupFactory() vm = dbmf.VirtualMachineFactory(userid=net.userid) request = { "port": { "name": "port1", "network_id": str(net.id), "device_id": str(vm.id), "security_groups": [str(sg1.id), str(sg2.id)] } } mrapi().ModifyInstance.return_value = 42 with override_settings(settings, GANETI_USE_HOTPLUG=False): response = self.post(PORTS_URL, params=json.dumps(request), user=net.userid) self.assertEqual(response.status_code, 400) with override_settings(settings, GANETI_USE_HOTPLUG=True): response = self.post(PORTS_URL, params=json.dumps(request), user=net.userid) self.assertEqual(response.status_code, 201)
def test_create(self, mrapi): flavor = mfactory.FlavorFactory() kwargs = { "userid": "test", "name": "test_vm", "password": "******", "flavor": flavor, "image_id": "safs", "networks": [], "metadata": { "foo": "bar" }, "personality": [], } # no backend! mfactory.BackendFactory(offline=True) self.assertRaises(faults.ServiceUnavailable, servers.create, **kwargs) self.assertEqual(models.VirtualMachine.objects.count(), 0) mfactory.IPv4SubnetFactory(network__public=True) mfactory.IPv6SubnetFactory(network__public=True) backend = mfactory.BackendFactory() # error in nics req = deepcopy(kwargs) req["networks"] = [{"uuid": 42}] self.assertRaises(faults.ItemNotFound, servers.create, **req) self.assertEqual(models.VirtualMachine.objects.count(), 0) # error in enqueue. check the vm is deleted and resources released mrapi().CreateInstance.side_effect = Exception("ganeti is down") with mocked_quotaholder(): servers.create(**kwargs) vm = models.VirtualMachine.objects.get() self.assertFalse(vm.deleted) self.assertEqual(vm.operstate, "ERROR") for nic in vm.nics.all(): self.assertEqual(nic.state, "ERROR") # test ext settings: req = deepcopy(kwargs) ext_flavor = mfactory.FlavorFactory( volume_type__disk_template="ext_archipelago", disk=1) req["flavor"] = ext_flavor mrapi().CreateInstance.return_value = 42 backend.disk_templates = ["ext"] backend.save() osettings = { "GANETI_DISK_PROVIDER_KWARGS": { "archipelago": { "foo": "mpaz", "lala": "lolo" } } } with mocked_quotaholder(): with override_settings(settings, **osettings): vm = servers.create(**req) name, args, kwargs = mrapi().CreateInstance.mock_calls[-1] self.assertEqual( kwargs["disks"][0], { "provider": "archipelago", "origin": "test_mapfile", "origin_size": 1000, "name": vm.volumes.all()[0].backend_volume_uuid, "foo": "mpaz", "lala": "lolo", "size": 1024 })
def test_create_network_info(self, mrapi): mrapi().CreateInstance.return_value = 12 # User requested private networks s1 = mfactory.IPv4SubnetFactory(network__userid="test") s2 = mfactory.IPv6SubnetFactory(network__userid="test") # and a public IPv6 request = deepcopy(self.request) request["server"]["networks"] = [{ "uuid": s1.network_id }, { "uuid": s2.network_id }] with override_settings(settings, **self.network_settings): with mocked_quotaholder(): response = self.mypost('servers', "test", json.dumps(request), 'json') self.assertEqual(response.status_code, 202) name, args, kwargs = mrapi().CreateInstance.mock_calls[0] self.assertEqual(len(kwargs["nics"]), 3) self.assertEqual(kwargs["nics"][0]["network"], self.net6.backend_id) self.assertEqual(kwargs["nics"][1]["network"], s1.network.backend_id) self.assertEqual(kwargs["nics"][2]["network"], s2.network.backend_id) # but fail if others user network s3 = mfactory.IPv6SubnetFactory(network__userid="test_other") request = deepcopy(self.request) request["server"]["networks"] = [{"uuid": s3.network_id}] response = self.mypost('servers', "test", json.dumps(request), 'json') self.assertEqual(response.status_code, 404) # User requested public networks # but no floating IP.. s1 = mfactory.IPv4SubnetFactory(network__public=True) request = deepcopy(self.request) request["server"]["networks"] = [{"uuid": s1.network_id}] response = self.mypost('servers', "test", json.dumps(request), 'json') self.assertEqual(response.status_code, 409) # Add one floating IP fp1 = mfactory.IPv4AddressFactory(userid="test", subnet=s1, network=s1.network, floating_ip=True, nic=None) self.assertEqual(fp1.nic, None) request = deepcopy(self.request) request["server"]["networks"] = [{ "uuid": s1.network_id, "fixed_ip": fp1.address }] with mocked_quotaholder(): with override_settings(settings, **self.network_settings): response = self.mypost('servers', "test", json.dumps(request), 'json') self.assertEqual(response.status_code, 202) server_id = json.loads(response.content)["server"]["id"] fp1 = IPAddress.objects.get(id=fp1.id) self.assertEqual(fp1.nic.machine_id, server_id) # check used floating IP response = self.mypost('servers', "test", json.dumps(request), 'json') self.assertEqual(response.status_code, 409) # Add more floating IP. but check auto-reserve fp2 = mfactory.IPv4AddressFactory(userid="test", subnet=s1, network=s1.network, floating_ip=True, nic=None) self.assertEqual(fp2.nic, None) request = deepcopy(self.request) request["server"]["networks"] = [{"uuid": s1.network_id}] with mocked_quotaholder(): with override_settings(settings, **self.network_settings): response = self.mypost('servers', "test", json.dumps(request), 'json') self.assertEqual(response.status_code, 202) server_id = json.loads(response.content)["server"]["id"] fp2 = IPAddress.objects.get(id=fp2.id) self.assertEqual(fp2.nic.machine_id, server_id) name, args, kwargs = mrapi().CreateInstance.mock_calls[-1] self.assertEqual(len(kwargs["nics"]), 2) self.assertEqual(kwargs["nics"][0]["network"], self.net6.backend_id) self.assertEqual(kwargs["nics"][1]["network"], fp2.network.backend_id)
def test_create(self, mrapi): flavor = mfactory.FlavorFactory() kwargs = { "credentials": self.credentials, "name": "test_vm", "password": "******", "flavor": flavor, "image_id": "safs", "networks": [], "metadata": { "foo": "bar" }, "personality": [], } # no backend! mfactory.BackendFactory(offline=True) self.assertRaises(faults.ServiceUnavailable, servers.create, **kwargs) self.assertEqual(models.VirtualMachine.objects.count(), 0) mfactory.IPv4SubnetFactory(network__public=True) mfactory.IPv6SubnetFactory(network__public=True) backend = mfactory.BackendFactory() # error in nics req = deepcopy(kwargs) req["networks"] = [{"uuid": 42}] self.assertRaises(faults.ItemNotFound, servers.create, **req) self.assertEqual(models.VirtualMachine.objects.count(), 0) # error in enqueue. check the vm is deleted and resources released mrapi().CreateInstance.side_effect = Exception("ganeti is down") with mocked_quotaholder(): servers.create(**kwargs) vm = models.VirtualMachine.objects.get() self.assertFalse(vm.deleted) self.assertEqual(vm.operstate, "ERROR") for nic in vm.nics.all(): self.assertEqual(nic.state, "ERROR") # test ext settings: req = deepcopy(kwargs) vlmt = mfactory.VolumeTypeFactory(disk_template='ext_archipelago') # Generate 4 specs. 2 prefixed with GNT_EXTP_VOLTYPESPEC_PREFIX # and 2 with an other prefix that should be omitted volume_type_specs = [ mfactory.VolumeTypeSpecsFactory(volume_type=vlmt, key='%sbar' % GNT_EXTP_VOLTYPESPEC_PREFIX), mfactory.VolumeTypeSpecsFactory(volume_type=vlmt, key='%sfoo' % GNT_EXTP_VOLTYPESPEC_PREFIX), mfactory.VolumeTypeSpecsFactory(volume_type=vlmt, key='other-prefx-baz'), mfactory.VolumeTypeSpecsFactory(volume_type=vlmt, key='another-prefix-biz'), ] gnt_prefixed_specs = filter( lambda s: s.key.startswith(GNT_EXTP_VOLTYPESPEC_PREFIX), volume_type_specs) ext_flavor = mfactory.FlavorFactory(volume_type=vlmt, disk=1) req["flavor"] = ext_flavor mrapi().CreateInstance.return_value = 42 backend.disk_templates = ["ext"] backend.save() osettings = { "GANETI_DISK_PROVIDER_KWARGS": { "archipelago": { "foo": "mpaz", "lala": "lolo" } } } with mocked_quotaholder(): with override_settings(settings, **osettings): with patch( 'synnefo.logic.backend_allocator.update_backends_disk_templates' # noqa E265 ) as update_disk_templates_mock: # Check that between the `get_available_backends` call # and the `update_backend_disk_templates` call # the backend doesn't change. update_disk_templates_mock.return_value = [backend] vm = servers.create(**req) update_disk_templates_mock.assert_called_once_with([backend]) name, args, kwargs = mrapi().CreateInstance.mock_calls[-1] disk_kwargs = { "provider": "archipelago", "origin": "test_mapfile", "origin_size": 1000, "name": vm.volumes.all()[0].backend_volume_uuid, "foo": "mpaz", "lala": "lolo", "size": 1024 } disk_kwargs.update({ spec.key[len(GNT_EXTP_VOLTYPESPEC_PREFIX):]: spec.value for spec in gnt_prefixed_specs }) self.assertEqual(kwargs["disks"][0], disk_kwargs)