From: Sage Weil Date: Fri, 9 Apr 2021 22:47:52 +0000 (-0400) Subject: mgr/orchestrator: report external endpoints from 'orch ls' X-Git-Tag: v17.1.0~2265^2~8 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=3f55c708b367da7b8890a00e48eb7c0498ef5d97;p=ceph.git mgr/orchestrator: report external endpoints from 'orch ls' Add a PORTS column and report the external/virtual IP (and port(s)) from 'orch ls' output. Signed-off-by: Sage Weil --- diff --git a/src/pybind/mgr/cephadm/module.py b/src/pybind/mgr/cephadm/module.py index 7060dbcd87f5f..56c3bac41f508 100644 --- a/src/pybind/mgr/cephadm/module.py +++ b/src/pybind/mgr/cephadm/module.py @@ -1577,6 +1577,8 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule, events=self.events.get_for_service(spec.service_name()), created=self.spec_store.spec_created[nm], deleted=self.spec_store.spec_deleted.get(nm, None), + virtual_ip=spec.get_virtual_ip(), + ports=spec.get_port_start(), ) if service_type == 'nfs': spec = cast(NFSServiceSpec, spec) diff --git a/src/pybind/mgr/cephadm/tests/test_cephadm.py b/src/pybind/mgr/cephadm/tests/test_cephadm.py index 2bf645de61964..f0896b9f96b60 100644 --- a/src/pybind/mgr/cephadm/tests/test_cephadm.py +++ b/src/pybind/mgr/cephadm/tests/test_cephadm.py @@ -148,7 +148,8 @@ class TestCephadm(object): 'service_id': 'r.z', 'service_name': 'rgw.r.z', 'service_type': 'rgw', - 'status': {'created': mock.ANY, 'running': 1, 'size': 1}, + 'status': {'created': mock.ANY, 'running': 1, 'size': 1, + 'ports': [80]}, } ] for o in out: diff --git a/src/pybind/mgr/orchestrator/_interface.py b/src/pybind/mgr/orchestrator/_interface.py index 9d1808fda9390..9b2c1e1fa88d9 100644 --- a/src/pybind/mgr/orchestrator/_interface.py +++ b/src/pybind/mgr/orchestrator/_interface.py @@ -1023,7 +1023,9 @@ class ServiceDescription(object): deleted: Optional[datetime.datetime] = None, size: int = 0, running: int = 0, - events: Optional[List['OrchestratorEvent']] = None) -> None: + events: Optional[List['OrchestratorEvent']] = None, + virtual_ip: Optional[str] = None, + ports: List[int] = []) -> None: # Not everyone runs in containers, but enough people do to # justify having the container_image_id (image hash) and container_image # (image name) @@ -1053,12 +1055,20 @@ class ServiceDescription(object): self.events: List[OrchestratorEvent] = events or [] + self.virtual_ip = virtual_ip + self.ports = ports + def service_type(self) -> str: return self.spec.service_type def __repr__(self) -> str: return f"" + def get_port_summary(self) -> str: + if not self.ports: + return '' + return f"{self.virtual_ip or '?'}:{','.join(map(str, self.ports or []))}" + def to_json(self) -> OrderedDict: out = self.spec.to_json() status = { @@ -1070,6 +1080,8 @@ class ServiceDescription(object): 'running': self.running, 'last_refresh': self.last_refresh, 'created': self.created, + 'virtual_ip': self.virtual_ip, + 'ports': self.ports if self.ports else None, } for k in ['last_refresh', 'created']: if getattr(self, k): diff --git a/src/pybind/mgr/orchestrator/module.py b/src/pybind/mgr/orchestrator/module.py index d4fb259ce4b76..cdf939d6be84f 100644 --- a/src/pybind/mgr/orchestrator/module.py +++ b/src/pybind/mgr/orchestrator/module.py @@ -561,11 +561,14 @@ class OrchestratorCli(OrchestratorClientMixin, MgrModule, else: now = datetime_now() table = PrettyTable( - ['NAME', 'RUNNING', 'REFRESHED', 'AGE', - 'PLACEMENT', - ], + [ + 'NAME', 'PORTS', + 'RUNNING', 'REFRESHED', 'AGE', + 'PLACEMENT', + ], border=False) table.align['NAME'] = 'l' + table.align['PORTS'] = 'l' table.align['RUNNING'] = 'r' table.align['REFRESHED'] = 'l' table.align['AGE'] = 'l' @@ -586,6 +589,7 @@ class OrchestratorCli(OrchestratorClientMixin, MgrModule, table.add_row(( s.spec.service_name(), + s.get_port_summary(), '%d/%d' % (s.running, s.size), refreshed, nice_delta(now, s.created), diff --git a/src/python-common/ceph/deployment/service_spec.py b/src/python-common/ceph/deployment/service_spec.py index d7f10fe09da6b..75d99a0f61cba 100644 --- a/src/python-common/ceph/deployment/service_spec.py +++ b/src/python-common/ceph/deployment/service_spec.py @@ -581,6 +581,9 @@ class ServiceSpec(object): # point. return [] + def get_virtual_ip(self) -> Optional[str]: + return None + def to_json(self): # type: () -> OrderedDict[str, Any] ret: OrderedDict[str, Any] = OrderedDict() @@ -901,6 +904,9 @@ class IngressSpec(ServiceSpec): return [cast(int, self.frontend_port), cast(int, self.monitor_port)] + def get_virtual_ip(self) -> Optional[str]: + return self.virtual_ip + def validate(self) -> None: super(IngressSpec, self).validate()