From fc47d7819e947eac2744aeae0c15b48670d1b4fc Mon Sep 17 00:00:00 2001 From: skarimo <40482491+skarimo@users.noreply.github.com> Date: Thu, 27 Jul 2023 17:17:15 -0400 Subject: [PATCH] Switch sdkv2 schemas to `SchemaFunc` (#2034) * datasource use SchemaFunc * switch Schema to SchemaFunc --- .../data_source_datadog_application_key.go | 38 +- ...dog_cloud_workload_security_agent_rules.go | 68 +- datadog/data_source_datadog_dashboard.go | 38 +- datadog/data_source_datadog_dashboard_list.go | 16 +- ...e_datadog_integration_aws_logs_services.go | 38 +- ...data_source_datadog_logs_archives_order.go | 18 +- datadog/data_source_datadog_logs_indexes.go | 85 +-- .../data_source_datadog_logs_indexes_order.go | 18 +- datadog/data_source_datadog_logs_pipelines.go | 103 +-- datadog/data_source_datadog_monitor.go | 477 ++++++------- ..._source_datadog_monitor_config_policies.go | 87 +-- datadog/data_source_datadog_monitors.go | 83 +-- datadog/data_source_datadog_permissions.go | 32 +- datadog/data_source_datadog_role.go | 36 +- datadog/data_source_datadog_roles.go | 61 +- .../data_source_datadog_rum_application.go | 68 +- ...rce_datadog_security_monitoring_filters.go | 32 +- ...ource_datadog_security_monitoring_rules.go | 80 +-- ...sensitive_data_scanner_standard_pattern.go | 49 +- ..._source_datadog_service_level_objective.go | 139 ++-- ...source_datadog_service_level_objectives.go | 91 +-- ...urce_datadog_synthetics_global_variable.go | 28 +- ...ata_source_datadog_synthetics_locations.go | 16 +- .../data_source_datadog_synthetics_test_.go | 50 +- datadog/data_source_datadog_user.go | 48 +- datadog/resource_datadog_application_key.go | 26 +- datadog/resource_datadog_authn_mapping.go | 34 +- .../resource_datadog_child_organization.go | 338 +++++----- ...source_datadog_cloud_configuration_rule.go | 4 +- ...adog_cloud_workload_security_agent_rule.go | 4 +- datadog/resource_datadog_dashboard.go | 194 +++--- datadog/resource_datadog_dashboard_json.go | 63 +- datadog/resource_datadog_dashboard_list.go | 48 +- datadog/resource_datadog_downtime.go | 298 +++++---- datadog/resource_datadog_integration_aws.go | 154 ++--- ...urce_datadog_integration_aws_lambda_arn.go | 28 +- ..._datadog_integration_aws_log_collection.go | 28 +- ...urce_datadog_integration_aws_tag_filter.go | 38 +- datadog/resource_datadog_integration_azure.go | 58 +- datadog/resource_datadog_integration_gcp.go | 100 +-- ...dog_integration_opsgenie_service_object.go | 48 +- .../resource_datadog_integration_pagerduty.go | 38 +- ...og_integration_pagerduty_service_object.go | 28 +- ...ource_datadog_integration_slack_channel.go | 88 +-- datadog/resource_datadog_ip_allowlist.go | 28 +- datadog/resource_datadog_logs_archive.go | 118 ++-- .../resource_datadog_logs_archive_order.go | 18 +- .../resource_datadog_logs_custom_pipeline.go | 4 +- datadog/resource_datadog_logs_index.go | 5 +- datadog/resource_datadog_logs_index_order.go | 28 +- ...ource_datadog_logs_integration_pipeline.go | 14 +- datadog/resource_datadog_logs_metric.go | 141 ++-- .../resource_datadog_logs_pipeline_order.go | 26 +- datadog/resource_datadog_metric_metadata.go | 74 +- ...source_datadog_metric_tag_configuration.go | 94 +-- datadog/resource_datadog_monitor.go | 630 +++++++++--------- .../resource_datadog_monitor_config_policy.go | 62 +- datadog/resource_datadog_monitor_json.go | 70 +- .../resource_datadog_organization_settings.go | 236 +++---- datadog/resource_datadog_role.go | 52 +- datadog/resource_datadog_rum_application.go | 36 +- ...atadog_security_monitoring_default_rule.go | 130 ++-- ...rce_datadog_security_monitoring_filters.go | 4 +- ...source_datadog_security_monitoring_rule.go | 4 +- ...ce_datadog_sensitive_data_scanner_group.go | 84 +-- ...rce_datadog_sensitive_data_scanner_rule.go | 166 ++--- datadog/resource_datadog_service_account.go | 48 +- ...esource_datadog_service_definition_yaml.go | 26 +- ...esource_datadog_service_level_objective.go | 286 ++++---- datadog/resource_datadog_slo_correction.go | 88 +-- ...urce_datadog_synthetics_global_variable.go | 216 +++--- ...rce_datadog_synthetics_private_location.go | 64 +- datadog/resource_datadog_synthetics_test_.go | 170 ++--- datadog/resource_datadog_user.go | 86 +-- datadog/resource_datadog_webhook.go | 60 +- ...esource_datadog_webhook_custom_variable.go | 36 +- 76 files changed, 3341 insertions(+), 3179 deletions(-) diff --git a/datadog/data_source_datadog_application_key.go b/datadog/data_source_datadog_application_key.go index 7590c532e..cc35b8391 100644 --- a/datadog/data_source_datadog_application_key.go +++ b/datadog/data_source_datadog_application_key.go @@ -15,25 +15,27 @@ func dataSourceDatadogApplicationKey() *schema.Resource { Description: "Use this data source to retrieve information about an existing application key.", ReadContext: dataSourceDatadogApplicationKeyRead, - Schema: map[string]*schema.Schema{ - "id": { - Description: "Id for Application Key.", - Type: schema.TypeString, - Optional: true, - }, - "name": { - Description: "Name for Application Key.", - Type: schema.TypeString, - Optional: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "id": { + Description: "Id for Application Key.", + Type: schema.TypeString, + Optional: true, + }, + "name": { + Description: "Name for Application Key.", + Type: schema.TypeString, + Optional: true, + }, - // Computed values - "key": { - Description: "The value of the Application Key.", - Type: schema.TypeString, - Computed: true, - Sensitive: true, - }, + // Computed values + "key": { + Description: "The value of the Application Key.", + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + } }, } } diff --git a/datadog/data_source_datadog_cloud_workload_security_agent_rules.go b/datadog/data_source_datadog_cloud_workload_security_agent_rules.go index ed4c1a3e9..b3897c14e 100644 --- a/datadog/data_source_datadog_cloud_workload_security_agent_rules.go +++ b/datadog/data_source_datadog_cloud_workload_security_agent_rules.go @@ -14,42 +14,44 @@ func dataSourceDatadogCloudWorkloadSecurityAgentRules() *schema.Resource { Description: "Use this data source to retrieve information about existing Cloud Workload Security Agent Rules for use in other resources.", ReadContext: dataSourceDatadogCloudWorkloadSecurityAgentRulesRead, - Schema: map[string]*schema.Schema{ - // Computed - "agent_rules": { - Description: "List of Agent rules.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Computed: true, - Description: "The id of the Agent rule.", - }, - "description": { - Type: schema.TypeString, - Computed: true, - Description: "The description of the Agent rule.", - }, - "enabled": { - Type: schema.TypeBool, - Computed: true, - Description: "Whether the Agent rule is enabled.", - }, - "expression": { - Type: schema.TypeString, - Computed: true, - Description: "The SECL expression of the Agent rule.", - }, - "name": { - Type: schema.TypeString, - Computed: true, - Description: "The name of the Agent rule.", + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + // Computed + "agent_rules": { + Description: "List of Agent rules.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the Agent rule.", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "The description of the Agent rule.", + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether the Agent rule is enabled.", + }, + "expression": { + Type: schema.TypeString, + Computed: true, + Description: "The SECL expression of the Agent rule.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the Agent rule.", + }, }, }, }, - }, + } }, } } diff --git a/datadog/data_source_datadog_dashboard.go b/datadog/data_source_datadog_dashboard.go index 0889a2a60..1d5696223 100644 --- a/datadog/data_source_datadog_dashboard.go +++ b/datadog/data_source_datadog_dashboard.go @@ -18,24 +18,26 @@ func dataSourceDatadogDashboard() *schema.Resource { Description: "Use this data source to retrieve information about an existing dashboard, for use in other resources. In particular, it can be used in a monitor message to link to a specific dashboard.", ReadContext: dataSourceDatadogDashboardRead, - Schema: map[string]*schema.Schema{ - "name": { - Description: "The dashboard name to search for. Must only match one dashboard.", - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - // Computed values - "title": { - Description: "The name of the dashboard.", - Type: schema.TypeString, - Computed: true, - }, - "url": { - Description: "The URL to a specific dashboard.", - Type: schema.TypeString, - Computed: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "The dashboard name to search for. Must only match one dashboard.", + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + // Computed values + "title": { + Description: "The name of the dashboard.", + Type: schema.TypeString, + Computed: true, + }, + "url": { + Description: "The URL to a specific dashboard.", + Type: schema.TypeString, + Computed: true, + }, + } }, } } diff --git a/datadog/data_source_datadog_dashboard_list.go b/datadog/data_source_datadog_dashboard_list.go index b19d2e300..d2d67b2e9 100644 --- a/datadog/data_source_datadog_dashboard_list.go +++ b/datadog/data_source_datadog_dashboard_list.go @@ -17,13 +17,15 @@ func dataSourceDatadogDashboardList() *schema.Resource { Description: "Use this data source to retrieve information about an existing dashboard list, for use in other resources. In particular, it can be used in a dashboard to register it in the list.", ReadContext: dataSourceDatadogDashboardListRead, - Schema: map[string]*schema.Schema{ - "name": { - Description: "A dashboard list name to limit the search.", - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringIsNotEmpty, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "A dashboard list name to limit the search.", + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + } }, } } diff --git a/datadog/data_source_datadog_integration_aws_logs_services.go b/datadog/data_source_datadog_integration_aws_logs_services.go index 8875473e4..de9424729 100644 --- a/datadog/data_source_datadog_integration_aws_logs_services.go +++ b/datadog/data_source_datadog_integration_aws_logs_services.go @@ -14,27 +14,29 @@ func dataSourceDatadogIntegrationAWSLogsServices() *schema.Resource { return &schema.Resource{ Description: "Use this data source to retrieve all AWS log ready services.", ReadContext: dataSourceDatadogIntegrationAWSLogsServicesRead, - Schema: map[string]*schema.Schema{ - // Computed - "aws_logs_services": { - Description: "List of AWS log ready services.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Computed: true, - Description: "The id of the AWS log service.", - }, - "label": { - Type: schema.TypeString, - Computed: true, - Description: "The name of the AWS log service.", + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + // Computed + "aws_logs_services": { + Description: "List of AWS log ready services.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the AWS log service.", + }, + "label": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the AWS log service.", + }, }, }, }, - }, + } }, } } diff --git a/datadog/data_source_datadog_logs_archives_order.go b/datadog/data_source_datadog_logs_archives_order.go index a157e365d..6309f677f 100644 --- a/datadog/data_source_datadog_logs_archives_order.go +++ b/datadog/data_source_datadog_logs_archives_order.go @@ -14,14 +14,16 @@ func dataSourceDatadogLogsArchivesOrder() *schema.Resource { Description: "Get the current order of your logs archives.", ReadContext: dataSourceDatadogLogsArchivesOrderRead, - Schema: map[string]*schema.Schema{ - // Computed values - "archive_ids": { - Description: "The archive IDs list. The order of archive IDs in this attribute defines the overall archive order for logs.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + // Computed values + "archive_ids": { + Description: "The archive IDs list. The order of archive IDs in this attribute defines the overall archive order for logs.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + } }, } } diff --git a/datadog/data_source_datadog_logs_indexes.go b/datadog/data_source_datadog_logs_indexes.go index 69874b402..f2f883281 100644 --- a/datadog/data_source_datadog_logs_indexes.go +++ b/datadog/data_source_datadog_logs_indexes.go @@ -13,54 +13,57 @@ func dataSourceDatadogLogsIndexes() *schema.Resource { return &schema.Resource{ Description: "Use this data source to list several existing logs indexes for use in other resources.", ReadContext: dataSourceDatadogLogsIndexesRead, - Schema: map[string]*schema.Schema{ - // Computed values - "logs_indexes": { - Description: "List of logs indexes", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "name": { - Description: "The name of the index.", - Type: schema.TypeString, - Computed: true, - }, - "daily_limit": { - Description: "The number of log events you can send in this index per day before you are rate-limited.", - Type: schema.TypeInt, - Computed: true, - }, - "retention_days": { - Description: "The number of days before logs are deleted from this index.", - Type: schema.TypeInt, - Computed: true, - }, - "filter": { - Description: "Logs filter", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "query": { - Description: "Logs filter criteria. Only logs matching this filter criteria are considered for this index.", - Type: schema.TypeString, - Required: true, + + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + // Computed values + "logs_indexes": { + Description: "List of logs indexes", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Description: "The name of the index.", + Type: schema.TypeString, + Computed: true, + }, + "daily_limit": { + Description: "The number of log events you can send in this index per day before you are rate-limited.", + Type: schema.TypeInt, + Computed: true, + }, + "retention_days": { + Description: "The number of days before logs are deleted from this index.", + Type: schema.TypeInt, + Computed: true, + }, + "filter": { + Description: "Logs filter", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "query": { + Description: "Logs filter criteria. Only logs matching this filter criteria are considered for this index.", + Type: schema.TypeString, + Required: true, + }, }, }, }, - }, - "exclusion_filter": { - Description: "List of exclusion filters.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: dataSourceLogsIndexesExclusionFilterSchema, + "exclusion_filter": { + Description: "List of exclusion filters.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: dataSourceLogsIndexesExclusionFilterSchema, + }, }, }, }, }, - }, + } }, } } diff --git a/datadog/data_source_datadog_logs_indexes_order.go b/datadog/data_source_datadog_logs_indexes_order.go index 0f02bd6f4..6e0e87cdc 100644 --- a/datadog/data_source_datadog_logs_indexes_order.go +++ b/datadog/data_source_datadog_logs_indexes_order.go @@ -14,14 +14,16 @@ func dataSourceDatadogLogsIndexesOrder() *schema.Resource { Description: "Get the current order of your log indexes.", ReadContext: dataSourceDatadogLogsIndexesOrderRead, - Schema: map[string]*schema.Schema{ - // Computed values - "index_names": { - Description: "Array of strings identifying by their name(s) the index(es) of your organization. Logs are tested against the query filter of each index one by one, following the order of the array. Logs are eventually stored in the first matching index.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + // Computed values + "index_names": { + Description: "Array of strings identifying by their name(s) the index(es) of your organization. Logs are tested against the query filter of each index one by one, following the order of the array. Logs are eventually stored in the first matching index.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + } }, } } diff --git a/datadog/data_source_datadog_logs_pipelines.go b/datadog/data_source_datadog_logs_pipelines.go index 5faa4502e..adf41883e 100644 --- a/datadog/data_source_datadog_logs_pipelines.go +++ b/datadog/data_source_datadog_logs_pipelines.go @@ -17,62 +17,65 @@ func dataSourceDatadogLogsPipelines() *schema.Resource { return &schema.Resource{ Description: "Use this data source to list all existing logs pipelines for use in other resources.", ReadContext: dataSourceDatadogLogsPipelinesRead, - Schema: map[string]*schema.Schema{ - "is_read_only": { - Description: "Filter parameter for retrieved pipelines", - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{"true", "false"}, true), - }, - // Computed values - "logs_pipelines": { - Description: "List of logs pipelines", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Description: "ID of the pipeline", - Type: schema.TypeString, - Computed: true, - }, - "filter": { - Description: "Pipelines filter", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "query": { - Description: "Pipeline filter criteria.", - Type: schema.TypeString, - Computed: true, + + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "is_read_only": { + Description: "Filter parameter for retrieved pipelines", + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"true", "false"}, true), + }, + // Computed values + "logs_pipelines": { + Description: "List of logs pipelines", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Description: "ID of the pipeline", + Type: schema.TypeString, + Computed: true, + }, + "filter": { + Description: "Pipelines filter", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "query": { + Description: "Pipeline filter criteria.", + Type: schema.TypeString, + Computed: true, + }, }, }, }, - }, - "name": { - Description: "The name of the pipeline.", - Type: schema.TypeString, - Computed: true, - }, - "is_enabled": { - Description: "Whether or not the pipeline is enabled.", - Type: schema.TypeBool, - Computed: true, - }, - "is_read_only": { - Description: "Whether or not the pipeline can be edited.", - Type: schema.TypeBool, - Computed: true, - }, - "type": { - Description: "Whether or not the pipeline can be edited.", - Type: schema.TypeString, - Computed: true, + "name": { + Description: "The name of the pipeline.", + Type: schema.TypeString, + Computed: true, + }, + "is_enabled": { + Description: "Whether or not the pipeline is enabled.", + Type: schema.TypeBool, + Computed: true, + }, + "is_read_only": { + Description: "Whether or not the pipeline can be edited.", + Type: schema.TypeBool, + Computed: true, + }, + "type": { + Description: "Whether or not the pipeline can be edited.", + Type: schema.TypeString, + Computed: true, + }, }, }, }, - }, + } }, } } diff --git a/datadog/data_source_datadog_monitor.go b/datadog/data_source_datadog_monitor.go index 0507bb945..6e7cc3697 100644 --- a/datadog/data_source_datadog_monitor.go +++ b/datadog/data_source_datadog_monitor.go @@ -19,257 +19,260 @@ func dataSourceDatadogMonitor() *schema.Resource { return &schema.Resource{ Description: "Use this data source to retrieve information about an existing monitor for use in other resources.", ReadContext: dataSourceDatadogMonitorRead, - Schema: map[string]*schema.Schema{ - "name_filter": { - Description: "A monitor name to limit the search.", - Type: schema.TypeString, - Optional: true, - }, - "tags_filter": { - Description: "A list of tags to limit the search. This filters on the monitor scope.", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "monitor_tags_filter": { - Description: "A list of monitor tags to limit the search. This filters on the tags set on the monitor itself.", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - // Computed values - "name": { - Description: "Name of the monitor", - Type: schema.TypeString, - Computed: true, - }, - "message": { - Description: "Message included with notifications for this monitor", - Type: schema.TypeString, - Computed: true, - }, - "escalation_message": { - Description: "Message included with a re-notification for this monitor.", - Type: schema.TypeString, - Computed: true, - }, - "query": { - Description: "Query of the monitor.", - Type: schema.TypeString, - Computed: true, - }, - "type": { - Description: "Type of the monitor.", - Type: schema.TypeString, - Computed: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name_filter": { + Description: "A monitor name to limit the search.", + Type: schema.TypeString, + Optional: true, + }, + "tags_filter": { + Description: "A list of tags to limit the search. This filters on the monitor scope.", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "monitor_tags_filter": { + Description: "A list of monitor tags to limit the search. This filters on the tags set on the monitor itself.", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, - // Options - "monitor_thresholds": { - Description: "Alert thresholds of the monitor.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "ok": { - Type: schema.TypeString, - Computed: true, - }, - "warning": { - Type: schema.TypeString, - Computed: true, - }, - "critical": { - Type: schema.TypeString, - Computed: true, - }, - "unknown": { - Type: schema.TypeString, - Computed: true, - }, - "warning_recovery": { - Type: schema.TypeString, - Computed: true, - }, - "critical_recovery": { - Type: schema.TypeString, - Computed: true, + // Computed values + "name": { + Description: "Name of the monitor", + Type: schema.TypeString, + Computed: true, + }, + "message": { + Description: "Message included with notifications for this monitor", + Type: schema.TypeString, + Computed: true, + }, + "escalation_message": { + Description: "Message included with a re-notification for this monitor.", + Type: schema.TypeString, + Computed: true, + }, + "query": { + Description: "Query of the monitor.", + Type: schema.TypeString, + Computed: true, + }, + "type": { + Description: "Type of the monitor.", + Type: schema.TypeString, + Computed: true, + }, + + // Options + "monitor_thresholds": { + Description: "Alert thresholds of the monitor.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ok": { + Type: schema.TypeString, + Computed: true, + }, + "warning": { + Type: schema.TypeString, + Computed: true, + }, + "critical": { + Type: schema.TypeString, + Computed: true, + }, + "unknown": { + Type: schema.TypeString, + Computed: true, + }, + "warning_recovery": { + Type: schema.TypeString, + Computed: true, + }, + "critical_recovery": { + Type: schema.TypeString, + Computed: true, + }, }, }, }, - }, - "monitor_threshold_windows": { - Description: "Mapping containing `recovery_window` and `trigger_window` values, e.g. `last_15m`. This is only used by anomaly monitors.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "recovery_window": { - Type: schema.TypeString, - Computed: true, - }, - "trigger_window": { - Type: schema.TypeString, - Computed: true, + "monitor_threshold_windows": { + Description: "Mapping containing `recovery_window` and `trigger_window` values, e.g. `last_15m`. This is only used by anomaly monitors.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "recovery_window": { + Type: schema.TypeString, + Computed: true, + }, + "trigger_window": { + Type: schema.TypeString, + Computed: true, + }, }, }, }, - }, - "notify_no_data": { - Description: "Whether or not this monitor notifies when data stops reporting.", - Type: schema.TypeBool, - Computed: true, - }, - "on_missing_data": { - Description: "Controls how groups or monitors are treated if an evaluation does not return any data points. The default option results in different behavior depending on the monitor query type. For monitors using `Count` queries, an empty monitor evaluation is treated as 0 and is compared to the threshold conditions. For monitors using any query type other than `Count`, for example `Gauge`, `Measure`, or `Rate`, the monitor shows the last known status. This option is only available for APM Trace Analytics, Audit Trail, CI, Error Tracking, Event, Logs, and RUM monitors. Valid values are: `show_no_data`, `show_and_notify_no_data`, `resolve`, and `default`.", - Type: schema.TypeString, - Computed: true, - }, - "group_retention_duration": { - Description: "The time span after which groups with missing data are dropped from the monitor state. The minimum value is one hour, and the maximum value is 72 hours. Example values are: 60m, 1h, and 2d. This option is only available for APM Trace Analytics, Audit Trail, CI, Error Tracking, Event, Logs, and RUM monitors.", - Type: schema.TypeString, - Computed: true, - }, - "new_group_delay": { - Description: "Time (in seconds) to skip evaluations for new groups.", - Type: schema.TypeInt, - Computed: true, - }, - "new_host_delay": { - Description: "Time (in seconds) allowing a host to boot and applications to fully start before starting the evaluation of monitor results.", - Type: schema.TypeInt, - Computed: true, - }, - "evaluation_delay": { - Description: "Time (in seconds) for which evaluation is delayed. This is only used by metric monitors.", - Type: schema.TypeInt, - Computed: true, - }, - "no_data_timeframe": { - Description: "The number of minutes before the monitor notifies when data stops reporting.", - Type: schema.TypeInt, - Computed: true, - }, - "renotify_interval": { - Description: "The number of minutes after the last notification before the monitor re-notifies on the current status.", - Type: schema.TypeInt, - Computed: true, - }, - "renotify_occurrences": { - Description: "The number of re-notification messages that should be sent on the current status.", - Type: schema.TypeInt, - Computed: true, - }, - "renotify_statuses": { - Description: "The types of statuses for which re-notification messages should be sent.", - Type: schema.TypeSet, - Elem: &schema.Schema{ - Type: schema.TypeString, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewMonitorRenotifyStatusTypeFromValue), - }, - Computed: true, - }, - "notify_audit": { - Description: "Whether or not tagged users are notified on changes to the monitor.", - Type: schema.TypeBool, - Computed: true, - }, - "timeout_h": { - Description: "Number of hours of the monitor not reporting data before it automatically resolves from a triggered state.", - Type: schema.TypeInt, - Computed: true, - }, - "require_full_window": { - Description: "Whether or not the monitor needs a full window of data before it is evaluated.", - Type: schema.TypeBool, - Computed: true, - }, - "locked": { - Description: "Whether or not changes to the monitor are restricted to the creator or admins.", - Type: schema.TypeBool, - Computed: true, - }, - "restricted_roles": { - // Uncomment when generally available - // Description: "A list of role identifiers to associate with the monitor. Cannot be used with `locked`.", - Type: schema.TypeSet, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "include_tags": { - Description: "Whether or not notifications from the monitor automatically inserts its triggering tags into the title.", - Type: schema.TypeBool, - Computed: true, - }, - "tags": { - Description: "List of tags associated with the monitor.", - // we use TypeSet to represent tags, paradoxically to be able to maintain them ordered; - // we order them explicitly in the read/create/update methods of this resource and using - // TypeSet makes Terraform ignore differences in order when creating a plan - Type: schema.TypeSet, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "enable_logs_sample": { - Description: "Whether or not a list of log values which triggered the alert is included. This is only used by log monitors.", - Type: schema.TypeBool, - Computed: true, - }, - "enable_samples": { - Description: "Whether or not a list of samples which triggered the alert is included. This is only used by CI Test and Pipeline monitors.", - Type: schema.TypeBool, - Computed: true, - }, - "groupby_simple_monitor": { - Description: "Whether or not to trigger one alert if any source breaches a threshold.", - Type: schema.TypeBool, - Computed: true, - }, - "notify_by": { - Description: "Controls what granularity a monitor alerts on. Only available for monitors with groupings. For instance, a monitor grouped by `cluster`, `namespace`, and `pod` can be configured to only notify on each new `cluster` violating the alert conditions by setting `notify_by` to `['cluster']`. Tags mentioned in `notify_by` must be a subset of the grouping tags in the query. For example, a query grouped by `cluster` and `namespace` cannot notify on `region`. Setting `notify_by` to `[*]` configures the monitor to notify as a simple-alert.", - Type: schema.TypeSet, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "scheduling_options": { - Description: "Configuration options for scheduling.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "evaluation_window": { - Description: "Configuration options for the evaluation window. If `hour_starts` is set, no other fields may be set. Otherwise, `day_starts` and `month_starts` must be set together.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "day_starts": { - Description: "The time of the day at which a one day cumulative evaluation window starts. Must be defined in UTC time in `HH:mm` format.", - Type: schema.TypeString, - Computed: true, - }, - "month_starts": { - Description: "The day of the month at which a one month cumulative evaluation window starts. Must be a value of 1.", - Type: schema.TypeInt, - Computed: true, - }, - "hour_starts": { - Description: "The minute of the hour at which a one hour cumulative evaluation window starts. Must be between 0 and 59.", - Type: schema.TypeInt, - Computed: true, + "notify_no_data": { + Description: "Whether or not this monitor notifies when data stops reporting.", + Type: schema.TypeBool, + Computed: true, + }, + "on_missing_data": { + Description: "Controls how groups or monitors are treated if an evaluation does not return any data points. The default option results in different behavior depending on the monitor query type. For monitors using `Count` queries, an empty monitor evaluation is treated as 0 and is compared to the threshold conditions. For monitors using any query type other than `Count`, for example `Gauge`, `Measure`, or `Rate`, the monitor shows the last known status. This option is only available for APM Trace Analytics, Audit Trail, CI, Error Tracking, Event, Logs, and RUM monitors. Valid values are: `show_no_data`, `show_and_notify_no_data`, `resolve`, and `default`.", + Type: schema.TypeString, + Computed: true, + }, + "group_retention_duration": { + Description: "The time span after which groups with missing data are dropped from the monitor state. The minimum value is one hour, and the maximum value is 72 hours. Example values are: 60m, 1h, and 2d. This option is only available for APM Trace Analytics, Audit Trail, CI, Error Tracking, Event, Logs, and RUM monitors.", + Type: schema.TypeString, + Computed: true, + }, + "new_group_delay": { + Description: "Time (in seconds) to skip evaluations for new groups.", + Type: schema.TypeInt, + Computed: true, + }, + "new_host_delay": { + Description: "Time (in seconds) allowing a host to boot and applications to fully start before starting the evaluation of monitor results.", + Type: schema.TypeInt, + Computed: true, + }, + "evaluation_delay": { + Description: "Time (in seconds) for which evaluation is delayed. This is only used by metric monitors.", + Type: schema.TypeInt, + Computed: true, + }, + "no_data_timeframe": { + Description: "The number of minutes before the monitor notifies when data stops reporting.", + Type: schema.TypeInt, + Computed: true, + }, + "renotify_interval": { + Description: "The number of minutes after the last notification before the monitor re-notifies on the current status.", + Type: schema.TypeInt, + Computed: true, + }, + "renotify_occurrences": { + Description: "The number of re-notification messages that should be sent on the current status.", + Type: schema.TypeInt, + Computed: true, + }, + "renotify_statuses": { + Description: "The types of statuses for which re-notification messages should be sent.", + Type: schema.TypeSet, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewMonitorRenotifyStatusTypeFromValue), + }, + Computed: true, + }, + "notify_audit": { + Description: "Whether or not tagged users are notified on changes to the monitor.", + Type: schema.TypeBool, + Computed: true, + }, + "timeout_h": { + Description: "Number of hours of the monitor not reporting data before it automatically resolves from a triggered state.", + Type: schema.TypeInt, + Computed: true, + }, + "require_full_window": { + Description: "Whether or not the monitor needs a full window of data before it is evaluated.", + Type: schema.TypeBool, + Computed: true, + }, + "locked": { + Description: "Whether or not changes to the monitor are restricted to the creator or admins.", + Type: schema.TypeBool, + Computed: true, + }, + "restricted_roles": { + // Uncomment when generally available + // Description: "A list of role identifiers to associate with the monitor. Cannot be used with `locked`.", + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "include_tags": { + Description: "Whether or not notifications from the monitor automatically inserts its triggering tags into the title.", + Type: schema.TypeBool, + Computed: true, + }, + "tags": { + Description: "List of tags associated with the monitor.", + // we use TypeSet to represent tags, paradoxically to be able to maintain them ordered; + // we order them explicitly in the read/create/update methods of this resource and using + // TypeSet makes Terraform ignore differences in order when creating a plan + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "enable_logs_sample": { + Description: "Whether or not a list of log values which triggered the alert is included. This is only used by log monitors.", + Type: schema.TypeBool, + Computed: true, + }, + "enable_samples": { + Description: "Whether or not a list of samples which triggered the alert is included. This is only used by CI Test and Pipeline monitors.", + Type: schema.TypeBool, + Computed: true, + }, + "groupby_simple_monitor": { + Description: "Whether or not to trigger one alert if any source breaches a threshold.", + Type: schema.TypeBool, + Computed: true, + }, + "notify_by": { + Description: "Controls what granularity a monitor alerts on. Only available for monitors with groupings. For instance, a monitor grouped by `cluster`, `namespace`, and `pod` can be configured to only notify on each new `cluster` violating the alert conditions by setting `notify_by` to `['cluster']`. Tags mentioned in `notify_by` must be a subset of the grouping tags in the query. For example, a query grouped by `cluster` and `namespace` cannot notify on `region`. Setting `notify_by` to `[*]` configures the monitor to notify as a simple-alert.", + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "scheduling_options": { + Description: "Configuration options for scheduling.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "evaluation_window": { + Description: "Configuration options for the evaluation window. If `hour_starts` is set, no other fields may be set. Otherwise, `day_starts` and `month_starts` must be set together.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "day_starts": { + Description: "The time of the day at which a one day cumulative evaluation window starts. Must be defined in UTC time in `HH:mm` format.", + Type: schema.TypeString, + Computed: true, + }, + "month_starts": { + Description: "The day of the month at which a one month cumulative evaluation window starts. Must be a value of 1.", + Type: schema.TypeInt, + Computed: true, + }, + "hour_starts": { + Description: "The minute of the hour at which a one hour cumulative evaluation window starts. Must be between 0 and 59.", + Type: schema.TypeInt, + Computed: true, + }, }, }, }, }, }, }, - }, - "notification_preset_name": { - Description: "Toggles the display of additional content sent in the monitor notification. Valid values are: `show_all`, `hide_query`, `hide_handles`, and `hide_all`.", - Type: schema.TypeString, - Computed: true, - }, + "notification_preset_name": { + Description: "Toggles the display of additional content sent in the monitor notification. Valid values are: `show_all`, `hide_query`, `hide_handles`, and `hide_all`.", + Type: schema.TypeString, + Computed: true, + }, + } }, } } diff --git a/datadog/data_source_datadog_monitor_config_policies.go b/datadog/data_source_datadog_monitor_config_policies.go index 8f23b305d..ff57952fb 100644 --- a/datadog/data_source_datadog_monitor_config_policies.go +++ b/datadog/data_source_datadog_monitor_config_policies.go @@ -13,54 +13,57 @@ func dataSourceDatadogMonitorConfigPolicies() *schema.Resource { return &schema.Resource{ Description: "Use this data source to list existing monitor config policies for use in other resources.", ReadContext: dataSourceDatadogMonitorConfigPoliciesRead, - Schema: map[string]*schema.Schema{ - // Computed values - "monitor_config_policies": { - Description: "List of monitor config policies", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Description: "ID of the monitor config policy", - Type: schema.TypeString, - Computed: true, - }, - "policy_type": { - Description: "The monitor config policy type", - Type: schema.TypeString, - Computed: true, - }, - "tag_policy": { - Description: "Config for a tag policy. Only set if `policy_type` is `tag`.", - Type: schema.TypeList, - Computed: true, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "tag_key": { - Type: schema.TypeString, - Description: "The key of the tag", - Computed: true, - }, - "tag_key_required": { - Type: schema.TypeBool, - Description: "If a tag key is required for monitor creation", - Computed: true, - }, - "valid_tag_values": { - Type: schema.TypeList, - Description: "Valid values for the tag", - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, + + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + // Computed values + "monitor_config_policies": { + Description: "List of monitor config policies", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Description: "ID of the monitor config policy", + Type: schema.TypeString, + Computed: true, + }, + "policy_type": { + Description: "The monitor config policy type", + Type: schema.TypeString, + Computed: true, + }, + "tag_policy": { + Description: "Config for a tag policy. Only set if `policy_type` is `tag`.", + Type: schema.TypeList, + Computed: true, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "tag_key": { + Type: schema.TypeString, + Description: "The key of the tag", + Computed: true, + }, + "tag_key_required": { + Type: schema.TypeBool, + Description: "If a tag key is required for monitor creation", + Computed: true, + }, + "valid_tag_values": { + Type: schema.TypeList, + Description: "Valid values for the tag", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, }, }, }, }, }, }, - }, + } }, } } diff --git a/datadog/data_source_datadog_monitors.go b/datadog/data_source_datadog_monitors.go index 851f70cc6..0e3c33f38 100644 --- a/datadog/data_source_datadog_monitors.go +++ b/datadog/data_source_datadog_monitors.go @@ -15,50 +15,53 @@ func dataSourceDatadogMonitors() *schema.Resource { return &schema.Resource{ Description: "Use this data source to list several existing monitors for use in other resources.", ReadContext: dataSourceDatadogMonitorsRead, - Schema: map[string]*schema.Schema{ - "name_filter": { - Description: "A monitor name to limit the search.", - Type: schema.TypeString, - Optional: true, - }, - "tags_filter": { - Description: "A list of tags to limit the search. This filters on the monitor scope.", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "monitor_tags_filter": { - Description: "A list of monitor tags to limit the search. This filters on the tags set on the monitor itself.", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - // Computed values - "monitors": { - Description: "List of monitors", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Description: "ID of the monitor", - Type: schema.TypeInt, - Computed: true, - }, - "name": { - Description: "Name of the monitor", - Type: schema.TypeString, - Computed: true, - }, - "type": { - Description: "Type of the monitor.", - Type: schema.TypeString, - Computed: true, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name_filter": { + Description: "A monitor name to limit the search.", + Type: schema.TypeString, + Optional: true, + }, + "tags_filter": { + Description: "A list of tags to limit the search. This filters on the monitor scope.", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "monitor_tags_filter": { + Description: "A list of monitor tags to limit the search. This filters on the tags set on the monitor itself.", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + // Computed values + "monitors": { + Description: "List of monitors", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Description: "ID of the monitor", + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Description: "Name of the monitor", + Type: schema.TypeString, + Computed: true, + }, + "type": { + Description: "Type of the monitor.", + Type: schema.TypeString, + Computed: true, + }, }, }, }, - }, + } }, } } diff --git a/datadog/data_source_datadog_permissions.go b/datadog/data_source_datadog_permissions.go index 68002f256..cac1cd91a 100644 --- a/datadog/data_source_datadog_permissions.go +++ b/datadog/data_source_datadog_permissions.go @@ -14,22 +14,24 @@ func dataSourceDatadogPermissions() *schema.Resource { Description: "Use this data source to retrieve the list of Datadog permissions by name and their corresponding ID, for use in the role resource.", ReadContext: dataSourceDatadogPermissionsRead, - Schema: map[string]*schema.Schema{ - "include_restricted": { - Description: "Whether to include restricted permissions. Restricted permissions are granted by default to all users of a Datadog org, and cannot be manually granted or revoked.", - Type: schema.TypeBool, - Default: false, - Optional: true, - }, - // Computed values - "permissions": { - Description: "Map of permissions names to their corresponding ID.", - Type: schema.TypeMap, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "include_restricted": { + Description: "Whether to include restricted permissions. Restricted permissions are granted by default to all users of a Datadog org, and cannot be manually granted or revoked.", + Type: schema.TypeBool, + Default: false, + Optional: true, }, - }, + // Computed values + "permissions": { + Description: "Map of permissions names to their corresponding ID.", + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + } }, } } diff --git a/datadog/data_source_datadog_role.go b/datadog/data_source_datadog_role.go index 8dd0b6236..5abf5476b 100644 --- a/datadog/data_source_datadog_role.go +++ b/datadog/data_source_datadog_role.go @@ -16,24 +16,26 @@ func dataSourceDatadogRole() *schema.Resource { Description: "Use this data source to retrieve information about an existing role for use in other resources.", ReadContext: dataSourceDatadogRoleRead, - Schema: map[string]*schema.Schema{ - "filter": { - Description: "A string on which to filter the roles.", - Type: schema.TypeString, - Required: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "filter": { + Description: "A string on which to filter the roles.", + Type: schema.TypeString, + Required: true, + }, - // Computed values - "name": { - Description: "Name of the role.", - Type: schema.TypeString, - Computed: true, - }, - "user_count": { - Description: "Number of users assigned to this role.", - Type: schema.TypeInt, - Computed: true, - }, + // Computed values + "name": { + Description: "Name of the role.", + Type: schema.TypeString, + Computed: true, + }, + "user_count": { + Description: "Number of users assigned to this role.", + Type: schema.TypeInt, + Computed: true, + }, + } }, } } diff --git a/datadog/data_source_datadog_roles.go b/datadog/data_source_datadog_roles.go index a422972f1..b32811d31 100644 --- a/datadog/data_source_datadog_roles.go +++ b/datadog/data_source_datadog_roles.go @@ -18,38 +18,41 @@ func dataSourceDatadogRoles() *schema.Resource { return &schema.Resource{ Description: "Use this data source to retrieve information about multiple roles for use in other resources.", ReadContext: dataSourceDatadogRolesRead, - Schema: map[string]*schema.Schema{ - "filter": { - Description: "Filter all roles by the given string.", - Type: schema.TypeString, - Optional: true, - }, - - // Computed values - "roles": { - Description: "List of Roles", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Description: "ID of the Datadog role", - Type: schema.TypeString, - Computed: true, - }, - "name": { - Description: "Name of the Datadog role", - Type: schema.TypeString, - Computed: true, - }, - "user_count": { - Description: "Number of users that have this role.", - Type: schema.TypeInt, - Computed: true, + + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "filter": { + Description: "Filter all roles by the given string.", + Type: schema.TypeString, + Optional: true, + }, + + // Computed values + "roles": { + Description: "List of Roles", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Description: "ID of the Datadog role", + Type: schema.TypeString, + Computed: true, + }, + "name": { + Description: "Name of the Datadog role", + Type: schema.TypeString, + Computed: true, + }, + "user_count": { + Description: "Number of users that have this role.", + Type: schema.TypeInt, + Computed: true, + }, }, }, }, - }, + } }, } } diff --git a/datadog/data_source_datadog_rum_application.go b/datadog/data_source_datadog_rum_application.go index 7b8197105..493aca361 100644 --- a/datadog/data_source_datadog_rum_application.go +++ b/datadog/data_source_datadog_rum_application.go @@ -13,39 +13,41 @@ func dataSourceDatadogRUMApplication() *schema.Resource { Description: "Use this data source to retrieve a Datadog RUM Application.", ReadContext: dataSourceDatadogRUMApplicationRead, - Schema: map[string]*schema.Schema{ - "name_filter": { - Type: schema.TypeString, - Optional: true, - Description: "The name used to search for a RUM application", - }, - "type_filter": { - Type: schema.TypeString, - Optional: true, - Description: "The type used to search for a RUM application", - }, - "id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ConflictsWith: []string{"name_filter", "type_filter"}, - Description: "ID of the RUM application. Cannot be used with name and type filters.", - }, - "name": { - Type: schema.TypeString, - Computed: true, - Description: "The name of the RUM application", - }, - "type": { - Type: schema.TypeString, - Computed: true, - Description: "The RUM application type. Supported values are `browser`, `ios`, `android`, `react-native`, `flutter`", - }, - "client_token": { - Type: schema.TypeString, - Computed: true, - Description: "The client token", - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name_filter": { + Type: schema.TypeString, + Optional: true, + Description: "The name used to search for a RUM application", + }, + "type_filter": { + Type: schema.TypeString, + Optional: true, + Description: "The type used to search for a RUM application", + }, + "id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"name_filter", "type_filter"}, + Description: "ID of the RUM application. Cannot be used with name and type filters.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the RUM application", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "The RUM application type. Supported values are `browser`, `ios`, `android`, `react-native`, `flutter`", + }, + "client_token": { + Type: schema.TypeString, + Computed: true, + Description: "The client token", + }, + } }, } } diff --git a/datadog/data_source_datadog_security_monitoring_filters.go b/datadog/data_source_datadog_security_monitoring_filters.go index 896209577..2e28aac2e 100644 --- a/datadog/data_source_datadog_security_monitoring_filters.go +++ b/datadog/data_source_datadog_security_monitoring_filters.go @@ -15,22 +15,24 @@ func dataSourceDatadogSecurityMonitoringFilters() *schema.Resource { Description: "Use this data source to retrieve information about existing security monitoring filters for use in other resources.", ReadContext: dataSourceDatadogSecurityFiltersRead, - Schema: map[string]*schema.Schema{ - // Computed - "filters_ids": { - Description: "List of IDs of filters.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "filters": { - Description: "List of filters.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: securityMonitoringFilterSchema(), + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + // Computed + "filters_ids": { + Description: "List of IDs of filters.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, - }, + "filters": { + Description: "List of filters.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: securityMonitoringFilterSchema(), + }, + }, + } }, } } diff --git a/datadog/data_source_datadog_security_monitoring_rules.go b/datadog/data_source_datadog_security_monitoring_rules.go index f9bd400a7..3540d5fc0 100644 --- a/datadog/data_source_datadog_security_monitoring_rules.go +++ b/datadog/data_source_datadog_security_monitoring_rules.go @@ -23,46 +23,48 @@ func dataSourceDatadogSecurityMonitoringRules() *schema.Resource { Description: "Use this data source to retrieve information about existing security monitoring rules for use in other resources.", ReadContext: dataSourceDatadogSecurityMonitoringRulesRead, - Schema: map[string]*schema.Schema{ - // Filters - "name_filter": { - Type: schema.TypeString, - Optional: true, - Description: "A rule name to limit the search", - ValidateFunc: validation.StringIsNotEmpty, - }, - "tags_filter": { - Type: schema.TypeList, - Optional: true, - Description: "A list of tags to limit the search", - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "default_only_filter": { - Type: schema.TypeBool, - Optional: true, - Description: "Limit the search to default rules", - }, - "user_only_filter": { - Type: schema.TypeBool, - Optional: true, - Description: "Limit the search to user rules", - }, - - // Computed - "rule_ids": { - Description: "List of IDs of the matched rules.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "rules": { - Description: "List of rules.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: datadogSecurityMonitoringRuleSchema(), + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + // Filters + "name_filter": { + Type: schema.TypeString, + Optional: true, + Description: "A rule name to limit the search", + ValidateFunc: validation.StringIsNotEmpty, }, - }, + "tags_filter": { + Type: schema.TypeList, + Optional: true, + Description: "A list of tags to limit the search", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "default_only_filter": { + Type: schema.TypeBool, + Optional: true, + Description: "Limit the search to default rules", + }, + "user_only_filter": { + Type: schema.TypeBool, + Optional: true, + Description: "Limit the search to user rules", + }, + + // Computed + "rule_ids": { + Description: "List of IDs of the matched rules.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "rules": { + Description: "List of rules.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: datadogSecurityMonitoringRuleSchema(), + }, + }, + } }, } } diff --git a/datadog/data_source_datadog_sensitive_data_scanner_standard_pattern.go b/datadog/data_source_datadog_sensitive_data_scanner_standard_pattern.go index 82c188832..4cc137f8d 100644 --- a/datadog/data_source_datadog_sensitive_data_scanner_standard_pattern.go +++ b/datadog/data_source_datadog_sensitive_data_scanner_standard_pattern.go @@ -15,29 +15,32 @@ func dataSourceDatadogSensitiveDataScannerStandardPattern() *schema.Resource { return &schema.Resource{ Description: "Use this data source to retrieve information about an existing sensitive data scanner standard pattern.", ReadContext: dataSourceDatadogSensitiveDataScannerStandardPatternRead, - Schema: map[string]*schema.Schema{ - "filter": { - Description: "Filter all the Datadog standard patterns by name.", - Type: schema.TypeString, - Required: true, - }, - // Computed - "name": { - Description: "Name of the standard pattern.", - Type: schema.TypeString, - Computed: true, - }, - "pattern": { - Description: "Regex that the standard pattern applies.", - Type: schema.TypeString, - Computed: true, - }, - "tags": { - Description: "List of tags.", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, + + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "filter": { + Description: "Filter all the Datadog standard patterns by name.", + Type: schema.TypeString, + Required: true, + }, + // Computed + "name": { + Description: "Name of the standard pattern.", + Type: schema.TypeString, + Computed: true, + }, + "pattern": { + Description: "Regex that the standard pattern applies.", + Type: schema.TypeString, + Computed: true, + }, + "tags": { + Description: "List of tags.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + } }, } } diff --git a/datadog/data_source_datadog_service_level_objective.go b/datadog/data_source_datadog_service_level_objective.go index 87ed27f48..819db3221 100644 --- a/datadog/data_source_datadog_service_level_objective.go +++ b/datadog/data_source_datadog_service_level_objective.go @@ -14,78 +14,81 @@ func dataSourceDatadogServiceLevelObjective() *schema.Resource { return &schema.Resource{ Description: "Use this data source to retrieve information about an existing SLO for use in other resources.", ReadContext: dataSourceDatadogServiceLevelObjectiveRead, - Schema: map[string]*schema.Schema{ - "id": { - Description: "A SLO ID to limit the search.", - Type: schema.TypeString, - Optional: true, - }, - "name_query": { - Description: "Filter results based on SLO names.", - Type: schema.TypeString, - Optional: true, - }, - "tags_query": { - Description: "Filter results based on a single SLO tag.", - Type: schema.TypeString, - Optional: true, - }, - "metrics_query": { - Description: "Filter results based on SLO numerator and denominator.", - Type: schema.TypeString, - Optional: true, - }, - // Computed values - "name": { - Description: "Name of the Datadog service level objective", - Type: schema.TypeString, - Computed: true, - }, - "type": { - Description: "The type of the service level objective. The mapping from these types to the types found in the Datadog Web UI can be found in the Datadog API [documentation page](https://docs.datadoghq.com/api/v1/service-level-objectives/#create-a-slo-object). Available values are: `metric` and `monitor`.", - Type: schema.TypeString, - Computed: true, - }, - "description": { - Description: "The description of the service level objective.", - Type: schema.TypeString, - Computed: true, - }, - "target_threshold": { - Description: "The primary target threshold of the service level objective.", - Type: schema.TypeFloat, - Computed: true, - }, - "warning_threshold": { - Description: "The primary warning threshold of the service level objective.", - Type: schema.TypeFloat, - Computed: true, - }, - "timeframe": { - Description: "The primary timeframe of the service level objective.", - Type: schema.TypeString, - Computed: true, - }, - "query": { - Type: schema.TypeList, - Computed: true, - Description: "The metric query of good / total events", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "numerator": { - Description: "The sum of all the `good` events.", - Type: schema.TypeString, - Computed: true, - }, - "denominator": { - Description: "The sum of the `total` events.", - Type: schema.TypeString, - Computed: true, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "id": { + Description: "A SLO ID to limit the search.", + Type: schema.TypeString, + Optional: true, + }, + "name_query": { + Description: "Filter results based on SLO names.", + Type: schema.TypeString, + Optional: true, + }, + "tags_query": { + Description: "Filter results based on a single SLO tag.", + Type: schema.TypeString, + Optional: true, + }, + "metrics_query": { + Description: "Filter results based on SLO numerator and denominator.", + Type: schema.TypeString, + Optional: true, + }, + + // Computed values + "name": { + Description: "Name of the Datadog service level objective", + Type: schema.TypeString, + Computed: true, + }, + "type": { + Description: "The type of the service level objective. The mapping from these types to the types found in the Datadog Web UI can be found in the Datadog API [documentation page](https://docs.datadoghq.com/api/v1/service-level-objectives/#create-a-slo-object). Available values are: `metric` and `monitor`.", + Type: schema.TypeString, + Computed: true, + }, + "description": { + Description: "The description of the service level objective.", + Type: schema.TypeString, + Computed: true, + }, + "target_threshold": { + Description: "The primary target threshold of the service level objective.", + Type: schema.TypeFloat, + Computed: true, + }, + "warning_threshold": { + Description: "The primary warning threshold of the service level objective.", + Type: schema.TypeFloat, + Computed: true, + }, + "timeframe": { + Description: "The primary timeframe of the service level objective.", + Type: schema.TypeString, + Computed: true, + }, + "query": { + Type: schema.TypeList, + Computed: true, + Description: "The metric query of good / total events", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "numerator": { + Description: "The sum of all the `good` events.", + Type: schema.TypeString, + Computed: true, + }, + "denominator": { + Description: "The sum of the `total` events.", + Type: schema.TypeString, + Computed: true, + }, }, }, }, - }, + } }, } } diff --git a/datadog/data_source_datadog_service_level_objectives.go b/datadog/data_source_datadog_service_level_objectives.go index 9982c0ef4..66e5be342 100644 --- a/datadog/data_source_datadog_service_level_objectives.go +++ b/datadog/data_source_datadog_service_level_objectives.go @@ -18,54 +18,57 @@ func dataSourceDatadogServiceLevelObjectives() *schema.Resource { return &schema.Resource{ Description: "Use this data source to retrieve information about multiple SLOs for use in other resources.", ReadContext: dataSourceDatadogServiceLevelObjectivesRead, - Schema: map[string]*schema.Schema{ - "ids": { - Description: "An array of SLO IDs to limit the search.", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "name_query": { - Description: "Filter results based on SLO names.", - Type: schema.TypeString, - Optional: true, - }, - "tags_query": { - Description: "Filter results based on a single SLO tag.", - Type: schema.TypeString, - Optional: true, - }, - "metrics_query": { - Description: "Filter results based on SLO numerator and denominator.", - Type: schema.TypeString, - Optional: true, - }, - // Computed values - "slos": { - Description: "List of SLOs", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Description: "ID of the Datadog service level objective", - Type: schema.TypeString, - Computed: true, - }, - "name": { - Description: "Name of the Datadog service level objective", - Type: schema.TypeString, - Computed: true, - }, - "type": { - Description: "The type of the service level objective. The mapping from these types to the types found in the Datadog Web UI can be found in the Datadog API [documentation page](https://docs.datadoghq.com/api/v1/service-level-objectives/#create-a-slo-object). Available options to choose from are: `metric` and `monitor`.", - Type: schema.TypeString, - Computed: true, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "ids": { + Description: "An array of SLO IDs to limit the search.", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "name_query": { + Description: "Filter results based on SLO names.", + Type: schema.TypeString, + Optional: true, + }, + "tags_query": { + Description: "Filter results based on a single SLO tag.", + Type: schema.TypeString, + Optional: true, + }, + "metrics_query": { + Description: "Filter results based on SLO numerator and denominator.", + Type: schema.TypeString, + Optional: true, + }, + + // Computed values + "slos": { + Description: "List of SLOs", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Description: "ID of the Datadog service level objective", + Type: schema.TypeString, + Computed: true, + }, + "name": { + Description: "Name of the Datadog service level objective", + Type: schema.TypeString, + Computed: true, + }, + "type": { + Description: "The type of the service level objective. The mapping from these types to the types found in the Datadog Web UI can be found in the Datadog API [documentation page](https://docs.datadoghq.com/api/v1/service-level-objectives/#create-a-slo-object). Available options to choose from are: `metric` and `monitor`.", + Type: schema.TypeString, + Computed: true, + }, }, }, }, - }, + } }, } } diff --git a/datadog/data_source_datadog_synthetics_global_variable.go b/datadog/data_source_datadog_synthetics_global_variable.go index 578168152..004fbc73e 100644 --- a/datadog/data_source_datadog_synthetics_global_variable.go +++ b/datadog/data_source_datadog_synthetics_global_variable.go @@ -17,19 +17,21 @@ func dataSourceDatadogSyntheticsGlobalVariable() *schema.Resource { Description: "Use this data source to retrieve a Datadog Synthetics global variable (to be used in Synthetics tests).", ReadContext: dataSourceDatadogSyntheticsGlobalVariableRead, - Schema: map[string]*schema.Schema{ - "name": { - Description: "The synthetics global variable name to search for. Must only match one global variable.", - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[A-Z][A-Z0-9_]+[A-Z0-9]$`), "must be all uppercase with underscores"), - }, - "tags": { - Description: "A list of tags assigned to the Synthetics global variable.", - Type: schema.TypeList, - Elem: &schema.Schema{Type: schema.TypeString}, - Computed: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "The synthetics global variable name to search for. Must only match one global variable.", + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[A-Z][A-Z0-9_]+[A-Z0-9]$`), "must be all uppercase with underscores"), + }, + "tags": { + Description: "A list of tags assigned to the Synthetics global variable.", + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + Computed: true, + }, + } }, } } diff --git a/datadog/data_source_datadog_synthetics_locations.go b/datadog/data_source_datadog_synthetics_locations.go index f97fbb6e3..aea212976 100644 --- a/datadog/data_source_datadog_synthetics_locations.go +++ b/datadog/data_source_datadog_synthetics_locations.go @@ -14,13 +14,15 @@ func dataSourceDatadogSyntheticsLocations() *schema.Resource { Description: "Use this data source to retrieve Datadog's Synthetics Locations (to be used in Synthetics tests).", ReadContext: dataSourceDatadogSyntheticsLocationsRead, - // Locations are a map of IDs to names - Schema: map[string]*schema.Schema{ - "locations": { - Description: "A map of available Synthetics location IDs to names for Synthetics tests.", - Type: schema.TypeMap, - Computed: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + // Locations are a map of IDs to names + return map[string]*schema.Schema{ + "locations": { + Description: "A map of available Synthetics location IDs to names for Synthetics tests.", + Type: schema.TypeMap, + Computed: true, + }, + } }, } } diff --git a/datadog/data_source_datadog_synthetics_test_.go b/datadog/data_source_datadog_synthetics_test_.go index 923fc1d74..91e5bd02f 100644 --- a/datadog/data_source_datadog_synthetics_test_.go +++ b/datadog/data_source_datadog_synthetics_test_.go @@ -16,30 +16,32 @@ func dataSourceDatadogSyntheticsTest() *schema.Resource { Description: "Use this data source to retrieve a Datadog Synthetic Test.", ReadContext: dataSourceDatadogSyntheticsTestRead, - Schema: map[string]*schema.Schema{ - "test_id": { - Description: "The synthetic test id or URL to search for", - Type: schema.TypeString, - Required: true, - }, - "name": { - Description: "The name of the synthetic test.", - Type: schema.TypeString, - Elem: &schema.Schema{Type: schema.TypeString}, - Computed: true, - }, - "tags": { - Description: "A list of tags assigned to the synthetic test.", - Type: schema.TypeList, - Elem: &schema.Schema{Type: schema.TypeString}, - Computed: true, - }, - "url": { - Description: "The start URL of the synthetic test.", - Type: schema.TypeString, - Elem: &schema.Schema{Type: schema.TypeString}, - Computed: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "test_id": { + Description: "The synthetic test id or URL to search for", + Type: schema.TypeString, + Required: true, + }, + "name": { + Description: "The name of the synthetic test.", + Type: schema.TypeString, + Elem: &schema.Schema{Type: schema.TypeString}, + Computed: true, + }, + "tags": { + Description: "A list of tags assigned to the synthetic test.", + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + Computed: true, + }, + "url": { + Description: "The start URL of the synthetic test.", + Type: schema.TypeString, + Elem: &schema.Schema{Type: schema.TypeString}, + Computed: true, + }, + } }, } } diff --git a/datadog/data_source_datadog_user.go b/datadog/data_source_datadog_user.go index 35acb9435..295aa8599 100644 --- a/datadog/data_source_datadog_user.go +++ b/datadog/data_source_datadog_user.go @@ -15,29 +15,31 @@ func dataSourceDatadogUser() *schema.Resource { Description: "Use this data source to retrieve information about an existing user to use it in an other resources.", ReadContext: dataSourceDatadogUserRead, - Schema: map[string]*schema.Schema{ - "filter": { - Description: "Filter all users by the given string.", - Type: schema.TypeString, - Required: true, - }, - "exact_match": { - Description: "When true, `filter` string is exact matched againts the users `email`, followed by `name` attribute.", - Type: schema.TypeBool, - Default: false, - Optional: true, - }, - // Computed values - "email": { - Description: "Email of the user.", - Type: schema.TypeString, - Computed: true, - }, - "name": { - Description: "Name of the user.", - Type: schema.TypeString, - Computed: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "filter": { + Description: "Filter all users by the given string.", + Type: schema.TypeString, + Required: true, + }, + "exact_match": { + Description: "When true, `filter` string is exact matched againts the users `email`, followed by `name` attribute.", + Type: schema.TypeBool, + Default: false, + Optional: true, + }, + // Computed values + "email": { + Description: "Email of the user.", + Type: schema.TypeString, + Computed: true, + }, + "name": { + Description: "Name of the user.", + Type: schema.TypeString, + Computed: true, + }, + } }, } } diff --git a/datadog/resource_datadog_application_key.go b/datadog/resource_datadog_application_key.go index 73c847d6e..079739bad 100644 --- a/datadog/resource_datadog_application_key.go +++ b/datadog/resource_datadog_application_key.go @@ -21,18 +21,20 @@ func resourceDatadogApplicationKey() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Description: "Name for Application Key.", - Type: schema.TypeString, - Required: true, - }, - "key": { - Description: "The value of the Application Key.", - Type: schema.TypeString, - Computed: true, - Sensitive: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "Name for Application Key.", + Type: schema.TypeString, + Required: true, + }, + "key": { + Description: "The value of the Application Key.", + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + } }, } } diff --git a/datadog/resource_datadog_authn_mapping.go b/datadog/resource_datadog_authn_mapping.go index 6b9a95a83..9d4086aed 100644 --- a/datadog/resource_datadog_authn_mapping.go +++ b/datadog/resource_datadog_authn_mapping.go @@ -24,22 +24,24 @@ func resourceDatadogAuthnMapping() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "key": { - Description: "Identity provider key.", - Type: schema.TypeString, - Required: true, - }, - "value": { - Description: "Identity provider value.", - Type: schema.TypeString, - Required: true, - }, - "role": { - Description: "The ID of a role to attach to all users with the corresponding key and value.", - Type: schema.TypeString, - Required: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "key": { + Description: "Identity provider key.", + Type: schema.TypeString, + Required: true, + }, + "value": { + Description: "Identity provider value.", + Type: schema.TypeString, + Required: true, + }, + "role": { + Description: "The ID of a role to attach to all users with the corresponding key and value.", + Type: schema.TypeString, + Required: true, + }, + } }, } } diff --git a/datadog/resource_datadog_child_organization.go b/datadog/resource_datadog_child_organization.go index 398dbf14b..d24aae4cc 100644 --- a/datadog/resource_datadog_child_organization.go +++ b/datadog/resource_datadog_child_organization.go @@ -18,199 +18,201 @@ func resourceDatadogChildOrganization() *schema.Resource { ReadContext: resourceDatadogChildOrganizationRead, DeleteContext: resourceDatadogChildOrganizationDelete, - Schema: map[string]*schema.Schema{ - "name": { - Description: "Name for Child Organization after creation.", - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringLenBetween(1, 32), - }, - "public_id": { - Description: "The `public_id` of the organization you are operating within.", - Type: schema.TypeString, - Computed: true, - }, - "description": { - Description: "Description of the organization.", - Type: schema.TypeString, - Computed: true, - }, - "settings": { - Description: "Organization settings", - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "private_widget_share": { - Type: schema.TypeBool, - Computed: true, - Description: "Whether or not the organization users can share widgets outside of Datadog.", - }, - "saml": { - Type: schema.TypeList, - Computed: true, - Description: "SAML properties", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Computed: true, - Description: "Whether or not SAML is enabled for this organization.", + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "Name for Child Organization after creation.", + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 32), + }, + "public_id": { + Description: "The `public_id` of the organization you are operating within.", + Type: schema.TypeString, + Computed: true, + }, + "description": { + Description: "Description of the organization.", + Type: schema.TypeString, + Computed: true, + }, + "settings": { + Description: "Organization settings", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "private_widget_share": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether or not the organization users can share widgets outside of Datadog.", + }, + "saml": { + Type: schema.TypeList, + Computed: true, + Description: "SAML properties", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether or not SAML is enabled for this organization.", + }, }, }, }, - }, - "saml_autocreate_access_role": { - Type: schema.TypeString, - Computed: true, - Description: "The access role of the user. Options are `st` (standard user), `adm` (admin user), or `ro` (read-only user). Allowed enum values: `st`, `adm` , `ro`, `ERROR`", - }, - "saml_autocreate_users_domains": { - Type: schema.TypeList, - Computed: true, - Description: "List of domains where the SAML automated user creation is enabled.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "domains": { - Type: schema.TypeList, - Computed: true, - Description: "List of domains where the SAML automated user creation is enabled.", - Elem: &schema.Schema{ - Type: schema.TypeString, + "saml_autocreate_access_role": { + Type: schema.TypeString, + Computed: true, + Description: "The access role of the user. Options are `st` (standard user), `adm` (admin user), or `ro` (read-only user). Allowed enum values: `st`, `adm` , `ro`, `ERROR`", + }, + "saml_autocreate_users_domains": { + Type: schema.TypeList, + Computed: true, + Description: "List of domains where the SAML automated user creation is enabled.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "domains": { + Type: schema.TypeList, + Computed: true, + Description: "List of domains where the SAML automated user creation is enabled.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether or not the automated user creation based on SAML domain is enabled.", }, - }, - "enabled": { - Type: schema.TypeBool, - Computed: true, - Description: "Whether or not the automated user creation based on SAML domain is enabled.", }, }, }, - }, - "saml_can_be_enabled": { - Type: schema.TypeBool, - Computed: true, - Description: "Whether or not SAML can be enabled for this organization.", - }, - "saml_idp_endpoint": { - Type: schema.TypeString, - Computed: true, - Description: "Identity provider endpoint for SAML authentication.", - }, - "saml_idp_initiated_login": { - Type: schema.TypeList, - Computed: true, - Description: "Whether or not a SAML identity provider metadata file was provided to the Datadog organization.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Computed: true, - Description: "Whether or not a SAML identity provider metadata file was provided to the Datadog organization.", + "saml_can_be_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether or not SAML can be enabled for this organization.", + }, + "saml_idp_endpoint": { + Type: schema.TypeString, + Computed: true, + Description: "Identity provider endpoint for SAML authentication.", + }, + "saml_idp_initiated_login": { + Type: schema.TypeList, + Computed: true, + Description: "Whether or not a SAML identity provider metadata file was provided to the Datadog organization.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether or not a SAML identity provider metadata file was provided to the Datadog organization.", + }, }, }, }, - }, - "saml_idp_metadata_uploaded": { - Type: schema.TypeBool, - Computed: true, - Description: "Whether or not a SAML identity provider metadata file was provided to the Datadog organization.", - }, - "saml_login_url": { - Type: schema.TypeString, - Computed: true, - Description: "URL for SAML logging.", - }, - "saml_strict_mode": { - Type: schema.TypeList, - Computed: true, - Description: "Whether or not the SAML strict mode is enabled. If true, all users must log in with SAML.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Computed: true, - Description: "Whether or not the SAML strict mode is enabled. If true, all users must log in with SAML.", + "saml_idp_metadata_uploaded": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether or not a SAML identity provider metadata file was provided to the Datadog organization.", + }, + "saml_login_url": { + Type: schema.TypeString, + Computed: true, + Description: "URL for SAML logging.", + }, + "saml_strict_mode": { + Type: schema.TypeList, + Computed: true, + Description: "Whether or not the SAML strict mode is enabled. If true, all users must log in with SAML.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether or not the SAML strict mode is enabled. If true, all users must log in with SAML.", + }, }, }, }, }, }, }, - }, - - "api_key": { - Type: schema.TypeList, - Computed: true, - Description: "Datadog API key.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - Sensitive: true, - Description: "API key.", - }, - "name": { - Type: schema.TypeString, - Computed: true, - Description: "Name of your API key.", + + "api_key": { + Type: schema.TypeList, + Computed: true, + Description: "Datadog API key.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + Description: "API key.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of your API key.", + }, }, }, }, - }, - - "application_key": { - Type: schema.TypeList, - Computed: true, - Description: "An application key with its associated metadata.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "hash": { - Type: schema.TypeString, - Computed: true, - Sensitive: true, - Description: "Hash of an application key.", - }, - "name": { - Type: schema.TypeString, - Computed: true, - Description: "Name of an application key.", - }, - "owner": { - Type: schema.TypeString, - Computed: true, - Description: "Owner of an application key.", + + "application_key": { + Type: schema.TypeList, + Computed: true, + Description: "An application key with its associated metadata.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "hash": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + Description: "Hash of an application key.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of an application key.", + }, + "owner": { + Type: schema.TypeString, + Computed: true, + Description: "Owner of an application key.", + }, }, }, }, - }, - - "user": { - Type: schema.TypeList, - Computed: true, - Description: "Information about a user", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "email": { - Type: schema.TypeString, - Computed: true, - Description: "The new email of the user.", - }, - "name": { - Type: schema.TypeString, - Computed: true, - Description: "The name of the user.", - }, - "access_role": { - Type: schema.TypeString, - Computed: true, - Description: "The access role of the user. Options are `st` (standard user), `adm` (admin user), or `ro` (read-only user). Allowed enum values: `st`, `adm`, `ro`, `ERROR`", + + "user": { + Type: schema.TypeList, + Computed: true, + Description: "Information about a user", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "email": { + Type: schema.TypeString, + Computed: true, + Description: "The new email of the user.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the user.", + }, + "access_role": { + Type: schema.TypeString, + Computed: true, + Description: "The access role of the user. Options are `st` (standard user), `adm` (admin user), or `ro` (read-only user). Allowed enum values: `st`, `adm`, `ro`, `ERROR`", + }, }, }, }, - }, + } }, } } diff --git a/datadog/resource_datadog_cloud_configuration_rule.go b/datadog/resource_datadog_cloud_configuration_rule.go index 125b03770..f9c7272d2 100644 --- a/datadog/resource_datadog_cloud_configuration_rule.go +++ b/datadog/resource_datadog_cloud_configuration_rule.go @@ -37,7 +37,9 @@ func resourceDatadogCloudConfigurationRule() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: cloudConfigurationRuleSchema(), + SchemaFunc: func() map[string]*schema.Schema { + return cloudConfigurationRuleSchema() + }, } } diff --git a/datadog/resource_datadog_cloud_workload_security_agent_rule.go b/datadog/resource_datadog_cloud_workload_security_agent_rule.go index 925cf6312..dd7a99350 100644 --- a/datadog/resource_datadog_cloud_workload_security_agent_rule.go +++ b/datadog/resource_datadog_cloud_workload_security_agent_rule.go @@ -21,7 +21,9 @@ func resourceDatadogCloudWorkloadSecurityAgentRule() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: cloudWorkloadSecurityAgentRuleSchema(), + SchemaFunc: func() map[string]*schema.Schema { + return cloudWorkloadSecurityAgentRuleSchema() + }, } } diff --git a/datadog/resource_datadog_dashboard.go b/datadog/resource_datadog_dashboard.go index 40b2a2520..c65f1a8d7 100644 --- a/datadog/resource_datadog_dashboard.go +++ b/datadog/resource_datadog_dashboard.go @@ -44,106 +44,108 @@ func resourceDatadogDashboard() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "title": { - Type: schema.TypeString, - Required: true, - Description: "The title of the dashboard.", - }, - "widget": { - Type: schema.TypeList, - Optional: true, - Description: "The list of widgets to display on the dashboard.", - Elem: &schema.Resource{ - Schema: getWidgetSchema(), + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "title": { + Type: schema.TypeString, + Required: true, + Description: "The title of the dashboard.", }, - }, - "layout_type": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "The layout type of the dashboard.", - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewDashboardLayoutTypeFromValue), - }, - "reflow_type": { - Type: schema.TypeString, - Optional: true, - Description: "The reflow type of a new dashboard layout. Set this only when layout type is `ordered`. If set to `fixed`, the dashboard expects all widgets to have a layout, and if it's set to `auto`, widgets should not have layouts.", - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewDashboardReflowTypeFromValue), - }, - "description": { - Type: schema.TypeString, - Optional: true, - Description: "The description of the dashboard.", - }, - "url": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The URL of the dashboard.", - DiffSuppressFunc: func(_, _, _ string, _ *schema.ResourceData) bool { - // This value is computed and cannot be updated. - // To maintain backward compatibility, always suppress diff rather - // than converting the attribute to `Computed` only - return true + "widget": { + Type: schema.TypeList, + Optional: true, + Description: "The list of widgets to display on the dashboard.", + Elem: &schema.Resource{ + Schema: getWidgetSchema(), + }, }, - }, - "restricted_roles": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - ConflictsWith: []string{"is_read_only"}, - Description: "UUIDs of roles whose associated users are authorized to edit the dashboard.", - }, - "template_variable": { - Type: schema.TypeList, - Optional: true, - Description: "The list of template variables for this dashboard.", - Elem: &schema.Resource{ - Schema: getTemplateVariableSchema(), + "layout_type": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The layout type of the dashboard.", + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewDashboardLayoutTypeFromValue), }, - }, - "template_variable_preset": { - Type: schema.TypeList, - Optional: true, - Description: "The list of selectable template variable presets for this dashboard.", - Elem: &schema.Resource{ - Schema: getTemplateVariablePresetSchema(), + "reflow_type": { + Type: schema.TypeString, + Optional: true, + Description: "The reflow type of a new dashboard layout. Set this only when layout type is `ordered`. If set to `fixed`, the dashboard expects all widgets to have a layout, and if it's set to `auto`, widgets should not have layouts.", + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewDashboardReflowTypeFromValue), }, - }, - "notify_list": { - Type: schema.TypeSet, - Optional: true, - Description: "The list of handles for the users to notify when changes are made to this dashboard.", - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "dashboard_lists": { - Type: schema.TypeSet, - Optional: true, - Description: "A list of dashboard lists this dashboard belongs to. This attribute should not be set if managing the corresponding dashboard lists using Terraform as it causes inconsistent behavior.", - Elem: &schema.Schema{Type: schema.TypeInt}, - }, - "dashboard_lists_removed": { - Type: schema.TypeSet, - Computed: true, - Description: "A list of dashboard lists this dashboard should be removed from. Internal only.", - Elem: &schema.Schema{Type: schema.TypeInt}, - }, - "is_read_only": { - Type: schema.TypeBool, - Optional: true, - Default: false, - ConflictsWith: []string{"restricted_roles"}, - Description: "Whether this dashboard is read-only.", - Deprecated: "Prefer using `restricted_roles` to define which roles are required to edit the dashboard.", - }, - "tags": { - Type: schema.TypeList, - Optional: true, - MaxItems: 5, - Description: "A list of tags assigned to the Dashboard. Only team names of the form `team:` are supported.", - Elem: &schema.Schema{Type: schema.TypeString}, - }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "The description of the dashboard.", + }, + "url": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The URL of the dashboard.", + DiffSuppressFunc: func(_, _, _ string, _ *schema.ResourceData) bool { + // This value is computed and cannot be updated. + // To maintain backward compatibility, always suppress diff rather + // than converting the attribute to `Computed` only + return true + }, + }, + "restricted_roles": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + ConflictsWith: []string{"is_read_only"}, + Description: "UUIDs of roles whose associated users are authorized to edit the dashboard.", + }, + "template_variable": { + Type: schema.TypeList, + Optional: true, + Description: "The list of template variables for this dashboard.", + Elem: &schema.Resource{ + Schema: getTemplateVariableSchema(), + }, + }, + "template_variable_preset": { + Type: schema.TypeList, + Optional: true, + Description: "The list of selectable template variable presets for this dashboard.", + Elem: &schema.Resource{ + Schema: getTemplateVariablePresetSchema(), + }, + }, + "notify_list": { + Type: schema.TypeSet, + Optional: true, + Description: "The list of handles for the users to notify when changes are made to this dashboard.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "dashboard_lists": { + Type: schema.TypeSet, + Optional: true, + Description: "A list of dashboard lists this dashboard belongs to. This attribute should not be set if managing the corresponding dashboard lists using Terraform as it causes inconsistent behavior.", + Elem: &schema.Schema{Type: schema.TypeInt}, + }, + "dashboard_lists_removed": { + Type: schema.TypeSet, + Computed: true, + Description: "A list of dashboard lists this dashboard should be removed from. Internal only.", + Elem: &schema.Schema{Type: schema.TypeInt}, + }, + "is_read_only": { + Type: schema.TypeBool, + Optional: true, + Default: false, + ConflictsWith: []string{"restricted_roles"}, + Description: "Whether this dashboard is read-only.", + Deprecated: "Prefer using `restricted_roles` to define which roles are required to edit the dashboard.", + }, + "tags": { + Type: schema.TypeList, + Optional: true, + MaxItems: 5, + Description: "A list of tags assigned to the Dashboard. Only team names of the form `team:` are supported.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + } }, } } diff --git a/datadog/resource_datadog_dashboard_json.go b/datadog/resource_datadog_dashboard_json.go index d506ca306..e5922c5fe 100644 --- a/datadog/resource_datadog_dashboard_json.go +++ b/datadog/resource_datadog_dashboard_json.go @@ -46,37 +46,40 @@ func resourceDatadogDashboardJSON() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "dashboard": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringIsJSON, - StateFunc: func(v interface{}) string { - attrMap, _ := structure.ExpandJsonFromString(v.(string)) - prepResource(attrMap) - res, _ := structure.FlattenJsonToString(attrMap) - return res + + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "dashboard": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsJSON, + StateFunc: func(v interface{}) string { + attrMap, _ := structure.ExpandJsonFromString(v.(string)) + prepResource(attrMap) + res, _ := structure.FlattenJsonToString(attrMap) + return res + }, + Description: "The JSON formatted definition of the Dashboard.", + }, + "url": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The URL of the dashboard.", + }, + "dashboard_lists": { + Type: schema.TypeSet, + Optional: true, + Description: "A list of dashboard lists this dashboard belongs to. This attribute should not be set if managing the corresponding dashboard lists using Terraform as it causes inconsistent behavior.", + Elem: &schema.Schema{Type: schema.TypeInt}, }, - Description: "The JSON formatted definition of the Dashboard.", - }, - "url": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The URL of the dashboard.", - }, - "dashboard_lists": { - Type: schema.TypeSet, - Optional: true, - Description: "A list of dashboard lists this dashboard belongs to. This attribute should not be set if managing the corresponding dashboard lists using Terraform as it causes inconsistent behavior.", - Elem: &schema.Schema{Type: schema.TypeInt}, - }, - "dashboard_lists_removed": { - Type: schema.TypeSet, - Computed: true, - Description: "The list of dashboard lists this dashboard should be removed from. Internal only.", - Elem: &schema.Schema{Type: schema.TypeInt}, - }, + "dashboard_lists_removed": { + Type: schema.TypeSet, + Computed: true, + Description: "The list of dashboard lists this dashboard should be removed from. Internal only.", + Elem: &schema.Schema{Type: schema.TypeInt}, + }, + } }, } } diff --git a/datadog/resource_datadog_dashboard_list.go b/datadog/resource_datadog_dashboard_list.go index b5b037bab..4e1a6c35d 100644 --- a/datadog/resource_datadog_dashboard_list.go +++ b/datadog/resource_datadog_dashboard_list.go @@ -23,32 +23,34 @@ func resourceDatadogDashboardList() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the Dashboard List", - }, - "dash_item": { - Type: schema.TypeSet, - Optional: true, - Description: "A set of dashboard items that belong to this list", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - Type: schema.TypeString, - Required: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewDashboardTypeFromValue), - Description: "The type of this dashboard.", - }, - "dash_id": { - Type: schema.TypeString, - Required: true, - Description: "The ID of the dashboard to add", + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "The name of the Dashboard List", + }, + "dash_item": { + Type: schema.TypeSet, + Optional: true, + Description: "A set of dashboard items that belong to this list", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewDashboardTypeFromValue), + Description: "The type of this dashboard.", + }, + "dash_id": { + Type: schema.TypeString, + Required: true, + Description: "The ID of the dashboard to add", + }, }, }, }, - }, + } }, } } diff --git a/datadog/resource_datadog_downtime.go b/datadog/resource_datadog_downtime.go index 276fefbf4..f24b8cd92 100644 --- a/datadog/resource_datadog_downtime.go +++ b/datadog/resource_datadog_downtime.go @@ -116,164 +116,166 @@ func resourceDatadogDowntime() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "active": { - Type: schema.TypeBool, - Computed: true, - Description: "When true indicates this downtime is being actively applied", - }, - "disabled": { - Type: schema.TypeBool, - Computed: true, - Description: "When true indicates this downtime is not being applied", - }, - "start": { - Type: schema.TypeInt, - Optional: true, - DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { - _, startDatePresent := d.GetOk("start_date") - now := time.Now().Unix() - - // If "start_date" is set, ignore diff for "start". If "start" isn't set, ignore diff if start is now or in the past - return startDatePresent || (newVal == "0" && oldVal != "0" && int64(d.Get("start").(int)) <= now) + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "active": { + Type: schema.TypeBool, + Computed: true, + Description: "When true indicates this downtime is being actively applied", }, - Description: "Specify when this downtime should start. Accepts a Unix timestamp in UTC.", - }, - "start_date": { - Type: schema.TypeString, - ValidateFunc: validation.IsRFC3339Time, - ConflictsWith: []string{"start"}, - Optional: true, - Description: "String representing date and time to start the downtime in RFC3339 format.", - DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { - oldDate, _ := time.Parse(time.RFC3339, oldVal) - newDate, _ := time.Parse(time.RFC3339, newVal) - return oldDate.Equal(newDate) + "disabled": { + Type: schema.TypeBool, + Computed: true, + Description: "When true indicates this downtime is not being applied", }, - }, - "end": { - Type: schema.TypeInt, - Optional: true, - DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { - _, endDatePresent := d.GetOk("end_date") - return endDatePresent + "start": { + Type: schema.TypeInt, + Optional: true, + DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { + _, startDatePresent := d.GetOk("start_date") + now := time.Now().Unix() + + // If "start_date" is set, ignore diff for "start". If "start" isn't set, ignore diff if start is now or in the past + return startDatePresent || (newVal == "0" && oldVal != "0" && int64(d.Get("start").(int)) <= now) + }, + Description: "Specify when this downtime should start. Accepts a Unix timestamp in UTC.", }, - Description: "Optionally specify an end date when this downtime should expire. Accepts a Unix timestamp in UTC.", - }, - "end_date": { - Type: schema.TypeString, - ValidateFunc: validation.IsRFC3339Time, - ConflictsWith: []string{"end"}, - Optional: true, - Description: "String representing date and time to end the downtime in RFC3339 format.", - DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { - oldDate, _ := time.Parse(time.RFC3339, oldVal) - newDate, _ := time.Parse(time.RFC3339, newVal) - return oldDate.Equal(newDate) + "start_date": { + Type: schema.TypeString, + ValidateFunc: validation.IsRFC3339Time, + ConflictsWith: []string{"start"}, + Optional: true, + Description: "String representing date and time to start the downtime in RFC3339 format.", + DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { + oldDate, _ := time.Parse(time.RFC3339, oldVal) + newDate, _ := time.Parse(time.RFC3339, newVal) + return oldDate.Equal(newDate) + }, }, - }, - "timezone": { - Type: schema.TypeString, - Default: "UTC", - Optional: true, - Description: "The timezone for the downtime, default UTC. Follows IANA timezone database identifiers.", - ValidateFunc: validators.ValidateDatadogDowntimeTimezone, - }, - "message": { - Type: schema.TypeString, - Optional: true, - Description: "An optional message to provide when creating the downtime, can include notification handles", - StateFunc: func(val interface{}) string { - return strings.TrimSpace(val.(string)) + "end": { + Type: schema.TypeInt, + Optional: true, + DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { + _, endDatePresent := d.GetOk("end_date") + return endDatePresent + }, + Description: "Optionally specify an end date when this downtime should expire. Accepts a Unix timestamp in UTC.", }, - }, - "recurrence": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Description: "Optional recurring schedule for this downtime", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "period": { - Type: schema.TypeInt, - Optional: true, - Description: "How often to repeat as an integer. For example to repeat every 3 days, select a `type` of `days` and a `period` of `3`.", - }, - "type": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validators.ValidateDatadogDowntimeRecurrenceType, - Description: "One of `days`, `weeks`, `months`, `years`, or `rrule`.", - }, - "until_date": { - Type: schema.TypeInt, - Optional: true, - ConflictsWith: []string{"recurrence.until_occurrences"}, - Description: "The date at which the recurrence should end as a POSIX timestamp. `until_occurrences` and `until_date` are mutually exclusive.", - }, - "until_occurrences": { - Type: schema.TypeInt, - Optional: true, - ConflictsWith: []string{"recurrence.until_date"}, - Description: "How many times the downtime will be rescheduled. `until_occurrences` and `until_date` are mutually exclusive.", - }, - "week_days": { - Type: schema.TypeList, - Optional: true, - Description: "A list of week days to repeat on. Choose from: `Mon`, `Tue`, `Wed`, `Thu`, `Fri`, `Sat` or `Sun`. Only applicable when `type` is `weeks`. First letter must be capitalized.", - Elem: &schema.Schema{ + "end_date": { + Type: schema.TypeString, + ValidateFunc: validation.IsRFC3339Time, + ConflictsWith: []string{"end"}, + Optional: true, + Description: "String representing date and time to end the downtime in RFC3339 format.", + DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { + oldDate, _ := time.Parse(time.RFC3339, oldVal) + newDate, _ := time.Parse(time.RFC3339, newVal) + return oldDate.Equal(newDate) + }, + }, + "timezone": { + Type: schema.TypeString, + Default: "UTC", + Optional: true, + Description: "The timezone for the downtime, default UTC. Follows IANA timezone database identifiers.", + ValidateFunc: validators.ValidateDatadogDowntimeTimezone, + }, + "message": { + Type: schema.TypeString, + Optional: true, + Description: "An optional message to provide when creating the downtime, can include notification handles", + StateFunc: func(val interface{}) string { + return strings.TrimSpace(val.(string)) + }, + }, + "recurrence": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Description: "Optional recurring schedule for this downtime", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "period": { + Type: schema.TypeInt, + Optional: true, + Description: "How often to repeat as an integer. For example to repeat every 3 days, select a `type` of `days` and a `period` of `3`.", + }, + "type": { Type: schema.TypeString, - ValidateFunc: validators.ValidateDatadogDowntimeRecurrenceWeekDays, + Required: true, + ValidateFunc: validators.ValidateDatadogDowntimeRecurrenceType, + Description: "One of `days`, `weeks`, `months`, `years`, or `rrule`.", + }, + "until_date": { + Type: schema.TypeInt, + Optional: true, + ConflictsWith: []string{"recurrence.until_occurrences"}, + Description: "The date at which the recurrence should end as a POSIX timestamp. `until_occurrences` and `until_date` are mutually exclusive.", + }, + "until_occurrences": { + Type: schema.TypeInt, + Optional: true, + ConflictsWith: []string{"recurrence.until_date"}, + Description: "How many times the downtime will be rescheduled. `until_occurrences` and `until_date` are mutually exclusive.", + }, + "week_days": { + Type: schema.TypeList, + Optional: true, + Description: "A list of week days to repeat on. Choose from: `Mon`, `Tue`, `Wed`, `Thu`, `Fri`, `Sat` or `Sun`. Only applicable when `type` is `weeks`. First letter must be capitalized.", + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validators.ValidateDatadogDowntimeRecurrenceWeekDays, + }, + }, + "rrule": { + Description: "The RRULE standard for defining recurring events. For example, to have a recurring event on the first day of each month, use `FREQ=MONTHLY;INTERVAL=1`. Most common rrule options from the iCalendar Spec are supported. Attributes specifying the duration in RRULE are not supported (for example, `DTSTART`, `DTEND`, `DURATION`). Only applicable when `type` is `rrule`.", + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"recurrence.period", "recurrence.until_date", "recurrence.until_occurrences", "recurrence.week_days"}, }, - }, - "rrule": { - Description: "The RRULE standard for defining recurring events. For example, to have a recurring event on the first day of each month, use `FREQ=MONTHLY;INTERVAL=1`. Most common rrule options from the iCalendar Spec are supported. Attributes specifying the duration in RRULE are not supported (for example, `DTSTART`, `DTEND`, `DURATION`). Only applicable when `type` is `rrule`.", - Type: schema.TypeString, - Optional: true, - ConflictsWith: []string{"recurrence.period", "recurrence.until_date", "recurrence.until_occurrences", "recurrence.week_days"}, }, }, }, - }, - "scope": { - Type: schema.TypeList, - Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, - Description: "specify the group scope to which this downtime applies. For everything use '*'", - }, - "monitor_id": { - Type: schema.TypeInt, - Optional: true, - ConflictsWith: []string{"monitor_tags"}, - Description: "When specified, this downtime will only apply to this monitor", - }, - "monitor_tags": { - // TypeSet makes Terraform ignore differences in order when creating a plan - Type: schema.TypeSet, - Optional: true, - Description: "A list of monitor tags (up to 32) to base the scheduled downtime on. Only monitors that have all selected tags are silenced", - // MonitorTags conflicts with MonitorId and it also has a default of `["*"]`, which brings some problems: - // * We can't use DefaultFunc to default to ["*"], since that's incompatible with - // ConflictsWith - // * Since this is a TypeSet, DiffSuppressFunc can't really be written well for it - // (it is called and expected to give result for each element, not for the whole - // list, so there's no way to tell in each iteration whether the new config value - // is an empty list). - // Therefore we handle the "default" manually in resourceDatadogDowntimeRead function - ConflictsWith: []string{"monitor_id"}, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "active_child_id": { - Type: schema.TypeInt, - Computed: true, - Description: "The id corresponding to the downtime object definition of the active child for the original parent recurring downtime. This field will only exist on recurring downtimes.", - }, - "mute_first_recovery_notification": { - Type: schema.TypeBool, - Optional: true, - Description: "When true the first recovery notification during the downtime will be muted", - Default: false, - }, + "scope": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Description: "specify the group scope to which this downtime applies. For everything use '*'", + }, + "monitor_id": { + Type: schema.TypeInt, + Optional: true, + ConflictsWith: []string{"monitor_tags"}, + Description: "When specified, this downtime will only apply to this monitor", + }, + "monitor_tags": { + // TypeSet makes Terraform ignore differences in order when creating a plan + Type: schema.TypeSet, + Optional: true, + Description: "A list of monitor tags (up to 32) to base the scheduled downtime on. Only monitors that have all selected tags are silenced", + // MonitorTags conflicts with MonitorId and it also has a default of `["*"]`, which brings some problems: + // * We can't use DefaultFunc to default to ["*"], since that's incompatible with + // ConflictsWith + // * Since this is a TypeSet, DiffSuppressFunc can't really be written well for it + // (it is called and expected to give result for each element, not for the whole + // list, so there's no way to tell in each iteration whether the new config value + // is an empty list). + // Therefore we handle the "default" manually in resourceDatadogDowntimeRead function + ConflictsWith: []string{"monitor_id"}, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "active_child_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The id corresponding to the downtime object definition of the active child for the original parent recurring downtime. This field will only exist on recurring downtimes.", + }, + "mute_first_recovery_notification": { + Type: schema.TypeBool, + Optional: true, + Description: "When true the first recovery notification during the downtime will be muted", + Default: false, + }, + } }, } } diff --git a/datadog/resource_datadog_integration_aws.go b/datadog/resource_datadog_integration_aws.go index 3c3589e46..f8ad1df42 100644 --- a/datadog/resource_datadog_integration_aws.go +++ b/datadog/resource_datadog_integration_aws.go @@ -30,82 +30,84 @@ func resourceDatadogIntegrationAws() *schema.Resource { StateContext: resourceDatadogIntegrationAwsImport, }, - Schema: map[string]*schema.Schema{ - "account_id": { - Description: "Your AWS Account ID without dashes.", - Type: schema.TypeString, - Optional: true, - ConflictsWith: []string{"access_key_id", "secret_access_key"}, - }, - "role_name": { - Description: "Your Datadog role delegation name.", - Type: schema.TypeString, - Optional: true, - ConflictsWith: []string{"access_key_id", "secret_access_key"}, - }, - "filter_tags": { - Description: "Array of EC2 tags (in the form `key:value`) defines a filter that Datadog uses when collecting metrics from EC2. Wildcards, such as `?` (for single characters) and `*` (for multiple characters) can also be used. Only hosts that match one of the defined tags will be imported into Datadog. The rest will be ignored. Host matching a given tag can also be excluded by adding `!` before the tag. e.x. `env:production,instance-type:c1.*,!region:us-east-1`.", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "host_tags": { - Description: "Array of tags (in the form `key:value`) to add to all hosts and metrics reporting through this integration.", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "account_specific_namespace_rules": { - Description: "Enables or disables metric collection for specific AWS namespaces for this AWS account only. A list of namespaces can be found at the [available namespace rules API endpoint](https://docs.datadoghq.com/api/v1/aws-integration/#list-namespace-rules).", - Type: schema.TypeMap, - Optional: true, - Elem: schema.TypeBool, - }, - "excluded_regions": { - Description: "An array of AWS regions to exclude from metrics collection.", - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "external_id": { - Description: "AWS External ID. **NOTE** This provider will not be able to detect changes made to the `external_id` field from outside Terraform.", - Type: schema.TypeString, - Computed: true, - }, - "access_key_id": { - Description: "Your AWS access key ID. Only required if your AWS account is a GovCloud or China account.", - Type: schema.TypeString, - ConflictsWith: []string{"account_id", "role_name"}, - Optional: true, - }, - "secret_access_key": { - Description: "Your AWS secret access key. Only required if your AWS account is a GovCloud or China account.", - Type: schema.TypeString, - Sensitive: true, - ConflictsWith: []string{"account_id", "role_name"}, - Optional: true, - }, - "metrics_collection_enabled": { - Description: "Whether Datadog collects metrics for this AWS account.", - Type: schema.TypeString, - Computed: true, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{"true", "false"}, true), - }, - "resource_collection_enabled": { - Type: schema.TypeString, - Description: "Whether Datadog collects a standard set of resources from your AWS account.", - Computed: true, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{"true", "false"}, true), - }, - "cspm_resource_collection_enabled": { - Type: schema.TypeString, - Description: "Whether Datadog collects cloud security posture management resources from your AWS account. This includes additional resources not covered under the general resource_collection.", - Computed: true, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{"true", "false"}, true), - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Description: "Your AWS Account ID without dashes.", + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"access_key_id", "secret_access_key"}, + }, + "role_name": { + Description: "Your Datadog role delegation name.", + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"access_key_id", "secret_access_key"}, + }, + "filter_tags": { + Description: "Array of EC2 tags (in the form `key:value`) defines a filter that Datadog uses when collecting metrics from EC2. Wildcards, such as `?` (for single characters) and `*` (for multiple characters) can also be used. Only hosts that match one of the defined tags will be imported into Datadog. The rest will be ignored. Host matching a given tag can also be excluded by adding `!` before the tag. e.x. `env:production,instance-type:c1.*,!region:us-east-1`.", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "host_tags": { + Description: "Array of tags (in the form `key:value`) to add to all hosts and metrics reporting through this integration.", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "account_specific_namespace_rules": { + Description: "Enables or disables metric collection for specific AWS namespaces for this AWS account only. A list of namespaces can be found at the [available namespace rules API endpoint](https://docs.datadoghq.com/api/v1/aws-integration/#list-namespace-rules).", + Type: schema.TypeMap, + Optional: true, + Elem: schema.TypeBool, + }, + "excluded_regions": { + Description: "An array of AWS regions to exclude from metrics collection.", + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "external_id": { + Description: "AWS External ID. **NOTE** This provider will not be able to detect changes made to the `external_id` field from outside Terraform.", + Type: schema.TypeString, + Computed: true, + }, + "access_key_id": { + Description: "Your AWS access key ID. Only required if your AWS account is a GovCloud or China account.", + Type: schema.TypeString, + ConflictsWith: []string{"account_id", "role_name"}, + Optional: true, + }, + "secret_access_key": { + Description: "Your AWS secret access key. Only required if your AWS account is a GovCloud or China account.", + Type: schema.TypeString, + Sensitive: true, + ConflictsWith: []string{"account_id", "role_name"}, + Optional: true, + }, + "metrics_collection_enabled": { + Description: "Whether Datadog collects metrics for this AWS account.", + Type: schema.TypeString, + Computed: true, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"true", "false"}, true), + }, + "resource_collection_enabled": { + Type: schema.TypeString, + Description: "Whether Datadog collects a standard set of resources from your AWS account.", + Computed: true, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"true", "false"}, true), + }, + "cspm_resource_collection_enabled": { + Type: schema.TypeString, + Description: "Whether Datadog collects cloud security posture management resources from your AWS account. This includes additional resources not covered under the general resource_collection.", + Computed: true, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"true", "false"}, true), + }, + } }, } } diff --git a/datadog/resource_datadog_integration_aws_lambda_arn.go b/datadog/resource_datadog_integration_aws_lambda_arn.go index 0cc4c7301..49733d378 100644 --- a/datadog/resource_datadog_integration_aws_lambda_arn.go +++ b/datadog/resource_datadog_integration_aws_lambda_arn.go @@ -29,19 +29,21 @@ func resourceDatadogIntegrationAwsLambdaArn() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "account_id": { - Description: "Your AWS Account ID without dashes. If your account is a GovCloud or China account, specify the `access_key_id` here.", - Type: schema.TypeString, - Required: true, - ForceNew: true, // waits for update API call support - }, - "lambda_arn": { - Description: "The ARN of the Datadog forwarder Lambda.", - Type: schema.TypeString, - Required: true, - ForceNew: true, // waits for update API call support - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Description: "Your AWS Account ID without dashes. If your account is a GovCloud or China account, specify the `access_key_id` here.", + Type: schema.TypeString, + Required: true, + ForceNew: true, // waits for update API call support + }, + "lambda_arn": { + Description: "The ARN of the Datadog forwarder Lambda.", + Type: schema.TypeString, + Required: true, + ForceNew: true, // waits for update API call support + }, + } }, } } diff --git a/datadog/resource_datadog_integration_aws_log_collection.go b/datadog/resource_datadog_integration_aws_log_collection.go index 87fe1de01..8bdcd142d 100644 --- a/datadog/resource_datadog_integration_aws_log_collection.go +++ b/datadog/resource_datadog_integration_aws_log_collection.go @@ -22,19 +22,21 @@ func resourceDatadogIntegrationAwsLogCollection() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "account_id": { - Description: "Your AWS Account ID without dashes. If your account is a GovCloud or China account, specify the `access_key_id` here.", - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "services": { - Description: "A list of services to collect logs from. See the [api docs](https://docs.datadoghq.com/api/v1/aws-logs-integration/#get-list-of-aws-log-ready-services) for more details on which services are supported.", - Type: schema.TypeList, - Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Description: "Your AWS Account ID without dashes. If your account is a GovCloud or China account, specify the `access_key_id` here.", + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "services": { + Description: "A list of services to collect logs from. See the [api docs](https://docs.datadoghq.com/api/v1/aws-logs-integration/#get-list-of-aws-log-ready-services) for more details on which services are supported.", + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + } }, } } diff --git a/datadog/resource_datadog_integration_aws_tag_filter.go b/datadog/resource_datadog_integration_aws_tag_filter.go index cc3a0c2c1..1c21e4fba 100644 --- a/datadog/resource_datadog_integration_aws_tag_filter.go +++ b/datadog/resource_datadog_integration_aws_tag_filter.go @@ -23,24 +23,26 @@ func resourceDatadogIntegrationAwsTagFilter() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "account_id": { - Description: "Your AWS Account ID without dashes. If your account is a GovCloud or China account, specify the `access_key_id` here.", - Type: schema.TypeString, - Required: true, - }, - "namespace": { - Description: "The namespace associated with the tag filter entry.", - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewAWSNamespaceFromValue), - }, - "tag_filter_str": { - Description: "The tag filter string.", - Type: schema.TypeString, - Required: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "account_id": { + Description: "Your AWS Account ID without dashes. If your account is a GovCloud or China account, specify the `access_key_id` here.", + Type: schema.TypeString, + Required: true, + }, + "namespace": { + Description: "The namespace associated with the tag filter entry.", + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewAWSNamespaceFromValue), + }, + "tag_filter_str": { + Description: "The tag filter string.", + Type: schema.TypeString, + Required: true, + }, + } }, } } diff --git a/datadog/resource_datadog_integration_azure.go b/datadog/resource_datadog_integration_azure.go index e89d05440..484f973d5 100644 --- a/datadog/resource_datadog_integration_azure.go +++ b/datadog/resource_datadog_integration_azure.go @@ -25,34 +25,36 @@ func resourceDatadogIntegrationAzure() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "tenant_name": { - Description: "Your Azure Active Directory ID.", - Type: schema.TypeString, - Required: true, - }, - "client_id": { - Description: "Your Azure web application ID.", - Type: schema.TypeString, - Required: true, - }, - "client_secret": { - Description: "(Required for Initial Creation) Your Azure web application secret key.", - Type: schema.TypeString, - Required: true, - Sensitive: true, - }, - "host_filters": { - Description: "String of host tag(s) (in the form `key:value,key:value`) defines a filter that Datadog will use when collecting metrics from Azure. Limit the Azure instances that are pulled into Datadog by using tags. Only hosts that match one of the defined tags are imported into Datadog. e.x. `env:production,deploymentgroup:red`", - Type: schema.TypeString, - Optional: true, - }, - "automute": { - Description: "Silence monitors for expected Azure VM shutdowns.", - Type: schema.TypeBool, - Default: false, - Optional: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "tenant_name": { + Description: "Your Azure Active Directory ID.", + Type: schema.TypeString, + Required: true, + }, + "client_id": { + Description: "Your Azure web application ID.", + Type: schema.TypeString, + Required: true, + }, + "client_secret": { + Description: "(Required for Initial Creation) Your Azure web application secret key.", + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "host_filters": { + Description: "String of host tag(s) (in the form `key:value,key:value`) defines a filter that Datadog will use when collecting metrics from Azure. Limit the Azure instances that are pulled into Datadog by using tags. Only hosts that match one of the defined tags are imported into Datadog. e.x. `env:production,deploymentgroup:red`", + Type: schema.TypeString, + Optional: true, + }, + "automute": { + Description: "Silence monitors for expected Azure VM shutdowns.", + Type: schema.TypeBool, + Default: false, + Optional: true, + }, + } }, } } diff --git a/datadog/resource_datadog_integration_gcp.go b/datadog/resource_datadog_integration_gcp.go index 37cf792ef..b43560ca7 100644 --- a/datadog/resource_datadog_integration_gcp.go +++ b/datadog/resource_datadog_integration_gcp.go @@ -26,55 +26,57 @@ func resourceDatadogIntegrationGcp() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "project_id": { - Description: "Your Google Cloud project ID found in your JSON service account key.", - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "private_key_id": { - Description: "Your private key ID found in your JSON service account key.", - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "private_key": { - Description: "Your private key name found in your JSON service account key.", - Type: schema.TypeString, - Required: true, - Sensitive: true, - ForceNew: true, - }, - "client_email": { - Description: "Your email found in your JSON service account key.", - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "client_id": { - Description: "Your ID found in your JSON service account key.", - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "host_filters": { - Description: "Limit the GCE instances that are pulled into Datadog by using tags. Only hosts that match one of the defined tags are imported into Datadog.", - Type: schema.TypeString, - Optional: true, - }, - "automute": { - Description: "Silence monitors for expected GCE instance shutdowns.", - Type: schema.TypeBool, - Default: false, - Optional: true, - }, - "cspm_resource_collection_enabled": { - Description: "Whether Datadog collects cloud security posture management resources from your GCP project.", - Type: schema.TypeBool, - Default: false, - Optional: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "project_id": { + Description: "Your Google Cloud project ID found in your JSON service account key.", + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "private_key_id": { + Description: "Your private key ID found in your JSON service account key.", + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "private_key": { + Description: "Your private key name found in your JSON service account key.", + Type: schema.TypeString, + Required: true, + Sensitive: true, + ForceNew: true, + }, + "client_email": { + Description: "Your email found in your JSON service account key.", + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "client_id": { + Description: "Your ID found in your JSON service account key.", + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "host_filters": { + Description: "Limit the GCE instances that are pulled into Datadog by using tags. Only hosts that match one of the defined tags are imported into Datadog.", + Type: schema.TypeString, + Optional: true, + }, + "automute": { + Description: "Silence monitors for expected GCE instance shutdowns.", + Type: schema.TypeBool, + Default: false, + Optional: true, + }, + "cspm_resource_collection_enabled": { + Description: "Whether Datadog collects cloud security posture management resources from your GCP project.", + Type: schema.TypeBool, + Default: false, + Optional: true, + }, + } }, } } diff --git a/datadog/resource_datadog_integration_opsgenie_service_object.go b/datadog/resource_datadog_integration_opsgenie_service_object.go index 4a5a82b5b..2b4c9ec79 100644 --- a/datadog/resource_datadog_integration_opsgenie_service_object.go +++ b/datadog/resource_datadog_integration_opsgenie_service_object.go @@ -21,29 +21,31 @@ func resourceDatadogIntegrationOpsgenieService() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Description: "The name for the Opsgenie service.", - Type: schema.TypeString, - Required: true, - }, - "opsgenie_api_key": { - Description: "The Opsgenie API key for the Opsgenie service. Note: Since the Datadog API never returns Opsgenie API keys, it is impossible to detect [drifts](https://www.hashicorp.com/blog/detecting-and-managing-drift-with-terraform). The best way to solve a drift is to manually mark the Service Object resource with [terraform taint](https://www.terraform.io/docs/commands/taint.html) to have it destroyed and recreated.", - Type: schema.TypeString, - Required: true, - Sensitive: true, - }, - "region": { - Description: "The region for the Opsgenie service.", - Type: schema.TypeString, - Required: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewOpsgenieServiceRegionTypeFromValue), - }, - "custom_url": { - Description: "The custom url for a custom region.", - Type: schema.TypeString, - Optional: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "The name for the Opsgenie service.", + Type: schema.TypeString, + Required: true, + }, + "opsgenie_api_key": { + Description: "The Opsgenie API key for the Opsgenie service. Note: Since the Datadog API never returns Opsgenie API keys, it is impossible to detect [drifts](https://www.hashicorp.com/blog/detecting-and-managing-drift-with-terraform). The best way to solve a drift is to manually mark the Service Object resource with [terraform taint](https://www.terraform.io/docs/commands/taint.html) to have it destroyed and recreated.", + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "region": { + Description: "The region for the Opsgenie service.", + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewOpsgenieServiceRegionTypeFromValue), + }, + "custom_url": { + Description: "The custom url for a custom region.", + Type: schema.TypeString, + Optional: true, + }, + } }, } } diff --git a/datadog/resource_datadog_integration_pagerduty.go b/datadog/resource_datadog_integration_pagerduty.go index 62f1d833c..85a5bf898 100644 --- a/datadog/resource_datadog_integration_pagerduty.go +++ b/datadog/resource_datadog_integration_pagerduty.go @@ -28,24 +28,26 @@ func resourceDatadogIntegrationPagerduty() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "subdomain": { - Description: "Your PagerDuty account’s personalized subdomain name.", - Type: schema.TypeString, - Required: true, - }, - "schedules": { - Description: "Array of your schedule URLs.", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "api_token": { - Description: "Your PagerDuty API token.", - Type: schema.TypeString, - Optional: true, - Sensitive: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "subdomain": { + Description: "Your PagerDuty account’s personalized subdomain name.", + Type: schema.TypeString, + Required: true, + }, + "schedules": { + Description: "Array of your schedule URLs.", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "api_token": { + Description: "Your PagerDuty API token.", + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + } }, } } diff --git a/datadog/resource_datadog_integration_pagerduty_service_object.go b/datadog/resource_datadog_integration_pagerduty_service_object.go index 3aceb9050..6e6e95e11 100644 --- a/datadog/resource_datadog_integration_pagerduty_service_object.go +++ b/datadog/resource_datadog_integration_pagerduty_service_object.go @@ -22,19 +22,21 @@ func resourceDatadogIntegrationPagerdutySO() *schema.Resource { // since the API never returns service_key, it's impossible to meaningfully import resources Importer: nil, - Schema: map[string]*schema.Schema{ - "service_name": { - Description: "Your Service name in PagerDuty.", - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "service_key": { - Description: "Your Service name associated service key in PagerDuty. Note: Since the Datadog API never returns service keys, it is impossible to detect [drifts](https://www.hashicorp.com/blog/detecting-and-managing-drift-with-terraform). The best way to solve a drift is to manually mark the Service Object resource with [terraform taint](https://www.terraform.io/docs/commands/taint.html) to have it destroyed and recreated.", - Type: schema.TypeString, - Required: true, - Sensitive: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "service_name": { + Description: "Your Service name in PagerDuty.", + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "service_key": { + Description: "Your Service name associated service key in PagerDuty. Note: Since the Datadog API never returns service keys, it is impossible to detect [drifts](https://www.hashicorp.com/blog/detecting-and-managing-drift-with-terraform). The best way to solve a drift is to manually mark the Service Object resource with [terraform taint](https://www.terraform.io/docs/commands/taint.html) to have it destroyed and recreated.", + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + } }, } } diff --git a/datadog/resource_datadog_integration_slack_channel.go b/datadog/resource_datadog_integration_slack_channel.go index ea206616d..83c01b2d9 100644 --- a/datadog/resource_datadog_integration_slack_channel.go +++ b/datadog/resource_datadog_integration_slack_channel.go @@ -26,52 +26,54 @@ func resourceDatadogIntegrationSlackChannel() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "channel_name": { - Type: schema.TypeString, - Required: true, - Description: "Slack channel name.", - }, - "account_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "Slack account name.", - }, - "display": { - Type: schema.TypeList, - Required: true, - Description: "Configuration options for what is shown in an alert event message.", - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "message": { - Type: schema.TypeBool, - Optional: true, - Description: "Show the main body of the alert event.", - Default: true, - }, - "notified": { - Type: schema.TypeBool, - Optional: true, - Description: "Show the list of @-handles in the alert event.", - Default: true, - }, - "snapshot": { - Type: schema.TypeBool, - Optional: true, - Description: "Show the alert event's snapshot image.", - Default: true, - }, - "tags": { - Type: schema.TypeBool, - Optional: true, - Description: "Show the scopes on which the monitor alerted.", - Default: true, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "channel_name": { + Type: schema.TypeString, + Required: true, + Description: "Slack channel name.", + }, + "account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Slack account name.", + }, + "display": { + Type: schema.TypeList, + Required: true, + Description: "Configuration options for what is shown in an alert event message.", + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "message": { + Type: schema.TypeBool, + Optional: true, + Description: "Show the main body of the alert event.", + Default: true, + }, + "notified": { + Type: schema.TypeBool, + Optional: true, + Description: "Show the list of @-handles in the alert event.", + Default: true, + }, + "snapshot": { + Type: schema.TypeBool, + Optional: true, + Description: "Show the alert event's snapshot image.", + Default: true, + }, + "tags": { + Type: schema.TypeBool, + Optional: true, + Description: "Show the scopes on which the monitor alerted.", + Default: true, + }, }, }, }, - }, + } }, } } diff --git a/datadog/resource_datadog_ip_allowlist.go b/datadog/resource_datadog_ip_allowlist.go index 1cc13e800..8e4792db8 100644 --- a/datadog/resource_datadog_ip_allowlist.go +++ b/datadog/resource_datadog_ip_allowlist.go @@ -25,19 +25,21 @@ func resourceDatadogIPAllowlist() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Required: true, - Description: "Whether the IP Allowlist is enabled.", - }, - "entry": { - Type: schema.TypeSet, - Optional: true, - Description: "Set of objects containing an IP address or range of IP addresses in the allowlist and an accompanying note.", - Elem: GetIPAllowlistEntrySchema(), - Set: hashCIDR, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + Description: "Whether the IP Allowlist is enabled.", + }, + "entry": { + Type: schema.TypeSet, + Optional: true, + Description: "Set of objects containing an IP address or range of IP addresses in the allowlist and an accompanying note.", + Elem: GetIPAllowlistEntrySchema(), + Set: hashCIDR, + }, + } }, } } diff --git a/datadog/resource_datadog_logs_archive.go b/datadog/resource_datadog_logs_archive.go index 68e039ddd..84577d261 100644 --- a/datadog/resource_datadog_logs_archive.go +++ b/datadog/resource_datadog_logs_archive.go @@ -23,71 +23,73 @@ func resourceDatadogLogsArchive() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": {Description: "Your archive name.", Type: schema.TypeString, Required: true}, - "query": {Description: "The archive query/filter. Logs matching this query are included in the archive.", Type: schema.TypeString, Required: true}, - "s3_archive": { - Description: "Definition of an s3 archive.", - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "bucket": {Description: "Name of your s3 bucket.", Type: schema.TypeString, Required: true}, - "path": {Description: "Path where the archive is stored.", Type: schema.TypeString, Optional: true}, - "account_id": {Description: "Your AWS account id.", Type: schema.TypeString, Required: true}, - "role_name": {Description: "Your AWS role name", Type: schema.TypeString, Required: true}, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": {Description: "Your archive name.", Type: schema.TypeString, Required: true}, + "query": {Description: "The archive query/filter. Logs matching this query are included in the archive.", Type: schema.TypeString, Required: true}, + "s3_archive": { + Description: "Definition of an s3 archive.", + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bucket": {Description: "Name of your s3 bucket.", Type: schema.TypeString, Required: true}, + "path": {Description: "Path where the archive is stored.", Type: schema.TypeString, Optional: true}, + "account_id": {Description: "Your AWS account id.", Type: schema.TypeString, Required: true}, + "role_name": {Description: "Your AWS role name", Type: schema.TypeString, Required: true}, + }, }, }, - }, - "azure_archive": { - Description: "Definition of an azure archive.", - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "container": {Description: "The container where the archive is stored.", Type: schema.TypeString, Required: true}, - "client_id": {Description: "Your client id.", Type: schema.TypeString, Required: true}, - "tenant_id": {Description: "Your tenant id.", Type: schema.TypeString, Required: true}, - "storage_account": {Description: "The associated storage account.", Type: schema.TypeString, Required: true}, - "path": {Description: "The path where the archive is stored.", Type: schema.TypeString, Optional: true}, + "azure_archive": { + Description: "Definition of an azure archive.", + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "container": {Description: "The container where the archive is stored.", Type: schema.TypeString, Required: true}, + "client_id": {Description: "Your client id.", Type: schema.TypeString, Required: true}, + "tenant_id": {Description: "Your tenant id.", Type: schema.TypeString, Required: true}, + "storage_account": {Description: "The associated storage account.", Type: schema.TypeString, Required: true}, + "path": {Description: "The path where the archive is stored.", Type: schema.TypeString, Optional: true}, + }, }, }, - }, - "gcs_archive": { - Description: "Definition of a GCS archive.", - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "bucket": {Description: "Name of your GCS bucket.", Type: schema.TypeString, Required: true}, - "path": {Description: "Path where the archive is stored.", Type: schema.TypeString, Optional: true}, - "client_email": {Description: "Your client email.", Type: schema.TypeString, Required: true}, - "project_id": {Description: "Your project id.", Type: schema.TypeString, Required: true}, + "gcs_archive": { + Description: "Definition of a GCS archive.", + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bucket": {Description: "Name of your GCS bucket.", Type: schema.TypeString, Required: true}, + "path": {Description: "Path where the archive is stored.", Type: schema.TypeString, Optional: true}, + "client_email": {Description: "Your client email.", Type: schema.TypeString, Required: true}, + "project_id": {Description: "Your project id.", Type: schema.TypeString, Required: true}, + }, }, }, - }, - "rehydration_tags": { - Description: "An array of tags to add to rehydrated logs from an archive.", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, + "rehydration_tags": { + Description: "An array of tags to add to rehydrated logs from an archive.", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "include_tags": { + Description: "To store the tags in the archive, set the value `true`. If it is set to `false`, the tags will be dropped when the logs are sent to the archive.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "rehydration_max_scan_size_in_gb": { + Description: "To limit the rehydration scan size for the archive, set a value in GB.", + Type: schema.TypeInt, + Optional: true, }, - }, - "include_tags": { - Description: "To store the tags in the archive, set the value `true`. If it is set to `false`, the tags will be dropped when the logs are sent to the archive.", - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "rehydration_max_scan_size_in_gb": { - Description: "To limit the rehydration scan size for the archive, set a value in GB.", - Type: schema.TypeInt, - Optional: true, - }, + } }, } } diff --git a/datadog/resource_datadog_logs_archive_order.go b/datadog/resource_datadog_logs_archive_order.go index b73ad9cc3..33b1800b5 100644 --- a/datadog/resource_datadog_logs_archive_order.go +++ b/datadog/resource_datadog_logs_archive_order.go @@ -21,14 +21,16 @@ func resourceDatadogLogsArchiveOrder() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "archive_ids": { - Description: "The archive IDs list. The order of archive IDs in this attribute defines the overall archive order for logs. If `archive_ids` is empty or not specified, it will import the actual archive order, and create the resource. Otherwise, it will try to update the order.", - Type: schema.TypeList, - Computed: true, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "archive_ids": { + Description: "The archive IDs list. The order of archive IDs in this attribute defines the overall archive order for logs. If `archive_ids` is empty or not specified, it will import the actual archive order, and create the resource. Otherwise, it will try to update the order.", + Type: schema.TypeList, + Computed: true, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + } }, } } diff --git a/datadog/resource_datadog_logs_custom_pipeline.go b/datadog/resource_datadog_logs_custom_pipeline.go index 6ef1a2a53..adcbe29c6 100644 --- a/datadog/resource_datadog_logs_custom_pipeline.go +++ b/datadog/resource_datadog_logs_custom_pipeline.go @@ -381,7 +381,9 @@ func resourceDatadogLogsCustomPipeline() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, Description: "Provides a Datadog [Logs Pipeline API](https://docs.datadoghq.com/api/v1/logs-pipelines/) resource, which is used to create and manage Datadog logs custom pipelines. Each `datadog_logs_custom_pipeline` resource defines a complete pipeline. The order of the pipelines is maintained in a different resource: `datadog_logs_pipeline_order`. When creating a new pipeline, you need to **explicitly** add this pipeline to the `datadog_logs_pipeline_order` resource to track the pipeline. Similarly, when a pipeline needs to be destroyed, remove its references from the `datadog_logs_pipeline_order` resource.", - Schema: getPipelineSchema(false), + SchemaFunc: func() map[string]*schema.Schema { + return getPipelineSchema(false) + }, } } diff --git a/datadog/resource_datadog_logs_index.go b/datadog/resource_datadog_logs_index.go index 8e09c5c69..986b9c678 100644 --- a/datadog/resource_datadog_logs_index.go +++ b/datadog/resource_datadog_logs_index.go @@ -112,7 +112,10 @@ func resourceDatadogLogsIndex() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: indexSchema, + + SchemaFunc: func() map[string]*schema.Schema { + return indexSchema + }, } } diff --git a/datadog/resource_datadog_logs_index_order.go b/datadog/resource_datadog_logs_index_order.go index f1de76f0c..380d7a1de 100644 --- a/datadog/resource_datadog_logs_index_order.go +++ b/datadog/resource_datadog_logs_index_order.go @@ -20,19 +20,21 @@ func resourceDatadogLogsIndexOrder() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Description: "The unique name of the index order resource.", - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "indexes": { - Description: "The index resource list. Logs are tested against the query filter of each index one by one following the order of the list.", - Type: schema.TypeList, - Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "The unique name of the index order resource.", + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "indexes": { + Description: "The index resource list. Logs are tested against the query filter of each index one by one following the order of the list.", + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + } }, } } diff --git a/datadog/resource_datadog_logs_integration_pipeline.go b/datadog/resource_datadog_logs_integration_pipeline.go index 9c34f9077..15ea146d4 100644 --- a/datadog/resource_datadog_logs_integration_pipeline.go +++ b/datadog/resource_datadog_logs_integration_pipeline.go @@ -20,12 +20,14 @@ func resourceDatadogLogsIntegrationPipeline() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "is_enabled": { - Description: "Boolean value to enable your pipeline.", - Type: schema.TypeBool, - Optional: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "is_enabled": { + Description: "Boolean value to enable your pipeline.", + Type: schema.TypeBool, + Optional: true, + }, + } }, } } diff --git a/datadog/resource_datadog_logs_metric.go b/datadog/resource_datadog_logs_metric.go index 37252feec..733fc5a71 100644 --- a/datadog/resource_datadog_logs_metric.go +++ b/datadog/resource_datadog_logs_metric.go @@ -22,86 +22,87 @@ func resourceDatadogLogsMetric() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - - "compute": { - Type: schema.TypeList, - Required: true, - ForceNew: true, - Description: "The compute rule to compute the log-based metric. This field can't be updated after creation.", - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - - "aggregation_type": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewLogsMetricComputeAggregationTypeFromValue), - Description: "The type of aggregation to use. This field can't be updated after creation.", - }, - - "path": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The path to the value the log-based metric will aggregate on (only used if the aggregation type is a \"distribution\"). This field can't be updated after creation.", - }, - - "include_percentiles": { - Description: "Toggle to include/exclude percentiles for a distribution metric. Defaults to false. Can only be applied to metrics that have an `aggregation_type` of distribution.", - Type: schema.TypeBool, - Optional: true, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute": { + Type: schema.TypeList, + Required: true, + ForceNew: true, + Description: "The compute rule to compute the log-based metric. This field can't be updated after creation.", + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + + "aggregation_type": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewLogsMetricComputeAggregationTypeFromValue), + Description: "The type of aggregation to use. This field can't be updated after creation.", + }, + + "path": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "The path to the value the log-based metric will aggregate on (only used if the aggregation type is a \"distribution\"). This field can't be updated after creation.", + }, + + "include_percentiles": { + Description: "Toggle to include/exclude percentiles for a distribution metric. Defaults to false. Can only be applied to metrics that have an `aggregation_type` of distribution.", + Type: schema.TypeBool, + Optional: true, + }, }, }, }, - }, - - "filter": { - Type: schema.TypeList, - Required: true, - Description: "The log-based metric filter. Logs matching this filter will be aggregated in this metric.", - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - - "query": { - Type: schema.TypeString, - Required: true, - Description: "The search query - following the log search syntax.", + + "filter": { + Type: schema.TypeList, + Required: true, + Description: "The log-based metric filter. Logs matching this filter will be aggregated in this metric.", + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + + "query": { + Type: schema.TypeString, + Required: true, + Description: "The search query - following the log search syntax.", + }, }, }, }, - }, - - "group_by": { - Type: schema.TypeSet, - Optional: true, - Description: "The rules for the group by.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - - "path": { - Type: schema.TypeString, - Required: true, - Description: "The path to the value the log-based metric will be aggregated over.", - }, - "tag_name": { - Type: schema.TypeString, - Required: true, - Description: "Name of the tag that gets created.", + "group_by": { + Type: schema.TypeSet, + Optional: true, + Description: "The rules for the group by.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + + "path": { + Type: schema.TypeString, + Required: true, + Description: "The path to the value the log-based metric will be aggregated over.", + }, + + "tag_name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the tag that gets created.", + }, }, }, }, - }, - - "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "The name of the log-based metric. This field can't be updated after creation.", - }, + + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The name of the log-based metric. This field can't be updated after creation.", + }, + } }, } } diff --git a/datadog/resource_datadog_logs_pipeline_order.go b/datadog/resource_datadog_logs_pipeline_order.go index b65b6e746..485797746 100644 --- a/datadog/resource_datadog_logs_pipeline_order.go +++ b/datadog/resource_datadog_logs_pipeline_order.go @@ -21,18 +21,20 @@ func resourceDatadogLogsPipelineOrder() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Description: "The name attribute in the resource `datadog_logs_pipeline_order` needs to be unique. It's recommended to use the same value as the resource name. No related field is available in [Logs Pipeline API](https://docs.datadoghq.com/api/v1/logs-pipelines/#get-pipeline-order).", - Type: schema.TypeString, - Required: true, - }, - "pipelines": { - Description: "The pipeline IDs list. The order of pipeline IDs in this attribute defines the overall pipeline order for logs.", - Type: schema.TypeList, - Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "The name attribute in the resource `datadog_logs_pipeline_order` needs to be unique. It's recommended to use the same value as the resource name. No related field is available in [Logs Pipeline API](https://docs.datadoghq.com/api/v1/logs-pipelines/#get-pipeline-order).", + Type: schema.TypeString, + Required: true, + }, + "pipelines": { + Description: "The pipeline IDs list. The order of pipeline IDs in this attribute defines the overall pipeline order for logs.", + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + } }, } } diff --git a/datadog/resource_datadog_metric_metadata.go b/datadog/resource_datadog_metric_metadata.go index 0b0ad66cd..b62cfc211 100644 --- a/datadog/resource_datadog_metric_metadata.go +++ b/datadog/resource_datadog_metric_metadata.go @@ -22,42 +22,44 @@ func resourceDatadogMetricMetadata() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "metric": { - Description: "The name of the metric.", - Type: schema.TypeString, - Required: true, - }, - "type": { - Description: "Metric type such as `gauge` or `rate`.", - Type: schema.TypeString, - Optional: true, - }, - "description": { - Description: "A description of the metric.", - Type: schema.TypeString, - Optional: true, - }, - "short_name": { - Description: "A short name of the metric.", - Type: schema.TypeString, - Optional: true, - }, - "unit": { - Description: "Primary unit of the metric such as `byte` or `operation`.", - Type: schema.TypeString, - Optional: true, - }, - "per_unit": { - Description: "Per unit of the metric such as `second` in `bytes per second`.", - Type: schema.TypeString, - Optional: true, - }, - "statsd_interval": { - Description: "If applicable, statsd flush interval in seconds for the metric.", - Type: schema.TypeInt, - Optional: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "metric": { + Description: "The name of the metric.", + Type: schema.TypeString, + Required: true, + }, + "type": { + Description: "Metric type such as `gauge` or `rate`.", + Type: schema.TypeString, + Optional: true, + }, + "description": { + Description: "A description of the metric.", + Type: schema.TypeString, + Optional: true, + }, + "short_name": { + Description: "A short name of the metric.", + Type: schema.TypeString, + Optional: true, + }, + "unit": { + Description: "Primary unit of the metric such as `byte` or `operation`.", + Type: schema.TypeString, + Optional: true, + }, + "per_unit": { + Description: "Per unit of the metric such as `second` in `bytes per second`.", + Type: schema.TypeString, + Optional: true, + }, + "statsd_interval": { + Description: "If applicable, statsd flush interval in seconds for the metric.", + Type: schema.TypeInt, + Optional: true, + }, + } }, } } diff --git a/datadog/resource_datadog_metric_tag_configuration.go b/datadog/resource_datadog_metric_tag_configuration.go index 2d49546cf..a7d1333da 100644 --- a/datadog/resource_datadog_metric_tag_configuration.go +++ b/datadog/resource_datadog_metric_tag_configuration.go @@ -67,57 +67,59 @@ func resourceDatadogMetricTagConfiguration() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "metric_name": { - Description: "The metric name for this resource.", - Type: schema.TypeString, - ForceNew: true, - Required: true, - ValidateFunc: validation.All(validation.StringMatch(regexp.MustCompile(`^[A-Za-z][A-Za-z0-9\.\_]*$`), "metric name must be valid"), validation.StringLenBetween(1, 200)), - }, - "metric_type": { - Description: "The metric's type. This field can't be updated after creation.", - Type: schema.TypeString, - ForceNew: true, - Required: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewMetricTagConfigurationMetricTypesFromValue), - }, - "tags": { - Description: "A list of tag keys that will be queryable for your metric.", - Type: schema.TypeSet, - Elem: &schema.Schema{ + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "metric_name": { + Description: "The metric name for this resource.", Type: schema.TypeString, - ValidateFunc: validation.All(validation.StringMatch(regexp.MustCompile(`^[A-Za-z][A-Za-z0-9\.\-\_:\/]*$`), "tags must be valid"), validation.StringLenBetween(1, 200)), + ForceNew: true, + Required: true, + ValidateFunc: validation.All(validation.StringMatch(regexp.MustCompile(`^[A-Za-z][A-Za-z0-9\.\_]*$`), "metric name must be valid"), validation.StringLenBetween(1, 200)), }, - Required: true, - }, - "include_percentiles": { - Description: "Toggle to include/exclude percentiles for a distribution metric. Defaults to false. Can only be applied to metrics that have a `metric_type` of distribution.", - Type: schema.TypeBool, - Optional: true, - }, - "aggregations": { - Description: "A list of queryable aggregation combinations for a count, rate, or gauge metric. By default, count and rate metrics require the (time: sum, space: sum) aggregation and gauge metrics require the (time: avg, space: avg) aggregation. Can only be applied to metrics that have a `metric_type` of count, rate, or gauge.", - Type: schema.TypeSet, - Optional: true, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "time": { - Description: "A time aggregation for use in query.", - Type: schema.TypeString, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewMetricCustomTimeAggregationFromValue), - Required: true, - }, - "space": { - Description: "A space aggregation for use in query.", - Type: schema.TypeString, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewMetricCustomSpaceAggregationFromValue), - Required: true, + "metric_type": { + Description: "The metric's type. This field can't be updated after creation.", + Type: schema.TypeString, + ForceNew: true, + Required: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewMetricTagConfigurationMetricTypesFromValue), + }, + "tags": { + Description: "A list of tag keys that will be queryable for your metric.", + Type: schema.TypeSet, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.All(validation.StringMatch(regexp.MustCompile(`^[A-Za-z][A-Za-z0-9\.\-\_:\/]*$`), "tags must be valid"), validation.StringLenBetween(1, 200)), + }, + Required: true, + }, + "include_percentiles": { + Description: "Toggle to include/exclude percentiles for a distribution metric. Defaults to false. Can only be applied to metrics that have a `metric_type` of distribution.", + Type: schema.TypeBool, + Optional: true, + }, + "aggregations": { + Description: "A list of queryable aggregation combinations for a count, rate, or gauge metric. By default, count and rate metrics require the (time: sum, space: sum) aggregation and gauge metrics require the (time: avg, space: avg) aggregation. Can only be applied to metrics that have a `metric_type` of count, rate, or gauge.", + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "time": { + Description: "A time aggregation for use in query.", + Type: schema.TypeString, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewMetricCustomTimeAggregationFromValue), + Required: true, + }, + "space": { + Description: "A space aggregation for use in query.", + Type: schema.TypeString, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewMetricCustomSpaceAggregationFromValue), + Required: true, + }, }, }, }, - }, + } }, } } diff --git a/datadog/resource_datadog_monitor.go b/datadog/resource_datadog_monitor.go index 93b886de7..0a681e87f 100644 --- a/datadog/resource_datadog_monitor.go +++ b/datadog/resource_datadog_monitor.go @@ -36,344 +36,346 @@ func resourceDatadogMonitor() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Description: "Name of Datadog monitor.", - Type: schema.TypeString, - Required: true, - }, - "message": { - Description: "A message to include with notifications for this monitor.\n\nEmail notifications can be sent to specific users by using the same `@username` notation as events.", - Type: schema.TypeString, - Required: true, - StateFunc: func(val interface{}) string { - return strings.TrimSpace(val.(string)) + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "Name of Datadog monitor.", + Type: schema.TypeString, + Required: true, }, - }, - "escalation_message": { - Description: "A message to include with a re-notification. Supports the `@username` notification allowed elsewhere.", - Type: schema.TypeString, - Optional: true, - StateFunc: func(val interface{}) string { - return strings.TrimSpace(val.(string)) + "message": { + Description: "A message to include with notifications for this monitor.\n\nEmail notifications can be sent to specific users by using the same `@username` notation as events.", + Type: schema.TypeString, + Required: true, + StateFunc: func(val interface{}) string { + return strings.TrimSpace(val.(string)) + }, }, - }, - "query": { - Description: "The monitor query to notify on. Note this is not the same query you see in the UI and the syntax is different depending on the monitor type, please see the [API Reference](https://docs.datadoghq.com/api/v1/monitors/#create-a-monitor) for details. `terraform plan` will validate query contents unless `validate` is set to `false`.\n\n**Note:** APM latency data is now available as Distribution Metrics. Existing monitors have been migrated automatically but all terraformed monitors can still use the existing metrics. We strongly recommend updating monitor definitions to query the new metrics. To learn more, or to see examples of how to update your terraform definitions to utilize the new distribution metrics, see the [detailed doc](https://docs.datadoghq.com/tracing/guide/ddsketch_trace_metrics/).", - Type: schema.TypeString, - Required: true, - StateFunc: func(val interface{}) string { - return strings.TrimSpace(val.(string)) + "escalation_message": { + Description: "A message to include with a re-notification. Supports the `@username` notification allowed elsewhere.", + Type: schema.TypeString, + Optional: true, + StateFunc: func(val interface{}) string { + return strings.TrimSpace(val.(string)) + }, }, - }, - "type": { - Description: "The type of the monitor. The mapping from these types to the types found in the Datadog Web UI can be found in the Datadog API [documentation page](https://docs.datadoghq.com/api/v1/monitors/#create-a-monitor). Note: The monitor type cannot be changed after a monitor is created.", - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewMonitorTypeFromValue), - // Datadog API quirk, see https://github.com/hashicorp/terraform/issues/13784 - DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { - if (oldVal == "query alert" && newVal == "metric alert") || - (oldVal == "metric alert" && newVal == "query alert") { - log.Printf("[DEBUG] Monitor '%s' got a '%s' response for an expected '%s' type. Suppressing change.", d.Get("name"), newVal, oldVal) - return true - } - return newVal == oldVal + "query": { + Description: "The monitor query to notify on. Note this is not the same query you see in the UI and the syntax is different depending on the monitor type, please see the [API Reference](https://docs.datadoghq.com/api/v1/monitors/#create-a-monitor) for details. `terraform plan` will validate query contents unless `validate` is set to `false`.\n\n**Note:** APM latency data is now available as Distribution Metrics. Existing monitors have been migrated automatically but all terraformed monitors can still use the existing metrics. We strongly recommend updating monitor definitions to query the new metrics. To learn more, or to see examples of how to update your terraform definitions to utilize the new distribution metrics, see the [detailed doc](https://docs.datadoghq.com/tracing/guide/ddsketch_trace_metrics/).", + Type: schema.TypeString, + Required: true, + StateFunc: func(val interface{}) string { + return strings.TrimSpace(val.(string)) + }, + }, + "type": { + Description: "The type of the monitor. The mapping from these types to the types found in the Datadog Web UI can be found in the Datadog API [documentation page](https://docs.datadoghq.com/api/v1/monitors/#create-a-monitor). Note: The monitor type cannot be changed after a monitor is created.", + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewMonitorTypeFromValue), + // Datadog API quirk, see https://github.com/hashicorp/terraform/issues/13784 + DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { + if (oldVal == "query alert" && newVal == "metric alert") || + (oldVal == "metric alert" && newVal == "query alert") { + log.Printf("[DEBUG] Monitor '%s' got a '%s' response for an expected '%s' type. Suppressing change.", d.Get("name"), newVal, oldVal) + return true + } + return newVal == oldVal + }, + }, + "priority": { + Description: "Integer from 1 (high) to 5 (low) indicating alert severity.", + Type: schema.TypeInt, + Optional: true, }, - }, - "priority": { - Description: "Integer from 1 (high) to 5 (low) indicating alert severity.", - Type: schema.TypeInt, - Optional: true, - }, - // Options - "monitor_thresholds": { - Description: "Alert thresholds of the monitor.", - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "ok": { - Description: "The monitor `OK` threshold. Only supported in monitor type `service check`. Must be a number.", - Type: schema.TypeString, - ValidateFunc: validators.ValidateFloatString, - Optional: true, - DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { - monitorType := d.Get("type").(string) - return monitorType != string(datadogV1.MONITORTYPE_SERVICE_CHECK) + // Options + "monitor_thresholds": { + Description: "Alert thresholds of the monitor.", + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ok": { + Description: "The monitor `OK` threshold. Only supported in monitor type `service check`. Must be a number.", + Type: schema.TypeString, + ValidateFunc: validators.ValidateFloatString, + Optional: true, + DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { + monitorType := d.Get("type").(string) + return monitorType != string(datadogV1.MONITORTYPE_SERVICE_CHECK) + }, }, - }, - "warning": { - Description: "The monitor `WARNING` threshold. Must be a number.", - Type: schema.TypeString, - ValidateFunc: validators.ValidateFloatString, - Optional: true, - }, - "critical": { - Description: "The monitor `CRITICAL` threshold. Must be a number.", - Type: schema.TypeString, - ValidateFunc: validators.ValidateFloatString, - Optional: true, - }, - "unknown": { - Description: "The monitor `UNKNOWN` threshold. Only supported in monitor type `service check`. Must be a number.", - Type: schema.TypeString, - ValidateFunc: validators.ValidateFloatString, - Optional: true, - DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { - monitorType := d.Get("type").(string) - return monitorType != string(datadogV1.MONITORTYPE_SERVICE_CHECK) + "warning": { + Description: "The monitor `WARNING` threshold. Must be a number.", + Type: schema.TypeString, + ValidateFunc: validators.ValidateFloatString, + Optional: true, + }, + "critical": { + Description: "The monitor `CRITICAL` threshold. Must be a number.", + Type: schema.TypeString, + ValidateFunc: validators.ValidateFloatString, + Optional: true, + }, + "unknown": { + Description: "The monitor `UNKNOWN` threshold. Only supported in monitor type `service check`. Must be a number.", + Type: schema.TypeString, + ValidateFunc: validators.ValidateFloatString, + Optional: true, + DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { + monitorType := d.Get("type").(string) + return monitorType != string(datadogV1.MONITORTYPE_SERVICE_CHECK) + }, + }, + "warning_recovery": { + Description: "The monitor `WARNING` recovery threshold. Must be a number.", + Type: schema.TypeString, + ValidateFunc: validators.ValidateFloatString, + Optional: true, + }, + "critical_recovery": { + Description: "The monitor `CRITICAL` recovery threshold. Must be a number.", + Type: schema.TypeString, + ValidateFunc: validators.ValidateFloatString, + Optional: true, }, - }, - "warning_recovery": { - Description: "The monitor `WARNING` recovery threshold. Must be a number.", - Type: schema.TypeString, - ValidateFunc: validators.ValidateFloatString, - Optional: true, - }, - "critical_recovery": { - Description: "The monitor `CRITICAL` recovery threshold. Must be a number.", - Type: schema.TypeString, - ValidateFunc: validators.ValidateFloatString, - Optional: true, }, }, + DiffSuppressFunc: suppressDataDogFloatIntDiff, }, - DiffSuppressFunc: suppressDataDogFloatIntDiff, - }, - "monitor_threshold_windows": { - Description: "A mapping containing `recovery_window` and `trigger_window` values, e.g. `last_15m` . Can only be used for, and are required for, anomaly monitors.", - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "recovery_window": { - Description: "Describes how long an anomalous metric must be normal before the alert recovers.", - Type: schema.TypeString, - Optional: true, - }, - "trigger_window": { - Description: "Describes how long a metric must be anomalous before an alert triggers.", - Type: schema.TypeString, - Optional: true, + "monitor_threshold_windows": { + Description: "A mapping containing `recovery_window` and `trigger_window` values, e.g. `last_15m` . Can only be used for, and are required for, anomaly monitors.", + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "recovery_window": { + Description: "Describes how long an anomalous metric must be normal before the alert recovers.", + Type: schema.TypeString, + Optional: true, + }, + "trigger_window": { + Description: "Describes how long a metric must be anomalous before an alert triggers.", + Type: schema.TypeString, + Optional: true, + }, }, }, }, - }, - "notify_no_data": { - Description: "A boolean indicating whether this monitor will notify when data stops reporting. Defaults to `false`.", - Type: schema.TypeBool, - Optional: true, - Default: false, - ConflictsWith: []string{"on_missing_data"}, - }, - "on_missing_data": { - Description: "Controls how groups or monitors are treated if an evaluation does not return any data points. The default option results in different behavior depending on the monitor query type. For monitors using `Count` queries, an empty monitor evaluation is treated as 0 and is compared to the threshold conditions. For monitors using any query type other than `Count`, for example `Gauge`, `Measure`, or `Rate`, the monitor shows the last known status. This option is only available for APM Trace Analytics, Audit Trail, CI, Error Tracking, Event, Logs, and RUM monitors. Valid values are: `show_no_data`, `show_and_notify_no_data`, `resolve`, and `default`.", - Type: schema.TypeString, - Optional: true, - ConflictsWith: []string{"notify_no_data", "no_data_timeframe"}, - }, - "group_retention_duration": { - Description: "The time span after which groups with missing data are dropped from the monitor state. The minimum value is one hour, and the maximum value is 72 hours. Example values are: 60m, 1h, and 2d. This option is only available for APM Trace Analytics, Audit Trail, CI, Error Tracking, Event, Logs, and RUM monitors.", - Type: schema.TypeString, - Optional: true, - }, - // We only set new_group_delay in the monitor API payload if it is nonzero - // because the SDKv2 terraform plugin API prevents unsetting new_group_delay - // in updateMonitorState, so we can't reliably distinguish between new_group_delay - // being unset (null) or set to zero. - // Note that "new_group_delay overrides new_host_delay if it is set to a nonzero value" - // refers to this terraform resource. In the API, setting new_group_delay - // to any value, including zero, causes it to override new_host_delay. - "new_group_delay": { - Description: "The time (in seconds) to skip evaluations for new groups.\n\n`new_group_delay` overrides `new_host_delay` if it is set to a nonzero value.", - Type: schema.TypeInt, - Optional: true, - }, - "new_host_delay": { - // Removing the default requires removing the default in the API as well (possibly only for - // terraform user agents) - Description: "**Deprecated**. See `new_group_delay`. Time (in seconds) to allow a host to boot and applications to fully start before starting the evaluation of monitor results. Should be a non-negative integer. This value is ignored for simple monitors and monitors not grouped by host. Defaults to `300`. The only case when this should be used is to override the default and set `new_host_delay` to zero for monitors grouped by host.", - Type: schema.TypeInt, - Optional: true, - Default: 300, - Deprecated: "Use `new_group_delay` except when setting `new_host_delay` to zero.", - }, - "evaluation_delay": { - Description: "(Only applies to metric alert) Time (in seconds) to delay evaluation, as a non-negative integer.\n\nFor example, if the value is set to `300` (5min), the `timeframe` is set to `last_5m` and the time is 7:00, the monitor will evaluate data from 6:50 to 6:55. This is useful for AWS CloudWatch and other backfilled metrics to ensure the monitor will always have data during evaluation.", - Type: schema.TypeInt, - Computed: true, - Optional: true, - }, - "no_data_timeframe": { - Description: "The number of minutes before a monitor will notify when data stops reporting. Provider defaults to 10 minutes.\n\nWe recommend at least 2x the monitor timeframe for metric alerts or 2 minutes for service checks.", - Type: schema.TypeInt, - Optional: true, - Default: defaultNoDataTimeframeMinutes, - DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { - if !d.Get("notify_no_data").(bool) { - if newVal != oldVal { - log.Printf("[DEBUG] Ignore the no_data_timeframe change of monitor '%s' because notify_no_data is false.", d.Get("name")) + "notify_no_data": { + Description: "A boolean indicating whether this monitor will notify when data stops reporting. Defaults to `false`.", + Type: schema.TypeBool, + Optional: true, + Default: false, + ConflictsWith: []string{"on_missing_data"}, + }, + "on_missing_data": { + Description: "Controls how groups or monitors are treated if an evaluation does not return any data points. The default option results in different behavior depending on the monitor query type. For monitors using `Count` queries, an empty monitor evaluation is treated as 0 and is compared to the threshold conditions. For monitors using any query type other than `Count`, for example `Gauge`, `Measure`, or `Rate`, the monitor shows the last known status. This option is only available for APM Trace Analytics, Audit Trail, CI, Error Tracking, Event, Logs, and RUM monitors. Valid values are: `show_no_data`, `show_and_notify_no_data`, `resolve`, and `default`.", + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"notify_no_data", "no_data_timeframe"}, + }, + "group_retention_duration": { + Description: "The time span after which groups with missing data are dropped from the monitor state. The minimum value is one hour, and the maximum value is 72 hours. Example values are: 60m, 1h, and 2d. This option is only available for APM Trace Analytics, Audit Trail, CI, Error Tracking, Event, Logs, and RUM monitors.", + Type: schema.TypeString, + Optional: true, + }, + // We only set new_group_delay in the monitor API payload if it is nonzero + // because the SDKv2 terraform plugin API prevents unsetting new_group_delay + // in updateMonitorState, so we can't reliably distinguish between new_group_delay + // being unset (null) or set to zero. + // Note that "new_group_delay overrides new_host_delay if it is set to a nonzero value" + // refers to this terraform resource. In the API, setting new_group_delay + // to any value, including zero, causes it to override new_host_delay. + "new_group_delay": { + Description: "The time (in seconds) to skip evaluations for new groups.\n\n`new_group_delay` overrides `new_host_delay` if it is set to a nonzero value.", + Type: schema.TypeInt, + Optional: true, + }, + "new_host_delay": { + // Removing the default requires removing the default in the API as well (possibly only for + // terraform user agents) + Description: "**Deprecated**. See `new_group_delay`. Time (in seconds) to allow a host to boot and applications to fully start before starting the evaluation of monitor results. Should be a non-negative integer. This value is ignored for simple monitors and monitors not grouped by host. Defaults to `300`. The only case when this should be used is to override the default and set `new_host_delay` to zero for monitors grouped by host.", + Type: schema.TypeInt, + Optional: true, + Default: 300, + Deprecated: "Use `new_group_delay` except when setting `new_host_delay` to zero.", + }, + "evaluation_delay": { + Description: "(Only applies to metric alert) Time (in seconds) to delay evaluation, as a non-negative integer.\n\nFor example, if the value is set to `300` (5min), the `timeframe` is set to `last_5m` and the time is 7:00, the monitor will evaluate data from 6:50 to 6:55. This is useful for AWS CloudWatch and other backfilled metrics to ensure the monitor will always have data during evaluation.", + Type: schema.TypeInt, + Computed: true, + Optional: true, + }, + "no_data_timeframe": { + Description: "The number of minutes before a monitor will notify when data stops reporting. Provider defaults to 10 minutes.\n\nWe recommend at least 2x the monitor timeframe for metric alerts or 2 minutes for service checks.", + Type: schema.TypeInt, + Optional: true, + Default: defaultNoDataTimeframeMinutes, + DiffSuppressFunc: func(k, oldVal, newVal string, d *schema.ResourceData) bool { + if !d.Get("notify_no_data").(bool) { + if newVal != oldVal { + log.Printf("[DEBUG] Ignore the no_data_timeframe change of monitor '%s' because notify_no_data is false.", d.Get("name")) + } + return true } - return true - } - return newVal == oldVal + return newVal == oldVal + }, + ConflictsWith: []string{"on_missing_data"}, }, - ConflictsWith: []string{"on_missing_data"}, - }, - "renotify_interval": { - Description: "The number of minutes after the last notification before a monitor will re-notify on the current status. It will only re-notify if it's not resolved.", - Type: schema.TypeInt, - Optional: true, - }, - "renotify_occurrences": { - Description: "The number of re-notification messages that should be sent on the current status.", - Type: schema.TypeInt, - Optional: true, - }, - "renotify_statuses": { - Description: "The types of statuses for which re-notification messages should be sent.", - Type: schema.TypeSet, - Elem: &schema.Schema{ - Type: schema.TypeString, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewMonitorRenotifyStatusTypeFromValue), + "renotify_interval": { + Description: "The number of minutes after the last notification before a monitor will re-notify on the current status. It will only re-notify if it's not resolved.", + Type: schema.TypeInt, + Optional: true, }, - Optional: true, - }, - "notify_audit": { - Description: "A boolean indicating whether tagged users will be notified on changes to this monitor. Defaults to `false`.", - Type: schema.TypeBool, - Optional: true, - }, - "timeout_h": { - Description: "The number of hours of the monitor not reporting data before it automatically resolves from a triggered state. The minimum allowed value is 0 hours. The maximum allowed value is 24 hours.", - Type: schema.TypeInt, - Optional: true, - }, - "require_full_window": { - Description: "A boolean indicating whether this monitor needs a full window of data before it's evaluated.\n\nWe highly recommend you set this to `false` for sparse metrics, otherwise some evaluations will be skipped. Default: `true` for `on average`, `at all times` and `in total` aggregation. `false` otherwise.", - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "locked": { - Description: "A boolean indicating whether changes to this monitor should be restricted to the creator or admins. Defaults to `false`.", - Type: schema.TypeBool, - Optional: true, - Deprecated: "Use `restricted_roles`.", - ConflictsWith: []string{"restricted_roles"}, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - // if restricted_roles is defined, ignore locked - if _, ok := d.GetOk("restricted_roles"); ok { - return true - } - return false + "renotify_occurrences": { + Description: "The number of re-notification messages that should be sent on the current status.", + Type: schema.TypeInt, + Optional: true, }, - }, - "restricted_roles": { - Description: "A list of unique role identifiers to define which roles are allowed to edit the monitor. Editing a monitor includes any updates to the monitor configuration, monitor deletion, and muting of the monitor for any amount of time. Roles unique identifiers can be pulled from the [Roles API](https://docs.datadoghq.com/api/latest/roles/#list-roles) in the `data.id` field.", - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - ConflictsWith: []string{"locked"}, - }, - "include_tags": { - Description: "A boolean indicating whether notifications from this monitor automatically insert its triggering tags into the title. Defaults to `true`.", - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "tags": { - Description: "A list of tags to associate with your monitor. This can help you categorize and filter monitors in the manage monitors page of the UI. Note: it's not currently possible to filter by these tags when querying via the API", - // we use TypeSet to represent tags, paradoxically to be able to maintain them ordered; - // we order them explicitly in the read/create/update methods of this resource and using - // TypeSet makes Terraform ignore differences in order when creating a plan - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "groupby_simple_monitor": { - Description: "Whether or not to trigger one alert if any source breaches a threshold. This is only used by log monitors. Defaults to `false`.", - Type: schema.TypeBool, - Optional: true, - }, - "notify_by": { - Description: "Controls what granularity a monitor alerts on. Only available for monitors with groupings. For instance, a monitor grouped by `cluster`, `namespace`, and `pod` can be configured to only notify on each new `cluster` violating the alert conditions by setting `notify_by` to `['cluster']`. Tags mentioned in `notify_by` must be a subset of the grouping tags in the query. For example, a query grouped by `cluster` and `namespace` cannot notify on `region`. Setting `notify_by` to `[*]` configures the monitor to notify as a simple-alert.", - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - // since this is only useful for "log alert" type, we don't set a default value - // if we did set it, it would be used for all types; we have to handle this manually - // throughout the code - "enable_logs_sample": { - Description: "A boolean indicating whether or not to include a list of log values which triggered the alert. This is only used by log monitors. Defaults to `false`.", - Type: schema.TypeBool, - Optional: true, - }, - "enable_samples": { - Description: "Whether or not a list of samples which triggered the alert is included. This is only used by CI Test and Pipeline monitors.", - Type: schema.TypeBool, - Computed: true, - }, - "force_delete": { - Description: "A boolean indicating whether this monitor can be deleted even if it’s referenced by other resources (e.g. SLO, composite monitor).", - Type: schema.TypeBool, - Optional: true, - }, - "validate": { - Description: "If set to `false`, skip the validation call done during plan.", - Type: schema.TypeBool, - Optional: true, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - // This is never sent to the backend, so it should never generate a diff - return true + "renotify_statuses": { + Description: "The types of statuses for which re-notification messages should be sent.", + Type: schema.TypeSet, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewMonitorRenotifyStatusTypeFromValue), + }, + Optional: true, }, - }, - "variables": getMonitorFormulaQuerySchema(), - "scheduling_options": { - Description: "Configuration options for scheduling.", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "evaluation_window": { - Description: "Configuration options for the evaluation window. If `hour_starts` is set, no other fields may be set. Otherwise, `day_starts` and `month_starts` must be set together.", - Type: schema.TypeList, - Required: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "day_starts": { - Description: "The time of the day at which a one day cumulative evaluation window starts. Must be defined in UTC time in `HH:mm` format.", - Type: schema.TypeString, - Optional: true, - }, - "month_starts": { - Description: "The day of the month at which a one month cumulative evaluation window starts. Must be a value of 1.", - Type: schema.TypeInt, - Optional: true, - }, - "hour_starts": { - Description: "The minute of the hour at which a one hour cumulative evaluation window starts. Must be between 0 and 59.", - Type: schema.TypeInt, - Optional: true, + "notify_audit": { + Description: "A boolean indicating whether tagged users will be notified on changes to this monitor. Defaults to `false`.", + Type: schema.TypeBool, + Optional: true, + }, + "timeout_h": { + Description: "The number of hours of the monitor not reporting data before it automatically resolves from a triggered state. The minimum allowed value is 0 hours. The maximum allowed value is 24 hours.", + Type: schema.TypeInt, + Optional: true, + }, + "require_full_window": { + Description: "A boolean indicating whether this monitor needs a full window of data before it's evaluated.\n\nWe highly recommend you set this to `false` for sparse metrics, otherwise some evaluations will be skipped. Default: `true` for `on average`, `at all times` and `in total` aggregation. `false` otherwise.", + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "locked": { + Description: "A boolean indicating whether changes to this monitor should be restricted to the creator or admins. Defaults to `false`.", + Type: schema.TypeBool, + Optional: true, + Deprecated: "Use `restricted_roles`.", + ConflictsWith: []string{"restricted_roles"}, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + // if restricted_roles is defined, ignore locked + if _, ok := d.GetOk("restricted_roles"); ok { + return true + } + return false + }, + }, + "restricted_roles": { + Description: "A list of unique role identifiers to define which roles are allowed to edit the monitor. Editing a monitor includes any updates to the monitor configuration, monitor deletion, and muting of the monitor for any amount of time. Roles unique identifiers can be pulled from the [Roles API](https://docs.datadoghq.com/api/latest/roles/#list-roles) in the `data.id` field.", + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + ConflictsWith: []string{"locked"}, + }, + "include_tags": { + Description: "A boolean indicating whether notifications from this monitor automatically insert its triggering tags into the title. Defaults to `true`.", + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "tags": { + Description: "A list of tags to associate with your monitor. This can help you categorize and filter monitors in the manage monitors page of the UI. Note: it's not currently possible to filter by these tags when querying via the API", + // we use TypeSet to represent tags, paradoxically to be able to maintain them ordered; + // we order them explicitly in the read/create/update methods of this resource and using + // TypeSet makes Terraform ignore differences in order when creating a plan + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "groupby_simple_monitor": { + Description: "Whether or not to trigger one alert if any source breaches a threshold. This is only used by log monitors. Defaults to `false`.", + Type: schema.TypeBool, + Optional: true, + }, + "notify_by": { + Description: "Controls what granularity a monitor alerts on. Only available for monitors with groupings. For instance, a monitor grouped by `cluster`, `namespace`, and `pod` can be configured to only notify on each new `cluster` violating the alert conditions by setting `notify_by` to `['cluster']`. Tags mentioned in `notify_by` must be a subset of the grouping tags in the query. For example, a query grouped by `cluster` and `namespace` cannot notify on `region`. Setting `notify_by` to `[*]` configures the monitor to notify as a simple-alert.", + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + // since this is only useful for "log alert" type, we don't set a default value + // if we did set it, it would be used for all types; we have to handle this manually + // throughout the code + "enable_logs_sample": { + Description: "A boolean indicating whether or not to include a list of log values which triggered the alert. This is only used by log monitors. Defaults to `false`.", + Type: schema.TypeBool, + Optional: true, + }, + "enable_samples": { + Description: "Whether or not a list of samples which triggered the alert is included. This is only used by CI Test and Pipeline monitors.", + Type: schema.TypeBool, + Computed: true, + }, + "force_delete": { + Description: "A boolean indicating whether this monitor can be deleted even if it’s referenced by other resources (e.g. SLO, composite monitor).", + Type: schema.TypeBool, + Optional: true, + }, + "validate": { + Description: "If set to `false`, skip the validation call done during plan.", + Type: schema.TypeBool, + Optional: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + // This is never sent to the backend, so it should never generate a diff + return true + }, + }, + "variables": getMonitorFormulaQuerySchema(), + "scheduling_options": { + Description: "Configuration options for scheduling.", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "evaluation_window": { + Description: "Configuration options for the evaluation window. If `hour_starts` is set, no other fields may be set. Otherwise, `day_starts` and `month_starts` must be set together.", + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "day_starts": { + Description: "The time of the day at which a one day cumulative evaluation window starts. Must be defined in UTC time in `HH:mm` format.", + Type: schema.TypeString, + Optional: true, + }, + "month_starts": { + Description: "The day of the month at which a one month cumulative evaluation window starts. Must be a value of 1.", + Type: schema.TypeInt, + Optional: true, + }, + "hour_starts": { + Description: "The minute of the hour at which a one hour cumulative evaluation window starts. Must be between 0 and 59.", + Type: schema.TypeInt, + Optional: true, + }, }, }, }, }, }, }, - }, - "notification_preset_name": { - Description: "Toggles the display of additional content sent in the monitor notification.", - Type: schema.TypeString, - Optional: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewMonitorOptionsNotificationPresetsFromValue), - }, + "notification_preset_name": { + Description: "Toggles the display of additional content sent in the monitor notification.", + Type: schema.TypeString, + Optional: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewMonitorOptionsNotificationPresetsFromValue), + }, + } }, } } diff --git a/datadog/resource_datadog_monitor_config_policy.go b/datadog/resource_datadog_monitor_config_policy.go index 958c625b9..e185b644f 100644 --- a/datadog/resource_datadog_monitor_config_policy.go +++ b/datadog/resource_datadog_monitor_config_policy.go @@ -22,39 +22,41 @@ func resourceDatadogMonitorConfigPolicy() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "policy_type": { - Description: "The monitor config policy type", - Type: schema.TypeString, - Required: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewMonitorConfigPolicyTypeFromValue), - }, - "tag_policy": { - Description: "Config for a tag policy. Only set if `policy_type` is `tag`.", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "tag_key": { - Type: schema.TypeString, - Description: "The key of the tag", - Required: true, - }, - "tag_key_required": { - Type: schema.TypeBool, - Description: "If a tag key is required for monitor creation", - Required: true, - }, - "valid_tag_values": { - Type: schema.TypeList, - Description: "Valid values for the tag", - Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "policy_type": { + Description: "The monitor config policy type", + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewMonitorConfigPolicyTypeFromValue), + }, + "tag_policy": { + Description: "Config for a tag policy. Only set if `policy_type` is `tag`.", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "tag_key": { + Type: schema.TypeString, + Description: "The key of the tag", + Required: true, + }, + "tag_key_required": { + Type: schema.TypeBool, + Description: "If a tag key is required for monitor creation", + Required: true, + }, + "valid_tag_values": { + Type: schema.TypeList, + Description: "Valid values for the tag", + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, }, }, }, - }, + } }, } } diff --git a/datadog/resource_datadog_monitor_json.go b/datadog/resource_datadog_monitor_json.go index 4673050d0..aa271f88a 100644 --- a/datadog/resource_datadog_monitor_json.go +++ b/datadog/resource_datadog_monitor_json.go @@ -63,45 +63,47 @@ func resourceDatadogMonitorJSON() *schema.Resource { return oldType != newType }), - Schema: map[string]*schema.Schema{ - "monitor": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringIsJSON, - StateFunc: func(v interface{}) string { - // Remove computed fields when comparing diffs - attrMap, _ := structure.ExpandJsonFromString(v.(string)) - for _, f := range monitorComputedFields { - utils.DeleteKeyInMap(attrMap, strings.Split(f, ".")) - } - if name, ok := attrMap["name"]; ok { - if name, ok := name.(string); ok { - attrMap["name"] = strings.TrimSpace(name) + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "monitor": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsJSON, + StateFunc: func(v interface{}) string { + // Remove computed fields when comparing diffs + attrMap, _ := structure.ExpandJsonFromString(v.(string)) + for _, f := range monitorComputedFields { + utils.DeleteKeyInMap(attrMap, strings.Split(f, ".")) } - } - if msg, ok := attrMap["message"]; ok { - if msg, ok := msg.(string); ok { - attrMap["message"] = strings.TrimSpace(msg) + if name, ok := attrMap["name"]; ok { + if name, ok := name.(string); ok { + attrMap["name"] = strings.TrimSpace(name) + } + } + if msg, ok := attrMap["message"]; ok { + if msg, ok := msg.(string); ok { + attrMap["message"] = strings.TrimSpace(msg) + } } - } - // restricted_roles is a special case and exporting the field from UI does not include this field. But the api - // returns a `null` value on creation. If null we remove the field from state to avoid unnecessary diffs. - if val := reflect.ValueOf(attrMap["restricted_roles"]); !val.IsValid() { - utils.DeleteKeyInMap(attrMap, []string{"restricted_roles"}) - } + // restricted_roles is a special case and exporting the field from UI does not include this field. But the api + // returns a `null` value on creation. If null we remove the field from state to avoid unnecessary diffs. + if val := reflect.ValueOf(attrMap["restricted_roles"]); !val.IsValid() { + utils.DeleteKeyInMap(attrMap, []string{"restricted_roles"}) + } - res, _ := structure.FlattenJsonToString(attrMap) - return res + res, _ := structure.FlattenJsonToString(attrMap) + return res + }, + Description: "The JSON formatted definition of the monitor.", }, - Description: "The JSON formatted definition of the monitor.", - }, - "url": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The URL of the monitor.", - }, + "url": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The URL of the monitor.", + }, + } }, } } diff --git a/datadog/resource_datadog_organization_settings.go b/datadog/resource_datadog_organization_settings.go index 05b61ef2d..2e3188f18 100644 --- a/datadog/resource_datadog_organization_settings.go +++ b/datadog/resource_datadog_organization_settings.go @@ -22,139 +22,141 @@ func resourceDatadogOrganizationSettings() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Description: "Name for Organization.", - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringLenBetween(1, 32), - }, - "public_id": { - Description: "The `public_id` of the organization you are operating within.", - Type: schema.TypeString, - Computed: true, - }, - "description": { - Description: "Description of the organization.", - Type: schema.TypeString, - Computed: true, - }, - "settings": { - Description: "Organization settings", - Type: schema.TypeList, - Optional: true, - Computed: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "private_widget_share": { - Type: schema.TypeBool, - Optional: true, - Default: false, - Description: "Whether or not the organization users can share widgets outside of Datadog.", - }, - "saml": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, - Description: "SAML properties", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: false, - Description: "Whether or not SAML is enabled for this organization.", + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "Name for Organization.", + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 32), + }, + "public_id": { + Description: "The `public_id` of the organization you are operating within.", + Type: schema.TypeString, + Computed: true, + }, + "description": { + Description: "Description of the organization.", + Type: schema.TypeString, + Computed: true, + }, + "settings": { + Description: "Organization settings", + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "private_widget_share": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Whether or not the organization users can share widgets outside of Datadog.", + }, + "saml": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Description: "SAML properties", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Whether or not SAML is enabled for this organization.", + }, }, }, }, - }, - "saml_autocreate_access_role": { - Type: schema.TypeString, - Optional: true, - Default: "st", - Description: "The access role of the user. Options are `st` (standard user), `adm` (admin user), or `ro` (read-only user). Allowed enum values: `st`, `adm` , `ro`, `ERROR`", - ValidateFunc: validation.StringInSlice([]string{"st", "adm", "ro", "ERROR"}, false), - }, - "saml_autocreate_users_domains": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, - Description: "List of domains where the SAML automated user creation is enabled.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "domains": { - Type: schema.TypeList, - Optional: true, - Description: "List of domains where the SAML automated user creation is enabled.", - Elem: &schema.Schema{ - Type: schema.TypeString, + "saml_autocreate_access_role": { + Type: schema.TypeString, + Optional: true, + Default: "st", + Description: "The access role of the user. Options are `st` (standard user), `adm` (admin user), or `ro` (read-only user). Allowed enum values: `st`, `adm` , `ro`, `ERROR`", + ValidateFunc: validation.StringInSlice([]string{"st", "adm", "ro", "ERROR"}, false), + }, + "saml_autocreate_users_domains": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Description: "List of domains where the SAML automated user creation is enabled.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "domains": { + Type: schema.TypeList, + Optional: true, + Description: "List of domains where the SAML automated user creation is enabled.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Whether or not the automated user creation based on SAML domain is enabled.", }, - }, - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: false, - Description: "Whether or not the automated user creation based on SAML domain is enabled.", }, }, }, - }, - "saml_can_be_enabled": { - Type: schema.TypeBool, - Computed: true, - Description: "Whether or not SAML can be enabled for this organization.", - }, - "saml_idp_endpoint": { - Type: schema.TypeString, - Computed: true, - Description: "Identity provider endpoint for SAML authentication.", - }, - "saml_idp_initiated_login": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, - Description: "Whether or not a SAML identity provider metadata file was provided to the Datadog organization.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: false, - Description: "Whether or not a SAML identity provider metadata file was provided to the Datadog organization.", + "saml_can_be_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether or not SAML can be enabled for this organization.", + }, + "saml_idp_endpoint": { + Type: schema.TypeString, + Computed: true, + Description: "Identity provider endpoint for SAML authentication.", + }, + "saml_idp_initiated_login": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Description: "Whether or not a SAML identity provider metadata file was provided to the Datadog organization.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Whether or not a SAML identity provider metadata file was provided to the Datadog organization.", + }, }, }, }, - }, - "saml_idp_metadata_uploaded": { - Type: schema.TypeBool, - Computed: true, - Description: "Whether or not a SAML identity provider metadata file was provided to the Datadog organization.", - }, - "saml_login_url": { - Type: schema.TypeString, - Computed: true, - Description: "URL for SAML logging.", - }, - "saml_strict_mode": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, - Description: "Whether or not the SAML strict mode is enabled. If true, all users must log in with SAML.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: false, - Description: "Whether or not the SAML strict mode is enabled. If true, all users must log in with SAML.", + "saml_idp_metadata_uploaded": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether or not a SAML identity provider metadata file was provided to the Datadog organization.", + }, + "saml_login_url": { + Type: schema.TypeString, + Computed: true, + Description: "URL for SAML logging.", + }, + "saml_strict_mode": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Description: "Whether or not the SAML strict mode is enabled. If true, all users must log in with SAML.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Whether or not the SAML strict mode is enabled. If true, all users must log in with SAML.", + }, }, }, }, }, }, }, - }, + } }, } } diff --git a/datadog/resource_datadog_role.go b/datadog/resource_datadog_role.go index 3bc701478..330951421 100644 --- a/datadog/resource_datadog_role.go +++ b/datadog/resource_datadog_role.go @@ -29,32 +29,34 @@ func resourceDatadogRole() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, CustomizeDiff: resourceDatadogRoleCustomizeDiff, - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - Description: "Name of the role.", - }, - "permission": { - Type: schema.TypeSet, - Optional: true, - Description: "Set of objects containing the permission ID and the name of the permissions granted to this role.", - Elem: GetRolePermissionSchema(), - }, - "user_count": { - Type: schema.TypeInt, - Computed: true, - Description: "Number of users that have this role.", - }, - "validate": { - Description: "If set to `false`, skip the validation call done during plan.", - Type: schema.TypeBool, - Optional: true, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - // This is never sent to the backend, so it should never generate a diff - return true + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the role.", }, - }, + "permission": { + Type: schema.TypeSet, + Optional: true, + Description: "Set of objects containing the permission ID and the name of the permissions granted to this role.", + Elem: GetRolePermissionSchema(), + }, + "user_count": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of users that have this role.", + }, + "validate": { + Description: "If set to `false`, skip the validation call done during plan.", + Type: schema.TypeBool, + Optional: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + // This is never sent to the backend, so it should never generate a diff + return true + }, + }, + } }, } } diff --git a/datadog/resource_datadog_rum_application.go b/datadog/resource_datadog_rum_application.go index 999ac8b87..8738016cd 100644 --- a/datadog/resource_datadog_rum_application.go +++ b/datadog/resource_datadog_rum_application.go @@ -21,23 +21,25 @@ func resourceDatadogRUMApplication() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the RUM application", - }, - "type": { - Type: schema.TypeString, - Optional: true, - Default: "browser", - Description: "The RUM application type. Supported values are `browser`, `ios`, `android`, `react-native`, `flutter`", - }, - "client_token": { - Type: schema.TypeString, - Computed: true, - Description: "The client token", - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "The name of the RUM application", + }, + "type": { + Type: schema.TypeString, + Optional: true, + Default: "browser", + Description: "The RUM application type. Supported values are `browser`, `ios`, `android`, `react-native`, `flutter`", + }, + "client_token": { + Type: schema.TypeString, + Computed: true, + Description: "The client token", + }, + } }, } } diff --git a/datadog/resource_datadog_security_monitoring_default_rule.go b/datadog/resource_datadog_security_monitoring_default_rule.go index 4ecb112cd..38c2c64ee 100644 --- a/datadog/resource_datadog_security_monitoring_default_rule.go +++ b/datadog/resource_datadog_security_monitoring_default_rule.go @@ -25,80 +25,82 @@ func resourceDatadogSecurityMonitoringDefaultRule() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "case": { - Type: schema.TypeList, - Optional: true, - Description: "Cases of the rule, this is used to update notifications.", - MaxItems: 10, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "status": { - Type: schema.TypeString, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewSecurityMonitoringRuleSeverityFromValue), - Required: true, - Description: "Status of the rule case to match.", - }, - "notifications": { - Type: schema.TypeList, - Required: true, - Description: "Notification targets for each rule case.", - Elem: &schema.Schema{Type: schema.TypeString}, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "case": { + Type: schema.TypeList, + Optional: true, + Description: "Cases of the rule, this is used to update notifications.", + MaxItems: 10, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "status": { + Type: schema.TypeString, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewSecurityMonitoringRuleSeverityFromValue), + Required: true, + Description: "Status of the rule case to match.", + }, + "notifications": { + Type: schema.TypeList, + Required: true, + Description: "Notification targets for each rule case.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, }, }, }, - }, - - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - Description: "Enable the rule.", - }, - - "filter": { - Type: schema.TypeList, - Optional: true, - Description: "Additional queries to filter matched events before they are processed.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "action": { - Type: schema.TypeString, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewSecurityMonitoringFilterActionFromValue), - Required: true, - Description: "The type of filtering action. Allowed enum values: require, suppress", - }, - "query": { - Type: schema.TypeString, - Required: true, - Description: "Query for selecting logs to apply the filtering action.", + + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Enable the rule.", + }, + + "filter": { + Type: schema.TypeList, + Optional: true, + Description: "Additional queries to filter matched events before they are processed.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "action": { + Type: schema.TypeString, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewSecurityMonitoringFilterActionFromValue), + Required: true, + Description: "The type of filtering action. Allowed enum values: require, suppress", + }, + "query": { + Type: schema.TypeString, + Required: true, + Description: "Query for selecting logs to apply the filtering action.", + }, }, }, }, - }, - - "options": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Description: "Options on default rules. Note that only a subset of fields can be updated on default rule options.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "decrease_criticality_based_on_env": { - Type: schema.TypeBool, - Optional: true, - Default: false, - Description: "If true, signals in non-production environments have a lower severity than what is defined by the rule case, which can reduce noise. The decrement is applied when the environment tag of the signal starts with `staging`, `test`, or `dev`. Only available when the rule type is `log_detection`.", + + "options": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Description: "Options on default rules. Note that only a subset of fields can be updated on default rule options.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "decrease_criticality_based_on_env": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "If true, signals in non-production environments have a lower severity than what is defined by the rule case, which can reduce noise. The decrement is applied when the environment tag of the signal starts with `staging`, `test`, or `dev`. Only available when the rule type is `log_detection`.", + }, }, }, }, - }, - "type": { - Type: schema.TypeString, - Computed: true, - Description: "The rule type.", - }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "The rule type.", + }, + } }, } } diff --git a/datadog/resource_datadog_security_monitoring_filters.go b/datadog/resource_datadog_security_monitoring_filters.go index 26b4b95fb..6f7cc337d 100644 --- a/datadog/resource_datadog_security_monitoring_filters.go +++ b/datadog/resource_datadog_security_monitoring_filters.go @@ -26,7 +26,9 @@ func resourceDatadogSecurityMonitoringFilter() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: securityMonitoringFilterSchema(), + SchemaFunc: func() map[string]*schema.Schema { + return securityMonitoringFilterSchema() + }, } } diff --git a/datadog/resource_datadog_security_monitoring_rule.go b/datadog/resource_datadog_security_monitoring_rule.go index 02178da20..94a6467f4 100644 --- a/datadog/resource_datadog_security_monitoring_rule.go +++ b/datadog/resource_datadog_security_monitoring_rule.go @@ -24,7 +24,9 @@ func resourceDatadogSecurityMonitoringRule() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: datadogSecurityMonitoringRuleSchema(), + SchemaFunc: func() map[string]*schema.Schema { + return datadogSecurityMonitoringRuleSchema() + }, } } diff --git a/datadog/resource_datadog_sensitive_data_scanner_group.go b/datadog/resource_datadog_sensitive_data_scanner_group.go index 3d382e222..20960e6fd 100644 --- a/datadog/resource_datadog_sensitive_data_scanner_group.go +++ b/datadog/resource_datadog_sensitive_data_scanner_group.go @@ -23,52 +23,54 @@ func resourceDatadogSensitiveDataScannerGroup() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Description: "Name of the Datadog scanning group.", - Type: schema.TypeString, - Required: true, - }, - "description": { - Description: "Description of the Datadog scanning group.", - Type: schema.TypeString, - Optional: true, - }, - "product_list": { - Description: "List of products the scanning group applies.", - Type: schema.TypeSet, - Required: true, - MaxItems: 4, - Elem: &schema.Schema{ - Type: schema.TypeString, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "Name of the Datadog scanning group.", + Type: schema.TypeString, + Required: true, }, - }, - "is_enabled": { - Description: "Whether or not the scanning group is enabled. If the group doesn't contain any rule or if all the rules in it are disabled, the group is force-disabled by our backend", - Type: schema.TypeBool, - Required: true, - }, - "filter": { - Description: "Filter object the scanning group applies.", - Type: schema.TypeList, - MaxItems: 1, - Required: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "query": { - Description: "Query to filter the events.", - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: func(_, oldVal, newVal string, d *schema.ResourceData) bool { - if (oldVal == "" && newVal == "*") || (oldVal == "*" && newVal == "") { - return true - } - return false + "description": { + Description: "Description of the Datadog scanning group.", + Type: schema.TypeString, + Optional: true, + }, + "product_list": { + Description: "List of products the scanning group applies.", + Type: schema.TypeSet, + Required: true, + MaxItems: 4, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "is_enabled": { + Description: "Whether or not the scanning group is enabled. If the group doesn't contain any rule or if all the rules in it are disabled, the group is force-disabled by our backend", + Type: schema.TypeBool, + Required: true, + }, + "filter": { + Description: "Filter object the scanning group applies.", + Type: schema.TypeList, + MaxItems: 1, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "query": { + Description: "Query to filter the events.", + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: func(_, oldVal, newVal string, d *schema.ResourceData) bool { + if (oldVal == "" && newVal == "*") || (oldVal == "*" && newVal == "") { + return true + } + return false + }, }, }, }, }, - }, + } }, } } diff --git a/datadog/resource_datadog_sensitive_data_scanner_rule.go b/datadog/resource_datadog_sensitive_data_scanner_rule.go index 57c90bed9..11d8c3cac 100644 --- a/datadog/resource_datadog_sensitive_data_scanner_rule.go +++ b/datadog/resource_datadog_sensitive_data_scanner_rule.go @@ -22,92 +22,94 @@ func resourceDatadogSensitiveDataScannerRule() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Optional: true, - Description: "Name of the rule.", - }, - "description": { - Type: schema.TypeString, - Optional: true, - Description: "Description of the rule.", - }, - "group_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "Id of the scanning group the rule belongs to.", - }, - "standard_pattern_id": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "Id of the standard pattern the rule refers to. If provided, then pattern must not be provided.", - }, - "excluded_namespaces": { - Type: schema.TypeList, - Optional: true, - Description: "Attributes excluded from the scan. If namespaces is provided, it has to be a sub-path of the namespaces array.", - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "namespaces": { - Type: schema.TypeList, - Optional: true, - Description: "Attributes included in the scan. If namespaces is empty or missing, all attributes except excluded_namespaces are scanned. If both are missing the whole event is scanned.", - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "is_enabled": { - Type: schema.TypeBool, - Optional: true, - Description: "Whether or not the rule is enabled.", - }, - "pattern": { - Type: schema.TypeString, - Optional: true, - Description: "Not included if there is a relationship to a standard pattern.", - }, - "tags": { - Type: schema.TypeList, - Optional: true, - Description: "List of tags.", - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "text_replacement": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Description: "Object describing how the scanned event will be replaced. Defaults to `type: none`", - DiffSuppressFunc: func(_, _, _ string, d *schema.ResourceData) bool { - old, new := d.GetChange("text_replacement.0.type") - oldS := old.(string) - newS := new.(string) - if (oldS == "" && newS == "none") || (oldS == "none" && newS == "") || (oldS == "none" && newS == "none") { - return true - } - return false + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Name of the rule.", }, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "number_of_chars": { - Type: schema.TypeInt, - Optional: true, - Description: "Required if type == 'partial_replacement_from_beginning' or 'partial_replacement_from_end'. It must be > 0.", - }, - "replacement_string": { - Type: schema.TypeString, - Optional: true, - Description: "Required if type == 'replacement_string'.", - }, - "type": { - Type: schema.TypeString, - Required: true, - Description: "Type of the replacement text. None means no replacement. hash means the data will be stubbed. replacement_string means that one can chose a text to replace the data. partial_replacement_from_beginning allows a user to partially replace the data from the beginning, and partial_replacement_from_end on the other hand, allows to replace data from the end.", - ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewSensitiveDataScannerTextReplacementTypeFromValue), + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Description of the rule.", + }, + "group_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Id of the scanning group the rule belongs to.", + }, + "standard_pattern_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "Id of the standard pattern the rule refers to. If provided, then pattern must not be provided.", + }, + "excluded_namespaces": { + Type: schema.TypeList, + Optional: true, + Description: "Attributes excluded from the scan. If namespaces is provided, it has to be a sub-path of the namespaces array.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "namespaces": { + Type: schema.TypeList, + Optional: true, + Description: "Attributes included in the scan. If namespaces is empty or missing, all attributes except excluded_namespaces are scanned. If both are missing the whole event is scanned.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "is_enabled": { + Type: schema.TypeBool, + Optional: true, + Description: "Whether or not the rule is enabled.", + }, + "pattern": { + Type: schema.TypeString, + Optional: true, + Description: "Not included if there is a relationship to a standard pattern.", + }, + "tags": { + Type: schema.TypeList, + Optional: true, + Description: "List of tags.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "text_replacement": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Description: "Object describing how the scanned event will be replaced. Defaults to `type: none`", + DiffSuppressFunc: func(_, _, _ string, d *schema.ResourceData) bool { + old, new := d.GetChange("text_replacement.0.type") + oldS := old.(string) + newS := new.(string) + if (oldS == "" && newS == "none") || (oldS == "none" && newS == "") || (oldS == "none" && newS == "none") { + return true + } + return false + }, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "number_of_chars": { + Type: schema.TypeInt, + Optional: true, + Description: "Required if type == 'partial_replacement_from_beginning' or 'partial_replacement_from_end'. It must be > 0.", + }, + "replacement_string": { + Type: schema.TypeString, + Optional: true, + Description: "Required if type == 'replacement_string'.", + }, + "type": { + Type: schema.TypeString, + Required: true, + Description: "Type of the replacement text. None means no replacement. hash means the data will be stubbed. replacement_string means that one can chose a text to replace the data. partial_replacement_from_beginning allows a user to partially replace the data from the beginning, and partial_replacement_from_end on the other hand, allows to replace data from the end.", + ValidateDiagFunc: validators.ValidateEnumValue(datadogV2.NewSensitiveDataScannerTextReplacementTypeFromValue), + }, }, }, }, - }, + } }, } } diff --git a/datadog/resource_datadog_service_account.go b/datadog/resource_datadog_service_account.go index f03ea4e8b..1960165b9 100644 --- a/datadog/resource_datadog_service_account.go +++ b/datadog/resource_datadog_service_account.go @@ -22,29 +22,31 @@ func resourceDatadogServiceAccount() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "disabled": { - Description: "Whether the service account is disabled.", - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "email": { - Description: "Email of the associated user.", - Type: schema.TypeString, - Required: true, - }, - "name": { - Description: "Name for the service account.", - Type: schema.TypeString, - Optional: true, - }, - "roles": { - Description: "A list a role IDs to assign to the service account.", - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "disabled": { + Description: "Whether the service account is disabled.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "email": { + Description: "Email of the associated user.", + Type: schema.TypeString, + Required: true, + }, + "name": { + Description: "Name for the service account.", + Type: schema.TypeString, + Optional: true, + }, + "roles": { + Description: "A list a role IDs to assign to the service account.", + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + } }, } } diff --git a/datadog/resource_datadog_service_definition_yaml.go b/datadog/resource_datadog_service_definition_yaml.go index c628c7eda..b6b45d60a 100644 --- a/datadog/resource_datadog_service_definition_yaml.go +++ b/datadog/resource_datadog_service_definition_yaml.go @@ -80,19 +80,21 @@ func resourceDatadogServiceDefinitionYAML() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "service_definition": { - Type: schema.TypeString, - Required: true, - ValidateFunc: isValidServiceDefinition, - StateFunc: func(v interface{}) string { - attrMap, _ := expandYAMLFromString(v.(string)) - prepServiceDefinitionResource(attrMap) - res, _ := flattenYAMLToString(attrMap) - return res + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "service_definition": { + Type: schema.TypeString, + Required: true, + ValidateFunc: isValidServiceDefinition, + StateFunc: func(v interface{}) string { + attrMap, _ := expandYAMLFromString(v.(string)) + prepServiceDefinitionResource(attrMap) + res, _ := flattenYAMLToString(attrMap) + return res + }, + Description: "The YAML/JSON formatted definition of the service", }, - Description: "The YAML/JSON formatted definition of the service", - }, + } }, } } diff --git a/datadog/resource_datadog_service_level_objective.go b/datadog/resource_datadog_service_level_objective.go index 82416ea6b..3f97c0a45 100644 --- a/datadog/resource_datadog_service_level_objective.go +++ b/datadog/resource_datadog_service_level_objective.go @@ -28,157 +28,159 @@ func resourceDatadogServiceLevelObjective() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - // Common - "name": { - Description: "Name of Datadog service level objective", - Type: schema.TypeString, - Required: true, - }, - "description": { - Description: "A description of this service level objective.", - Type: schema.TypeString, - Optional: true, - StateFunc: trimStateValue, - DiffSuppressFunc: diffTrimmedValues, - }, - "tags": { - // we use TypeSet to represent tags, paradoxically to be able to maintain them ordered; - // we order them explicitly in the read/create/update methods of this resource and using - // TypeSet makes Terraform ignore differences in order when creating a plan - Type: schema.TypeSet, - Description: "A list of tags to associate with your service level objective. This can help you categorize and filter service level objectives in the service level objectives page of the UI. Note: it's not currently possible to filter by these tags when querying via the API", - Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - StateFunc: func(val any) string { - return utils.NormalizeTag(val.(string)) - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + // Common + "name": { + Description: "Name of Datadog service level objective", + Type: schema.TypeString, + Required: true, }, - }, - "thresholds": { - Description: "A list of thresholds and targets that define the service level objectives from the provided SLIs.", - Type: schema.TypeList, - Required: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "timeframe": { - Description: "The time frame for the objective. The mapping from these types to the types found in the Datadog Web UI can be found in the Datadog API documentation page.", - Type: schema.TypeString, - Required: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSLOTimeframeFromValue), - }, - "target": { - Description: "The objective's target in `(0,100)`.", - Type: schema.TypeFloat, - Required: true, - DiffSuppressFunc: suppressDataDogFloatIntDiff, - }, - "target_display": { - Description: "A string representation of the target that indicates its precision. It uses trailing zeros to show significant decimal places (e.g. `98.00`).", - Type: schema.TypeString, - Computed: true, - }, - "warning": { - Description: "The objective's warning value in `(0,100)`. This must be greater than the target value.", - Type: schema.TypeFloat, - Optional: true, - DiffSuppressFunc: suppressDataDogFloatIntDiff, - }, - "warning_display": { - Description: "A string representation of the warning target (see the description of the target_display field for details).", - Type: schema.TypeString, - Computed: true, + "description": { + Description: "A description of this service level objective.", + Type: schema.TypeString, + Optional: true, + StateFunc: trimStateValue, + DiffSuppressFunc: diffTrimmedValues, + }, + "tags": { + // we use TypeSet to represent tags, paradoxically to be able to maintain them ordered; + // we order them explicitly in the read/create/update methods of this resource and using + // TypeSet makes Terraform ignore differences in order when creating a plan + Type: schema.TypeSet, + Description: "A list of tags to associate with your service level objective. This can help you categorize and filter service level objectives in the service level objectives page of the UI. Note: it's not currently possible to filter by these tags when querying via the API", + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + StateFunc: func(val any) string { + return utils.NormalizeTag(val.(string)) }, }, }, - }, - "target_threshold": { - Description: "The objective's target in `(0,100)`. This must match the corresponding thresholds of the primary time frame.", - Type: schema.TypeFloat, - Optional: true, - Computed: true, - DiffSuppressFunc: suppressDataDogFloatIntDiff, - }, - "warning_threshold": { - Description: "The objective's warning value in `(0,100)`. This must be greater than the target value and match the corresponding thresholds of the primary time frame.", - Type: schema.TypeFloat, - Optional: true, - Computed: true, - DiffSuppressFunc: suppressDataDogFloatIntDiff, - }, - "timeframe": { - Description: "The primary time frame for the objective. The mapping from these types to the types found in the Datadog Web UI can be found in the Datadog API documentation page.", - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSLOTimeframeFromValue), - }, - "type": { - Description: "The type of the service level objective. The mapping from these types to the types found in the Datadog Web UI can be found in the Datadog API [documentation page](https://docs.datadoghq.com/api/v1/service-level-objectives/#create-a-slo-object).", - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSLOTypeFromValue), - }, - "force_delete": { - Description: "A boolean indicating whether this monitor can be deleted even if it's referenced by other resources (for example, dashboards).", - Type: schema.TypeBool, - Optional: true, - }, - - // Metric-Based SLO - "query": { - // we use TypeList here because of https://github.com/hashicorp/terraform/issues/6215/ - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - ConflictsWith: []string{"monitor_ids", "groups"}, - Description: "The metric query of good / total events", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "numerator": { - Description: "The sum of all the `good` events.", - Type: schema.TypeString, - Required: true, - StateFunc: trimStateValue, - DiffSuppressFunc: diffTrimmedValues, + "thresholds": { + Description: "A list of thresholds and targets that define the service level objectives from the provided SLIs.", + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "timeframe": { + Description: "The time frame for the objective. The mapping from these types to the types found in the Datadog Web UI can be found in the Datadog API documentation page.", + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSLOTimeframeFromValue), + }, + "target": { + Description: "The objective's target in `(0,100)`.", + Type: schema.TypeFloat, + Required: true, + DiffSuppressFunc: suppressDataDogFloatIntDiff, + }, + "target_display": { + Description: "A string representation of the target that indicates its precision. It uses trailing zeros to show significant decimal places (e.g. `98.00`).", + Type: schema.TypeString, + Computed: true, + }, + "warning": { + Description: "The objective's warning value in `(0,100)`. This must be greater than the target value.", + Type: schema.TypeFloat, + Optional: true, + DiffSuppressFunc: suppressDataDogFloatIntDiff, + }, + "warning_display": { + Description: "A string representation of the warning target (see the description of the target_display field for details).", + Type: schema.TypeString, + Computed: true, + }, }, - "denominator": { - Description: "The sum of the `total` events.", - Type: schema.TypeString, - Required: true, - StateFunc: trimStateValue, - DiffSuppressFunc: diffTrimmedValues, + }, + }, + "target_threshold": { + Description: "The objective's target in `(0,100)`. This must match the corresponding thresholds of the primary time frame.", + Type: schema.TypeFloat, + Optional: true, + Computed: true, + DiffSuppressFunc: suppressDataDogFloatIntDiff, + }, + "warning_threshold": { + Description: "The objective's warning value in `(0,100)`. This must be greater than the target value and match the corresponding thresholds of the primary time frame.", + Type: schema.TypeFloat, + Optional: true, + Computed: true, + DiffSuppressFunc: suppressDataDogFloatIntDiff, + }, + "timeframe": { + Description: "The primary time frame for the objective. The mapping from these types to the types found in the Datadog Web UI can be found in the Datadog API documentation page.", + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSLOTimeframeFromValue), + }, + "type": { + Description: "The type of the service level objective. The mapping from these types to the types found in the Datadog Web UI can be found in the Datadog API [documentation page](https://docs.datadoghq.com/api/v1/service-level-objectives/#create-a-slo-object).", + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSLOTypeFromValue), + }, + "force_delete": { + Description: "A boolean indicating whether this monitor can be deleted even if it's referenced by other resources (for example, dashboards).", + Type: schema.TypeBool, + Optional: true, + }, + + // Metric-Based SLO + "query": { + // we use TypeList here because of https://github.com/hashicorp/terraform/issues/6215/ + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + ConflictsWith: []string{"monitor_ids", "groups"}, + Description: "The metric query of good / total events", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "numerator": { + Description: "The sum of all the `good` events.", + Type: schema.TypeString, + Required: true, + StateFunc: trimStateValue, + DiffSuppressFunc: diffTrimmedValues, + }, + "denominator": { + Description: "The sum of the `total` events.", + Type: schema.TypeString, + Required: true, + StateFunc: trimStateValue, + DiffSuppressFunc: diffTrimmedValues, + }, }, }, }, - }, - - // Monitor-Based SLO - "monitor_ids": { - Type: schema.TypeSet, - Optional: true, - ConflictsWith: []string{"query"}, - Description: "A static set of monitor IDs to use as part of the SLO", - Elem: &schema.Schema{Type: schema.TypeInt, MinItems: 1}, - }, - "groups": { - Type: schema.TypeSet, - Optional: true, - Description: "A static set of groups to filter monitor-based SLOs", - ConflictsWith: []string{"query"}, - Elem: &schema.Schema{Type: schema.TypeString, MinItems: 1}, - }, - "validate": { - Description: "Whether or not to validate the SLO.", - Type: schema.TypeBool, - Optional: true, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - // This is never sent to the backend, so it should never generate a diff - return true + + // Monitor-Based SLO + "monitor_ids": { + Type: schema.TypeSet, + Optional: true, + ConflictsWith: []string{"query"}, + Description: "A static set of monitor IDs to use as part of the SLO", + Elem: &schema.Schema{Type: schema.TypeInt, MinItems: 1}, }, - }, + "groups": { + Type: schema.TypeSet, + Optional: true, + Description: "A static set of groups to filter monitor-based SLOs", + ConflictsWith: []string{"query"}, + Elem: &schema.Schema{Type: schema.TypeString, MinItems: 1}, + }, + "validate": { + Description: "Whether or not to validate the SLO.", + Type: schema.TypeBool, + Optional: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + // This is never sent to the backend, so it should never generate a diff + return true + }, + }, + } }, } } diff --git a/datadog/resource_datadog_slo_correction.go b/datadog/resource_datadog_slo_correction.go index 7e4e7b33e..69d947e23 100644 --- a/datadog/resource_datadog_slo_correction.go +++ b/datadog/resource_datadog_slo_correction.go @@ -21,49 +21,51 @@ func resourceDatadogSloCorrection() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "category": { - Type: schema.TypeString, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSLOCorrectionCategoryFromValue), - Required: true, - Description: "Category the SLO correction belongs to.", - }, - "description": { - Type: schema.TypeString, - Optional: true, - Description: "Description of the correction being made.", - }, - "end": { - Type: schema.TypeInt, - Optional: true, - ConflictsWith: []string{"rrule", "duration"}, - Description: "Ending time of the correction in epoch seconds. Required for one time corrections, but optional if `rrule` is specified", - }, - "slo_id": { - Type: schema.TypeString, - Required: true, - Description: "ID of the SLO that this correction will be applied to.", - }, - "start": { - Type: schema.TypeInt, - Required: true, - Description: "Starting time of the correction in epoch seconds.", - }, - "timezone": { - Type: schema.TypeString, - Optional: true, - Description: "The timezone to display in the UI for the correction times (defaults to \"UTC\")", - }, - "duration": { - Type: schema.TypeInt, - Optional: true, - Description: "Length of time in seconds for a specified `rrule` recurring SLO correction (required if specifying `rrule`)", - }, - "rrule": { - Type: schema.TypeString, - Optional: true, - Description: "Recurrence rules as defined in the iCalendar RFC 5545. Supported rules for SLO corrections are `FREQ`, `INTERVAL`, `COUNT` and `UNTIL`.", - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "category": { + Type: schema.TypeString, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSLOCorrectionCategoryFromValue), + Required: true, + Description: "Category the SLO correction belongs to.", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Description of the correction being made.", + }, + "end": { + Type: schema.TypeInt, + Optional: true, + ConflictsWith: []string{"rrule", "duration"}, + Description: "Ending time of the correction in epoch seconds. Required for one time corrections, but optional if `rrule` is specified", + }, + "slo_id": { + Type: schema.TypeString, + Required: true, + Description: "ID of the SLO that this correction will be applied to.", + }, + "start": { + Type: schema.TypeInt, + Required: true, + Description: "Starting time of the correction in epoch seconds.", + }, + "timezone": { + Type: schema.TypeString, + Optional: true, + Description: "The timezone to display in the UI for the correction times (defaults to \"UTC\")", + }, + "duration": { + Type: schema.TypeInt, + Optional: true, + Description: "Length of time in seconds for a specified `rrule` recurring SLO correction (required if specifying `rrule`)", + }, + "rrule": { + Type: schema.TypeString, + Optional: true, + Description: "Recurrence rules as defined in the iCalendar RFC 5545. Supported rules for SLO corrections are `FREQ`, `INTERVAL`, `COUNT` and `UNTIL`.", + }, + } }, } } diff --git a/datadog/resource_datadog_synthetics_global_variable.go b/datadog/resource_datadog_synthetics_global_variable.go index 4d3c4bf00..39fa6e8c2 100644 --- a/datadog/resource_datadog_synthetics_global_variable.go +++ b/datadog/resource_datadog_synthetics_global_variable.go @@ -26,125 +26,127 @@ func resourceDatadogSyntheticsGlobalVariable() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Description: "Synthetics global variable name.", - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[A-Z][A-Z0-9_]+[A-Z0-9]$`), "must be all uppercase with underscores"), - }, - "description": { - Description: "Description of the global variable.", - Type: schema.TypeString, - Optional: true, - }, - "tags": { - Description: "A list of tags to associate with your synthetics global variable.", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "value": { - Description: "The value of the global variable.", - Type: schema.TypeString, - Required: true, - Sensitive: true, - }, - "secure": { - Description: "If set to true, the value of the global variable is hidden. Defaults to `false`.", - Default: false, - Type: schema.TypeBool, - Optional: true, - }, - "parse_test_id": { - Description: "Id of the Synthetics test to use for a variable from test.", - Type: schema.TypeString, - Optional: true, - }, - "parse_test_options": { - Description: "ID of the Synthetics test to use a source of the global variable value.", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "field": { - Description: "Required when type = `http_header`. Defines the header to use to extract the value", - Type: schema.TypeString, - Optional: true, - }, - "type": { - Description: "Defines the source to use to extract the value.", - Type: schema.TypeString, - Required: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSyntheticsGlobalVariableParseTestOptionsTypeFromValue), - }, - "parser": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - Description: "Type of parser to extract the value.", - Type: schema.TypeString, - Required: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSyntheticsGlobalVariableParserTypeFromValue), - }, - "value": { - Description: "Value for the parser to use, required for type `json_path` or `regex`.", - Type: schema.TypeString, - Optional: true, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "Synthetics global variable name.", + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[A-Z][A-Z0-9_]+[A-Z0-9]$`), "must be all uppercase with underscores"), + }, + "description": { + Description: "Description of the global variable.", + Type: schema.TypeString, + Optional: true, + }, + "tags": { + Description: "A list of tags to associate with your synthetics global variable.", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "value": { + Description: "The value of the global variable.", + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "secure": { + Description: "If set to true, the value of the global variable is hidden. Defaults to `false`.", + Default: false, + Type: schema.TypeBool, + Optional: true, + }, + "parse_test_id": { + Description: "Id of the Synthetics test to use for a variable from test.", + Type: schema.TypeString, + Optional: true, + }, + "parse_test_options": { + Description: "ID of the Synthetics test to use a source of the global variable value.", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "field": { + Description: "Required when type = `http_header`. Defines the header to use to extract the value", + Type: schema.TypeString, + Optional: true, + }, + "type": { + Description: "Defines the source to use to extract the value.", + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSyntheticsGlobalVariableParseTestOptionsTypeFromValue), + }, + "parser": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Description: "Type of parser to extract the value.", + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSyntheticsGlobalVariableParserTypeFromValue), + }, + "value": { + Description: "Value for the parser to use, required for type `json_path` or `regex`.", + Type: schema.TypeString, + Optional: true, + }, }, }, }, - }, - "local_variable_name": { - Type: schema.TypeString, - Description: "When type is `local_variable`, name of the local variable to use to extract the value.", - Optional: true, + "local_variable_name": { + Type: schema.TypeString, + Description: "When type is `local_variable`, name of the local variable to use to extract the value.", + Optional: true, + }, }, }, }, - }, - "options": { - Description: "Additional options for the variable, such as a MFA token.", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "totp_parameters": { - Description: "Parameters needed for MFA/TOTP.", - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "digits": { - Description: "Number of digits for the OTP.", - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntBetween(4, 10), - }, - "refresh_interval": { - Description: "Interval for which to refresh the token (in seconds).", - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntBetween(0, 999), + "options": { + Description: "Additional options for the variable, such as a MFA token.", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "totp_parameters": { + Description: "Parameters needed for MFA/TOTP.", + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "digits": { + Description: "Number of digits for the OTP.", + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(4, 10), + }, + "refresh_interval": { + Description: "Interval for which to refresh the token (in seconds).", + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(0, 999), + }, }, }, }, }, }, }, - }, - "restricted_roles": { - Description: "A list of role identifiers to associate with the Synthetics global variable.", - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Optional: true, - }, + "restricted_roles": { + Description: "A list of role identifiers to associate with the Synthetics global variable.", + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + }, + } }, } } diff --git a/datadog/resource_datadog_synthetics_private_location.go b/datadog/resource_datadog_synthetics_private_location.go index bad75f128..ead647f4a 100644 --- a/datadog/resource_datadog_synthetics_private_location.go +++ b/datadog/resource_datadog_synthetics_private_location.go @@ -24,38 +24,40 @@ func resourceDatadogSyntheticsPrivateLocation() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Description: "Synthetics private location name.", - Type: schema.TypeString, - Required: true, - }, - "description": { - Description: "Description of the private location.", - Type: schema.TypeString, - Optional: true, - }, - "tags": { - Description: "A list of tags to associate with your synthetics private location.", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "config": { - Description: "Configuration skeleton for the private location. See installation instructions of the private location on how to use this configuration.", - Type: schema.TypeString, - Computed: true, - Sensitive: true, - }, - "metadata": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "The private location metadata", - Elem: &schema.Resource{ - Schema: syntheticsPrivateLocationMetadata(), + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "Synthetics private location name.", + Type: schema.TypeString, + Required: true, }, - }, + "description": { + Description: "Description of the private location.", + Type: schema.TypeString, + Optional: true, + }, + "tags": { + Description: "A list of tags to associate with your synthetics private location.", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "config": { + Description: "Configuration skeleton for the private location. See installation instructions of the private location on how to use this configuration.", + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + "metadata": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Description: "The private location metadata", + Elem: &schema.Resource{ + Schema: syntheticsPrivateLocationMetadata(), + }, + }, + } }, } } diff --git a/datadog/resource_datadog_synthetics_test_.go b/datadog/resource_datadog_synthetics_test_.go index 5d316419b..982ce6e6d 100644 --- a/datadog/resource_datadog_synthetics_test_.go +++ b/datadog/resource_datadog_synthetics_test_.go @@ -32,94 +32,96 @@ func resourceDatadogSyntheticsTest() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "type": { - Description: "Synthetics test type.", - Type: schema.TypeString, - Required: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSyntheticsTestDetailsTypeFromValue), - }, - "subtype": { - Description: "The subtype of the Synthetic API test. Defaults to `http`.", - Type: schema.TypeString, - Optional: true, - DiffSuppressFunc: func(key, old, new string, d *schema.ResourceData) bool { - if d.Get("type") == "api" && old == "http" && new == "" { - // defaults to http if type is api for retro-compatibility - return true - } - return old == new + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "type": { + Description: "Synthetics test type.", + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSyntheticsTestDetailsTypeFromValue), }, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSyntheticsTestDetailsSubTypeFromValue), - }, - "request_definition": { - Description: "Required if `type = \"api\"`. The synthetics test request.", - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Elem: syntheticsTestRequest(), - }, - "request_headers": syntheticsTestRequestHeaders(), - "request_query": syntheticsTestRequestQuery(), - "request_basicauth": syntheticsTestRequestBasicAuth(), - "request_proxy": syntheticsTestRequestProxy(), - "request_client_certificate": syntheticsTestRequestClientCertificate(), - "assertion": syntheticsAPIAssertion(), - "browser_variable": syntheticsBrowserVariable(), - "config_variable": syntheticsConfigVariable(), - "device_ids": { - Description: "Required if `type = \"browser\"`. Array with the different device IDs used to run the test.", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{ + "subtype": { + Description: "The subtype of the Synthetic API test. Defaults to `http`.", + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: func(key, old, new string, d *schema.ResourceData) bool { + if d.Get("type") == "api" && old == "http" && new == "" { + // defaults to http if type is api for retro-compatibility + return true + } + return old == new + }, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSyntheticsTestDetailsSubTypeFromValue), + }, + "request_definition": { + Description: "Required if `type = \"api\"`. The synthetics test request.", + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: syntheticsTestRequest(), + }, + "request_headers": syntheticsTestRequestHeaders(), + "request_query": syntheticsTestRequestQuery(), + "request_basicauth": syntheticsTestRequestBasicAuth(), + "request_proxy": syntheticsTestRequestProxy(), + "request_client_certificate": syntheticsTestRequestClientCertificate(), + "assertion": syntheticsAPIAssertion(), + "browser_variable": syntheticsBrowserVariable(), + "config_variable": syntheticsConfigVariable(), + "device_ids": { + Description: "Required if `type = \"browser\"`. Array with the different device IDs used to run the test.", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSyntheticsDeviceIDFromValue), + }, + }, + "locations": { + Description: "Array of locations used to run the test. Refer to [the Datadog Synthetics location data source](https://registry.terraform.io/providers/DataDog/datadog/latest/docs/data-sources/synthetics_locations) to retrieve the list of locations.", + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "options_list": syntheticsTestOptionsList(), + "name": { + Description: "Name of Datadog synthetics test.", + Type: schema.TypeString, + Required: true, + }, + "message": { + Description: "A message to include with notifications for this synthetics test. Email notifications can be sent to specific users by using the same `@username` notation as events.", + Type: schema.TypeString, + Optional: true, + Default: "", + }, + "tags": { + Description: "A list of tags to associate with your synthetics test. This can help you categorize and filter tests in the manage synthetics page of the UI. Default is an empty list (`[]`).", + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "status": { + Description: "Define whether you want to start (`live`) or pause (`paused`) a Synthetic test.", Type: schema.TypeString, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSyntheticsDeviceIDFromValue), + Required: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSyntheticsTestPauseStatusFromValue), }, - }, - "locations": { - Description: "Array of locations used to run the test. Refer to [the Datadog Synthetics location data source](https://registry.terraform.io/providers/DataDog/datadog/latest/docs/data-sources/synthetics_locations) to retrieve the list of locations.", - Type: schema.TypeSet, - Required: true, - Elem: &schema.Schema{ - Type: schema.TypeString, + "monitor_id": { + Description: "ID of the monitor associated with the Datadog synthetics test.", + Type: schema.TypeInt, + Computed: true, }, - }, - "options_list": syntheticsTestOptionsList(), - "name": { - Description: "Name of Datadog synthetics test.", - Type: schema.TypeString, - Required: true, - }, - "message": { - Description: "A message to include with notifications for this synthetics test. Email notifications can be sent to specific users by using the same `@username` notation as events.", - Type: schema.TypeString, - Optional: true, - Default: "", - }, - "tags": { - Description: "A list of tags to associate with your synthetics test. This can help you categorize and filter tests in the manage synthetics page of the UI. Default is an empty list (`[]`).", - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "status": { - Description: "Define whether you want to start (`live`) or pause (`paused`) a Synthetic test.", - Type: schema.TypeString, - Required: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewSyntheticsTestPauseStatusFromValue), - }, - "monitor_id": { - Description: "ID of the monitor associated with the Datadog synthetics test.", - Type: schema.TypeInt, - Computed: true, - }, - "browser_step": syntheticsTestBrowserStep(), - "api_step": syntheticsTestAPIStep(), - "set_cookie": { - Description: "Cookies to be used for a browser test request, using the [Set-Cookie](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) syntax.", - Type: schema.TypeString, - Optional: true, - }, + "browser_step": syntheticsTestBrowserStep(), + "api_step": syntheticsTestAPIStep(), + "set_cookie": { + Description: "Cookies to be used for a browser test request, using the [Set-Cookie](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) syntax.", + Type: schema.TypeString, + Optional: true, + }, + } }, } } diff --git a/datadog/resource_datadog_user.go b/datadog/resource_datadog_user.go index 91c45c8cb..64731a1cf 100644 --- a/datadog/resource_datadog_user.go +++ b/datadog/resource_datadog_user.go @@ -22,49 +22,51 @@ func resourceDatadogUser() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "disabled": { - Description: "Whether the user is disabled.", - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "email": { - Description: "Email address for user.", - Type: schema.TypeString, - Required: true, - }, - "name": { - Description: "Name for user.", - Type: schema.TypeString, - Optional: true, - }, - "roles": { - Description: "A list a role IDs to assign to the user.", - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "send_user_invitation": { - Description: "Whether an invitation email should be sent when the user is created.", - Type: schema.TypeBool, - Optional: true, - Default: true, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - // This is only used on create, so don't generate diff when the resource already exists - return d.Id() != "" + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "disabled": { + Description: "Whether the user is disabled.", + Type: schema.TypeBool, + Optional: true, + Default: false, }, - }, - "verified": { - Description: "Returns `true` if the user is verified.", - Type: schema.TypeBool, - Computed: true, - }, - "user_invitation_id": { - Description: "The ID of the user invitation that was sent when creating the user.", - Type: schema.TypeString, - Computed: true, - }, + "email": { + Description: "Email address for user.", + Type: schema.TypeString, + Required: true, + }, + "name": { + Description: "Name for user.", + Type: schema.TypeString, + Optional: true, + }, + "roles": { + Description: "A list a role IDs to assign to the user.", + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "send_user_invitation": { + Description: "Whether an invitation email should be sent when the user is created.", + Type: schema.TypeBool, + Optional: true, + Default: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + // This is only used on create, so don't generate diff when the resource already exists + return d.Id() != "" + }, + }, + "verified": { + Description: "Returns `true` if the user is verified.", + Type: schema.TypeBool, + Computed: true, + }, + "user_invitation_id": { + Description: "The ID of the user invitation that was sent when creating the user.", + Type: schema.TypeString, + Computed: true, + }, + } }, } } diff --git a/datadog/resource_datadog_webhook.go b/datadog/resource_datadog_webhook.go index e6342b2ec..d40eaf636 100644 --- a/datadog/resource_datadog_webhook.go +++ b/datadog/resource_datadog_webhook.go @@ -25,35 +25,37 @@ func resourceDatadogWebhook() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Description: "The name of the webhook. It corresponds with ``.", - Type: schema.TypeString, - Required: true, - }, - "url": { - Description: "The URL of the webhook.", - Type: schema.TypeString, - Required: true, - }, - "payload": { - Description: "The payload of the webhook.", - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "custom_headers": { - Description: "The headers attached to the webhook.", - Type: schema.TypeString, - Optional: true, - }, - "encode_as": { - Description: "Encoding type.", - Type: schema.TypeString, - Optional: true, - ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewWebhooksIntegrationEncodingFromValue), - Computed: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "The name of the webhook. It corresponds with ``.", + Type: schema.TypeString, + Required: true, + }, + "url": { + Description: "The URL of the webhook.", + Type: schema.TypeString, + Required: true, + }, + "payload": { + Description: "The payload of the webhook.", + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "custom_headers": { + Description: "The headers attached to the webhook.", + Type: schema.TypeString, + Optional: true, + }, + "encode_as": { + Description: "Encoding type.", + Type: schema.TypeString, + Optional: true, + ValidateDiagFunc: validators.ValidateEnumValue(datadogV1.NewWebhooksIntegrationEncodingFromValue), + Computed: true, + }, + } }, } } diff --git a/datadog/resource_datadog_webhook_custom_variable.go b/datadog/resource_datadog_webhook_custom_variable.go index e622e7cc8..63b6bf35f 100644 --- a/datadog/resource_datadog_webhook_custom_variable.go +++ b/datadog/resource_datadog_webhook_custom_variable.go @@ -22,23 +22,25 @@ func resourceDatadogWebhookCustomVariable() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Description: "The name of the variable. It corresponds with ``.", - Type: schema.TypeString, - Required: true, - }, - "value": { - Description: "The value of the custom variable.", - Type: schema.TypeString, - Required: true, - Sensitive: true, - }, - "is_secret": { - Description: "Whether the custom variable is secret or not.", - Type: schema.TypeBool, - Required: true, - }, + SchemaFunc: func() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Description: "The name of the variable. It corresponds with ``.", + Type: schema.TypeString, + Required: true, + }, + "value": { + Description: "The value of the custom variable.", + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "is_secret": { + Description: "Whether the custom variable is secret or not.", + Type: schema.TypeBool, + Required: true, + }, + } }, } }