Skip to content

Submit general resource via checks base#23905

Open
steveny91 wants to merge 11 commits into
masterfrom
sy/genresources-allow-list
Open

Submit general resource via checks base#23905
steveny91 wants to merge 11 commits into
masterfrom
sy/genresources-allow-list

Conversation

@steveny91
Copy link
Copy Markdown
Contributor

@steveny91 steveny91 commented Jun 2, 2026

What does this PR do?
Add helper functions to submit data to general resources via EVP.

As part a 3 part process:
PR1 to add the forwarder: DataDog/datadog-agent#51365
PR2 to add the helper functions in checks: this PR
PR3 to onboard ArgoCD as to submit entity metadata: #23834

@datadog-prod-us1-5
Copy link
Copy Markdown

datadog-prod-us1-5 Bot commented Jun 2, 2026

Pipelines  Tests  Code Coverage

Fix all issues with BitsAI

⚠️ Warnings

🚦 5 Pipeline jobs failed

PR All | test / j06ca546 / SNMP   View in Datadog   GitHub Actions

PR All | test / j46da136 / JBoss_WildFly   View in Datadog   GitHub Actions

PR All | test / j5a9585a / IBM ACE   View in Datadog   GitHub Actions

View all 5 failed jobs.

🧪 20 Tests failed in 1 job

PR All | run   GitHub Actions

test_bulk_table from test_check.py   View in Datadog (Fix with Cursor)
HTTPSConnectionPool(host='ddintegrations.blob.core.windows.net', port=443): Max retries exceeded with url: /snmp/cisco-3850.snmprec (Caused by NameResolutionError("HTTPSConnection(host='ddintegrations.blob.core.windows.net', port=443): Failed to resolve 'ddintegrations.blob.core.windows.net' ([Errno -2] Name or service not known)"))
test_cast_metrics from test_check.py   View in Datadog (Fix with Cursor)
HTTPSConnectionPool(host='ddintegrations.blob.core.windows.net', port=443): Max retries exceeded with url: /snmp/cisco-3850.snmprec (Caused by NameResolutionError("HTTPSConnection(host='ddintegrations.blob.core.windows.net', port=443): Failed to resolve 'ddintegrations.blob.core.windows.net' ([Errno -2] Name or service not known)"))

View all 20 test failures

ℹ️ Info

No other issues found (see more)

❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 88.96%
Overall Coverage: 87.67% (-0.25%)

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: b3500a9 | Docs | Datadog PR Page | Give us feedback!

@steveny91 steveny91 changed the title Sy/genresources allow list Submit general resource via checks base Jun 2, 2026
@steveny91 steveny91 marked this pull request as ready for review June 3, 2026 15:51
@steveny91 steveny91 requested a review from a team as a code owner June 3, 2026 15:51
@steveny91 steveny91 added the qa/skip-qa Automatically skip this PR for the next QA label Jun 4, 2026
Comment on lines +823 to +826
``include`` is required: ``{"paths": [...], "map_paths": [...], "annotation_keys": [...]}``.
``paths`` select values; ``map_paths`` select whole flat maps (e.g. ``metadata.labels``);
``annotation_keys`` glob ``metadata.annotations`` keys. A path that resolves to a structured
object is dropped. ``seen_at`` / ``expire_at`` are optional ``int`` unix-seconds.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit
I find the wording a bit confusing.

  • There is no need to specify that args/kwargs are required or not, that is ensured by the function signature.
  • After reading I'm still not sure where 'paths' and the other selectors select FROM?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Paths select from a json tree. For example:
status.operationState.operation.initiatedBy.username

Selects a field inside of status called operationState etc.:

Something like this for example.

{
  "status": {
    "operationState": {
      "operation": {
        "initiatedBy": {
          "username": "string"
        }
      }
    }
  }
}

status.operationState.operation[*].username:
This is used for arrays if operation was an array. It just means grab the username for each operation inside the array.

For maps_path it's only for flat maps for example:

  {
    "metadata": {
      "labels": {
        "team": "platform",
        "env": "prod"
      }
    }
  }

metadata.labels will take both team and env labels.

Comment on lines +850 to +853
if not key:
self.log.warning("genresources: dropping resource with empty key for type=%s", type)
_emit_dropped()
return
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

request
Please add a check for type as well.

_emit_dropped()
return

if any(not pattern.strip("*?") for pattern in annotation_keys):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question
Patterns like *a* will pass through, is this intended?

Comment on lines +63 to +64
if _targets_annotations(segments):
continue
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question
Why are "annotations" forbidden in the paths?

request
Please add a log for the skipped path/map_path. Maybe at DEBUG level.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for the most part, annotations can contain sensitive information in kubernetes. Say for example you annotate this application with a postgrescheck for example. So this is just to prevent annotations and secrets from being leaked and collected.

datadog_agent.emit_agent_telemetry(integration, "datadog.agent.check.genresources.dropped", count, "count")

if not key:
self.log.warning("genresources: dropping resource with empty key for type=%s", type)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any more information you can print in this log line?

return

# stdlib json on purpose: module-level json is the orjson wrapper, which coerces datetime instead of failing.
import json as _json
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, what you think about about using orjson but using the orjson.OPT_PASSTHROUGH_DATETIME flag to handle datetime?

``include`` is required: ``{"paths": [...], "map_paths": [...], "annotation_keys": [...]}``.
``paths`` select values; ``map_paths`` select whole flat maps (e.g. ``metadata.labels``);
``annotation_keys`` glob ``metadata.annotations`` keys. A path that resolves to a structured
object is dropped. Pass ``include=INCLUDE_ALL`` to ship a dict you built in code as-is — only
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might just be personal preference, but I don't see the need to define this INCLUDE_ALL constant when we could just let None signify INCLUDE_ALL

Copy link
Copy Markdown
Contributor Author

@steveny91 steveny91 Jun 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted this to be an explicit flag. The process for scrubbing data is pretty hard sadly. So I wanted the ability to ingest everything to be explicitly agreed on.


from datadog_checks.base.utils.genresources.inclusion import apply_allow_list, find_invalid_include


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about testing the inclusion logic solely in test_agent_check_submit_generic_resource.py by passing different include values to get_event_platform_events? That way we only test the public method get_event_platform_events and the tests are resilient to refactors of this logic.

def test_submit_generic_resource_drops_and_counts_invalid_input(aggregator, check, kwargs):
check.submit_generic_resource(**kwargs)
assert aggregator.get_event_platform_events("genresources", parse_json=False) == []
datadog_agent.assert_telemetry("argocd", "datadog.agent.check.genresources.dropped", "count", 1)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you test the log lines here too?

@dd-octo-sts
Copy link
Copy Markdown
Contributor

dd-octo-sts Bot commented Jun 5, 2026

Validation Report

All 21 validations passed.

Show details
Validation Description Status
agent-reqs Verify check versions match the Agent requirements file
ci Validate CI configuration and code coverage settings
codeowners Validate every integration has a CODEOWNERS entry
config Validate default configuration files against spec.yaml
dep Verify dependency pins are consistent and Agent-compatible
http Validate integrations use the HTTP wrapper correctly
imports Validate check imports do not use deprecated modules
integration-style Validate check code style conventions
jmx-metrics Validate JMX metrics definition files and config
labeler Validate PR labeler config matches integration directories
legacy-signature Validate no integration uses the legacy Agent check signature
license-headers Validate Python files have proper license headers
licenses Validate third-party license attribution list
metadata Validate metadata.csv metric definitions
models Validate configuration data models match spec.yaml
openmetrics Validate OpenMetrics integrations disable the metric limit
package Validate Python package metadata and naming
qa-label Validate the pull request declares whether it needs QA for the next Agent release
readmes Validate README files have required sections
saved-views Validate saved view JSON file structure and fields
version Validate version consistency between package and changelog

View full run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

base_package qa/skip-qa Automatically skip this PR for the next QA team/agent-integrations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants