From 08001d256fc4ed82e35bfc14c35493676e52c35f Mon Sep 17 00:00:00 2001 From: Sebastian Wagner Date: Thu, 19 Mar 2020 14:43:44 +0100 Subject: [PATCH] mgr/orch: add yaml to `orch ls` Signed-off-by: Sebastian Wagner (cherry picked from commit dcde4899ce42836b8c15dcd6076d2521bca24ff7) --- src/pybind/mgr/orchestrator/module.py | 45 +++++++++++++++++---------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/src/pybind/mgr/orchestrator/module.py b/src/pybind/mgr/orchestrator/module.py index 2522ddcb78128..b023f3d6d3be7 100644 --- a/src/pybind/mgr/orchestrator/module.py +++ b/src/pybind/mgr/orchestrator/module.py @@ -24,7 +24,8 @@ from mgr_module import MgrModule, HandleCommandResult from ._interface import OrchestratorClientMixin, DeviceLightLoc, _cli_read_command, \ raise_if_exception, _cli_write_command, TrivialReadCompletion, OrchestratorError, \ NoOrchestrator, OrchestratorValidationError, NFSServiceSpec, \ - RGWSpec, InventoryFilter, InventoryHost, HostSpec, CLICommandMeta + RGWSpec, InventoryFilter, InventoryHost, HostSpec, CLICommandMeta, \ + ServiceDescription def nice_delta(now, t, suffix=''): if t: @@ -32,6 +33,16 @@ def nice_delta(now, t, suffix=''): else: return '-' + +def to_format(what, format): + if format == 'json': + return json.dumps(what, sort_keys=True) + elif format == 'json-pretty': + return json.dumps(what, indent=2, sort_keys=True) + elif format == 'yaml': + return yaml.safe_dump_all(what, default_flow_style=False) + + @six.add_metaclass(CLICommandMeta) class OrchestratorCli(OrchestratorClientMixin, MgrModule): MODULE_OPTIONS = [ @@ -202,16 +213,16 @@ class OrchestratorCli(OrchestratorClientMixin, MgrModule): @_cli_read_command( 'orch host ls', - 'name=format,type=CephChoices,strings=json|plain,req=false', + 'name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false', 'List hosts') def _get_hosts(self, format='plain'): completion = self.get_hosts() self._orchestrator_wait([completion]) raise_if_exception(completion) - if format == 'json': + if format != 'plain': hosts = [host.to_json() for host in completion.result] - output = json.dumps(hosts, sort_keys=True) + output = to_format(hosts, format) else: table = PrettyTable( ['HOST', 'ADDR', 'LABELS', 'STATUS'], @@ -249,7 +260,7 @@ class OrchestratorCli(OrchestratorClientMixin, MgrModule): @_cli_read_command( 'orch device ls', "name=hostname,type=CephString,n=N,req=false " - "name=format,type=CephChoices,strings=json|plain,req=false " + "name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false " "name=refresh,type=CephBool,req=false", 'List devices on a host') def _list_devices(self, hostname=None, format='plain', refresh=False): @@ -268,9 +279,9 @@ class OrchestratorCli(OrchestratorClientMixin, MgrModule): self._orchestrator_wait([completion]) raise_if_exception(completion) - if format == 'json': + if format != 'plain': data = [n.to_json() for n in completion.result] - return HandleCommandResult(stdout=json.dumps(data)) + return HandleCommandResult(stdout=to_format(data, format)) else: out = [] @@ -316,7 +327,7 @@ class OrchestratorCli(OrchestratorClientMixin, MgrModule): 'orch ls', "name=service_type,type=CephString,req=false " "name=service_name,type=CephString,req=false " - "name=format,type=CephChoices,strings=json|plain,req=false " + "name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false " "name=refresh,type=CephBool,req=false", 'List services known to orchestrator') def _list_services(self, host=None, service_type=None, service_name=None, format='plain', refresh=False): @@ -325,19 +336,19 @@ class OrchestratorCli(OrchestratorClientMixin, MgrModule): refresh=refresh) self._orchestrator_wait([completion]) raise_if_exception(completion) - services = completion.result + services: List[ServiceDescription] = completion.result def ukn(s): return '' if s is None else s # Sort the list for display - services.sort(key=lambda s: (ukn(s.service_name))) + services.sort(key=lambda s: (ukn(s.spec.service_name()))) if len(services) == 0: return HandleCommandResult(stdout="No services reported") - elif format == 'json': + elif format != 'plain': data = [s.to_json() for s in services] - return HandleCommandResult(stdout=json.dumps(data)) + return HandleCommandResult(stdout=to_format(data, format)) else: now = datetime.datetime.utcnow() table = PrettyTable( @@ -355,7 +366,7 @@ class OrchestratorCli(OrchestratorClientMixin, MgrModule): table.align['PLACEMENT'] = 'l' table.left_padding_width = 0 table.right_padding_width = 2 - for s in sorted(services, key=lambda s: s.service_name): + for s in services: if not s.spec: pl = '' elif s.spec.unmanaged: @@ -363,7 +374,7 @@ class OrchestratorCli(OrchestratorClientMixin, MgrModule): else: pl = s.spec.placement.pretty_str() table.add_row(( - s.service_name, + s.spec.service_name(), '%d/%d' % (s.running, s.size), nice_delta(now, s.last_refresh, ' ago'), nice_delta(now, s.created), @@ -380,7 +391,7 @@ class OrchestratorCli(OrchestratorClientMixin, MgrModule): "name=service_name,type=CephString,req=false " "name=daemon_type,type=CephString,req=false " "name=daemon_id,type=CephString,req=false " - "name=format,type=CephChoices,strings=json|plain,req=false " + "name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false " "name=refresh,type=CephBool,req=false", 'List daemons known to orchestrator') def _list_daemons(self, hostname=None, service_name=None, daemon_type=None, daemon_id=None, format='plain', refresh=False): @@ -400,9 +411,9 @@ class OrchestratorCli(OrchestratorClientMixin, MgrModule): if len(daemons) == 0: return HandleCommandResult(stdout="No daemons reported") - elif format == 'json': + elif format != 'plain': data = [s.to_json() for s in daemons] - return HandleCommandResult(stdout=json.dumps(data)) + return HandleCommandResult(stdout=to_format(data, format)) else: now = datetime.datetime.utcnow() table = PrettyTable( -- 2.39.5