From d466adea7f5655158918751aed829d69f5d6b2ef Mon Sep 17 00:00:00 2001 From: Andreas Kapfer Date: Fri, 11 Nov 2022 12:44:02 +0100 Subject: [PATCH] Add authentication to Elasticsearch via client cert --- .../elasticsearch_security_role.md | 4 ++ .../elasticsearch_security_role_mapping.md | 4 ++ .../elasticsearch_security_user.md | 4 ++ .../elasticsearch_snapshot_repository.md | 4 ++ docs/index.md | 4 ++ .../elasticsearch_cluster_settings.md | 4 ++ .../elasticsearch_component_template.md | 4 ++ docs/resources/elasticsearch_data_stream.md | 4 ++ docs/resources/elasticsearch_index.md | 4 ++ .../elasticsearch_index_lifecycle.md | 4 ++ .../resources/elasticsearch_index_template.md | 4 ++ .../elasticsearch_ingest_pipeline.md | 4 ++ .../elasticsearch_logstash_pipeline.md | 4 ++ docs/resources/elasticsearch_script.md | 4 ++ docs/resources/elasticsearch_security_role.md | 4 ++ .../elasticsearch_security_role_mapping.md | 4 ++ docs/resources/elasticsearch_security_user.md | 4 ++ .../elasticsearch_snapshot_lifecycle.md | 4 ++ .../elasticsearch_snapshot_repository.md | 4 ++ internal/clients/api_client.go | 69 ++++++++++++++++++- internal/utils/utils.go | 32 ++++++++- provider/provider.go | 33 ++++++++- 22 files changed, 203 insertions(+), 7 deletions(-) diff --git a/docs/data-sources/elasticsearch_security_role.md b/docs/data-sources/elasticsearch_security_role.md index 8f747c94e..f6de31042 100644 --- a/docs/data-sources/elasticsearch_security_role.md +++ b/docs/data-sources/elasticsearch_security_role.md @@ -55,8 +55,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/data-sources/elasticsearch_security_role_mapping.md b/docs/data-sources/elasticsearch_security_role_mapping.md index 947ee66df..522289b31 100644 --- a/docs/data-sources/elasticsearch_security_role_mapping.md +++ b/docs/data-sources/elasticsearch_security_role_mapping.md @@ -54,7 +54,11 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/data-sources/elasticsearch_security_user.md b/docs/data-sources/elasticsearch_security_user.md index a0310393d..634fff7b0 100644 --- a/docs/data-sources/elasticsearch_security_user.md +++ b/docs/data-sources/elasticsearch_security_user.md @@ -54,7 +54,11 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/data-sources/elasticsearch_snapshot_repository.md b/docs/data-sources/elasticsearch_snapshot_repository.md index 35436665c..9c4806467 100644 --- a/docs/data-sources/elasticsearch_snapshot_repository.md +++ b/docs/data-sources/elasticsearch_snapshot_repository.md @@ -82,8 +82,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/index.md b/docs/index.md index 1c41f2636..e8c76573d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -95,7 +95,11 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A comma-separated list of endpoints where the terraform provider will point to, this must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String, Sensitive) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) Password to use for API authentication to Elasticsearch. - `username` (String) Username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_cluster_settings.md b/docs/resources/elasticsearch_cluster_settings.md index 3eea6591a..ff76a40db 100644 --- a/docs/resources/elasticsearch_cluster_settings.md +++ b/docs/resources/elasticsearch_cluster_settings.md @@ -67,8 +67,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_component_template.md b/docs/resources/elasticsearch_component_template.md index cfece5469..09ddd4159 100644 --- a/docs/resources/elasticsearch_component_template.md +++ b/docs/resources/elasticsearch_component_template.md @@ -92,8 +92,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_data_stream.md b/docs/resources/elasticsearch_data_stream.md index 88f544177..d20c9ce57 100644 --- a/docs/resources/elasticsearch_data_stream.md +++ b/docs/resources/elasticsearch_data_stream.md @@ -98,8 +98,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_index.md b/docs/resources/elasticsearch_index.md index 781fe4759..0e0976a4a 100644 --- a/docs/resources/elasticsearch_index.md +++ b/docs/resources/elasticsearch_index.md @@ -153,8 +153,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_index_lifecycle.md b/docs/resources/elasticsearch_index_lifecycle.md index 6449042f9..3914aa93d 100644 --- a/docs/resources/elasticsearch_index_lifecycle.md +++ b/docs/resources/elasticsearch_index_lifecycle.md @@ -188,8 +188,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_index_template.md b/docs/resources/elasticsearch_index_template.md index 37298f310..6a1b897e0 100644 --- a/docs/resources/elasticsearch_index_template.md +++ b/docs/resources/elasticsearch_index_template.md @@ -84,8 +84,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_ingest_pipeline.md b/docs/resources/elasticsearch_ingest_pipeline.md index a8158a922..9de853d13 100644 --- a/docs/resources/elasticsearch_ingest_pipeline.md +++ b/docs/resources/elasticsearch_ingest_pipeline.md @@ -97,8 +97,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_logstash_pipeline.md b/docs/resources/elasticsearch_logstash_pipeline.md index d4213df43..96f11ca86 100644 --- a/docs/resources/elasticsearch_logstash_pipeline.md +++ b/docs/resources/elasticsearch_logstash_pipeline.md @@ -99,8 +99,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_script.md b/docs/resources/elasticsearch_script.md index aeb8ac094..102ea9df5 100644 --- a/docs/resources/elasticsearch_script.md +++ b/docs/resources/elasticsearch_script.md @@ -69,8 +69,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_security_role.md b/docs/resources/elasticsearch_security_role.md index ce618adfa..d66ff2c7f 100644 --- a/docs/resources/elasticsearch_security_role.md +++ b/docs/resources/elasticsearch_security_role.md @@ -83,8 +83,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_security_role_mapping.md b/docs/resources/elasticsearch_security_role_mapping.md index 8be459b94..46be1af67 100644 --- a/docs/resources/elasticsearch_security_role_mapping.md +++ b/docs/resources/elasticsearch_security_role_mapping.md @@ -64,8 +64,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_security_user.md b/docs/resources/elasticsearch_security_user.md index 9bc431e69..26aac6093 100644 --- a/docs/resources/elasticsearch_security_user.md +++ b/docs/resources/elasticsearch_security_user.md @@ -83,8 +83,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_snapshot_lifecycle.md b/docs/resources/elasticsearch_snapshot_lifecycle.md index 52533a07e..3a8039513 100644 --- a/docs/resources/elasticsearch_snapshot_lifecycle.md +++ b/docs/resources/elasticsearch_snapshot_lifecycle.md @@ -82,8 +82,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/docs/resources/elasticsearch_snapshot_repository.md b/docs/resources/elasticsearch_snapshot_repository.md index 29640a01b..db9ac6b6a 100644 --- a/docs/resources/elasticsearch_snapshot_repository.md +++ b/docs/resources/elasticsearch_snapshot_repository.md @@ -85,8 +85,12 @@ Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch - `ca_data` (String) PEM-encoded custom Certificate Authority certificate - `ca_file` (String) Path to a custom Certificate Authority certificate +- `cert_data` (String) PEM encoded certificate for client auth +- `cert_file` (String) Path to a file containing the PEM encoded certificate for client auth - `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. - `insecure` (Boolean) Disable TLS certificate validation +- `key_data` (String) PEM encoded private key for client auth +- `key_file` (String) Path to a file containing the PEM encoded private key for client auth - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. diff --git a/internal/clients/api_client.go b/internal/clients/api_client.go index 1657b9b2b..4fb768edd 100644 --- a/internal/clients/api_client.go +++ b/internal/clients/api_client.go @@ -96,9 +96,8 @@ func NewApiClientFunc(version string, p *schema.Provider) func(context.Context, } if insecure, ok := esConfig["insecure"]; ok && insecure.(bool) { - tr := http.DefaultTransport.(*http.Transport) - tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - config.Transport = tr + ensureTLSClientConfig(&config) + config.Transport.(*http.Transport).TLSClientConfig.InsecureSkipVerify = true } if caFile, ok := esConfig["ca_file"]; ok && caFile.(string) != "" { @@ -116,6 +115,37 @@ func NewApiClientFunc(version string, p *schema.Provider) func(context.Context, if caData, ok := esConfig["ca_data"]; ok && caData.(string) != "" { config.CACert = []byte(caData.(string)) } + + if certFile, ok := esConfig["cert_file"]; ok && certFile.(string) != "" { + if keyFile, ok := esConfig["key_file"]; ok && keyFile.(string) != "" { + cert, err := tls.LoadX509KeyPair(certFile.(string), keyFile.(string)) + if err != nil { + diags = append(diags, diag.Diagnostic{ + Severity: diag.Error, + Summary: "Unable to read certificate or key file", + Detail: err.Error(), + }) + return nil, diags + } + ensureTLSClientConfig(&config) + config.Transport.(*http.Transport).TLSClientConfig.Certificates = []tls.Certificate{cert} + } + } + if certData, ok := esConfig["cert_data"]; ok && certData.(string) != "" { + if keyData, ok := esConfig["key_data"]; ok && keyData.(string) != "" { + cert, err := tls.X509KeyPair([]byte(certData.(string)), []byte(keyData.(string))) + if err != nil { + diags = append(diags, diag.Diagnostic{ + Severity: diag.Error, + Summary: "Unable to parse certificate or key", + Detail: err.Error(), + }) + return nil, diags + } + ensureTLSClientConfig(&config) + config.Transport.(*http.Transport).TLSClientConfig.Certificates = []tls.Certificate{cert} + } + } } } @@ -172,6 +202,30 @@ func NewApiClient(d *schema.ResourceData, meta interface{}) (*ApiClient, error) } config.CACert = caCert } + if caData, ok := conn["ca_data"]; ok && caData.(string) != "" { + config.CACert = []byte(caData.(string)) + } + + if certFile, ok := conn["cert_file"]; ok && certFile.(string) != "" { + if keyFile, ok := conn["key_file"]; ok && keyFile.(string) != "" { + cert, err := tls.LoadX509KeyPair(certFile.(string), keyFile.(string)) + if err != nil { + return nil, fmt.Errorf("Unable to read certificate or key file: %w", err) + } + ensureTLSClientConfig(&config) + config.Transport.(*http.Transport).TLSClientConfig.Certificates = []tls.Certificate{cert} + } + } + if certData, ok := conn["cert_data"]; ok && certData.(string) != "" { + if keyData, ok := conn["key_data"]; ok && keyData.(string) != "" { + cert, err := tls.X509KeyPair([]byte(certData.(string)), []byte(keyData.(string))) + if err != nil { + return nil, fmt.Errorf("Unable to parse certificate or key: %w", err) + } + ensureTLSClientConfig(&config) + config.Transport.(*http.Transport).TLSClientConfig.Certificates = []tls.Certificate{cert} + } + } es, err := elasticsearch.NewClient(config) if err != nil { @@ -186,6 +240,15 @@ func NewApiClient(d *schema.ResourceData, meta interface{}) (*ApiClient, error) } } +func ensureTLSClientConfig(config *elasticsearch.Config) { + if config.Transport == nil { + config.Transport = http.DefaultTransport.(*http.Transport) + } + if config.Transport.(*http.Transport).TLSClientConfig == nil { + config.Transport.(*http.Transport).TLSClientConfig = &tls.Config{} + } +} + func (a *ApiClient) GetESClient() *elasticsearch.Client { return a.es } diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 7ffc8ad85..46dd0dbed 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -169,13 +169,41 @@ func AddConnectionSchema(providedSchema map[string]*schema.Schema) { Description: "Path to a custom Certificate Authority certificate", Type: schema.TypeString, Optional: true, - ConflictsWith: []string{"elasticsearch_connection.ca_data"}, + ConflictsWith: []string{"elasticsearch_connection.0.ca_data"}, }, "ca_data": { Description: "PEM-encoded custom Certificate Authority certificate", Type: schema.TypeString, Optional: true, - ConflictsWith: []string{"elasticsearch_connection.ca_file"}, + ConflictsWith: []string{"elasticsearch_connection.0.ca_file"}, + }, + "cert_file": { + Description: "Path to a file containing the PEM encoded certificate for client auth", + Type: schema.TypeString, + Optional: true, + RequiredWith: []string{"elasticsearch_connection.0.key_file"}, + ConflictsWith: []string{"elasticsearch_connection.0.cert_data", "elasticsearch_connection.0.key_data"}, + }, + "key_file": { + Description: "Path to a file containing the PEM encoded private key for client auth", + Type: schema.TypeString, + Optional: true, + RequiredWith: []string{"elasticsearch_connection.0.cert_file"}, + ConflictsWith: []string{"elasticsearch_connection.0.cert_data", "elasticsearch_connection.0.key_data"}, + }, + "cert_data": { + Description: "PEM encoded certificate for client auth", + Type: schema.TypeString, + Optional: true, + RequiredWith: []string{"elasticsearch_connection.0.key_data"}, + ConflictsWith: []string{"elasticsearch_connection.0.cert_file", "elasticsearch_connection.0.key_file"}, + }, + "key_data": { + Description: "PEM encoded private key for client auth", + Type: schema.TypeString, + Optional: true, + RequiredWith: []string{"elasticsearch_connection.0.cert_data"}, + ConflictsWith: []string{"elasticsearch_connection.0.cert_file", "elasticsearch_connection.0.key_file"}, }, }, }, diff --git a/provider/provider.go b/provider/provider.go index 7655402d7..304caaa7e 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -67,13 +67,42 @@ func New(version string) func() *schema.Provider { Description: "Path to a custom Certificate Authority certificate", Type: schema.TypeString, Optional: true, - ConflictsWith: []string{"elasticsearch.ca_data"}, + ConflictsWith: []string{"elasticsearch.0.ca_data"}, }, "ca_data": { Description: "PEM-encoded custom Certificate Authority certificate", Type: schema.TypeString, Optional: true, - ConflictsWith: []string{"elasticsearch.ca_file"}, + ConflictsWith: []string{"elasticsearch.0.ca_file"}, + }, + "cert_file": { + Description: "Path to a file containing the PEM encoded certificate for client auth", + Type: schema.TypeString, + Optional: true, + RequiredWith: []string{"elasticsearch.0.key_file"}, + ConflictsWith: []string{"elasticsearch.0.cert_data", "elasticsearch.0.key_data"}, + }, + "key_file": { + Description: "Path to a file containing the PEM encoded private key for client auth", + Type: schema.TypeString, + Optional: true, + RequiredWith: []string{"elasticsearch.0.cert_file"}, + ConflictsWith: []string{"elasticsearch.0.cert_data", "elasticsearch.0.key_data"}, + }, + "cert_data": { + Description: "PEM encoded certificate for client auth", + Type: schema.TypeString, + Optional: true, + RequiredWith: []string{"elasticsearch.0.key_data"}, + ConflictsWith: []string{"elasticsearch.0.cert_file", "elasticsearch.0.key_file"}, + }, + "key_data": { + Description: "PEM encoded private key for client auth", + Type: schema.TypeString, + Optional: true, + Sensitive: true, + RequiredWith: []string{"elasticsearch.0.cert_data"}, + ConflictsWith: []string{"elasticsearch.0.cert_file", "elasticsearch.0.key_file"}, }, }, },