Commit 3c64fb4d authored by Daniele Venzano's avatar Daniele Venzano

Execution list API filters

parent f16c6073
......@@ -127,7 +127,20 @@ class ExecutionCollectionAPI(RequestHandler):
"""
Returns a list of all active executions.
Return a list of all executions which have status equal to ..."
The list can be filtered by passing a non-empty JSON dictionary. Any combination of the following filters is supported:
* status: one of submitted, scheduled, starting, error, running, cleaning up, terminated
* name: execution mane
* user_id: user_id owning the execution (admin only)
* limit: limit the number of returned entries
* earlier_than_submit: all execution that where submitted earlier than this timestamp
* earlier_than_start: all execution that started earlier than this timestamp
* earlier_than_end: all execution that ended earlier than this timestamp
* later_than_submit: all execution that where submitted later than this timestamp
* later_than_start: all execution that started later than this timestamp
* later_than_end: all execution that started later than this timestamp
All timestamps should be passed as number of seconds since the epoch (UTC timezone).
example: curl -u 'username:password' -X GET -H "Content-Type: application/json" -d '{"status":"terminated"}' http://bf5:8080/api/0.6/execution
......@@ -137,16 +150,26 @@ class ExecutionCollectionAPI(RequestHandler):
filt_dict = {}
try:
if self.request.body:
filt_dict = tornado.escape.json_decode(self.request.body)
except ValueError:
raise zoe_api.exceptions.ZoeRestAPIException('Error decoding JSON data')
if 'status' in filt_dict:
execs = self.api_endpoint.execution_list(uid, role, status=filt_dict['status'])
filters = [
('status', str),
('name', str),
('user_id', str),
('limit', int),
('earlier_than_submit', int),
('earlier_than_start', int),
('earlier_than_end', int),
('later_than_submit', int),
('later_than_start', int),
('later_than_end', int)
]
for f in filters:
if f[0] in self.request.arguments:
if f[1] == str:
filt_dict[f[0]] = self.request.arguments[f[0]][0].decode('utf-8')
else:
execs = self.api_endpoint.execution_list(uid, role)
filt_dict[f[0]] = f[1](self.request.arguments[f[0]][0])
execs = self.api_endpoint.execution_list(uid, role, **filt_dict)
self.write(dict([(e.id, e.serialize()) for e in execs]))
......
......@@ -66,10 +66,26 @@ def app_get_cmd(args):
json.dump(execution['description'], sys.stdout, sort_keys=True, indent=4)
def exec_list_cmd(args_):
def exec_list_cmd(args):
"""List executions"""
exec_api = ZoeExecutionsAPI(utils.zoe_url(), utils.zoe_user(), utils.zoe_pass())
data = exec_api.list()
filter_names = [
'status',
'name',
'user_id',
'limit',
'earlier_than_submit',
'earlier_than_start',
'earlier_than_end',
'later_than_submit',
'later_than_start',
'later_than_end'
]
filters = {}
for k, v in vars(args).items():
if k in filter_names:
filters[k] = v
data = exec_api.list(**filters)
for e in sorted(data.values(), key=lambda x: x['id']):
print('Execution {} (User: {}, ID: {}): {}'.format(e['name'], e['user_id'], e['id'], e['status']))
......@@ -181,6 +197,16 @@ def process_arguments() -> Tuple[ArgumentParser, Namespace]:
argparser_exec_start.set_defaults(func=exec_start_cmd)
argparser_app_list = subparser.add_parser('exec-ls', help="List all executions for the calling user")
argparser_app_list.add_argument('--limit', type=int, help='Limit the number of executions')
argparser_app_list.add_argument('--name', help='Show only executions with this name')
argparser_app_list.add_argument('--user', help='Show only executions belonging to this user')
argparser_app_list.add_argument('--status', choices=["submitted", "scheduled", "starting", "error", "running", "cleaning up", "terminated"], help='Show only executions with this status')
argparser_app_list.add_argument('--earlier-than-submit', help='Show only executions submitted earlier than this timestamp (seconds since UTC epoch)')
argparser_app_list.add_argument('--earlier-than-start', help='Show only executions submitted earlier than this timestamp (seconds since UTC epoch)')
argparser_app_list.add_argument('--earlier-than-end', help='Show only executions submitted earlier than this timestamp (seconds since UTC epoch)')
argparser_app_list.add_argument('--later-than-submit', help='Show only executions submitted earlier than this timestamp (seconds since UTC epoch)')
argparser_app_list.add_argument('--later-than-start', help='Show only executions submitted earlier than this timestamp (seconds since UTC epoch)')
argparser_app_list.add_argument('--later-than-end', help='Show only executions submitted earlier than this timestamp (seconds since UTC epoch)')
argparser_app_list.set_defaults(func=exec_list_cmd)
argparser_execution_get = subparser.add_parser('exec-get', help="Get execution status")
......@@ -195,9 +221,9 @@ def process_arguments() -> Tuple[ArgumentParser, Namespace]:
argparser_execution_kill.add_argument('id', type=int, help="Execution id")
argparser_execution_kill.set_defaults(func=exec_kill_cmd)
argparser_execution_kill = subparser.add_parser('exec-rm', help="Deletes an execution")
argparser_execution_kill.add_argument('id', type=int, help="Execution id")
argparser_execution_kill.set_defaults(func=exec_rm_cmd)
argparser_execution_rm = subparser.add_parser('exec-rm', help="Deletes an execution")
argparser_execution_rm.add_argument('id', type=int, help="Execution id")
argparser_execution_rm.set_defaults(func=exec_rm_cmd)
argparser_stats = subparser.add_parser('stats', help="Prints all available statistics")
argparser_stats.set_defaults(func=stats_cmd)
......
......@@ -79,14 +79,15 @@ class ZoeAPIBase:
return req, req.status_code
@retry(ZoeAPIException)
def _rest_get(self, path):
def _rest_get(self, path, payload=None):
"""
:type path: str
:type payload: dict
:rtype: (dict, int)
"""
url = self.url + '/api/' + ZOE_API_VERSION + path
try:
req = requests.get(url, auth=(self.user, self.password))
req = requests.get(url, auth=(self.user, self.password), params=payload)
except requests.exceptions.Timeout:
raise ZoeAPIException('HTTP connection timeout')
except requests.exceptions.HTTPError:
......
......@@ -61,13 +61,26 @@ class ZoeExecutionsAPI(ZoeAPIBase):
else:
raise ZoeAPIException(data['message'])
def list(self):
def list(self, **kwargs):
"""
Returns a list of all executions for the calling user, all of them if the user is admin.
The list can be filtered by passing arguments. Any combination of the following filters is supported:
* status: one of submitted, scheduled, starting, error, running, cleaning up, terminated
* name: execution mane
* user_id: user_id owning the execution (admin only)
* limit: limit the number of returned entries
* earlier_than_submit: all execution that where submitted earlier than this timestamp
* earlier_than_start: all execution that started earlier than this timestamp
* earlier_than_end: all execution that ended earlier than this timestamp
* later_than_submit: all execution that where submitted later than this timestamp
* later_than_start: all execution that started later than this timestamp
* later_than_end: all execution that started later than this timestamp
:return:
"""
data, status_code = self._rest_get('/execution')
data, status_code = self._rest_get('/execution', kwargs)
if status_code == 200:
return data
else:
......
......@@ -59,12 +59,14 @@ class SQLManager:
cur.execute('SET search_path TO {},public'.format(self.schema))
return cur
def execution_list(self, only_one=False, **kwargs):
def execution_list(self, only_one=False, limit=-1, **kwargs):
"""
Return a list of executions.
:param only_one: only one result is expected
:type only_one: bool
:param limit: limit the result to this number of entries
:type limit: int
:param kwargs: filter executions based on their fields/columns
:return: one or more executions
"""
......@@ -75,11 +77,28 @@ class SQLManager:
filter_list = []
args_list = []
for key, value in kwargs.items():
if key == 'earlier_than_submit':
filter_list.append('"time_submit" <= to_timestamp(%s)')
elif key == 'earlier_than_start':
filter_list.append('"time_start" <= to_timestamp(%s)')
elif key == 'earlier_than_end':
filter_list.append('"time_end" <= to_timestamp(%s)')
elif key == 'later_than_submit':
filter_list.append('"time_submit" >= to_timestamp(%s)')
elif key == 'later_than_start':
filter_list.append('"time_start" >= to_timestamp(%s)')
elif key == 'later_than_end':
filter_list.append('"time_end" >= to_timestamp(%s)')
else:
filter_list.append('{} = %s'.format(key))
args_list.append(value)
q += ' AND '.join(filter_list)
if limit > 0:
q += ' LIMIT {}'.format(limit)
query = cur.mogrify(q, args_list)
else:
if limit > 0:
q_base += ' LIMIT {}'.format(limit)
query = cur.mogrify(q_base)
cur.execute(query)
......
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