From 5d949a622a81db41359859fb0f0eed8ee3646b50 Mon Sep 17 00:00:00 2001 From: Ofek Lev Date: Wed, 29 Sep 2021 16:56:59 -0400 Subject: [PATCH] Add runtime configuration validation (#8983) * Sync config models * re-sync * sync config models * see https://github.com/DataDog/integrations-core/pull/9750 Co-authored-by: Fanny Jiang --- .../snowflake/config_models/__init__.py | 18 ++++ .../snowflake/config_models/defaults.py | 96 +++++++++++++++++++ .../snowflake/config_models/instance.py | 71 ++++++++++++++ .../snowflake/config_models/shared.py | 47 +++++++++ .../snowflake/config_models/validators.py | 11 +++ 5 files changed, 243 insertions(+) create mode 100644 snowflake/datadog_checks/snowflake/config_models/__init__.py create mode 100644 snowflake/datadog_checks/snowflake/config_models/defaults.py create mode 100644 snowflake/datadog_checks/snowflake/config_models/instance.py create mode 100644 snowflake/datadog_checks/snowflake/config_models/shared.py create mode 100644 snowflake/datadog_checks/snowflake/config_models/validators.py diff --git a/snowflake/datadog_checks/snowflake/config_models/__init__.py b/snowflake/datadog_checks/snowflake/config_models/__init__.py new file mode 100644 index 0000000000000..ba42dbdc7ffb0 --- /dev/null +++ b/snowflake/datadog_checks/snowflake/config_models/__init__.py @@ -0,0 +1,18 @@ +# (C) Datadog, Inc. 2021-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +from .instance import InstanceConfig +from .shared import SharedConfig + + +class ConfigMixin: + _config_model_instance: InstanceConfig + _config_model_shared: SharedConfig + + @property + def config(self) -> InstanceConfig: + return self._config_model_instance + + @property + def shared_config(self) -> SharedConfig: + return self._config_model_shared diff --git a/snowflake/datadog_checks/snowflake/config_models/defaults.py b/snowflake/datadog_checks/snowflake/config_models/defaults.py new file mode 100644 index 0000000000000..23f4393efb786 --- /dev/null +++ b/snowflake/datadog_checks/snowflake/config_models/defaults.py @@ -0,0 +1,96 @@ +# (C) Datadog, Inc. 2021-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +from datadog_checks.base.utils.models.fields import get_default_field_value + + +def shared_global_custom_queries(field, value): + return get_default_field_value(field, value) + + +def shared_proxy_host(field, value): + return get_default_field_value(field, value) + + +def shared_proxy_password(field, value): + return get_default_field_value(field, value) + + +def shared_proxy_port(field, value): + return get_default_field_value(field, value) + + +def shared_proxy_user(field, value): + return get_default_field_value(field, value) + + +def shared_service(field, value): + return get_default_field_value(field, value) + + +def instance_authenticator(field, value): + return 'snowflake' + + +def instance_client_prefetch_threads(field, value): + return 4 + + +def instance_client_session_keep_alive(field, value): + return False + + +def instance_custom_queries(field, value): + return get_default_field_value(field, value) + + +def instance_database(field, value): + return 'SNOWFLAKE' + + +def instance_disable_generic_tags(field, value): + return False + + +def instance_empty_default_hostname(field, value): + return False + + +def instance_login_timeout(field, value): + return 60 + + +def instance_metric_groups(field, value): + return get_default_field_value(field, value) + + +def instance_min_collection_interval(field, value): + return 3600 + + +def instance_ocsp_response_cache_filename(field, value): + return get_default_field_value(field, value) + + +def instance_schema(field, value): + return 'ACCOUNT_USAGE' + + +def instance_service(field, value): + return get_default_field_value(field, value) + + +def instance_tags(field, value): + return get_default_field_value(field, value) + + +def instance_token(field, value): + return get_default_field_value(field, value) + + +def instance_use_global_custom_queries(field, value): + return 'true' + + +def instance_warehouse(field, value): + return get_default_field_value(field, value) diff --git a/snowflake/datadog_checks/snowflake/config_models/instance.py b/snowflake/datadog_checks/snowflake/config_models/instance.py new file mode 100644 index 0000000000000..038235c273b00 --- /dev/null +++ b/snowflake/datadog_checks/snowflake/config_models/instance.py @@ -0,0 +1,71 @@ +# (C) Datadog, Inc. 2021-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +from __future__ import annotations + +from typing import Any, Mapping, Optional, Sequence + +from pydantic import BaseModel, Field, root_validator, validator + +from datadog_checks.base.utils.functions import identity +from datadog_checks.base.utils.models import validation + +from . import defaults, validators + + +class CustomQuery(BaseModel): + class Config: + allow_mutation = False + + columns: Optional[Sequence[Mapping[str, Any]]] + query: Optional[str] + tags: Optional[Sequence[str]] + + +class InstanceConfig(BaseModel): + class Config: + allow_mutation = False + + account: str + authenticator: Optional[str] + client_prefetch_threads: Optional[int] + client_session_keep_alive: Optional[bool] + custom_queries: Optional[Sequence[CustomQuery]] + database: Optional[str] + disable_generic_tags: Optional[bool] + empty_default_hostname: Optional[bool] + login_timeout: Optional[int] + metric_groups: Optional[Sequence[str]] + min_collection_interval: Optional[float] + ocsp_response_cache_filename: Optional[str] + password: str + role: str + schema_: Optional[str] = Field(None, alias='schema') + service: Optional[str] + tags: Optional[Sequence[str]] + token: Optional[str] + use_global_custom_queries: Optional[str] + username: str + warehouse: Optional[str] + + @root_validator(pre=True) + def _initial_validation(cls, values): + return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) + + @validator('*', pre=True, always=True) + def _ensure_defaults(cls, v, field): + if v is not None or field.required: + return v + + return getattr(defaults, f'instance_{field.name}')(field, v) + + @validator('*') + def _run_validations(cls, v, field): + if not v: + return v + + return getattr(validators, f'instance_{field.name}', identity)(v, field=field) + + @root_validator(pre=False) + def _final_validation(cls, values): + return validation.core.finalize_config(getattr(validators, 'finalize_instance', identity)(values)) diff --git a/snowflake/datadog_checks/snowflake/config_models/shared.py b/snowflake/datadog_checks/snowflake/config_models/shared.py new file mode 100644 index 0000000000000..4d73ff97b056b --- /dev/null +++ b/snowflake/datadog_checks/snowflake/config_models/shared.py @@ -0,0 +1,47 @@ +# (C) Datadog, Inc. 2021-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +from __future__ import annotations + +from typing import Any, Mapping, Optional, Sequence + +from pydantic import BaseModel, root_validator, validator + +from datadog_checks.base.utils.functions import identity +from datadog_checks.base.utils.models import validation + +from . import defaults, validators + + +class SharedConfig(BaseModel): + class Config: + allow_mutation = False + + global_custom_queries: Optional[Sequence[Mapping[str, Any]]] + proxy_host: Optional[str] + proxy_password: Optional[str] + proxy_port: Optional[int] + proxy_user: Optional[str] + service: Optional[str] + + @root_validator(pre=True) + def _initial_validation(cls, values): + return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) + + @validator('*', pre=True, always=True) + def _ensure_defaults(cls, v, field): + if v is not None or field.required: + return v + + return getattr(defaults, f'shared_{field.name}')(field, v) + + @validator('*') + def _run_validations(cls, v, field): + if not v: + return v + + return getattr(validators, f'shared_{field.name}', identity)(v, field=field) + + @root_validator(pre=False) + def _final_validation(cls, values): + return validation.core.finalize_config(getattr(validators, 'finalize_shared', identity)(values)) diff --git a/snowflake/datadog_checks/snowflake/config_models/validators.py b/snowflake/datadog_checks/snowflake/config_models/validators.py new file mode 100644 index 0000000000000..96996e5bfa2e2 --- /dev/null +++ b/snowflake/datadog_checks/snowflake/config_models/validators.py @@ -0,0 +1,11 @@ +# (C) Datadog, Inc. 2021-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) + + +def initialize_instance(values, **kwargs): + # TODO: remove when deprecation is finalized https://github.com/DataDog/integrations-core/pull/9340 + if 'username' not in values and 'user' in values: + values['username'] = values['user'] + + return values