Commit c809dbaa authored by Xavier Thompson's avatar Xavier Thompson

cli/(.*)list: Implement optional ad-hoc --limit

parent d8b44acc
...@@ -40,6 +40,10 @@ class ListCommand(ClientConfigCommand): ...@@ -40,6 +40,10 @@ class ListCommand(ClientConfigCommand):
def get_parser(self, prog_name): def get_parser(self, prog_name):
ap = super(ListCommand, self).get_parser(prog_name) ap = super(ListCommand, self).get_parser(prog_name)
ap.add_argument('--limit',
type=int,
help='Count limit')
return ap return ap
def take_action(self, args): def take_action(self, args):
...@@ -52,7 +56,7 @@ class ListCommand(ClientConfigCommand): ...@@ -52,7 +56,7 @@ class ListCommand(ClientConfigCommand):
def do_list(logger, conf, local): def do_list(logger, conf, local):
resetLogger(logger) resetLogger(logger)
computer_dict = local['slap'].getComputerDict() computer_dict = local['slap'].getComputerDict(limit=conf.limit)
if computer_dict == {}: if computer_dict == {}:
logger.info('No existing computer.') logger.info('No existing computer.')
return return
......
...@@ -41,6 +41,11 @@ class ListCommand(ClientConfigCommand): ...@@ -41,6 +41,11 @@ class ListCommand(ClientConfigCommand):
def get_parser(self, prog_name): def get_parser(self, prog_name):
ap = super(ListCommand, self).get_parser(prog_name) ap = super(ListCommand, self).get_parser(prog_name)
ap.add_argument('--limit',
type=int,
help='Count limit')
return ap return ap
def take_action(self, args): def take_action(self, args):
...@@ -54,7 +59,7 @@ class ListCommand(ClientConfigCommand): ...@@ -54,7 +59,7 @@ class ListCommand(ClientConfigCommand):
def do_list(logger, conf, local): def do_list(logger, conf, local):
resetLogger(logger) resetLogger(logger)
# XXX catch exception # XXX catch exception
instance_dict = local['slap'].getOpenOrderDict() instance_dict = local['slap'].getOpenOrderDict(limit=conf.limit)
logger.info( logger.info(
json.dumps( json.dumps(
{title: instance._software_release_url {title: instance._software_release_url
......
...@@ -60,6 +60,9 @@ ALLOWED_JIO_FIELD_LIST = [ ...@@ -60,6 +60,9 @@ ALLOWED_JIO_FIELD_LIST = [
"FloatField", "FloatField",
"TextAreaField"] "TextAreaField"]
JIO_QUERY_DEFAULT_LIMIT = 40
class TempDocument(object): class TempDocument(object):
def __init__(self, **kw): def __init__(self, **kw):
""" """
...@@ -272,15 +275,14 @@ class HateoasNavigator(object): ...@@ -272,15 +275,14 @@ class HateoasNavigator(object):
"form_data": form_data_dict "form_data": form_data_dict
} }
def jio_allDocs(self, query): def jio_allDocs(self, **query):
# by default search_url is a Python script (ERP5Document_getHateoas) # by default search_url is a Python script (ERP5Document_getHateoas)
# which enforces a too low limit of what is to be returned (default = 10) # which enforces a too low limit of what is to be returned (default = 10)
# as testnode uses this to introspect created ERP5 instance which usually has # as testnode uses this to introspect created ERP5 instance which usually has
# at least 18 sub instances this limit is too low thus we need to explicitly # at least 18 sub instances this limit is too low thus we need to explicitly
# increase it. 40 is the de-facto default ERP5 preference for number of objects # increase it. 40 is the de-facto default ERP5 preference for number of objects
# which are usually to be rendered in alistbox 'view' mode # which are usually to be rendered in alistbox 'view' mode
if 'limit' not in query: query.setdefault('limit', JIO_QUERY_DEFAULT_LIMIT)
query['limit'] = 40
search_url = self._getSearchUrl() search_url = self._getSearchUrl()
getter_link = expand(search_url, query) getter_link = expand(search_url, query)
...@@ -342,17 +344,19 @@ class SlapHateoasNavigator(HateoasNavigator): ...@@ -342,17 +344,19 @@ class SlapHateoasNavigator(HateoasNavigator):
############################################################### ###############################################################
# API for Client as a Person # API for Client as a Person
############################################################### ###############################################################
def _getInstanceTreeList(self, title=None, select_list=["title", "url_string"]): def _getInstanceTreeList(self, title=None, select_list=("title", "url_string"), limit=None):
query_str = 'portal_type:"Instance Tree" AND validation_state:validated' query_str = 'portal_type:"Instance Tree" AND validation_state:validated'
if title is not None: if title is not None:
query_str = 'portal_type:"Instance Tree" AND validation_state:validated AND title:="%s"' % title query_str = 'portal_type:"Instance Tree" AND validation_state:validated AND title:="%s"' % title
result = self.jio_allDocs( result = self.jio_allDocs(
query={"query" : query_str, "select_list": select_list}) query=query_str,
select_list=select_list,
limit=limit or JIO_QUERY_DEFAULT_LIMIT)
return result['data']['rows'] return result['data']['rows']
def _getComputerList(self, title=None, reference=None, select_list=["title", "reference"]): def _getComputerList(self, title=None, reference=None, select_list=("title", "reference"), limit=None):
query_str = 'portal_type:"Computer" AND validation_state:validated' query_str = 'portal_type:"Computer" AND validation_state:validated'
if title is not None: if title is not None:
query_str += ' AND title:="%s"' % title query_str += ' AND title:="%s"' % title
...@@ -361,23 +365,27 @@ class SlapHateoasNavigator(HateoasNavigator): ...@@ -361,23 +365,27 @@ class SlapHateoasNavigator(HateoasNavigator):
query_str += ' AND reference:="%s"' % reference query_str += ' AND reference:="%s"' % reference
result = self.jio_allDocs( result = self.jio_allDocs(
query={"query" : query_str, "select_list": select_list}) query=query_str,
select_list=select_list,
limit=limit or JIO_QUERY_DEFAULT_LIMIT)
return result['data']['rows'] return result['data']['rows']
def getInstanceTreeInstanceList(self, title): def getInstanceTreeInstanceList(self, title, limit=None):
select_list = ['uid', 'title', 'relative_url', 'portal_type', select_list = ['uid', 'title', 'relative_url', 'portal_type',
'url_string', 'text_content', 'getConnectionXmlAsDict', 'url_string', 'text_content', 'getConnectionXmlAsDict',
'SoftwareInstance_getNewsDict'] 'SoftwareInstance_getNewsDict']
query_str = 'portal_type:("Software Instance", "Slave Instance") AND validation_state:validated' query_str = 'portal_type:("Software Instance", "Slave Instance") AND validation_state:validated'
query_str += ' AND default_specialise_title:="%s"' % title query_str += ' AND default_specialise_title:="%s"' % title
result = self.jio_allDocs( result = self.jio_allDocs(
query={"query" : query_str, "select_list": select_list}) query=query_str,
select_list=select_list,
limit=limit or JIO_QUERY_DEFAULT_LIMIT)
return result['data']['rows'] return result['data']['rows']
def getInstanceTreeDict(self, title=None): def getInstanceTreeDict(self, title=None, limit=None):
instance_tree_list = self._getInstanceTreeList(title=title) instance_tree_list = self._getInstanceTreeList(title=title, limit=limit)
instance_tree_dict = {} instance_tree_dict = {}
for instance_tree in instance_tree_list: for instance_tree in instance_tree_list:
software_instance = TempDocument() software_instance = TempDocument()
...@@ -390,8 +398,8 @@ class SlapHateoasNavigator(HateoasNavigator): ...@@ -390,8 +398,8 @@ class SlapHateoasNavigator(HateoasNavigator):
return instance_tree_dict return instance_tree_dict
def getComputerDict(self): def getComputerDict(self, limit=None):
computer_list = self._getComputerList() computer_list = self._getComputerList(limit=None)
computer_dict = {} computer_dict = {}
for computer_json in computer_list: for computer_json in computer_list:
computer = TempDocument() computer = TempDocument()
...@@ -448,13 +456,16 @@ class SlapHateoasNavigator(HateoasNavigator): ...@@ -448,13 +456,16 @@ class SlapHateoasNavigator(HateoasNavigator):
return self.jio_get(computer_jio_key) return self.jio_get(computer_jio_key)
def getSoftwareInstallationList(self, computer_guid=None, def getSoftwareInstallationList(self, computer_guid=None,
select_list=['uid', 'relative_url', 'url_string', 'SoftwareInstallation_getNewsDict']): select_list=('uid', 'relative_url', 'url_string', 'SoftwareInstallation_getNewsDict'),
limit=None):
query_str = 'portal_type:"Software Installation" AND validation_state:validated' query_str = 'portal_type:"Software Installation" AND validation_state:validated'
if computer_guid is not None: if computer_guid is not None:
query_str += ' AND default_aggregate_reference:="%s"' % computer_guid query_str += ' AND default_aggregate_reference:="%s"' % computer_guid
result = self.jio_allDocs( result = self.jio_allDocs(
query={"query" : query_str, "select_list": select_list}) query=query_str,
select_list=select_list,
limit=limit or JIO_QUERY_DEFAULT_LIMIT)
return result['data']['rows'] return result['data']['rows']
......
...@@ -887,13 +887,13 @@ class slap: ...@@ -887,13 +887,13 @@ class slap:
assert(type(result) == list) assert(type(result) == list)
return result return result
def getOpenOrderDict(self): def getOpenOrderDict(self, limit=None):
if not getattr(self, '_hateoas_navigator', None): if not getattr(self, '_hateoas_navigator', None):
raise Exception('SlapOS Master Hateoas API required for this operation is not available.') raise Exception('SlapOS Master Hateoas API required for this operation is not available.')
return self._hateoas_navigator.getInstanceTreeDict() return self._hateoas_navigator.getInstanceTreeDict(limit=limit)
def getComputerDict(self): def getComputerDict(self, limit=None):
if not getattr(self, '_hateoas_navigator', None): if not getattr(self, '_hateoas_navigator', None):
raise Exception('SlapOS Master Hateoas API required for this operation is not available.') raise Exception('SlapOS Master Hateoas API required for this operation is not available.')
return self._hateoas_navigator.getComputerDict() return self._hateoas_navigator.getComputerDict(limit=limit)
...@@ -594,6 +594,10 @@ class TestCliNode(CliMixin): ...@@ -594,6 +594,10 @@ class TestCliNode(CliMixin):
class TestCliList(CliMixin): class TestCliList(CliMixin):
def setUp(self):
super(TestCliList, self).setUp()
self.conf.limit = None
def test_list(self): def test_list(self):
""" """
Test "slapos service list" command output. Test "slapos service list" command output.
...@@ -705,6 +709,10 @@ class TestCliInfo(CliMixin): ...@@ -705,6 +709,10 @@ class TestCliInfo(CliMixin):
self.logger.warning.assert_called_once_with('Instance %s does not exist.', self.conf.reference) self.logger.warning.assert_called_once_with('Instance %s does not exist.', self.conf.reference)
class TestCliComputerList(CliMixin): class TestCliComputerList(CliMixin):
def setUp(self):
super(TestCliComputerList, self).setUp()
self.conf.limit = None
def test_computer_list(self): def test_computer_list(self):
""" """
Test "slapos computer list" command output. Test "slapos computer list" command output.
...@@ -714,14 +722,14 @@ class TestCliComputerList(CliMixin): ...@@ -714,14 +722,14 @@ class TestCliComputerList(CliMixin):
'computer2': slapos.slap.hateoas.TempDocument(title='computer2', _reference='COMP-0'), 'computer2': slapos.slap.hateoas.TempDocument(title='computer2', _reference='COMP-0'),
} }
with patch.object(slapos.slap.slap, 'getComputerDict', return_value=return_value) as _: with patch.object(slapos.slap.slap, 'getComputerDict', return_value=return_value) as _:
slapos.cli.computer_list.do_list(self.logger, None, self.local) slapos.cli.computer_list.do_list(self.logger, self.conf, self.local)
self.logger.info.assert_any_call('%s %s', 'COMP-1', 'computer1') self.logger.info.assert_any_call('%s %s', 'COMP-1', 'computer1')
self.logger.info.assert_any_call('%s %s', 'COMP-0', 'computer2') self.logger.info.assert_any_call('%s %s', 'COMP-0', 'computer2')
def test_computer_emptyList(self): def test_computer_emptyList(self):
with patch.object(slapos.slap.slap, 'getComputerDict', return_value={}) as _: with patch.object(slapos.slap.slap, 'getComputerDict', return_value={}) as _:
slapos.cli.computer_list.do_list(self.logger, None, self.local) slapos.cli.computer_list.do_list(self.logger, self.conf, self.local)
self.logger.info.assert_called_once_with('No existing computer.') self.logger.info.assert_called_once_with('No existing computer.')
......
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