Revision dca7553e snf-cyclades-app/synnefo/api/servers.py

b/snf-cyclades-app/synnefo/api/servers.py
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
from base64 import b64decode
35

  
36 34
from django.conf import settings
37 35
from django.conf.urls.defaults import patterns
38 36
from django.db import transaction
......
48 46
from synnefo.logic.utils import get_rsapi_state
49 47
from synnefo.logic.rapi import GanetiApiError
50 48
from synnefo.logic.backend_allocator import BackendAllocator
51
from random import choice
52 49

  
53 50

  
54 51
from logging import getLogger
......
258 255
    try:
259 256
        req = util.get_request_dict(request)
260 257
        log.info('create_server %s', req)
258
        user_id = request.user_uniq
261 259

  
262 260
        try:
263 261
            server = req['server']
......
274 272
        if len(personality) > settings.MAX_PERSONALITY:
275 273
            raise faults.OverLimit("Maximum number of personalities exceeded")
276 274

  
277
        for p in personality:
278
            # Verify that personalities are well-formed
279
            try:
280
                assert isinstance(p, dict)
281
                keys = set(p.keys())
282
                allowed = set(['contents', 'group', 'mode', 'owner', 'path'])
283
                assert keys.issubset(allowed)
284
                contents = p['contents']
285
                if len(contents) > settings.MAX_PERSONALITY_SIZE:
286
                    # No need to decode if contents already exceed limit
287
                    raise faults.OverLimit("Maximum size of personality exceeded")
288
                if len(b64decode(contents)) > settings.MAX_PERSONALITY_SIZE:
289
                    raise faults.OverLimit("Maximum size of personality exceeded")
290
            except AssertionError:
291
                raise faults.BadRequest("Malformed personality in request")
292

  
293
        image = {}
294
        img = util.get_image(image_id, request.user_uniq)
295
        properties = img.get('properties', {})
296
        image['backend_id'] = img['location']
297
        image['format'] = img['disk_format']
298
        image['metadata'] = dict((key.upper(), val) \
299
                                 for key, val in properties.items())
300

  
301
        # Ensure that request if for active flavor
302
        flavor = util.get_flavor(flavor_id, include_deleted=False)
275
        util.verify_personality(personality)
276
        image = util.get_image_dict(image_id, user_id)
277
        flavor = util.get_flavor(flavor_id)
303 278
        password = util.random_password()
304 279

  
305
        count = VirtualMachine.objects.filter(userid=request.user_uniq,
280
        count = VirtualMachine.objects.filter(userid=user_id,
306 281
                                              deleted=False).count()
307 282

  
308 283
        # get user limit
309 284
        vms_limit_for_user = \
310
            settings.VMS_USER_QUOTA.get(request.user_uniq,
285
            settings.VMS_USER_QUOTA.get(user_id,
311 286
                    settings.MAX_VMS_PER_USER)
312 287

  
313 288
        if count >= vms_limit_for_user:
......
326 301
        transaction.commit()
327 302

  
328 303
    try:
329
        if settings.PUBLIC_USE_POOL:
330
            (network, address) = util.allocate_public_address(backend)
331
            if address is None:
332
                log.error("Public networks of backend %s are full", backend)
333
                msg = "Failed to allocate public IP for new VM"
334
                raise faults.ServiceUnavailable(msg)
335
            nic = {'ip': address, 'network': network.backend_id}
336
        else:
337
            network = choice(list(util.backend_public_networks(backend)))
338
            nic = {'ip': 'pool', 'network': network.backend_id}
304
        (network, address) = util.get_public_ip(backend)
305
        nic = {'ip': address, 'network': network.backend_id}
339 306
    except:
340 307
        transaction.rollback()
341
        raise
342 308
    else:
343 309
        transaction.commit()
344 310

  
......
348 314
        vm = VirtualMachine.objects.create(
349 315
            name=name,
350 316
            backend=backend,
351
            userid=request.user_uniq,
317
            userid=user_id,
352 318
            imageid=image_id,
353 319
            flavor=flavor,
354 320
            action="CREATE")
355 321

  
356 322
        try:
357
            jobID = create_instance(vm, nic, flavor, image, password, personality)
323
            jobID = create_instance(vm, nic, flavor, image, password,
324
                                    personality)
358 325
        except GanetiApiError:
359 326
            vm.delete()
360 327
            raise
361 328

  
362 329
        log.info("User %s created VM %s, NIC %s, Backend %s, JobID %s",
363
                request.user_uniq, vm, nic, backend, str(jobID))
330
                user_id, vm, nic, backend, str(jobID))
364 331

  
365 332
        vm.backendjobid = jobID
366 333
        vm.save()

Also available in: Unified diff