Skip to content

Commit baaed78

Browse files
committed
process autodiscovery for krakend
1 parent d8e7b90 commit baaed78

13 files changed

Lines changed: 133 additions & 17 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add process autodiscovery E2E testing helpers.

datadog_checks_dev/datadog_checks/dev/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Licensed under a 3-clause BSD style license (see LICENSE)
44
from .__about__ import __version__
55
from .conditions import WaitFor
6-
from .docker import docker_run, get_docker_hostname, get_e2e_discovery_metadata
6+
from .docker import docker_run, get_docker_hostname, get_e2e_discovery_metadata, get_e2e_process_discovery_metadata
77
from .env import environment_run
88
from .errors import RetryError
99
from .fs import chdir, get_here, temp_chdir, temp_dir

datadog_checks_dev/datadog_checks/dev/docker.py

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,13 @@ def _assert_no_log_patterns(logs: str, patterns: Sequence[str], candidate_index:
229229
)
230230

231231

232+
def _get_auto_conf_volume(check_root: str | os.PathLike[str] | None = None) -> str:
233+
check_root = os.fspath(check_root or find_check_root(depth=2))
234+
check_name = os.path.basename(check_root)
235+
check_pkg = os.path.join(check_root, 'datadog_checks', check_name)
236+
return f'{check_pkg}/data/auto_conf.yaml:/etc/datadog-agent/conf.d/{check_name}.d/auto_conf.yaml:ro'
237+
238+
232239
def get_e2e_discovery_metadata(
233240
check_root: str | os.PathLike[str] | None = None,
234241
) -> dict[str, list[str]]:
@@ -240,19 +247,55 @@ def get_e2e_discovery_metadata(
240247
per-env config is temporarily replaced with an empty-instances file, leaving
241248
``auto_conf.yaml`` as the sole AD template driving config-discovery.
242249
"""
243-
check_root = os.fspath(check_root or find_check_root(depth=1))
244-
check_name = os.path.basename(check_root)
245-
check_pkg = os.path.join(check_root, 'datadog_checks', check_name)
246-
auto_conf = os.path.join(check_pkg, 'data', 'auto_conf.yaml')
247-
248250
return {
249251
'docker_volumes': [
250-
f'{auto_conf}:/etc/datadog-agent/conf.d/{check_name}.d/auto_conf.yaml:ro',
252+
_get_auto_conf_volume(check_root),
251253
'/var/run/docker.sock:/var/run/docker.sock:ro',
252254
],
253255
}
254256

255257

258+
def get_e2e_process_discovery_metadata(
259+
check_root: str | os.PathLike[str] | None = None,
260+
) -> dict[str, list[str] | dict[str, str]]:
261+
"""Return metadata for an e2e process-autodiscovery run.
262+
263+
Mounts the integration's ``auto_conf.yaml`` into the agent container
264+
(without the Docker socket) and sets ``DD_AUTOCONFIG_EXCLUDE_FEATURES=docker``
265+
so only the process listener is active.
266+
267+
Use ``dd_agent_check_discovery`` alongside this metadata.
268+
"""
269+
return {
270+
'docker_volumes': [
271+
_get_auto_conf_volume(check_root),
272+
],
273+
'env_vars': {
274+
# Reduce the default service collection interval from 60s to speed
275+
# up tests.
276+
'DD_DISCOVERY_SERVICE_COLLECTION_INTERVAL': '10s',
277+
# Process autodiscovery will only match processes that are not
278+
# inside a container. Since our test environment actually run the
279+
# services inside containers, we need to exclude the docker
280+
# features, so that the agent doesn't know about the containers.
281+
'DD_AUTOCONFIG_EXCLUDE_FEATURES': 'docker',
282+
# The agent container has /proc:/host/proc mounted by ddev. Without this,
283+
# the workloadmeta process-collector scans /proc (the container's own PID
284+
# namespace) instead of /host/proc, so host processes aren't visible.
285+
#
286+
# This is normally automatically detected by the agent when running
287+
# inside a container, but it's not in this case since we
288+
# explicitly disable the agent's docker-based features.
289+
'DD_PROC_ROOT': '/host/proc',
290+
},
291+
# system-probe(-lite) needs these capabilities to read /proc entries of
292+
# other processes for service discovery. Without them it falls back to
293+
# only scanning the agent's own PID namespace, which finds no host
294+
# processes.
295+
'cap_add': ['SYS_PTRACE', 'DAC_READ_SEARCH'],
296+
}
297+
298+
256299
def compose_file_active(compose_file):
257300
"""
258301
Returns a `bool` indicating whether or not a compose file has any active services.

datadog_checks_dev/datadog_checks/dev/plugin/pytest.py

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import re
99
from base64 import urlsafe_b64encode
1010
from collections import namedtuple # Not using dataclasses for Py2 compatibility
11+
from collections.abc import Collection
1112
from io import open
1213
from typing import Dict, List, Literal, Optional, Tuple, overload # noqa: F401
1314

@@ -238,7 +239,7 @@ def run_check(config=None, **kwargs):
238239

239240

240241
@pytest.fixture
241-
def dd_agent_check_discovery(dd_agent_check):
242+
def dd_agent_check_discovery(dd_agent_check, is_process_e2e):
242243
"""Wrapper around ``dd_agent_check`` for config-discovery e2e tests.
243244
244245
Passes the empty-instances config required to let ``auto_conf.yaml`` drive
@@ -248,7 +249,13 @@ def dd_agent_check_discovery(dd_agent_check):
248249
if not e2e_testing():
249250
pytest.skip('Not running E2E tests')
250251

251-
def run(*, discovery_min_instances=1, discovery_timeout=30, **kwargs):
252+
# Process autodiscovery needs to wait for the agent to recognize the process
253+
# as a service which happens after a minimum process age of 1 minute. This
254+
# time can be reduced significantly once agent-side support for reducing the
255+
# minimum age via configuration is available.
256+
extra_timeout = 60 if is_process_e2e else 0
257+
258+
def run(*, discovery_min_instances=1, discovery_timeout=30 + extra_timeout, **kwargs):
252259
return dd_agent_check(
253260
{'init_config': {}, 'instances': []},
254261
discovery_min_instances=discovery_min_instances,
@@ -483,12 +490,29 @@ def enum_object_items(data_source, machine_name, object_name, detail_level):
483490
)
484491

485492

493+
def _is_process_e2e_env() -> bool:
494+
return os.getenv('DDEV_E2E_PROCESS_DISCOVERY', 'false') == 'true'
495+
496+
497+
def _should_skip_in_process_e2e(keywords: Collection[str]) -> bool:
498+
"""In the process-autodiscovery e2e env, only ``process_e2e`` tests run."""
499+
return 'process_e2e' not in keywords
500+
501+
502+
@pytest.fixture(scope='session')
503+
def is_process_e2e() -> bool:
504+
return _is_process_e2e_env()
505+
506+
486507
def pytest_configure(config):
487508
# pytest will emit warnings if these aren't registered ahead of time
488509
for ttype in TEST_TYPES:
489510
config.addinivalue_line('markers', '{}: {}'.format(ttype.name, ttype.description))
490511

491512
config.addinivalue_line("markers", "latest_metrics: marker for verifying support of new metrics")
513+
config.addinivalue_line(
514+
"markers", "process_e2e: also run this e2e test in the process autodiscovery e2e environment"
515+
)
492516

493517

494518
def pytest_addoption(parser):
@@ -498,16 +522,22 @@ def pytest_addoption(parser):
498522
def pytest_collection_modifyitems(config, items):
499523
# at test collection time, this function gets called by pytest, see:
500524
# https://docs.pytest.org/en/latest/example/simple.html#control-skipping-of-tests-according-to-command-line-option
501-
# if the particular option is not present, it will skip all tests marked `latest_metrics`
502-
if config.getoption("--run-latest-metrics"):
503-
# --run-check-metrics given in cli: do not skip slow tests
504-
return
525+
skip_latest_metrics = (
526+
None
527+
if config.getoption("--run-latest-metrics")
528+
else pytest.mark.skip(reason="need --run-latest-metrics option to run")
529+
)
530+
skip_non_process_e2e = (
531+
pytest.mark.skip(reason="not a process autodiscovery e2e test") if _is_process_e2e_env() else None
532+
)
505533

506-
skip_latest_metrics = pytest.mark.skip(reason="need --run-latest-metrics option to run")
507534
for item in items:
508-
if "latest_metrics" in item.keywords:
535+
if skip_latest_metrics and "latest_metrics" in item.keywords:
509536
item.add_marker(skip_latest_metrics)
510537

538+
if skip_non_process_e2e and _should_skip_in_process_e2e(item.keywords):
539+
item.add_marker(skip_non_process_e2e)
540+
511541
item_path = item.path
512542
if item_path is None:
513543
continue
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- name: cel_selector
2+
description: CEL selector for autodiscovery.
3+
enabled: true
4+
example: {}

ddev/changelog.d/24238.added

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Pass capabilities from e2e metadata `cap_add` to the Agent container via `docker --cap-add`.

ddev/src/ddev/e2e/agent/docker.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,9 @@ def start(self, *, agent_build: str | None, local_packages: dict[Path, str], env
275275
for key, value in sorted(env_vars.items()):
276276
command.extend(['-e', f'{key}={value}'])
277277

278+
for cap in self.metadata.get('cap_add', []):
279+
command.extend(['--cap-add', cap])
280+
278281
# The docker `--add-host` command will reliably create entries in the `/etc/hosts` file,
279282
# otherwise, edits to that file will be overwritten on container restarts
280283
for host, ip in self.metadata.get('custom_hosts', []):

krakend/assets/configuration/spec.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,9 @@ files:
8080
overrides:
8181
value.example:
8282
- krakend
83+
- template: auto_conf/cel_selector
84+
overrides:
85+
cel_selector.example:
86+
processes:
87+
- "process.name == 'krakend'"
8388
- template: auto_conf/discovery

krakend/changelog.d/24238.added

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add process autodiscovery support.

krakend/datadog_checks/krakend/data/auto_conf.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
ad_identifiers:
77
- krakend
88

9+
## CEL selector for autodiscovery.
10+
#
11+
cel_selector:
12+
processes:
13+
- process.name == 'krakend'
14+
915
## Enables configuration discovery
1016
#
1117
discovery: {}

0 commit comments

Comments
 (0)