~ubuntu-branches/ubuntu/precise/maas/precise-security

« back to all changes in this revision

Viewing changes to src/maasserver/api.py

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez, Dave Walker (Daviey), Andres Rodriguez
  • Date: 2012-03-27 14:49:56 UTC
  • mfrom: (1.1.7)
  • Revision ID: package-import@ubuntu.com-20120327144956-zezstgry6t61438x
Tags: 0.1+bzr363+dfsg-0ubuntu1
[ Dave Walker (Daviey) ]
* debian/control: Add openssh-server as a Recommends, and wrap-and-sort. 

[ Andres Rodriguez ]
* debian/maas.postinst:
  - Do not start apache with apache2ctl. Use invoke-rc.d instead to not
    fail in the installer.
  - For start of postgresql before creating the DB, otherwise it will
    fail in the installer.
  - Add check of invoke-rc.d for syslog.
  - Add check of invoke-rc.d for rabbitmq-server; Add check for rabbitmqctl
  - Add db_stop, in case invoke-rc.d fails.
* debian/control: Tight python-django-maas dependency.
* debian/postrm: Add check for rabbitmqctl.
* debian/maas.maas-txlongpoll.upstart: Create rabbitmq longpoll user/vhost
  and set permissions if they don't exist. Start on rabbitmq-server-running.

Show diffs side-by-side

added added

removed removed

Lines of Context:
56
56
    MACAddress,
57
57
    Node,
58
58
    NODE_STATUS,
59
 
    NODE_STATUS_CHOICES_DICT,
60
59
    )
61
60
from piston.doc import generate_doc
62
61
from piston.handler import (
350
349
        else:
351
350
            raise NodeStateViolation(
352
351
                "Node cannot be released in its current state ('%s')."
353
 
                % NODE_STATUS_CHOICES_DICT.get(node.status, "UNKNOWN"))
 
352
                % node.display_status())
354
353
        return node
355
354
 
356
355
 
380
379
        return ('nodes_handler', [])
381
380
 
382
381
 
 
382
def extract_constraints(request_params):
 
383
    """Extract a dict of node allocation constraints from http parameters.
 
384
 
 
385
    :param request_params: Parameters submitted with the allocation request.
 
386
    :type request_params: :class:`django.http.QueryDict`
 
387
    :return: A mapping of applicable constraint names to their values.
 
388
    :rtype: :class:`dict`
 
389
    """
 
390
    name = request_params.get('name', None)
 
391
    if name is None:
 
392
        return {}
 
393
    else:
 
394
        return {'name': name}
 
395
 
 
396
 
383
397
@api_operations
384
398
class NodesHandler(BaseHandler):
385
399
    """Manage collection of Nodes."""
414
428
        assert key is not None, (
415
429
            "Invalid Authorization header on request.")
416
430
        token = Token.objects.get(key=key)
417
 
        nodes = Node.objects.get_allocated_visible_nodes(token)
 
431
        match_ids = request.GET.getlist('id')
 
432
        if match_ids == []:
 
433
            match_ids = None
 
434
        nodes = Node.objects.get_allocated_visible_nodes(token, match_ids)
418
435
        return nodes.order_by('id')
419
436
 
420
437
    @api_exported('acquire', 'POST')
421
438
    def acquire(self, request):
422
439
        """Acquire an available node for deployment."""
423
 
        node = Node.objects.get_available_node_for_acquisition(request.user)
 
440
        node = Node.objects.get_available_node_for_acquisition(
 
441
            request.user, constraints=extract_constraints(request.data))
424
442
        if node is None:
425
 
            raise NodesNotAvailable("No node is available.")
 
443
            raise NodesNotAvailable("No matching node is available.")
426
444
        auth_header = request.META.get("HTTP_AUTHORIZATION")
427
445
        assert auth_header is not None, (
428
446
            "HTTP_AUTHORIZATION not set on request")
502
520
        return ('node_mac_handler', [node_system_id, mac_address])
503
521
 
504
522
 
505
 
def get_file(request):
 
523
def get_file(handler, request):
 
524
    """Get a named file from the file storage.
 
525
 
 
526
    :param filename: The exact name of the file you want to get.
 
527
    :type filename: string
 
528
    :return: The file is returned in the response content.
 
529
    """
506
530
    filename = request.GET.get("filename", None)
507
531
    if not filename:
508
532
        raise MAASAPIBadRequest("Filename not supplied")
515
539
 
516
540
@api_operations
517
541
class AnonFilesHandler(AnonymousBaseHandler):
518
 
    """Anonymous file operations."""
 
542
    """Anonymous file operations.
 
543
 
 
544
    This is needed for Juju. The story goes something like this:
 
545
 
 
546
    - The Juju provider will upload a file using an "unguessable" name.
 
547
 
 
548
    - The name of this file (or its URL) will be shared with all the agents in
 
549
      the environment. They cannot modify the file, but they can access it
 
550
      without credentials.
 
551
 
 
552
    """
519
553
    allowed_methods = ('GET',)
520
554
 
521
 
    @api_exported('get', 'GET')
522
 
    def get(self, request):
523
 
        """Get a named file from the file storage.
524
 
 
525
 
        :param filename: The exact name of the file you want to get.
526
 
        :type filename: string
527
 
        :return: The file is returned in the response content.
528
 
        """
529
 
        return get_file(request)
 
555
    get = api_exported('get', 'GET')(get_file)
530
556
 
531
557
 
532
558
@api_operations
535
561
    allowed_methods = ('GET', 'POST',)
536
562
    anonymous = AnonFilesHandler
537
563
 
538
 
    @api_exported('get', 'GET')
539
 
    def get(self, request):
540
 
        """Get a named file from the file storage.
541
 
 
542
 
        :param filename: The exact name of the file you want to get.
543
 
        :type filename: string
544
 
        :return: The file is returned in the response content.
545
 
        """
546
 
        return get_file(request)
 
564
    get = api_exported('get', 'GET')(get_file)
547
565
 
548
566
    @api_exported('add', 'POST')
549
567
    def add(self, request):