Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .in-toto/tag.47c5a022.link

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions adyen/assets/logs/adyen.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: adyen
metric_id: adyen
backend_only: false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: arctic-wolf-aurora-endpoint-security
metric_id: arctic-wolf-aurora-endpoint-security
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions authorize_net/assets/logs/authorize-net.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: authorize-net
metric_id: authorize-net
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions avast/assets/logs/avast.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: avast
metric_id: avast
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions bentoml/assets/logs/bentoml.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: bentoml
metric_id: bentoml
backend_only: false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: beyondtrust-identity-security-insights
metric_id: beyondtrust-identity-security-insights
backend_only: false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: beyondtrust-password-safe
metric_id: beyondtrust-password-safe
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions bitdefender/assets/logs/bitdefender.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: bitdefender
metric_id: bitdefender
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions box/assets/logs/box.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: box
metric_id: box
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions brevo/assets/logs/brevo.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: brevo
metric_id: brevo
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions carbon_black_cloud/assets/logs/carbon-black-cloud.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
# bypass-global-missing-date-remapper-checks
id: carbon-black-cloud
metric_id: carbon-black-cloud
Expand Down
1 change: 1 addition & 0 deletions cato_networks/assets/logs/cato-networks.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: cato-networks
metric_id: cato-networks
backend_only: false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: checkpoint-harmony-email-and-collaboration
metric_id: checkpoint-harmony-email-and-collaboration
backend_only: false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: checkpoint-quantum-firewall
metric_id: checkpoint-quantum-firewall
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions cisco_asa/assets/logs/cisco-asa.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: cisco-asa
metric_id: cisco-asa
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions cisco_duo/assets/logs/cisco-duo.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: cisco-duo
metric_id: cisco-duo
backend_only: false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: cisco-secure-email-threat-defense
metric_id: cisco-secure-email-threat-defense
backend_only: false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: cisco-secure-endpoint
metric_id: cisco-secure-endpoint
backend_only: false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: cisco-secure-web-appliance
metric_id: cisco-secure-web-appliance
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions cisco_umbrella_dns/assets/logs/cisco-umbrella-dns.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: cisco-umbrella-dns
metric_id: cisco-umbrella-dns
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions cofense_triage/assets/logs/cofense-triage.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: cofense-triage
metric_id: cofense-triage
backend_only: false
Expand Down
12 changes: 12 additions & 0 deletions datadog_checks_base/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

<!-- towncrier release notes start -->

## 37.34.1 / 2026-04-02

***Fixed***:

* Fix logging when using process_isolation parameter. ([#23136](https://github.com/DataDog/integrations-core/pull/23136))

## 37.34.0 / 2026-04-01

***Added***:
Expand All @@ -15,6 +21,12 @@
* Fix process_isolation parameter to handle log formats and external tags. ([#22973](https://github.com/DataDog/integrations-core/pull/22973))
* Reduce allocations in `StatementMetrics` by deferring dict construction and updating the previous-statements cache in place. ([#23075](https://github.com/DataDog/integrations-core/pull/23075))

## 37.33.1 / 2026-03-27

***Fixed***:

* Bump PyJWT to 2.12.1 to address CVE-2026-32597. ([#23065](https://github.com/DataDog/integrations-core/pull/23065))

## 37.33.0 / 2026-03-20

***Added***:
Expand Down
1 change: 1 addition & 0 deletions datadog_checks_base/changelog.d/23140.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improve compile-time error messages for invalid syntax in DB query extras expressions
2 changes: 1 addition & 1 deletion datadog_checks_base/datadog_checks/base/__about__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# (C) Datadog, Inc. 2018-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
__version__ = "37.34.0"
__version__ = "37.34.1"
69 changes: 68 additions & 1 deletion datadog_checks_base/datadog_checks/base/utils/db/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Licensed under a 3-clause BSD style license (see LICENSE)
from __future__ import division

import ast
import re
import time
from datetime import datetime
Expand Down Expand Up @@ -31,6 +32,70 @@
SOURCE_PATTERN = r'(?<!"|\')({})(?!"|\')'


_ALLOWED_AST_NODES = frozenset(
{
ast.Expression,
# Literals
ast.Constant,
ast.Tuple,
ast.List,
ast.Dict,
ast.Set,
# Variables and access
ast.Name,
ast.Load,
ast.Subscript,
ast.Slice,
ast.Attribute,
# Operators
ast.BinOp,
ast.UnaryOp,
ast.BoolOp,
ast.Compare,
ast.IfExp,
ast.Add,
ast.Sub,
ast.Mult,
ast.Div,
ast.FloorDiv,
ast.Mod,
ast.Pow,
ast.USub,
ast.UAdd,
ast.Not,
ast.Invert,
ast.And,
ast.Or,
ast.Eq,
ast.NotEq,
ast.Lt,
ast.LtE,
ast.Gt,
ast.GtE,
ast.Is,
ast.IsNot,
ast.In,
ast.NotIn,
# Function calls
ast.Call,
ast.keyword,
}
)


def _validate_expression_ast(tree: ast.Expression, name: str) -> None:
for node in ast.walk(tree):
node_type = type(node)
if node_type not in _ALLOWED_AST_NODES:
raise ValueError('expression for {} contains unsupported syntax `{}`'.format(name, node_type.__name__))
if node_type is ast.Attribute and node.attr.startswith('__'):
raise ValueError(
'expression for {} accesses reserved attribute `{}`; reference source columns by name directly'.format(
name, node.attr
)
)


def get_tag(transformers, column_name, **modifiers):
# type: (Dict[str, Transformer], str, Any) -> Transformer
"""
Expand Down Expand Up @@ -405,7 +470,9 @@ def get_expression(transformers, name, **modifiers):
expression,
)

expression = compile(expression, filename=name, mode='eval')
tree = ast.parse(expression, filename=name, mode='eval')
_validate_expression_ast(tree, name)
expression = compile(tree, filename=name, mode='eval')

del available_sources

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,11 @@ def _kill_on_timeout():
if message_type == 'aggregator':
getattr(aggregator, message['method'])(check, *message['args'], **message['kwargs'])
elif message_type == 'log':
getattr(check.log, message['method'])(*message['args'])
args = message.get('args', [])
if args:
getattr(check.log, message['method'])(args[0])
elif message_type == 'datadog_agent':
method = message['method']
value = getattr(datadog_agent, method)(*message['args'], **message['kwargs'])
args = message['args']
if method == 'set_external_tags':
args = [[tuple(item) for item in args[0]]]
Expand Down
46 changes: 46 additions & 0 deletions datadog_checks_base/tests/base/utils/db/test_query_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,52 @@ def test_expression_submit_type_unknown(self):
):
query_manager.compile_queries()

@pytest.mark.parametrize(
'expression, match',
[
pytest.param('f"total: {disk.total}"', r'contains unsupported syntax `JoinedStr`', id='f-string'),
pytest.param('sum(x for x in values)', r'contains unsupported syntax `GeneratorExp`', id='generator-expr'),
pytest.param('[x * 2 for x in values]', r'contains unsupported syntax `ListComp`', id='list-comp'),
pytest.param('{k: v for k, v in items}', r'contains unsupported syntax `DictComp`', id='dict-comp'),
pytest.param('(n := disk.total + disk.used)', r'contains unsupported syntax `NamedExpr`', id='walrus'),
pytest.param('lambda x: x + 1', r'contains unsupported syntax `Lambda`', id='lambda'),
pytest.param('result.__class__', r'accesses reserved attribute `__class__`', id='dunder-attr'),
],
)
def test_expression_invalid_syntax(self, expression, match):
query_manager = create_query_manager(
{
'name': 'test query',
'query': 'foo',
'columns': [{'name': 'test.foo', 'type': 'source'}],
'extras': [{'name': 'result', 'type': 'expression', 'expression': expression, 'verbose': True}],
'tags': ['test:bar'],
}
)
with pytest.raises(ValueError, match=match):
query_manager.compile_queries()

@pytest.mark.parametrize(
'expression',
[
pytest.param('disk.total - disk.used', id='arithmetic'),
pytest.param('min(a, b)', id='function-call'),
pytest.param('tags[0]', id='subscript'),
pytest.param('a if condition else b', id='ternary'),
],
)
def test_expression_valid_syntax(self, expression):
query_manager = create_query_manager(
{
'name': 'test query',
'query': 'foo',
'columns': [{'name': 'test.foo', 'type': 'source'}],
'extras': [{'name': 'result', 'type': 'expression', 'expression': expression, 'verbose': True}],
'tags': ['test:bar'],
}
)
query_manager.compile_queries()

@pytest.mark.parametrize('expression', ['import os', 'raise Exception', 'foo = 5'])
def test_expression_compile_error(self, expression):
query_manager = create_query_manager(
Expand Down
2 changes: 2 additions & 0 deletions datadog_checks_base/tests/base/utils/replay/test_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class ReplayCheckBadLog(AgentCheck):
def check(self, _):
self.log.debug('TypeError format: %d', 'not_a_number')
self.log.debug('OverflowError format: %c', 2**32)
self.log.info('Replayed ok with %d arg', 1)


def test_replay_skips_invalid_log_format(caplog, dd_run_check, aggregator, datadog_agent):
Expand All @@ -86,6 +87,7 @@ def test_replay_skips_invalid_log_format(caplog, dd_run_check, aggregator, datad

assert 'TypeError format' not in caplog.text
assert 'OverflowError format' not in caplog.text
assert 'Replayed ok with 1 arg' in caplog.text


class SlowReplayCheck(AgentCheck):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
# bypass-global-grok-parser-rules-checks
id: delinea-privilege-manager
metric_id: delinea-privilege-manager
Expand Down
1 change: 1 addition & 0 deletions eset_protect/assets/logs/eset-protect.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: eset-protect
metric_id: eset-protect
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions extrahop/assets/logs/extrahop.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: extrahop
metric_id: extrahop
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions fly_io/assets/logs/fly_io.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
# bypass-global-missing-date-remapper-checks
id: fly_io
metric_id: fly-io
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
# bypass-global-grok-parser-count-per-pipeline-checks
id: forcepoint-secure-web-gateway
metric_id: forcepoint-secure-web-gateway
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
# bypass-global-grok-parser-count-per-pipeline-checks
id: forcepoint-security-service-edge
metric_id: forcepoint-security-service-edge
Expand Down
1 change: 1 addition & 0 deletions forescout/assets/logs/forescout.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: forescout
metric_id: forescout
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions genesys/assets/logs/genesys.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: genesys
metric_id: genesys
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions harbor/assets/logs/harbor.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
# bypass-global-facets-path-checks
# bypass-global-grok-parser-count-per-pipeline-checks
id: harbor
Expand Down
1 change: 1 addition & 0 deletions have_i_been_pwned/assets/logs/have-i-been-pwned.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: have-i-been-pwned
metric_id: have-i-been-pwned
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions hubspot_content_hub/assets/logs/hubspot-content-hub.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# bypass-global-no-service-config-checks
id: hubspot-content-hub
metric_id: hubspot-content-hub
backend_only: false
Expand Down
1 change: 1 addition & 0 deletions ibm_mq/changelog.d/23130.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix UnicodeDecodeError when IBM MQ queue manager returns channel or queue description fields in non-UTF-8 encoding.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from datadog_checks.base.log import CheckLoggingAdapter # noqa: F401
from datadog_checks.ibm_mq import metrics
from datadog_checks.ibm_mq.config import IBMMQConfig # noqa: F401
from datadog_checks.ibm_mq.utils import normalize_desc_tag
from datadog_checks.ibm_mq.utils import decode_mq_description, normalize_desc_tag

try:
import pymqi
Expand Down Expand Up @@ -53,7 +53,7 @@ def __init__(

def _add_channel_description_tag(self, channel_info, channel_tags):
# Add channel description as a tag, normalizing if configured.
channel_desc = to_string(channel_info[pymqi.CMQCFC.MQCACH_DESC]).strip()
channel_desc = decode_mq_description(channel_info[pymqi.CMQCFC.MQCACH_DESC], self.log).strip()
if channel_desc:
if self.config.normalize_description_tags:
channel_desc = normalize_desc_tag(channel_desc)
Expand Down
Loading
Loading