From 2cfa4e3696806a900b16adf583ea689060c9a86b Mon Sep 17 00:00:00 2001 From: Brian Helba Date: Fri, 22 Nov 2024 08:57:11 -0500 Subject: [PATCH 1/4] Fix docs for "digitalocean_database_opensearch_config" (#1265) * Fix docs for "digitalocean_database_opensearch_config" The description for the "action_auto_create_index_enabled" argument appears to be a copy-paste error. Use a more correct description from: https://www.elastic.co/guide/en/elasticsearch/reference/current/index-management-settings.html * Use documentation text from DigitalOcean API docs --- docs/resources/database_opensearch_config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/resources/database_opensearch_config.md b/docs/resources/database_opensearch_config.md index 4e615f177..57ec45d43 100644 --- a/docs/resources/database_opensearch_config.md +++ b/docs/resources/database_opensearch_config.md @@ -90,7 +90,7 @@ for additional details on each option. * `indices_queries_cache_size_percentage` - (Optional) Maximum amount of heap used for query cache. Too low value will decrease query performance and increase performance for other operations; too high value will cause issues with other functionality. Default: `10` * `indices_recovery_max_mb_per_sec` - (Optional) Limits total inbound and outbound recovery traffic for each node, expressed in mb per second. Applies to both peer recoveries as well as snapshot recoveries (i.e., restores from a snapshot). Default: `40` * `indices_recovery_max_concurrent_file_chunks` - (Optional) Maximum number of file chunks sent in parallel for each recovery. Default: `2` -* `action_auto_create_index_enabled` - (Optional) Specifies whether ISM is enabled or not. Default: `true` +* `action_auto_create_index_enabled` - (Optional) Specifices whether to allow automatic creation of indices. Default: `true` * `action_destructive_requires_name` - (Optional) Specifies whether to require explicit index names when deleting indices. * `enable_security_audit` - (Optional) Specifies whether to allow security audit logging. Default: `false` * `thread_pool_search_size` - (Optional) Number of workers in the search operation thread pool. Do note this may have maximum value depending on CPU count - value is automatically lowered if set to higher than maximum value. From 054313d97544348961d8533d82547db11e91db13 Mon Sep 17 00:00:00 2001 From: Andrew Starr-Bochicchio Date: Fri, 22 Nov 2024 10:30:49 -0500 Subject: [PATCH 2/4] opensearch_config: follow PATCH semantics (#1273) Co-authored-by: Anna Lushnikova --- .../resource_database_opensearch_config.go | 245 +++++++++++------- 1 file changed, 157 insertions(+), 88 deletions(-) diff --git a/digitalocean/database/resource_database_opensearch_config.go b/digitalocean/database/resource_database_opensearch_config.go index bd7bd02a5..e1e528694 100644 --- a/digitalocean/database/resource_database_opensearch_config.go +++ b/digitalocean/database/resource_database_opensearch_config.go @@ -280,165 +280,234 @@ func updateOpensearchConfig(ctx context.Context, d *schema.ResourceData, client opts := &godo.OpensearchConfig{} - if v, ok := d.GetOkExists("ism_enabled"); ok { - opts.IsmEnabled = godo.PtrTo(v.(bool)) - } + if d.HasChanges("ism_enabled", "ism_history_enabled", "ism_history_max_age_hours", + "ism_history_max_docs", "ism_history_rollover_check_period_hours", + "ism_history_rollover_retention_period_days") { - if v, ok := d.GetOkExists("ism_history_enabled"); ok { - opts.IsmHistoryEnabled = godo.PtrTo(v.(bool)) - } + if v, ok := d.GetOkExists("ism_enabled"); ok { + opts.IsmEnabled = godo.PtrTo(v.(bool)) + } - if v, ok := d.GetOk("ism_history_max_age_hours"); ok { - opts.IsmHistoryMaxAgeHours = godo.PtrTo(v.(int)) - } + if v, ok := d.GetOkExists("ism_history_enabled"); ok { + opts.IsmHistoryEnabled = godo.PtrTo(v.(bool)) + } - if v, ok := d.GetOk("ism_history_max_docs"); ok { - opts.IsmHistoryMaxDocs = godo.PtrTo(int64(v.(int))) - } + if v, ok := d.GetOk("ism_history_max_age_hours"); ok { + opts.IsmHistoryMaxAgeHours = godo.PtrTo(v.(int)) + } - if v, ok := d.GetOk("ism_history_rollover_check_period_hours"); ok { - opts.IsmHistoryRolloverCheckPeriodHours = godo.PtrTo(v.(int)) - } + if v, ok := d.GetOk("ism_history_max_docs"); ok { + opts.IsmHistoryMaxDocs = godo.PtrTo(int64(v.(int))) + } + + if v, ok := d.GetOk("ism_history_rollover_check_period_hours"); ok { + opts.IsmHistoryRolloverCheckPeriodHours = godo.PtrTo(v.(int)) + } - if v, ok := d.GetOk("ism_history_rollover_retention_period_days"); ok { - opts.IsmHistoryRolloverRetentionPeriodDays = godo.PtrTo(v.(int)) + if v, ok := d.GetOk("ism_history_rollover_retention_period_days"); ok { + opts.IsmHistoryRolloverRetentionPeriodDays = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("http_max_content_length_bytes"); ok { - opts.HttpMaxContentLengthBytes = godo.PtrTo(v.(int)) + if d.HasChange("http_max_content_length_bytes") { + if v, ok := d.GetOk("http_max_content_length_bytes"); ok { + opts.HttpMaxContentLengthBytes = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("http_max_header_size_bytes"); ok { - opts.HttpMaxHeaderSizeBytes = godo.PtrTo(v.(int)) + if d.HasChange("http_max_header_size_bytes") { + if v, ok := d.GetOk("http_max_header_size_bytes"); ok { + opts.HttpMaxHeaderSizeBytes = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("http_max_initial_line_length_bytes"); ok { - opts.HttpMaxInitialLineLengthBytes = godo.PtrTo(v.(int)) + if d.HasChange("http_max_initial_line_length_bytes") { + if v, ok := d.GetOk("http_max_initial_line_length_bytes"); ok { + opts.HttpMaxInitialLineLengthBytes = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("indices_query_bool_max_clause_count"); ok { - opts.IndicesQueryBoolMaxClauseCount = godo.PtrTo(v.(int)) + if d.HasChange("indices_query_bool_max_clause_count") { + if v, ok := d.GetOk("indices_query_bool_max_clause_count"); ok { + opts.IndicesQueryBoolMaxClauseCount = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("search_max_buckets"); ok { - opts.SearchMaxBuckets = godo.PtrTo(v.(int)) + if d.HasChange("search_max_buckets") { + if v, ok := d.GetOk("search_max_buckets"); ok { + opts.SearchMaxBuckets = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("indices_fielddata_cache_size_percentage"); ok { - opts.IndicesFielddataCacheSizePercentage = godo.PtrTo(v.(int)) + if d.HasChange("indices_fielddata_cache_size_percentage") { + if v, ok := d.GetOk("indices_fielddata_cache_size_percentage"); ok { + opts.IndicesFielddataCacheSizePercentage = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("indices_memory_index_buffer_size_percentage"); ok { - opts.IndicesMemoryIndexBufferSizePercentage = godo.PtrTo(v.(int)) + if d.HasChange("indices_memory_index_buffer_size_percentage") { + if v, ok := d.GetOk("indices_memory_index_buffer_size_percentage"); ok { + opts.IndicesMemoryIndexBufferSizePercentage = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("indices_memory_min_index_buffer_size_mb"); ok { - opts.IndicesMemoryMinIndexBufferSizeMb = godo.PtrTo(v.(int)) + if d.HasChange("indices_memory_min_index_buffer_size_mb") { + if v, ok := d.GetOk("indices_memory_min_index_buffer_size_mb"); ok { + opts.IndicesMemoryMinIndexBufferSizeMb = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("indices_memory_max_index_buffer_size_mb"); ok { - opts.IndicesMemoryMaxIndexBufferSizeMb = godo.PtrTo(v.(int)) + if d.HasChange("indices_memory_max_index_buffer_size_mb") { + if v, ok := d.GetOk("indices_memory_max_index_buffer_size_mb"); ok { + opts.IndicesMemoryMaxIndexBufferSizeMb = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("indices_queries_cache_size_percentage"); ok { - opts.IndicesQueriesCacheSizePercentage = godo.PtrTo(v.(int)) + if d.HasChange("indices_queries_cache_size_percentage") { + if v, ok := d.GetOk("indices_queries_cache_size_percentage"); ok { + opts.IndicesQueriesCacheSizePercentage = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("indices_recovery_max_mb_per_sec"); ok { - opts.IndicesRecoveryMaxMbPerSec = godo.PtrTo(v.(int)) + if d.HasChange("indices_recovery_max_mb_per_sec") { + if v, ok := d.GetOk("indices_recovery_max_mb_per_sec"); ok { + opts.IndicesRecoveryMaxMbPerSec = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("indices_recovery_max_concurrent_file_chunks"); ok { - opts.IndicesRecoveryMaxConcurrentFileChunks = godo.PtrTo(v.(int)) + if d.HasChange("indices_recovery_max_concurrent_file_chunks") { + if v, ok := d.GetOk("indices_recovery_max_concurrent_file_chunks"); ok { + opts.IndicesRecoveryMaxConcurrentFileChunks = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOkExists("action_auto_create_index_enabled"); ok { - opts.ActionAutoCreateIndexEnabled = godo.PtrTo(v.(bool)) + if d.HasChange("action_auto_create_index_enabled") { + if v, ok := d.GetOkExists("action_auto_create_index_enabled"); ok { + opts.ActionAutoCreateIndexEnabled = godo.PtrTo(v.(bool)) + } } - if v, ok := d.GetOkExists("action_destructive_requires_name"); ok { - opts.ActionDestructiveRequiresName = godo.PtrTo(v.(bool)) + if d.HasChange("action_destructive_requires_name") { + if v, ok := d.GetOkExists("action_destructive_requires_name"); ok { + opts.ActionDestructiveRequiresName = godo.PtrTo(v.(bool)) + } } - if v, ok := d.GetOkExists("enable_security_audit"); ok { - opts.EnableSecurityAudit = godo.PtrTo(v.(bool)) + if d.HasChange("enable_security_audit") { + if v, ok := d.GetOkExists("enable_security_audit"); ok { + opts.EnableSecurityAudit = godo.PtrTo(v.(bool)) + } } - if v, ok := d.GetOk("thread_pool_search_size"); ok { - opts.ThreadPoolSearchSize = godo.PtrTo(v.(int)) + if d.HasChange("thread_pool_search_size") { + if v, ok := d.GetOk("thread_pool_search_size"); ok { + opts.ThreadPoolSearchSize = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("thread_pool_search_throttled_size"); ok { - opts.ThreadPoolSearchThrottledSize = godo.PtrTo(v.(int)) + if d.HasChange("thread_pool_search_throttled_size") { + if v, ok := d.GetOk("thread_pool_search_throttled_size"); ok { + opts.ThreadPoolSearchThrottledSize = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("thread_pool_search_throttled_queue_size"); ok { - opts.ThreadPoolSearchThrottledQueueSize = godo.PtrTo(v.(int)) + if d.HasChange("thread_pool_search_throttled_queue_size") { + if v, ok := d.GetOk("thread_pool_search_throttled_queue_size"); ok { + opts.ThreadPoolSearchThrottledQueueSize = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("thread_pool_search_queue_size"); ok { - opts.ThreadPoolSearchQueueSize = godo.PtrTo(v.(int)) + if d.HasChange("thread_pool_search_queue_size") { + if v, ok := d.GetOk("thread_pool_search_queue_size"); ok { + opts.ThreadPoolSearchQueueSize = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("thread_pool_get_size"); ok { - opts.ThreadPoolGetSize = godo.PtrTo(v.(int)) + if d.HasChange("thread_pool_get_size") { + if v, ok := d.GetOk("thread_pool_get_size"); ok { + opts.ThreadPoolGetSize = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("thread_pool_get_queue_size"); ok { - opts.ThreadPoolGetQueueSize = godo.PtrTo(v.(int)) + if d.HasChange("thread_pool_get_queue_size") { + if v, ok := d.GetOk("thread_pool_get_queue_size"); ok { + opts.ThreadPoolGetQueueSize = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("thread_pool_analyze_size"); ok { - opts.ThreadPoolAnalyzeSize = godo.PtrTo(v.(int)) + if d.HasChange("thread_pool_analyze_size") { + if v, ok := d.GetOk("thread_pool_analyze_size"); ok { + opts.ThreadPoolAnalyzeSize = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("thread_pool_analyze_queue_size"); ok { - opts.ThreadPoolAnalyzeQueueSize = godo.PtrTo(v.(int)) + if d.HasChange("thread_pool_analyze_queue_size") { + if v, ok := d.GetOk("thread_pool_analyze_queue_size"); ok { + opts.ThreadPoolAnalyzeQueueSize = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("thread_pool_write_size"); ok { - opts.ThreadPoolWriteSize = godo.PtrTo(v.(int)) + if d.HasChange("thread_pool_write_size") { + if v, ok := d.GetOk("thread_pool_write_size"); ok { + opts.ThreadPoolWriteSize = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("thread_pool_write_queue_size"); ok { - opts.ThreadPoolWriteQueueSize = godo.PtrTo(v.(int)) + if d.HasChange("thread_pool_write_queue_size") { + if v, ok := d.GetOk("thread_pool_write_queue_size"); ok { + opts.ThreadPoolWriteQueueSize = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("thread_pool_force_merge_size"); ok { - opts.ThreadPoolForceMergeSize = godo.PtrTo(v.(int)) + if d.HasChange("thread_pool_force_merge_size") { + if v, ok := d.GetOk("thread_pool_force_merge_size"); ok { + opts.ThreadPoolForceMergeSize = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOkExists("override_main_response_version"); ok { - opts.OverrideMainResponseVersion = godo.PtrTo(v.(bool)) + if d.HasChange("override_main_response_version") { + if v, ok := d.GetOkExists("override_main_response_version"); ok { + opts.OverrideMainResponseVersion = godo.PtrTo(v.(bool)) + } } - if v, ok := d.GetOk("script_max_compilations_rate"); ok { - opts.ScriptMaxCompilationsRate = godo.PtrTo(v.(string)) + if d.HasChange("script_max_compilations_rate") { + if v, ok := d.GetOk("script_max_compilations_rate"); ok { + opts.ScriptMaxCompilationsRate = godo.PtrTo(v.(string)) + } } - if v, ok := d.GetOk("cluster_max_shards_per_node"); ok { - opts.ClusterMaxShardsPerNode = godo.PtrTo(v.(int)) + if d.HasChange("cluster_max_shards_per_node") { + if v, ok := d.GetOk("cluster_max_shards_per_node"); ok { + opts.ClusterMaxShardsPerNode = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOk("cluster_routing_allocation_node_concurrent_recoveries"); ok { - opts.ClusterRoutingAllocationNodeConcurrentRecoveries = godo.PtrTo(v.(int)) + if d.HasChange("cluster_routing_allocation_node_concurrent_recoveries") { + if v, ok := d.GetOk("cluster_routing_allocation_node_concurrent_recoveries"); ok { + opts.ClusterRoutingAllocationNodeConcurrentRecoveries = godo.PtrTo(v.(int)) + } } - if v, ok := d.GetOkExists("plugins_alerting_filter_by_backend_roles_enabled"); ok { - opts.PluginsAlertingFilterByBackendRolesEnabled = godo.PtrTo(v.(bool)) + if d.HasChange("plugins_alerting_filter_by_backend_roles_enabled") { + if v, ok := d.GetOkExists("plugins_alerting_filter_by_backend_roles_enabled"); ok { + opts.PluginsAlertingFilterByBackendRolesEnabled = godo.PtrTo(v.(bool)) + } } - if v, ok := d.GetOk("reindex_remote_whitelist"); ok { - if exampleSet, ok := v.(*schema.Set); ok { - var items []string - for _, item := range exampleSet.List() { - if str, ok := item.(string); ok { - items = append(items, str) - } else { - return fmt.Errorf("non-string item found in set") // todo: anna update err message + if d.HasChange("reindex_remote_whitelist") { + if v, ok := d.GetOk("reindex_remote_whitelist"); ok { + if exampleSet, ok := v.(*schema.Set); ok { + var items []string + for _, item := range exampleSet.List() { + if str, ok := item.(string); ok { + items = append(items, str) + } else { + return fmt.Errorf("non-string item found in set") + } } + opts.ReindexRemoteWhitelist = items } - opts.ReindexRemoteWhitelist = items } } From d25af357311f949b54a6fc9942178e50ab843f16 Mon Sep 17 00:00:00 2001 From: Andrew Starr-Bochicchio Date: Fri, 22 Nov 2024 10:56:53 -0500 Subject: [PATCH 3/4] Prep v2.44.1 release. (#1274) --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3565bdeea..68f0a1a32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## 2.44.1 + +BUG FIXES: + +- #1273 - @andrewsomething - opensearch_config: follow PATCH semantics + +MISC: + +- #1265 - @brianhelba - Fix docs for "digitalocean_database_opensearch_config" +- #1270 - @dduportal - docs(droplet) details `user_data` behavior (resource forces recreate) + ## 2.44.0 IMPROVEMENTS: From 2be86214dbde639acada7b8ef1b4adb637f557c7 Mon Sep 17 00:00:00 2001 From: Andrew Starr-Bochicchio Date: Mon, 25 Nov 2024 11:49:09 -0500 Subject: [PATCH 4/4] apps: support removing ingress rules. (#1276) --- digitalocean/app/app_spec.go | 1 - digitalocean/app/resource_app_test.go | 92 +++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/digitalocean/app/app_spec.go b/digitalocean/app/app_spec.go index 60b9ce638..dbbaedc2d 100644 --- a/digitalocean/app/app_spec.go +++ b/digitalocean/app/app_spec.go @@ -1033,7 +1033,6 @@ func appSpecIngressSchema() *schema.Resource { "rule": { Type: schema.TypeList, Optional: true, - Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "match": { diff --git a/digitalocean/app/resource_app_test.go b/digitalocean/app/resource_app_test.go index 63caec9e9..41095cf4a 100644 --- a/digitalocean/app/resource_app_test.go +++ b/digitalocean/app/resource_app_test.go @@ -865,6 +865,55 @@ func TestAccDigitalOceanApp_TimeoutConfig(t *testing.T) { }) } +func TestAccDigitalOceanApp_makeServiceInternal(t *testing.T) { + var app godo.App + appName := acceptance.RandomTestName() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.TestAccPreCheck(t) }, + Providers: acceptance.TestAccProviders, + CheckDestroy: testAccCheckDigitalOceanAppDestroy, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(testAccCheckDigitalOceanAppConfig_minimalService, appName), + Check: resource.ComposeTestCheckFunc( + testAccCheckDigitalOceanAppExists("digitalocean_app.foobar", &app), + resource.TestCheckResourceAttr( + "digitalocean_app.foobar", "spec.0.name", appName, + ), + resource.TestCheckResourceAttr( + "digitalocean_app.foobar", "spec.0.ingress.0.rule.0.match.0.path.0.prefix", "/", + ), + resource.TestCheckResourceAttr( + "digitalocean_app.foobar", "spec.0.service.0.http_port", "8080", + ), + ), + }, + { + Config: fmt.Sprintf(testAccCheckDigitalOceanAppConfig_internalOnlyService, appName), + Check: resource.ComposeTestCheckFunc( + testAccCheckDigitalOceanAppExists("digitalocean_app.foobar", &app), + resource.TestCheckResourceAttr( + "digitalocean_app.foobar", "spec.0.name", appName, + ), + resource.TestCheckResourceAttr( + "digitalocean_app.foobar", "spec.0.service.0.http_port", "0", + ), + resource.TestCheckResourceAttr( + "digitalocean_app.foobar", "spec.0.service.0.internal_ports.#", "1", + ), + resource.TestCheckResourceAttr( + "digitalocean_app.foobar", "spec.0.service.0.internal_ports.0", "8080", + ), + resource.TestCheckResourceAttr( + "digitalocean_app.foobar", "spec.0.ingress.0.rule.#", "0", + ), + ), + }, + }, + }) +} + func testAccCheckDigitalOceanAppDestroy(s *terraform.State) error { client := acceptance.TestAccProvider.Meta().(*config.CombinedConfig).GodoClient() @@ -1577,3 +1626,46 @@ resource "digitalocean_app" "foobar" { } } }` + +var testAccCheckDigitalOceanAppConfig_minimalService = ` +resource "digitalocean_app" "foobar" { + spec { + name = "%s" + region = "nyc" + + service { + name = "go-service" + instance_count = 1 + instance_size_slug = "apps-d-1vcpu-0.5gb" + + git { + repo_clone_url = "https://github.com/digitalocean/sample-golang.git" + branch = "main" + } + } + } +}` + +var testAccCheckDigitalOceanAppConfig_internalOnlyService = ` +resource "digitalocean_app" "foobar" { + spec { + name = "%s" + region = "nyc" + + service { + name = "go-service" + instance_count = 1 + instance_size_slug = "apps-d-1vcpu-0.5gb" + + http_port = 0 + internal_ports = [8080] + + git { + repo_clone_url = "https://github.com/digitalocean/sample-golang.git" + branch = "main" + } + } + + ingress {} + } +}`