Skip to content

Commit 2c725b3

Browse files
INTMDB-600: Add support for conditional timeout for search index build (#1077)
* Update access_list_api_key.html.markdown (#1058) * Add support for conditional timeout for search index build * fix lint --------- Co-authored-by: Zuhair Ahmed <[email protected]>
1 parent f6ae1a3 commit 2c725b3

File tree

2 files changed

+93
-5
lines changed

2 files changed

+93
-5
lines changed

mongodbatlas/resource_mongodbatlas_search_index.go

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,30 @@ import (
77
"fmt"
88
"log"
99
"strings"
10+
"time"
1011

1112
"github.com/go-test/deep"
1213
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
14+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1315
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1416
matlas "go.mongodb.org/atlas/mongodbatlas"
1517
)
1618

1719
func resourceMongoDBAtlasSearchIndex() *schema.Resource {
1820
return &schema.Resource{
19-
CreateContext: resourceMongoDBAtlasSearchIndexCreate,
20-
ReadContext: resourceMongoDBAtlasSearchIndexRead,
21-
UpdateContext: resourceMongoDBAtlasSearchIndexUpdate,
22-
DeleteContext: resourceMongoDBAtlasSearchIndexDelete,
21+
CreateWithoutTimeout: resourceMongoDBAtlasSearchIndexCreate,
22+
ReadContext: resourceMongoDBAtlasSearchIndexRead,
23+
UpdateWithoutTimeout: resourceMongoDBAtlasSearchIndexUpdate,
24+
DeleteContext: resourceMongoDBAtlasSearchIndexDelete,
2325
Importer: &schema.ResourceImporter{
2426
StateContext: resourceMongoDBAtlasSearchIndexImportState,
2527
},
2628
Schema: returnSearchIndexSchema(),
29+
Timeouts: &schema.ResourceTimeout{
30+
Create: schema.DefaultTimeout(3 * time.Hour),
31+
Update: schema.DefaultTimeout(3 * time.Hour),
32+
Delete: schema.DefaultTimeout(3 * time.Hour),
33+
},
2734
}
2835
}
2936

@@ -101,6 +108,10 @@ func returnSearchIndexSchema() map[string]*schema.Schema {
101108
Optional: true,
102109
Computed: true,
103110
},
111+
"wait_for_index_build_completion": {
112+
Type: schema.TypeBool,
113+
Optional: true,
114+
},
104115
}
105116
}
106117

@@ -210,11 +221,36 @@ func resourceMongoDBAtlasSearchIndexUpdate(ctx context.Context, d *schema.Resour
210221
}
211222

212223
searchIndex.IndexID = ""
213-
_, _, err = conn.Search.UpdateIndex(context.Background(), projectID, clusterName, indexID, searchIndex)
224+
dbSearchIndexRes, _, err := conn.Search.UpdateIndex(context.Background(), projectID, clusterName, indexID, searchIndex)
214225
if err != nil {
215226
return diag.Errorf("error updating search index (%s): %s", searchIndex.Name, err)
216227
}
217228

229+
if d.Get("wait_for_index_build_completion").(bool) {
230+
timeout := d.Timeout(schema.TimeoutCreate)
231+
stateConf := &resource.StateChangeConf{
232+
Pending: []string{"CREATING", "IN_PROGRESS", "NOT_VALID", "PENDING"},
233+
Target: []string{"VALID"},
234+
Refresh: resourceSearchIndexRefreshFunc(ctx, clusterName, projectID, dbSearchIndexRes.IndexID, conn),
235+
Timeout: timeout,
236+
MinTimeout: 1 * time.Minute,
237+
Delay: 1 * time.Minute,
238+
}
239+
240+
// Wait, catching any errors
241+
_, err = stateConf.WaitForStateContext(ctx)
242+
if err != nil {
243+
d.SetId(encodeStateID(map[string]string{
244+
"project_id": projectID,
245+
"cluster_name": clusterName,
246+
"index_id": dbSearchIndexRes.IndexID,
247+
}))
248+
resourceMongoDBAtlasSearchIndexDelete(ctx, d, meta)
249+
d.SetId("")
250+
return diag.FromErr(fmt.Errorf("error creating index in cluster (%s): %s", clusterName, err))
251+
}
252+
}
253+
218254
return resourceMongoDBAtlasSearchIndexRead(ctx, d, meta)
219255
}
220256

@@ -357,7 +393,30 @@ func resourceMongoDBAtlasSearchIndexCreate(ctx context.Context, d *schema.Resour
357393
if err != nil {
358394
return diag.Errorf("error creating index: %s", err)
359395
}
396+
if d.Get("wait_for_index_build_completion").(bool) {
397+
timeout := d.Timeout(schema.TimeoutCreate)
398+
stateConf := &resource.StateChangeConf{
399+
Pending: []string{"CREATING", "IN_PROGRESS", "NOT_VALID", "PENDING"},
400+
Target: []string{"VALID"},
401+
Refresh: resourceSearchIndexRefreshFunc(ctx, clusterName, projectID, dbSearchIndexRes.IndexID, conn),
402+
Timeout: timeout,
403+
MinTimeout: 1 * time.Minute,
404+
Delay: 1 * time.Minute,
405+
}
360406

407+
// Wait, catching any errors
408+
_, err = stateConf.WaitForStateContext(ctx)
409+
if err != nil {
410+
d.SetId(encodeStateID(map[string]string{
411+
"project_id": projectID,
412+
"cluster_name": clusterName,
413+
"index_id": dbSearchIndexRes.IndexID,
414+
}))
415+
resourceMongoDBAtlasSearchIndexDelete(ctx, d, meta)
416+
d.SetId("")
417+
return diag.FromErr(fmt.Errorf("error creating index in cluster (%s): %s", clusterName, err))
418+
}
419+
}
361420
d.SetId(encodeStateID(map[string]string{
362421
"project_id": projectID,
363422
"cluster_name": clusterName,
@@ -466,3 +525,30 @@ func unmarshalSearchIndexAnalyzersFields(mappingString string) []map[string]inte
466525

467526
return fields
468527
}
528+
529+
func resourceSearchIndexRefreshFunc(ctx context.Context, clusterName, projectID, indexID string, client *matlas.Client) resource.StateRefreshFunc {
530+
return func() (interface{}, string, error) {
531+
searchIndex, resp, err := client.Search.GetIndex(ctx, projectID, clusterName, indexID)
532+
if err != nil {
533+
return nil, "ERROR", err
534+
}
535+
536+
if err != nil && searchIndex == nil && resp == nil {
537+
return nil, "", err
538+
} else if err != nil {
539+
if resp.StatusCode == 404 {
540+
return "", "DELETED", nil
541+
}
542+
if resp.StatusCode == 503 {
543+
return "", "PENDING", nil
544+
}
545+
return nil, "", err
546+
}
547+
548+
if searchIndex.Status != "" {
549+
log.Printf("[DEBUG] status for Search Index : %s: %s", clusterName, searchIndex.Status)
550+
}
551+
552+
return searchIndex, searchIndex.Status, nil
553+
}
554+
}

website/docs/r/search_index.html.markdown

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ EOF
103103
* `name` - (Required) The name of the search index you want to create.
104104
* `project_id` - (Required) The ID of the organization or project you want to create the search index within.
105105
* `cluster_name` - (Required) The name of the cluster where you want to create the search index within.
106+
* `wait_for_index_build_completion` - (Optional) Wait for search index to achieve Active status before terraform considers resource built.
107+
* `timeouts`- (Optional) The duration of time to wait for Search Index to be created, updated, or deleted. The timeout value is defined by a signed sequence of decimal numbers with an time unit suffix such as: `1h45m`, `300s`, `10m`, .... The valid time units are: `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`. The default timeout for Serach Index create & update is `3h`. Learn more about timeouts [here](https://www.terraform.io/plugin/sdkv2/resources/retries-and-customizable-timeouts).
106108

107109

108110
* `analyzer` - [Analyzer](https://docs.atlas.mongodb.com/reference/atlas-search/analyzers/#std-label-analyzers-ref) to use when creating the index. Defaults to [lucene.standard](https://docs.atlas.mongodb.com/reference/atlas-search/analyzers/standard/#std-label-ref-standard-analyzer)

0 commit comments

Comments
 (0)