Skip to content

Commit aa22e70

Browse files
Refine discovery implementation: E2E stability test, spec/auto_conf regeneration, and dependency floor
- Tighten E2E discovery metric assertions from at_least=0 to at_least=1 - Add discovery_overrides.py/discovery_strategies.py stub files - Move ad_identifiers out of the spec discovery stanza and regenerate discovery.py/auto_conf.yaml - Add test_e2e_discovery_all_candidates and fix the changelog filename to match PR #24118 - Add NGINX_CONFIG_FOLDER fallback in docker-compose so docker compose ps works without the env var set - Bump datadog-checks-base floor to >=37.41.0, matching the version that introduced get_e2e_discovery_metadata, assert_all_discovery_candidates_stable, and candidate_ports
1 parent a6c9f65 commit aa22e70

9 files changed

Lines changed: 94 additions & 21 deletions

File tree

nginx/assets/configuration/spec.yaml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ fleet_configurable: true
33
files:
44
- name: nginx.yaml
55
discovery:
6-
ad_identifiers:
7-
- nginx
86
strategies:
97
- strategy: from_ports
108
port_hints:
@@ -109,3 +107,11 @@ files:
109107
- type: file
110108
path: /var/log/nginx/error.log
111109
source: nginx
110+
111+
- name: auto_conf.yaml
112+
options:
113+
- template: ad_identifiers
114+
overrides:
115+
value.example:
116+
- nginx
117+
- template: auto_conf/discovery

nginx/datadog_checks/nginx/config_models/discovery.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,36 @@
77
# ddev -x validate config -s <INTEGRATION_NAME>
88
# ddev -x validate models -s <INTEGRATION_NAME>
99

10+
from __future__ import annotations
11+
1012
from collections.abc import Iterator
1113
from typing import Any
1214

13-
from datadog_checks.base.utils.discovery import Service, from_ports
15+
from datadog_checks.base.utils.discovery import Service, candidate_ports
16+
from datadog_checks.nginx.config_models import discovery_overrides
17+
from datadog_checks.nginx.config_models.instance import InstanceConfig
18+
from datadog_checks.nginx.config_models.shared import SharedConfig
1419

1520

16-
def candidates(service: Service) -> Iterator[dict[str, Any]]:
21+
def _generated_candidates(service: Service) -> Iterator[dict[str, Any]]:
22+
shared = SharedConfig.model_validate({}, context={'configured_fields': frozenset()}).model_dump(
23+
by_alias=True, mode='json', exclude_none=True
24+
)
1725
# discovery[0]: from_ports
18-
for ctx in from_ports(service, port_hints=[80]):
19-
yield {
20-
'init_config': {},
21-
'instances': [
22-
{
23-
'nginx_status_url': 'http://{service.host}:{port.number}/nginx_status'.format(
24-
service=service, **ctx
25-
),
26-
}
27-
],
26+
for port in candidate_ports(service, [80]):
27+
ctx = {'port': port}
28+
instance_data = {
29+
'nginx_status_url': 'http://{service.host}:{port.number}/nginx_status'.format(service=service, **ctx),
2830
}
31+
instance = InstanceConfig.model_validate(
32+
instance_data, context={'configured_fields': frozenset(instance_data)}
33+
).model_dump(by_alias=True, mode='json', exclude_none=True)
34+
yield {'init_config': shared, 'instances': [instance]}
35+
36+
37+
def candidates(service: Service) -> Iterator[dict[str, Any]]:
38+
override = getattr(discovery_overrides, 'candidates', None)
39+
if override is None:
40+
yield from _generated_candidates(service)
41+
else:
42+
yield from override(service, default=_generated_candidates)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# (C) Datadog, Inc. 2026-present
2+
# All rights reserved
3+
# Licensed under a 3-clause BSD style license (see LICENSE)
4+
5+
# Override the generated discovery candidates() for this integration.
6+
#
7+
# Define a candidates(service, default) function to wrap or replace the generated
8+
# candidate generation. `default` is the generated generator; call it to reuse
9+
# the spec-driven candidates, or ignore it to replace them entirely.
10+
#
11+
# def candidates(service, default):
12+
# yield from default(service)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# (C) Datadog, Inc. 2026-present
2+
# All rights reserved
3+
# Licensed under a 3-clause BSD style license (see LICENSE)
4+
5+
# Here you can define custom (local:) discovery strategies for this integration.
6+
#
7+
# Decorate a generator with @discovery_strategy (imported from
8+
# datadog_checks.base.utils.discovery) and reference it from the spec discovery
9+
# stanza as `strategy: local:<function_name>`. The function receives the
10+
# discovered Service plus the inputs declared in the spec and yields one context
11+
# (ctx) mapping per candidate, exposing the keys listed in `provides`.
12+
#
13+
# from datadog_checks.base.utils.discovery import discovery_strategy
14+
#
15+
# @discovery_strategy(provides=('svc',))
16+
# def from_some_config(service, config_path):
17+
# ...
18+
# yield {'svc': ...}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
1+
## @param ad_identifiers - list of strings - required
2+
## A list of container identifiers that are used by Autodiscovery to identify
3+
## which container the check should be run against. For more information, see:
4+
## https://docs.datadoghq.com/agent/guide/ad_identifiers/
5+
#
16
ad_identifiers:
27
- nginx
8+
9+
## Enables configuration discovery
10+
#
311
discovery: {}
12+
13+
## Unused init configuration
14+
#
415
init_config:
16+
17+
## Unused instance configuration
18+
#
519
instances: []

nginx/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ classifiers = [
2828
"Private :: Do Not Upload",
2929
]
3030
dependencies = [
31-
"datadog-checks-base>=37.33.0",
31+
"datadog-checks-base>=37.41.0",
3232
]
3333
dynamic = [
3434
"version",

nginx/tests/docker/docker-compose.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ services:
22
nginx:
33
image: ${NGINX_IMAGE}
44
volumes:
5-
- ${NGINX_CONFIG_FOLDER}:/etc/nginx
5+
- ${NGINX_CONFIG_FOLDER:-/tmp}:/etc/nginx
66
ports:
77
- "8080:80"
88
- "8081:443"

nginx/tests/test_e2e.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,20 @@
33
# Licensed under Simplified BSD License (see LICENSE)
44
import pytest
55

6+
from datadog_checks.dev.docker import assert_all_discovery_candidates_stable
67
from datadog_checks.nginx import Nginx
78

89
from . import common
910

1011

12+
def _assert_nginx_metrics(aggregator):
13+
for m in ('nginx.net.conn_dropped_per_s', 'nginx.net.conn_opened_per_s', 'nginx.net.request_per_s'):
14+
aggregator.assert_metric(m, at_least=1)
15+
for m in ('nginx.net.writing', 'nginx.net.reading', 'nginx.net.waiting', 'nginx.net.connections'):
16+
aggregator.assert_metric(m, at_least=1)
17+
aggregator.assert_service_check('nginx.can_connect', status=Nginx.OK)
18+
19+
1120
@pytest.mark.e2e
1221
@pytest.mark.skipif(common.USING_VTS, reason="Non-VTS test")
1322
def test_e2e(dd_agent_check, instance):
@@ -25,13 +34,13 @@ def test_e2e(dd_agent_check, instance):
2534
@pytest.mark.skipif(common.USING_VTS, reason="Non-VTS test")
2635
def test_e2e_discovery(dd_agent_check_discovery):
2736
aggregator = dd_agent_check_discovery(check_rate=True)
37+
_assert_nginx_metrics(aggregator)
2838

29-
for m in ('nginx.net.conn_dropped_per_s', 'nginx.net.conn_opened_per_s', 'nginx.net.request_per_s'):
30-
aggregator.assert_metric(m, at_least=0)
31-
for m in ('nginx.net.writing', 'nginx.net.reading', 'nginx.net.waiting', 'nginx.net.connections'):
32-
aggregator.assert_metric(m, at_least=0)
3339

34-
aggregator.assert_service_check('nginx.can_connect', status=Nginx.OK)
40+
@pytest.mark.e2e
41+
@pytest.mark.skipif(common.USING_VTS, reason="Non-VTS test")
42+
def test_e2e_discovery_all_candidates(dd_agent_check):
43+
assert_all_discovery_candidates_stable(dd_agent_check, Nginx)
3544

3645

3746
@pytest.mark.e2e

0 commit comments

Comments
 (0)