diff --git a/.codecov.yml b/.codecov.yml index b3cfc075f7df5..6e1b5b1c7ef12 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -758,6 +758,10 @@ coverage: target: 75 flags: - cert_manager + datadog_csi_driver: + target: 75 + flags: + - datadog_csi_driver dcgm: target: 75 flags: @@ -1000,6 +1004,11 @@ flags: paths: - datadog_cluster_agent/datadog_checks/datadog_cluster_agent - datadog_cluster_agent/tests + datadog_csi_driver: + carryforward: true + paths: + - datadog_csi_driver/datadog_checks/datadog_csi_driver + - datadog_csi_driver/tests dcgm: carryforward: true paths: diff --git a/.ddqa/config.toml b/.ddqa/config.toml index 5fba1e85a1ae4..3d6cf36d84e23 100644 --- a/.ddqa/config.toml +++ b/.ddqa/config.toml @@ -45,6 +45,21 @@ exclude_members = [ ] github_labels = ["team/container-integrations"] +[teams."Container Platform"] +jira_project = "CONTP" +jira_issue_type = "Task" +jira_statuses = [ + "To Do", + "In Progress", + "Done", +] +github_team = "container-platform" +exclude_members = [ + "clamoriniere", + "hkaj", +] +github_labels = ["team/container-platform"] + [teams."Database Monitoring"] jira_project = "DBMON" jira_issue_type = "Task" diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 365acfcff0f5e..9d5318128bf81 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -44,6 +44,8 @@ manifest.json @DataDog/documentation @DataDog/agent-integrations /crio/manifest.json @DataDog/container-integrations @DataDog/agent-integrations @DataDog/documentation /datadog_cluster_agent/ @DataDog/container-integrations @DataDog/agent-integrations /datadog_cluster_agent/*.md @DataDog/container-integrations @DataDog/agent-integrations @DataDog/documentation +/datadog_csi_driver/ @DataDog/container-platform @DataDog/agent-integrations +/datadog_csi_driver/*.md @DataDog/container-platform @DataDog/agent-integrations @DataDog/documentation /datadog_operator/ @DataDog/container-ecosystems @DataDog/agent-integrations /datadog_operator/*.md @DataDog/container-ecosystems @DataDog/agent-integrations @DataDog/documentation /docker_daemon/ @DataDog/container-integrations @DataDog/agent-integrations diff --git a/.github/workflows/config/labeler.yml b/.github/workflows/config/labeler.yml index c245bc7c4aa00..50999edddba6d 100644 --- a/.github/workflows/config/labeler.yml +++ b/.github/workflows/config/labeler.yml @@ -183,6 +183,8 @@ integration/datadog_checks_tests_helper: - datadog_checks_tests_helper/**/* integration/datadog_cluster_agent: - datadog_cluster_agent/**/* +integration/datadog_csi_driver: +- datadog_csi_driver/**/* integration/datadog_operator: - datadog_operator/**/* integration/dcgm: diff --git a/.github/workflows/test-all.yml b/.github/workflows/test-all.yml index 67dd5d9bdab95..3460c9f513ddb 100644 --- a/.github/workflows/test-all.yml +++ b/.github/workflows/test-all.yml @@ -857,6 +857,25 @@ jobs: minimum-base-package: ${{ inputs.minimum-base-package }} pytest-args: ${{ inputs.pytest-args }} secrets: inherit + j58cf93c: + uses: ./.github/workflows/test-target.yml + with: + job-name: datadog_csi_driver + target: datadog_csi_driver + platform: linux + runner: '["ubuntu-22.04"]' + repo: "${{ inputs.repo }}" + python-version: "${{ inputs.python-version }}" + latest: ${{ inputs.latest }} + agent-image: "${{ inputs.agent-image }}" + agent-image-py2: "${{ inputs.agent-image-py2 }}" + agent-image-windows: "${{ inputs.agent-image-windows }}" + agent-image-windows-py2: "${{ inputs.agent-image-windows-py2 }}" + test-py2: ${{ inputs.test-py2 }} + test-py3: ${{ inputs.test-py3 }} + minimum-base-package: ${{ inputs.minimum-base-package }} + pytest-args: ${{ inputs.pytest-args }} + secrets: inherit j69f9754: uses: ./.github/workflows/test-target.yml with: diff --git a/cisco_aci/datadog_checks/cisco_aci/fabric.py b/cisco_aci/datadog_checks/cisco_aci/fabric.py index 3842f8d63d335..683e07c3ca9a6 100644 --- a/cisco_aci/datadog_checks/cisco_aci/fabric.py +++ b/cisco_aci/datadog_checks/cisco_aci/fabric.py @@ -9,8 +9,8 @@ VENDOR_CISCO = 'cisco' PAYLOAD_METADATA_BATCH_SIZE = 100 -DEVICE_USER_TAGS_PREFIX = "dd.internal.resource:ndm_device_user_tags" -INTERFACE_USER_TAGS_PREFIX = "dd.internal.resource:ndm_interface_user_tags" +DEVICE_TAGS_PREFIX = "dd.internal.resource:ndm_device" +INTERFACE_TAGS_PREFIX = "dd.internal.resource:ndm_interface" class Fabric: @@ -104,7 +104,7 @@ def submit_nodes_health_and_metadata(self, nodes, pods): device_metadata.append(ndm.create_node_metadata(node_attrs, tags, self.namespace)) device_id = '{}:{}'.format(self.namespace, node_attrs.get('address', '')) - tags.append('{}:{}'.format(DEVICE_USER_TAGS_PREFIX, device_id)) + tags.append('{}:{}'.format(DEVICE_TAGS_PREFIX, device_id)) self.submit_process_metric(n, tags + self.check_tags + user_tags, hostname=hostname) except (exceptions.APIConnectionException, exceptions.APIParsingException): @@ -140,10 +140,10 @@ def process_eth(self, node): interface_metadata = ndm.create_interface_metadata(e, node.get('address', ''), self.namespace) interfaces.append(interface_metadata) device_id = '{}:{}'.format(self.namespace, node.get('address', '')) - tags.append('{}:{}'.format(DEVICE_USER_TAGS_PREFIX, device_id)) + tags.append('{}:{}'.format(DEVICE_TAGS_PREFIX, device_id)) tags.append( "{}:{}:{}".format( - INTERFACE_USER_TAGS_PREFIX, interface_metadata.device_id, str(interface_metadata.index) + INTERFACE_TAGS_PREFIX, interface_metadata.device_id, str(interface_metadata.index) ), ) self.submit_interface_status_metric( diff --git a/cisco_aci/tests/test_fabric.py b/cisco_aci/tests/test_fabric.py index 0e8feb1a01f60..416a7571bb550 100644 --- a/cisco_aci/tests/test_fabric.py +++ b/cisco_aci/tests/test_fabric.py @@ -31,40 +31,40 @@ namespace = 'default' -node101_port1 = 'dd.internal.resource:ndm_interface_user_tags:default:10.0.200.0:1' -node101_port2 = 'dd.internal.resource:ndm_interface_user_tags:default:10.0.200.0:2' -node102_port1 = 'dd.internal.resource:ndm_interface_user_tags:default:10.0.200.1:1' -node102_port2 = 'dd.internal.resource:ndm_interface_user_tags:default:10.0.200.1:2' -node201_port1 = 'dd.internal.resource:ndm_interface_user_tags:default:10.0.200.5:1' -node201_port2 = 'dd.internal.resource:ndm_interface_user_tags:default:10.0.200.5:2' +node101_port1 = 'dd.internal.resource:ndm_interface:default:10.0.200.0:1' +node101_port2 = 'dd.internal.resource:ndm_interface:default:10.0.200.0:2' +node102_port1 = 'dd.internal.resource:ndm_interface:default:10.0.200.1:1' +node102_port2 = 'dd.internal.resource:ndm_interface:default:10.0.200.1:2' +node201_port1 = 'dd.internal.resource:ndm_interface:default:10.0.200.5:1' +node201_port2 = 'dd.internal.resource:ndm_interface:default:10.0.200.5:2' device_tags_101 = [ 'device_hostname:{}'.format(device_hn101), 'device_id:{}:{}'.format(namespace, node101), 'device_ip:{}'.format(node101), 'device_namespace:{}'.format(namespace), - 'dd.internal.resource:ndm_device_user_tags:default:10.0.200.0', + 'dd.internal.resource:ndm_device:default:10.0.200.0', ] device_tags_102 = [ 'device_hostname:{}'.format(device_hn102), 'device_id:{}:{}'.format(namespace, node102), 'device_ip:{}'.format(node102), 'device_namespace:{}'.format(namespace), - 'dd.internal.resource:ndm_device_user_tags:default:10.0.200.1', + 'dd.internal.resource:ndm_device:default:10.0.200.1', ] device_tags_201 = [ 'device_hostname:{}'.format(device_hn201), 'device_id:{}:{}'.format(namespace, node201), 'device_ip:{}'.format(node201), 'device_namespace:{}'.format(namespace), - 'dd.internal.resource:ndm_device_user_tags:default:10.0.200.5', + 'dd.internal.resource:ndm_device:default:10.0.200.5', ] device_tags_1 = [ 'device_hostname:{}'.format(device_hn1), 'device_id:{}:{}'.format(namespace, node1), 'device_ip:{}'.format(node1), 'device_namespace:{}'.format(namespace), - 'dd.internal.resource:ndm_device_user_tags:default:10.0.200.4', + 'dd.internal.resource:ndm_device:default:10.0.200.4', ] tags000 = ['cisco', 'project:cisco_aci', 'medium:broadcast', 'snmpTrapSt:enable', 'fabric_pod_id:1'] @@ -129,8 +129,8 @@ def test_fabric_mocked(aggregator): 'device_hostname:{}'.format(device_hn), 'device_id:{}'.format(interface.device_id), 'status:{}'.format(interface.status), - 'dd.internal.resource:ndm_device_user_tags:{}'.format(interface.device_id), - 'dd.internal.resource:ndm_interface_user_tags:{}:{}'.format(interface.device_id, interface.index), + 'dd.internal.resource:ndm_device:{}'.format(interface.device_id), + 'dd.internal.resource:ndm_interface:{}:{}'.format(interface.device_id, interface.index), ] aggregator.assert_metric('cisco_aci.fabric.port.status', value=1.0, tags=interface_tags, hostname=device_hn) diff --git a/datadog_csi_driver/CHANGELOG.md b/datadog_csi_driver/CHANGELOG.md new file mode 100644 index 0000000000000..6d3ea292f1249 --- /dev/null +++ b/datadog_csi_driver/CHANGELOG.md @@ -0,0 +1,4 @@ +# CHANGELOG - datadog_csi_driver + + + diff --git a/datadog_csi_driver/README.md b/datadog_csi_driver/README.md new file mode 100644 index 0000000000000..9de872e122e50 --- /dev/null +++ b/datadog_csi_driver/README.md @@ -0,0 +1,61 @@ +# Agent Check: datadog_csi_driver + +## Overview + +This check monitors [`datadog_csi_driver`][1] through the Datadog Agent. + +The Datadog CSI Driver is a DaemonSet that runs a gRPC server implementing the CSI specifications on each node of your Kubernetes cluster. + +Installing Datadog CSI driver on a Kubernetes cluster allows using CSI volumes by specifying the name of Datadog CSI driver. + +The Datadog CSI node server is responsible for managing Datadog CSI volume lifecycle, allowing mounting UDS sockets for high performance dogstatsd and tracing without breaking constraints set by [`kubernetes pod security standards`][10]. + +The Datadog CSI Driver integration collects and monitors metrics from your Datadog CSI Driver, providing visibility into publish/unpublish requests and pod health for improved troubleshooting and performance monitoring. + +## Setup + +Follow the instructions below to install and configure this check for an Agent running on a host. For containerized environments, see the [Autodiscovery Integration Templates][3] for guidance on applying these instructions. + +### Installation + +The `datadog_csi_driver` check is included in the [Datadog Agent][2] package. +No additional installation is needed on your server. + +### Configuration + +1. Edit the `datadog_csi_driver.d/conf.yaml` file, located in the `conf.d/` folder at the root of your Agent's configuration directory to start collecting your `datadog_csi_driver` performance data. See the [sample datadog_csi_driver.d/conf.yaml][4] for all available configuration options. + +2. [Restart the Agent][5]. + +### Validation + +[Run the Agent's status subcommand][6] and verify that `datadog_csi_driver` appears under the Checks section. + +## Data Collected + +### Metrics + +See [metadata.csv][7] for a list of metrics provided by this integration. + +### Events + +This integration does not include any events. + +### Service Checks + +This integration does not include any service checks. + +## Troubleshooting + +Need help? Contact [Datadog support][9]. + +[1]: https://docs.datadoghq.com/containers/csi_driver/ +[2]: https://app.datadoghq.com/account/settings/agent/latest +[3]: https://docs.datadoghq.com/containers/kubernetes/integrations/ +[4]: https://github.com/DataDog/integrations-core/blob/master/datadog_csi_driver/datadog_checks/datadog_csi_driver/data/conf.yaml.example +[5]: https://docs.datadoghq.com/agent/configuration/agent-commands/#start-stop-and-restart-the-agent +[6]: https://docs.datadoghq.com/agent/configuration/agent-commands/#agent-status-and-information +[7]: https://github.com/DataDog/integrations-core/blob/master/datadog_csi_driver/metadata.csv +[8]: https://github.com/DataDog/integrations-core/blob/master/datadog_csi_driver/assets/service_checks.json +[9]: https://docs.datadoghq.com/help/ +[10]: https://kubernetes.io/docs/concepts/security/pod-security-standards/ diff --git a/datadog_csi_driver/assets/configuration/spec.yaml b/datadog_csi_driver/assets/configuration/spec.yaml new file mode 100644 index 0000000000000..44884f00a6529 --- /dev/null +++ b/datadog_csi_driver/assets/configuration/spec.yaml @@ -0,0 +1,24 @@ +name: Datadog CSI Driver +files: +- name: datadog_csi_driver.yaml + options: + - template: init_config + options: + - template: init_config/default + - template: instances + options: + - template: instances/openmetrics +- name: auto_conf.yaml + options: + - template: ad_identifiers + overrides: + value.example: + - csi-driver + - template: init_config + options: + - template: init_config/openmetrics_legacy + - template: instances + options: + - template: instances/openmetrics_legacy + overrides: + prometheus_url.value.example: http://%%host%%:5000/metrics diff --git a/datadog_csi_driver/assets/dashboards/datadog_csi_driver_overview.json b/datadog_csi_driver/assets/dashboards/datadog_csi_driver_overview.json new file mode 100644 index 0000000000000..72f68c2654c9a --- /dev/null +++ b/datadog_csi_driver/assets/dashboards/datadog_csi_driver_overview.json @@ -0,0 +1,206 @@ +{ + "title": "Datadog CSI Driver Overview", + "description": "Dashboard showing the state of Datadog CSI driver and the publish and unpublish requests.", + "widgets": [ + { + "id": 1034514339638144, + "definition": { + "title": "CSI Node Server Pods", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "response_format": "timeseries", + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "sum:kubernetes_state.pod.count{kube_daemon_set:datadog-csi-driver-node-server} by {cluster_name}" + } + ], + "formulas": [ + { + "formula": "query1" + } + ], + "style": { + "palette": "dog_classic", + "order_by": "values", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 0, + "width": 4, + "height": 2 + } + }, + { + "id": 7486956895262488, + "definition": { + "title": "Container Restarts", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "response_format": "timeseries", + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "sum:kubernetes_state.container.restarts{kube_daemon_set:datadog-csi-driver-node-server} by {cluster_name}" + } + ], + "formulas": [ + { + "formula": "query1" + } + ], + "style": { + "palette": "dog_classic", + "order_by": "values", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 4, + "y": 0, + "width": 4, + "height": 2 + } + }, + { + "id": 7496902802045867, + "definition": { + "title": "Publish Volume Requests", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "response_format": "timeseries", + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "sum:datadog.csi_driver.node_publish_volume_attempts.count{*} by {status,type}.as_count()" + } + ], + "formulas": [ + { + "formula": "query1" + } + ], + "style": { + "palette": "dog_classic", + "order_by": "values", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 8, + "y": 0, + "width": 4, + "height": 2 + } + }, + { + "id": 5905199997649465, + "definition": { + "title": "Unpublish Volume Requests", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "response_format": "timeseries", + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "sum:datadog.csi_driver.node_unpublish_volume_attempts.count{*} by {status}.as_count()" + } + ], + "formulas": [ + { + "formula": "query1" + } + ], + "style": { + "palette": "dog_classic", + "order_by": "values", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 2, + "width": 4, + "height": 2 + } + } + ], + "template_variables": [], + "layout_type": "ordered", + "notify_list": [], + "reflow_type": "fixed", + "tags": [ + "team:container-platform", + "team:combined-agent" + ] +} \ No newline at end of file diff --git a/datadog_csi_driver/changelog.d/21151.added b/datadog_csi_driver/changelog.d/21151.added new file mode 100644 index 0000000000000..aa949b47b7b41 --- /dev/null +++ b/datadog_csi_driver/changelog.d/21151.added @@ -0,0 +1 @@ +Initial Release \ No newline at end of file diff --git a/datadog_csi_driver/datadog_checks/datadog_csi_driver/__about__.py b/datadog_csi_driver/datadog_checks/datadog_csi_driver/__about__.py new file mode 100644 index 0000000000000..1bde5986a04b2 --- /dev/null +++ b/datadog_csi_driver/datadog_checks/datadog_csi_driver/__about__.py @@ -0,0 +1,4 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +__version__ = '0.0.1' diff --git a/datadog_csi_driver/datadog_checks/datadog_csi_driver/__init__.py b/datadog_csi_driver/datadog_checks/datadog_csi_driver/__init__.py new file mode 100644 index 0000000000000..d77cedda99a81 --- /dev/null +++ b/datadog_csi_driver/datadog_checks/datadog_csi_driver/__init__.py @@ -0,0 +1,7 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +from .__about__ import __version__ +from .check import DatadogCSIDriverCheck + +__all__ = ['__version__', 'DatadogCSIDriverCheck'] diff --git a/datadog_csi_driver/datadog_checks/datadog_csi_driver/check.py b/datadog_csi_driver/datadog_checks/datadog_csi_driver/check.py new file mode 100644 index 0000000000000..fa59eda2dace0 --- /dev/null +++ b/datadog_csi_driver/datadog_checks/datadog_csi_driver/check.py @@ -0,0 +1,28 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +from datadog_checks.base import OpenMetricsBaseCheckV2 + +METRICS_MAP = [ + { + 'datadog_csi_driver_node_publish_volume_attempts': {'name': 'node_publish_volume_attempts'}, + 'datadog_csi_driver_node_unpublish_volume_attempts': {'name': 'node_unpublish_volume_attempts'}, + } +] + + +class DatadogCSIDriverCheck(OpenMetricsBaseCheckV2): + __NAMESPACE__ = 'datadog.csi_driver' + DEFAULT_METRIC_LIMIT = 0 + + def __init__(self, name, init_config, instances): + super().__init__(name, init_config, instances) + + def get_default_config(self): + return { + 'metrics': METRICS_MAP, + 'openmetrics_endpoint': 'http://localhost:5000/metrics', + } + + def check(self, instance): + super().check(instance) diff --git a/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/__init__.py b/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/__init__.py new file mode 100644 index 0000000000000..4d80b1e478f62 --- /dev/null +++ b/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/__init__.py @@ -0,0 +1,24 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) + +# This file is autogenerated. +# To change this file you should edit assets/configuration/spec.yaml and then run the following commands: +# ddev -x validate config -s +# ddev -x validate models -s + +from .instance import InstanceConfig +from .shared import SharedConfig + + +class ConfigMixin: + _config_model_instance: InstanceConfig + _config_model_shared: SharedConfig + + @property + def config(self) -> InstanceConfig: + return self._config_model_instance + + @property + def shared_config(self) -> SharedConfig: + return self._config_model_shared diff --git a/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/defaults.py b/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/defaults.py new file mode 100644 index 0000000000000..cf4ad06207be4 --- /dev/null +++ b/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/defaults.py @@ -0,0 +1,124 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) + +# This file is autogenerated. +# To change this file you should edit assets/configuration/spec.yaml and then run the following commands: +# ddev -x validate config -s +# ddev -x validate models -s + + +def instance_allow_redirects(): + return True + + +def instance_auth_type(): + return 'basic' + + +def instance_cache_metric_wildcards(): + return True + + +def instance_cache_shared_labels(): + return True + + +def instance_collect_counters_with_distributions(): + return False + + +def instance_collect_histogram_buckets(): + return True + + +def instance_disable_generic_tags(): + return False + + +def instance_empty_default_hostname(): + return False + + +def instance_enable_health_service_check(): + return True + + +def instance_histogram_buckets_as_distributions(): + return False + + +def instance_ignore_connection_errors(): + return False + + +def instance_kerberos_auth(): + return 'disabled' + + +def instance_kerberos_delegate(): + return False + + +def instance_kerberos_force_initiate(): + return False + + +def instance_log_requests(): + return False + + +def instance_min_collection_interval(): + return 15 + + +def instance_non_cumulative_histogram_buckets(): + return False + + +def instance_persist_connections(): + return False + + +def instance_request_size(): + return 16 + + +def instance_skip_proxy(): + return False + + +def instance_tag_by_endpoint(): + return True + + +def instance_telemetry(): + return False + + +def instance_timeout(): + return 10 + + +def instance_tls_ignore_warning(): + return False + + +def instance_tls_use_host_header(): + return False + + +def instance_tls_verify(): + return True + + +def instance_use_latest_spec(): + return False + + +def instance_use_legacy_auth_encoding(): + return True + + +def instance_use_process_start_time(): + return False diff --git a/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/instance.py b/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/instance.py new file mode 100644 index 0000000000000..e33be37fd1cf5 --- /dev/null +++ b/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/instance.py @@ -0,0 +1,172 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) + +# This file is autogenerated. +# To change this file you should edit assets/configuration/spec.yaml and then run the following commands: +# ddev -x validate config -s +# ddev -x validate models -s + +from __future__ import annotations + +from types import MappingProxyType +from typing import Any, Optional, Union + +from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator + +from datadog_checks.base.utils.functions import identity +from datadog_checks.base.utils.models import validation + +from . import defaults, validators + + +class AuthToken(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + frozen=True, + ) + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None + + +class ExtraMetrics(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + extra='allow', + frozen=True, + ) + name: Optional[str] = None + type: Optional[str] = None + + +class MetricPatterns(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + frozen=True, + ) + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None + + +class Metrics(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + extra='allow', + frozen=True, + ) + name: Optional[str] = None + type: Optional[str] = None + + +class Proxy(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + frozen=True, + ) + http: Optional[str] = None + https: Optional[str] = None + no_proxy: Optional[tuple[str, ...]] = None + + +class ShareLabels(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + frozen=True, + ) + labels: Optional[tuple[str, ...]] = None + match: Optional[tuple[str, ...]] = None + + +class InstanceConfig(BaseModel): + model_config = ConfigDict( + validate_default=True, + arbitrary_types_allowed=True, + frozen=True, + ) + allow_redirects: Optional[bool] = None + auth_token: Optional[AuthToken] = None + auth_type: Optional[str] = None + aws_host: Optional[str] = None + aws_region: Optional[str] = None + aws_service: Optional[str] = None + cache_metric_wildcards: Optional[bool] = None + cache_shared_labels: Optional[bool] = None + collect_counters_with_distributions: Optional[bool] = None + collect_histogram_buckets: Optional[bool] = None + connect_timeout: Optional[float] = None + disable_generic_tags: Optional[bool] = None + empty_default_hostname: Optional[bool] = None + enable_health_service_check: Optional[bool] = None + exclude_labels: Optional[tuple[str, ...]] = None + exclude_metrics: Optional[tuple[str, ...]] = None + exclude_metrics_by_labels: Optional[MappingProxyType[str, Union[bool, tuple[str, ...]]]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + extra_metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, ExtraMetrics]]], ...]] = None + headers: Optional[MappingProxyType[str, Any]] = None + histogram_buckets_as_distributions: Optional[bool] = None + hostname_format: Optional[str] = None + hostname_label: Optional[str] = None + ignore_connection_errors: Optional[bool] = None + ignore_tags: Optional[tuple[str, ...]] = None + include_labels: Optional[tuple[str, ...]] = None + kerberos_auth: Optional[str] = None + kerberos_cache: Optional[str] = None + kerberos_delegate: Optional[bool] = None + kerberos_force_initiate: Optional[bool] = None + kerberos_hostname: Optional[str] = None + kerberos_keytab: Optional[str] = None + kerberos_principal: Optional[str] = None + log_requests: Optional[bool] = None + metric_patterns: Optional[MetricPatterns] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metrics]]], ...]] = None + min_collection_interval: Optional[float] = None + namespace: Optional[str] = Field(None, pattern='\\w*') + non_cumulative_histogram_buckets: Optional[bool] = None + ntlm_domain: Optional[str] = None + openmetrics_endpoint: str + password: Optional[str] = None + persist_connections: Optional[bool] = None + proxy: Optional[Proxy] = None + raw_line_filters: Optional[tuple[str, ...]] = None + raw_metric_prefix: Optional[str] = None + read_timeout: Optional[float] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None + request_size: Optional[float] = None + service: Optional[str] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabels]]] = None + skip_proxy: Optional[bool] = None + tag_by_endpoint: Optional[bool] = None + tags: Optional[tuple[str, ...]] = None + telemetry: Optional[bool] = None + timeout: Optional[float] = None + tls_ca_cert: Optional[str] = None + tls_cert: Optional[str] = None + tls_ciphers: Optional[tuple[str, ...]] = None + tls_ignore_warning: Optional[bool] = None + tls_private_key: Optional[str] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None + tls_use_host_header: Optional[bool] = None + tls_verify: Optional[bool] = None + use_latest_spec: Optional[bool] = None + use_legacy_auth_encoding: Optional[bool] = None + use_process_start_time: Optional[bool] = None + username: Optional[str] = None + + @model_validator(mode='before') + def _initial_validation(cls, values): + return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) + + @field_validator('*', mode='before') + def _validate(cls, value, info): + field = cls.model_fields[info.field_name] + field_name = field.alias or info.field_name + if field_name in info.context['configured_fields']: + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() + + return validation.utils.make_immutable(value) + + @model_validator(mode='after') + def _final_validation(cls, model): + return validation.core.check_model(getattr(validators, 'check_instance', identity)(model)) diff --git a/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/shared.py b/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/shared.py new file mode 100644 index 0000000000000..8721d9e284e5f --- /dev/null +++ b/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/shared.py @@ -0,0 +1,45 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) + +# This file is autogenerated. +# To change this file you should edit assets/configuration/spec.yaml and then run the following commands: +# ddev -x validate config -s +# ddev -x validate models -s + +from __future__ import annotations + +from typing import Optional + +from pydantic import BaseModel, ConfigDict, field_validator, model_validator + +from datadog_checks.base.utils.functions import identity +from datadog_checks.base.utils.models import validation + +from . import validators + + +class SharedConfig(BaseModel): + model_config = ConfigDict( + validate_default=True, + arbitrary_types_allowed=True, + frozen=True, + ) + service: Optional[str] = None + + @model_validator(mode='before') + def _initial_validation(cls, values): + return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) + + @field_validator('*', mode='before') + def _validate(cls, value, info): + field = cls.model_fields[info.field_name] + field_name = field.alias or info.field_name + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + + return validation.utils.make_immutable(value) + + @model_validator(mode='after') + def _final_validation(cls, model): + return validation.core.check_model(getattr(validators, 'check_shared', identity)(model)) diff --git a/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/validators.py b/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/validators.py new file mode 100644 index 0000000000000..8495a481e5308 --- /dev/null +++ b/datadog_csi_driver/datadog_checks/datadog_csi_driver/config_models/validators.py @@ -0,0 +1,13 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) + +# Here you can include additional config validators or transformers +# +# def initialize_instance(values, **kwargs): +# if 'my_option' not in values and 'my_legacy_option' in values: +# values['my_option'] = values['my_legacy_option'] +# if values.get('my_number') > 10: +# raise ValueError('my_number max value is 10, got %s' % str(values.get('my_number'))) +# +# return values diff --git a/datadog_csi_driver/datadog_checks/datadog_csi_driver/data/auto_conf.yaml b/datadog_csi_driver/datadog_checks/datadog_csi_driver/data/auto_conf.yaml new file mode 100644 index 0000000000000..a67437b73f260 --- /dev/null +++ b/datadog_csi_driver/datadog_checks/datadog_csi_driver/data/auto_conf.yaml @@ -0,0 +1,555 @@ +## @param ad_identifiers - list of strings - required +## A list of container identifiers that are used by Autodiscovery to identify +## which container the check should be run against. For more information, see: +## https://docs.datadoghq.com/agent/guide/ad_identifiers/ +# +ad_identifiers: + - csi-driver + +## All options defined here are available to all instances. +# +init_config: + + ## @param proxy - mapping - optional + ## Set HTTP or HTTPS proxies for all instances. Use the `no_proxy` list + ## to specify hosts that must bypass proxies. + ## + ## The SOCKS protocol is also supported like so: + ## + ## socks5://user:pass@host:port + ## + ## Using the scheme `socks5` causes the DNS resolution to happen on the + ## client, rather than on the proxy server. This is in line with `curl`, + ## which uses the scheme to decide whether to do the DNS resolution on + ## the client or proxy. If you want to resolve the domains on the proxy + ## server, use `socks5h` as the scheme. + # + # proxy: + # http: http://: + # https: https://: + # no_proxy: + # - + # - + + ## @param skip_proxy - boolean - optional - default: false + ## If set to `true`, this makes the check bypass any proxy + ## settings enabled and attempt to reach services directly. + # + # skip_proxy: false + + ## @param timeout - number - optional - default: 10 + ## The timeout for connecting to services. + # + # timeout: 10 + + ## @param service - string - optional + ## Attach the tag `service:` to every metric, event, and service check emitted by this integration. + ## + ## Additionally, this sets the default `service` for every log source. + # + # service: + +## Every instance is scheduled independently of the others. +# +instances: + + ## @param prometheus_url - string - required + ## The URL where your application metrics are exposed by Prometheus. + # + - prometheus_url: http://%%host%%:5000/metrics + + ## @param prometheus_metrics_prefix - string - optional + ## Removes a given from exposed Prometheus metrics. + # + # prometheus_metrics_prefix: _ + + ## @param health_service_check - boolean - optional - default: true + ## Send a service check reporting about the health of the Prometheus endpoint. + ## The service check is named .prometheus.health + # + # health_service_check: true + + ## @param label_to_hostname - string - optional + ## Override the hostname with the value of one label. + # + # label_to_hostname: