From 23b5aadb4060708ddd311475d552adfb6379a784 Mon Sep 17 00:00:00 2001 From: aizerin Date: Wed, 21 Aug 2024 15:41:51 +0200 Subject: [PATCH] add support for datastream lifecycle elastic#673 --- CHANGELOG.md | 1 + .../resources/elasticsearch_index_template.md | 11 ++++++- internal/elasticsearch/index/commons.go | 25 ++++++++++++++++ internal/elasticsearch/index/template.go | 29 ++++++++++++++++++- internal/models/models.go | 11 +++++-- 5 files changed, 72 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8ec9806d..8a02e2a61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## [Unreleased] - Add the `alert_delay` field to the Create Rule API ([#715](https://github.com/elastic/terraform-provider-elasticstack/pull/715)) +- Add support for data_stream `lifecycle` template settings ([#724](https://github.com/elastic/terraform-provider-elasticstack/pull/724)) ## [0.11.6] - 2024-08-20 diff --git a/docs/resources/elasticsearch_index_template.md b/docs/resources/elasticsearch_index_template.md index f93dfbe6f..dc229c5e2 100644 --- a/docs/resources/elasticsearch_index_template.md +++ b/docs/resources/elasticsearch_index_template.md @@ -60,7 +60,7 @@ resource "elasticstack_elasticsearch_index_template" "my_data_stream" { - `elasticsearch_connection` (Block List, Max: 1, Deprecated) Elasticsearch connection configuration block. This property will be removed in a future provider version. Configure the Elasticsearch connection via the provider configuration instead. (see [below for nested schema](#nestedblock--elasticsearch_connection)) - `metadata` (String) Optional user metadata about the index template. - `priority` (Number) Priority to determine index template precedence when a new data stream or index is created. -- `template` (Block List, Max: 1) Template to be applied. It may optionally include an aliases, mappings, or settings configuration. (see [below for nested schema](#nestedblock--template)) +- `template` (Block List, Max: 1) Template to be applied. It may optionally include an aliases, mappings, lifecycle, or settings configuration. (see [below for nested schema](#nestedblock--template)) - `version` (Number) Version number used to manage index templates externally. ### Read-Only @@ -102,6 +102,7 @@ Optional: Optional: - `alias` (Block Set) Alias to add. (see [below for nested schema](#nestedblock--template--alias)) +- `lifecycle` (Block Set, Max: 1) Lifecycle of data stream. See, https://www.elastic.co/guide/en/elasticsearch/reference/current/data-stream-lifecycle.html (see [below for nested schema](#nestedblock--template--lifecycle)) - `mappings` (String) Mapping for fields in the index. Should be specified as a JSON object of field mappings. See the documentation (https://www.elastic.co/guide/en/elasticsearch/reference/current/explicit-mapping.html) for more details - `settings` (String) Configuration options for the index. See, https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-modules-settings @@ -121,6 +122,14 @@ Optional: - `routing` (String) Value used to route indexing and search operations to a specific shard. - `search_routing` (String) Value used to route search operations to a specific shard. If specified, this overwrites the routing value for search operations. + + +### Nested Schema for `template.lifecycle` + +Required: + +- `data_retention` (String) The retention period of the data indexed in this data stream. + ## Import Import is supported using the following syntax: diff --git a/internal/elasticsearch/index/commons.go b/internal/elasticsearch/index/commons.go index bcfcc0ce7..380e60e56 100644 --- a/internal/elasticsearch/index/commons.go +++ b/internal/elasticsearch/index/commons.go @@ -80,3 +80,28 @@ func FlattenIndexAlias(name string, alias models.IndexAlias) (interface{}, diag. return a, diags } + +func ExpandLifecycle(definedLifecycle *schema.Set) *models.LifecycleSettings { + if definedLifecycle.Len() == 0 { + return nil + } + lifecycleMap := definedLifecycle.List()[0].(map[string]interface{}) + if lifecycleMap != nil { + lifecycle := &models.LifecycleSettings{} + if s, ok := lifecycleMap["data_retention"]; ok { + lifecycle.DataRetention = s.(string) + } + return lifecycle + } + return nil +} + +func FlattenLifecycle(lifecycle *models.LifecycleSettings) interface{} { + lf := make([]interface{}, 1) + lfSettings := make(map[string]interface{}) + lfSettings["data_retention"] = lifecycle.DataRetention + + lf[0] = lfSettings + + return lf +} diff --git a/internal/elasticsearch/index/template.go b/internal/elasticsearch/index/template.go index 834565096..d5a70cfc9 100644 --- a/internal/elasticsearch/index/template.go +++ b/internal/elasticsearch/index/template.go @@ -81,7 +81,7 @@ func ResourceTemplate() *schema.Resource { Optional: true, }, "template": { - Description: "Template to be applied. It may optionally include an aliases, mappings, or settings configuration.", + Description: "Template to be applied. It may optionally include an aliases, mappings, lifecycle, or settings configuration.", Type: schema.TypeList, Optional: true, MaxItems: 1, @@ -157,6 +157,21 @@ func ResourceTemplate() *schema.Resource { validation.StringIsJSON, stringIsJSONObject, ), }, + "lifecycle": { + Description: "Lifecycle of data stream. See, https://www.elastic.co/guide/en/elasticsearch/reference/current/data-stream-lifecycle.html", + Type: schema.TypeSet, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "data_retention": { + Description: "The retention period of the data indexed in this data stream.", + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, }, }, }, @@ -298,6 +313,13 @@ func expandTemplate(config interface{}) (models.Template, bool, diag.Diagnostics } templ.Aliases = aliases + if lc, ok := definedTempl["lifecycle"]; ok { + lifecycle := ExpandLifecycle(lc.(*schema.Set)) + if lifecycle != nil { + templ.Lifecycle = lifecycle + } + } + if mappings, ok := definedTempl["mappings"]; ok { if mappings.(string) != "" { maps := make(map[string]interface{}) @@ -422,6 +444,11 @@ func flattenTemplateData(template *models.Template) ([]interface{}, diag.Diagnos tmpl["alias"] = aliases } + if template.Lifecycle != nil { + lifecycle := FlattenLifecycle(template.Lifecycle) + tmpl["lifecycle"] = lifecycle + } + return []interface{}{tmpl}, diags } diff --git a/internal/models/models.go b/internal/models/models.go index dc8af8937..af5cb3f64 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -161,9 +161,10 @@ type DataStreamSettings struct { } type Template struct { - Aliases map[string]IndexAlias `json:"aliases,omitempty"` - Mappings map[string]interface{} `json:"mappings,omitempty"` - Settings map[string]interface{} `json:"settings,omitempty"` + Aliases map[string]IndexAlias `json:"aliases,omitempty"` + Mappings map[string]interface{} `json:"mappings,omitempty"` + Settings map[string]interface{} `json:"settings,omitempty"` + Lifecycle *LifecycleSettings `json:"lifecycle,omitempty"` } type IndexTemplatesResponse struct { @@ -291,6 +292,10 @@ type IndexAlias struct { SearchRouting string `json:"search_routing,omitempty"` } +type LifecycleSettings struct { + DataRetention string `json:"data_retention,omitempty"` +} + type DataStream struct { Name string `json:"name"` TimestampField TimestampField `json:"timestamp_field"`