def test_create(self, mrapi): flavor = mfactory.FlavorFactory() kwargs = { "userid": "test", "name": "test_vm", "password": "******", "flavor": flavor, "image": { "id": "foo", "backend_id": "foo", "format": "diskdump", "checksum": "test_checksum", "metadata": "{}", }, "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(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_checksum", "foo": "mpaz", "lala": "lolo", "size": 1024}, )
def create_server(request): # Normal Response Code: 202 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badMediaType(415), # itemNotFound (404), # badRequest (400), # serverCapacityUnavailable (503), # overLimit (413) req = utils.get_json_body(request) user_id = request.user_uniq log.info('create_server user: %s request: %s', user_id, req) try: server = req['server'] name = server['name'] metadata = server.get('metadata', {}) assert isinstance(metadata, dict) image_id = server['imageRef'] flavor_id = server['flavorRef'] personality = server.get('personality', []) assert isinstance(personality, list) networks = server.get("networks") if networks is not None: assert isinstance(networks, list) project = server.get("project") except (KeyError, AssertionError): raise faults.BadRequest("Malformed request") volumes = None dev_map = server.get("block_device_mapping_v2") if dev_map is not None: volumes = parse_block_device_mapping(dev_map) # Verify that personalities are well-formed util.verify_personality(personality) # Get flavor (ensure it is active) flavor = util.get_flavor(flavor_id, include_deleted=False) if not flavor.allow_create: msg = ("It is not allowed to create a server from flavor with id '%d'," " see 'allow_create' flavor attribute") raise faults.Forbidden(msg % flavor.id) # Generate password password = util.random_password() vm = servers.create(user_id, name, password, flavor, image_id, metadata=metadata, personality=personality, project=project, networks=networks, volumes=volumes) server = vm_to_dict(vm, detail=True) server['status'] = 'BUILD' server['adminPass'] = password response = render_server(request, server, status=202) return response
def handle(self, *args, **options): if args: raise CommandError("Command doesn't accept any arguments") name = options['name'] user_id = options['user_id'] project = options['project'] backend_id = options['backend_id'] image_id = options['image_id'] flavor_id = options['flavor_id'] password = options['password'] volumes = options['volumes'] helper_vm = options['helper_vm'] if not name: raise CommandError("name is mandatory") if not user_id: raise CommandError("user is mandatory") if not project: project = user_id if not password: raise CommandError("password is mandatory") if not flavor_id: raise CommandError("flavor is mandatory") if not image_id and not volumes: raise CommandError("image is mandatory") flavor = common.get_resource("flavor", flavor_id) if image_id is not None: common.get_image(image_id, user_id) if backend_id: backend = common.get_resource("backend", backend_id) else: backend = None connection_list = parse_connections(options["connections"]) volumes_list = parse_volumes(volumes) credentials = Credentials(user_id) server = servers.create(credentials, name, password, flavor, image_id, networks=connection_list, volumes=volumes_list, use_backend=backend, helper=helper_vm, project=project) pprint.pprint_server(server, stdout=self.stdout) wait = parse_bool(options["wait"]) common.wait_server_task(server, wait, self.stdout)
def create_server(request): # Normal Response Code: 202 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badMediaType(415), # itemNotFound (404), # badRequest (400), # serverCapacityUnavailable (503), # overLimit (413) req = utils.get_request_dict(request) user_id = request.user_uniq log.info('create_server user: %s request: %s', user_id, req) try: server = req['server'] name = server['name'] metadata = server.get('metadata', {}) assert isinstance(metadata, dict) image_id = server['imageRef'] flavor_id = server['flavorRef'] personality = server.get('personality', []) assert isinstance(personality, list) networks = server.get("networks") if networks is not None: assert isinstance(networks, list) except (KeyError, AssertionError): raise faults.BadRequest("Malformed request") # Verify that personalities are well-formed util.verify_personality(personality) # Get image information image = util.get_image_dict(image_id, user_id) # Get flavor (ensure it is active) flavor = util.get_flavor(flavor_id, include_deleted=False) if not flavor.allow_create: msg = ("It is not allowed to create a server from flavor with id '%d'," " see 'allow_create' flavor attribute") raise faults.Forbidden(msg % flavor.id) # Generate password password = util.random_password() vm = servers.create(user_id, name, password, flavor, image, metadata=metadata, personality=personality, networks=networks) server = vm_to_dict(vm, detail=True) server['status'] = 'BUILD' server['adminPass'] = password response = render_server(request, server, status=202) return response
def handle(self, *args, **options): if args: raise CommandError("Command doesn't accept any arguments") name = options['name'] user_id = options['user_id'] backend_id = options['backend_id'] image_id = options['image_id'] flavor_id = options['flavor_id'] password = options['password'] if not name: raise CommandError("name is mandatory") if not user_id: raise CommandError("user-id is mandatory") if not password: raise CommandError("password is mandatory") if not flavor_id: raise CommandError("flavor-id is mandatory") if not image_id: raise CommandError("image-id is mandatory") flavor = common.get_flavor(flavor_id) image = common.get_image(image_id, user_id) if backend_id: backend = common.get_backend(backend_id) else: backend = None connection_list = parse_connections(options["connections"]) server = servers.create(user_id, name, password, flavor, image, networks=connection_list, use_backend=backend) pprint.pprint_server(server, stdout=self.stdout) wait = parse_bool(options["wait"]) common.wait_server_task(server, wait, self.stdout)
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 create_server(request): # Normal Response Code: 202 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # badMediaType(415), # itemNotFound (404), # badRequest (400), # serverCapacityUnavailable (503), # overLimit (413) req = utils.get_json_body(request) credentials = request.credentials user_id = credentials.userid log.info("User: %s, Action: create_server, Request: %s", user_id, req) try: server = req['server'] name = server['name'] metadata = server.get('metadata', {}) assert isinstance(metadata, dict) image_id = server['imageRef'] flavor_id = server['flavorRef'] personality = server.get('personality', []) assert isinstance(personality, list) networks = server.get("networks") if networks is not None: assert isinstance(networks, list) project = server.get("project") shared_to_project = server.get("shared_to_project", False) key_name = server.get('key_name') user_data = server.get('user_data', "") SNF_key_names = server.get('SNF:key_names', []) assert isinstance(SNF_key_names, list) except (KeyError, AssertionError): raise faults.BadRequest("Malformed request") volumes = None dev_map = server.get("block_device_mapping_v2") if dev_map is not None: allowed_types = VOLUME_SOURCE_TYPES[:] if snapshots_enabled_for_user(request.user): allowed_types.append('snapshot') volumes = parse_block_device_mapping(dev_map, allowed_types) # If no project is provided, use the user's system project as default. if project is None: project = user_id # Verify that personalities are well-formed util.verify_personality(personality) # Verify that user_data are well-formed util.verify_user_data(user_data) # Get flavor (ensure it is active and project has access) flavor = util.get_flavor(flavor_id, credentials, include_deleted=False, for_project=project) if not util.can_create_flavor(flavor, request.user): msg = ("It is not allowed to create a server from flavor with id '%d'," " see 'allow_create' flavor attribute") raise faults.Forbidden(msg % flavor.id) # Generate password password = util.random_password() if key_name is not None: # If both key_name and SNF:key_names are provided we should # raise an error if len(SNF_key_names) > 0: raise faults.BadRequest('Only one of the SNF:key_names and' 'key_name can be set') # If only key_name is provided then we will set key_names as # a list with only one element else: key_names = [key_name] else: # In case key_name is not provided we will set key_names to the # value of SNF:key_names. We don't need to check if it is provided # since even if it is not, its value will be [] # Remove duplicate key names key_names = list(set(SNF_key_names)) vm = servers.create(credentials, name, password, flavor, image_id, metadata=metadata, personality=personality, user_data=user_data, project=project, networks=networks, volumes=volumes, shared_to_project=shared_to_project, key_names=key_names) log.info("User %s created VM %s, shared: %s", user_id, vm.id, shared_to_project) server = vm_to_dict(vm, detail=True) server['status'] = 'BUILD' server['adminPass'] = password set_password_in_cache(server['id'], password) response = render_server(request, server, status=202) return response
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): with patch( 'synnefo.logic.backend_allocator.update_backends_disk_templates' ) 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], ext_flavor) 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(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)
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)