Commit 3a3d6907 authored by Antoine Millet's avatar Antoine Millet

Added "#" separator.

parent ccc6335e
......@@ -4,7 +4,7 @@
import inspect
import logging
from sjrpc.utils import RpcHandler, pure
from tql import TqlQuery
from tql import TqlQuery, TqlCondition, TqlLimit
from conf import CCConf
from exceptions import AlreadyRegistered, AuthenticationError
......@@ -70,49 +70,53 @@ class ClientHandler(OnlineCCHandler):
query = TqlQuery(query)
for condition in query.iterconditions():
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.tags)
objects.append(tags)
if tag_name in ('vm', 'h', 'id'):
hvs = [o for o in objects if o['role'] == 'hypervisor'
and o['status'] == 'online']
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=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))]
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.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=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.tags
tags.add('id')
......
......@@ -59,6 +59,14 @@ class TqlCondition(object):
def check(self, value):
return self.operator(value, self.value) ^ self.invert
class TqlLimit(object):
def __init__(self, number):
self.number = number
def __repr__(self):
return '<TqlLimit object [%s]>' % self.number
class TqlQuery(object):
'''
Parse a query written with TQL (Tag Query Language) and allow to filter a
......@@ -75,12 +83,11 @@ class TqlQuery(object):
'<=': 'lte',
'~': 'regex'}
RE_COND = re.compile(r'^(?P<name>[a-z-A-Z0-9_-]+)'
r'((?P<operator>[!$<>~:=]{1,3})'
r'(?P<value>[^&]+))?$')
RE_COND = re.compile(r'^(?P<name>[a-z-A-Z0-9_?*-]+)'
r'((?P<operator>[!<>~:=]{1,3})'
r'(?P<value>[^&$#]+?))?$')
RE_TAG = re.compile(r'^(?P<name>[a-z-A-Z0-9_-]+)')
RE_SEPARATOR = re.compile(r'(&|\$)')
RE_SEPARATOR = re.compile(r'(&|\$|#)')
def __init__(self, query):
self._conditions = []
......@@ -151,6 +158,14 @@ class TqlQuery(object):
raise TqlParsingError('Error while parsing, invalid tag '
'name %s' % repr(tok))
elif sep == '#':
if tok.isdigit():
lim = TqlLimit(int(tok))
self._conditions.append(lim)
else:
raise TqlParsingError('Error while parsing, invalid limit '
'%s' % repr(tok))
def has_condition(self, tag_name):
'''
Return True if query has made a condition for the specified tag name.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment