Skip to content

Commit

Permalink
Add destination data source.
Browse files Browse the repository at this point in the history
  • Loading branch information
phillbaker committed Jun 30, 2019
1 parent a117447 commit 11d47d9
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ install:
script:
- export GO111MODULE=on
- wget -q --waitretry=1 --retry-connrefused -T 10 -O - $ELASTICSEARCH_URL
# Opendistro lazily initializes it's indexes, warm it up here :|
# https://github.com/opendistro-for-elasticsearch/alerting/issues/60
- |
if [ -n "$ES_OPENDISTRO_IMAGE" ]; then curl -X POST -H 'Content-type: application/json' -d '{"name":"_warmup","type":"slack","slack":{"url": "http://www.example.com"}}' 127.0.0.1:9220/_opendistro/_alerting/destinations; fi
- TF_ACC=1 go test -v -cover
before_deploy:
- export GO111MODULE=on
Expand Down
107 changes: 107 additions & 0 deletions data_source_elasticsearch_destination.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package main

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

"github.com/hashicorp/terraform/helper/schema"

elastic7 "github.com/olivere/elastic/v7"
elastic6 "gopkg.in/olivere/elastic.v6"
)

const DESTINATION_NAME_FIELD = "destination.name.keyword"

func dataSourceElasticsearchDestination() *schema.Resource {
return &schema.Resource{
Read: dataSourceElasticsearchDestinationRead,

Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"body": &schema.Schema{
Type: schema.TypeMap,
Computed: true,
},
},
}
}

func dataSourceElasticsearchDestinationRead(d *schema.ResourceData, m interface{}) error {
destinationName := d.Get("name").(string)

response := new(destinationResponse)

// See https://github.com/opendistro-for-elasticsearch/alerting/issues/70, no tags or API endpoint for searching destination
var id string
var body *json.RawMessage
var err error
switch m.(type) {
case *elastic7.Client:
client := m.(*elastic7.Client)
id, body, err = elastic7Search(client, DESTINATION_INDEX, destinationName)
case *elastic6.Client:
client := m.(*elastic6.Client)
id, body, err = elastic6Search(client, DESTINATION_INDEX, destinationName)
default:
err = errors.New("destination resource not implemented prior to Elastic v6")
}

if err != nil {
return err
} else if id == "" {
// short circuit
return nil
}

if err := json.Unmarshal(*body, response); err != nil {
return fmt.Errorf("error unmarshalling destination body: %+v: %+v", err, body)
}

d.SetId(id)
d.Set("body", response.Destination.(map[string]interface{}))

return err
}

func elastic7Search(client *elastic7.Client, index string, name string) (string, *json.RawMessage, error) {
termQuery := elastic7.NewTermQuery(DESTINATION_NAME_FIELD, name)
result, err := client.Search().
Index(index).
Query(termQuery).
Do(context.TODO())

if err != nil {
return "", nil, err
}
if result.TotalHits() == 1 {
return result.Hits.Hits[0].Id, &result.Hits.Hits[0].Source, nil
} else if result.TotalHits() < 1 {
return "", nil, err
} else {
return "", nil, fmt.Errorf("1 result expected, found %d.", result.TotalHits())
}
}

func elastic6Search(client *elastic6.Client, index string, name string) (string, *json.RawMessage, error) {
termQuery := elastic6.NewTermQuery(DESTINATION_NAME_FIELD, name)
result, err := client.Search().
Index(index).
Query(termQuery).
Do(context.TODO())

if err != nil {
return "", nil, err
}
if result.TotalHits() == 1 {
return result.Hits.Hits[0].Id, result.Hits.Hits[0].Source, nil
} else if result.TotalHits() < 1 {
return "", nil, err
} else {
return "", nil, fmt.Errorf("1 result expected, found %d.", result.TotalHits())
}
}
67 changes: 67 additions & 0 deletions data_source_elasticsearch_destination_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package main

import (
"testing"

elastic7 "github.com/olivere/elastic/v7"
elastic5 "gopkg.in/olivere/elastic.v5"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)

func TestAccElasticsearchDataSourceDestination_basic(t *testing.T) {
provider := Provider().(*schema.Provider)
err := provider.Configure(&terraform.ResourceConfig{})
if err != nil {
t.Skipf("err: %s", err)
}
meta := provider.Meta()
var allowed bool
switch meta.(type) {
case *elastic7.Client:
allowed = false
case *elastic5.Client:
allowed = false
default:
allowed = true
}

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
if !allowed {
t.Skip("Destinations only supported on ES 6, https://github.com/opendistro-for-elasticsearch/alerting/issues/66")
}
},
Providers: testAccOpendistroProviders,
Steps: []resource.TestStep{
{
Config: testAccElasticsearchDataSourceDestination,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet("data.elasticsearch_destination.test", "id"),
),
},
},
})
}

var testAccElasticsearchDataSourceDestination = `
resource "elasticsearch_destination" "test" {
body = <<EOF
{
"name": "my-destination",
"type": "slack",
"slack": {
"url": "http://www.example.com"
}
}
EOF
}
data "elasticsearch_destination" "test" {
# Ugh, song and dance to get the json value to force dependency
name = "${element(list("my-destination", "${elasticsearch_destination.test.body}"), 0)}"
}
`
4 changes: 4 additions & 0 deletions provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ func Provider() terraform.ResourceProvider {
"elasticsearch_destination": resourceElasticsearchDestination(),
},

DataSourcesMap: map[string]*schema.Resource{
"elasticsearch_destination": dataSourceElasticsearchDestination(),
},

ConfigureFunc: providerConfigure,
}
}
Expand Down

0 comments on commit 11d47d9

Please sign in to comment.