From 792836622999f56d879af531998430c72ba9dd78 Mon Sep 17 00:00:00 2001 From: Ofek Lev Date: Thu, 20 Jul 2023 23:59:44 -0400 Subject: [PATCH] Fix types for generated config models --- LICENSE-3rdparty.csv | 1 - .../config_models/instance.py | 54 +++++----- .../active_directory/config_models/shared.py | 20 +--- .../activemq/config_models/instance.py | 24 ++--- .../activemq/config_models/shared.py | 25 ++--- .../activemq_xml/config_models/instance.py | 50 ++++----- .../activemq_xml/config_models/shared.py | 25 ++--- .../aerospike/config_models/instance.py | 81 +++++++------- .../aerospike/config_models/shared.py | 27 ++--- .../airflow/config_models/instance.py | 44 ++++---- .../airflow/config_models/shared.py | 25 ++--- .../amazon_msk/config_models/instance.py | 73 ++++++------- .../amazon_msk/config_models/shared.py | 25 ++--- .../ambari/config_models/instance.py | 46 ++++---- .../ambari/config_models/shared.py | 25 ++--- .../apache/config_models/instance.py | 44 ++++---- .../apache/config_models/shared.py | 25 ++--- .../arangodb/config_models/instance.py | 71 ++++++------- .../arangodb/config_models/shared.py | 25 ++--- .../argocd/config_models/instance.py | 71 ++++++------- .../argocd/config_models/shared.py | 25 ++--- .../aspdotnet/config_models/instance.py | 54 +++++----- .../aspdotnet/config_models/shared.py | 20 +--- .../avi_vantage/config_models/instance.py | 73 ++++++------- .../avi_vantage/config_models/shared.py | 25 ++--- .../azure_iot_edge/config_models/instance.py | 65 ++++++------ .../azure_iot_edge/config_models/shared.py | 25 ++--- .../boundary/config_models/instance.py | 71 ++++++------- .../boundary/config_models/shared.py | 25 ++--- .../btrfs/config_models/instance.py | 31 ++---- .../btrfs/config_models/shared.py | 13 +-- .../cacti/config_models/instance.py | 31 ++---- .../cacti/config_models/shared.py | 13 +-- .../calico/config_models/instance.py | 71 ++++++------- .../calico/config_models/shared.py | 25 ++--- .../cassandra/config_models/instance.py | 24 ++--- .../cassandra/config_models/shared.py | 25 ++--- .../config_models/instance.py | 31 ++---- .../config_models/shared.py | 20 +--- .../ceph/config_models/instance.py | 31 ++---- .../ceph/config_models/shared.py | 13 +-- .../cilium/config_models/instance.py | 84 +++++++-------- .../cilium/config_models/shared.py | 25 ++--- .../cisco_aci/config_models/instance.py | 48 ++++----- .../cisco_aci/config_models/shared.py | 25 ++--- .../config_models/instance.py | 44 ++++---- .../citrix_hypervisor/config_models/shared.py | 25 ++--- .../clickhouse/config_models/instance.py | 37 +++---- .../clickhouse/config_models/shared.py | 18 ++-- .../config_models/instance.py | 46 ++++---- .../cloud_foundry_api/config_models/shared.py | 25 ++--- cloudera/assets/configuration/spec.yaml | 44 ++++---- cloudera/datadog_checks/cloudera/config.py | 6 +- .../cloudera/config_models/instance.py | 48 ++++----- .../cloudera/config_models/shared.py | 13 +-- cloudera/tests/test_unit_autodiscover.py | 16 +-- .../cockroachdb/config_models/instance.py | 84 +++++++-------- .../cockroachdb/config_models/shared.py | 25 ++--- .../config_models/instance.py | 24 ++--- .../config_models/shared.py | 25 ++--- .../consul/config_models/instance.py | 48 ++++----- .../consul/config_models/shared.py | 25 ++--- .../coredns/config_models/instance.py | 84 +++++++-------- .../coredns/config_models/shared.py | 25 ++--- .../couch/config_models/instance.py | 48 ++++----- .../couch/config_models/shared.py | 25 ++--- .../couchbase/config_models/instance.py | 44 ++++---- .../couchbase/config_models/shared.py | 25 ++--- .../crio/config_models/instance.py | 65 ++++++------ .../crio/config_models/shared.py | 25 ++--- .../base/data/agent_requirements.in | 3 +- .../datadog_checks/base/utils/models/types.py | 16 --- .../base/utils/models/validation/utils.py | 11 +- datadog_checks_base/pyproject.toml | 1 - .../tests/models/config_models/instance.py | 30 ++---- .../tests/models/config_models/shared.py | 13 +-- .../tests/models/test_types.py | 16 +-- .../consumers/model/model_consumer.py | 4 +- .../consumers/model/model_file.py | 100 +++++++++++------- .../{check_name}/config_models/instance.py | 24 ++--- .../{check_name}/config_models/shared.py | 20 +--- .../{check_name}/config_models/instance.py | 24 ++--- .../{check_name}/config_models/shared.py | 25 ++--- .../consumers/model/test_all_required.py | 13 +-- .../consumers/model/test_array.py | 17 ++- .../consumers/model/test_both_models_basic.py | 26 ++--- .../consumers/model/test_common_validators.py | 57 +++------- .../consumers/model/test_defaults.py | 29 ++--- .../consumers/model/test_duplicate_hidden.py | 20 +--- .../consumers/model/test_enum.py | 40 ++----- .../consumers/model/test_merge_instances.py | 13 +-- .../consumers/model/test_nested_option.py | 19 ++-- .../model/test_object_arbitrary_values.py | 18 ++-- .../consumers/model/test_object_model.py | 18 ++-- .../model/test_object_typed_values.py | 18 ++-- .../consumers/model/test_only_shared.py | 13 +-- .../model/test_option_name_normalization.py | 13 +-- .../consumers/model/test_union_types.py | 17 ++- .../config_models/instance.py | 65 ++++++------ .../config_models/shared.py | 25 ++--- .../dcgm/config_models/instance.py | 71 ++++++------- .../dcgm/config_models/shared.py | 25 ++--- .../directory/config_models/instance.py | 31 ++---- .../directory/config_models/shared.py | 13 +-- .../disk/config_models/instance.py | 47 ++++---- .../disk/config_models/shared.py | 21 ++-- .../dns_check/config_models/instance.py | 29 ++--- .../dns_check/config_models/shared.py | 20 +--- .../dotnetclr/config_models/instance.py | 54 +++++----- .../dotnetclr/config_models/shared.py | 20 +--- .../druid/config_models/instance.py | 44 ++++---- .../druid/config_models/shared.py | 25 ++--- .../ecs_fargate/config_models/instance.py | 44 ++++---- .../ecs_fargate/config_models/shared.py | 25 ++--- .../eks_fargate/config_models/instance.py | 44 ++++---- .../eks_fargate/config_models/shared.py | 25 ++--- .../elastic/config_models/instance.py | 54 +++++----- .../elastic/config_models/shared.py | 25 ++--- .../envoy/config_models/instance.py | 75 +++++++------ .../envoy/config_models/shared.py | 25 ++--- .../etcd/config_models/instance.py | 65 ++++++------ .../etcd/config_models/shared.py | 25 ++--- .../exchange_server/config_models/instance.py | 54 +++++----- .../exchange_server/config_models/shared.py | 20 +--- .../external_dns/config_models/instance.py | 65 ++++++------ .../external_dns/config_models/shared.py | 25 ++--- .../fluentd/config_models/instance.py | 46 ++++---- .../fluentd/config_models/shared.py | 25 ++--- .../foundationdb/config_models/instance.py | 32 +++--- .../foundationdb/config_models/shared.py | 13 +-- .../gearmand/config_models/instance.py | 31 ++---- .../gearmand/config_models/shared.py | 13 +-- .../gitlab/config_models/instance.py | 84 +++++++-------- .../gitlab/config_models/shared.py | 25 ++--- .../gitlab_runner/config_models/instance.py | 65 ++++++------ .../gitlab_runner/config_models/shared.py | 27 ++--- .../glusterfs/config_models/instance.py | 29 ++--- .../glusterfs/config_models/shared.py | 20 +--- .../go_expvar/config_models/instance.py | 49 ++++----- .../go_expvar/config_models/shared.py | 25 ++--- .../gunicorn/config_models/instance.py | 29 ++--- .../gunicorn/config_models/shared.py | 20 +--- .../haproxy/config_models/instance.py | 88 +++++++-------- .../haproxy/config_models/shared.py | 25 ++--- .../harbor/config_models/instance.py | 44 ++++---- .../harbor/config_models/shared.py | 25 ++--- .../hazelcast/config_models/instance.py | 41 +++---- .../hazelcast/config_models/shared.py | 28 ++--- .../hdfs_datanode/config_models/instance.py | 44 ++++---- .../hdfs_datanode/config_models/shared.py | 25 ++--- .../hdfs_namenode/config_models/instance.py | 44 ++++---- .../hdfs_namenode/config_models/shared.py | 25 ++--- .../hive/config_models/instance.py | 24 ++--- .../hive/config_models/shared.py | 25 ++--- .../hivemq/config_models/instance.py | 24 ++--- .../hivemq/config_models/shared.py | 25 ++--- .../http_check/config_models/instance.py | 46 ++++---- .../http_check/config_models/shared.py | 25 ++--- .../hudi/config_models/instance.py | 24 ++--- .../hudi/config_models/shared.py | 25 ++--- .../hyperv/config_models/instance.py | 54 +++++----- .../hyperv/config_models/shared.py | 20 +--- .../ibm_ace/config_models/instance.py | 29 ++--- .../ibm_ace/config_models/shared.py | 13 +-- .../ibm_db2/config_models/instance.py | 37 +++---- .../ibm_db2/config_models/shared.py | 18 ++-- .../ibm_i/config_models/instance.py | 35 +++--- .../ibm_i/config_models/shared.py | 13 +-- .../ibm_mq/config_models/instance.py | 42 +++----- .../ibm_mq/config_models/shared.py | 20 +--- .../ibm_was/config_models/instance.py | 51 ++++----- .../ibm_was/config_models/shared.py | 25 ++--- .../ignite/config_models/instance.py | 24 ++--- .../ignite/config_models/shared.py | 25 ++--- .../iis/config_models/instance.py | 68 ++++++------ .../iis/config_models/shared.py | 20 +--- .../impala/config_models/instance.py | 71 ++++++------- .../impala/config_models/shared.py | 25 ++--- .../istio/config_models/instance.py | 84 +++++++-------- .../istio/config_models/shared.py | 25 ++--- .../jboss_wildfly/config_models/instance.py | 24 ++--- .../jboss_wildfly/config_models/shared.py | 27 ++--- .../kafka/config_models/instance.py | 24 ++--- .../kafka/config_models/shared.py | 25 ++--- .../kafka_consumer/config_models/instance.py | 37 +++---- .../kafka_consumer/config_models/shared.py | 20 +--- .../kong/config_models/instance.py | 71 ++++++------- .../kong/config_models/shared.py | 25 ++--- .../config_models/instance.py | 65 ++++++------ .../config_models/shared.py | 25 ++--- .../kube_dns/config_models/instance.py | 65 ++++++------ .../kube_dns/config_models/shared.py | 25 ++--- .../config_models/instance.py | 65 ++++++------ .../config_models/shared.py | 25 ++--- .../kube_proxy/config_models/instance.py | 65 ++++++------ .../kube_proxy/config_models/shared.py | 25 ++--- .../kube_scheduler/config_models/instance.py | 65 ++++++------ .../kube_scheduler/config_models/shared.py | 25 ++--- .../kubelet/config_models/instance.py | 69 ++++++------ .../kubelet/config_models/shared.py | 25 ++--- .../kyototycoon/config_models/instance.py | 44 ++++---- .../kyototycoon/config_models/shared.py | 25 ++--- .../lighttpd/config_models/instance.py | 44 ++++---- .../lighttpd/config_models/shared.py | 25 ++--- .../linkerd/config_models/instance.py | 84 +++++++-------- .../linkerd/config_models/shared.py | 25 ++--- .../config_models/instance.py | 29 ++--- .../linux_proc_extras/config_models/shared.py | 13 +-- .../mapr/config_models/instance.py | 31 ++---- .../mapr/config_models/shared.py | 13 +-- .../mapreduce/config_models/instance.py | 44 ++++---- .../mapreduce/config_models/shared.py | 30 ++---- .../marathon/config_models/instance.py | 46 ++++---- .../marathon/config_models/shared.py | 25 ++--- .../marklogic/config_models/instance.py | 46 ++++---- .../marklogic/config_models/shared.py | 25 ++--- .../mcache/config_models/instance.py | 32 +++--- .../mcache/config_models/shared.py | 13 +-- .../mesos_master/config_models/instance.py | 44 ++++---- .../mesos_master/config_models/shared.py | 25 ++--- .../mesos_slave/config_models/instance.py | 46 ++++---- .../mesos_slave/config_models/shared.py | 25 ++--- .../mongo/config_models/instance.py | 50 ++++----- .../mongo/config_models/shared.py | 13 +-- .../mysql/config_models/instance.py | 52 ++++----- .../mysql/config_models/shared.py | 18 ++-- .../nagios/config_models/instance.py | 29 ++--- .../nagios/config_models/shared.py | 13 +-- .../network/config_models/instance.py | 35 +++--- .../network/config_models/shared.py | 13 +-- .../nfsstat/config_models/instance.py | 29 ++--- .../nfsstat/config_models/shared.py | 20 +--- .../nginx/config_models/instance.py | 44 ++++---- .../nginx/config_models/shared.py | 25 ++--- .../config_models/instance.py | 65 ++++++------ .../config_models/shared.py | 25 ++--- .../openldap/config_models/instance.py | 32 +++--- .../openldap/config_models/shared.py | 13 +-- .../openmetrics/config_models/instance.py | 84 +++++++-------- .../openmetrics/config_models/shared.py | 25 ++--- .../config_models/instance.py | 54 +++++----- .../config_models/shared.py | 25 ++--- .../oracle/config_models/instance.py | 37 +++---- .../oracle/config_models/shared.py | 25 ++--- .../pdh_check/config_models/instance.py | 35 +++--- .../pdh_check/config_models/shared.py | 13 +-- .../pgbouncer/config_models/instance.py | 29 ++--- .../pgbouncer/config_models/shared.py | 13 +-- .../php_fpm/config_models/instance.py | 44 ++++---- .../php_fpm/config_models/shared.py | 25 ++--- .../postfix/config_models/instance.py | 31 ++---- .../postfix/config_models/shared.py | 20 +--- .../postgres/config_models/instance.py | 56 +++++----- .../postgres/config_models/shared.py | 13 +-- .../config_models/instance.py | 44 ++++---- .../powerdns_recursor/config_models/shared.py | 25 ++--- .../presto/config_models/instance.py | 24 ++--- .../presto/config_models/shared.py | 25 ++--- .../process/config_models/instance.py | 34 +++--- .../process/config_models/shared.py | 20 +--- .../prometheus/config_models/instance.py | 35 +++--- .../prometheus/config_models/shared.py | 13 +-- .../proxysql/config_models/instance.py | 31 ++---- .../proxysql/config_models/shared.py | 13 +-- .../pulsar/config_models/instance.py | 71 ++++++------- .../pulsar/config_models/shared.py | 25 ++--- .../rabbitmq/config_models/instance.py | 86 ++++++++------- .../rabbitmq/config_models/shared.py | 25 ++--- .../redisdb/config_models/instance.py | 31 ++---- .../redisdb/config_models/shared.py | 13 +-- .../rethinkdb/config_models/instance.py | 29 ++--- .../rethinkdb/config_models/shared.py | 13 +-- .../riak/config_models/instance.py | 44 ++++---- .../riak/config_models/shared.py | 25 ++--- .../riakcs/config_models/instance.py | 31 ++---- .../riakcs/config_models/shared.py | 13 +-- .../sap_hana/config_models/instance.py | 39 +++---- .../sap_hana/config_models/shared.py | 25 ++--- .../scylla/config_models/instance.py | 67 ++++++------ .../scylla/config_models/shared.py | 25 ++--- .../silk/config_models/instance.py | 44 ++++---- .../silk/config_models/shared.py | 25 ++--- .../singlestore/config_models/instance.py | 37 +++---- .../singlestore/config_models/shared.py | 18 ++-- .../snowflake/config_models/instance.py | 39 +++---- .../snowflake/config_models/shared.py | 18 ++-- .../solr/config_models/instance.py | 24 ++--- .../solr/config_models/shared.py | 25 ++--- .../sonarqube/config_models/instance.py | 50 ++++----- .../sonarqube/config_models/shared.py | 28 ++--- .../spark/config_models/instance.py | 46 ++++---- .../spark/config_models/shared.py | 25 ++--- .../sqlserver/config_models/instance.py | 49 +++++---- .../sqlserver/config_models/shared.py | 20 ++-- .../squid/config_models/instance.py | 44 ++++---- .../squid/config_models/shared.py | 25 ++--- .../ssh_check/config_models/instance.py | 29 ++--- .../ssh_check/config_models/shared.py | 13 +-- .../statsd/config_models/instance.py | 29 ++--- .../statsd/config_models/shared.py | 13 +-- .../strimzi/config_models/instance.py | 71 ++++++------- .../strimzi/config_models/shared.py | 25 ++--- .../supervisord/config_models/instance.py | 33 +++--- .../supervisord/config_models/shared.py | 13 +-- .../system_core/config_models/instance.py | 29 ++--- .../system_core/config_models/shared.py | 13 +-- .../system_swap/config_models/instance.py | 29 ++--- .../system_swap/config_models/shared.py | 13 +-- .../tcp_check/config_models/instance.py | 29 ++--- .../tcp_check/config_models/shared.py | 13 +-- .../teamcity/config_models/instance.py | 85 ++++++++------- .../teamcity/config_models/shared.py | 13 +-- .../temporal/config_models/instance.py | 71 ++++++------- .../temporal/config_models/shared.py | 25 ++--- .../teradata/config_models/instance.py | 44 ++++---- .../teradata/config_models/shared.py | 18 ++-- .../tls/config_models/instance.py | 31 ++---- .../tls/config_models/shared.py | 24 ++--- .../tomcat/config_models/instance.py | 24 ++--- .../tomcat/config_models/shared.py | 25 ++--- .../torchserve/config_models/instance.py | 75 +++++++------ .../torchserve/config_models/shared.py | 25 ++--- .../traffic_server/config_models/instance.py | 44 ++++---- .../traffic_server/config_models/shared.py | 13 +-- .../twemproxy/config_models/instance.py | 29 ++--- .../twemproxy/config_models/shared.py | 13 +-- .../twistlock/config_models/instance.py | 44 ++++---- .../twistlock/config_models/shared.py | 25 ++--- .../varnish/config_models/instance.py | 31 ++---- .../varnish/config_models/shared.py | 13 +-- .../vault/config_models/instance.py | 71 ++++++------- .../vault/config_models/shared.py | 25 ++--- .../vertica/config_models/instance.py | 41 +++---- .../vertica/config_models/shared.py | 18 ++-- .../voltdb/config_models/instance.py | 53 +++++----- .../voltdb/config_models/shared.py | 28 ++--- .../vsphere/config_models/instance.py | 72 ++++++------- .../vsphere/config_models/shared.py | 19 ++-- .../weaviate/config_models/instance.py | 71 ++++++------- .../weaviate/config_models/shared.py | 25 ++--- .../weblogic/config_models/instance.py | 24 ++--- .../weblogic/config_models/shared.py | 25 ++--- .../win32_event_log/config_models/instance.py | 72 +++++++------ .../win32_event_log/config_models/shared.py | 20 +--- .../config_models/instance.py | 50 ++++----- .../config_models/shared.py | 20 +--- .../windows_service/config_models/instance.py | 32 +++--- .../windows_service/config_models/shared.py | 13 +-- .../wmi_check/config_models/instance.py | 36 +++---- .../wmi_check/config_models/shared.py | 13 +-- .../yarn/config_models/instance.py | 75 +++++++------ .../yarn/config_models/shared.py | 50 +++++---- .../zk/config_models/instance.py | 29 ++--- zk/datadog_checks/zk/config_models/shared.py | 13 +-- 354 files changed, 4834 insertions(+), 7050 deletions(-) delete mode 100644 datadog_checks_base/datadog_checks/base/utils/models/types.py diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 5b179aba8d955c..64f52d5c0f1ed2 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -37,7 +37,6 @@ flup-py3,Vendor,BSD-3-Clause,"Copyright (c) 2005, 2006 Allan Saddi .foo and cloudera..bar, both with custom tags of `baz:1`. diff --git a/cloudera/datadog_checks/cloudera/config.py b/cloudera/datadog_checks/cloudera/config.py index ae0cb065f7b25b..d7d2bc0b3f9d52 100644 --- a/cloudera/datadog_checks/cloudera/config.py +++ b/cloudera/datadog_checks/cloudera/config.py @@ -1,6 +1,8 @@ # (C) Datadog, Inc. 2023-present # All rights reserved # Licensed under a 3-clause BSD style license (see LICENSE) +from types import MappingProxyType + # Discovery class requires 'include' to be a dict, so this function is needed to normalize the config def normalize_discover_config_include(log, config): @@ -8,12 +10,12 @@ def normalize_discover_config_include(log, config): log.debug("normalize_discover_config_include config: %s", config) include_list = config.get('include') if isinstance(config, dict) else config.include if config else [] log.debug("normalize_discover_config_include include_list: %s", include_list) - if not isinstance(include_list, list): + if not isinstance(include_list, (list, tuple)): raise TypeError('Setting `include` must be an array') for entry in include_list: if isinstance(entry, str): normalized_config[entry] = None - elif isinstance(entry, dict): + elif isinstance(entry, (dict, MappingProxyType)): for key, value in entry.items(): normalized_config[key] = value.copy() else: diff --git a/cloudera/datadog_checks/cloudera/config_models/instance.py b/cloudera/datadog_checks/cloudera/config_models/instance.py index 8e52c9a8c3499a..c78ef1b16f2b45 100644 --- a/cloudera/datadog_checks/cloudera/config_models/instance.py +++ b/cloudera/datadog_checks/cloudera/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,77 +22,64 @@ class Clusters(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = Field( - None, description='List of regular expressions with the patterns of clusters that will not be processed.\n' - ) - include: Optional[Sequence[Union[str, Mapping[str, Any]]]] = Field( - None, description='Mapping of regular expressions keys and cluster config values that will be processed.\n' - ) - interval: Optional[int] = Field( - None, description='Validity time of the last list of clusters obtained through the endpoint.\n' - ) + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[Union[str, MappingProxyType[str, Any]], ...]] = None + interval: Optional[int] = None limit: Optional[int] = Field(None, description='Maximum number of clusters to be processed.\n') class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) query: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) api_url: str cloudera_client: Optional[str] = None clusters: Optional[Clusters] = None - custom_queries: Optional[Sequence[CustomQuery]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None max_parallel_requests: Optional[int] = None metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value - - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/cloudera/datadog_checks/cloudera/config_models/shared.py b/cloudera/datadog_checks/cloudera/config_models/shared.py index 8739f906cef355..fe3d78579617ca 100644 --- a/cloudera/datadog_checks/cloudera/config_models/shared.py +++ b/cloudera/datadog_checks/cloudera/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -32,17 +33,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/cloudera/tests/test_unit_autodiscover.py b/cloudera/tests/test_unit_autodiscover.py index 2482b7e6b7f235..2c23a0b737d964 100644 --- a/cloudera/tests/test_unit_autodiscover.py +++ b/cloudera/tests/test_unit_autodiscover.py @@ -22,11 +22,11 @@ 'instance, read_clusters, expected_exception, expected_can_connects, expected_cluster_healths, expected_metrics', [ ( - {'api_url': 'http://localhost:8080/api/v48/', 'clusters': {'include': {'^cluster.*'}}}, + {'api_url': 'http://localhost:8080/api/v48/', 'clusters': {'include': 9000}}, [], pytest.raises( Exception, - match=re.escape('clusters -> include\n Input should be an instance of Sequence'), + match=re.escape('clusters -> include\n Input should be a valid tuple'), ), [ { @@ -40,11 +40,11 @@ [{'count': 0}], ), ( - {'api_url': 'http://localhost:8080/api/v48/', 'tags': ['new_tag'], 'clusters': {'include': {'^cluster.*'}}}, + {'api_url': 'http://localhost:8080/api/v48/', 'tags': ['new_tag'], 'clusters': {'include': 9000}}, [], pytest.raises( Exception, - match=re.escape('clusters -> include\n Input should be an instance of Sequence'), + match=re.escape('clusters -> include\n Input should be a valid tuple'), ), [ { @@ -65,8 +65,8 @@ match=re.escape( 'clusters -> include -> 1 -> str\n' ' Input should be a valid string\n' - 'clusters -> include -> 1 -> dict[str,any]\n' - ' Input should be a valid dictionary' + 'clusters -> include -> 1 -> is-instance[mappingproxy]\n' + ' Input should be an instance of mappingproxy' ), ), [ @@ -88,8 +88,8 @@ match=re.escape( 'clusters -> include -> 1 -> str\n' ' Input should be a valid string\n' - 'clusters -> include -> 1 -> dict[str,any]\n' - ' Input should be a valid dictionary' + 'clusters -> include -> 1 -> is-instance[mappingproxy]\n' + ' Input should be an instance of mappingproxy' ), ), [ diff --git a/cockroachdb/datadog_checks/cockroachdb/config_models/instance.py b/cockroachdb/datadog_checks/cockroachdb/config_models/instance.py index e57304ed42cee0..b09b6ca50f22a9 100644 --- a/cockroachdb/datadog_checks/cockroachdb/config_models/instance.py +++ b/cockroachdb/datadog_checks/cockroachdb/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,22 +41,25 @@ class ExtraMetric(BaseModel): class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -61,14 +67,16 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -78,24 +86,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -115,21 +126,21 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = 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_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -139,10 +150,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -153,10 +164,10 @@ class InstanceConfig(BaseModel): prometheus_metrics_prefix: Optional[str] = None prometheus_url: Optional[str] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None send_distribution_buckets: Optional[bool] = None send_distribution_counts_as_monotonic: Optional[bool] = None @@ -165,20 +176,20 @@ class InstanceConfig(BaseModel): send_monotonic_counter: Optional[bool] = None send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_latest_spec: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None @@ -189,25 +200,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/cockroachdb/datadog_checks/cockroachdb/config_models/shared.py b/cockroachdb/datadog_checks/cockroachdb/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/cockroachdb/datadog_checks/cockroachdb/config_models/shared.py +++ b/cockroachdb/datadog_checks/cockroachdb/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/confluent_platform/datadog_checks/confluent_platform/config_models/instance.py b/confluent_platform/datadog_checks/confluent_platform/config_models/instance.py index 631a321dda3bb7..a07c63edd14368 100644 --- a/confluent_platform/datadog_checks/confluent_platform/config_models/instance.py +++ b/confluent_platform/datadog_checks/confluent_platform/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,6 +22,7 @@ class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_jvm_metrics: Optional[bool] = None @@ -42,7 +43,7 @@ class InstanceConfig(BaseModel): rmi_connection_timeout: Optional[float] = None rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tools_jar_path: Optional[str] = None trust_store_password: Optional[str] = None trust_store_path: Optional[str] = None @@ -53,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/confluent_platform/datadog_checks/confluent_platform/config_models/shared.py b/confluent_platform/datadog_checks/confluent_platform/config_models/shared.py index d4711fb6c2c0b7..375b5161bacefd 100644 --- a/confluent_platform/datadog_checks/confluent_platform/config_models/shared.py +++ b/confluent_platform/datadog_checks/confluent_platform/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,10 +23,11 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: Optional[bool] = None - conf: Optional[Sequence[Mapping[str, Any]]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None is_jmx: bool new_gc_metrics: Optional[bool] = None service: Optional[str] = None @@ -36,25 +38,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/consul/datadog_checks/consul/config_models/instance.py b/consul/datadog_checks/consul/config_models/instance.py index 075af1db48b8e8..462c80f45c87df 100644 --- a/consul/datadog_checks/consul/config_models/instance.py +++ b/consul/datadog_checks/consul/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) acl_token: Optional[str] = None @@ -61,8 +66,8 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None disable_legacy_service_tag: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -84,18 +89,18 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None self_leader_check: Optional[bool] = None service: Optional[str] = None - services_exclude: Optional[Sequence[str]] = None - services_include: Optional[Sequence[str]] = None + services_exclude: Optional[tuple[str, ...]] = None + services_include: Optional[tuple[str, ...]] = None single_node_install: Optional[bool] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None threads_count: Optional[float] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None url: str @@ -108,25 +113,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/consul/datadog_checks/consul/config_models/shared.py b/consul/datadog_checks/consul/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/consul/datadog_checks/consul/config_models/shared.py +++ b/consul/datadog_checks/consul/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/coredns/datadog_checks/coredns/config_models/instance.py b/coredns/datadog_checks/coredns/config_models/instance.py index e57304ed42cee0..b09b6ca50f22a9 100644 --- a/coredns/datadog_checks/coredns/config_models/instance.py +++ b/coredns/datadog_checks/coredns/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,22 +41,25 @@ class ExtraMetric(BaseModel): class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -61,14 +67,16 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -78,24 +86,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -115,21 +126,21 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = 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_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -139,10 +150,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -153,10 +164,10 @@ class InstanceConfig(BaseModel): prometheus_metrics_prefix: Optional[str] = None prometheus_url: Optional[str] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None send_distribution_buckets: Optional[bool] = None send_distribution_counts_as_monotonic: Optional[bool] = None @@ -165,20 +176,20 @@ class InstanceConfig(BaseModel): send_monotonic_counter: Optional[bool] = None send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_latest_spec: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None @@ -189,25 +200,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/coredns/datadog_checks/coredns/config_models/shared.py b/coredns/datadog_checks/coredns/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/coredns/datadog_checks/coredns/config_models/shared.py +++ b/coredns/datadog_checks/coredns/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/couch/datadog_checks/couch/config_models/instance.py b/couch/datadog_checks/couch/config_models/instance.py index ee8d8a969a1739..e2be3d63fb80a1 100644 --- a/couch/datadog_checks/couch/config_models/instance.py +++ b/couch/datadog_checks/couch/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -56,12 +61,12 @@ class InstanceConfig(BaseModel): aws_region: Optional[str] = None aws_service: Optional[str] = None connect_timeout: Optional[float] = None - db_exclude: Optional[Sequence[str]] = None - db_include: Optional[Sequence[str]] = None + db_exclude: Optional[tuple[str, ...]] = None + db_include: Optional[tuple[str, ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -84,13 +89,13 @@ class InstanceConfig(BaseModel): server: str service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -101,25 +106,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/couch/datadog_checks/couch/config_models/shared.py b/couch/datadog_checks/couch/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/couch/datadog_checks/couch/config_models/shared.py +++ b/couch/datadog_checks/couch/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/couchbase/datadog_checks/couchbase/config_models/instance.py b/couchbase/datadog_checks/couchbase/config_models/instance.py index 48c0c5c580c4e3..eb3d841543d5fa 100644 --- a/couchbase/datadog_checks/couchbase/config_models/instance.py +++ b/couchbase/datadog_checks/couchbase/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None index_stats_url: Optional[str] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None @@ -82,13 +87,13 @@ class InstanceConfig(BaseModel): service: Optional[str] = None skip_proxy: Optional[bool] = None sync_gateway_url: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -99,25 +104,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/couchbase/datadog_checks/couchbase/config_models/shared.py b/couchbase/datadog_checks/couchbase/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/couchbase/datadog_checks/couchbase/config_models/shared.py +++ b/couchbase/datadog_checks/couchbase/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/crio/datadog_checks/crio/config_models/instance.py b/crio/datadog_checks/crio/config_models/instance.py index 5ded4c1b97033b..fa5952896f32c6 100644 --- a/crio/datadog_checks/crio/config_models/instance.py +++ b/crio/datadog_checks/crio/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +22,34 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -52,24 +57,27 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -84,14 +92,14 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + exclude_labels: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = None - ignore_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -101,10 +109,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, str]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, str]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -123,16 +131,16 @@ class InstanceConfig(BaseModel): send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None username: Optional[str] = None @@ -142,25 +150,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/crio/datadog_checks/crio/config_models/shared.py b/crio/datadog_checks/crio/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/crio/datadog_checks/crio/config_models/shared.py +++ b/crio/datadog_checks/crio/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_base/datadog_checks/base/data/agent_requirements.in b/datadog_checks_base/datadog_checks/base/data/agent_requirements.in index 026c532007a3ec..7ed935a31b4c8a 100644 --- a/datadog_checks_base/datadog_checks/base/data/agent_requirements.in +++ b/datadog_checks_base/datadog_checks/base/data/agent_requirements.in @@ -27,7 +27,6 @@ enum34==1.1.10; python_version < '3.0' foundationdb==6.3.24; python_version > '3.0' futures==3.4.0; python_version < '3.0' gearman==2.0.2; sys_platform != 'win32' and python_version < '3.0' -immutables==0.19; python_version > '3.0' importlib-metadata==2.1.3; python_version < '3.8' in-toto==1.0.1; python_version > '3.0' ipaddress==1.0.23; python_version < '3.0' @@ -59,7 +58,7 @@ psutil==5.9.0 psycopg2-binary==2.8.6; sys_platform != 'darwin' or platform_machine != 'arm64' pyasn1==0.4.6 pycryptodomex==3.10.1 -pydantic==1.10.8; python_version > '3.0' +pydantic==2.0; python_version > '3.0' pyjwt==1.7.1; python_version < '3.0' pyjwt==2.7.0; python_version > '3.0' pymongo[srv]==4.3.3; python_version >= '3.8' diff --git a/datadog_checks_base/datadog_checks/base/utils/models/types.py b/datadog_checks_base/datadog_checks/base/utils/models/types.py deleted file mode 100644 index 2e183d205c4abd..00000000000000 --- a/datadog_checks_base/datadog_checks/base/utils/models/types.py +++ /dev/null @@ -1,16 +0,0 @@ -# (C) Datadog, Inc. 2021-present -# All rights reserved -# Licensed under a 3-clause BSD style license (see LICENSE) -from collections.abc import Mapping, Sequence - -from immutables import Map - - -def make_immutable_check_config(obj): - if isinstance(obj, Sequence) and not isinstance(obj, str): - return tuple(make_immutable_check_config(item) for item in obj) - elif isinstance(obj, Mapping): - # There are no ordering guarantees, see https://github.com/MagicStack/immutables/issues/57 - return Map((k, make_immutable_check_config(v)) for k, v in obj.items()) - - return obj diff --git a/datadog_checks_base/datadog_checks/base/utils/models/validation/utils.py b/datadog_checks_base/datadog_checks/base/utils/models/validation/utils.py index 6690b172ede4c8..d5b5c11fe1aae5 100644 --- a/datadog_checks_base/datadog_checks/base/utils/models/validation/utils.py +++ b/datadog_checks_base/datadog_checks/base/utils/models/validation/utils.py @@ -1,11 +1,16 @@ # (C) Datadog, Inc. 2021-present # All rights reserved # Licensed under a 3-clause BSD style license (see LICENSE) -from ..types import make_immutable_check_config +from types import MappingProxyType -def make_immutable(value): - return make_immutable_check_config(value) +def make_immutable(obj): + if isinstance(obj, list): + return tuple(make_immutable(item) for item in obj) + elif isinstance(obj, dict): + return MappingProxyType({k: make_immutable(v) for k, v in obj.items()}) + + return obj def handle_deprecations(config_section, deprecations, fields, context): diff --git a/datadog_checks_base/pyproject.toml b/datadog_checks_base/pyproject.toml index 14b21fd082f19a..a01e0f7adeebf1 100644 --- a/datadog_checks_base/pyproject.toml +++ b/datadog_checks_base/pyproject.toml @@ -47,7 +47,6 @@ deps = [ "ddtrace==0.32.2; sys_platform == 'win32' and python_version < '3.0'", "ddtrace==0.53.2; (sys_platform != 'win32' and (sys_platform != 'darwin' or platform_machine != 'arm64' and python_version > '3.0')) or python_version > '3.0'", "enum34==1.1.10; python_version < '3.0'", - "immutables==0.19; python_version > '3.0'", "importlib-metadata==2.1.3; python_version < '3.8'", "ipaddress==1.0.23; python_version < '3.0'", "jellyfish==1.0.0; python_version > '3.0'", diff --git a/datadog_checks_base/tests/models/config_models/instance.py b/datadog_checks_base/tests/models/config_models/instance.py index d879e003da783c..213d9f6937f0e8 100644 --- a/datadog_checks_base/tests/models/config_models/instance.py +++ b/datadog_checks_base/tests/models/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,22 +22,24 @@ class Obj(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - bar: Optional[Sequence[str]] = None + bar: Optional[tuple[str, ...]] = None foo: bool class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - array: Optional[Sequence[str]] = None + array: Optional[tuple[str, ...]] = None deprecated: Optional[str] = None flag: Optional[bool] = None hyphenated_name: Optional[str] = Field(None, alias='hyphenated-name') - mapping: Optional[Mapping[str, Any]] = None + mapping: Optional[MappingProxyType[str, Any]] = None obj: Optional[Obj] = None pass_: Optional[str] = Field(None, alias='pass') pid: Optional[int] = None @@ -54,25 +57,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_base/tests/models/config_models/shared.py b/datadog_checks_base/tests/models/config_models/shared.py index 6c63a9244322bb..f05b14a4d96e9e 100644 --- a/datadog_checks_base/tests/models/config_models/shared.py +++ b/datadog_checks_base/tests/models/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) deprecated: Optional[str] = None @@ -37,17 +38,13 @@ def _handle_deprecations(cls, values, info): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_base/tests/models/test_types.py b/datadog_checks_base/tests/models/test_types.py index e783d30916ce4a..c4ccc0f07b7454 100644 --- a/datadog_checks_base/tests/models/test_types.py +++ b/datadog_checks_base/tests/models/test_types.py @@ -6,13 +6,13 @@ pytestmark = [requires_py3] -def test_make_immutable_check_config(): +def test_make_immutable(): # TODO: move imports up top when we drop Python 2 - from immutables import Map + from types import MappingProxyType - from datadog_checks.base.utils.models.types import make_immutable_check_config + from datadog_checks.base.utils.models.validation.utils import make_immutable - obj = make_immutable_check_config( + obj = make_immutable( { 'string': 'foo', 'integer': 9000, @@ -23,7 +23,7 @@ def test_make_immutable_check_config(): } ) - assert isinstance(obj, Map) + assert isinstance(obj, MappingProxyType) assert len(obj) == 6 assert isinstance(obj['string'], str) assert obj['string'] == 'foo' @@ -35,10 +35,10 @@ def test_make_immutable_check_config(): assert obj['boolean'] is True assert isinstance(obj['array'], tuple) assert len(obj['array']) == 2 - assert isinstance(obj['array'][0], Map) + assert isinstance(obj['array'][0], MappingProxyType) assert obj['array'][0]['key'] == 'foo' - assert isinstance(obj['array'][1], Map) + assert isinstance(obj['array'][1], MappingProxyType) assert obj['array'][1]['key'] == 'bar' - assert isinstance(obj['mapping'], Map) + assert isinstance(obj['mapping'], MappingProxyType) assert len(obj['mapping']) == 1 assert obj['mapping']['foo'] == 'bar' diff --git a/datadog_checks_dev/datadog_checks/dev/tooling/configuration/consumers/model/model_consumer.py b/datadog_checks_dev/datadog_checks/dev/tooling/configuration/consumers/model/model_consumer.py index 3b9948dada87b5..77863dab97b239 100644 --- a/datadog_checks_dev/datadog_checks/dev/tooling/configuration/consumers/model/model_consumer.py +++ b/datadog_checks_dev/datadog_checks/dev/tooling/configuration/consumers/model/model_consumer.py @@ -110,10 +110,8 @@ def _process_section(self, section) -> (List[Tuple[str, str]], dict, ModelInfo): dump_resolve_reference_action=model_types.dump_resolve_reference_action, enum_field_as_literal=LiteralType.All, encoding='utf-8', - use_generic_container_types=True, enable_faux_immutability=True, - # TODO: uncomment when the Agent upgrades Python to 3.9 - # use_standard_collections=True, + use_standard_collections=True, strip_default_none=True, # https://github.com/koxudaxi/datamodel-code-generator/pull/173 field_constraints=True, diff --git a/datadog_checks_dev/datadog_checks/dev/tooling/configuration/consumers/model/model_file.py b/datadog_checks_dev/datadog_checks/dev/tooling/configuration/consumers/model/model_file.py index 2c010611fd99b9..f4302b3284fc8b 100644 --- a/datadog_checks_dev/datadog_checks/dev/tooling/configuration/consumers/model/model_file.py +++ b/datadog_checks_dev/datadog_checks/dev/tooling/configuration/consumers/model/model_file.py @@ -24,6 +24,7 @@ def build_model_file( options_with_defaults = len(model_info.defaults_file_lines) > 0 model_file_lines = parsed_document.splitlines() _add_imports(model_file_lines, options_with_defaults, len(model_info.deprecation_data)) + _fix_types(model_file_lines) if model_id in model_info.deprecation_data: model_file_lines += _define_deprecation_functions(model_id, section_name) @@ -35,8 +36,14 @@ def build_model_file( if line.startswith(' model_config = ConfigDict('): config_lines.append(i) - final_config_line = config_lines[-1] - model_file_lines.insert(final_config_line + 1, ' validate_default=True,') + extra_config_lines = [' arbitrary_types_allowed=True,'] + for i, line_number in enumerate(config_lines): + index = line_number + (len(extra_config_lines) * i) + 1 + for line in extra_config_lines: + model_file_lines.insert(index, line) + + if i == len(config_lines) - 1: + model_file_lines.insert(index, ' validate_default=True,') model_file_lines.append('') model_file_contents = '\n'.join(model_file_lines) @@ -47,10 +54,16 @@ def build_model_file( def _add_imports(model_file_lines, need_defaults, need_deprecations): import_lines = [] + mapping_found = False + typing_location = -1 for i, line in enumerate(model_file_lines): if line.startswith('from '): import_lines.append(i) + if line.startswith('from typing '): + typing_location = i + elif 'dict[' in line: + mapping_found = True # pydantic imports final_import_line = import_lines[-1] @@ -60,14 +73,22 @@ def _add_imports(model_file_lines, need_defaults, need_deprecations): model_file_lines[index] += ', field_validator, model_validator' break + if mapping_found: + if typing_location == -1: + insertion_index = import_lines[0] + 1 + model_file_lines.insert(insertion_index, 'from types import MappingProxyType') + model_file_lines.insert(insertion_index, '') + final_import_line += 2 + else: + model_file_lines.insert(typing_location, 'from types import MappingProxyType') + final_import_line += 1 + local_imports = ['validators'] if need_defaults: local_imports.append('defaults') if need_deprecations: local_imports.append('deprecations') - local_imports_part = ', '.join(sorted(local_imports)) - local_import_start_location = final_import_line + 1 for line in reversed( ( @@ -75,12 +96,36 @@ def _add_imports(model_file_lines, need_defaults, need_deprecations): 'from datadog_checks.base.utils.functions import identity', 'from datadog_checks.base.utils.models import validation', '', - f'from . import {local_imports_part}', + f'from . import {", ".join(sorted(local_imports))}', ) ): model_file_lines.insert(local_import_start_location, line) +def _fix_types(model_file_lines): + for i, line in enumerate(model_file_lines): + line = model_file_lines[i] = line.replace('dict[', 'MappingProxyType[') + if 'list[' not in line: + continue + + buffer = bytearray() + containers = [] + + for char in line: + if char == '[': + if buffer[-4:] == b'list': + containers.append(True) + buffer[-4:] = b'tuple' + else: + containers.append(False) + elif char == ']' and containers.pop(): + buffer.extend(b', ...') + + buffer.append(ord(char)) + + model_file_lines[i] = buffer.decode('utf-8') + + def _define_deprecation_functions(model_id, section_name): model_file_lines = [''] model_file_lines.append(" @model_validator(mode='before')") @@ -103,46 +148,29 @@ def _define_validator_functions(model_id, validator_data, need_defaults): f"getattr(validators, 'initialize_{model_id}', identity)(values))" ) - if need_defaults: - model_file_lines.append('') - model_file_lines.append(" @field_validator('*', mode='before')") - model_file_lines.append(' def _ensure_defaults(cls, value, info):') - model_file_lines.append(' field = cls.model_fields[info.field_name]') - model_file_lines.append(' field_name = field.alias or info.field_name') - model_file_lines.append(" if field_name in info.context['configured_fields']:") - model_file_lines.append(' return value') - model_file_lines.append('') - model_file_lines.append(f" return getattr(defaults, f'{model_id}_{{info.field_name}}', lambda: value)()") - model_file_lines.append('') - model_file_lines.append(" @field_validator('*')") - model_file_lines.append(' def _run_validations(cls, value, info):') + model_file_lines.append(" @field_validator('*', mode='before')") + model_file_lines.append(' def _validate(cls, value, info):') model_file_lines.append(' field = cls.model_fields[info.field_name]') model_file_lines.append(' field_name = field.alias or info.field_name') - model_file_lines.append(" if field_name not in info.context['configured_fields']:") - model_file_lines.append(' return value') - model_file_lines.append('') + model_file_lines.append(" if field_name in info.context['configured_fields']:") model_file_lines.append( - f" return getattr(validators, f'{model_id}_{{info.field_name}}', identity)(value, field=field)" + f" value = getattr(validators, f'{model_id}_{{info.field_name}}', identity)(value, field=field)" ) - for option_name, import_paths in validator_data: + if need_defaults: + model_file_lines.append(' else:') + model_file_lines.append( + f" value = getattr(defaults, f'{model_id}_{{info.field_name}}', lambda: value)()" + ) + + for option_name, import_paths in sorted(validator_data): + model_file_lines.append('') + model_file_lines.append(f' if info.field_name == {option_name!r}:') for import_path in import_paths: - validator_name = import_path.replace('.', '_') - - model_file_lines.append('') - model_file_lines.append(f' @field_validator({option_name!r})') - model_file_lines.append(f' def _run_{option_name}_{validator_name}(cls, value, info):') - model_file_lines.append(' field = cls.model_fields[info.field_name]') - model_file_lines.append(' field_name = field.alias or info.field_name') - model_file_lines.append(" if field_name not in info.context['configured_fields']:") - model_file_lines.append(' return value') - model_file_lines.append('') - model_file_lines.append(f' return validation.{import_path}(value, field=field)') + model_file_lines.append(f' value = validation.{import_path}(value, field=field)') model_file_lines.append('') - model_file_lines.append(" @field_validator('*', mode='after')") - model_file_lines.append(' def _make_immutable(cls, value):') model_file_lines.append(' return validation.utils.make_immutable(value)') model_file_lines.append('') diff --git a/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/check/{check_name}/datadog_checks/{check_name}/config_models/instance.py b/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/check/{check_name}/datadog_checks/{check_name}/config_models/instance.py index cf2c08158a52fe..c1f54484fe1a79 100644 --- a/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/check/{check_name}/datadog_checks/{check_name}/config_models/instance.py +++ b/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/check/{check_name}/datadog_checks/{check_name}/config_models/instance.py @@ -4,7 +4,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -17,37 +17,27 @@ class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) empty_default_hostname: Optional[bool] = None min_collection_interval: Optional[float] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{{info.field_name}}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{{info.field_name}}', lambda: value)() - return getattr(defaults, f'instance_{{info.field_name}}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{{info.field_name}}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/check/{check_name}/datadog_checks/{check_name}/config_models/shared.py b/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/check/{check_name}/datadog_checks/{check_name}/config_models/shared.py index 9ff64c128faaef..dd76a1c12fa518 100644 --- a/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/check/{check_name}/datadog_checks/{check_name}/config_models/shared.py +++ b/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/check/{check_name}/datadog_checks/{check_name}/config_models/shared.py @@ -17,6 +17,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -26,25 +27,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{{info.field_name}}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{{info.field_name}}', lambda: value)() - return getattr(defaults, f'shared_{{info.field_name}}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{{info.field_name}}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/jmx/{check_name}/datadog_checks/{check_name}/config_models/instance.py b/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/jmx/{check_name}/datadog_checks/{check_name}/config_models/instance.py index 48711372c14ac5..a5273ebaae04f5 100644 --- a/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/jmx/{check_name}/datadog_checks/{check_name}/config_models/instance.py +++ b/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/jmx/{check_name}/datadog_checks/{check_name}/config_models/instance.py @@ -4,7 +4,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -17,6 +17,7 @@ class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_jvm_metrics: Optional[bool] = None @@ -36,7 +37,7 @@ class InstanceConfig(BaseModel): rmi_connection_timeout: Optional[float] = None rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tools_jar_path: Optional[str] = None trust_store_password: Optional[str] = None trust_store_path: Optional[str] = None @@ -47,25 +48,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{{info.field_name}}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{{info.field_name}}', lambda: value)() - return getattr(defaults, f'instance_{{info.field_name}}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{{info.field_name}}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/jmx/{check_name}/datadog_checks/{check_name}/config_models/shared.py b/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/jmx/{check_name}/datadog_checks/{check_name}/config_models/shared.py index 3b34891a38ca7e..9adc113c3cf24f 100644 --- a/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/jmx/{check_name}/datadog_checks/{check_name}/config_models/shared.py +++ b/datadog_checks_dev/datadog_checks/dev/tooling/templates/integration/jmx/{check_name}/datadog_checks/{check_name}/config_models/shared.py @@ -4,7 +4,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -17,10 +18,11 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: bool - conf: Optional[Sequence[Mapping[str, Any]]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None is_jmx: bool new_gc_metrics: Optional[bool] = None service: Optional[str] = None @@ -31,25 +33,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{{info.field_name}}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{{info.field_name}}', lambda: value)() - return getattr(defaults, f'shared_{{info.field_name}}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{{info.field_name}}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_all_required.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_all_required.py index d33c17c579d73e..f88887f76e8049 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_all_required.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_all_required.py @@ -67,6 +67,7 @@ def config(self) -> InstanceConfig: class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) foo: str @@ -75,17 +76,13 @@ class InstanceConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_array.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_array.py index 2b9087df0d2f2c..a73d1d3a916ed1 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_array.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_array.py @@ -62,7 +62,7 @@ def config(self) -> InstanceConfig: """ from __future__ import annotations - from typing import Optional, Sequence + from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -75,26 +75,23 @@ def config(self) -> InstanceConfig: class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) foo: str - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None @model_validator(mode='before') def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_both_models_basic.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_both_models_basic.py index b7482f3e637c82..e7e726bfa8883b 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_both_models_basic.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_both_models_basic.py @@ -80,6 +80,7 @@ def shared_config(self) -> SharedConfig: class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) foo: Optional[str] = None @@ -88,17 +89,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') @@ -126,6 +123,7 @@ def _final_validation(cls, model): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) foo: Optional[str] = None @@ -134,17 +132,13 @@ class InstanceConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + if field_name in info.context['configured_fields']: + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_common_validators.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_common_validators.py index 8a6f8831336bef..1cf5d426a9a1d0 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_common_validators.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_common_validators.py @@ -68,7 +68,7 @@ def config(self) -> InstanceConfig: """ from __future__ import annotations - from typing import Optional, Sequence + from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -81,62 +81,31 @@ def config(self) -> InstanceConfig: class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) foo: str - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None @model_validator(mode='before') def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + if info.field_name == 'foo': + value = validation.pkg.subpkg2.validate2(value, field=field) + value = validation.pkg.subpkg2.validate1(value, field=field) - @field_validator('foo') - def _run_foo_pkg_subpkg2_validate2(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return validation.pkg.subpkg2.validate2(value, field=field) - - @field_validator('foo') - def _run_foo_pkg_subpkg2_validate1(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return validation.pkg.subpkg2.validate1(value, field=field) - - @field_validator('tags') - def _run_tags_pkg_subpkg1_validate2(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return validation.pkg.subpkg1.validate2(value, field=field) - - @field_validator('tags') - def _run_tags_pkg_subpkg1_validate1(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return validation.pkg.subpkg1.validate1(value, field=field) + if info.field_name == 'tags': + value = validation.pkg.subpkg1.validate2(value, field=field) + value = validation.pkg.subpkg1.validate1(value, field=field) - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_defaults.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_defaults.py index c48c676ea2a77d..92d4fb649698a9 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_defaults.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_defaults.py @@ -119,7 +119,8 @@ def instance_long_default_formatted(): """ from __future__ import annotations - from typing import Any, Mapping, Optional, Sequence + from types import MappingProxyType + from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -132,39 +133,29 @@ def instance_long_default_formatted(): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) default_precedence: Optional[str] = None example: Optional[str] = None - example_ignored_array: Optional[Sequence[str]] = None - example_ignored_object: Optional[Mapping[str, Any]] = None + example_ignored_array: Optional[tuple[str, ...]] = None + example_ignored_object: Optional[MappingProxyType[str, Any]] = None foo: str - long_default_formatted: Optional[Sequence[Sequence[str]]] = None + long_default_formatted: Optional[tuple[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_duplicate_hidden.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_duplicate_hidden.py index ffdc50f10cf53b..97c42549260251 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_duplicate_hidden.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_duplicate_hidden.py @@ -88,6 +88,7 @@ def instance_password(): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) foo: str @@ -98,25 +99,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_enum.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_enum.py index 614e165f063246..0110625a0919fb 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_enum.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_enum.py @@ -83,6 +83,7 @@ def instance_my_str(): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) my_str: Optional[Literal['a', 'b', 'c']] = None @@ -92,25 +93,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') @@ -198,6 +188,7 @@ def instance_my_int(): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) my_int: Optional[Literal[1, 2, 3]] = None @@ -207,25 +198,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value - - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_merge_instances.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_merge_instances.py index eb4b23dfe65f5f..d3bc9d03e5e910 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_merge_instances.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_merge_instances.py @@ -87,6 +87,7 @@ def config(self) -> InstanceConfig: class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) bar: str @@ -96,17 +97,13 @@ class InstanceConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_nested_option.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_nested_option.py index 25693e22ba180b..2d17af93d71db5 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_nested_option.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_nested_option.py @@ -76,7 +76,7 @@ def config(self) -> InstanceConfig: """ from __future__ import annotations - from typing import Optional, Sequence + from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -88,14 +88,16 @@ def config(self) -> InstanceConfig: class Setting2(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) bar: str - baz: Optional[Sequence[str]] = None + baz: Optional[tuple[str, ...]] = None class Settings(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) setting1: Optional[str] = None @@ -105,6 +107,7 @@ class Settings(BaseModel): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) foo: str @@ -114,17 +117,13 @@ class InstanceConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_object_arbitrary_values.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_object_arbitrary_values.py index 1b762b7dbfa0e2..db4ae518758e57 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_object_arbitrary_values.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_object_arbitrary_values.py @@ -61,7 +61,8 @@ def config(self) -> InstanceConfig: """ from __future__ import annotations - from typing import Any, Mapping, Optional + from types import MappingProxyType + from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -74,26 +75,23 @@ def config(self) -> InstanceConfig: class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) foo: str - obj: Optional[Mapping[str, Any]] = None + obj: Optional[MappingProxyType[str, Any]] = None @model_validator(mode='before') def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_object_model.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_object_model.py index fe025ed3f19e51..344b2dd2e6e9c3 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_object_model.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_object_model.py @@ -69,7 +69,7 @@ def config(self) -> InstanceConfig: """ from __future__ import annotations - from typing import Optional, Sequence + from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -81,15 +81,17 @@ def config(self) -> InstanceConfig: class Obj(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) bar: str - baz: Optional[Sequence[str]] = None + baz: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) foo: str @@ -99,17 +101,13 @@ class InstanceConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_object_typed_values.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_object_typed_values.py index e307459352992f..44721cac8521e9 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_object_typed_values.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_object_typed_values.py @@ -64,7 +64,8 @@ def config(self) -> InstanceConfig: """ from __future__ import annotations - from typing import Mapping, Optional, Sequence + from types import MappingProxyType + from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -77,26 +78,23 @@ def config(self) -> InstanceConfig: class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) foo: str - obj: Optional[Mapping[str, Sequence[float]]] = None + obj: Optional[MappingProxyType[str, tuple[float, ...]]] = None @model_validator(mode='before') def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_only_shared.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_only_shared.py index 3ba607df3d9c0e..feb43d3930505f 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_only_shared.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_only_shared.py @@ -68,6 +68,7 @@ def shared_config(self) -> SharedConfig: class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) foo: Optional[str] = None @@ -76,17 +77,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_option_name_normalization.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_option_name_normalization.py index 5b2869035c79bc..42621a78fc52d3 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_option_name_normalization.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_option_name_normalization.py @@ -73,6 +73,7 @@ def config(self) -> InstanceConfig: class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) bar_baz: Optional[str] = Field(None, alias='bar-baz') @@ -82,17 +83,13 @@ class InstanceConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_union_types.py b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_union_types.py index 6c075f31408d83..cf4a294c8e573c 100644 --- a/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_union_types.py +++ b/datadog_checks_dev/tests/tooling/configuration/consumers/model/test_union_types.py @@ -64,7 +64,7 @@ def config(self) -> InstanceConfig: """ from __future__ import annotations - from typing import Optional, Sequence, Union + from typing import Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -77,26 +77,23 @@ def config(self) -> InstanceConfig: class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) foo: str - obj: Optional[Union[str, Sequence[str]]] = None + obj: Optional[Union[str, tuple[str, ...]]] = None @model_validator(mode='before') def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_cluster_agent/datadog_checks/datadog_cluster_agent/config_models/instance.py b/datadog_cluster_agent/datadog_checks/datadog_cluster_agent/config_models/instance.py index 5ded4c1b97033b..fa5952896f32c6 100644 --- a/datadog_cluster_agent/datadog_checks/datadog_cluster_agent/config_models/instance.py +++ b/datadog_cluster_agent/datadog_checks/datadog_cluster_agent/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +22,34 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -52,24 +57,27 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -84,14 +92,14 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + exclude_labels: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = None - ignore_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -101,10 +109,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, str]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, str]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -123,16 +131,16 @@ class InstanceConfig(BaseModel): send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None username: Optional[str] = None @@ -142,25 +150,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/datadog_cluster_agent/datadog_checks/datadog_cluster_agent/config_models/shared.py b/datadog_cluster_agent/datadog_checks/datadog_cluster_agent/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/datadog_cluster_agent/datadog_checks/datadog_cluster_agent/config_models/shared.py +++ b/datadog_cluster_agent/datadog_checks/datadog_cluster_agent/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/dcgm/datadog_checks/dcgm/config_models/instance.py b/dcgm/datadog_checks/dcgm/config_models/instance.py index 364568d359afaa..b78811820d5e5e 100644 --- a/dcgm/datadog_checks/dcgm/config_models/instance.py +++ b/dcgm/datadog_checks/dcgm/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,14 +41,16 @@ class ExtraMetric(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -55,24 +60,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -89,18 +97,18 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = 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[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -110,7 +118,7 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -119,23 +127,23 @@ class InstanceConfig(BaseModel): password: Optional[str] = None persist_connections: Optional[bool] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[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 @@ -148,25 +156,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/dcgm/datadog_checks/dcgm/config_models/shared.py b/dcgm/datadog_checks/dcgm/config_models/shared.py index 59c534d071001b..458a7003d92bbe 100644 --- a/dcgm/datadog_checks/dcgm/config_models/shared.py +++ b/dcgm/datadog_checks/dcgm/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/directory/datadog_checks/directory/config_models/instance.py b/directory/datadog_checks/directory/config_models/instance.py index 071490eb1e54b3..d17f342746747d 100644 --- a/directory/datadog_checks/directory/config_models/instance.py +++ b/directory/datadog_checks/directory/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) countonly: Optional[bool] = None @@ -38,7 +40,7 @@ class InstanceConfig(BaseModel): dirtagname: Optional[str] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_dirs: Optional[Sequence[str]] = None + exclude_dirs: Optional[tuple[str, ...]] = None filegauges: Optional[bool] = None filetagname: Optional[str] = None follow_symlinks: Optional[bool] = None @@ -51,32 +53,21 @@ class InstanceConfig(BaseModel): service: Optional[str] = None stat_follow_symlinks: Optional[bool] = None submit_histograms: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/directory/datadog_checks/directory/config_models/shared.py b/directory/datadog_checks/directory/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/directory/datadog_checks/directory/config_models/shared.py +++ b/directory/datadog_checks/directory/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/disk/datadog_checks/disk/config_models/instance.py b/disk/datadog_checks/disk/config_models/instance.py index d2190c71451005..6dcf32df56ff74 100644 --- a/disk/datadog_checks/disk/config_models/instance.py +++ b/disk/datadog_checks/disk/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,6 +22,7 @@ class CreateMount(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) host: Optional[str] = None @@ -33,38 +35,40 @@ class CreateMount(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) all_partitions: Optional[bool] = None blkid_cache_file: Optional[str] = None - create_mounts: Optional[Sequence[CreateMount]] = None - device_exclude: Optional[Sequence[str]] = None - device_include: Optional[Sequence[str]] = None - device_tag_re: Optional[Mapping[str, Any]] = None + create_mounts: Optional[tuple[CreateMount, ...]] = None + device_exclude: Optional[tuple[str, ...]] = None + device_include: Optional[tuple[str, ...]] = None + device_tag_re: Optional[MappingProxyType[str, Any]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - file_system_exclude: Optional[Sequence[str]] = None - file_system_include: Optional[Sequence[str]] = None + file_system_exclude: Optional[tuple[str, ...]] = None + file_system_include: Optional[tuple[str, ...]] = None include_all_devices: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None min_disk_size: Optional[float] = None - mount_point_exclude: Optional[Sequence[str]] = None - mount_point_include: Optional[Sequence[str]] = None + mount_point_exclude: Optional[tuple[str, ...]] = None + mount_point_include: Optional[tuple[str, ...]] = None service: Optional[str] = None service_check_rw: Optional[bool] = None tag_by_filesystem: Optional[bool] = None tag_by_label: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[int] = None use_lsblk: Optional[bool] = None use_mount: Optional[bool] = None @@ -74,25 +78,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/disk/datadog_checks/disk/config_models/shared.py b/disk/datadog_checks/disk/config_models/shared.py index f26e88b208fdf0..e0be3bc1aacdd8 100644 --- a/disk/datadog_checks/disk/config_models/shared.py +++ b/disk/datadog_checks/disk/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,28 +22,25 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - device_global_exclude: Optional[Sequence[str]] = None - file_system_global_exclude: Optional[Sequence[str]] = None - mount_point_global_exclude: Optional[Sequence[str]] = None + device_global_exclude: Optional[tuple[str, ...]] = None + file_system_global_exclude: Optional[tuple[str, ...]] = None + mount_point_global_exclude: Optional[tuple[str, ...]] = None 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('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/dns_check/datadog_checks/dns_check/config_models/instance.py b/dns_check/datadog_checks/dns_check/config_models/instance.py index 28bf117ac104f2..6756ff353d4ec8 100644 --- a/dns_check/datadog_checks/dns_check/config_models/instance.py +++ b/dns_check/datadog_checks/dns_check/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -43,7 +45,7 @@ class InstanceConfig(BaseModel): record_type: Optional[str] = None resolves_as: Optional[str] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[int] = None @model_validator(mode='before') @@ -51,25 +53,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/dns_check/datadog_checks/dns_check/config_models/shared.py b/dns_check/datadog_checks/dns_check/config_models/shared.py index 76b4effac7b5f1..599daf7e856c9f 100644 --- a/dns_check/datadog_checks/dns_check/config_models/shared.py +++ b/dns_check/datadog_checks/dns_check/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) default_timeout: Optional[int] = None @@ -32,25 +33,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/dotnetclr/datadog_checks/dotnetclr/config_models/instance.py b/dotnetclr/datadog_checks/dotnetclr/config_models/instance.py index 5edb57d89d89e6..283484a91d7b1a 100644 --- a/dotnetclr/datadog_checks/dotnetclr/config_models/instance.py +++ b/dotnetclr/datadog_checks/dotnetclr/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from typing_extensions import Literal @@ -22,6 +23,7 @@ class Counter(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -34,6 +36,7 @@ class Counter(BaseModel): class InstanceCounts(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) monitored: Optional[str] = None @@ -43,11 +46,12 @@ class InstanceCounts(BaseModel): class ExtraMetrics(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - counters: Sequence[Mapping[str, Union[str, Counter]]] - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + counters: tuple[MappingProxyType[str, Union[str, Counter]], ...] + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None instance_counts: Optional[InstanceCounts] = None name: str tag_name: Optional[str] = None @@ -56,19 +60,21 @@ class ExtraMetrics(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metrics(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - counters: Sequence[Mapping[str, Union[str, Counter]]] - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + counters: tuple[MappingProxyType[str, Union[str, Counter]], ...] + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None instance_counts: Optional[InstanceCounts] = None name: str tag_name: Optional[str] = None @@ -78,24 +84,25 @@ class Metrics(BaseModel): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - additional_metrics: Optional[Sequence[Sequence[str]]] = None - counter_data_types: Optional[Sequence[str]] = None + additional_metrics: Optional[tuple[tuple[str, ...], ...]] = None + counter_data_types: Optional[tuple[str, ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - extra_metrics: Optional[Mapping[str, ExtraMetrics]] = None + extra_metrics: Optional[MappingProxyType[str, ExtraMetrics]] = None host: Optional[str] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Mapping[str, Metrics]] = None + metrics: Optional[MappingProxyType[str, Metrics]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') password: Optional[str] = None server: Optional[str] = None server_tag: Optional[str] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None use_legacy_check_version: Optional[bool] = None username: Optional[str] = None @@ -104,25 +111,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/dotnetclr/datadog_checks/dotnetclr/config_models/shared.py b/dotnetclr/datadog_checks/dotnetclr/config_models/shared.py index aa58639466c054..94b02c19dbbb69 100644 --- a/dotnetclr/datadog_checks/dotnetclr/config_models/shared.py +++ b/dotnetclr/datadog_checks/dotnetclr/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -32,25 +33,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/druid/datadog_checks/druid/config_models/instance.py b/druid/datadog_checks/druid/config_models/instance.py index b0c9dd6112c5c4..e31c99d217e86f 100644 --- a/druid/datadog_checks/druid/config_models/instance.py +++ b/druid/datadog_checks/druid/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -78,13 +83,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None url: str @@ -96,25 +101,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/druid/datadog_checks/druid/config_models/shared.py b/druid/datadog_checks/druid/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/druid/datadog_checks/druid/config_models/shared.py +++ b/druid/datadog_checks/druid/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ecs_fargate/datadog_checks/ecs_fargate/config_models/instance.py b/ecs_fargate/datadog_checks/ecs_fargate/config_models/instance.py index f15b81079e3188..cbb367875f2a0f 100644 --- a/ecs_fargate/datadog_checks/ecs_fargate/config_models/instance.py +++ b/ecs_fargate/datadog_checks/ecs_fargate/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -78,13 +83,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -95,25 +100,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ecs_fargate/datadog_checks/ecs_fargate/config_models/shared.py b/ecs_fargate/datadog_checks/ecs_fargate/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/ecs_fargate/datadog_checks/ecs_fargate/config_models/shared.py +++ b/ecs_fargate/datadog_checks/ecs_fargate/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/eks_fargate/datadog_checks/eks_fargate/config_models/instance.py b/eks_fargate/datadog_checks/eks_fargate/config_models/instance.py index f15b81079e3188..cbb367875f2a0f 100644 --- a/eks_fargate/datadog_checks/eks_fargate/config_models/instance.py +++ b/eks_fargate/datadog_checks/eks_fargate/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -78,13 +83,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -95,25 +100,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/eks_fargate/datadog_checks/eks_fargate/config_models/shared.py b/eks_fargate/datadog_checks/eks_fargate/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/eks_fargate/datadog_checks/eks_fargate/config_models/shared.py +++ b/eks_fargate/datadog_checks/eks_fargate/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/elastic/datadog_checks/elastic/config_models/instance.py b/elastic/datadog_checks/elastic/config_models/instance.py index 4ac11de5cb8175..b311db088fd42d 100644 --- a/elastic/datadog_checks/elastic/config_models/instance.py +++ b/elastic/datadog_checks/elastic/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class Column(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) name: Optional[str] = None @@ -38,35 +41,39 @@ class Column(BaseModel): class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - columns: Optional[Sequence[Column]] = None + columns: Optional[tuple[Column, ...]] = None data_path: Optional[str] = None endpoint: Optional[str] = None - payload: Optional[Mapping[str, Any]] = None - tags: Optional[Sequence[str]] = None + payload: Optional[MappingProxyType[str, Any]] = None + tags: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) admin_forwarder: Optional[bool] = None @@ -79,14 +86,14 @@ class InstanceConfig(BaseModel): cat_allocation_stats: Optional[bool] = None cluster_stats: Optional[bool] = None connect_timeout: Optional[float] = None - custom_queries: Optional[Sequence[CustomQuery]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None detailed_index_stats: Optional[bool] = None disable_generic_tags: Optional[bool] = None disable_legacy_cluster_tag: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None gc_collectors_as_rate: Optional[bool] = None - headers: Optional[Mapping[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None index_stats: Optional[bool] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None @@ -112,13 +119,13 @@ class InstanceConfig(BaseModel): skip_proxy: Optional[bool] = None slm_stats: Optional[bool] = None submit_events: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None url: str @@ -130,25 +137,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/elastic/datadog_checks/elastic/config_models/shared.py b/elastic/datadog_checks/elastic/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/elastic/datadog_checks/elastic/config_models/shared.py +++ b/elastic/datadog_checks/elastic/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/envoy/datadog_checks/envoy/config_models/instance.py b/envoy/datadog_checks/envoy/config_models/instance.py index bb67674f09245e..0561bef4d081d9 100644 --- a/envoy/datadog_checks/envoy/config_models/instance.py +++ b/envoy/datadog_checks/envoy/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,14 +41,16 @@ class ExtraMetric(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -55,24 +60,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -92,20 +100,20 @@ class InstanceConfig(BaseModel): disable_legacy_cluster_tag: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - excluded_metrics: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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 + excluded_metrics: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + extra_metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, ExtraMetric]]], ...]] = 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[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = None - included_metrics: Optional[Sequence[str]] = None + ignore_tags: Optional[tuple[str, ...]] = None + include_labels: Optional[tuple[str, ...]] = None + included_metrics: Optional[tuple[str, ...]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -115,7 +123,7 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -125,24 +133,24 @@ class InstanceConfig(BaseModel): password: Optional[str] = None persist_connections: Optional[bool] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None stats_url: Optional[str] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[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 @@ -155,25 +163,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/envoy/datadog_checks/envoy/config_models/shared.py b/envoy/datadog_checks/envoy/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/envoy/datadog_checks/envoy/config_models/shared.py +++ b/envoy/datadog_checks/envoy/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/etcd/datadog_checks/etcd/config_models/instance.py b/etcd/datadog_checks/etcd/config_models/instance.py index 4e5ce72d0b2aa6..d607fa9927b26f 100644 --- a/etcd/datadog_checks/etcd/config_models/instance.py +++ b/etcd/datadog_checks/etcd/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +22,34 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -52,24 +57,27 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -84,14 +92,14 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + exclude_labels: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = None - ignore_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -101,11 +109,11 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None leader_tag: Optional[bool] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, str]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, str]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -124,16 +132,16 @@ class InstanceConfig(BaseModel): send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_legacy_auth_encoding: Optional[bool] = None use_preview: Optional[bool] = None use_process_start_time: Optional[bool] = None @@ -144,25 +152,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/etcd/datadog_checks/etcd/config_models/shared.py b/etcd/datadog_checks/etcd/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/etcd/datadog_checks/etcd/config_models/shared.py +++ b/etcd/datadog_checks/etcd/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/exchange_server/datadog_checks/exchange_server/config_models/instance.py b/exchange_server/datadog_checks/exchange_server/config_models/instance.py index 5edb57d89d89e6..283484a91d7b1a 100644 --- a/exchange_server/datadog_checks/exchange_server/config_models/instance.py +++ b/exchange_server/datadog_checks/exchange_server/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from typing_extensions import Literal @@ -22,6 +23,7 @@ class Counter(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -34,6 +36,7 @@ class Counter(BaseModel): class InstanceCounts(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) monitored: Optional[str] = None @@ -43,11 +46,12 @@ class InstanceCounts(BaseModel): class ExtraMetrics(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - counters: Sequence[Mapping[str, Union[str, Counter]]] - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + counters: tuple[MappingProxyType[str, Union[str, Counter]], ...] + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None instance_counts: Optional[InstanceCounts] = None name: str tag_name: Optional[str] = None @@ -56,19 +60,21 @@ class ExtraMetrics(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metrics(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - counters: Sequence[Mapping[str, Union[str, Counter]]] - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + counters: tuple[MappingProxyType[str, Union[str, Counter]], ...] + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None instance_counts: Optional[InstanceCounts] = None name: str tag_name: Optional[str] = None @@ -78,24 +84,25 @@ class Metrics(BaseModel): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - additional_metrics: Optional[Sequence[Sequence[str]]] = None - counter_data_types: Optional[Sequence[str]] = None + additional_metrics: Optional[tuple[tuple[str, ...], ...]] = None + counter_data_types: Optional[tuple[str, ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - extra_metrics: Optional[Mapping[str, ExtraMetrics]] = None + extra_metrics: Optional[MappingProxyType[str, ExtraMetrics]] = None host: Optional[str] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Mapping[str, Metrics]] = None + metrics: Optional[MappingProxyType[str, Metrics]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') password: Optional[str] = None server: Optional[str] = None server_tag: Optional[str] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None use_legacy_check_version: Optional[bool] = None username: Optional[str] = None @@ -104,25 +111,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/exchange_server/datadog_checks/exchange_server/config_models/shared.py b/exchange_server/datadog_checks/exchange_server/config_models/shared.py index aa58639466c054..94b02c19dbbb69 100644 --- a/exchange_server/datadog_checks/exchange_server/config_models/shared.py +++ b/exchange_server/datadog_checks/exchange_server/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -32,25 +33,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/external_dns/datadog_checks/external_dns/config_models/instance.py b/external_dns/datadog_checks/external_dns/config_models/instance.py index 5ded4c1b97033b..fa5952896f32c6 100644 --- a/external_dns/datadog_checks/external_dns/config_models/instance.py +++ b/external_dns/datadog_checks/external_dns/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +22,34 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -52,24 +57,27 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -84,14 +92,14 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + exclude_labels: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = None - ignore_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -101,10 +109,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, str]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, str]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -123,16 +131,16 @@ class InstanceConfig(BaseModel): send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None username: Optional[str] = None @@ -142,25 +150,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/external_dns/datadog_checks/external_dns/config_models/shared.py b/external_dns/datadog_checks/external_dns/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/external_dns/datadog_checks/external_dns/config_models/shared.py +++ b/external_dns/datadog_checks/external_dns/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/fluentd/datadog_checks/fluentd/config_models/instance.py b/fluentd/datadog_checks/fluentd/config_models/instance.py index 4ab45d86111ffe..f28be920395ae3 100644 --- a/fluentd/datadog_checks/fluentd/config_models/instance.py +++ b/fluentd/datadog_checks/fluentd/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,9 +63,9 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None fluentd: Optional[str] = None - headers: Optional[Mapping[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -75,20 +80,20 @@ class InstanceConfig(BaseModel): ntlm_domain: Optional[str] = None password: Optional[str] = None persist_connections: Optional[bool] = None - plugin_ids: Optional[Sequence[str]] = None + plugin_ids: Optional[tuple[str, ...]] = None proxy: Optional[Proxy] = None read_timeout: Optional[float] = None request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None tag_by: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -99,25 +104,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/fluentd/datadog_checks/fluentd/config_models/shared.py b/fluentd/datadog_checks/fluentd/config_models/shared.py index abe63595382bac..2f8a16842164f9 100644 --- a/fluentd/datadog_checks/fluentd/config_models/shared.py +++ b/fluentd/datadog_checks/fluentd/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) fluentd: Optional[str] = None @@ -44,25 +46,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/foundationdb/datadog_checks/foundationdb/config_models/instance.py b/foundationdb/datadog_checks/foundationdb/config_models/instance.py index b9b9b6da6a5a4a..a24e8ba7fde807 100644 --- a/foundationdb/datadog_checks/foundationdb/config_models/instance.py +++ b/foundationdb/datadog_checks/foundationdb/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,25 +22,27 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) cluster_file: Optional[str] = None - custom_queries: Optional[Sequence[Mapping[str, Any]]] = None + custom_queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tls_ca_file: Optional[str] = None tls_certificate_file: Optional[str] = None tls_key_file: Optional[str] = None @@ -51,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/foundationdb/datadog_checks/foundationdb/config_models/shared.py b/foundationdb/datadog_checks/foundationdb/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/foundationdb/datadog_checks/foundationdb/config_models/shared.py +++ b/foundationdb/datadog_checks/foundationdb/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/gearmand/datadog_checks/gearmand/config_models/instance.py b/gearmand/datadog_checks/gearmand/config_models/instance.py index c9099a4117ffae..2890ae7548e955 100644 --- a/gearmand/datadog_checks/gearmand/config_models/instance.py +++ b/gearmand/datadog_checks/gearmand/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -39,33 +41,22 @@ class InstanceConfig(BaseModel): port: Optional[int] = None server: Optional[str] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None - tasks: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None + tasks: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/gearmand/datadog_checks/gearmand/config_models/shared.py b/gearmand/datadog_checks/gearmand/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/gearmand/datadog_checks/gearmand/config_models/shared.py +++ b/gearmand/datadog_checks/gearmand/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/gitlab/datadog_checks/gitlab/config_models/instance.py b/gitlab/datadog_checks/gitlab/config_models/instance.py index e5f617f9fcac81..76537f90decad5 100644 --- a/gitlab/datadog_checks/gitlab/config_models/instance.py +++ b/gitlab/datadog_checks/gitlab/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,22 +41,25 @@ class ExtraMetric(BaseModel): class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -61,14 +67,16 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -78,24 +86,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -116,23 +127,23 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = 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, ExtraMetric]]], ...]] = None gitaly_server_endpoint: Optional[str] = None gitlab_url: Optional[str] = None - headers: Optional[Mapping[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = 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_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -142,10 +153,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -157,10 +168,10 @@ class InstanceConfig(BaseModel): prometheus_metrics_prefix: Optional[str] = None prometheus_url: Optional[str] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None send_distribution_buckets: Optional[bool] = None send_distribution_counts_as_monotonic: Optional[bool] = None @@ -169,20 +180,20 @@ class InstanceConfig(BaseModel): send_monotonic_counter: Optional[bool] = None send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_latest_spec: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None @@ -193,25 +204,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/gitlab/datadog_checks/gitlab/config_models/shared.py b/gitlab/datadog_checks/gitlab/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/gitlab/datadog_checks/gitlab/config_models/shared.py +++ b/gitlab/datadog_checks/gitlab/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/gitlab_runner/datadog_checks/gitlab_runner/config_models/instance.py b/gitlab_runner/datadog_checks/gitlab_runner/config_models/instance.py index 241f30e5c5214d..09b386a2b776e6 100644 --- a/gitlab_runner/datadog_checks/gitlab_runner/config_models/instance.py +++ b/gitlab_runner/datadog_checks/gitlab_runner/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +22,34 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -52,24 +57,27 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -84,15 +92,15 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None + exclude_labels: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None gitlab_url: str - headers: Optional[Mapping[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = None - ignore_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -102,10 +110,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, str]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, str]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -125,16 +133,16 @@ class InstanceConfig(BaseModel): send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None username: Optional[str] = None @@ -144,25 +152,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/gitlab_runner/datadog_checks/gitlab_runner/config_models/shared.py b/gitlab_runner/datadog_checks/gitlab_runner/config_models/shared.py index 70855079e3ede8..507ffec96daf9f 100644 --- a/gitlab_runner/datadog_checks/gitlab_runner/config_models/shared.py +++ b/gitlab_runner/datadog_checks/gitlab_runner/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,19 +21,21 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - allowed_metrics: Sequence[str] + allowed_metrics: tuple[str, ...] proxy: Optional[Proxy] = None service: Optional[str] = None skip_proxy: Optional[bool] = None @@ -44,25 +46,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/glusterfs/datadog_checks/glusterfs/config_models/instance.py b/glusterfs/datadog_checks/glusterfs/config_models/instance.py index 0ac5b0739126ba..55f0d9db64df14 100644 --- a/glusterfs/datadog_checks/glusterfs/config_models/instance.py +++ b/glusterfs/datadog_checks/glusterfs/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -37,7 +39,7 @@ class InstanceConfig(BaseModel): metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None use_sudo: Optional[bool] = None @model_validator(mode='before') @@ -45,25 +47,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/glusterfs/datadog_checks/glusterfs/config_models/shared.py b/glusterfs/datadog_checks/glusterfs/config_models/shared.py index a802847d143fbc..73eab6388015c4 100644 --- a/glusterfs/datadog_checks/glusterfs/config_models/shared.py +++ b/glusterfs/datadog_checks/glusterfs/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) gstatus_path: Optional[str] = None @@ -32,25 +33,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/go_expvar/datadog_checks/go_expvar/config_models/instance.py b/go_expvar/datadog_checks/go_expvar/config_models/instance.py index aa877478dbc9e3..92666c6acae70d 100644 --- a/go_expvar/datadog_checks/go_expvar/config_models/instance.py +++ b/go_expvar/datadog_checks/go_expvar/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,42 +22,47 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) alias: Optional[str] = None path: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -69,8 +75,8 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None expvar_url: str - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -80,7 +86,7 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Metric]] = None + metrics: Optional[tuple[Metric, ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -91,13 +97,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -108,25 +114,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/go_expvar/datadog_checks/go_expvar/config_models/shared.py b/go_expvar/datadog_checks/go_expvar/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/go_expvar/datadog_checks/go_expvar/config_models/shared.py +++ b/go_expvar/datadog_checks/go_expvar/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/gunicorn/datadog_checks/gunicorn/config_models/instance.py b/gunicorn/datadog_checks/gunicorn/config_models/instance.py index 01d7e3ef549602..fecd32408b60d9 100644 --- a/gunicorn/datadog_checks/gunicorn/config_models/instance.py +++ b/gunicorn/datadog_checks/gunicorn/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -39,32 +41,21 @@ class InstanceConfig(BaseModel): min_collection_interval: Optional[float] = None proc_name: str service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/gunicorn/datadog_checks/gunicorn/config_models/shared.py b/gunicorn/datadog_checks/gunicorn/config_models/shared.py index 94a7316157dfcb..28ee7a5e78d94f 100644 --- a/gunicorn/datadog_checks/gunicorn/config_models/shared.py +++ b/gunicorn/datadog_checks/gunicorn/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) gunicorn: Optional[str] = None @@ -32,25 +33,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/haproxy/datadog_checks/haproxy/config_models/instance.py b/haproxy/datadog_checks/haproxy/config_models/instance.py index ea3a92f4cc67c2..63f0835b5bd173 100644 --- a/haproxy/datadog_checks/haproxy/config_models/instance.py +++ b/haproxy/datadog_checks/haproxy/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,22 +41,25 @@ class ExtraMetric(BaseModel): class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -61,14 +67,16 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -78,24 +86,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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, ) active_tag: Optional[bool] = None @@ -123,21 +134,21 @@ class InstanceConfig(BaseModel): empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None enable_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = 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_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -147,10 +158,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -161,10 +172,10 @@ class InstanceConfig(BaseModel): prometheus_metrics_prefix: Optional[str] = None prometheus_url: Optional[str] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None send_distribution_buckets: Optional[bool] = None send_distribution_counts_as_monotonic: Optional[bool] = None @@ -173,15 +184,15 @@ class InstanceConfig(BaseModel): send_monotonic_counter: Optional[bool] = None send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None - services_exclude: Optional[Sequence[str]] = None - services_include: Optional[Sequence[str]] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + services_exclude: Optional[tuple[str, ...]] = None + services_include: Optional[tuple[str, ...]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None startup_grace_seconds: Optional[float] = None status_check: Optional[bool] = None tag_by_endpoint: Optional[bool] = None tag_service_check_by_host: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tags_regex: Optional[str] = None telemetry: Optional[bool] = None timeout: Optional[float] = None @@ -189,10 +200,10 @@ class InstanceConfig(BaseModel): tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None url: Optional[str] = None use_latest_spec: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -206,25 +217,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/haproxy/datadog_checks/haproxy/config_models/shared.py b/haproxy/datadog_checks/haproxy/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/haproxy/datadog_checks/haproxy/config_models/shared.py +++ b/haproxy/datadog_checks/haproxy/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/harbor/datadog_checks/harbor/config_models/instance.py b/harbor/datadog_checks/harbor/config_models/instance.py index 1afa826fcdf022..a3c6ff7d6809f0 100644 --- a/harbor/datadog_checks/harbor/config_models/instance.py +++ b/harbor/datadog_checks/harbor/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -78,13 +83,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None url: str @@ -96,25 +101,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/harbor/datadog_checks/harbor/config_models/shared.py b/harbor/datadog_checks/harbor/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/harbor/datadog_checks/harbor/config_models/shared.py +++ b/harbor/datadog_checks/harbor/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hazelcast/datadog_checks/hazelcast/config_models/instance.py b/hazelcast/datadog_checks/hazelcast/config_models/instance.py index 6c38cc1e77b7f5..53458dd3868c87 100644 --- a/hazelcast/datadog_checks/hazelcast/config_models/instance.py +++ b/hazelcast/datadog_checks/hazelcast/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,24 +22,27 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -50,8 +54,8 @@ class InstanceConfig(BaseModel): collect_default_jvm_metrics: Optional[bool] = None connect_timeout: Optional[float] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None host: Optional[str] = None is_jmx: Optional[bool] = None java_bin_path: Optional[str] = None @@ -67,7 +71,7 @@ class InstanceConfig(BaseModel): key_store_password: Optional[str] = None key_store_path: Optional[str] = None log_requests: Optional[bool] = None - mc_cluster_states: Optional[Mapping[str, Any]] = None + mc_cluster_states: Optional[MappingProxyType[str, Any]] = None mc_health_check_endpoint: Optional[str] = None min_collection_interval: Optional[float] = None name: Optional[str] = None @@ -84,13 +88,13 @@ class InstanceConfig(BaseModel): rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None tools_jar_path: Optional[str] = None @@ -105,25 +109,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hazelcast/datadog_checks/hazelcast/config_models/shared.py b/hazelcast/datadog_checks/hazelcast/config_models/shared.py index 83534741d40197..1d08bdb6284cd9 100644 --- a/hazelcast/datadog_checks/hazelcast/config_models/shared.py +++ b/hazelcast/datadog_checks/hazelcast/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,20 +22,22 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: Optional[bool] = None - conf: Optional[Sequence[Mapping[str, Any]]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None is_jmx: Optional[bool] = None new_gc_metrics: Optional[bool] = None proxy: Optional[Proxy] = None @@ -48,25 +51,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hdfs_datanode/datadog_checks/hdfs_datanode/config_models/instance.py b/hdfs_datanode/datadog_checks/hdfs_datanode/config_models/instance.py index 977815744f1638..b01962928ea446 100644 --- a/hdfs_datanode/datadog_checks/hdfs_datanode/config_models/instance.py +++ b/hdfs_datanode/datadog_checks/hdfs_datanode/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,9 +63,9 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None hdfs_datanode_jmx_uri: str - headers: Optional[Mapping[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -79,13 +84,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -96,25 +101,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hdfs_datanode/datadog_checks/hdfs_datanode/config_models/shared.py b/hdfs_datanode/datadog_checks/hdfs_datanode/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/hdfs_datanode/datadog_checks/hdfs_datanode/config_models/shared.py +++ b/hdfs_datanode/datadog_checks/hdfs_datanode/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hdfs_namenode/datadog_checks/hdfs_namenode/config_models/instance.py b/hdfs_namenode/datadog_checks/hdfs_namenode/config_models/instance.py index 7a11a8ba7b92ef..ba663871d98b1f 100644 --- a/hdfs_namenode/datadog_checks/hdfs_namenode/config_models/instance.py +++ b/hdfs_namenode/datadog_checks/hdfs_namenode/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,9 +63,9 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None hdfs_namenode_jmx_uri: str - headers: Optional[Mapping[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -79,13 +84,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -96,25 +101,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hdfs_namenode/datadog_checks/hdfs_namenode/config_models/shared.py b/hdfs_namenode/datadog_checks/hdfs_namenode/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/hdfs_namenode/datadog_checks/hdfs_namenode/config_models/shared.py +++ b/hdfs_namenode/datadog_checks/hdfs_namenode/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hive/datadog_checks/hive/config_models/instance.py b/hive/datadog_checks/hive/config_models/instance.py index 631a321dda3bb7..a07c63edd14368 100644 --- a/hive/datadog_checks/hive/config_models/instance.py +++ b/hive/datadog_checks/hive/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,6 +22,7 @@ class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_jvm_metrics: Optional[bool] = None @@ -42,7 +43,7 @@ class InstanceConfig(BaseModel): rmi_connection_timeout: Optional[float] = None rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tools_jar_path: Optional[str] = None trust_store_password: Optional[str] = None trust_store_path: Optional[str] = None @@ -53,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hive/datadog_checks/hive/config_models/shared.py b/hive/datadog_checks/hive/config_models/shared.py index 0db55a6d064d5d..b8bb8146892a0f 100644 --- a/hive/datadog_checks/hive/config_models/shared.py +++ b/hive/datadog_checks/hive/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,10 +23,11 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: Optional[bool] = None - conf: Optional[Sequence[Mapping[str, Any]]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None is_jmx: bool new_gc_metrics: Optional[bool] = None service: Optional[str] = None @@ -36,25 +38,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hivemq/datadog_checks/hivemq/config_models/instance.py b/hivemq/datadog_checks/hivemq/config_models/instance.py index 631a321dda3bb7..a07c63edd14368 100644 --- a/hivemq/datadog_checks/hivemq/config_models/instance.py +++ b/hivemq/datadog_checks/hivemq/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,6 +22,7 @@ class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_jvm_metrics: Optional[bool] = None @@ -42,7 +43,7 @@ class InstanceConfig(BaseModel): rmi_connection_timeout: Optional[float] = None rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tools_jar_path: Optional[str] = None trust_store_password: Optional[str] = None trust_store_path: Optional[str] = None @@ -53,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hivemq/datadog_checks/hivemq/config_models/shared.py b/hivemq/datadog_checks/hivemq/config_models/shared.py index 0db55a6d064d5d..b8bb8146892a0f 100644 --- a/hivemq/datadog_checks/hivemq/config_models/shared.py +++ b/hivemq/datadog_checks/hivemq/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,10 +23,11 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: Optional[bool] = None - conf: Optional[Sequence[Mapping[str, Any]]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None is_jmx: bool new_gc_metrics: Optional[bool] = None service: Optional[str] = None @@ -36,25 +38,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/http_check/datadog_checks/http_check/config_models/instance.py b/http_check/datadog_checks/http_check/config_models/instance.py index d9d7ff6479833f..017f5d7d5762ba 100644 --- a/http_check/datadog_checks/http_check/config_models/instance.py +++ b/http_check/datadog_checks/http_check/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -59,13 +64,13 @@ class InstanceConfig(BaseModel): collect_response_time: Optional[bool] = None connect_timeout: Optional[float] = None content_match: Optional[str] = None - data: Optional[Union[Mapping[str, Any], str]] = None + data: Optional[Union[MappingProxyType[str, Any], str]] = None days_critical: Optional[int] = None days_warning: Optional[int] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None http_response_status_code: Optional[str] = None include_content: Optional[bool] = None include_default_headers: Optional[bool] = None @@ -94,14 +99,14 @@ class InstanceConfig(BaseModel): skip_proxy: Optional[bool] = None ssl_server_name: Optional[str] = None stream: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None tls_private_key_password: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_retrieve_non_validated_cert: Optional[bool] = None tls_use_host_header: Optional[bool] = None tls_validate_hostname: Optional[bool] = None @@ -115,25 +120,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/http_check/datadog_checks/http_check/config_models/shared.py b/http_check/datadog_checks/http_check/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/http_check/datadog_checks/http_check/config_models/shared.py +++ b/http_check/datadog_checks/http_check/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hudi/datadog_checks/hudi/config_models/instance.py b/hudi/datadog_checks/hudi/config_models/instance.py index 631a321dda3bb7..a07c63edd14368 100644 --- a/hudi/datadog_checks/hudi/config_models/instance.py +++ b/hudi/datadog_checks/hudi/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,6 +22,7 @@ class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_jvm_metrics: Optional[bool] = None @@ -42,7 +43,7 @@ class InstanceConfig(BaseModel): rmi_connection_timeout: Optional[float] = None rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tools_jar_path: Optional[str] = None trust_store_password: Optional[str] = None trust_store_path: Optional[str] = None @@ -53,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hudi/datadog_checks/hudi/config_models/shared.py b/hudi/datadog_checks/hudi/config_models/shared.py index 0db55a6d064d5d..b8bb8146892a0f 100644 --- a/hudi/datadog_checks/hudi/config_models/shared.py +++ b/hudi/datadog_checks/hudi/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,10 +23,11 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: Optional[bool] = None - conf: Optional[Sequence[Mapping[str, Any]]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None is_jmx: bool new_gc_metrics: Optional[bool] = None service: Optional[str] = None @@ -36,25 +38,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hyperv/datadog_checks/hyperv/config_models/instance.py b/hyperv/datadog_checks/hyperv/config_models/instance.py index 5edb57d89d89e6..283484a91d7b1a 100644 --- a/hyperv/datadog_checks/hyperv/config_models/instance.py +++ b/hyperv/datadog_checks/hyperv/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from typing_extensions import Literal @@ -22,6 +23,7 @@ class Counter(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -34,6 +36,7 @@ class Counter(BaseModel): class InstanceCounts(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) monitored: Optional[str] = None @@ -43,11 +46,12 @@ class InstanceCounts(BaseModel): class ExtraMetrics(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - counters: Sequence[Mapping[str, Union[str, Counter]]] - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + counters: tuple[MappingProxyType[str, Union[str, Counter]], ...] + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None instance_counts: Optional[InstanceCounts] = None name: str tag_name: Optional[str] = None @@ -56,19 +60,21 @@ class ExtraMetrics(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metrics(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - counters: Sequence[Mapping[str, Union[str, Counter]]] - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + counters: tuple[MappingProxyType[str, Union[str, Counter]], ...] + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None instance_counts: Optional[InstanceCounts] = None name: str tag_name: Optional[str] = None @@ -78,24 +84,25 @@ class Metrics(BaseModel): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - additional_metrics: Optional[Sequence[Sequence[str]]] = None - counter_data_types: Optional[Sequence[str]] = None + additional_metrics: Optional[tuple[tuple[str, ...], ...]] = None + counter_data_types: Optional[tuple[str, ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - extra_metrics: Optional[Mapping[str, ExtraMetrics]] = None + extra_metrics: Optional[MappingProxyType[str, ExtraMetrics]] = None host: Optional[str] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Mapping[str, Metrics]] = None + metrics: Optional[MappingProxyType[str, Metrics]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') password: Optional[str] = None server: Optional[str] = None server_tag: Optional[str] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None use_legacy_check_version: Optional[bool] = None username: Optional[str] = None @@ -104,25 +111,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/hyperv/datadog_checks/hyperv/config_models/shared.py b/hyperv/datadog_checks/hyperv/config_models/shared.py index aa58639466c054..94b02c19dbbb69 100644 --- a/hyperv/datadog_checks/hyperv/config_models/shared.py +++ b/hyperv/datadog_checks/hyperv/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -32,25 +33,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ibm_ace/datadog_checks/ibm_ace/config_models/instance.py b/ibm_ace/datadog_checks/ibm_ace/config_models/instance.py index 374c33c3127aca..cb531dd606ddc4 100644 --- a/ibm_ace/datadog_checks/ibm_ace/config_models/instance.py +++ b/ibm_ace/datadog_checks/ibm_ace/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from typing_extensions import Literal @@ -22,15 +22,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) channel: str = Field(..., min_length=1) @@ -48,7 +50,7 @@ class InstanceConfig(BaseModel): queue_manager: str = Field(..., min_length=1) resource_statistics: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tls_auth: Optional[bool] = None tls_certificate_label: Optional[str] = None tls_cipher_spec: Optional[str] = None @@ -59,25 +61,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ibm_ace/datadog_checks/ibm_ace/config_models/shared.py b/ibm_ace/datadog_checks/ibm_ace/config_models/shared.py index d7f4dd28de4784..1a8081d40b0c4a 100644 --- a/ibm_ace/datadog_checks/ibm_ace/config_models/shared.py +++ b/ibm_ace/datadog_checks/ibm_ace/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ibm_db2/datadog_checks/ibm_db2/config_models/instance.py b/ibm_db2/datadog_checks/ibm_db2/config_models/instance.py index 2fe2a731edf9a2..164dfba7b581dd 100644 --- a/ibm_db2/datadog_checks/ibm_db2/config_models/instance.py +++ b/ibm_db2/datadog_checks/ibm_db2/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator from typing_extensions import Literal @@ -22,28 +23,31 @@ class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - columns: Optional[Sequence[Mapping[str, Any]]] = None + columns: Optional[tuple[MappingProxyType[str, Any], ...]] = None metric_prefix: Optional[str] = None query: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - custom_queries: Optional[Sequence[CustomQuery]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None db: str disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None @@ -55,7 +59,7 @@ class InstanceConfig(BaseModel): port: Optional[int] = None security: Optional[Literal['none', 'ssl']] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tls_cert: Optional[str] = None use_global_custom_queries: Optional[str] = None username: str @@ -65,25 +69,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ibm_db2/datadog_checks/ibm_db2/config_models/shared.py b/ibm_db2/datadog_checks/ibm_db2/config_models/shared.py index 45d1293f12b20f..8a1218b18c7641 100644 --- a/ibm_db2/datadog_checks/ibm_db2/config_models/shared.py +++ b/ibm_db2/datadog_checks/ibm_db2/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,26 +23,23 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - global_custom_queries: Optional[Sequence[Mapping[str, Any]]] = None + global_custom_queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None 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('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ibm_i/datadog_checks/ibm_i/config_models/instance.py b/ibm_i/datadog_checks/ibm_i/config_models/instance.py index f246be0ce38d9a..ace8c92ab5f331 100644 --- a/ibm_i/datadog_checks/ibm_i/config_models/instance.py +++ b/ibm_i/datadog_checks/ibm_i/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,21 +21,24 @@ class MessageQueueInfo(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - selected_message_queues: Optional[Sequence[str]] = None + selected_message_queues: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Query(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) name: str @@ -44,6 +47,7 @@ class Query(BaseModel): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) connection_string: Optional[str] = None @@ -56,13 +60,13 @@ class InstanceConfig(BaseModel): metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None password: Optional[str] = None - queries: Optional[Sequence[Query]] = None + queries: Optional[tuple[Query, ...]] = None query_timeout: Optional[int] = Field(None, gt=0) service: Optional[str] = None severity_threshold: Optional[int] = Field(None, ge=0, le=99) system: Optional[str] = None system_mq_query_timeout: Optional[int] = Field(None, gt=0) - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None username: Optional[str] = None @model_validator(mode='before') @@ -70,25 +74,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ibm_i/datadog_checks/ibm_i/config_models/shared.py b/ibm_i/datadog_checks/ibm_i/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/ibm_i/datadog_checks/ibm_i/config_models/shared.py +++ b/ibm_i/datadog_checks/ibm_i/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ibm_mq/datadog_checks/ibm_mq/config_models/instance.py b/ibm_mq/datadog_checks/ibm_mq/config_models/instance.py index 7d867a411947d8..ac501692fb97b9 100644 --- a/ibm_mq/datadog_checks/ibm_mq/config_models/instance.py +++ b/ibm_mq/datadog_checks/ibm_mq/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,22 +22,24 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) auto_discover_channels: Optional[bool] = None auto_discover_queues: Optional[bool] = None channel: str = Field(..., min_length=1) - channel_status_mapping: Optional[Mapping[str, Any]] = None - channels: Optional[Sequence[str]] = None + channel_status_mapping: Optional[MappingProxyType[str, Any]] = None + channels: Optional[tuple[str, ...]] = None collect_reset_queue_metrics: Optional[bool] = None collect_statistics_metrics: Optional[bool] = None connection_name: Optional[str] = Field(None, min_length=1) @@ -53,16 +56,16 @@ class InstanceConfig(BaseModel): queue_manager: str = Field(..., min_length=1) queue_manager_process: Optional[str] = None queue_manager_timezone: Optional[str] = Field(None, min_length=1) - queue_patterns: Optional[Sequence[str]] = None - queue_regex: Optional[Sequence[str]] = None - queue_tag_re: Optional[Mapping[str, Any]] = None - queues: Optional[Sequence[str]] = None + queue_patterns: Optional[tuple[str, ...]] = None + queue_regex: Optional[tuple[str, ...]] = None + queue_tag_re: Optional[MappingProxyType[str, Any]] = None + queues: Optional[tuple[str, ...]] = None service: Optional[str] = None ssl_auth: Optional[bool] = None ssl_certificate_label: Optional[str] = None ssl_cipher_spec: Optional[str] = None ssl_key_repository_location: Optional[str] = Field(None, min_length=1) - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[int] = None try_basic_auth: Optional[bool] = None username: Optional[str] = Field(None, min_length=1) @@ -72,25 +75,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ibm_mq/datadog_checks/ibm_mq/config_models/shared.py b/ibm_mq/datadog_checks/ibm_mq/config_models/shared.py index 980a6f2d7be75c..6e27e8c4ef1fc5 100644 --- a/ibm_mq/datadog_checks/ibm_mq/config_models/shared.py +++ b/ibm_mq/datadog_checks/ibm_mq/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) queue_manager_process: Optional[str] = None @@ -33,25 +34,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ibm_was/datadog_checks/ibm_was/config_models/instance.py b/ibm_was/datadog_checks/ibm_was/config_models/instance.py index 484f6fb8b9aeca..84f9691debd105 100644 --- a/ibm_was/datadog_checks/ibm_was/config_models/instance.py +++ b/ibm_was/datadog_checks/ibm_was/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,41 +22,46 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) metric_prefix: Optional[str] = None stat: Optional[str] = None - tag_keys: Optional[Sequence[str]] = None + tag_keys: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -65,12 +71,12 @@ class InstanceConfig(BaseModel): aws_region: Optional[str] = None aws_service: Optional[str] = None connect_timeout: Optional[float] = None - custom_queries: Optional[Sequence[CustomQuery]] = None - custom_queries_units_gauge: Optional[Sequence[str]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None + custom_queries_units_gauge: Optional[tuple[str, ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -91,13 +97,13 @@ class InstanceConfig(BaseModel): service: Optional[str] = None servlet_url: str skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_global_custom_queries: Optional[str] = None @@ -109,25 +115,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ibm_was/datadog_checks/ibm_was/config_models/shared.py b/ibm_was/datadog_checks/ibm_was/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/ibm_was/datadog_checks/ibm_was/config_models/shared.py +++ b/ibm_was/datadog_checks/ibm_was/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ignite/datadog_checks/ignite/config_models/instance.py b/ignite/datadog_checks/ignite/config_models/instance.py index 631a321dda3bb7..a07c63edd14368 100644 --- a/ignite/datadog_checks/ignite/config_models/instance.py +++ b/ignite/datadog_checks/ignite/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,6 +22,7 @@ class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_jvm_metrics: Optional[bool] = None @@ -42,7 +43,7 @@ class InstanceConfig(BaseModel): rmi_connection_timeout: Optional[float] = None rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tools_jar_path: Optional[str] = None trust_store_password: Optional[str] = None trust_store_path: Optional[str] = None @@ -53,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ignite/datadog_checks/ignite/config_models/shared.py b/ignite/datadog_checks/ignite/config_models/shared.py index 0db55a6d064d5d..b8bb8146892a0f 100644 --- a/ignite/datadog_checks/ignite/config_models/shared.py +++ b/ignite/datadog_checks/ignite/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,10 +23,11 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: Optional[bool] = None - conf: Optional[Sequence[Mapping[str, Any]]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None is_jmx: bool new_gc_metrics: Optional[bool] = None service: Optional[str] = None @@ -36,25 +38,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/iis/datadog_checks/iis/config_models/instance.py b/iis/datadog_checks/iis/config_models/instance.py index c7122a2901ca0c..3214b773bd1be3 100644 --- a/iis/datadog_checks/iis/config_models/instance.py +++ b/iis/datadog_checks/iis/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from typing_extensions import Literal @@ -22,14 +23,16 @@ class AppPool(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Counter(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -42,6 +45,7 @@ class Counter(BaseModel): class InstanceCounts(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) monitored: Optional[str] = None @@ -51,11 +55,12 @@ class InstanceCounts(BaseModel): class ExtraMetrics(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - counters: Sequence[Mapping[str, Union[str, Counter]]] - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + counters: tuple[MappingProxyType[str, Union[str, Counter]], ...] + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None instance_counts: Optional[InstanceCounts] = None name: str tag_name: Optional[str] = None @@ -64,19 +69,21 @@ class ExtraMetrics(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metrics(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - counters: Sequence[Mapping[str, Union[str, Counter]]] - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + counters: tuple[MappingProxyType[str, Union[str, Counter]], ...] + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None instance_counts: Optional[InstanceCounts] = None name: str tag_name: Optional[str] = None @@ -85,35 +92,37 @@ class Metrics(BaseModel): class Site(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - additional_metrics: Optional[Sequence[Sequence[str]]] = None - app_pools: Optional[Union[Sequence[str], AppPool]] = None - counter_data_types: Optional[Sequence[str]] = None + additional_metrics: Optional[tuple[tuple[str, ...], ...]] = None + app_pools: Optional[Union[tuple[str, ...], AppPool]] = None + counter_data_types: Optional[tuple[str, ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - extra_metrics: Optional[Mapping[str, ExtraMetrics]] = None + extra_metrics: Optional[MappingProxyType[str, ExtraMetrics]] = None host: Optional[str] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Mapping[str, Metrics]] = None + metrics: Optional[MappingProxyType[str, Metrics]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') password: Optional[str] = None server: Optional[str] = None server_tag: Optional[str] = None service: Optional[str] = None - sites: Optional[Union[Sequence[str], Site]] = None - tags: Optional[Sequence[str]] = None + sites: Optional[Union[tuple[str, ...], Site]] = None + tags: Optional[tuple[str, ...]] = None use_legacy_check_version: Optional[bool] = None username: Optional[str] = None @@ -122,25 +131,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/iis/datadog_checks/iis/config_models/shared.py b/iis/datadog_checks/iis/config_models/shared.py index aa58639466c054..94b02c19dbbb69 100644 --- a/iis/datadog_checks/iis/config_models/shared.py +++ b/iis/datadog_checks/iis/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -32,25 +33,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/impala/datadog_checks/impala/config_models/instance.py b/impala/datadog_checks/impala/config_models/instance.py index 316d8f5856387e..33eeababf0b92e 100644 --- a/impala/datadog_checks/impala/config_models/instance.py +++ b/impala/datadog_checks/impala/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from typing_extensions import Literal @@ -22,14 +23,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -39,14 +42,16 @@ class ExtraMetric(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -56,24 +61,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -90,18 +98,18 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = 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[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -111,7 +119,7 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -120,24 +128,24 @@ class InstanceConfig(BaseModel): password: Optional[str] = None persist_connections: Optional[bool] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None service: Optional[str] = None service_type: Literal['daemon', 'statestore', 'catalog'] - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[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 @@ -150,25 +158,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/impala/datadog_checks/impala/config_models/shared.py b/impala/datadog_checks/impala/config_models/shared.py index cddf15255ec303..906da89039040e 100644 --- a/impala/datadog_checks/impala/config_models/shared.py +++ b/impala/datadog_checks/impala/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/istio/datadog_checks/istio/config_models/instance.py b/istio/datadog_checks/istio/config_models/instance.py index c9118b04f664a7..21cb58ebd43144 100644 --- a/istio/datadog_checks/istio/config_models/instance.py +++ b/istio/datadog_checks/istio/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,22 +41,25 @@ class ExtraMetric(BaseModel): class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -61,14 +67,16 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -78,24 +86,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -115,21 +126,21 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = 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_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = None + ignore_tags: Optional[tuple[str, ...]] = None + include_labels: Optional[tuple[str, ...]] = None istio_mesh_endpoint: Optional[str] = None istiod_endpoint: Optional[str] = None kerberos_auth: Optional[str] = None @@ -141,10 +152,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -155,10 +166,10 @@ class InstanceConfig(BaseModel): prometheus_metrics_prefix: Optional[str] = None prometheus_url: Optional[str] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None send_distribution_buckets: Optional[bool] = None send_distribution_counts_as_monotonic: Optional[bool] = None @@ -167,20 +178,20 @@ class InstanceConfig(BaseModel): send_monotonic_counter: Optional[bool] = None send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_latest_spec: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None use_openmetrics: Optional[bool] = None @@ -192,25 +203,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/istio/datadog_checks/istio/config_models/shared.py b/istio/datadog_checks/istio/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/istio/datadog_checks/istio/config_models/shared.py +++ b/istio/datadog_checks/istio/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/jboss_wildfly/datadog_checks/jboss_wildfly/config_models/instance.py b/jboss_wildfly/datadog_checks/jboss_wildfly/config_models/instance.py index 27518398030cb7..cb2b8e7a0d94e7 100644 --- a/jboss_wildfly/datadog_checks/jboss_wildfly/config_models/instance.py +++ b/jboss_wildfly/datadog_checks/jboss_wildfly/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,6 +22,7 @@ class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_jvm_metrics: Optional[bool] = None @@ -42,7 +43,7 @@ class InstanceConfig(BaseModel): rmi_connection_timeout: Optional[float] = None rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tools_jar_path: Optional[str] = None trust_store_password: Optional[str] = None trust_store_path: Optional[str] = None @@ -53,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/jboss_wildfly/datadog_checks/jboss_wildfly/config_models/shared.py b/jboss_wildfly/datadog_checks/jboss_wildfly/config_models/shared.py index 4450cb75df5e64..42e415baf89817 100644 --- a/jboss_wildfly/datadog_checks/jboss_wildfly/config_models/shared.py +++ b/jboss_wildfly/datadog_checks/jboss_wildfly/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,11 +23,12 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: Optional[bool] = None - conf: Optional[Sequence[Mapping[str, Any]]] = None - custom_jar_paths: Optional[Sequence[str]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None + custom_jar_paths: Optional[tuple[str, ...]] = None is_jmx: bool new_gc_metrics: Optional[bool] = None service: Optional[str] = None @@ -37,25 +39,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kafka/datadog_checks/kafka/config_models/instance.py b/kafka/datadog_checks/kafka/config_models/instance.py index 631a321dda3bb7..a07c63edd14368 100644 --- a/kafka/datadog_checks/kafka/config_models/instance.py +++ b/kafka/datadog_checks/kafka/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,6 +22,7 @@ class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_jvm_metrics: Optional[bool] = None @@ -42,7 +43,7 @@ class InstanceConfig(BaseModel): rmi_connection_timeout: Optional[float] = None rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tools_jar_path: Optional[str] = None trust_store_password: Optional[str] = None trust_store_path: Optional[str] = None @@ -53,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kafka/datadog_checks/kafka/config_models/shared.py b/kafka/datadog_checks/kafka/config_models/shared.py index 0db55a6d064d5d..b8bb8146892a0f 100644 --- a/kafka/datadog_checks/kafka/config_models/shared.py +++ b/kafka/datadog_checks/kafka/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,10 +23,11 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: Optional[bool] = None - conf: Optional[Sequence[Mapping[str, Any]]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None is_jmx: bool new_gc_metrics: Optional[bool] = None service: Optional[str] = None @@ -36,25 +38,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kafka_consumer/datadog_checks/kafka_consumer/config_models/instance.py b/kafka_consumer/datadog_checks/kafka_consumer/config_models/instance.py index 55c8a77f3824c6..793d1dcb4eaa0e 100644 --- a/kafka_consumer/datadog_checks/kafka_consumer/config_models/instance.py +++ b/kafka_consumer/datadog_checks/kafka_consumer/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,14 +22,16 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class SaslOauthTokenProvider(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) client_id: Optional[str] = None @@ -39,14 +42,15 @@ class SaslOauthTokenProvider(BaseModel): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - consumer_groups: Optional[Mapping[str, Any]] = None - consumer_groups_regex: Optional[Mapping[str, Any]] = None + consumer_groups: Optional[MappingProxyType[str, Any]] = None + consumer_groups_regex: Optional[MappingProxyType[str, Any]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None kafka_client_api_version: Optional[str] = None - kafka_connect_str: Union[str, Sequence[str]] + kafka_connect_str: Union[str, tuple[str, ...]] metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None monitor_all_broker_highwatermarks: Optional[bool] = None @@ -61,7 +65,7 @@ class InstanceConfig(BaseModel): sasl_plain_username: Optional[str] = None security_protocol: Optional[str] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_crlfile: Optional[str] = None @@ -75,25 +79,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kafka_consumer/datadog_checks/kafka_consumer/config_models/shared.py b/kafka_consumer/datadog_checks/kafka_consumer/config_models/shared.py index 1209ce0b60d1b2..c1c74e3714cabc 100644 --- a/kafka_consumer/datadog_checks/kafka_consumer/config_models/shared.py +++ b/kafka_consumer/datadog_checks/kafka_consumer/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) kafka_timeout: Optional[int] = None @@ -32,25 +33,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kong/datadog_checks/kong/config_models/instance.py b/kong/datadog_checks/kong/config_models/instance.py index 3ea2106b6038d1..ac94e43a64b801 100644 --- a/kong/datadog_checks/kong/config_models/instance.py +++ b/kong/datadog_checks/kong/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,14 +41,16 @@ class ExtraMetric(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -55,24 +60,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -89,18 +97,18 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = 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[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -111,7 +119,7 @@ class InstanceConfig(BaseModel): kong_status_url: Optional[str] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -120,23 +128,23 @@ class InstanceConfig(BaseModel): password: Optional[str] = None persist_connections: Optional[bool] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[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 @@ -149,25 +157,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kong/datadog_checks/kong/config_models/shared.py b/kong/datadog_checks/kong/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/kong/datadog_checks/kong/config_models/shared.py +++ b/kong/datadog_checks/kong/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kube_apiserver_metrics/datadog_checks/kube_apiserver_metrics/config_models/instance.py b/kube_apiserver_metrics/datadog_checks/kube_apiserver_metrics/config_models/instance.py index 08bcf458d13e8b..a688cfe0471011 100644 --- a/kube_apiserver_metrics/datadog_checks/kube_apiserver_metrics/config_models/instance.py +++ b/kube_apiserver_metrics/datadog_checks/kube_apiserver_metrics/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +22,34 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -52,24 +57,27 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -84,14 +92,14 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + exclude_labels: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = None - ignore_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -101,10 +109,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, str]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, str]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -124,16 +132,16 @@ class InstanceConfig(BaseModel): send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None username: Optional[str] = None @@ -143,25 +151,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kube_apiserver_metrics/datadog_checks/kube_apiserver_metrics/config_models/shared.py b/kube_apiserver_metrics/datadog_checks/kube_apiserver_metrics/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/kube_apiserver_metrics/datadog_checks/kube_apiserver_metrics/config_models/shared.py +++ b/kube_apiserver_metrics/datadog_checks/kube_apiserver_metrics/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kube_dns/datadog_checks/kube_dns/config_models/instance.py b/kube_dns/datadog_checks/kube_dns/config_models/instance.py index db57870d93a167..56f81f0cbfa97a 100644 --- a/kube_dns/datadog_checks/kube_dns/config_models/instance.py +++ b/kube_dns/datadog_checks/kube_dns/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +22,34 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -52,24 +57,27 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -84,15 +92,15 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + exclude_labels: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = None health_url: Optional[str] = None - ignore_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -102,10 +110,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, str]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, str]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -125,16 +133,16 @@ class InstanceConfig(BaseModel): send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None username: Optional[str] = None @@ -144,25 +152,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kube_dns/datadog_checks/kube_dns/config_models/shared.py b/kube_dns/datadog_checks/kube_dns/config_models/shared.py index cddf15255ec303..906da89039040e 100644 --- a/kube_dns/datadog_checks/kube_dns/config_models/shared.py +++ b/kube_dns/datadog_checks/kube_dns/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kube_metrics_server/datadog_checks/kube_metrics_server/config_models/instance.py b/kube_metrics_server/datadog_checks/kube_metrics_server/config_models/instance.py index 860d9668d06d85..f187261518e4b0 100644 --- a/kube_metrics_server/datadog_checks/kube_metrics_server/config_models/instance.py +++ b/kube_metrics_server/datadog_checks/kube_metrics_server/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +22,34 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -52,24 +57,27 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -84,15 +92,15 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + exclude_labels: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = None health_url: Optional[str] = None - ignore_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -102,10 +110,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, str]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, str]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -124,16 +132,16 @@ class InstanceConfig(BaseModel): send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None username: Optional[str] = None @@ -143,25 +151,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kube_metrics_server/datadog_checks/kube_metrics_server/config_models/shared.py b/kube_metrics_server/datadog_checks/kube_metrics_server/config_models/shared.py index cddf15255ec303..906da89039040e 100644 --- a/kube_metrics_server/datadog_checks/kube_metrics_server/config_models/shared.py +++ b/kube_metrics_server/datadog_checks/kube_metrics_server/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kube_proxy/datadog_checks/kube_proxy/config_models/instance.py b/kube_proxy/datadog_checks/kube_proxy/config_models/instance.py index 860d9668d06d85..f187261518e4b0 100644 --- a/kube_proxy/datadog_checks/kube_proxy/config_models/instance.py +++ b/kube_proxy/datadog_checks/kube_proxy/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +22,34 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -52,24 +57,27 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -84,15 +92,15 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + exclude_labels: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = None health_url: Optional[str] = None - ignore_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -102,10 +110,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, str]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, str]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -124,16 +132,16 @@ class InstanceConfig(BaseModel): send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None username: Optional[str] = None @@ -143,25 +151,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kube_proxy/datadog_checks/kube_proxy/config_models/shared.py b/kube_proxy/datadog_checks/kube_proxy/config_models/shared.py index cddf15255ec303..906da89039040e 100644 --- a/kube_proxy/datadog_checks/kube_proxy/config_models/shared.py +++ b/kube_proxy/datadog_checks/kube_proxy/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kube_scheduler/datadog_checks/kube_scheduler/config_models/instance.py b/kube_scheduler/datadog_checks/kube_scheduler/config_models/instance.py index 9994d4ff148094..b39289c5850738 100644 --- a/kube_scheduler/datadog_checks/kube_scheduler/config_models/instance.py +++ b/kube_scheduler/datadog_checks/kube_scheduler/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +22,34 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -52,24 +57,27 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -84,15 +92,15 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + exclude_labels: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = None health_url: Optional[str] = None - ignore_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -102,12 +110,12 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None leader_election: Optional[bool] = None leader_election_kind: Optional[str] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, str]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, str]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -126,16 +134,16 @@ class InstanceConfig(BaseModel): send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None username: Optional[str] = None @@ -145,25 +153,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kube_scheduler/datadog_checks/kube_scheduler/config_models/shared.py b/kube_scheduler/datadog_checks/kube_scheduler/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/kube_scheduler/datadog_checks/kube_scheduler/config_models/shared.py +++ b/kube_scheduler/datadog_checks/kube_scheduler/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kubelet/datadog_checks/kubelet/config_models/instance.py b/kubelet/datadog_checks/kubelet/config_models/instance.py index 94a9cf2bfcb6ad..848e6264c8b880 100644 --- a/kubelet/datadog_checks/kubelet/config_models/instance.py +++ b/kubelet/datadog_checks/kubelet/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +22,34 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -52,24 +57,27 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -86,16 +94,16 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - enabled_gauges: Optional[Sequence[str]] = None - enabled_rates: Optional[Sequence[str]] = None - exclude_labels: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + enabled_gauges: Optional[tuple[str, ...]] = None + enabled_rates: Optional[tuple[str, ...]] = None + exclude_labels: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = None - ignore_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -106,10 +114,10 @@ class InstanceConfig(BaseModel): kubelet_metrics_endpoint: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, str]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, str]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -129,16 +137,16 @@ class InstanceConfig(BaseModel): send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None username: Optional[str] = None @@ -148,25 +156,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kubelet/datadog_checks/kubelet/config_models/shared.py b/kubelet/datadog_checks/kubelet/config_models/shared.py index 59c534d071001b..458a7003d92bbe 100644 --- a/kubelet/datadog_checks/kubelet/config_models/shared.py +++ b/kubelet/datadog_checks/kubelet/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kyototycoon/datadog_checks/kyototycoon/config_models/instance.py b/kyototycoon/datadog_checks/kyototycoon/config_models/instance.py index 2b910204564ccf..3ca6c0cde7479e 100644 --- a/kyototycoon/datadog_checks/kyototycoon/config_models/instance.py +++ b/kyototycoon/datadog_checks/kyototycoon/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -80,13 +85,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -97,25 +102,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/kyototycoon/datadog_checks/kyototycoon/config_models/shared.py b/kyototycoon/datadog_checks/kyototycoon/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/kyototycoon/datadog_checks/kyototycoon/config_models/shared.py +++ b/kyototycoon/datadog_checks/kyototycoon/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/lighttpd/datadog_checks/lighttpd/config_models/instance.py b/lighttpd/datadog_checks/lighttpd/config_models/instance.py index c9aaef1aef14b4..48e558de10eb8f 100644 --- a/lighttpd/datadog_checks/lighttpd/config_models/instance.py +++ b/lighttpd/datadog_checks/lighttpd/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -79,13 +84,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -96,25 +101,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/lighttpd/datadog_checks/lighttpd/config_models/shared.py b/lighttpd/datadog_checks/lighttpd/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/lighttpd/datadog_checks/lighttpd/config_models/shared.py +++ b/lighttpd/datadog_checks/lighttpd/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/linkerd/datadog_checks/linkerd/config_models/instance.py b/linkerd/datadog_checks/linkerd/config_models/instance.py index e57304ed42cee0..b09b6ca50f22a9 100644 --- a/linkerd/datadog_checks/linkerd/config_models/instance.py +++ b/linkerd/datadog_checks/linkerd/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,22 +41,25 @@ class ExtraMetric(BaseModel): class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -61,14 +67,16 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -78,24 +86,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -115,21 +126,21 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = 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_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -139,10 +150,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -153,10 +164,10 @@ class InstanceConfig(BaseModel): prometheus_metrics_prefix: Optional[str] = None prometheus_url: Optional[str] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None send_distribution_buckets: Optional[bool] = None send_distribution_counts_as_monotonic: Optional[bool] = None @@ -165,20 +176,20 @@ class InstanceConfig(BaseModel): send_monotonic_counter: Optional[bool] = None send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_latest_spec: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None @@ -189,25 +200,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/linkerd/datadog_checks/linkerd/config_models/shared.py b/linkerd/datadog_checks/linkerd/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/linkerd/datadog_checks/linkerd/config_models/shared.py +++ b/linkerd/datadog_checks/linkerd/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/linux_proc_extras/datadog_checks/linux_proc_extras/config_models/instance.py b/linux_proc_extras/datadog_checks/linux_proc_extras/config_models/instance.py index 32d51a43106c77..e589be01e8f1b0 100644 --- a/linux_proc_extras/datadog_checks/linux_proc_extras/config_models/instance.py +++ b/linux_proc_extras/datadog_checks/linux_proc_extras/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -38,32 +40,21 @@ class InstanceConfig(BaseModel): metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/linux_proc_extras/datadog_checks/linux_proc_extras/config_models/shared.py b/linux_proc_extras/datadog_checks/linux_proc_extras/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/linux_proc_extras/datadog_checks/linux_proc_extras/config_models/shared.py +++ b/linux_proc_extras/datadog_checks/linux_proc_extras/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mapr/datadog_checks/mapr/config_models/instance.py b/mapr/datadog_checks/mapr/config_models/instance.py index 1c96a015ba27dc..b6d01b6d6e18b6 100644 --- a/mapr/datadog_checks/mapr/config_models/instance.py +++ b/mapr/datadog_checks/mapr/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -37,12 +39,12 @@ class InstanceConfig(BaseModel): empty_default_hostname: Optional[bool] = None hostname: Optional[str] = None metric_patterns: Optional[MetricPatterns] = None - metric_whitelist: Optional[Sequence[str]] = None + metric_whitelist: Optional[tuple[str, ...]] = None min_collection_interval: Optional[float] = None service: Optional[str] = None stream_path: Optional[str] = None streams_count: Optional[int] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None ticket_location: Optional[str] = None @model_validator(mode='before') @@ -50,25 +52,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mapr/datadog_checks/mapr/config_models/shared.py b/mapr/datadog_checks/mapr/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/mapr/datadog_checks/mapr/config_models/shared.py +++ b/mapr/datadog_checks/mapr/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mapreduce/datadog_checks/mapreduce/config_models/instance.py b/mapreduce/datadog_checks/mapreduce/config_models/instance.py index 28d64960f3f86f..77f30c482acd23 100644 --- a/mapreduce/datadog_checks/mapreduce/config_models/instance.py +++ b/mapreduce/datadog_checks/mapreduce/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -60,8 +65,8 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None disable_legacy_cluster_tag: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -81,13 +86,13 @@ class InstanceConfig(BaseModel): resourcemanager_uri: str service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -98,25 +103,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mapreduce/datadog_checks/mapreduce/config_models/shared.py b/mapreduce/datadog_checks/mapreduce/config_models/shared.py index 0134382ffc5b8a..487ff2d1aaa482 100644 --- a/mapreduce/datadog_checks/mapreduce/config_models/shared.py +++ b/mapreduce/datadog_checks/mapreduce/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,20 +22,22 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - general_counters: Optional[Sequence[Mapping[str, Any]]] = None - job_specific_counters: Optional[Sequence[Mapping[str, Any]]] = None + general_counters: Optional[tuple[MappingProxyType[str, Any], ...]] = None + job_specific_counters: Optional[tuple[MappingProxyType[str, Any], ...]] = None proxy: Optional[Proxy] = None service: Optional[str] = None skip_proxy: Optional[bool] = None @@ -45,25 +48,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/marathon/datadog_checks/marathon/config_models/instance.py b/marathon/datadog_checks/marathon/config_models/instance.py index ba80721d113ae7..aa8c004b5e263e 100644 --- a/marathon/datadog_checks/marathon/config_models/instance.py +++ b/marathon/datadog_checks/marathon/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) acs_url: Optional[str] = None @@ -59,9 +64,9 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None group: Optional[str] = None - headers: Optional[Mapping[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -69,7 +74,7 @@ class InstanceConfig(BaseModel): kerberos_hostname: Optional[str] = None kerberos_keytab: Optional[str] = None kerberos_principal: Optional[str] = None - label_tags: Optional[Sequence[str]] = None + label_tags: Optional[tuple[str, ...]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None @@ -81,13 +86,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None url: str @@ -99,25 +104,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/marathon/datadog_checks/marathon/config_models/shared.py b/marathon/datadog_checks/marathon/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/marathon/datadog_checks/marathon/config_models/shared.py +++ b/marathon/datadog_checks/marathon/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/marklogic/datadog_checks/marklogic/config_models/instance.py b/marklogic/datadog_checks/marklogic/config_models/instance.py index 374308be961314..b4d54148b69959 100644 --- a/marklogic/datadog_checks/marklogic/config_models/instance.py +++ b/marklogic/datadog_checks/marklogic/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -59,8 +64,8 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_checks: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -77,16 +82,16 @@ class InstanceConfig(BaseModel): proxy: Optional[Proxy] = None read_timeout: Optional[float] = None request_size: Optional[float] = None - resource_filters: Optional[Sequence[Mapping[str, Any]]] = None + resource_filters: Optional[tuple[MappingProxyType[str, Any], ...]] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None url: str @@ -98,25 +103,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/marklogic/datadog_checks/marklogic/config_models/shared.py b/marklogic/datadog_checks/marklogic/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/marklogic/datadog_checks/marklogic/config_models/shared.py +++ b/marklogic/datadog_checks/marklogic/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mcache/datadog_checks/mcache/config_models/instance.py b/mcache/datadog_checks/mcache/config_models/instance.py index a7d97edbeb9777..a12f640f5850ee 100644 --- a/mcache/datadog_checks/mcache/config_models/instance.py +++ b/mcache/datadog_checks/mcache/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,27 +22,29 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None - options: Optional[Mapping[str, Any]] = None + options: Optional[MappingProxyType[str, Any]] = None password: Optional[str] = None port: Optional[int] = None service: Optional[str] = None socket: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None url: Optional[str] = None username: Optional[str] = None @@ -50,25 +53,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mcache/datadog_checks/mcache/config_models/shared.py b/mcache/datadog_checks/mcache/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/mcache/datadog_checks/mcache/config_models/shared.py +++ b/mcache/datadog_checks/mcache/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mesos_master/datadog_checks/mesos_master/config_models/instance.py b/mesos_master/datadog_checks/mesos_master/config_models/instance.py index b0c9dd6112c5c4..e31c99d217e86f 100644 --- a/mesos_master/datadog_checks/mesos_master/config_models/instance.py +++ b/mesos_master/datadog_checks/mesos_master/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -78,13 +83,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None url: str @@ -96,25 +101,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mesos_master/datadog_checks/mesos_master/config_models/shared.py b/mesos_master/datadog_checks/mesos_master/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/mesos_master/datadog_checks/mesos_master/config_models/shared.py +++ b/mesos_master/datadog_checks/mesos_master/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mesos_slave/datadog_checks/mesos_slave/config_models/instance.py b/mesos_slave/datadog_checks/mesos_slave/config_models/instance.py index 032e50574fcccc..1f20c4593025fd 100644 --- a/mesos_slave/datadog_checks/mesos_slave/config_models/instance.py +++ b/mesos_slave/datadog_checks/mesos_slave/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -59,8 +64,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -80,14 +85,14 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None - tasks: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None + tasks: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None url: str @@ -99,25 +104,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mesos_slave/datadog_checks/mesos_slave/config_models/shared.py b/mesos_slave/datadog_checks/mesos_slave/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/mesos_slave/datadog_checks/mesos_slave/config_models/shared.py +++ b/mesos_slave/datadog_checks/mesos_slave/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mongo/datadog_checks/mongo/config_models/instance.py b/mongo/datadog_checks/mongo/config_models/instance.py index cfd5dd0d29e78a..8ad26699095d01 100644 --- a/mongo/datadog_checks/mongo/config_models/instance.py +++ b/mongo/datadog_checks/mongo/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,6 +22,7 @@ class Field(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) field_name: Optional[str] = None @@ -30,46 +32,49 @@ class Field(BaseModel): class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) database: Optional[str] = None - fields: Optional[Sequence[Field]] = None + fields: Optional[tuple[Field, ...]] = None metric_prefix: Optional[str] = None - query: Optional[Mapping[str, Any]] = None - tags: Optional[Sequence[str]] = None + query: Optional[MappingProxyType[str, Any]] = None + tags: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - additional_metrics: Optional[Sequence[str]] = None - collections: Optional[Sequence[str]] = None + additional_metrics: Optional[tuple[str, ...]] = None + collections: Optional[tuple[str, ...]] = None collections_indexes_stats: Optional[bool] = None connection_scheme: Optional[str] = None - custom_queries: Optional[Sequence[CustomQuery]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None database: Optional[str] = None - dbnames: Optional[Sequence[str]] = None + dbnames: Optional[tuple[str, ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - hosts: Optional[Union[str, Sequence[str]]] = None + hosts: Optional[Union[str, tuple[str, ...]]] = None metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None - options: Optional[Mapping[str, Any]] = None + options: Optional[MappingProxyType[str, Any]] = None password: Optional[str] = None replica_check: Optional[bool] = None server: Optional[str] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[int] = None tls: Optional[bool] = None tls_allow_invalid_certificates: Optional[bool] = None @@ -89,25 +94,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mongo/datadog_checks/mongo/config_models/shared.py b/mongo/datadog_checks/mongo/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/mongo/datadog_checks/mongo/config_models/shared.py +++ b/mongo/datadog_checks/mongo/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mysql/datadog_checks/mysql/config_models/instance.py b/mysql/datadog_checks/mysql/config_models/instance.py index 9e05824b265d65..d233b0ad48b9ee 100644 --- a/mysql/datadog_checks/mysql/config_models/instance.py +++ b/mysql/datadog_checks/mysql/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,6 +22,7 @@ class Aws(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) instance_endpoint: Optional[str] = None @@ -28,6 +30,7 @@ class Aws(BaseModel): class Azure(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) deployment_type: Optional[str] = None @@ -36,15 +39,17 @@ class Azure(BaseModel): class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - columns: Optional[Sequence[Mapping[str, Any]]] = None + columns: Optional[tuple[MappingProxyType[str, Any], ...]] = None query: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None class Gcp(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) instance_id: Optional[str] = None @@ -53,14 +58,16 @@ class Gcp(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class ObfuscatorOptions(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) collect_commands: Optional[bool] = None @@ -73,6 +80,7 @@ class ObfuscatorOptions(BaseModel): class Options(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) disable_innodb_metrics: Optional[bool] = None @@ -91,6 +99,7 @@ class Options(BaseModel): class QueryActivity(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) collection_interval: Optional[float] = None @@ -99,6 +108,7 @@ class QueryActivity(BaseModel): class QueryMetrics(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) collection_interval: Optional[float] = None @@ -107,6 +117,7 @@ class QueryMetrics(BaseModel): class QuerySamples(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) collection_interval: Optional[float] = None @@ -126,6 +137,7 @@ class QuerySamples(BaseModel): class Ssl(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) ca: Optional[str] = None @@ -137,15 +149,16 @@ class Ssl(BaseModel): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - additional_status: Optional[Sequence[Mapping[str, Any]]] = None - additional_variable: Optional[Sequence[Mapping[str, Any]]] = None + additional_status: Optional[tuple[MappingProxyType[str, Any], ...]] = None + additional_variable: Optional[tuple[MappingProxyType[str, Any], ...]] = None aws: Optional[Aws] = None azure: Optional[Azure] = None charset: Optional[str] = None connect_timeout: Optional[float] = None - custom_queries: Optional[Sequence[CustomQuery]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None dbm: Optional[bool] = None defaults_file: Optional[str] = None disable_generic_tags: Optional[bool] = None @@ -162,7 +175,7 @@ class InstanceConfig(BaseModel): options: Optional[Options] = None password: Optional[str] = None port: Optional[float] = None - queries: Optional[Sequence[Mapping[str, Any]]] = None + queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None query_activity: Optional[QueryActivity] = None query_metrics: Optional[QueryMetrics] = None query_samples: Optional[QuerySamples] = None @@ -170,7 +183,7 @@ class InstanceConfig(BaseModel): service: Optional[str] = None sock: Optional[str] = None ssl: Optional[Ssl] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None use_global_custom_queries: Optional[str] = None username: Optional[str] = None @@ -179,25 +192,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/mysql/datadog_checks/mysql/config_models/shared.py b/mysql/datadog_checks/mysql/config_models/shared.py index 45d1293f12b20f..8a1218b18c7641 100644 --- a/mysql/datadog_checks/mysql/config_models/shared.py +++ b/mysql/datadog_checks/mysql/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,26 +23,23 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - global_custom_queries: Optional[Sequence[Mapping[str, Any]]] = None + global_custom_queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None 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('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/nagios/datadog_checks/nagios/config_models/instance.py b/nagios/datadog_checks/nagios/config_models/instance.py index 89bcad3570e22e..884079177f4633 100644 --- a/nagios/datadog_checks/nagios/config_models/instance.py +++ b/nagios/datadog_checks/nagios/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_events: Optional[bool] = None @@ -42,32 +44,21 @@ class InstanceConfig(BaseModel): nagios_conf: str passive_checks_events: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/nagios/datadog_checks/nagios/config_models/shared.py b/nagios/datadog_checks/nagios/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/nagios/datadog_checks/nagios/config_models/shared.py +++ b/nagios/datadog_checks/nagios/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/network/datadog_checks/network/config_models/instance.py b/network/datadog_checks/network/config_models/instance.py index a54b47ef2a2c1d..6e4f5095cfa26d 100644 --- a/network/datadog_checks/network/config_models/instance.py +++ b/network/datadog_checks/network/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,18 +21,20 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - blacklist_conntrack_metrics: Optional[Sequence[str]] = None + blacklist_conntrack_metrics: Optional[tuple[str, ...]] = None collect_aws_ena_metrics: Optional[bool] = None collect_connection_queues: Optional[bool] = None collect_connection_state: Optional[bool] = None @@ -44,38 +46,27 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None excluded_interface_re: Optional[str] = None - excluded_interfaces: Optional[Sequence[str]] = None + excluded_interfaces: Optional[tuple[str, ...]] = None metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None use_sudo_conntrack: Optional[bool] = None - whitelist_conntrack_metrics: Optional[Sequence[str]] = None + whitelist_conntrack_metrics: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/network/datadog_checks/network/config_models/shared.py b/network/datadog_checks/network/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/network/datadog_checks/network/config_models/shared.py +++ b/network/datadog_checks/network/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/nfsstat/datadog_checks/nfsstat/config_models/instance.py b/nfsstat/datadog_checks/nfsstat/config_models/instance.py index 9fd87afb27b4bd..8b251986605c44 100644 --- a/nfsstat/datadog_checks/nfsstat/config_models/instance.py +++ b/nfsstat/datadog_checks/nfsstat/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -37,32 +39,21 @@ class InstanceConfig(BaseModel): metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/nfsstat/datadog_checks/nfsstat/config_models/shared.py b/nfsstat/datadog_checks/nfsstat/config_models/shared.py index e262ac1b3291a1..0b39d48714a58c 100644 --- a/nfsstat/datadog_checks/nfsstat/config_models/shared.py +++ b/nfsstat/datadog_checks/nfsstat/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) autofs_enabled: Optional[bool] = None @@ -33,25 +34,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/nginx/datadog_checks/nginx/config_models/instance.py b/nginx/datadog_checks/nginx/config_models/instance.py index 2eeafce0ed9fb4..3caa2bbef12ac6 100644 --- a/nginx/datadog_checks/nginx/config_models/instance.py +++ b/nginx/datadog_checks/nginx/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -81,13 +86,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -101,25 +106,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/nginx/datadog_checks/nginx/config_models/shared.py b/nginx/datadog_checks/nginx/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/nginx/datadog_checks/nginx/config_models/shared.py +++ b/nginx/datadog_checks/nginx/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/nginx_ingress_controller/datadog_checks/nginx_ingress_controller/config_models/instance.py b/nginx_ingress_controller/datadog_checks/nginx_ingress_controller/config_models/instance.py index f5050d760dceef..3cea17569c4bca 100644 --- a/nginx_ingress_controller/datadog_checks/nginx_ingress_controller/config_models/instance.py +++ b/nginx_ingress_controller/datadog_checks/nginx_ingress_controller/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +22,34 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -52,24 +57,27 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -85,14 +93,14 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + exclude_labels: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = None - ignore_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -102,10 +110,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, str]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, str]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -124,16 +132,16 @@ class InstanceConfig(BaseModel): send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None username: Optional[str] = None @@ -143,25 +151,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/nginx_ingress_controller/datadog_checks/nginx_ingress_controller/config_models/shared.py b/nginx_ingress_controller/datadog_checks/nginx_ingress_controller/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/nginx_ingress_controller/datadog_checks/nginx_ingress_controller/config_models/shared.py +++ b/nginx_ingress_controller/datadog_checks/nginx_ingress_controller/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/openldap/datadog_checks/openldap/config_models/instance.py b/openldap/datadog_checks/openldap/config_models/instance.py index 480864e5965d4a..aa45d4ab08f904 100644 --- a/openldap/datadog_checks/openldap/config_models/instance.py +++ b/openldap/datadog_checks/openldap/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,18 +22,20 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - custom_queries: Optional[Sequence[Mapping[str, Any]]] = None + custom_queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None @@ -43,7 +46,7 @@ class InstanceConfig(BaseModel): ssl_cert: Optional[str] = None ssl_key: Optional[str] = None ssl_verify: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None url: str username: Optional[str] = None @@ -52,25 +55,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/openldap/datadog_checks/openldap/config_models/shared.py b/openldap/datadog_checks/openldap/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/openldap/datadog_checks/openldap/config_models/shared.py +++ b/openldap/datadog_checks/openldap/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/openmetrics/datadog_checks/openmetrics/config_models/instance.py b/openmetrics/datadog_checks/openmetrics/config_models/instance.py index 2497c1d2a92b22..4ad346915fb34e 100644 --- a/openmetrics/datadog_checks/openmetrics/config_models/instance.py +++ b/openmetrics/datadog_checks/openmetrics/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,22 +41,25 @@ class ExtraMetric(BaseModel): class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -61,14 +67,16 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -78,24 +86,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -115,21 +126,21 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = 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_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -139,10 +150,10 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Sequence[Union[str, Mapping[str, Union[str, Metric]]]] + metrics: tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...] min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -153,10 +164,10 @@ class InstanceConfig(BaseModel): prometheus_metrics_prefix: Optional[str] = None prometheus_url: Optional[str] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None send_distribution_buckets: Optional[bool] = None send_distribution_counts_as_monotonic: Optional[bool] = None @@ -165,20 +176,20 @@ class InstanceConfig(BaseModel): send_monotonic_counter: Optional[bool] = None send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_latest_spec: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None @@ -189,25 +200,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/openmetrics/datadog_checks/openmetrics/config_models/shared.py b/openmetrics/datadog_checks/openmetrics/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/openmetrics/datadog_checks/openmetrics/config_models/shared.py +++ b/openmetrics/datadog_checks/openmetrics/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/openstack_controller/datadog_checks/openstack_controller/config_models/instance.py b/openstack_controller/datadog_checks/openstack_controller/config_models/instance.py index 8d0db0b9856d28..1ff04581e13d5c 100644 --- a/openstack_controller/datadog_checks/openstack_controller/config_models/instance.py +++ b/openstack_controller/datadog_checks/openstack_controller/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -55,7 +60,7 @@ class InstanceConfig(BaseModel): aws_host: Optional[str] = None aws_region: Optional[str] = None aws_service: Optional[str] = None - blacklist_project_names: Optional[Sequence[str]] = None + blacklist_project_names: Optional[tuple[str, ...]] = None collect_hypervisor_load: Optional[bool] = None collect_hypervisor_metrics: Optional[bool] = None collect_network_metrics: Optional[bool] = None @@ -65,10 +70,10 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_network_ids: Optional[Sequence[str]] = None - exclude_server_ids: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + exclude_network_ids: Optional[tuple[str, ...]] = None + exclude_server_ids: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -92,46 +97,35 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_agent_proxy: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None use_shortname: Optional[bool] = None - user: Optional[Mapping[str, Any]] = None + user: Optional[MappingProxyType[str, Any]] = None username: Optional[str] = None - whitelist_project_names: Optional[Sequence[str]] = None + whitelist_project_names: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/openstack_controller/datadog_checks/openstack_controller/config_models/shared.py b/openstack_controller/datadog_checks/openstack_controller/config_models/shared.py index 59c534d071001b..458a7003d92bbe 100644 --- a/openstack_controller/datadog_checks/openstack_controller/config_models/shared.py +++ b/openstack_controller/datadog_checks/openstack_controller/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/oracle/datadog_checks/oracle/config_models/instance.py b/oracle/datadog_checks/oracle/config_models/instance.py index 75f1e7097531a5..cd241fe79ae46a 100644 --- a/oracle/datadog_checks/oracle/config_models/instance.py +++ b/oracle/datadog_checks/oracle/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,27 +22,30 @@ class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - columns: Optional[Sequence[Mapping[str, Any]]] = None + columns: Optional[tuple[MappingProxyType[str, Any], ...]] = None query: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - custom_queries: Optional[Sequence[CustomQuery]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None jdbc_driver_path: Optional[str] = None @@ -56,7 +60,7 @@ class InstanceConfig(BaseModel): server: str service: Optional[str] = None service_name: str - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None use_global_custom_queries: Optional[str] = None username: str @@ -65,25 +69,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/oracle/datadog_checks/oracle/config_models/shared.py b/oracle/datadog_checks/oracle/config_models/shared.py index 18baeec9cb2089..85a3725c3582ff 100644 --- a/oracle/datadog_checks/oracle/config_models/shared.py +++ b/oracle/datadog_checks/oracle/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,9 +23,10 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - global_custom_queries: Optional[Sequence[Mapping[str, Any]]] = None + global_custom_queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None service: Optional[str] = None use_instant_client: Optional[bool] = None @@ -33,25 +35,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/pdh_check/datadog_checks/pdh_check/config_models/instance.py b/pdh_check/datadog_checks/pdh_check/config_models/instance.py index b81d8fd6d013ca..8227af1221575a 100644 --- a/pdh_check/datadog_checks/pdh_check/config_models/instance.py +++ b/pdh_check/datadog_checks/pdh_check/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +21,32 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - additional_metrics: Optional[Sequence[Sequence[str]]] = None + additional_metrics: Optional[tuple[tuple[str, ...], ...]] = None admin_share: Optional[str] = None - counter_data_types: Optional[Sequence[str]] = None + counter_data_types: Optional[tuple[str, ...]] = None countersetname: str disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None host: Optional[str] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Sequence[Sequence[str]] + metrics: tuple[tuple[str, ...], ...] min_collection_interval: Optional[float] = None password: Optional[str] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None username: Optional[str] = None @model_validator(mode='before') @@ -52,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/pdh_check/datadog_checks/pdh_check/config_models/shared.py b/pdh_check/datadog_checks/pdh_check/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/pdh_check/datadog_checks/pdh_check/config_models/shared.py +++ b/pdh_check/datadog_checks/pdh_check/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/pgbouncer/datadog_checks/pgbouncer/config_models/instance.py b/pgbouncer/datadog_checks/pgbouncer/config_models/instance.py index 1a8f390a5a15e4..b8579a769a7d15 100644 --- a/pgbouncer/datadog_checks/pgbouncer/config_models/instance.py +++ b/pgbouncer/datadog_checks/pgbouncer/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_per_client_metrics: Optional[bool] = None @@ -43,7 +45,7 @@ class InstanceConfig(BaseModel): password: Optional[str] = None port: Optional[int] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None use_cached: Optional[bool] = None username: Optional[str] = None @@ -52,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/pgbouncer/datadog_checks/pgbouncer/config_models/shared.py b/pgbouncer/datadog_checks/pgbouncer/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/pgbouncer/datadog_checks/pgbouncer/config_models/shared.py +++ b/pgbouncer/datadog_checks/pgbouncer/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/php_fpm/datadog_checks/php_fpm/config_models/instance.py b/php_fpm/datadog_checks/php_fpm/config_models/instance.py index 887c6ff7189425..bb131ef1034732 100644 --- a/php_fpm/datadog_checks/php_fpm/config_models/instance.py +++ b/php_fpm/datadog_checks/php_fpm/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None http_host: Optional[str] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None @@ -82,13 +87,13 @@ class InstanceConfig(BaseModel): service: Optional[str] = None skip_proxy: Optional[bool] = None status_url: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_fastcgi: Optional[bool] = None @@ -100,25 +105,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/php_fpm/datadog_checks/php_fpm/config_models/shared.py b/php_fpm/datadog_checks/php_fpm/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/php_fpm/datadog_checks/php_fpm/config_models/shared.py +++ b/php_fpm/datadog_checks/php_fpm/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/postfix/datadog_checks/postfix/config_models/instance.py b/postfix/datadog_checks/postfix/config_models/instance.py index 37078bb780d3c2..4876399a097372 100644 --- a/postfix/datadog_checks/postfix/config_models/instance.py +++ b/postfix/datadog_checks/postfix/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) config_directory: Optional[str] = None @@ -38,34 +40,23 @@ class InstanceConfig(BaseModel): empty_default_hostname: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None - queues: Optional[Sequence[str]] = None + queues: Optional[tuple[str, ...]] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/postfix/datadog_checks/postfix/config_models/shared.py b/postfix/datadog_checks/postfix/config_models/shared.py index 8ef1ae63aed9b5..4c0afca46b0625 100644 --- a/postfix/datadog_checks/postfix/config_models/shared.py +++ b/postfix/datadog_checks/postfix/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) postfix_user: Optional[str] = None @@ -33,25 +34,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/postgres/datadog_checks/postgres/config_models/instance.py b/postgres/datadog_checks/postgres/config_models/instance.py index 6f7fad8e0a4ec7..a937bbc5390309 100644 --- a/postgres/datadog_checks/postgres/config_models/instance.py +++ b/postgres/datadog_checks/postgres/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,6 +22,7 @@ class Aws(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) instance_endpoint: Optional[str] = None @@ -29,6 +31,7 @@ class Aws(BaseModel): class Azure(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) deployment_type: Optional[str] = None @@ -37,6 +40,7 @@ class Azure(BaseModel): class CollectSettings(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) collection_interval: Optional[float] = None @@ -45,17 +49,19 @@ class CollectSettings(BaseModel): class DatabaseAutodiscovery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) enabled: Optional[bool] = None - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None max_databases: Optional[int] = None refresh: Optional[int] = None class Gcp(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) instance_id: Optional[str] = None @@ -64,14 +70,16 @@ class Gcp(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class ObfuscatorOptions(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) collect_commands: Optional[bool] = None @@ -85,6 +93,7 @@ class ObfuscatorOptions(BaseModel): class QueryActivity(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) collection_interval: Optional[float] = None @@ -94,6 +103,7 @@ class QueryActivity(BaseModel): class QueryMetrics(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) collection_interval: Optional[float] = None @@ -103,6 +113,7 @@ class QueryMetrics(BaseModel): class QuerySamples(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) collection_interval: Optional[float] = None @@ -117,21 +128,23 @@ class QuerySamples(BaseModel): class Relation(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) relation_name: Optional[str] = None relation_regex: Optional[str] = None relation_schema: Optional[str] = None - relkind: Optional[Sequence[str]] = None - schemas: Optional[Sequence[str]] = None + relkind: Optional[tuple[str, ...]] = None + schemas: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - activity_metrics_excluded_aggregations: Optional[Sequence[str]] = None + activity_metrics_excluded_aggregations: Optional[tuple[str, ...]] = None application_name: Optional[str] = None aws: Optional[Aws] = None azure: Optional[Azure] = None @@ -143,7 +156,7 @@ class InstanceConfig(BaseModel): collect_function_metrics: Optional[bool] = None collect_settings: Optional[CollectSettings] = None collect_wal_metrics: Optional[bool] = None - custom_queries: Optional[Sequence[Mapping[str, Any]]] = None + custom_queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None data_directory: Optional[str] = None database_autodiscovery: Optional[DatabaseAutodiscovery] = None dbm: Optional[bool] = None @@ -154,7 +167,7 @@ class InstanceConfig(BaseModel): gcp: Optional[Gcp] = None host: str idle_connection_timeout: Optional[int] = None - ignore_databases: Optional[Sequence[str]] = None + ignore_databases: Optional[tuple[str, ...]] = None log_unobfuscated_plans: Optional[bool] = None log_unobfuscated_queries: Optional[bool] = None max_connections: Optional[int] = None @@ -169,7 +182,7 @@ class InstanceConfig(BaseModel): query_metrics: Optional[QueryMetrics] = None query_samples: Optional[QuerySamples] = None query_timeout: Optional[int] = None - relations: Optional[Sequence[Union[str, Relation]]] = None + relations: Optional[tuple[Union[str, Relation], ...]] = None reported_hostname: Optional[str] = None service: Optional[str] = None ssl: Optional[str] = None @@ -179,7 +192,7 @@ class InstanceConfig(BaseModel): ssl_root_cert: Optional[str] = None table_count_limit: Optional[int] = None tag_replication_role: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None username: str @model_validator(mode='before') @@ -187,25 +200,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/postgres/datadog_checks/postgres/config_models/shared.py b/postgres/datadog_checks/postgres/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/postgres/datadog_checks/postgres/config_models/shared.py +++ b/postgres/datadog_checks/postgres/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/powerdns_recursor/datadog_checks/powerdns_recursor/config_models/instance.py b/powerdns_recursor/datadog_checks/powerdns_recursor/config_models/instance.py index 5ceeba7f7c1598..21aec840c69bba 100644 --- a/powerdns_recursor/datadog_checks/powerdns_recursor/config_models/instance.py +++ b/powerdns_recursor/datadog_checks/powerdns_recursor/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -59,8 +64,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None host: str kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None @@ -81,13 +86,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -99,25 +104,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/powerdns_recursor/datadog_checks/powerdns_recursor/config_models/shared.py b/powerdns_recursor/datadog_checks/powerdns_recursor/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/powerdns_recursor/datadog_checks/powerdns_recursor/config_models/shared.py +++ b/powerdns_recursor/datadog_checks/powerdns_recursor/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/presto/datadog_checks/presto/config_models/instance.py b/presto/datadog_checks/presto/config_models/instance.py index 631a321dda3bb7..a07c63edd14368 100644 --- a/presto/datadog_checks/presto/config_models/instance.py +++ b/presto/datadog_checks/presto/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,6 +22,7 @@ class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_jvm_metrics: Optional[bool] = None @@ -42,7 +43,7 @@ class InstanceConfig(BaseModel): rmi_connection_timeout: Optional[float] = None rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tools_jar_path: Optional[str] = None trust_store_password: Optional[str] = None trust_store_path: Optional[str] = None @@ -53,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/presto/datadog_checks/presto/config_models/shared.py b/presto/datadog_checks/presto/config_models/shared.py index 0db55a6d064d5d..b8bb8146892a0f 100644 --- a/presto/datadog_checks/presto/config_models/shared.py +++ b/presto/datadog_checks/presto/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,10 +23,11 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: Optional[bool] = None - conf: Optional[Sequence[Mapping[str, Any]]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None is_jmx: bool new_gc_metrics: Optional[bool] = None service: Optional[str] = None @@ -36,25 +38,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/process/datadog_checks/process/config_models/instance.py b/process/datadog_checks/process/config_models/instance.py index 981f21e38fee49..68fb748b2851b5 100644 --- a/process/datadog_checks/process/config_models/instance.py +++ b/process/datadog_checks/process/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +22,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_children: Optional[bool] = None @@ -43,10 +46,10 @@ class InstanceConfig(BaseModel): pid: Optional[int] = None pid_cache_duration: Optional[int] = None pid_file: Optional[str] = None - search_string: Optional[Sequence[str]] = None + search_string: Optional[tuple[str, ...]] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None - thresholds: Optional[Mapping[str, Any]] = None + tags: Optional[tuple[str, ...]] = None + thresholds: Optional[MappingProxyType[str, Any]] = None try_sudo: Optional[bool] = None user: Optional[str] = None @@ -55,25 +58,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/process/datadog_checks/process/config_models/shared.py b/process/datadog_checks/process/config_models/shared.py index 6a773c518a17ff..436837e2a25647 100644 --- a/process/datadog_checks/process/config_models/shared.py +++ b/process/datadog_checks/process/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) access_denied_cache_duration: Optional[int] = None @@ -35,25 +36,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/prometheus/datadog_checks/prometheus/config_models/instance.py b/prometheus/datadog_checks/prometheus/config_models/instance.py index d1d6ff0d2fde54..eeeb26d4bb72e3 100644 --- a/prometheus/datadog_checks/prometheus/config_models/instance.py +++ b/prometheus/datadog_checks/prometheus/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,14 +22,16 @@ class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -37,15 +40,16 @@ class LabelJoins(BaseModel): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - exclude_labels: Optional[Sequence[str]] = None + exclude_labels: Optional[tuple[str, ...]] = None health_service_check: Optional[bool] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None max_returned_metrics: Optional[int] = None - metrics: Sequence[Union[Mapping[str, str], str]] + metrics: tuple[Union[MappingProxyType[str, str], str], ...] namespace: str prometheus_metrics_prefix: Optional[str] = None prometheus_timeout: Optional[int] = None @@ -55,32 +59,21 @@ class InstanceConfig(BaseModel): ssl_ca_cert: Optional[str] = None ssl_cert: Optional[str] = None ssl_private_key: Optional[str] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = 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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/prometheus/datadog_checks/prometheus/config_models/shared.py b/prometheus/datadog_checks/prometheus/config_models/shared.py index d7f4dd28de4784..1a8081d40b0c4a 100644 --- a/prometheus/datadog_checks/prometheus/config_models/shared.py +++ b/prometheus/datadog_checks/prometheus/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/proxysql/datadog_checks/proxysql/config_models/instance.py b/proxysql/datadog_checks/proxysql/config_models/instance.py index 86141964cbc9c5..896759db8b71a7 100644 --- a/proxysql/datadog_checks/proxysql/config_models/instance.py +++ b/proxysql/datadog_checks/proxysql/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,18 +21,20 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - additional_metrics: Optional[Sequence[str]] = None + additional_metrics: Optional[tuple[str, ...]] = None connect_timeout: Optional[int] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None @@ -43,7 +45,7 @@ class InstanceConfig(BaseModel): port: int read_timeout: Optional[int] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_private_key: Optional[str] = None @@ -57,25 +59,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/proxysql/datadog_checks/proxysql/config_models/shared.py b/proxysql/datadog_checks/proxysql/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/proxysql/datadog_checks/proxysql/config_models/shared.py +++ b/proxysql/datadog_checks/proxysql/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/pulsar/datadog_checks/pulsar/config_models/instance.py b/pulsar/datadog_checks/pulsar/config_models/instance.py index 6634ff2831f5bc..4b88707da02c5d 100644 --- a/pulsar/datadog_checks/pulsar/config_models/instance.py +++ b/pulsar/datadog_checks/pulsar/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,14 +41,16 @@ class ExtraMetric(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -55,24 +60,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -89,18 +97,18 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = 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[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -110,7 +118,7 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -119,23 +127,23 @@ class InstanceConfig(BaseModel): password: Optional[str] = None persist_connections: Optional[bool] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[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 @@ -148,25 +156,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/pulsar/datadog_checks/pulsar/config_models/shared.py b/pulsar/datadog_checks/pulsar/config_models/shared.py index cddf15255ec303..906da89039040e 100644 --- a/pulsar/datadog_checks/pulsar/config_models/shared.py +++ b/pulsar/datadog_checks/pulsar/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/rabbitmq/datadog_checks/rabbitmq/config_models/instance.py b/rabbitmq/datadog_checks/rabbitmq/config_models/instance.py index 6252b5547851d2..e6d8cb306152fa 100644 --- a/rabbitmq/datadog_checks/rabbitmq/config_models/instance.py +++ b/rabbitmq/datadog_checks/rabbitmq/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,14 +41,16 @@ class ExtraMetric(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -55,6 +60,7 @@ class Metric(BaseModel): class PrometheusPlugin(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) include_aggregated_endpoint: Optional[bool] = None @@ -64,24 +70,27 @@ class PrometheusPlugin(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -99,20 +108,20 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exchanges: Optional[Sequence[str]] = None - exchanges_regexes: Optional[Sequence[str]] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = None + exchanges: Optional[tuple[str, ...]] = None + exchanges_regexes: Optional[tuple[str, ...]] = 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, ExtraMetric]]], ...]] = 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[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -122,11 +131,11 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') - nodes: Optional[Sequence[str]] = None - nodes_regexes: Optional[Sequence[str]] = None + nodes: Optional[tuple[str, ...]] = None + nodes_regexes: Optional[tuple[str, ...]] = None non_cumulative_histogram_buckets: Optional[bool] = None ntlm_domain: Optional[str] = None openmetrics_endpoint: Optional[str] = None @@ -134,59 +143,48 @@ class InstanceConfig(BaseModel): persist_connections: Optional[bool] = None prometheus_plugin: Optional[PrometheusPlugin] = None proxy: Optional[Proxy] = None - queues: Optional[Sequence[str]] = None - queues_regexes: Optional[Sequence[str]] = None + queues: Optional[tuple[str, ...]] = None + queues_regexes: Optional[tuple[str, ...]] = None rabbitmq_api_url: Optional[str] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None tag_families: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[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 - vhosts: Optional[Sequence[str]] = None + vhosts: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/rabbitmq/datadog_checks/rabbitmq/config_models/shared.py b/rabbitmq/datadog_checks/rabbitmq/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/rabbitmq/datadog_checks/rabbitmq/config_models/shared.py +++ b/rabbitmq/datadog_checks/rabbitmq/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/redisdb/datadog_checks/redisdb/config_models/instance.py b/redisdb/datadog_checks/redisdb/config_models/instance.py index a466b28bc8b6d7..a58aaac262ef73 100644 --- a/redisdb/datadog_checks/redisdb/config_models/instance.py +++ b/redisdb/datadog_checks/redisdb/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_client_metrics: Optional[bool] = None @@ -39,7 +41,7 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None host: str - keys: Optional[Sequence[str]] = None + keys: Optional[tuple[str, ...]] = None metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None password: Optional[str] = None @@ -52,7 +54,7 @@ class InstanceConfig(BaseModel): ssl_cert_reqs: Optional[int] = None ssl_certfile: Optional[str] = None ssl_keyfile: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None unix_socket_path: Optional[str] = None username: Optional[str] = None warn_on_missing_keys: Optional[bool] = None @@ -62,25 +64,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/redisdb/datadog_checks/redisdb/config_models/shared.py b/redisdb/datadog_checks/redisdb/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/redisdb/datadog_checks/redisdb/config_models/shared.py +++ b/redisdb/datadog_checks/redisdb/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/rethinkdb/datadog_checks/rethinkdb/config_models/instance.py b/rethinkdb/datadog_checks/rethinkdb/config_models/instance.py index ec190b26198406..5a4b6ed9efacc6 100644 --- a/rethinkdb/datadog_checks/rethinkdb/config_models/instance.py +++ b/rethinkdb/datadog_checks/rethinkdb/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -40,7 +42,7 @@ class InstanceConfig(BaseModel): password: Optional[str] = None port: Optional[int] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tls_ca_cert: Optional[str] = None username: Optional[str] = None @@ -49,25 +51,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/rethinkdb/datadog_checks/rethinkdb/config_models/shared.py b/rethinkdb/datadog_checks/rethinkdb/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/rethinkdb/datadog_checks/rethinkdb/config_models/shared.py +++ b/rethinkdb/datadog_checks/rethinkdb/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/riak/datadog_checks/riak/config_models/instance.py b/riak/datadog_checks/riak/config_models/instance.py index b0c9dd6112c5c4..e31c99d217e86f 100644 --- a/riak/datadog_checks/riak/config_models/instance.py +++ b/riak/datadog_checks/riak/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -78,13 +83,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None url: str @@ -96,25 +101,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/riak/datadog_checks/riak/config_models/shared.py b/riak/datadog_checks/riak/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/riak/datadog_checks/riak/config_models/shared.py +++ b/riak/datadog_checks/riak/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/riakcs/datadog_checks/riakcs/config_models/instance.py b/riakcs/datadog_checks/riakcs/config_models/instance.py index fb25a1a11912b0..1ce0a8b985c1de 100644 --- a/riakcs/datadog_checks/riakcs/config_models/instance.py +++ b/riakcs/datadog_checks/riakcs/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) access_id: Optional[str] = None @@ -39,37 +41,26 @@ class InstanceConfig(BaseModel): host: Optional[str] = None is_secure: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[str]] = None + metrics: Optional[tuple[str, ...]] = None min_collection_interval: Optional[float] = None port: Optional[int] = None s3_root: Optional[str] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/riakcs/datadog_checks/riakcs/config_models/shared.py b/riakcs/datadog_checks/riakcs/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/riakcs/datadog_checks/riakcs/config_models/shared.py +++ b/riakcs/datadog_checks/riakcs/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/sap_hana/datadog_checks/sap_hana/config_models/instance.py b/sap_hana/datadog_checks/sap_hana/config_models/instance.py index 5b3dea4f94eee9..82c51f6b0606a4 100644 --- a/sap_hana/datadog_checks/sap_hana/config_models/instance.py +++ b/sap_hana/datadog_checks/sap_hana/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,29 +22,32 @@ class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - columns: Optional[Sequence[Mapping[str, Any]]] = None + columns: Optional[tuple[MappingProxyType[str, Any], ...]] = None query: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) batch_size: Optional[int] = None - connection_properties: Optional[Mapping[str, Any]] = None - custom_queries: Optional[Sequence[CustomQuery]] = None + connection_properties: Optional[MappingProxyType[str, Any]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None @@ -55,7 +59,7 @@ class InstanceConfig(BaseModel): schema_: Optional[str] = Field(None, alias='schema') server: str service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None @@ -73,25 +77,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/sap_hana/datadog_checks/sap_hana/config_models/shared.py b/sap_hana/datadog_checks/sap_hana/config_models/shared.py index 314a5343f67bfa..841ee90bdb33ea 100644 --- a/sap_hana/datadog_checks/sap_hana/config_models/shared.py +++ b/sap_hana/datadog_checks/sap_hana/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,9 +23,10 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - global_custom_queries: Optional[Sequence[Mapping[str, Any]]] = None + global_custom_queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None persist_db_connections: Optional[bool] = None service: Optional[str] = None @@ -33,25 +35,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/scylla/datadog_checks/scylla/config_models/instance.py b/scylla/datadog_checks/scylla/config_models/instance.py index 4db066610b71d3..0af62c350dfc98 100644 --- a/scylla/datadog_checks/scylla/config_models/instance.py +++ b/scylla/datadog_checks/scylla/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,30 +22,34 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class IgnoreMetricsByLabels(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_label_key: Optional[str] = None - target_label_value_list: Optional[Sequence[str]] = None + target_label_value_list: Optional[tuple[str, ...]] = None class TargetMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) label_to_match: Optional[str] = None - labels_to_get: Optional[Sequence[str]] = None + labels_to_get: Optional[tuple[str, ...]] = None class LabelJoins(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) target_metric: Optional[TargetMetric] = None @@ -52,24 +57,27 @@ class LabelJoins(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -84,14 +92,14 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + exclude_labels: Optional[tuple[str, ...]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None health_service_check: Optional[bool] = None - ignore_metrics: Optional[Sequence[str]] = None + ignore_metrics: Optional[tuple[str, ...]] = None ignore_metrics_by_labels: Optional[IgnoreMetricsByLabels] = None - ignore_tags: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -101,11 +109,11 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None label_joins: Optional[LabelJoins] = None label_to_hostname: Optional[str] = None - labels_mapper: Optional[Mapping[str, Any]] = None + labels_mapper: Optional[MappingProxyType[str, Any]] = None log_requests: Optional[bool] = None - metric_groups: Optional[Sequence[str]] = None + metric_groups: Optional[tuple[str, ...]] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, str]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, str]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = None ntlm_domain: Optional[str] = None @@ -124,16 +132,16 @@ class InstanceConfig(BaseModel): send_monotonic_with_gauge: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None - type_overrides: Optional[Mapping[str, Any]] = None + type_overrides: Optional[MappingProxyType[str, Any]] = None use_legacy_auth_encoding: Optional[bool] = None use_process_start_time: Optional[bool] = None username: Optional[str] = None @@ -143,25 +151,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/scylla/datadog_checks/scylla/config_models/shared.py b/scylla/datadog_checks/scylla/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/scylla/datadog_checks/scylla/config_models/shared.py +++ b/scylla/datadog_checks/scylla/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/silk/datadog_checks/silk/config_models/instance.py b/silk/datadog_checks/silk/config_models/instance.py index 249a49fadd2194..09aa914845965c 100644 --- a/silk/datadog_checks/silk/config_models/instance.py +++ b/silk/datadog_checks/silk/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -60,8 +65,8 @@ class InstanceConfig(BaseModel): empty_default_hostname: Optional[bool] = None enable_blocksize_statistics: Optional[bool] = None enable_read_write_statistics: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None host_address: str kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None @@ -81,13 +86,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -98,25 +103,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/silk/datadog_checks/silk/config_models/shared.py b/silk/datadog_checks/silk/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/silk/datadog_checks/silk/config_models/shared.py +++ b/silk/datadog_checks/silk/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/singlestore/datadog_checks/singlestore/config_models/instance.py b/singlestore/datadog_checks/singlestore/config_models/instance.py index 9400f1b6e557e8..4184b9bff32b33 100644 --- a/singlestore/datadog_checks/singlestore/config_models/instance.py +++ b/singlestore/datadog_checks/singlestore/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,29 +22,32 @@ class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - columns: Optional[Sequence[Mapping[str, Any]]] = None + columns: Optional[tuple[MappingProxyType[str, Any], ...]] = None query: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_system_metrics: Optional[bool] = None connect_timeout: Optional[int] = None - custom_queries: Optional[Sequence[CustomQuery]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None host: str @@ -54,7 +58,7 @@ class InstanceConfig(BaseModel): port: Optional[int] = None read_timeout: Optional[int] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_private_key: Optional[str] = None @@ -70,25 +74,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/singlestore/datadog_checks/singlestore/config_models/shared.py b/singlestore/datadog_checks/singlestore/config_models/shared.py index 45d1293f12b20f..8a1218b18c7641 100644 --- a/singlestore/datadog_checks/singlestore/config_models/shared.py +++ b/singlestore/datadog_checks/singlestore/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,26 +23,23 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - global_custom_queries: Optional[Sequence[Mapping[str, Any]]] = None + global_custom_queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None 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('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/snowflake/datadog_checks/snowflake/config_models/instance.py b/snowflake/datadog_checks/snowflake/config_models/instance.py index e307b0710ed5e3..2b8ac9c129eb8b 100644 --- a/snowflake/datadog_checks/snowflake/config_models/instance.py +++ b/snowflake/datadog_checks/snowflake/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,24 +22,27 @@ class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - columns: Optional[Sequence[Mapping[str, Any]]] = None + columns: Optional[tuple[MappingProxyType[str, Any], ...]] = None query: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) account: str @@ -46,12 +50,12 @@ class InstanceConfig(BaseModel): authenticator: Optional[str] = None client_prefetch_threads: Optional[int] = None client_session_keep_alive: Optional[bool] = None - custom_queries: Optional[Sequence[CustomQuery]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None database: Optional[str] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None login_timeout: Optional[int] = None - metric_groups: Optional[Sequence[str]] = None + metric_groups: Optional[tuple[str, ...]] = None metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None ocsp_response_cache_filename: Optional[str] = None @@ -62,7 +66,7 @@ class InstanceConfig(BaseModel): role: str schema_: Optional[str] = Field(None, alias='schema') service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None token: Optional[str] = None token_path: Optional[str] = None use_global_custom_queries: Optional[str] = None @@ -74,25 +78,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/snowflake/datadog_checks/snowflake/config_models/shared.py b/snowflake/datadog_checks/snowflake/config_models/shared.py index 562a329103e697..533494b6e7558a 100644 --- a/snowflake/datadog_checks/snowflake/config_models/shared.py +++ b/snowflake/datadog_checks/snowflake/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,9 +23,10 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - global_custom_queries: Optional[Sequence[Mapping[str, Any]]] = None + global_custom_queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None proxy_host: Optional[str] = None proxy_password: Optional[str] = None proxy_port: Optional[int] = None @@ -35,17 +37,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/solr/datadog_checks/solr/config_models/instance.py b/solr/datadog_checks/solr/config_models/instance.py index 631a321dda3bb7..a07c63edd14368 100644 --- a/solr/datadog_checks/solr/config_models/instance.py +++ b/solr/datadog_checks/solr/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,6 +22,7 @@ class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_jvm_metrics: Optional[bool] = None @@ -42,7 +43,7 @@ class InstanceConfig(BaseModel): rmi_connection_timeout: Optional[float] = None rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tools_jar_path: Optional[str] = None trust_store_password: Optional[str] = None trust_store_path: Optional[str] = None @@ -53,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/solr/datadog_checks/solr/config_models/shared.py b/solr/datadog_checks/solr/config_models/shared.py index 0db55a6d064d5d..b8bb8146892a0f 100644 --- a/solr/datadog_checks/solr/config_models/shared.py +++ b/solr/datadog_checks/solr/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,10 +23,11 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: Optional[bool] = None - conf: Optional[Sequence[Mapping[str, Any]]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None is_jmx: bool new_gc_metrics: Optional[bool] = None service: Optional[str] = None @@ -36,25 +38,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/sonarqube/datadog_checks/sonarqube/config_models/instance.py b/sonarqube/datadog_checks/sonarqube/config_models/instance.py index 378d5d10b95f93..ab196ce0e777f3 100644 --- a/sonarqube/datadog_checks/sonarqube/config_models/instance.py +++ b/sonarqube/datadog_checks/sonarqube/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,33 +22,37 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ComponentsDiscovery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Mapping[str, Any]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[MappingProxyType[str, Any]] = None limit: Optional[int] = None class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -57,15 +62,15 @@ class InstanceConfig(BaseModel): aws_region: Optional[str] = None aws_service: Optional[str] = None collect_default_jvm_metrics: Optional[bool] = None - components: Optional[Mapping[str, Any]] = None + components: Optional[MappingProxyType[str, Any]] = None components_discovery: Optional[ComponentsDiscovery] = None connect_timeout: Optional[float] = None - default_exclude: Optional[Sequence[str]] = None - default_include: Optional[Sequence[str]] = None + default_exclude: Optional[tuple[str, ...]] = None + default_include: Optional[tuple[str, ...]] = None default_tag: Optional[str] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None host: Optional[str] = None is_jmx: Optional[bool] = None java_bin_path: Optional[str] = None @@ -96,13 +101,13 @@ class InstanceConfig(BaseModel): rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None tools_jar_path: Optional[str] = None @@ -118,25 +123,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/sonarqube/datadog_checks/sonarqube/config_models/shared.py b/sonarqube/datadog_checks/sonarqube/config_models/shared.py index 83534741d40197..1d08bdb6284cd9 100644 --- a/sonarqube/datadog_checks/sonarqube/config_models/shared.py +++ b/sonarqube/datadog_checks/sonarqube/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,20 +22,22 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: Optional[bool] = None - conf: Optional[Sequence[Mapping[str, Any]]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None is_jmx: Optional[bool] = None new_gc_metrics: Optional[bool] = None proxy: Optional[Proxy] = None @@ -48,25 +51,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/spark/datadog_checks/spark/config_models/instance.py b/spark/datadog_checks/spark/config_models/instance.py index d5833281005c9c..7ce704b0707df9 100644 --- a/spark/datadog_checks/spark/config_models/instance.py +++ b/spark/datadog_checks/spark/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -62,8 +67,8 @@ class InstanceConfig(BaseModel): empty_default_hostname: Optional[bool] = None enable_query_name_tag: Optional[bool] = None executor_level_metrics: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -86,16 +91,16 @@ class InstanceConfig(BaseModel): spark_cluster_mode: Optional[str] = None spark_pre_20_mode: Optional[bool] = None spark_proxy_enabled: Optional[bool] = None - spark_ui_ports: Optional[Sequence[int]] = None + spark_ui_ports: Optional[tuple[int, ...]] = None spark_url: str streaming_metrics: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -106,25 +111,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/spark/datadog_checks/spark/config_models/shared.py b/spark/datadog_checks/spark/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/spark/datadog_checks/spark/config_models/shared.py +++ b/spark/datadog_checks/spark/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/sqlserver/datadog_checks/sqlserver/config_models/instance.py b/sqlserver/datadog_checks/sqlserver/config_models/instance.py index c7a2d3dd7b7e9a..99e2fbab02b80e 100644 --- a/sqlserver/datadog_checks/sqlserver/config_models/instance.py +++ b/sqlserver/datadog_checks/sqlserver/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,6 +22,7 @@ class Aws(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) instance_endpoint: Optional[str] = None @@ -28,6 +30,7 @@ class Aws(BaseModel): class Azure(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) deployment_type: Optional[str] = None @@ -36,15 +39,17 @@ class Azure(BaseModel): class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - columns: Optional[Sequence[Mapping[str, Any]]] = None + columns: Optional[tuple[MappingProxyType[str, Any], ...]] = None query: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None class Gcp(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) instance_id: Optional[str] = None @@ -53,14 +58,16 @@ class Gcp(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class ObfuscatorOptions(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) collect_commands: Optional[bool] = None @@ -73,6 +80,7 @@ class ObfuscatorOptions(BaseModel): class QueryActivity(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) collection_interval: Optional[float] = None @@ -81,6 +89,7 @@ class QueryActivity(BaseModel): class QueryMetrics(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) collection_interval: Optional[float] = None @@ -95,24 +104,25 @@ class QueryMetrics(BaseModel): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) adoprovider: Optional[str] = None ao_database: Optional[str] = None autodiscovery_db_service_check: Optional[bool] = None - autodiscovery_exclude: Optional[Sequence[str]] = None - autodiscovery_include: Optional[Sequence[str]] = None + autodiscovery_exclude: Optional[tuple[str, ...]] = None + autodiscovery_include: Optional[tuple[str, ...]] = None availability_group: Optional[str] = None aws: Optional[Aws] = None azure: Optional[Azure] = None command_timeout: Optional[int] = None connection_string: Optional[str] = None connector: Optional[str] = None - custom_queries: Optional[Sequence[CustomQuery]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None database: Optional[str] = None database_autodiscovery: Optional[bool] = None database_autodiscovery_interval: Optional[int] = None - db_fragmentation_object_names: Optional[Sequence[str]] = None + db_fragmentation_object_names: Optional[tuple[str, ...]] = None dbm: Optional[bool] = None disable_generic_tags: Optional[bool] = None driver: Optional[str] = None @@ -143,7 +153,7 @@ class InstanceConfig(BaseModel): server_version: Optional[str] = None service: Optional[str] = None stored_procedure: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None use_global_custom_queries: Optional[str] = None username: Optional[str] = None @@ -152,25 +162,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/sqlserver/datadog_checks/sqlserver/config_models/shared.py b/sqlserver/datadog_checks/sqlserver/config_models/shared.py index 12d1bc5787102a..ea7963bad6e266 100644 --- a/sqlserver/datadog_checks/sqlserver/config_models/shared.py +++ b/sqlserver/datadog_checks/sqlserver/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,27 +23,24 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - custom_metrics: Optional[Sequence[Mapping[str, Any]]] = None - global_custom_queries: Optional[Sequence[Mapping[str, Any]]] = None + custom_metrics: Optional[tuple[MappingProxyType[str, Any], ...]] = None + global_custom_queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None 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('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/squid/datadog_checks/squid/config_models/instance.py b/squid/datadog_checks/squid/config_models/instance.py index 3c25b1571159d1..75a4ea94df196e 100644 --- a/squid/datadog_checks/squid/config_models/instance.py +++ b/squid/datadog_checks/squid/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None host: Optional[str] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None @@ -81,13 +86,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -98,25 +103,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/squid/datadog_checks/squid/config_models/shared.py b/squid/datadog_checks/squid/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/squid/datadog_checks/squid/config_models/shared.py +++ b/squid/datadog_checks/squid/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ssh_check/datadog_checks/ssh_check/config_models/instance.py b/ssh_check/datadog_checks/ssh_check/config_models/instance.py index 93c090ff165a3f..7aac85cc742a2e 100644 --- a/ssh_check/datadog_checks/ssh_check/config_models/instance.py +++ b/ssh_check/datadog_checks/ssh_check/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) add_missing_keys: Optional[bool] = None @@ -44,7 +46,7 @@ class InstanceConfig(BaseModel): private_key_type: Optional[str] = None service: Optional[str] = None sftp_check: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None username: str @model_validator(mode='before') @@ -52,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/ssh_check/datadog_checks/ssh_check/config_models/shared.py b/ssh_check/datadog_checks/ssh_check/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/ssh_check/datadog_checks/ssh_check/config_models/shared.py +++ b/ssh_check/datadog_checks/ssh_check/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/statsd/datadog_checks/statsd/config_models/instance.py b/statsd/datadog_checks/statsd/config_models/instance.py index 89f10fefd2b8cc..bb08642f2b5a47 100644 --- a/statsd/datadog_checks/statsd/config_models/instance.py +++ b/statsd/datadog_checks/statsd/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -39,7 +41,7 @@ class InstanceConfig(BaseModel): min_collection_interval: Optional[float] = None port: Optional[int] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None @model_validator(mode='before') @@ -47,25 +49,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/statsd/datadog_checks/statsd/config_models/shared.py b/statsd/datadog_checks/statsd/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/statsd/datadog_checks/statsd/config_models/shared.py +++ b/statsd/datadog_checks/statsd/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/strimzi/datadog_checks/strimzi/config_models/instance.py b/strimzi/datadog_checks/strimzi/config_models/instance.py index 040fc5bd6ec7a1..58be5f4151b9d2 100644 --- a/strimzi/datadog_checks/strimzi/config_models/instance.py +++ b/strimzi/datadog_checks/strimzi/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,14 +41,16 @@ class ExtraMetric(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -55,24 +60,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -90,18 +98,18 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = 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[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -111,7 +119,7 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -120,23 +128,23 @@ class InstanceConfig(BaseModel): password: Optional[str] = None persist_connections: Optional[bool] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None topic_operator_endpoint: Optional[str] = None @@ -151,25 +159,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/strimzi/datadog_checks/strimzi/config_models/shared.py b/strimzi/datadog_checks/strimzi/config_models/shared.py index 59c534d071001b..458a7003d92bbe 100644 --- a/strimzi/datadog_checks/strimzi/config_models/shared.py +++ b/strimzi/datadog_checks/strimzi/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/supervisord/datadog_checks/supervisord/config_models/instance.py b/supervisord/datadog_checks/supervisord/config_models/instance.py index 17d891e0cf7e60..8c190ef82e0352 100644 --- a/supervisord/datadog_checks/supervisord/config_models/instance.py +++ b/supervisord/datadog_checks/supervisord/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -40,11 +42,11 @@ class InstanceConfig(BaseModel): name: str password: Optional[str] = None port: Optional[int] = None - proc_names: Optional[Sequence[str]] = None - proc_regex: Optional[Sequence[str]] = None + proc_names: Optional[tuple[str, ...]] = None + proc_regex: Optional[tuple[str, ...]] = None service: Optional[str] = None socket: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None username: Optional[str] = None @model_validator(mode='before') @@ -52,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/supervisord/datadog_checks/supervisord/config_models/shared.py b/supervisord/datadog_checks/supervisord/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/supervisord/datadog_checks/supervisord/config_models/shared.py +++ b/supervisord/datadog_checks/supervisord/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/system_core/datadog_checks/system_core/config_models/instance.py b/system_core/datadog_checks/system_core/config_models/instance.py index 9fd87afb27b4bd..8b251986605c44 100644 --- a/system_core/datadog_checks/system_core/config_models/instance.py +++ b/system_core/datadog_checks/system_core/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -37,32 +39,21 @@ class InstanceConfig(BaseModel): metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/system_core/datadog_checks/system_core/config_models/shared.py b/system_core/datadog_checks/system_core/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/system_core/datadog_checks/system_core/config_models/shared.py +++ b/system_core/datadog_checks/system_core/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/system_swap/datadog_checks/system_swap/config_models/instance.py b/system_swap/datadog_checks/system_swap/config_models/instance.py index 9fd87afb27b4bd..8b251986605c44 100644 --- a/system_swap/datadog_checks/system_swap/config_models/instance.py +++ b/system_swap/datadog_checks/system_swap/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -37,32 +39,21 @@ class InstanceConfig(BaseModel): metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/system_swap/datadog_checks/system_swap/config_models/shared.py b/system_swap/datadog_checks/system_swap/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/system_swap/datadog_checks/system_swap/config_models/shared.py +++ b/system_swap/datadog_checks/system_swap/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/tcp_check/datadog_checks/tcp_check/config_models/instance.py b/tcp_check/datadog_checks/tcp_check/config_models/instance.py index e2a8ae99e2c472..b8c0c7e33d028b 100644 --- a/tcp_check/datadog_checks/tcp_check/config_models/instance.py +++ b/tcp_check/datadog_checks/tcp_check/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_response_time: Optional[bool] = None @@ -44,7 +46,7 @@ class InstanceConfig(BaseModel): name: str port: int service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None @model_validator(mode='before') @@ -52,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/tcp_check/datadog_checks/tcp_check/config_models/shared.py b/tcp_check/datadog_checks/tcp_check/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/tcp_check/datadog_checks/tcp_check/config_models/shared.py +++ b/tcp_check/datadog_checks/tcp_check/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/teamcity/datadog_checks/teamcity/config_models/instance.py b/teamcity/datadog_checks/teamcity/config_models/instance.py index 924b244acb9c74..9561b0e135fa8f 100644 --- a/teamcity/datadog_checks/teamcity/config_models/instance.py +++ b/teamcity/datadog_checks/teamcity/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,14 +41,16 @@ class ExtraMetric(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -55,42 +60,47 @@ class Metric(BaseModel): class IncludeItem(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None limit: Optional[int] = 5 class Projects(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[IncludeItem]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[IncludeItem, ...]] = None class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -113,21 +123,21 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = 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 experimental_metrics: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - global_build_configs_exclude: Optional[Sequence[str]] = None - global_build_configs_include: Optional[Sequence[str]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + extra_metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, ExtraMetric]]], ...]] = None + global_build_configs_exclude: Optional[tuple[str, ...]] = None + global_build_configs_include: Optional[tuple[str, ...]] = 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[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -137,7 +147,7 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -148,17 +158,17 @@ class InstanceConfig(BaseModel): projects: Optional[Projects] = None projects_refresh_interval: Optional[int] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None server: str service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None telemetry: Optional[bool] = None tests_health_check: Optional[bool] = None timeout: Optional[float] = None @@ -166,7 +176,7 @@ class InstanceConfig(BaseModel): tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[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 @@ -180,25 +190,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/teamcity/datadog_checks/teamcity/config_models/shared.py b/teamcity/datadog_checks/teamcity/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/teamcity/datadog_checks/teamcity/config_models/shared.py +++ b/teamcity/datadog_checks/teamcity/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/temporal/datadog_checks/temporal/config_models/instance.py b/temporal/datadog_checks/temporal/config_models/instance.py index 364568d359afaa..b78811820d5e5e 100644 --- a/temporal/datadog_checks/temporal/config_models/instance.py +++ b/temporal/datadog_checks/temporal/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,14 +41,16 @@ class ExtraMetric(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -55,24 +60,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -89,18 +97,18 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = 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[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -110,7 +118,7 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -119,23 +127,23 @@ class InstanceConfig(BaseModel): password: Optional[str] = None persist_connections: Optional[bool] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[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 @@ -148,25 +156,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/temporal/datadog_checks/temporal/config_models/shared.py b/temporal/datadog_checks/temporal/config_models/shared.py index 59c534d071001b..458a7003d92bbe 100644 --- a/temporal/datadog_checks/temporal/config_models/shared.py +++ b/temporal/datadog_checks/temporal/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/teradata/datadog_checks/teradata/config_models/instance.py b/teradata/datadog_checks/teradata/config_models/instance.py index 603c66a0857d00..8012d8c92a1c53 100644 --- a/teradata/datadog_checks/teradata/config_models/instance.py +++ b/teradata/datadog_checks/teradata/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator from typing_extensions import Literal @@ -22,32 +23,36 @@ class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - columns: Optional[Sequence[Mapping[str, Any]]] = None + columns: Optional[tuple[MappingProxyType[str, Any], ...]] = None query: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Table(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) account: Optional[str] = None @@ -55,7 +60,7 @@ class InstanceConfig(BaseModel): auth_mechanism: Optional[Literal['TD2', 'TDNEGO', 'LDAP', 'KRB5', 'JWT']] = None collect_res_usage_metrics: Optional[bool] = None collect_table_disk_metrics: Optional[bool] = None - custom_queries: Optional[Sequence[CustomQuery]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None database: str disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None @@ -69,8 +74,8 @@ class InstanceConfig(BaseModel): service: Optional[str] = None ssl_mode: Optional[Literal['Allow', 'Disable', 'Prefer', 'Require']] = None ssl_protocol: Optional[str] = None - tables: Optional[Union[Sequence[str], Table]] = None - tags: Optional[Sequence[str]] = None + tables: Optional[Union[tuple[str, ...], Table]] = None + tags: Optional[tuple[str, ...]] = None use_global_custom_queries: Optional[str] = None username: Optional[str] = None @@ -79,25 +84,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/teradata/datadog_checks/teradata/config_models/shared.py b/teradata/datadog_checks/teradata/config_models/shared.py index 505547fd024b3e..7db2588188044b 100644 --- a/teradata/datadog_checks/teradata/config_models/shared.py +++ b/teradata/datadog_checks/teradata/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,26 +23,23 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - global_custom_queries: Optional[Sequence[Mapping[str, Any]]] = None + global_custom_queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None 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('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/tls/datadog_checks/tls/config_models/instance.py b/tls/datadog_checks/tls/config_models/instance.py index 8020a455598d3c..7a57ff3caa56d7 100644 --- a/tls/datadog_checks/tls/config_models/instance.py +++ b/tls/datadog_checks/tls/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator from typing_extensions import Literal @@ -22,18 +22,20 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - allowed_versions: Optional[Sequence[str]] = None + allowed_versions: Optional[tuple[str, ...]] = None days_critical: Optional[float] = None days_warning: Optional[float] = None disable_generic_tags: Optional[bool] = None @@ -52,7 +54,7 @@ class InstanceConfig(BaseModel): server_hostname: Optional[str] = None service: Optional[str] = None start_tls: Optional[Literal['postgres', 'mysql']] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[int] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None @@ -67,25 +69,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/tls/datadog_checks/tls/config_models/shared.py b/tls/datadog_checks/tls/config_models/shared.py index b8e50175791f58..61ac754553862c 100644 --- a/tls/datadog_checks/tls/config_models/shared.py +++ b/tls/datadog_checks/tls/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,9 +22,10 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - allowed_versions: Optional[Sequence[str]] = None + allowed_versions: Optional[tuple[str, ...]] = None fetch_intermediate_certs: Optional[bool] = None service: Optional[str] = None @@ -33,25 +34,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/tomcat/datadog_checks/tomcat/config_models/instance.py b/tomcat/datadog_checks/tomcat/config_models/instance.py index 631a321dda3bb7..a07c63edd14368 100644 --- a/tomcat/datadog_checks/tomcat/config_models/instance.py +++ b/tomcat/datadog_checks/tomcat/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,6 +22,7 @@ class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_jvm_metrics: Optional[bool] = None @@ -42,7 +43,7 @@ class InstanceConfig(BaseModel): rmi_connection_timeout: Optional[float] = None rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tools_jar_path: Optional[str] = None trust_store_password: Optional[str] = None trust_store_path: Optional[str] = None @@ -53,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/tomcat/datadog_checks/tomcat/config_models/shared.py b/tomcat/datadog_checks/tomcat/config_models/shared.py index 0db55a6d064d5d..b8bb8146892a0f 100644 --- a/tomcat/datadog_checks/tomcat/config_models/shared.py +++ b/tomcat/datadog_checks/tomcat/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,10 +23,11 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: Optional[bool] = None - conf: Optional[Sequence[Mapping[str, Any]]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None is_jmx: bool new_gc_metrics: Optional[bool] = None service: Optional[str] = None @@ -36,25 +38,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/torchserve/datadog_checks/torchserve/config_models/instance.py b/torchserve/datadog_checks/torchserve/config_models/instance.py index 173a9700a8f927..32b018c6c8b328 100644 --- a/torchserve/datadog_checks/torchserve/config_models/instance.py +++ b/torchserve/datadog_checks/torchserve/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,14 +41,16 @@ class ExtraMetric(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -55,24 +60,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -89,20 +97,20 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude: Optional[Sequence[str]] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = None + exclude: Optional[tuple[str, ...]] = 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, ExtraMetric]]], ...]] = 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[Sequence[str]] = None - include: Optional[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = None + ignore_tags: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None + include_labels: Optional[tuple[str, ...]] = None inference_api_url: Optional[str] = None interval: Optional[int] = None kerberos_auth: Optional[str] = None @@ -116,7 +124,7 @@ class InstanceConfig(BaseModel): log_requests: Optional[bool] = None management_api_url: Optional[str] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -125,24 +133,24 @@ class InstanceConfig(BaseModel): password: Optional[str] = None persist_connections: Optional[bool] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None submit_events: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[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 @@ -155,25 +163,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/torchserve/datadog_checks/torchserve/config_models/shared.py b/torchserve/datadog_checks/torchserve/config_models/shared.py index 59c534d071001b..458a7003d92bbe 100644 --- a/torchserve/datadog_checks/torchserve/config_models/shared.py +++ b/torchserve/datadog_checks/torchserve/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/traffic_server/datadog_checks/traffic_server/config_models/instance.py b/traffic_server/datadog_checks/traffic_server/config_models/instance.py index ba7171e7584f0e..3b2bc40503c538 100644 --- a/traffic_server/datadog_checks/traffic_server/config_models/instance.py +++ b/traffic_server/datadog_checks/traffic_server/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -78,13 +83,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None traffic_server_url: str @@ -96,25 +101,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/traffic_server/datadog_checks/traffic_server/config_models/shared.py b/traffic_server/datadog_checks/traffic_server/config_models/shared.py index d7f4dd28de4784..1a8081d40b0c4a 100644 --- a/traffic_server/datadog_checks/traffic_server/config_models/shared.py +++ b/traffic_server/datadog_checks/traffic_server/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/twemproxy/datadog_checks/twemproxy/config_models/instance.py b/twemproxy/datadog_checks/twemproxy/config_models/instance.py index 3dc6609fbfe2a5..2d64ade8845a95 100644 --- a/twemproxy/datadog_checks/twemproxy/config_models/instance.py +++ b/twemproxy/datadog_checks/twemproxy/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -39,32 +41,21 @@ class InstanceConfig(BaseModel): min_collection_interval: Optional[float] = None port: int service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[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 _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/twemproxy/datadog_checks/twemproxy/config_models/shared.py b/twemproxy/datadog_checks/twemproxy/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/twemproxy/datadog_checks/twemproxy/config_models/shared.py +++ b/twemproxy/datadog_checks/twemproxy/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/twistlock/datadog_checks/twistlock/config_models/instance.py b/twistlock/datadog_checks/twistlock/config_models/instance.py index 7694701addcd60..027224ea0341bd 100644 --- a/twistlock/datadog_checks/twistlock/config_models/instance.py +++ b/twistlock/datadog_checks/twistlock/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,32 +22,36 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -58,8 +63,8 @@ class InstanceConfig(BaseModel): connect_timeout: Optional[float] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -79,13 +84,13 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None url: str @@ -97,25 +102,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/twistlock/datadog_checks/twistlock/config_models/shared.py b/twistlock/datadog_checks/twistlock/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/twistlock/datadog_checks/twistlock/config_models/shared.py +++ b/twistlock/datadog_checks/twistlock/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/varnish/datadog_checks/varnish/config_models/instance.py b/varnish/datadog_checks/varnish/config_models/instance.py index b5c4b5be065282..e49a34aea5ea3b 100644 --- a/varnish/datadog_checks/varnish/config_models/instance.py +++ b/varnish/datadog_checks/varnish/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) daemon_host: Optional[str] = None @@ -37,12 +39,12 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics_filter: Optional[Sequence[str]] = None + metrics_filter: Optional[tuple[str, ...]] = None min_collection_interval: Optional[float] = None name: Optional[str] = None secretfile: Optional[str] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None varnishadm: Optional[str] = None varnishstat: str @@ -51,25 +53,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/varnish/datadog_checks/varnish/config_models/shared.py b/varnish/datadog_checks/varnish/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/varnish/datadog_checks/varnish/config_models/shared.py +++ b/varnish/datadog_checks/varnish/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/vault/datadog_checks/vault/config_models/instance.py b/vault/datadog_checks/vault/config_models/instance.py index 723f4c3a0c09e3..1de4c8e19e8a95 100644 --- a/vault/datadog_checks/vault/config_models/instance.py +++ b/vault/datadog_checks/vault/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,14 +41,16 @@ class ExtraMetric(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -55,24 +60,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -94,18 +102,18 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = 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[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -115,7 +123,7 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') no_token: Optional[bool] = None @@ -125,23 +133,23 @@ class InstanceConfig(BaseModel): password: Optional[str] = None persist_connections: Optional[bool] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[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 @@ -155,25 +163,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/vault/datadog_checks/vault/config_models/shared.py b/vault/datadog_checks/vault/config_models/shared.py index fa44821e002afa..1a02ea86a818b6 100644 --- a/vault/datadog_checks/vault/config_models/shared.py +++ b/vault/datadog_checks/vault/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/vertica/datadog_checks/vertica/config_models/instance.py b/vertica/datadog_checks/vertica/config_models/instance.py index 5ff3252ebf90e0..2baac499009d72 100644 --- a/vertica/datadog_checks/vertica/config_models/instance.py +++ b/vertica/datadog_checks/vertica/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,34 +22,37 @@ class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - columns: Optional[Sequence[Mapping[str, Any]]] = None + columns: Optional[tuple[MappingProxyType[str, Any], ...]] = None query: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - backup_servers: Optional[Sequence[Mapping[str, Any]]] = None + backup_servers: Optional[tuple[MappingProxyType[str, Any], ...]] = None client_lib_log_level: Optional[str] = None connection_load_balance: Optional[bool] = None - custom_queries: Optional[Sequence[CustomQuery]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None db: Optional[str] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - metric_groups: Optional[Sequence[str]] = None + metric_groups: Optional[tuple[str, ...]] = None metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None only_custom_queries: Optional[bool] = None @@ -56,7 +60,7 @@ class InstanceConfig(BaseModel): port: Optional[int] = None server: Optional[str] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[int] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None @@ -73,25 +77,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/vertica/datadog_checks/vertica/config_models/shared.py b/vertica/datadog_checks/vertica/config_models/shared.py index 45d1293f12b20f..8a1218b18c7641 100644 --- a/vertica/datadog_checks/vertica/config_models/shared.py +++ b/vertica/datadog_checks/vertica/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,26 +23,23 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - global_custom_queries: Optional[Sequence[Mapping[str, Any]]] = None + global_custom_queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None 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('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/voltdb/datadog_checks/voltdb/config_models/instance.py b/voltdb/datadog_checks/voltdb/config_models/instance.py index c8f00330406fb3..3f9bff6b683200 100644 --- a/voltdb/datadog_checks/voltdb/config_models/instance.py +++ b/voltdb/datadog_checks/voltdb/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,41 +22,46 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class CustomQuery(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - columns: Optional[Sequence[Mapping[str, Any]]] = None + columns: Optional[tuple[MappingProxyType[str, Any], ...]] = None query: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -65,11 +71,11 @@ class InstanceConfig(BaseModel): aws_region: Optional[str] = None aws_service: Optional[str] = None connect_timeout: Optional[float] = None - custom_queries: Optional[Sequence[CustomQuery]] = None + custom_queries: Optional[tuple[CustomQuery, ...]] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -90,14 +96,14 @@ class InstanceConfig(BaseModel): request_size: Optional[float] = None service: Optional[str] = None skip_proxy: Optional[bool] = None - statistics_components: Optional[Sequence[str]] = None - tags: Optional[Sequence[str]] = None + statistics_components: Optional[tuple[str, ...]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None url: str @@ -110,25 +116,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/voltdb/datadog_checks/voltdb/config_models/shared.py b/voltdb/datadog_checks/voltdb/config_models/shared.py index 175a57ff6454f8..2f0f34925dbefb 100644 --- a/voltdb/datadog_checks/voltdb/config_models/shared.py +++ b/voltdb/datadog_checks/voltdb/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,19 +22,21 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) - global_custom_queries: Optional[Sequence[Mapping[str, Any]]] = None + global_custom_queries: Optional[tuple[MappingProxyType[str, Any], ...]] = None proxy: Optional[Proxy] = None service: Optional[str] = None skip_proxy: Optional[bool] = None @@ -44,25 +47,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/vsphere/datadog_checks/vsphere/config_models/instance.py b/vsphere/datadog_checks/vsphere/config_models/instance.py index 0dd11a12559349..7d888fa6ca1b38 100644 --- a/vsphere/datadog_checks/vsphere/config_models/instance.py +++ b/vsphere/datadog_checks/vsphere/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,38 +22,42 @@ class CollectPerInstanceFilters(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - cluster: Optional[Sequence[str]] = None - datastore: Optional[Sequence[str]] = None - host: Optional[Sequence[str]] = None - vm: Optional[Sequence[str]] = None + cluster: Optional[tuple[str, ...]] = None + datastore: Optional[tuple[str, ...]] = None + host: Optional[tuple[str, ...]] = None + vm: Optional[tuple[str, ...]] = None class MetricFilters(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - cluster: Optional[Sequence[str]] = None - datacenter: Optional[Sequence[str]] = None - datastore: Optional[Sequence[str]] = None - host: Optional[Sequence[str]] = None - vm: Optional[Sequence[str]] = None + cluster: Optional[tuple[str, ...]] = None + datacenter: Optional[tuple[str, ...]] = None + datastore: Optional[tuple[str, ...]] = None + host: Optional[tuple[str, ...]] = None + vm: Optional[tuple[str, ...]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class ResourceFilter(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - patterns: Optional[Sequence[str]] = None + patterns: Optional[tuple[str, ...]] = None property: Optional[str] = None resource: Optional[str] = None type: Optional[str] = None @@ -60,23 +65,26 @@ class ResourceFilter(BaseModel): class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class RestApiOptions(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None @@ -86,8 +94,8 @@ class RestApiOptions(BaseModel): aws_region: Optional[str] = None aws_service: Optional[str] = None connect_timeout: Optional[float] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -108,7 +116,7 @@ class RestApiOptions(BaseModel): tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -118,6 +126,7 @@ class RestApiOptions(BaseModel): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) attributes_prefix: Optional[str] = None @@ -133,7 +142,7 @@ class InstanceConfig(BaseModel): connection_reset_timeout: Optional[int] = None disable_generic_tags: Optional[bool] = None empty_default_hostname: bool - excluded_host_tags: Optional[Sequence[str]] = None + excluded_host_tags: Optional[tuple[str, ...]] = None host: str include_datastore_cluster_folder_tag: Optional[bool] = None max_historical_metrics: Optional[int] = None @@ -144,12 +153,12 @@ class InstanceConfig(BaseModel): password: str refresh_infrastructure_cache_interval: Optional[int] = None refresh_metrics_metadata_cache_interval: Optional[int] = None - resource_filters: Optional[Sequence[ResourceFilter]] = None + resource_filters: Optional[tuple[ResourceFilter, ...]] = None rest_api_options: Optional[RestApiOptions] = None service: Optional[str] = None ssl_capath: Optional[str] = None ssl_verify: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tags_prefix: Optional[str] = None threads_count: Optional[int] = None tls_ignore_warning: Optional[bool] = None @@ -164,25 +173,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/vsphere/datadog_checks/vsphere/config_models/shared.py b/vsphere/datadog_checks/vsphere/config_models/shared.py index f87d2a23237cd9..5c68b1cce2f749 100644 --- a/vsphere/datadog_checks/vsphere/config_models/shared.py +++ b/vsphere/datadog_checks/vsphere/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class RestApiOptions(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -40,6 +42,7 @@ class RestApiOptions(BaseModel): class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) rest_api_options: Optional[RestApiOptions] = None @@ -49,17 +52,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/weaviate/datadog_checks/weaviate/config_models/instance.py b/weaviate/datadog_checks/weaviate/config_models/instance.py index ea66679c7482e7..ad77c9348d0a27 100644 --- a/weaviate/datadog_checks/weaviate/config_models/instance.py +++ b/weaviate/datadog_checks/weaviate/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,14 +22,16 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class ExtraMetric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -38,14 +41,16 @@ class ExtraMetric(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metric(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -55,24 +60,27 @@ class Metric(BaseModel): class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class ShareLabel(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - labels: Optional[Sequence[str]] = None - match: Optional[Sequence[str]] = None + 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 @@ -89,18 +97,18 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - exclude_labels: Optional[Sequence[str]] = None - exclude_metrics: Optional[Sequence[str]] = None - exclude_metrics_by_labels: Optional[Mapping[str, Union[bool, Sequence[str]]]] = None - extra_headers: Optional[Mapping[str, Any]] = None - extra_metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, ExtraMetric]]]]] = None - headers: Optional[Mapping[str, Any]] = 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, ExtraMetric]]], ...]] = 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[Sequence[str]] = None - include_labels: Optional[Sequence[str]] = 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 @@ -110,7 +118,7 @@ class InstanceConfig(BaseModel): kerberos_principal: Optional[str] = None log_requests: Optional[bool] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Optional[Sequence[Union[str, Mapping[str, Union[str, Metric]]]]] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metric]]], ...]] = None min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') non_cumulative_histogram_buckets: Optional[bool] = None @@ -119,23 +127,23 @@ class InstanceConfig(BaseModel): password: Optional[str] = None persist_connections: Optional[bool] = None proxy: Optional[Proxy] = None - raw_line_filters: Optional[Sequence[str]] = None + raw_line_filters: Optional[tuple[str, ...]] = None raw_metric_prefix: Optional[str] = None read_timeout: Optional[float] = None - rename_labels: Optional[Mapping[str, Any]] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None request_size: Optional[float] = None service: Optional[str] = None - share_labels: Optional[Mapping[str, Union[bool, ShareLabel]]] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabel]]] = None skip_proxy: Optional[bool] = None tag_by_endpoint: Optional[bool] = None - tags: Optional[Sequence[str]] = 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_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[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 @@ -149,25 +157,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/weaviate/datadog_checks/weaviate/config_models/shared.py b/weaviate/datadog_checks/weaviate/config_models/shared.py index 59c534d071001b..458a7003d92bbe 100644 --- a/weaviate/datadog_checks/weaviate/config_models/shared.py +++ b/weaviate/datadog_checks/weaviate/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,16 +21,18 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) proxy: Optional[Proxy] = None @@ -43,25 +45,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/weblogic/datadog_checks/weblogic/config_models/instance.py b/weblogic/datadog_checks/weblogic/config_models/instance.py index 631a321dda3bb7..a07c63edd14368 100644 --- a/weblogic/datadog_checks/weblogic/config_models/instance.py +++ b/weblogic/datadog_checks/weblogic/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,6 +22,7 @@ class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_jvm_metrics: Optional[bool] = None @@ -42,7 +43,7 @@ class InstanceConfig(BaseModel): rmi_connection_timeout: Optional[float] = None rmi_registry_ssl: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None tools_jar_path: Optional[str] = None trust_store_password: Optional[str] = None trust_store_path: Optional[str] = None @@ -53,25 +54,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/weblogic/datadog_checks/weblogic/config_models/shared.py b/weblogic/datadog_checks/weblogic/config_models/shared.py index 0db55a6d064d5d..b8bb8146892a0f 100644 --- a/weblogic/datadog_checks/weblogic/config_models/shared.py +++ b/weblogic/datadog_checks/weblogic/config_models/shared.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -22,10 +23,11 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_default_metrics: Optional[bool] = None - conf: Optional[Sequence[Mapping[str, Any]]] = None + conf: Optional[tuple[MappingProxyType[str, Any], ...]] = None is_jmx: bool new_gc_metrics: Optional[bool] = None service: Optional[str] = None @@ -36,25 +38,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/win32_event_log/datadog_checks/win32_event_log/config_models/instance.py b/win32_event_log/datadog_checks/win32_event_log/config_models/instance.py index 1c13248580c2fd..b2988b39bdaf14 100644 --- a/win32_event_log/datadog_checks/win32_event_log/config_models/instance.py +++ b/win32_event_log/datadog_checks/win32_event_log/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator from typing_extensions import Literal @@ -22,26 +22,39 @@ class Filters(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - id: Optional[Sequence[int]] = None - source: Optional[Sequence[str]] = None + id: Optional[tuple[int, ...]] = None + source: Optional[tuple[str, ...]] = None type: Optional[ - Sequence[Literal['success', 'error', 'warning', 'information', 'success audit', 'failure audit']] + tuple[ + Literal[ + 'success', + 'error', + 'warning', + 'information', + 'success audit', + 'failure audit', + ], + ..., + ] ] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) auth_type: Optional[Literal['default', 'negotiate', 'kerberos', 'ntlm']] = None @@ -49,17 +62,17 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None domain: Optional[str] = None empty_default_hostname: Optional[bool] = None - event_format: Optional[Sequence[str]] = None - event_id: Optional[Sequence[str]] = None + event_format: Optional[tuple[str, ...]] = None + event_id: Optional[tuple[str, ...]] = None event_priority: Optional[Literal['normal', 'low']] = None - excluded_messages: Optional[Sequence[str]] = None + excluded_messages: Optional[tuple[str, ...]] = None filters: Optional[Filters] = None host: Optional[str] = None - included_messages: Optional[Sequence[str]] = None + included_messages: Optional[tuple[str, ...]] = None interpret_messages: Optional[bool] = None legacy_mode: Optional[bool] = None - log_file: Optional[Sequence[str]] = None - message_filters: Optional[Sequence[str]] = None + log_file: Optional[tuple[str, ...]] = None + message_filters: Optional[tuple[str, ...]] = None metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None password: Optional[str] = None @@ -68,41 +81,36 @@ class InstanceConfig(BaseModel): query: Optional[str] = None server: Optional[str] = None service: Optional[str] = None - source_name: Optional[Sequence[str]] = None + source_name: Optional[tuple[str, ...]] = None start: Optional[Literal['now', 'oldest']] = None tag_event_id: Optional[bool] = None tag_sid: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None - type: Optional[Sequence[str]] = None + type: Optional[tuple[str, ...]] = None user: Optional[str] = None @model_validator(mode='before') def _initial_validation(cls, values): - return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) + return validation.core.initialize_config( + getattr(validators, 'initialize_instance', identity)(values) + ) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)( + value, field=field + ) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, 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)) + return validation.core.check_model( + getattr(validators, 'check_instance', identity)(model) + ) diff --git a/win32_event_log/datadog_checks/win32_event_log/config_models/shared.py b/win32_event_log/datadog_checks/win32_event_log/config_models/shared.py index f9bffdbac04367..b478ae61c105a3 100644 --- a/win32_event_log/datadog_checks/win32_event_log/config_models/shared.py +++ b/win32_event_log/datadog_checks/win32_event_log/config_models/shared.py @@ -23,6 +23,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) default_event_priority: Optional[str] = None @@ -37,25 +38,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/windows_performance_counters/datadog_checks/windows_performance_counters/config_models/instance.py b/windows_performance_counters/datadog_checks/windows_performance_counters/config_models/instance.py index 45a72e9e57bdb1..e7792af9245501 100644 --- a/windows_performance_counters/datadog_checks/windows_performance_counters/config_models/instance.py +++ b/windows_performance_counters/datadog_checks/windows_performance_counters/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Optional, Union from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from typing_extensions import Literal @@ -22,6 +23,7 @@ class Counter(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, extra='allow', frozen=True, ) @@ -34,6 +36,7 @@ class Counter(BaseModel): class InstanceCounts(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) monitored: Optional[str] = None @@ -43,11 +46,12 @@ class InstanceCounts(BaseModel): class ExtraMetrics(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - counters: Sequence[Mapping[str, Union[str, Counter]]] - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + counters: tuple[MappingProxyType[str, Union[str, Counter]], ...] + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None instance_counts: Optional[InstanceCounts] = None name: str tag_name: Optional[str] = None @@ -56,19 +60,21 @@ class ExtraMetrics(BaseModel): class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class Metrics(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - counters: Sequence[Mapping[str, Union[str, Counter]]] - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + counters: tuple[MappingProxyType[str, Union[str, Counter]], ...] + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None instance_counts: Optional[InstanceCounts] = None name: str tag_name: Optional[str] = None @@ -78,21 +84,22 @@ class Metrics(BaseModel): class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None enable_health_service_check: Optional[bool] = None - extra_metrics: Optional[Mapping[str, ExtraMetrics]] = None + extra_metrics: Optional[MappingProxyType[str, ExtraMetrics]] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Mapping[str, Metrics] + metrics: MappingProxyType[str, Metrics] min_collection_interval: Optional[float] = None namespace: Optional[str] = Field(None, pattern='\\w*') password: Optional[str] = None server: Optional[str] = None server_tag: Optional[str] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None use_legacy_check_version: Optional[bool] = None username: Optional[str] = None @@ -101,25 +108,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/windows_performance_counters/datadog_checks/windows_performance_counters/config_models/shared.py b/windows_performance_counters/datadog_checks/windows_performance_counters/config_models/shared.py index aa58639466c054..94b02c19dbbb69 100644 --- a/windows_performance_counters/datadog_checks/windows_performance_counters/config_models/shared.py +++ b/windows_performance_counters/datadog_checks/windows_performance_counters/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -32,25 +33,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/windows_service/datadog_checks/windows_service/config_models/instance.py b/windows_service/datadog_checks/windows_service/config_models/instance.py index 704d28d35a1e20..55de174948edff 100644 --- a/windows_service/datadog_checks/windows_service/config_models/instance.py +++ b/windows_service/datadog_checks/windows_service/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence, Union +from types import MappingProxyType +from typing import Any, Optional, Union from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +22,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -38,8 +41,8 @@ class InstanceConfig(BaseModel): metric_patterns: Optional[MetricPatterns] = None min_collection_interval: Optional[float] = None service: Optional[str] = None - services: Sequence[Union[str, Mapping[str, Any]]] - tags: Optional[Sequence[str]] = None + services: tuple[Union[str, MappingProxyType[str, Any]], ...] + tags: Optional[tuple[str, ...]] = None windows_service_startup_type_tag: Optional[bool] = None @model_validator(mode='before') @@ -47,25 +50,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/windows_service/datadog_checks/windows_service/config_models/shared.py b/windows_service/datadog_checks/windows_service/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/windows_service/datadog_checks/windows_service/config_models/shared.py +++ b/windows_service/datadog_checks/windows_service/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/wmi_check/datadog_checks/wmi_check/config_models/instance.py b/wmi_check/datadog_checks/wmi_check/config_models/instance.py index 7f208ac9d3c4bf..047d3452619c96 100644 --- a/wmi_check/datadog_checks/wmi_check/config_models/instance.py +++ b/wmi_check/datadog_checks/wmi_check/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator @@ -21,32 +22,34 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) class_: str = Field(..., alias='class') disable_generic_tags: Optional[bool] = None empty_default_hostname: Optional[bool] = None - filters: Optional[Sequence[Mapping[str, Any]]] = None + filters: Optional[tuple[MappingProxyType[str, Any], ...]] = None host: Optional[str] = None metric_patterns: Optional[MetricPatterns] = None - metrics: Sequence[Sequence[str]] + metrics: tuple[tuple[str, ...], ...] min_collection_interval: Optional[float] = None namespace: Optional[str] = None password: Optional[str] = None provider: Optional[int] = None service: Optional[str] = None tag_by: Optional[str] = None - tag_queries: Optional[Sequence[Sequence[str]]] = None - tags: Optional[Sequence[str]] = None + tag_queries: Optional[tuple[tuple[str, ...], ...]] = None + tags: Optional[tuple[str, ...]] = None username: Optional[str] = None @model_validator(mode='before') @@ -54,25 +57,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/wmi_check/datadog_checks/wmi_check/config_models/shared.py b/wmi_check/datadog_checks/wmi_check/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/wmi_check/datadog_checks/wmi_check/config_models/shared.py +++ b/wmi_check/datadog_checks/wmi_check/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/yarn/datadog_checks/yarn/config_models/instance.py b/yarn/datadog_checks/yarn/config_models/instance.py index b45568e8f08441..fe9372c4f4c1a8 100644 --- a/yarn/datadog_checks/yarn/config_models/instance.py +++ b/yarn/datadog_checks/yarn/config_models/instance.py @@ -9,7 +9,8 @@ from __future__ import annotations -from typing import Any, Mapping, Optional, Sequence +from types import MappingProxyType +from typing import Any, Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator from typing_extensions import Literal @@ -22,37 +23,41 @@ class AuthToken(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - reader: Optional[Mapping[str, Any]] = None - writer: Optional[Mapping[str, Any]] = None + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[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[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) allow_redirects: Optional[bool] = None - application_status_mapping: Optional[Mapping[str, Any]] = None - application_tags: Optional[Mapping[str, Any]] = None + application_status_mapping: Optional[MappingProxyType[str, Any]] = None + application_tags: Optional[MappingProxyType[str, Any]] = None auth_token: Optional[AuthToken] = None auth_type: Optional[str] = None aws_host: Optional[str] = None @@ -62,8 +67,19 @@ class InstanceConfig(BaseModel): collect_app_metrics: Optional[bool] = None collect_apps_all_states: Optional[bool] = None collect_apps_states_list: Optional[ - Sequence[ - Literal['ALL', 'NEW', 'NEW_SAVING', 'SUBMITTED', 'ACCEPTED', 'RUNNING', 'FINISHED', 'FAILED', 'KILLED'] + tuple[ + Literal[ + 'ALL', + 'NEW', + 'NEW_SAVING', + 'SUBMITTED', + 'ACCEPTED', + 'RUNNING', + 'FINISHED', + 'FAILED', + 'KILLED', + ], + ..., ] ] = None collect_node_metrics: Optional[bool] = None @@ -71,8 +87,8 @@ class InstanceConfig(BaseModel): disable_generic_tags: Optional[bool] = None disable_legacy_cluster_tag: Optional[bool] = None empty_default_hostname: Optional[bool] = None - extra_headers: Optional[Mapping[str, Any]] = None - headers: Optional[Mapping[str, Any]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + headers: Optional[MappingProxyType[str, Any]] = None kerberos_auth: Optional[str] = None kerberos_cache: Optional[str] = None kerberos_delegate: Optional[bool] = None @@ -87,20 +103,20 @@ class InstanceConfig(BaseModel): password: Optional[str] = None persist_connections: Optional[bool] = None proxy: Optional[Proxy] = None - queue_blacklist: Optional[Sequence[str]] = None + queue_blacklist: Optional[tuple[str, ...]] = None read_timeout: Optional[float] = None request_size: Optional[float] = None resourcemanager_uri: Optional[str] = None service: Optional[str] = None skip_proxy: Optional[bool] = None split_yarn_application_tags: Optional[bool] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[float] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None tls_ignore_warning: Optional[bool] = None tls_private_key: Optional[str] = None - tls_protocols_allowed: Optional[Sequence[str]] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None tls_use_host_header: Optional[bool] = None tls_verify: Optional[bool] = None use_legacy_auth_encoding: Optional[bool] = None @@ -108,30 +124,25 @@ class InstanceConfig(BaseModel): @model_validator(mode='before') def _initial_validation(cls, values): - return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) + return validation.core.initialize_config( + getattr(validators, 'initialize_instance', identity)(values) + ) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)( + value, field=field + ) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, 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)) + return validation.core.check_model( + getattr(validators, 'check_instance', identity)(model) + ) diff --git a/yarn/datadog_checks/yarn/config_models/shared.py b/yarn/datadog_checks/yarn/config_models/shared.py index f7577f84507f0c..35c58894e558a5 100644 --- a/yarn/datadog_checks/yarn/config_models/shared.py +++ b/yarn/datadog_checks/yarn/config_models/shared.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator from typing_extensions import Literal @@ -22,22 +22,35 @@ class Proxy(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) http: Optional[str] = None https: Optional[str] = None - no_proxy: Optional[Sequence[str]] = None + no_proxy: Optional[tuple[str, ...]] = None class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) collect_apps_all_states: Optional[bool] = None collect_apps_states_list: Optional[ - Sequence[ - Literal['ALL', 'NEW', 'NEW_SAVING', 'SUBMITTED', 'ACCEPTED', 'RUNNING', 'FINISHED', 'FAILED', 'KILLED'] + tuple[ + Literal[ + 'ALL', + 'NEW', + 'NEW_SAVING', + 'SUBMITTED', + 'ACCEPTED', + 'RUNNING', + 'FINISHED', + 'FAILED', + 'KILLED', + ], + ..., ] ] = None proxy: Optional[Proxy] = None @@ -47,30 +60,25 @@ class SharedConfig(BaseModel): @model_validator(mode='before') def _initial_validation(cls, values): - return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) + return validation.core.initialize_config( + getattr(validators, 'initialize_shared', identity)(values) + ) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'shared_{info.field_name}', identity)( + value, field=field + ) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() - return getattr(defaults, f'shared_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): 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)) + return validation.core.check_model( + getattr(validators, 'check_shared', identity)(model) + ) diff --git a/zk/datadog_checks/zk/config_models/instance.py b/zk/datadog_checks/zk/config_models/instance.py index ee76eaa0406285..906392adc539f9 100644 --- a/zk/datadog_checks/zk/config_models/instance.py +++ b/zk/datadog_checks/zk/config_models/instance.py @@ -9,7 +9,7 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import Optional from pydantic import BaseModel, ConfigDict, field_validator, model_validator @@ -21,15 +21,17 @@ class MetricPatterns(BaseModel): model_config = ConfigDict( + arbitrary_types_allowed=True, frozen=True, ) - exclude: Optional[Sequence[str]] = None - include: Optional[Sequence[str]] = None + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None class InstanceConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) disable_generic_tags: Optional[bool] = None @@ -41,7 +43,7 @@ class InstanceConfig(BaseModel): port: Optional[int] = None report_instance_mode: Optional[bool] = None service: Optional[str] = None - tags: Optional[Sequence[str]] = None + tags: Optional[tuple[str, ...]] = None timeout: Optional[int] = None tls_ca_cert: Optional[str] = None tls_cert: Optional[str] = None @@ -56,25 +58,14 @@ def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) @field_validator('*', mode='before') - def _ensure_defaults(cls, value, info): + 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']: - return value + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() - return getattr(defaults, f'instance_{info.field_name}', lambda: value)() - - @field_validator('*') - def _run_validations(cls, value, info): - field = cls.model_fields[info.field_name] - field_name = field.alias or info.field_name - if field_name not in info.context['configured_fields']: - return value - - return getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after') diff --git a/zk/datadog_checks/zk/config_models/shared.py b/zk/datadog_checks/zk/config_models/shared.py index 9de2608b18ec15..a6d823f3783cd4 100644 --- a/zk/datadog_checks/zk/config_models/shared.py +++ b/zk/datadog_checks/zk/config_models/shared.py @@ -22,6 +22,7 @@ class SharedConfig(BaseModel): model_config = ConfigDict( validate_default=True, + arbitrary_types_allowed=True, frozen=True, ) service: Optional[str] = None @@ -30,17 +31,13 @@ class SharedConfig(BaseModel): def _initial_validation(cls, values): return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) - @field_validator('*') - def _run_validations(cls, value, info): + @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 not in info.context['configured_fields']: - return value + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - return getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) - - @field_validator('*', mode='after') - def _make_immutable(cls, value): return validation.utils.make_immutable(value) @model_validator(mode='after')