Skip to content

Commit

Permalink
feat: Add suport for new composable template (#9)
Browse files Browse the repository at this point in the history
* feat: rename index_template to index_template_legacy. Add index_component_template resource

Signed-off-by: disaster37 <[email protected]>

* feat: Add support for new index template API

Signed-off-by: disaster37 <[email protected]>
  • Loading branch information
disaster37 authored Jan 17, 2022
1 parent 16da12c commit 5ca17fe
Show file tree
Hide file tree
Showing 15 changed files with 1,000 additions and 86 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ trial-license:
curl -XPOST -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} ${ELASTICSEARCH_URLS}/_license/start_trial?acknowledge=true

start-pods: clean-pods
kubectl run elasticsearch --image docker.elastic.co/elasticsearch/elasticsearch:7.5.1 --port "9200" --expose --env "cluster.name=test" --env "discovery.type=single-node" --env "ELASTIC_PASSWORD=changeme" --env "xpack.security.enabled=true" --env "ES_JAVA_OPTS=-Xms512m -Xmx512m" --env "path.repo=/tmp" --limits "cpu=500m,memory=1024Mi"
kubectl run elasticsearch --image docker.elastic.co/elasticsearch/elasticsearch:7.16.2 --port "9200" --expose --env "cluster.name=test" --env "discovery.type=single-node" --env "ELASTIC_PASSWORD=changeme" --env "xpack.security.enabled=true" --env "ES_JAVA_OPTS=-Xms512m -Xmx512m" --env "path.repo=/tmp" --limits "cpu=500m,memory=1024Mi"

clean-pods:
kubectl delete --ignore-not-found pod/elasticsearch
Expand Down
2 changes: 2 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ provider "elasticsearch" {

- [elasticsearch_index_lifecycle_policy](resources/elasticsearch_index_lifecycle_policy.md)
- [elasticsearch_index_template](resources/elasticsearch_index_template.md)
- [elasticsearch_index_component_template](resources/elasticsearch_index_component_template.md)
- [elasticsearch_index_template_legacy](resources/elasticsearch_index_template_legacy.md)
- [elasticsearch_role](resources/elasticsearch_role.md)
- [elasticsearch_role_mapping](resources/elasticsearch_role_mapping.md)
- [elasticsearch_user](resources/elasticsearch_user.md)
Expand Down
50 changes: 50 additions & 0 deletions docs/resources/elasticsearch_index_component_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# elasticsearch_index_component_template Resource Source

This resource permit to manage the index component template in Elasticsearch.
You can see the API documentation: https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-component-template.html

***Supported Elasticsearch version:***
- v7

## Example Usage

It will create index template.

```tf
resource elasticsearch_index_component_template "test" {
name = "terraform-test"
template = <<EOF
{
"template": {
"settings": {
"index.refresh_interval": "3s"
},
"mappings": {
"_source": {
"enabled": false
},
"properties": {
"host_name": {
"type": "keyword"
},
"created_at": {
"type": "date",
"format": "EEE MMM dd HH:mm:ss Z yyyy"
}
}
}
}
}
EOF
}
```

## Argument Reference

***The following arguments are supported:***
- **name**: (required) Identifier for the template.
- **template**: (required) The template specification. It's a string as JSON object.

## Attribute Reference

NA
21 changes: 10 additions & 11 deletions docs/resources/elasticsearch_index_template.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# elasticsearch_index_template Resource Source

This resource permit to manage the index template in Elasticsearch.
You can see the API documentation: https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates.html
You can see the API documentation: https://www.elastic.co/guide/en/elasticsearch/reference/current/index-templates.html

***Supported Elasticsearch version:***
- v6
- v7

## Example Usage
Expand All @@ -16,15 +15,15 @@ resource elasticsearch_index_template "test" {
name = "terraform-test"
template = <<EOF
{
"index_patterns": [
"test"
],
"settings": {
"index.refresh_interval": "5s",
"index.lifecycle.name": "policy-logstash-backup",
"index.lifecycle.rollover_alias": "logstash-backup-alias"
},
"order": 2
"index_patterns": ["test-index-template"],
"template": {
"settings": {
"index.refresh_interval": "5s",
"index.lifecycle.name": "policy-logstash-backup",
"index.lifecycle.rollover_alias": "logstash-backup-alias"
}
},
"priority": 2
}
EOF
}
Expand Down
41 changes: 41 additions & 0 deletions docs/resources/elasticsearch_index_template_legacy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# elasticsearch_index_template_legacy Resource Source

This resource permit to manage the index template in Elasticsearch (the legacy API).
You can see the API documentation: https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates.html

***Supported Elasticsearch version:***
- v6
- v7

## Example Usage

It will create index template.

```tf
resource elasticsearch_index_template_legacy "test" {
name = "terraform-test"
template = <<EOF
{
"index_patterns": [
"test"
],
"settings": {
"index.refresh_interval": "5s",
"index.lifecycle.name": "policy-logstash-backup",
"index.lifecycle.rollover_alias": "logstash-backup-alias"
},
"order": 2
}
EOF
}
```

## Argument Reference

***The following arguments are supported:***
- **name**: (required) Identifier for the template.
- **template**: (required) The template specification. It's a string as JSON object.

## Attribute Reference

NA
164 changes: 147 additions & 17 deletions es/diff_suppress_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,65 @@ package es

import (
"encoding/json"
"fmt"
"reflect"
"strconv"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/olivere/elastic/v7"
log "github.com/sirupsen/logrus"
)

// diffSuppressIndexTemplate permit to compare template in current state vs from API
func diffSuppressIndexTemplate(k, old, new string, d *schema.ResourceData) bool {
var oo, no map[string]interface{}
// diffSuppressIndexTemplateLegacy permit to compare template in current state vs from API
func diffSuppressIndexTemplateLegacy(k, old, new string, d *schema.ResourceData) bool {

oo := &elastic.IndicesGetTemplateResponse{}
no := &elastic.IndicesGetTemplateResponse{}

if err := json.Unmarshal([]byte(old), &oo); err != nil {
fmt.Printf("[ERR] Error when converting to IndicesGetComponentTemplate: %s", err.Error())
log.Errorf("Error when converting to IndicesGetComponentTemplate: %s", err.Error())
return false
}
if err := json.Unmarshal([]byte(new), &no); err != nil {
fmt.Printf("[ERR] Error when converting to IndicesGetComponentTemplate: %s", err.Error())
log.Errorf("Error when converting to IndicesGetComponentTemplate: %s", err.Error())
return false
}

// Add default parameters on new index template if needed
if _, ok := no["order"]; !ok {
no["order"] = 0
// inits default values

if oo.Aliases == nil {
oo.Aliases = make(map[string]interface{})
}
if _, ok := no["settings"]; !ok {
no["settings"] = make(map[string]interface{})
if oo.Mappings == nil {
oo.Mappings = make(map[string]interface{})
}
if oo.Settings == nil {
oo.Settings = make(map[string]interface{})
}

if no.Aliases == nil {
no.Aliases = make(map[string]interface{})
}
if _, ok := no["mappings"]; !ok {
no["mappings"] = make(map[string]interface{})
if no.Mappings == nil {
no.Mappings = make(map[string]interface{})
}
if _, ok := no["aliases"]; !ok {
no["aliases"] = make(map[string]interface{})
if no.Settings == nil {
no.Settings = make(map[string]interface{})
}

ob, _ := json.Marshal(oo)
nb, _ := json.Marshal(parseAllDotProperties(no))
// force undot properties to compare the same think
oo.Aliases = parseAllDotProperties(oo.Aliases)
oo.Mappings = parseAllDotProperties(oo.Mappings)
oo.Settings = parseAllDotProperties(oo.Settings)

log.Debugf("Old: %s", string(ob))
log.Debugf("New: %s", string(nb))
no.Aliases = parseAllDotProperties(no.Aliases)
no.Mappings = parseAllDotProperties(no.Mappings)
no.Settings = parseAllDotProperties(no.Settings)

return reflect.DeepEqual(oo, parseAllDotProperties(no))
return reflect.DeepEqual(oo, no)
}

// suppressEquivalentJSON permit to compare state store as JSON string
Expand Down Expand Up @@ -121,3 +141,113 @@ func parseDotPropertie(key string, value interface{}, result map[string]interfac
}

}

// diffSuppressIndexComponentTemplate permit to compare index component template in current state vs from API
func diffSuppressIndexComponentTemplate(k, old, new string, d *schema.ResourceData) bool {
oo := &elastic.IndicesGetComponentTemplate{}
no := &elastic.IndicesGetComponentTemplate{}

if err := json.Unmarshal([]byte(old), &oo); err != nil {
fmt.Printf("[ERR] Error when converting to IndicesGetComponentTemplate: %s", err.Error())
log.Errorf("Error when converting to IndicesGetComponentTemplate: %s", err.Error())
return false
}
if err := json.Unmarshal([]byte(new), &no); err != nil {
fmt.Printf("[ERR] Error when converting to IndicesGetComponentTemplate: %s", err.Error())
log.Errorf("Error when converting to IndicesGetComponentTemplate: %s", err.Error())
return false
}

// inits default values
if oo.Template != nil {
if oo.Template.Aliases == nil {
oo.Template.Aliases = make(map[string]interface{})
}
if oo.Template.Mappings == nil {
oo.Template.Mappings = make(map[string]interface{})
}
if oo.Template.Settings == nil {
oo.Template.Settings = make(map[string]interface{})
}
}
if no.Template != nil {
if no.Template.Aliases == nil {
no.Template.Aliases = make(map[string]interface{})
}
if no.Template.Mappings == nil {
no.Template.Mappings = make(map[string]interface{})
}
if no.Template.Settings == nil {
no.Template.Settings = make(map[string]interface{})
}
}

// force undot properties to compare the same think
if oo.Template != nil {
oo.Template.Aliases = parseAllDotProperties(oo.Template.Aliases)
oo.Template.Mappings = parseAllDotProperties(oo.Template.Mappings)
oo.Template.Settings = parseAllDotProperties(oo.Template.Settings)
}
if no.Template != nil {
no.Template.Aliases = parseAllDotProperties(no.Template.Aliases)
no.Template.Mappings = parseAllDotProperties(no.Template.Mappings)
no.Template.Settings = parseAllDotProperties(no.Template.Settings)
}

return reflect.DeepEqual(oo, no)
}

// diffSuppressIndexTemplate permit to compare index template in current state vs from API
func diffSuppressIndexTemplate(k, old, new string, d *schema.ResourceData) bool {
oo := &elastic.IndicesGetIndexTemplate{}
no := &elastic.IndicesGetIndexTemplate{}

if err := json.Unmarshal([]byte(old), &oo); err != nil {
fmt.Printf("[ERR] Error when converting to IndicesGetIndexTemplate on old object: %s", err.Error())
log.Errorf("Error when converting to IndicesGetIndexTemplate on old object: %s\n%s", err.Error(), old)
return false
}
if err := json.Unmarshal([]byte(new), &no); err != nil {
fmt.Printf("[ERR] Error when converting to IndicesGetIndexTemplate on new object: %s", err.Error())
log.Errorf("Error when converting to IndicesGetIndexTemplate on new object: %s\n%s", err.Error(), new)
return false
}

// inits default values
if oo.Template != nil {
if oo.Template.Aliases == nil {
oo.Template.Aliases = make(map[string]interface{})
}
if oo.Template.Mappings == nil {
oo.Template.Mappings = make(map[string]interface{})
}
if oo.Template.Settings == nil {
oo.Template.Settings = make(map[string]interface{})
}
}
if no.Template != nil {
if no.Template.Aliases == nil {
no.Template.Aliases = make(map[string]interface{})
}
if no.Template.Mappings == nil {
no.Template.Mappings = make(map[string]interface{})
}
if no.Template.Settings == nil {
no.Template.Settings = make(map[string]interface{})
}
}

// force undot properties to compare the same think
if oo.Template != nil {
oo.Template.Aliases = parseAllDotProperties(oo.Template.Aliases)
oo.Template.Mappings = parseAllDotProperties(oo.Template.Mappings)
oo.Template.Settings = parseAllDotProperties(oo.Template.Settings)
}
if no.Template != nil {
no.Template.Aliases = parseAllDotProperties(no.Template.Aliases)
no.Template.Mappings = parseAllDotProperties(no.Template.Mappings)
no.Template.Settings = parseAllDotProperties(no.Template.Settings)
}

return reflect.DeepEqual(no, oo)
}
2 changes: 2 additions & 0 deletions es/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ func Provider() *schema.Provider {

ResourcesMap: map[string]*schema.Resource{
"elasticsearch_index_lifecycle_policy": resourceElasticsearchIndexLifecyclePolicy(),
"elasticsearch_index_template_legacy": resourceElasticsearchIndexTemplateLegacy(),
"elasticsearch_index_template": resourceElasticsearchIndexTemplate(),
"elasticsearch_index_component_template": resourceElasticsearchIndexComponentTemplate(),
"elasticsearch_role": resourceElasticsearchSecurityRole(),
"elasticsearch_role_mapping": resourceElasticsearchSecurityRoleMapping(),
"elasticsearch_user": resourceElasticsearchSecurityUser(),
Expand Down
Loading

0 comments on commit 5ca17fe

Please sign in to comment.