Skip to content

Commit 9e2044d

Browse files
committed
Merge branch 'aerospike-agent-and-dashboards' of github.com:mphanias/aerospike-datadog-integrations-core into aerospike-agent-and-dashboards
2 parents 5d55991 + 59919af commit 9e2044d

File tree

56 files changed

+925
-155
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+925
-155
lines changed

.github/CODEOWNERS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ datadog_checks_base/datadog_checks/base/checks/windows/ @DataDog/wi
194194
/win32_event_log/ @DataDog/windows-agent @DataDog/agent-integrations
195195
/win32_event_log/*.md @DataDog/windows-agent @DataDog/agent-integrations @DataDog/documentation
196196
/win32_event_log/manifest.json @DataDog/windows-agent @DataDog/agent-integrations @DataDog/documentation
197+
/windows_certificate/ @DataDog/windows-agent @DataDog/agent-integrations
198+
/windows_certificate/*.md @DataDog/windows-agent @DataDog/agent-integrations @DataDog/documentation
199+
/windows_certificate/manifest.json @DataDog/windows-agent @DataDog/agent-integrations @DataDog/documentation
197200
/windows_performance_counters/ @DataDog/windows-agent @DataDog/agent-integrations
198201
/windows_performance_counters/*.md @DataDog/windows-agent @DataDog/agent-integrations @DataDog/documentation
199202
/windows_performance_counters/manifest.json @DataDog/windows-agent @DataDog/agent-integrations @DataDog/documentation

.github/workflows/config/labeler.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,8 @@ integration/win32_event_log:
693693
- win32_event_log/**/*
694694
integration/wincrashdetect:
695695
- wincrashdetect/**/*
696+
integration/windows_certificate:
697+
- windows_certificate/**/*
696698
integration/windows_performance_counters:
697699
- windows_performance_counters/**/*
698700
integration/windows_registry:

.in-toto/tag.ec45eb9d.link

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

appgate_sdp/README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44

55
This check monitors [Appgate SDP][1] through the Datadog Agent.
66

7-
Include a high level overview of what this integration does:
8-
- What does your product do (in 1-2 sentences)?
9-
- What value will customers get from this integration, and why is it valuable to them?
10-
- What specific data will your integration monitor, and what's the value of that data?
7+
- Monitors the health and performance of Appgate SDP appliances, controllers, and gateways by collecting key metrics.
8+
- Provides visibility into resource utilization, active connections, session counts, and license usage to help ensure secure and efficient access management.
9+
- Enables proactive alerting and troubleshooting by tracking critical indicators such as CPU, memory, disk usage, and system events across distributed environments.
1110

1211
## Setup
1312

@@ -20,7 +19,7 @@ No additional installation is needed on your server.
2019

2120
### Configuration
2221

23-
1. Edit the `appgate_sdp.d/conf.yaml` file, in the `conf.d/` folder at the root of your Agent's configuration directory to start collecting your appgate_sdp performance data. See the [sample appgate_sdp.d/conf.yaml][4] for all available configuration options.
22+
1. Edit the `appgate_sdp.d/conf.yaml` file, in the `conf.d/` folder at the root of your Agent's configuration directory to start collecting your Appgate SDP performance data. See the [sample appgate_sdp.d/conf.yaml][4] for all available configuration options.
2423

2524
2. [Restart the Agent][5].
2625

appgate_sdp/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"manifest_version": "2.0.0",
33
"app_uuid": "77acdb8a-4ea8-4294-baa7-d5ccfe698d9f",
44
"app_id": "appgate-sdp",
5-
"display_on_public_website": false,
5+
"display_on_public_website": true,
66
"tile": {
77
"overview": "README.md#Overview",
88
"configuration": "README.md#Setup",

datadog_checks_base/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
<!-- towncrier release notes start -->
44

5+
## 37.13.0 / 2025-05-29
6+
7+
***Added***:
8+
9+
* Add TagManager class to dbm base utils ([#20397](https://github.com/DataDog/integrations-core/pull/20397))
10+
* Update dependencies ([#20399](https://github.com/DataDog/integrations-core/pull/20399))
11+
512
## 37.12.0 / 2025-05-28
613

714
***Added***:

datadog_checks_base/changelog.d/20399.added

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# (C) Datadog, Inc. 2018-present
22
# All rights reserved
33
# Licensed under a 3-clause BSD style license (see LICENSE)
4-
__version__ = "37.12.0"
4+
__version__ = "37.13.0"

datadog_checks_base/datadog_checks/base/utils/db/utils.py

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
import threading
1212
import time
1313
from concurrent.futures.thread import ThreadPoolExecutor
14+
from enum import Enum, auto
1415
from ipaddress import IPv4Address
15-
from typing import Any, Callable, Dict, List, Tuple # noqa: F401
16+
from typing import Any, Callable, Dict, List, Optional, Tuple, Union # noqa: F401
1617

1718
from cachetools import TTLCache
1819

@@ -441,3 +442,128 @@ def tracked_query(check, operation, tags=None):
441442
yield
442443
elapsed_ms = (time.time() - start_time) * 1000
443444
check.histogram("dd.{}.operation.time".format(check.name), elapsed_ms, **stats_kwargs)
445+
446+
447+
class TagType(Enum):
448+
"""Enum for different types of tags"""
449+
450+
KEYLESS = auto()
451+
452+
453+
class TagManager:
454+
"""
455+
Manages tags for a check. Tags are stored as a dictionary of key-value pairs
456+
for key-value tags and as a list of values for keyless tags useful for easy update and deletion.
457+
There's an internal cache of the tag list to avoid generating the list of tag strings
458+
multiple times.
459+
"""
460+
461+
def __init__(self) -> None:
462+
self._tags: Dict[Union[str, TagType], List[str]] = {}
463+
self._cached_tag_list: Optional[tuple[str, ...]] = None
464+
self._keyless: TagType = TagType.KEYLESS
465+
466+
def set_tag(self, key: Optional[str], value: str, replace: bool = False) -> None:
467+
"""
468+
Set a tag with the given key and value.
469+
If key is None or empty, the value is stored as a keyless tag.
470+
Args:
471+
key (str): The tag key, or None/empty for keyless tags
472+
value (str): The tag value
473+
replace (bool): If True, replaces all existing values for this key
474+
If False, appends the value if it doesn't exist
475+
"""
476+
if not key:
477+
key = self._keyless
478+
479+
if replace or key not in self._tags:
480+
self._tags[key] = [value]
481+
# Invalidate the cache since tags have changed
482+
self._cached_tag_list = None
483+
elif value not in self._tags[key]:
484+
self._tags[key].append(value)
485+
# Invalidate the cache since tags have changed
486+
self._cached_tag_list = None
487+
488+
def set_tags_from_list(self, tag_list: List[str], replace: bool = False) -> None:
489+
"""
490+
Set multiple tags from a list of strings.
491+
Strings can be in "key:value" format or just "value" format.
492+
Args:
493+
tag_list (List[str]): List of tags in "key:value" format or just "value"
494+
replace (bool): If True, replaces all existing tags with the new tags list
495+
"""
496+
if replace:
497+
self._tags.clear()
498+
self._cached_tag_list = None
499+
500+
for tag in tag_list:
501+
if ':' in tag:
502+
key, value = tag.split(':', 1)
503+
self.set_tag(key, value)
504+
else:
505+
self.set_tag(None, tag)
506+
507+
def delete_tag(self, key: Optional[str], value: Optional[str] = None) -> bool:
508+
"""
509+
Delete a tag or specific value for a tag.
510+
For keyless tags, use None or empty string as the key.
511+
Args:
512+
key (str): The tag key to delete, or None/empty for keyless tags
513+
value (str, optional): If provided, only deletes this specific value for the key.
514+
If None, deletes all values for the key.
515+
Returns:
516+
bool: True if something was deleted, False otherwise
517+
"""
518+
if not key:
519+
key = self._keyless
520+
521+
if key not in self._tags:
522+
return False
523+
524+
if value is None:
525+
# Delete the entire key
526+
del self._tags[key]
527+
# Invalidate the cache
528+
self._cached_tag_list = None
529+
return True
530+
else:
531+
# Delete specific value if it exists
532+
if value in self._tags[key]:
533+
self._tags[key].remove(value)
534+
# Clean up empty lists
535+
if not self._tags[key]:
536+
del self._tags[key]
537+
# Invalidate the cache
538+
self._cached_tag_list = None
539+
return True
540+
return False
541+
542+
def _generate_tag_strings(self, tags_dict: Dict[Union[str, TagType], List[str]]) -> tuple[str, ...]:
543+
"""
544+
Generate a tuple of tag strings from a tags dictionary.
545+
Args:
546+
tags_dict (Dict[Union[str, TagType], List[str]]): Dictionary of tags to convert to strings
547+
Returns:
548+
tuple[str, ...]: Tuple of tag strings
549+
"""
550+
return tuple(
551+
value if key == self._keyless else f"{key}:{value}" for key, values in tags_dict.items() for value in values
552+
)
553+
554+
def get_tags(self) -> List[str]:
555+
"""
556+
Get a list of tag strings.
557+
For key-value tags, returns "key:value" format.
558+
For keyless tags, returns just the value.
559+
The returned list is always sorted alphabetically.
560+
Returns:
561+
list: Sorted list of tag strings
562+
"""
563+
# Return cached list if available
564+
if self._cached_tag_list is not None:
565+
return list(self._cached_tag_list)
566+
567+
# Generate and cache regular tags
568+
self._cached_tag_list = self._generate_tag_strings(self._tags)
569+
return list(self._cached_tag_list)

0 commit comments

Comments
 (0)