From 533e0871ec7693cf1d68d362a33abf3ef4b41940 Mon Sep 17 00:00:00 2001 From: Omri Zeneva Date: Mon, 14 Mar 2022 10:37:56 +0200 Subject: [PATCH] mgr/cephadm: add unit tests for jaeger services Signed-off-by: Omri Zeneva --- src/cephadm/cephadm | 9 +- src/cephadm/tests/test_cephadm.py | 71 +++++++++++ src/pybind/mgr/cephadm/module.py | 16 --- src/pybind/mgr/cephadm/services/jaeger.py | 14 +- src/pybind/mgr/cephadm/tests/test_services.py | 120 +++++++++++++++++- src/pybind/mgr/orchestrator/_interface.py | 6 +- src/pybind/mgr/orchestrator/module.py | 1 - .../ceph/deployment/service_spec.py | 1 + 8 files changed, 208 insertions(+), 30 deletions(-) diff --git a/src/cephadm/cephadm b/src/cephadm/cephadm index 04cc1b258d918..9693b13ed2304 100755 --- a/src/cephadm/cephadm +++ b/src/cephadm/cephadm @@ -1100,16 +1100,18 @@ class Keepalived(object): ################################## + class Tracing(object): """Define the configs for the jaeger tracing containers""" - components = { + components: Dict[str, Dict[str, Any]] = { 'elasticsearch': { 'image': DEFAULT_ELASTICSEARCH_IMAGE, 'envs': ['discovery.type=single-node'] }, 'jaeger-agent': { 'image': DEFAULT_JAEGER_AGENT_IMAGE, + 'envs': '' }, 'jaeger-collector': { 'image': DEFAULT_JAEGER_COLLECTOR_IMAGE, @@ -1120,8 +1122,8 @@ class Tracing(object): } # type: ignore @staticmethod - def set_configuration(config, daemon_type: str): - if daemon_type in ['jaeger-collector','jaeger-query']: + def set_configuration(config: Dict[str, str], daemon_type: str) -> None: + if daemon_type in ['jaeger-collector', 'jaeger-query']: assert 'elasticsearch_nodes' in config Tracing.components[daemon_type]['envs'] = [ 'SPAN_STORAGE_TYPE=elasticsearch', @@ -1133,6 +1135,7 @@ class Tracing(object): ################################## + class CustomContainer(object): """Defines a custom container""" daemon_type = 'container' diff --git a/src/cephadm/tests/test_cephadm.py b/src/cephadm/tests/test_cephadm.py index 58701e43db6ff..98b40e389b633 100644 --- a/src/cephadm/tests/test_cephadm.py +++ b/src/cephadm/tests/test_cephadm.py @@ -2364,3 +2364,74 @@ class TestSysctl: "fs.aio-max-nr = 1048576", " vm.max_map_count = 65530 ", ] + +class TestJaeger: + single_es_node_conf = { + 'elasticsearch_nodes': 'http://192.168.0.1:9200'} + multiple_es_nodes_conf = { + 'elasticsearch_nodes': 'http://192.168.0.1:9200,http://192.168.0.2:9300'} + agent_conf = { + 'collector_nodes': 'test:14250'} + + def test_single_es(self, cephadm_fs): + fsid = 'ca734440-3dc6-11ec-9b98-5254002537a6' + with with_cephadm_ctx(['--image=quay.io/jaegertracing/jaeger-collector:1.29'], list_networks={}) as ctx: + import json + ctx.config_json = json.dumps(self.single_es_node_conf) + ctx.fsid = fsid + c = cd.get_container(ctx, fsid, 'jaeger-collector', 'daemon_id') + cd.create_daemon_dirs(ctx, fsid, 'jaeger-collector', 'daemon_id', 0, 0) + cd.deploy_daemon_units( + ctx, + fsid, + 0, 0, + 'jaeger-collector', + 'daemon_id', + c, + True, True + ) + with open(f'/var/lib/ceph/{fsid}/jaeger-collector.daemon_id/unit.run', 'r') as f: + run_cmd = f.readlines()[-1].rstrip() + assert run_cmd.endswith('SPAN_STORAGE_TYPE=elasticsearch -e ES_SERVER_URLS=http://192.168.0.1:9200 quay.io/jaegertracing/jaeger-collector:1.29') + + def test_multiple_es(self, cephadm_fs): + fsid = 'ca734440-3dc6-11ec-9b98-5254002537a6' + with with_cephadm_ctx(['--image=quay.io/jaegertracing/jaeger-collector:1.29'], list_networks={}) as ctx: + import json + ctx.config_json = json.dumps(self.multiple_es_nodes_conf) + ctx.fsid = fsid + c = cd.get_container(ctx, fsid, 'jaeger-collector', 'daemon_id') + cd.create_daemon_dirs(ctx, fsid, 'jaeger-collector', 'daemon_id', 0, 0) + cd.deploy_daemon_units( + ctx, + fsid, + 0, 0, + 'jaeger-collector', + 'daemon_id', + c, + True, True + ) + with open(f'/var/lib/ceph/{fsid}/jaeger-collector.daemon_id/unit.run', 'r') as f: + run_cmd = f.readlines()[-1].rstrip() + assert run_cmd.endswith('SPAN_STORAGE_TYPE=elasticsearch -e ES_SERVER_URLS=http://192.168.0.1:9200,http://192.168.0.2:9300 quay.io/jaegertracing/jaeger-collector:1.29') + + def test_jaeger_agent(self, cephadm_fs): + fsid = 'ca734440-3dc6-11ec-9b98-5254002537a6' + with with_cephadm_ctx(['--image=quay.io/jaegertracing/jaeger-agent:1.29'], list_networks={}) as ctx: + import json + ctx.config_json = json.dumps(self.agent_conf) + ctx.fsid = fsid + c = cd.get_container(ctx, fsid, 'jaeger-agent', 'daemon_id') + cd.create_daemon_dirs(ctx, fsid, 'jaeger-agent', 'daemon_id', 0, 0) + cd.deploy_daemon_units( + ctx, + fsid, + 0, 0, + 'jaeger-agent', + 'daemon_id', + c, + True, True + ) + with open(f'/var/lib/ceph/{fsid}/jaeger-agent.daemon_id/unit.run', 'r') as f: + run_cmd = f.readlines()[-1].rstrip() + assert run_cmd.endswith('quay.io/jaegertracing/jaeger-agent:1.29 --reporter.grpc.host-port=test:14250') diff --git a/src/pybind/mgr/cephadm/module.py b/src/pybind/mgr/cephadm/module.py index 55621b7bf14e0..dd966d1569e5c 100644 --- a/src/pybind/mgr/cephadm/module.py +++ b/src/pybind/mgr/cephadm/module.py @@ -2671,22 +2671,6 @@ Then run the following: def apply_alertmanager(self, spec: ServiceSpec) -> str: return self._apply(spec) - @handle_orch_error - def apply_elasticsearch(self, spec: ServiceSpec) -> str: - return self._apply(spec) - - @handle_orch_error - def apply_jaeger_agent(self, spec: ServiceSpec) -> str: - return self._apply(spec) - - @handle_orch_error - def apply_jaeger_collector(self, spec: ServiceSpec) -> str: - return self._apply(spec) - - @handle_orch_error - def apply_jaeger_query(self, spec: ServiceSpec) -> str: - return self._apply(spec) - @handle_orch_error def apply_container(self, spec: ServiceSpec) -> str: return self._apply(spec) diff --git a/src/pybind/mgr/cephadm/services/jaeger.py b/src/pybind/mgr/cephadm/services/jaeger.py index 83ad47007822a..129afacef810c 100644 --- a/src/pybind/mgr/cephadm/services/jaeger.py +++ b/src/pybind/mgr/cephadm/services/jaeger.py @@ -1,8 +1,9 @@ -from typing import List, Any, Tuple, Dict, cast +from typing import List, cast from cephadm.services.cephadmservice import CephadmService, CephadmDaemonDeploySpec from ceph.deployment.service_spec import TracingSpec from mgr_util import build_url + class ElasticSearchService(CephadmService): TYPE = 'elasticsearch' DEFAULT_SERVICE_PORT = 9200 @@ -11,6 +12,7 @@ class ElasticSearchService(CephadmService): assert self.TYPE == daemon_spec.daemon_type return daemon_spec + class JaegerAgentService(CephadmService): TYPE = 'jaeger-agent' DEFAULT_SERVICE_PORT = 6831 @@ -38,6 +40,7 @@ class JaegerCollectorService(CephadmService): daemon_spec.final_config = {'elasticsearch_nodes': ",".join(elasticsearch_nodes)} return daemon_spec + class JaegerQueryService(CephadmService): TYPE = 'jaeger-query' DEFAULT_SERVICE_PORT = 16686 @@ -48,9 +51,11 @@ class JaegerQueryService(CephadmService): daemon_spec.final_config = {'elasticsearch_nodes': ",".join(elasticsearch_nodes)} return daemon_spec -def get_elasticsearch_nodes(service: CephadmService, daemon_spec: CephadmDaemonDeploySpec): + +def get_elasticsearch_nodes(service: CephadmService, daemon_spec: CephadmDaemonDeploySpec) -> List[str]: elasticsearch_nodes = [] for dd in service.mgr.cache.get_daemons_by_type(ElasticSearchService.TYPE): + assert dd.hostname is not None addr = dd.ip if dd.ip else service.mgr.inventory.get_addr(dd.hostname) port = dd.ports[0] if dd.ports else ElasticSearchService.DEFAULT_SERVICE_PORT url = build_url(host=addr, port=port).lstrip('/') @@ -58,10 +63,11 @@ def get_elasticsearch_nodes(service: CephadmService, daemon_spec: CephadmDaemonD if len(elasticsearch_nodes) == 0: # takes elasticsearch address from TracingSpec - spec: TracingSpec = cast(TracingSpec, service.mgr.spec_store.active_specs[daemon_spec.service_name]) + spec: TracingSpec = cast( + TracingSpec, service.mgr.spec_store.active_specs[daemon_spec.service_name]) assert spec.es_nodes is not None urls = spec.es_nodes.split(",") for url in urls: elasticsearch_nodes.append(f'http://{url}') - return elasticsearch_nodes \ No newline at end of file + return elasticsearch_nodes diff --git a/src/pybind/mgr/cephadm/tests/test_services.py b/src/pybind/mgr/cephadm/tests/test_services.py index 69ee8a9944ee7..128dae1233133 100644 --- a/src/pybind/mgr/cephadm/tests/test_services.py +++ b/src/pybind/mgr/cephadm/tests/test_services.py @@ -1,6 +1,7 @@ from textwrap import dedent import json import yaml +from mgr_util import build_url import pytest @@ -16,7 +17,7 @@ from cephadm.services.monitoring import GrafanaService, AlertmanagerService, Pro NodeExporterService, LokiService, PromtailService from cephadm.module import CephadmOrchestrator from ceph.deployment.service_spec import IscsiServiceSpec, MonitoringSpec, AlertManagerSpec, \ - ServiceSpec, RGWSpec, GrafanaSpec, SNMPGatewaySpec, IngressSpec, PlacementSpec + ServiceSpec, RGWSpec, GrafanaSpec, SNMPGatewaySpec, IngressSpec, PlacementSpec, TracingSpec from cephadm.tests.fixtures import with_host, with_service, _run_cephadm, async_side_effect from orchestrator import OrchestratorError @@ -1016,3 +1017,120 @@ class TestCephFsMirror: 'prefix': 'mgr module enable', 'module': 'mirroring' }) + + +class TestJaeger: + @patch("cephadm.serve.CephadmServe._run_cephadm") + def test_jaeger_query(self, _run_cephadm, cephadm_module: CephadmOrchestrator): + _run_cephadm.side_effect = async_side_effect(('{}', '', 0)) + + spec = TracingSpec(es_nodes="192.168.0.1:9200", + service_type="jaeger-query") + + config = {"elasticsearch_nodes": "http://192.168.0.1:9200"} + + with with_host(cephadm_module, 'test'): + with with_service(cephadm_module, spec): + _run_cephadm.assert_called_with( + 'test', + 'jaeger-query.test', + 'deploy', + [ + '--name', 'jaeger-query.test', + '--meta-json', + '{"service_name": "jaeger-query", "ports": [16686], "ip": null, "deployed_by": [], "rank": null, "rank_generation": null, "extra_container_args": null}', + '--config-json', '-', + '--tcp-ports', '16686' + + ], + stdin=json.dumps(config), + image='' + ) + + @patch("cephadm.serve.CephadmServe._run_cephadm") + def test_jaeger_collector_es_deploy(self, _run_cephadm, cephadm_module: CephadmOrchestrator): + _run_cephadm.side_effect = async_side_effect(('{}', '', 0)) + + collector_spec = TracingSpec(service_type="jaeger-collector") + es_spec = TracingSpec(service_type="elasticsearch") + es_config = {} + + with with_host(cephadm_module, 'test'): + collector_config = { + "elasticsearch_nodes": f'http://{build_url(host=cephadm_module.inventory.get_addr("test"), port=9200).lstrip("/")}'} + with with_service(cephadm_module, es_spec): + _run_cephadm.assert_called_with( + 'test', + 'elasticsearch.test', + 'deploy', + [ + '--name', 'elasticsearch.test', + '--meta-json', + '{"service_name": "elasticsearch", "ports": [9200], "ip": null, "deployed_by": [], "rank": null, "rank_generation": null, "extra_container_args": null}', + '--config-json', '-', + '--tcp-ports', '9200' + + ], + stdin=json.dumps(es_config), + image='' + ) + with with_service(cephadm_module, collector_spec): + _run_cephadm.assert_called_with( + 'test', + 'jaeger-collector.test', + 'deploy', + [ + '--name', 'jaeger-collector.test', + '--meta-json', + '{"service_name": "jaeger-collector", "ports": [14250], "ip": null, "deployed_by": [], "rank": null, "rank_generation": null, "extra_container_args": null}', + '--config-json', '-', + '--tcp-ports', '14250' + + ], + stdin=json.dumps(collector_config), + image='' + ) + + @patch("cephadm.serve.CephadmServe._run_cephadm") + def test_jaeger_agent(self, _run_cephadm, cephadm_module: CephadmOrchestrator): + _run_cephadm.side_effect = async_side_effect(('{}', '', 0)) + + collector_spec = TracingSpec(service_type="jaeger-collector", es_nodes="192.168.0.1:9200") + collector_config = {"elasticsearch_nodes": "http://192.168.0.1:9200"} + + agent_spec = TracingSpec(service_type="jaeger-agent") + agent_config = {"collector_nodes": "test:14250"} + + with with_host(cephadm_module, 'test'): + with with_service(cephadm_module, collector_spec): + _run_cephadm.assert_called_with( + 'test', + 'jaeger-collector.test', + 'deploy', + [ + '--name', 'jaeger-collector.test', + '--meta-json', + '{"service_name": "jaeger-collector", "ports": [14250], "ip": null, "deployed_by": [], "rank": null, "rank_generation": null, "extra_container_args": null}', + '--config-json', '-', + '--tcp-ports', '14250' + + ], + stdin=json.dumps(collector_config), + image='' + ) + with with_service(cephadm_module, agent_spec): + _run_cephadm.assert_called_with( + 'test', + 'jaeger-agent.test', + 'deploy', + [ + '--name', 'jaeger-agent.test', + '--meta-json', + '{"service_name": "jaeger-agent", "ports": [6831], "ip": null, "deployed_by": [], "rank": null, "rank_generation": null, "extra_container_args": null}', + '--config-json', '-', + '--tcp-ports', '6831' + + ], + stdin=json.dumps(agent_config), + image='' + ) diff --git a/src/pybind/mgr/orchestrator/_interface.py b/src/pybind/mgr/orchestrator/_interface.py index 7f8b63e6af851..294fe8176e1e9 100644 --- a/src/pybind/mgr/orchestrator/_interface.py +++ b/src/pybind/mgr/orchestrator/_interface.py @@ -31,7 +31,7 @@ import yaml from ceph.deployment import inventory from ceph.deployment.service_spec import ServiceSpec, NFSServiceSpec, RGWSpec, \ - IscsiServiceSpec, IngressSpec, SNMPGatewaySpec, MDSSpec, TracingSpec + IscsiServiceSpec, IngressSpec, SNMPGatewaySpec, MDSSpec from ceph.deployment.drive_group import DriveGroupSpec from ceph.deployment.hostspec import HostSpec, SpecValidationError from ceph.utils import datetime_to_str, str_to_datetime @@ -472,10 +472,6 @@ class Orchestrator(object): 'rgw': self.apply_rgw, 'ingress': self.apply_ingress, 'snmp-gateway': self.apply_snmp_gateway, - 'elasticsearch': self.apply_elasticsearch, - 'jaeger-agent': self.apply_jaeger_agent, - 'jaeger-collector': self.apply_jaeger_collector, - 'jaeger-query': self.apply_jaeger_query, 'host': self.add_host, } diff --git a/src/pybind/mgr/orchestrator/module.py b/src/pybind/mgr/orchestrator/module.py index 3bc9a6529eaaa..edaa3f99f6db5 100644 --- a/src/pybind/mgr/orchestrator/module.py +++ b/src/pybind/mgr/orchestrator/module.py @@ -68,7 +68,6 @@ class ServiceType(enum.Enum): jaeger_query = 'jaeger-query' - class ServiceAction(enum.Enum): start = 'start' stop = 'stop' diff --git a/src/python-common/ceph/deployment/service_spec.py b/src/python-common/ceph/deployment/service_spec.py index c02d271ba62b8..70815d02e7ffa 100644 --- a/src/python-common/ceph/deployment/service_spec.py +++ b/src/python-common/ceph/deployment/service_spec.py @@ -1362,6 +1362,7 @@ class MDSSpec(ServiceSpec): yaml.add_representer(MDSSpec, ServiceSpec.yaml_representer) + class TracingSpec(ServiceSpec): SERVICE_TYPES = ['elasticsearch', 'jaeger-collector', 'jaeger-query', 'jaeger-agent'] -- 2.39.5