Commit ebe7240e authored by Xavier Thompson's avatar Xavier Thompson

cli/info: Include news digest in service info

See merge request nexedi/slapos.core!497
parents 3006cb19 f94eef59
...@@ -54,6 +54,10 @@ class InfoCommand(ClientConfigCommand): ...@@ -54,6 +54,10 @@ class InfoCommand(ClientConfigCommand):
ap.add_argument('reference', ap.add_argument('reference',
help='Your instance reference') help='Your instance reference')
ap.add_argument('--news',
action='store_true',
help='Include raw news in output')
return ap return ap
def take_action(self, args): def take_action(self, args):
...@@ -98,14 +102,32 @@ def do_info(logger, conf, local): ...@@ -98,14 +102,32 @@ def do_info(logger, conf, local):
if '_' in connection_parameter_dict: if '_' in connection_parameter_dict:
connection_parameter_dict = json.loads(connection_parameter_dict['_']) connection_parameter_dict = json.loads(connection_parameter_dict['_'])
logger.info(
json.dumps( info = {
{
'software-url': instance._software_release_url, 'software-url': instance._software_release_url,
'instance-state': instance._requested_state, 'requested-state': instance._requested_state,
'instance-parameters': instance._parameter_dict, 'instance-parameters': instance._parameter_dict,
'connection-parameters': connection_parameter_dict, 'connection-parameters': connection_parameter_dict,
}, }
indent=2,
) try:
) news = instance._news['instance']
except (AttributeError, KeyError):
info['status'] = 'unsupported'
else:
# 2 bits : 00 -> none, 01 -> green, 10 -> red, 11 -> orange
status = 0b00
for e in news:
text = e.get('text', '')
if text.startswith('#access'):
status |= 0b01
elif text.startswith('#error'):
status |= 0b10
if status == 0b11:
break
info['status'] = ('none', 'green', 'red', 'orange')[status]
if conf.news:
info['news'] = news
logger.info(json.dumps(info, indent=2))
...@@ -1084,6 +1084,7 @@ def hateoas_partitions(partition_reference): ...@@ -1084,6 +1084,7 @@ def hateoas_partitions(partition_reference):
partition = execute_db('partition', 'SELECT * FROM %s WHERE partition_reference=?', [partition_reference], one=True) partition = execute_db('partition', 'SELECT * FROM %s WHERE partition_reference=?', [partition_reference], one=True)
if partition is None: if partition is None:
abort(404) abort(404)
# my_slap_state corresponds to requested_state, not slap_state.
return { return {
'_embedded': { '_embedded': {
'_view': { '_view': {
...@@ -1100,7 +1101,7 @@ def hateoas_partitions(partition_reference): ...@@ -1100,7 +1101,7 @@ def hateoas_partitions(partition_reference):
'my_slap_state': { 'my_slap_state': {
'type': 'StringField', 'type': 'StringField',
'key': 'slap_state', 'key': 'slap_state',
'default': partition['slap_state'], 'default': partition['requested_state'],
}, },
'my_text_content': { 'my_text_content': {
'type': 'StringField', 'type': 'StringField',
......
##############################################################################
# #
# Copyright (c) 2013 Vifib SARL and Contributors. All Rights Reserved. # Copyright (c) 2013 Vifib SARL and Contributors. All Rights Reserved.
# #
...@@ -40,7 +40,7 @@ import pkg_resources ...@@ -40,7 +40,7 @@ import pkg_resources
from contextlib import contextmanager from contextlib import contextmanager
from mock import patch, create_autospec from mock import patch, create_autospec
import mock import mock
from slapos.util import sqlite_connect, bytes2str, UndefinedSerializationError from slapos.util import sqlite_connect, bytes2str, UndefinedSerializationError, dict2xml
from slapos.slap.slap import DEFAULT_SOFTWARE_TYPE from slapos.slap.slap import DEFAULT_SOFTWARE_TYPE
import slapos.cli.console import slapos.cli.console
...@@ -617,45 +617,81 @@ class TestCliList(CliMixin): ...@@ -617,45 +617,81 @@ class TestCliList(CliMixin):
class TestCliInfo(CliMixin): class TestCliInfo(CliMixin):
def test_info_xml_serialisation(self, _): def test_info_xml_serialisation(self, _):
self._test_info_output( self._test_info_output(self._make_fake_instance())
slapos.slap.SoftwareInstance(
_software_release_url='SR1',
_requested_state='mystate',
_connection_dict=
'<?xml version=\'1.0\' encoding=\'utf-8\'?>\n<instance>\n <parameter id="myconnectionparameter">value1</parameter>\n</instance>\n',
_parameter_dict={'myinstanceparameter': 'value2'}))
def test_info_json_in_serialisation(self, _): def test_info_json_in_serialisation(self, _):
self._test_info_output(self._make_fake_instance(xml=False))
def test_info_status_none(self, _):
self._test_info_output(
self._make_fake_instance(
news=[{'text': 'toto'}]),
status='none')
def test_info_status_green(self, _):
self._test_info_output(
self._make_fake_instance(
news=[{'text': '#access'}, {'text': 'toto'}]),
status='green')
def test_info_status_red(self, _):
self._test_info_output(
self._make_fake_instance(
news=[{'text': '#error'}, {'text': 'toto'}]),
status='red')
def test_info_status_orange(self, _):
self._test_info_output(
self._make_fake_instance(
news=[{'text': '#error'}, {'text': '#access'}, {'text': 'toto'}]),
status='orange')
def test_info_news(self, _):
news=[{'text': 'toto'}]
self._test_info_output( self._test_info_output(
slapos.slap.SoftwareInstance( self._make_fake_instance(
news=news),
status='none',
news=news)
def _make_fake_instance(self, xml=True, news=None):
conn = {'myconnectionparameter': 'value1'}
if xml:
conn_params = dict2xml(conn)
else:
conn_params = '<instance>\n <parameter id="_">%s</parameter>\n</instance>' % json.dumps(conn)
instance = slapos.slap.SoftwareInstance(
_software_release_url='SR1', _software_release_url='SR1',
_requested_state='mystate', _requested_state='mystate',
_connection_dict= _connection_dict=conn_params,
'<?xml version=\'1.0\' encoding=\'utf-8\'?>\n<instance>\n <parameter id="_">{"myconnectionparameter": "value1"}</parameter>\n</instance>\n', _parameter_dict={'myinstanceparameter': 'value2'})
_parameter_dict={'myinstanceparameter': 'value2'})) if news:
instance._news = {'instance': news}
return instance
def _test_info_output(self, instance): def _test_info_output(self, instance, status="unsupported", news=None):
""" """
Test "slapos service info" command output. Test "slapos service info" command output.
""" """
setattr(self.conf, 'reference', 'instance1') setattr(self.conf, 'reference', 'instance1')
setattr(self.conf, 'news', bool(news))
with patch.object(slapos.slap.OpenOrder, 'getInformation', with patch.object(slapos.slap.OpenOrder, 'getInformation',
return_value=instance): return_value=instance):
slapos.cli.info.do_info(self.logger, self.conf, self.local) slapos.cli.info.do_info(self.logger, self.conf, self.local)
if six.PY3: if six.PY3:
self.logger.info.assert_called_once_with( expected = {
textwrap.dedent('''\ "software-url": instance._software_release_url,
{ "requested-state": instance._requested_state,
"software-url": "SR1", "instance-parameters": instance._parameter_dict,
"instance-state": "mystate",
"instance-parameters": {
"myinstanceparameter": "value2"
},
"connection-parameters": { "connection-parameters": {
"myconnectionparameter": "value1" "myconnectionparameter": "value1"
},
"status": status
} }
}''')) if news:
expected['news'] = news
self.logger.info.assert_called_once_with(json.dumps(expected, indent=2))
def test_unknownReference(self, _): def test_unknownReference(self, _):
""" """
......
...@@ -1298,9 +1298,10 @@ class TestCliInformation(CliMasterMixin): ...@@ -1298,9 +1298,10 @@ class TestCliInformation(CliMasterMixin):
json.loads(output0), json.loads(output0),
{ {
"software-url": "http://sr0//", "software-url": "http://sr0//",
"instance-state": "busy", "requested-state": "started",
"instance-parameters": {}, "instance-parameters": {},
"connection-parameters": {}, "connection-parameters": {},
"status": "unsupported",
}, },
) )
output1 = self.cliDoSlapos(('service', 'info', 'MyInstance1'), stderr=subprocess.DEVNULL) output1 = self.cliDoSlapos(('service', 'info', 'MyInstance1'), stderr=subprocess.DEVNULL)
...@@ -1308,9 +1309,10 @@ class TestCliInformation(CliMasterMixin): ...@@ -1308,9 +1309,10 @@ class TestCliInformation(CliMasterMixin):
json.loads(output1), json.loads(output1),
{ {
"software-url": "http://sr1//", "software-url": "http://sr1//",
"instance-state": "busy", "requested-state": "started",
"instance-parameters": {"couscous": "hello"}, "instance-parameters": {"couscous": "hello"},
"connection-parameters": {}, "connection-parameters": {},
"status": "unsupported",
}, },
) )
try: try:
......
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