Skip to content

Commit

Permalink
Add support for ElasticSearch 7.8+ Index templates (#120)
Browse files Browse the repository at this point in the history
* Add resource_elasticsearch_template_index.go and update ES7 client to latest version

* Remove phases.delete.actions.delete.delete_searchable_snapshot when true from IL Policy

* Fix ineffassign errors

* Add testing for new resource, adjust some error messages and add new diff supress function

* Update go.sum

* Rename resource and functions from template index to composable index template

* Add documentation page

* cleanup, add changelog

* back out phases.delete.actions.delete.delete_searchable_snapshot diff supress for now

* fix linting

* update tests for default value

* split es6 from es7 fixtures

Co-authored-by: Victor Cabezas <[email protected]>
Co-authored-by: Phillip Baker <[email protected]>
  • Loading branch information
3 people authored Dec 15, 2020
1 parent 5302ba1 commit 8b5a81f
Show file tree
Hide file tree
Showing 11 changed files with 498 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ env:
jobs:
- ES_VERSION=5.6.16 ES_OSS_IMAGE=elasticsearch:${ES_VERSION} ES_IMAGE=docker.elastic.co/elasticsearch/elasticsearch:${ES_VERSION} ES_COMMAND="elasticsearch -Epath.repo=/tmp"
- ES_VERSION=6.8.9 ES_OSS_IMAGE=docker.elastic.co/elasticsearch/elasticsearch-oss:${ES_VERSION} ES_IMAGE=docker.elastic.co/elasticsearch/elasticsearch:${ES_VERSION} ES_OPENDISTRO_IMAGE=amazon/opendistro-for-elasticsearch:0.9.0
- ES_VERSION=7.6.1 ES_OSS_IMAGE=docker.elastic.co/elasticsearch/elasticsearch-oss:${ES_VERSION} ES_IMAGE=docker.elastic.co/elasticsearch/elasticsearch:${ES_VERSION} ES_OPENDISTRO_IMAGE=amazon/opendistro-for-elasticsearch:1.6.0
- ES_VERSION=7.9.3 ES_OSS_IMAGE=docker.elastic.co/elasticsearch/elasticsearch-oss:${ES_VERSION} ES_IMAGE=docker.elastic.co/elasticsearch/elasticsearch:${ES_VERSION} ES_OPENDISTRO_IMAGE=amazon/opendistro-for-elasticsearch:1.6.0
addons:
ssh_known_hosts: github.com
apt:
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
- Allow provider variable interpolation by deferring client instanation, `providerConfigure` only returns a configuration struct.

### Added
-
- Composable Index Template resource, available in ESv7.8+

## [1.5.0] - 2020-10-26
### Changed
Expand Down
63 changes: 63 additions & 0 deletions docs/resources/composable_index_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
layout: "elasticsearch"
page_title: "Elasticsearch: elasticsearch_composable_index_template"
subcategory: "Elasticsearch Opensource"
description: |-
Provides an Elasticsearch Composable index template resource.
---

# elasticsearch_composable_index_template

Provides an Elasticsearch Composable index template resource. This resource uses the `/_index_template`
endpoint of Elasticsearch API that is available since version 7.8. Use `elasticsearch_index_template` if
you are using older versions of Elasticsearch or if you want to keep using legacy Index Templates in Elasticsearch 7.8+.

## Example Usage

```tf
# Create an index template
resource "elasticsearch_composable_index_template" "template_1" {
name = "template_1"
body = <<EOF
{
"index_patterns": ["te*", "bar*"],
"template": {
"settings": {
"index": {
"number_of_shards": 1
}
},
"mappings": {
"properties": {
"host_name": {
"type": "keyword"
},
"created_at": {
"type": "date",
"format": "EEE MMM dd HH:mm:ss Z yyyy"
}
}
},
"aliases": {
"mydata": { }
}
},
"priority": 200,
"version": 3
}
EOF
}
```

## Argument Reference

The following arguments are supported:

* `name` - (Required) The name of the index template.
* `body` - (Required) The JSON body of the index template.

## Attributes Reference

The following attributes are exported:

* `id` - The name of the index template.
24 changes: 24 additions & 0 deletions es/diff_suppress_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,30 @@ func diffSuppressIndexTemplate(k, old, new string, d *schema.ResourceData) bool
return reflect.DeepEqual(oo, no)
}

/*
diffSuppressComposableIndexTemplate compares an index_template (ES >= 7.8) Index template definition
For legacy index templates (ES < 7.8) or /_template endpoint on ES >= 7.8 see diffSuppressIndexTemplate.
*/
func diffSuppressComposableIndexTemplate(k, old, new string, d *schema.ResourceData) bool {
var oo, no interface{}
if err := json.Unmarshal([]byte(old), &oo); err != nil {
return false
}
if err := json.Unmarshal([]byte(new), &no); err != nil {
return false
}

if om, ok := oo.(map[string]interface{}); ok {
normalizeComposableIndexTemplate(om)
}

if nm, ok := no.(map[string]interface{}); ok {
normalizeComposableIndexTemplate(nm)
}

return reflect.DeepEqual(oo, no)
}

func diffSuppressDestination(k, old, new string, d *schema.ResourceData) bool {
var oo, no interface{}
if err := json.Unmarshal([]byte(old), &oo); err != nil {
Expand Down
1 change: 1 addition & 0 deletions es/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ func Provider() terraform.ResourceProvider {
"elasticsearch_index": resourceElasticsearchIndex(),
"elasticsearch_index_lifecycle_policy": resourceElasticsearchDeprecatedIndexLifecyclePolicy(),
"elasticsearch_index_template": resourceElasticsearchIndexTemplate(),
"elasticsearch_composable_index_template": resourceElasticsearchComposableIndexTemplate(),
"elasticsearch_ingest_pipeline": resourceElasticsearchIngestPipeline(),
"elasticsearch_kibana_object": resourceElasticsearchKibanaObject(),
"elasticsearch_monitor": resourceElasticsearchDeprecatedMonitor(),
Expand Down
151 changes: 151 additions & 0 deletions es/resource_elasticsearch_composable_index_template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package es

import (
"context"
"encoding/json"
"fmt"
"log"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
elastic7 "github.com/olivere/elastic/v7"
)

func resourceElasticsearchComposableIndexTemplate() *schema.Resource {
return &schema.Resource{
Create: resourceElasticsearchComposableIndexTemplateCreate,
Read: resourceElasticsearchComposableIndexTemplateRead,
Update: resourceElasticsearchComposableIndexTemplateUpdate,
Delete: resourceElasticsearchComposableIndexTemplateDelete,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"body": {
Type: schema.TypeString,
Required: true,
DiffSuppressFunc: diffSuppressComposableIndexTemplate,
ValidateFunc: validation.StringIsJSON,
},
},
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
}
}

func resourceElasticsearchComposableIndexTemplateCreate(d *schema.ResourceData, meta interface{}) error {
err := resourceElasticsearchPutComposableIndexTemplate(d, meta, true)
if err != nil {
return err
}
d.SetId(d.Get("name").(string))
return nil
}

func resourceElasticsearchComposableIndexTemplateRead(d *schema.ResourceData, meta interface{}) error {
id := d.Id()

var result, version string
var err error
switch client := meta.(type) {
case *elastic7.Client:
version, err = elastic7GetVersion(client)
if err == nil {
if version < "7.8.0" {
err = fmt.Errorf("index_template endpoint only available from ElasticSearch >= 7.8, got version %s", version)
} else {
result, err = elastic7GetIndexTemplate(client, id)
}
}
default:
err = fmt.Errorf("index_template endpoint only available from ElasticSearch >= 7.8, got version < 7.0.0")
}
if err != nil {
if elastic7.IsNotFound(err) {
log.Printf("[WARN] Index template (%s) not found, removing from state", id)
d.SetId("")
return nil
}

return err
}

ds := &resourceDataSetter{d: d}
ds.set("name", d.Id())
ds.set("body", result)
return ds.err
}

func elastic7GetIndexTemplate(client *elastic7.Client, id string) (string, error) {
res, err := client.IndexGetIndexTemplate(id).Do(context.TODO())
if err != nil {
return "", err
}

// No more than 1 element is expected, if the index template is not found, previous call should
// return a 404 error
t := res.IndexTemplates[0].IndexTemplate
tj, err := json.Marshal(t)
if err != nil {
return "", err
}
return string(tj), nil
}

func resourceElasticsearchComposableIndexTemplateUpdate(d *schema.ResourceData, meta interface{}) error {
return resourceElasticsearchPutComposableIndexTemplate(d, meta, false)
}

func resourceElasticsearchComposableIndexTemplateDelete(d *schema.ResourceData, meta interface{}) error {
id := d.Id()

var version string
var err error
switch client := meta.(type) {
case *elastic7.Client:
version, err = elastic7GetVersion(client)
if err == nil {
if version < "7.8.0" {
err = fmt.Errorf("index_template endpoint only available from ElasticSearch >= 7.8, got version %s", version)
} else {
err = elastic7DeleteIndexTemplate(client, id)
}
}
default:
err = fmt.Errorf("index_template endpoint only available from ElasticSearch >= 7.8, got version < 7.0.0")
}

if err != nil {
return err
}
d.SetId("")
return nil
}

func elastic7DeleteIndexTemplate(client *elastic7.Client, id string) error {
_, err := client.IndexDeleteIndexTemplate(id).Do(context.TODO())
return err
}

func resourceElasticsearchPutComposableIndexTemplate(d *schema.ResourceData, meta interface{}, create bool) error {
name := d.Get("name").(string)
body := d.Get("body").(string)

var err error
switch client := meta.(type) {
case *elastic7.Client:
err = elastic7PutIndexTemplate(client, name, body, create)
default:
err = fmt.Errorf("index_template endpoint only available from ElasticSearch >= 7.8, got version < 7.0.0")
}

return err
}

func elastic7PutIndexTemplate(client *elastic7.Client, name string, body string, create bool) error {
_, err := client.IndexPutIndexTemplate(name).BodyString(body).Create(create).Do(context.TODO())
return err
}
Loading

0 comments on commit 8b5a81f

Please sign in to comment.