Commit 5d2afa97 authored by Antoine Millet's avatar Antoine Millet
Browse files

Moved _list method of client handler to server class (become public).

parent 51e7b8d8
Loading
Loading
Loading
Loading
+72 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ from handlers import WelcomeHandler
from conf import CCConf
from client import CCClient
from exceptions import AlreadyRegistered
from tql import TqlQuery, TqlCondition, TqlLimit

class CCServer(object):
    '''
@@ -153,3 +154,74 @@ class CCServer(object):
        tags['__static_user'] = conf['tags']

        return tags

    def list(self, query):
        '''
        List objects on server.

        :param query: the TQL to use to select objects to list
        '''

        objects = []
        query = TqlQuery(query)

        for condition in query.iterconditions():
            if isinstance(condition, TqlCondition):
                tag_name = condition.name
                
                if tag_name in ('a', 'hv', 'h', 'id'):
                    # Append all accounts:
                    for login in self.conf.list_accounts():
                        tags = self.resolve_tags(login, query.req_tags)
                        objects.append(tags)

                if tag_name in ('vm', 'h', 'id'):
                    hvs = [o for o in objects if o['role'] == 'hypervisor'
                           and o['con'] != 'offline']
                    if not hvs:
                        for hy in self.iter_connected_role('hypervisor'):
                            tags = self.resolve_tags(hy.login, query.tags)
                            hvs.append(tags)

                    # Query the selected hypervisors:
                    logging.debug('Querying %d hypervisors: '
                                  '%s' % (len(hvs), hvs))
                    async_calls = {}
                    tags = tuple(query.tags)
                    for hy_tags in hvs:
                        hy = self.get_connection(hy_tags['a'])
                        cid = hy.connection.async_call('list_vm', tags=query.req_tags)
                        async_calls[cid] = hy_tags

                    logging.debug('Waiting for the response of hypervisors...')
                    calls = frozenset(async_calls)
                    responses = self.manager.wait(calls, timeout=5)
                    logging.debug('Responses received from hypervisors.')

                    for resp in responses:
                        if resp['error'] is None:
                            hy = async_calls[resp['id']]
                            for vm_tags in resp['return']:
                                vm_tags['role'] = 'vm'
                                vm_tags['id'] = '%s.%s' % (hy['a'], vm_tags['vm'])
                                vm_tags.update(hy['__static_user'])
                                objects.append(vm_tags)

                # Filter the tag
                objects = [o for o in objects if condition.check(o.get(tag_name))]

            elif isinstance(condition, TqlLimit):
                objects = objects[:condition.number]
                
        # Before to return, filter with the asked tags for each objects:
        tags = query.req_tags
        uniq_objects = {}
        if tags is not None:
            tags += ('id', 'role')
        for obj in objects:
            for key in obj.keys():
                if tags is not None and key not in tags or key.startswith('__'):
                    del obj[key]
            uniq_objects[obj['id']] = obj

        return uniq_objects.values()
+1 −68
Original line number Diff line number Diff line
@@ -4,7 +4,6 @@
import inspect
import logging
from sjrpc.utils import RpcHandler, pure
from tql import TqlQuery, TqlCondition, TqlLimit
from conf import CCConf
from exceptions import AlreadyRegistered, AuthenticationError

@@ -64,72 +63,6 @@ class ClientHandler(OnlineCCHandler):
    
    role_name = 'client'

    def _list(self, query):

        objects = []
        query = TqlQuery(query)

        for condition in query.iterconditions():
            if isinstance(condition, TqlCondition):
                tag_name = condition.name
                
                if tag_name in ('a', 'hv', 'h', 'id'):
                    # Append all accounts:
                    for login in self._server.conf.list_accounts():
                        tags = self._server.resolve_tags(login, query.req_tags)
                        objects.append(tags)

                if tag_name in ('vm', 'h', 'id'):
                    hvs = [o for o in objects if o['role'] == 'hypervisor'
                                   and o['con'] != 'offline']
                    if not hvs:
                        for hy in self._server.iter_connected_role('hypervisor'):
                            tags = self._server.resolve_tags(hy.login, query.tags)
                            hvs.append(tags)

                    # Query the selected hypervisors:
                    logging.debug('Querying %d hypervisors: '
                                  '%s' % (len(hvs), hvs))
                    async_calls = {}
                    tags = tuple(query.tags)
                    for hy_tags in hvs:
                        hy = self._server.get_connection(hy_tags['a'])
                        cid = hy.connection.async_call('list_vm', tags=query.req_tags)
                        async_calls[cid] = hy_tags

                    logging.debug('Waiting for the response of hypervisors...')
                    calls = frozenset(async_calls)
                    responses = self._server.manager.wait(calls, timeout=5)
                    logging.debug('Responses received from hypervisors.')

                    for resp in responses:
                        if resp['error'] is None:
                            hy = async_calls[resp['id']]
                            for vm_tags in resp['return']:
                                vm_tags['role'] = 'vm'
                                vm_tags['id'] = '%s.%s' % (hy['a'], vm_tags['vm'])
                                vm_tags.update(hy['__static_user'])
                                objects.append(vm_tags)

                # Filter the tag
                objects = [o for o in objects if condition.check(o.get(tag_name))]

            elif isinstance(condition, TqlLimit):
                objects = objects[:condition.number]
                
        # Before to return, filter with the asked tags for each objects:
        tags = query.req_tags
        uniq_objects = {}
        if tags is not None:
            tags += ('id', 'role')
        for obj in objects:
            for key in obj.keys():
                if tags is not None and key not in tags or key.startswith('__'):
                    del obj[key]
            uniq_objects[obj['id']] = obj

        return uniq_objects.values()

    @pure
    @listed
    def list(self, query):
@@ -138,7 +71,7 @@ class ClientHandler(OnlineCCHandler):
        '''

        logging.debug('Executed list function with query %s' % query)
        return self._list(query)
        return self._server.list(query)

    def _vm_action(self, query, method, *args, **kwargs):
        vms = self._list(query + '$vm')