From 01e0538b984c2ce3d15c46b48abd5cb5d0c91cc9 Mon Sep 17 00:00:00 2001 From: Artem Iarmoliuk Date: Mon, 4 Dec 2017 12:05:05 +0200 Subject: [PATCH] Add support for custom CA cert --- README.md | 2 + glide.lock | 3 +- provider.go | 51 ++++++++++++++++++- .../elasticsearch/index.html.markdown | 2 + 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1470295b..7e6100b9 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ provider "elasticsearch" { aws_access_key = "" aws_secret_key = "" aws_token = "" # if necessary + insecure = true # to bypass certificate check + cacert_file = "/path/to/ca.crt" # when connecting to elastic with self-signed certificate } resource "elasticsearch_index_template" "test" { diff --git a/glide.lock b/glide.lock index 18f82ea3..ad483edd 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: fab5044983637e52255e2a15e9c2903edaee00b37e54c96fce02cb365fd426aa -updated: 2017-09-18T09:44:54.350432701-04:00 +updated: 2017-12-03T18:55:37.48086421+02:00 imports: - name: github.com/apparentlymart/go-cidr version: 2bd8b58cf4275aeb086ade613de226773e29e853 @@ -102,6 +102,7 @@ imports: - helper/hashcode - helper/hilmapstructure - helper/logging + - helper/pathorcontents - helper/resource - helper/schema - helper/shadow diff --git a/provider.go b/provider.go index 1ec0e624..653fe1c7 100644 --- a/provider.go +++ b/provider.go @@ -1,6 +1,8 @@ package main import ( + "crypto/tls" + "crypto/x509" "log" "net/http" "net/url" @@ -9,6 +11,7 @@ import ( awscredentials "github.com/aws/aws-sdk-go/aws/credentials" awssigv4 "github.com/aws/aws-sdk-go/aws/signer/v4" "github.com/deoxxa/aws_signing_client" + "github.com/hashicorp/terraform/helper/pathorcontents" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" elastic "gopkg.in/olivere/elastic.v5" @@ -46,12 +49,26 @@ func Provider() terraform.ResourceProvider { Default: "", Description: "The session token for use with AWS Elasticsearch Service domains", }, + + "cacert_file": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "", + Description: "A Custom CA certificate", + }, + + "insecure": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Disable SSL verification of API calls", + }, }, ResourcesMap: map[string]*schema.Resource{ "elasticsearch_index_template": resourceElasticsearchIndexTemplate(), "elasticsearch_snapshot_repository": resourceElasticsearchSnapshotRepository(), - "elasticsearch_kibana_object": resourceElasticsearchKibanaObject(), + "elasticsearch_kibana_object": resourceElasticsearchKibanaObject(), }, ConfigureFunc: providerConfigure, @@ -60,6 +77,8 @@ func Provider() terraform.ResourceProvider { func providerConfigure(d *schema.ResourceData) (interface{}, error) { rawUrl := d.Get("url").(string) + insecure := d.Get("insecure").(bool) + cacertFile := d.Get("cacert_file").(string) parsedUrl, err := url.Parse(rawUrl) if err != nil { return nil, err @@ -72,6 +91,8 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { if m := awsUrlRegexp.FindStringSubmatch(parsedUrl.Hostname()); m != nil { log.Printf("[INFO] Using AWS: %+v", m[1]) opts = append(opts, elastic.SetHttpClient(awsHttpClient(m[1], d)), elastic.SetSniff(false)) + } else if insecure || cacertFile != "" { + opts = append(opts, elastic.SetHttpClient(tlsHttpClient(d)), elastic.SetSniff(false)) } return elastic.NewClient(opts...) @@ -93,3 +114,31 @@ func awsHttpClient(region string, d *schema.ResourceData) *http.Client { return client } + +func tlsHttpClient(d *schema.ResourceData) *http.Client { + insecure := d.Get("insecure").(bool) + cacertFile := d.Get("cacert_file").(string) + + // Configure TLS/SSL + tlsConfig := &tls.Config{} + + // If a cacertFile has been specified, use that for cert validation + if cacertFile != "" { + caCert, _, _ := pathorcontents.Read(cacertFile) + + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM([]byte(caCert)) + tlsConfig.RootCAs = caCertPool + } + + // If configured as insecure, turn off SSL verification + if insecure { + tlsConfig.InsecureSkipVerify = true + } + + transport := &http.Transport{TLSClientConfig: tlsConfig} + + client := &http.Client{Transport: transport} + + return client +} diff --git a/website/source/docs/providers/elasticsearch/index.html.markdown b/website/source/docs/providers/elasticsearch/index.html.markdown index 88960688..bc2a043a 100644 --- a/website/source/docs/providers/elasticsearch/index.html.markdown +++ b/website/source/docs/providers/elasticsearch/index.html.markdown @@ -62,3 +62,5 @@ The following arguments are supported: * `aws_access_key` - (Optional) The access key for use with AWS Elasticsearch Service domains. It can also be sourced from the `AWS_ACCESS_KEY_ID` environment variable. * `aws_secret_key` - (Optional) The secret key for use with AWS Elasticsearch Service domains. It can also be sourced from the `AWS_SECRET_ACCESS_KEY` environment variable. * `aws_token` - (Optional) The session token for use with AWS Elasticsearch Service domains. It can also be sourced from the `AWS_SESSION_TOKEN` environment variable. +* `cacert_file` - (Optional) Specify a custom CA certificate when communicating over SSL. You can specify either a path to the file or the contents of the certificate. +* `insecure` - (Optional) Trust self-signed certificates.