From 7ed7281a0aac253532174c79e915e992ef20b066 Mon Sep 17 00:00:00 2001 From: SquareShark Date: Sat, 2 Dec 2023 19:24:09 +0000 Subject: [PATCH 1/4] Adding Bearer token support for Elasticsearch authentication --- CHANGELOG.md | 1 + internal/clients/config/base.go | 2 +- internal/clients/config/elasticsearch.go | 23 ++++++++++++++ internal/clients/config/provider.go | 24 +++++++------- internal/schema/connection.go | 40 ++++++++++++++++++++++-- templates/index.md.tmpl | 2 ++ 6 files changed, 78 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15a9c32a2..777183b11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Switch to Terraform [protocol version 6](https://developer.hashicorp.com/terraform/plugin/terraform-plugin-protocol#protocol-version-6) that is compatible with Terraform CLI version 1.0 and later. - Add 'elasticstack_fleet_package' data source ([#469](https://github.com/elastic/terraform-provider-elasticstack/pull/469)) - Add `tags` option to Kibana's SLOs ([#495](https://github.com/elastic/terraform-provider-elasticstack/pull/495)) +- Add support for Authorization header - Bearer Token and ES-Client-Authentication fields added.([#481]()https://github.com/elastic/terraform-provider-elasticstack/pull/481) ### Fixed - Rename fleet package objects to `elasticstack_fleet_integration` and `elasticstack_fleet_integration_policy` ([#476](https://github.com/elastic/terraform-provider-elasticstack/pull/476)) diff --git a/internal/clients/config/base.go b/internal/clients/config/base.go index ced9ee3e8..46f17700f 100644 --- a/internal/clients/config/base.go +++ b/internal/clients/config/base.go @@ -78,7 +78,7 @@ func (b baseConfig) toKibanaConfig() kibanaConfig { func (b baseConfig) toElasticsearchConfig() elasticsearchConfig { return elasticsearchConfig{ - Header: b.Header, + Header: b.Header.Clone(), Username: b.Username, Password: b.Password, APIKey: b.ApiKey, diff --git a/internal/clients/config/elasticsearch.go b/internal/clients/config/elasticsearch.go index 62610bd1f..b2a1a2d69 100644 --- a/internal/clients/config/elasticsearch.go +++ b/internal/clients/config/elasticsearch.go @@ -38,6 +38,14 @@ func newElasticsearchConfigFromSDK(d *schema.ResourceData, base baseConfig, key config.Addresses = addrs } + if bearer_token, ok := esConfig["bearer_token"].(string); ok && bearer_token != "" { + config.Header.Set("Authorization", bearer_token) + } + + if es_client_authentication, ok := esConfig["es_client_authentication"].(string); ok && es_client_authentication != "" { + config.Header.Set("ES-Client-Authentication", es_client_authentication) + } + if insecure, ok := esConfig["insecure"]; ok && insecure.(bool) { tlsClientConfig := config.ensureTLSClientConfig() tlsClientConfig.InsecureSkipVerify = true @@ -132,6 +140,13 @@ func newElasticsearchConfigFromFramework(ctx context.Context, cfg ProviderConfig config.Addresses = endpoints } + if esConfig.BearerToken.ValueString() != "" { + config.Header.Set("Authorization", esConfig.BearerToken.ValueString()) + if esConfig.ESClientAuthentication.ValueString() != "" { + config.Header.Set("ES-Client-authentication", esConfig.ESClientAuthentication.ValueString()) + } + } + if esConfig.Insecure.ValueBool() { tlsClientConfig := config.ensureTLSClientConfig() tlsClientConfig.InsecureSkipVerify = true @@ -213,5 +228,13 @@ func (c elasticsearchConfig) withEnvironmentOverrides() elasticsearchConfig { } } + if bearerToken := os.Getenv("ELASTICSEARCH_BEARER_TOKEN"); bearerToken != "" { + c.Header.Set("Authorization", bearerToken) + } + + if esClientAuthentication := os.Getenv("ELASTICSEARCH_BEARER_TOKEN"); esClientAuthentication != "" { + c.Header.Set("ES-Client-authentication", esClientAuthentication) + } + return c } diff --git a/internal/clients/config/provider.go b/internal/clients/config/provider.go index b089b8493..1fc87aa14 100644 --- a/internal/clients/config/provider.go +++ b/internal/clients/config/provider.go @@ -9,17 +9,19 @@ type ProviderConfiguration struct { } type ElasticsearchConnection struct { - Username types.String `tfsdk:"username"` - Password types.String `tfsdk:"password"` - APIKey types.String `tfsdk:"api_key"` - Endpoints types.List `tfsdk:"endpoints"` - Insecure types.Bool `tfsdk:"insecure"` - CAFile types.String `tfsdk:"ca_file"` - CAData types.String `tfsdk:"ca_data"` - CertFile types.String `tfsdk:"cert_file"` - KeyFile types.String `tfsdk:"key_file"` - CertData types.String `tfsdk:"cert_data"` - KeyData types.String `tfsdk:"key_data"` + Username types.String `tfsdk:"username"` + Password types.String `tfsdk:"password"` + APIKey types.String `tfsdk:"api_key"` + BearerToken types.String `tfsdk:"bearer_token"` + ESClientAuthentication types.String `tfsdk:"es_client_authentication"` + Endpoints types.List `tfsdk:"endpoints"` + Insecure types.Bool `tfsdk:"insecure"` + CAFile types.String `tfsdk:"ca_file"` + CAData types.String `tfsdk:"ca_data"` + CertFile types.String `tfsdk:"cert_file"` + KeyFile types.String `tfsdk:"key_file"` + CertData types.String `tfsdk:"cert_data"` + KeyData types.String `tfsdk:"key_data"` } type KibanaConnection struct { diff --git a/internal/schema/connection.go b/internal/schema/connection.go index 5810aac46..432666058 100644 --- a/internal/schema/connection.go +++ b/internal/schema/connection.go @@ -15,6 +15,8 @@ import ( func GetEsFWConnectionBlock(keyName string) fwschema.Block { usernamePath := path.MatchRelative().AtParent().AtName("username") passwordPath := path.MatchRelative().AtParent().AtName("password") + apiKeyPath := path.MatchRelative().AtParent().AtName("api_key") + bearerTokenPath := path.MatchRelative().AtParent().AtName("bearer_token") caFilePath := path.MatchRelative().AtParent().AtName("ca_file") caDataPath := path.MatchRelative().AtParent().AtName("ca_data") certFilePath := path.MatchRelative().AtParent().AtName("cert_file") @@ -43,7 +45,24 @@ func GetEsFWConnectionBlock(keyName string) fwschema.Block { Optional: true, Sensitive: true, Validators: []validator.String{ - stringvalidator.ConflictsWith(usernamePath, passwordPath), + stringvalidator.ConflictsWith(usernamePath, passwordPath, bearerTokenPath), + }, + }, + "bearer_token": fwschema.StringAttribute{ + MarkdownDescription: "Bearer Token to use for authentication to Elasticsearch", + Optional: true, + Sensitive: true, + Validators: []validator.String{ + stringvalidator.ConflictsWith(usernamePath, passwordPath, apiKeyPath), + }, + }, + "es_client_authentication": fwschema.StringAttribute{ + MarkdownDescription: "ES Client Authentication field to be used with the bearer token", + Optional: true, + Sensitive: true, + Validators: []validator.String{ + stringvalidator.ConflictsWith(usernamePath, passwordPath, apiKeyPath), + stringvalidator.AlsoRequires(bearerTokenPath), }, }, "endpoints": fwschema.ListAttribute{ @@ -209,6 +228,8 @@ func GetFleetFWConnectionBlock() fwschema.Block { func GetEsConnectionSchema(keyName string, isProviderConfiguration bool) *schema.Schema { usernamePath := makePathRef(keyName, "username") passwordPath := makePathRef(keyName, "password") + apiKeyPath := makePathRef(keyName, "api_key") + bearerTokenPath := makePathRef(keyName, "bearer_token") caFilePath := makePathRef(keyName, "ca_file") caDataPath := makePathRef(keyName, "ca_data") certFilePath := makePathRef(keyName, "cert_file") @@ -258,7 +279,22 @@ func GetEsConnectionSchema(keyName string, isProviderConfiguration bool) *schema Optional: true, Sensitive: true, DefaultFunc: withEnvDefault("ELASTICSEARCH_API_KEY", nil), - ConflictsWith: []string{usernamePath, passwordPath}, + ConflictsWith: []string{usernamePath, passwordPath, bearerTokenPath}, + }, + "bearer_token": { + Description: "Bearer Token to use for authentication to Elasticsearch", + Type: schema.TypeString, + Optional: true, + Sensitive: true, + DefaultFunc: withEnvDefault("ELASTICSEARCH_BEARER_TOKEN", nil), + ConflictsWith: []string{usernamePath, passwordPath, apiKeyPath}, + }, + "es_client_authentication": { + Description: "ES Client Authentication field to be used with the bearer token", + Type: schema.TypeString, + Optional: true, + Sensitive: true, + DefaultFunc: withEnvDefault("ELASTICSEARCH_ES_CLIENT_AUTHENTICATION", nil), }, "endpoints": { Description: "A list of endpoints where the terraform provider will point to, this must include the http(s) schema and port number.", diff --git a/templates/index.md.tmpl b/templates/index.md.tmpl index 54a5ada79..6bcff8abd 100644 --- a/templates/index.md.tmpl +++ b/templates/index.md.tmpl @@ -54,6 +54,8 @@ For Elasticsearch resources, you can use the following variables: - `ELASTICSEARCH_PASSWORD` - The password to use for Elasticsearch authentication - `ELASTICSEARCH_ENDPOINTS` - A comma separated list of Elasticsearch hosts to connect to - `ELASTICSEARCH_API_KEY` - An Elasticsearch API key to use instead of `ELASTICSEARCH_USERNAME` and `ELASTICSEARCH_PASSWORD` +- `ELASTICSEARCH_BEARER_TOKEN` - A bearer token to use for Elasticsearch authorization header. +- `ELASTICSEARCH_ES_CLIENT_AUTHENTICATION` - The shared secret for the Elasticsearch authorization header. Kibana resources will re-use any Elasticsearch credentials specified, these may be overridden with the following variables: - `KIBANA_USERNAME` - The username to use for Kibana authentication From f5f77bc940b1c58361e9be2fd596450e52ad548b Mon Sep 17 00:00:00 2001 From: SquareShark Date: Sat, 2 Dec 2023 19:31:01 +0000 Subject: [PATCH 2/4] Updating CHANGELOG for the merge request link --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 777183b11..48021b120 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ - Switch to Terraform [protocol version 6](https://developer.hashicorp.com/terraform/plugin/terraform-plugin-protocol#protocol-version-6) that is compatible with Terraform CLI version 1.0 and later. - Add 'elasticstack_fleet_package' data source ([#469](https://github.com/elastic/terraform-provider-elasticstack/pull/469)) - Add `tags` option to Kibana's SLOs ([#495](https://github.com/elastic/terraform-provider-elasticstack/pull/495)) -- Add support for Authorization header - Bearer Token and ES-Client-Authentication fields added.([#481]()https://github.com/elastic/terraform-provider-elasticstack/pull/481) +- Add support for Authorization header - Bearer Token and ES-Client-Authentication fields added.([#500]()https://github.com/elastic/terraform-provider-elasticstack/pull/500) ### Fixed - Rename fleet package objects to `elasticstack_fleet_integration` and `elasticstack_fleet_integration_policy` ([#476](https://github.com/elastic/terraform-provider-elasticstack/pull/476)) From df9713b1010aa4b1a5c52beb302980e80df7ee76 Mon Sep 17 00:00:00 2001 From: SquareShark Date: Sat, 2 Dec 2023 19:36:11 +0000 Subject: [PATCH 3/4] Generating Docs as Lint reccomends --- docs/data-sources/elasticsearch_security_role.md | 2 ++ docs/data-sources/elasticsearch_security_role_mapping.md | 2 ++ docs/data-sources/elasticsearch_security_user.md | 2 ++ docs/data-sources/elasticsearch_snapshot_repository.md | 2 ++ docs/index.md | 4 ++++ docs/resources/elasticsearch_cluster_settings.md | 2 ++ docs/resources/elasticsearch_component_template.md | 2 ++ docs/resources/elasticsearch_data_stream.md | 2 ++ docs/resources/elasticsearch_enrich_policy.md | 2 ++ docs/resources/elasticsearch_index.md | 2 ++ docs/resources/elasticsearch_index_lifecycle.md | 2 ++ docs/resources/elasticsearch_index_template.md | 2 ++ docs/resources/elasticsearch_ingest_pipeline.md | 2 ++ docs/resources/elasticsearch_logstash_pipeline.md | 2 ++ docs/resources/elasticsearch_script.md | 2 ++ docs/resources/elasticsearch_security_api_key.md | 2 ++ docs/resources/elasticsearch_security_role.md | 2 ++ docs/resources/elasticsearch_security_role_mapping.md | 2 ++ docs/resources/elasticsearch_security_system_user.md | 2 ++ docs/resources/elasticsearch_security_user.md | 2 ++ docs/resources/elasticsearch_snapshot_lifecycle.md | 2 ++ docs/resources/elasticsearch_snapshot_repository.md | 2 ++ 22 files changed, 46 insertions(+) diff --git a/docs/data-sources/elasticsearch_security_role.md b/docs/data-sources/elasticsearch_security_role.md index ab82db146..8e39174b8 100644 --- a/docs/data-sources/elasticsearch_security_role.md +++ b/docs/data-sources/elasticsearch_security_role.md @@ -53,11 +53,13 @@ output "role" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/data-sources/elasticsearch_security_role_mapping.md b/docs/data-sources/elasticsearch_security_role_mapping.md index e095abebd..a18c335ac 100644 --- a/docs/data-sources/elasticsearch_security_role_mapping.md +++ b/docs/data-sources/elasticsearch_security_role_mapping.md @@ -52,11 +52,13 @@ output "user" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/data-sources/elasticsearch_security_user.md b/docs/data-sources/elasticsearch_security_user.md index de9476bf1..3f2cc7b10 100644 --- a/docs/data-sources/elasticsearch_security_user.md +++ b/docs/data-sources/elasticsearch_security_user.md @@ -52,11 +52,13 @@ output "user" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/data-sources/elasticsearch_snapshot_repository.md b/docs/data-sources/elasticsearch_snapshot_repository.md index 487174580..bf2e4a3a8 100644 --- a/docs/data-sources/elasticsearch_snapshot_repository.md +++ b/docs/data-sources/elasticsearch_snapshot_repository.md @@ -80,11 +80,13 @@ output "repo_url" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/index.md b/docs/index.md index 87c2a1a75..1c0e8c1c1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -87,6 +87,8 @@ For Elasticsearch resources, you can use the following variables: - `ELASTICSEARCH_PASSWORD` - The password to use for Elasticsearch authentication - `ELASTICSEARCH_ENDPOINTS` - A comma separated list of Elasticsearch hosts to connect to - `ELASTICSEARCH_API_KEY` - An Elasticsearch API key to use instead of `ELASTICSEARCH_USERNAME` and `ELASTICSEARCH_PASSWORD` +- `ELASTICSEARCH_BEARER_TOKEN` - A bearer token to use for Elasticsearch authorization header. +- `ELASTICSEARCH_ES_CLIENT_AUTHENTICATION` - The shared secret for the Elasticsearch authorization header. Kibana resources will re-use any Elasticsearch credentials specified, these may be overridden with the following variables: - `KIBANA_USERNAME` - The username to use for Kibana authentication @@ -150,11 +152,13 @@ provider "elasticstack" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_cluster_settings.md b/docs/resources/elasticsearch_cluster_settings.md index d172e3816..36a95568f 100644 --- a/docs/resources/elasticsearch_cluster_settings.md +++ b/docs/resources/elasticsearch_cluster_settings.md @@ -65,11 +65,13 @@ resource "elasticstack_elasticsearch_cluster_settings" "my_cluster_settings" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_component_template.md b/docs/resources/elasticsearch_component_template.md index c064592aa..5908917ba 100644 --- a/docs/resources/elasticsearch_component_template.md +++ b/docs/resources/elasticsearch_component_template.md @@ -90,11 +90,13 @@ Optional: Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_data_stream.md b/docs/resources/elasticsearch_data_stream.md index 1c5c1390d..a52854667 100644 --- a/docs/resources/elasticsearch_data_stream.md +++ b/docs/resources/elasticsearch_data_stream.md @@ -96,11 +96,13 @@ resource "elasticstack_elasticsearch_data_stream" "my_data_stream" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_enrich_policy.md b/docs/resources/elasticsearch_enrich_policy.md index 097a30e3a..d7723afc0 100644 --- a/docs/resources/elasticsearch_enrich_policy.md +++ b/docs/resources/elasticsearch_enrich_policy.md @@ -72,11 +72,13 @@ resource "elasticstack_elasticsearch_enrich_policy" "policy1" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_index.md b/docs/resources/elasticsearch_index.md index e53611314..5d1e3a08a 100644 --- a/docs/resources/elasticsearch_index.md +++ b/docs/resources/elasticsearch_index.md @@ -160,11 +160,13 @@ Optional: Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_index_lifecycle.md b/docs/resources/elasticsearch_index_lifecycle.md index 799878f91..3b8e2ccc6 100644 --- a/docs/resources/elasticsearch_index_lifecycle.md +++ b/docs/resources/elasticsearch_index_lifecycle.md @@ -186,11 +186,13 @@ Required: Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_index_template.md b/docs/resources/elasticsearch_index_template.md index 5bfbd097f..4eae1398e 100644 --- a/docs/resources/elasticsearch_index_template.md +++ b/docs/resources/elasticsearch_index_template.md @@ -82,11 +82,13 @@ Optional: Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_ingest_pipeline.md b/docs/resources/elasticsearch_ingest_pipeline.md index 525ae686a..fb352ee47 100644 --- a/docs/resources/elasticsearch_ingest_pipeline.md +++ b/docs/resources/elasticsearch_ingest_pipeline.md @@ -95,11 +95,13 @@ resource "elasticstack_elasticsearch_ingest_pipeline" "ingest" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_logstash_pipeline.md b/docs/resources/elasticsearch_logstash_pipeline.md index 9b280209c..a84266ea2 100644 --- a/docs/resources/elasticsearch_logstash_pipeline.md +++ b/docs/resources/elasticsearch_logstash_pipeline.md @@ -94,11 +94,13 @@ output "pipeline" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_script.md b/docs/resources/elasticsearch_script.md index 37a6a92b0..079f6211e 100644 --- a/docs/resources/elasticsearch_script.md +++ b/docs/resources/elasticsearch_script.md @@ -67,11 +67,13 @@ resource "elasticstack_elasticsearch_script" "my_search_template" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_security_api_key.md b/docs/resources/elasticsearch_security_api_key.md index 746a69073..9d9c9b90e 100644 --- a/docs/resources/elasticsearch_security_api_key.md +++ b/docs/resources/elasticsearch_security_api_key.md @@ -74,11 +74,13 @@ output "api_key" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_security_role.md b/docs/resources/elasticsearch_security_role.md index 4736af57c..646548536 100644 --- a/docs/resources/elasticsearch_security_role.md +++ b/docs/resources/elasticsearch_security_role.md @@ -81,11 +81,13 @@ Required: Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_security_role_mapping.md b/docs/resources/elasticsearch_security_role_mapping.md index 06644a20d..718bc4816 100644 --- a/docs/resources/elasticsearch_security_role_mapping.md +++ b/docs/resources/elasticsearch_security_role_mapping.md @@ -62,11 +62,13 @@ output "role" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_security_system_user.md b/docs/resources/elasticsearch_security_system_user.md index 0186e1427..9e67af1fc 100644 --- a/docs/resources/elasticsearch_security_system_user.md +++ b/docs/resources/elasticsearch_security_system_user.md @@ -56,11 +56,13 @@ resource "elasticstack_elasticsearch_security_system_user" "kibana_system" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_security_user.md b/docs/resources/elasticsearch_security_user.md index 152350be7..a6db7f6b2 100644 --- a/docs/resources/elasticsearch_security_user.md +++ b/docs/resources/elasticsearch_security_user.md @@ -81,11 +81,13 @@ resource "elasticstack_elasticsearch_security_user" "dev" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_snapshot_lifecycle.md b/docs/resources/elasticsearch_snapshot_lifecycle.md index 88dfe6826..2b1d8eeef 100644 --- a/docs/resources/elasticsearch_snapshot_lifecycle.md +++ b/docs/resources/elasticsearch_snapshot_lifecycle.md @@ -80,11 +80,13 @@ resource "elasticstack_elasticsearch_snapshot_lifecycle" "slm_policy" { Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 diff --git a/docs/resources/elasticsearch_snapshot_repository.md b/docs/resources/elasticsearch_snapshot_repository.md index 453f6c6ba..385d4aa47 100644 --- a/docs/resources/elasticsearch_snapshot_repository.md +++ b/docs/resources/elasticsearch_snapshot_repository.md @@ -83,11 +83,13 @@ Optional: Optional: - `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `bearer_token` (String, Sensitive) Bearer Token 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 where the terraform provider will point to, this must include the http(s) schema and port number. +- `es_client_authentication` (String, Sensitive) ES Client Authentication field to be used with the bearer token - `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 From e2f58b0a412f953893bebbec8366b0f2f33597ec Mon Sep 17 00:00:00 2001 From: Toby Brain Date: Wed, 6 Dec 2023 14:00:36 +1100 Subject: [PATCH 4/4] Code review --- Makefile | 21 ++++++ internal/acctest/acctest.go | 6 +- internal/clients/config/base.go | 11 ++-- internal/clients/config/elasticsearch.go | 65 ++++++++++++------- internal/clients/config/elasticsearch_test.go | 12 ++-- internal/clients/config/env.go | 9 ++- internal/clients/config/framework.go | 3 +- internal/clients/config/sdk.go | 3 +- provider/provider_test.go | 6 ++ 9 files changed, 95 insertions(+), 41 deletions(-) diff --git a/Makefile b/Makefile index 0fad2a50c..2304b755f 100644 --- a/Makefile +++ b/Makefile @@ -83,6 +83,22 @@ docker-testacc: docker-elasticsearch docker-kibana ## Run acceptance tests in th -v "$(SOURCE_LOCATION):/provider" \ golang:$(GOVERSION) make testacc TESTARGS="$(TESTARGS)" +# To run specific test (e.g. TestAccResourceActionConnector) execute `make docker-testacc TESTARGS='-run ^TestAccResourceActionConnector$$'` +# To enable tracing (or debugging), execute `make docker-testacc TF_LOG=TRACE` +.PHONY: docker-testacc-with-token +docker-testacc-with-token: + @ docker run --rm \ + -e ELASTICSEARCH_ENDPOINTS="$(ELASTICSEARCH_ENDPOINTS)" \ + -e KIBANA_ENDPOINT="$(KIBANA_ENDPOINT)" \ + -e ELASTICSEARCH_BEARER_TOKEN="$(ELASTICSEARCH_BEARER_TOKEN)" \ + -e KIBANA_USERNAME="$(ELASTICSEARCH_USERNAME)" \ + -e KIBANA_PASSWORD="$(ELASTICSEARCH_PASSWORD)" \ + -e TF_LOG="$(TF_LOG)" \ + --network $(ELASTICSEARCH_NETWORK) \ + -w "/provider" \ + -v "$(SOURCE_LOCATION):/provider" \ + golang:$(GOVERSION) make testacc TESTARGS="$(TESTARGS)" + .PHONY: docker-elasticsearch docker-elasticsearch: docker-network ## Start Elasticsearch single node cluster in docker container @ docker rm -f $(ELASTICSEARCH_NAME) &> /dev/null || true @@ -93,6 +109,7 @@ docker-elasticsearch: docker-network ## Start Elasticsearch single node cluster -e "discovery.type=single-node" \ -e "xpack.security.enabled=true" \ -e "xpack.security.authc.api_key.enabled=true" \ + -e "xpack.security.authc.token.enabled=true" \ -e "xpack.watcher.enabled=true" \ -e "xpack.license.self_generated.type=trial" \ -e "repositories.url.allowed_urls=https://example.com/*" \ @@ -134,6 +151,10 @@ set-kibana-password: ## Sets the ES KIBANA_SYSTEM_USERNAME's password to KIBANA_ create-es-api-key: ## Creates and outputs a new API Key. This expects Elasticsearch to be available at localhost:9200 @ $(call retry, 10, curl -X POST -u $(ELASTICSEARCH_USERNAME):$(ELASTICSEARCH_PASSWORD) -H "Content-Type: application/json" http://localhost:9200/_security/api_key -d "{\"name\":\"$(KIBANA_API_KEY_NAME)\"}") +.PHONY: create-es-bearer-token +create-es-bearer-token: + @ $(call retry, 10, curl -X POST -u $(ELASTICSEARCH_USERNAME):$(ELASTICSEARCH_PASSWORD) -H "Content-Type: application/json" http://localhost:9200/_security/oauth2/token -d "{\"grant_type\": \"client_credentials\"}") + .PHONY: docker-clean docker-clean: ## Try to remove provisioned nodes and assigned network @ docker rm -f $(ELASTICSEARCH_NAME) $(KIBANA_NAME) || true diff --git a/internal/acctest/acctest.go b/internal/acctest/acctest.go index f1827bd4f..d1fd4808c 100644 --- a/internal/acctest/acctest.go +++ b/internal/acctest/acctest.go @@ -29,6 +29,8 @@ func PreCheck(t *testing.T) { _, kibanaEndpointOk := os.LookupEnv("KIBANA_ENDPOINT") _, userOk := os.LookupEnv("ELASTICSEARCH_USERNAME") _, passOk := os.LookupEnv("ELASTICSEARCH_PASSWORD") + _, kbUserOk := os.LookupEnv("KIBANA_USERNAME") + _, kbPassOk := os.LookupEnv("KIBANA_PASSWORD") if !elasticsearchEndpointsOk { t.Fatal("ELASTICSEARCH_ENDPOINTS must be set for acceptance tests to run") @@ -39,8 +41,8 @@ func PreCheck(t *testing.T) { } // Technically ES tests can use the API Key, however username/password is required for Kibana tests. - usernamePasswordOk := userOk && passOk + usernamePasswordOk := (userOk && passOk) || (kbUserOk && kbPassOk) if !usernamePasswordOk { - t.Fatal("ELASTICSEARCH_USERNAME and ELASTICSEARCH_PASSWORD must be set for acceptance tests to run") + t.Fatal("ELASTICSEARCH_USERNAME and ELASTICSEARCH_PASSWORD or KIBANA_USERNAME and KIBANA_PASSWORD must be set for acceptance tests to run") } } diff --git a/internal/clients/config/base.go b/internal/clients/config/base.go index 46f17700f..89f42a56b 100644 --- a/internal/clients/config/base.go +++ b/internal/clients/config/base.go @@ -5,6 +5,7 @@ import ( "net/http" "os" + "github.com/elastic/go-elasticsearch/v7" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -78,10 +79,12 @@ func (b baseConfig) toKibanaConfig() kibanaConfig { func (b baseConfig) toElasticsearchConfig() elasticsearchConfig { return elasticsearchConfig{ - Header: b.Header.Clone(), - Username: b.Username, - Password: b.Password, - APIKey: b.ApiKey, + config: elasticsearch.Config{ + Header: b.Header.Clone(), + Username: b.Username, + Password: b.Password, + APIKey: b.ApiKey, + }, } } diff --git a/internal/clients/config/elasticsearch.go b/internal/clients/config/elasticsearch.go index b2a1a2d69..6e68f1222 100644 --- a/internal/clients/config/elasticsearch.go +++ b/internal/clients/config/elasticsearch.go @@ -3,6 +3,7 @@ package config import ( "context" "crypto/tls" + "fmt" "net/http" "os" "strconv" @@ -15,7 +16,11 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -type elasticsearchConfig elasticsearch.Config +type elasticsearchConfig struct { + config elasticsearch.Config + bearerToken string + esClientAuthentication string +} func newElasticsearchConfigFromSDK(d *schema.ResourceData, base baseConfig, key string, useEnvAsDefault bool) (*elasticsearchConfig, sdkdiags.Diagnostics) { esConn, ok := d.GetOk(key) @@ -35,15 +40,15 @@ func newElasticsearchConfigFromSDK(d *schema.ResourceData, base baseConfig, key for _, e := range endpoints.([]interface{}) { addrs = append(addrs, e.(string)) } - config.Addresses = addrs + config.config.Addresses = addrs } if bearer_token, ok := esConfig["bearer_token"].(string); ok && bearer_token != "" { - config.Header.Set("Authorization", bearer_token) + config.bearerToken = bearer_token } if es_client_authentication, ok := esConfig["es_client_authentication"].(string); ok && es_client_authentication != "" { - config.Header.Set("ES-Client-Authentication", es_client_authentication) + config.esClientAuthentication = es_client_authentication } if insecure, ok := esConfig["insecure"]; ok && insecure.(bool) { @@ -61,10 +66,10 @@ func newElasticsearchConfigFromSDK(d *schema.ResourceData, base baseConfig, key }) return nil, diags } - config.CACert = caCert + config.config.CACert = caCert } if caData, ok := esConfig["ca_data"]; ok && caData.(string) != "" { - config.CACert = []byte(caData.(string)) + config.config.CACert = []byte(caData.(string)) } if certFile, ok := esConfig["cert_file"]; ok && certFile.(string) != "" { @@ -114,8 +119,8 @@ func newElasticsearchConfigFromSDK(d *schema.ResourceData, base baseConfig, key } if logging.IsDebugOrHigher() { - config.EnableDebugLogger = true - config.Logger = &debugLogger{Name: "elasticsearch"} + config.config.EnableDebugLogger = true + config.config.Logger = &debugLogger{Name: "elasticsearch"} } config = config.withEnvironmentOverrides() @@ -137,13 +142,13 @@ func newElasticsearchConfigFromFramework(ctx context.Context, cfg ProviderConfig } if len(endpoints) > 0 { - config.Addresses = endpoints + config.config.Addresses = endpoints } if esConfig.BearerToken.ValueString() != "" { - config.Header.Set("Authorization", esConfig.BearerToken.ValueString()) + config.bearerToken = esConfig.BearerToken.ValueString() if esConfig.ESClientAuthentication.ValueString() != "" { - config.Header.Set("ES-Client-authentication", esConfig.ESClientAuthentication.ValueString()) + config.esClientAuthentication = esConfig.ESClientAuthentication.ValueString() } } @@ -158,10 +163,10 @@ func newElasticsearchConfigFromFramework(ctx context.Context, cfg ProviderConfig diags.Append(fwdiags.NewErrorDiagnostic("Unable to read CA file", err.Error())) return nil, diags } - config.CACert = caCert + config.config.CACert = caCert } if caData := esConfig.CAData.ValueString(); caData != "" { - config.CACert = []byte(caData) + config.config.CACert = []byte(caData) } if certFile := esConfig.CertFile.ValueString(); certFile != "" { @@ -194,8 +199,8 @@ func newElasticsearchConfigFromFramework(ctx context.Context, cfg ProviderConfig } if logging.IsDebugOrHigher() { - config.EnableDebugLogger = true - config.Logger = &debugLogger{Name: "elasticsearch"} + config.config.EnableDebugLogger = true + config.config.Logger = &debugLogger{Name: "elasticsearch"} } config = config.withEnvironmentOverrides() @@ -203,13 +208,13 @@ func newElasticsearchConfigFromFramework(ctx context.Context, cfg ProviderConfig } func (c *elasticsearchConfig) ensureTLSClientConfig() *tls.Config { - if c.Transport == nil { - c.Transport = http.DefaultTransport.(*http.Transport) + if c.config.Transport == nil { + c.config.Transport = http.DefaultTransport.(*http.Transport) } - if c.Transport.(*http.Transport).TLSClientConfig == nil { - c.Transport.(*http.Transport).TLSClientConfig = &tls.Config{} + if c.config.Transport.(*http.Transport).TLSClientConfig == nil { + c.config.Transport.(*http.Transport).TLSClientConfig = &tls.Config{} } - return c.Transport.(*http.Transport).TLSClientConfig + return c.config.Transport.(*http.Transport).TLSClientConfig } func (c elasticsearchConfig) withEnvironmentOverrides() elasticsearchConfig { @@ -218,7 +223,7 @@ func (c elasticsearchConfig) withEnvironmentOverrides() elasticsearchConfig { for _, e := range strings.Split(endpointsCSV, ",") { endpoints = append(endpoints, strings.TrimSpace(e)) } - c.Addresses = endpoints + c.config.Addresses = endpoints } if insecure, ok := os.LookupEnv("ELASTICSEARCH_INSECURE"); ok { @@ -229,12 +234,24 @@ func (c elasticsearchConfig) withEnvironmentOverrides() elasticsearchConfig { } if bearerToken := os.Getenv("ELASTICSEARCH_BEARER_TOKEN"); bearerToken != "" { - c.Header.Set("Authorization", bearerToken) + c.bearerToken = bearerToken } - if esClientAuthentication := os.Getenv("ELASTICSEARCH_BEARER_TOKEN"); esClientAuthentication != "" { - c.Header.Set("ES-Client-authentication", esClientAuthentication) + if esClientAuthentication := os.Getenv("ELASTICSEARCH_ES_CLIENT_AUTHENTICATION"); esClientAuthentication != "" { + c.esClientAuthentication = esClientAuthentication } return c } + +func (c elasticsearchConfig) toElasticsearchConfiguration() elasticsearch.Config { + if c.bearerToken != "" { + c.config.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.bearerToken)) + } + + if c.esClientAuthentication != "" { + c.config.Header.Set("ES-Client-Authentication", fmt.Sprintf("SharedSecret %s", c.esClientAuthentication)) + } + + return c.config +} diff --git a/internal/clients/config/elasticsearch_test.go b/internal/clients/config/elasticsearch_test.go index cd93bfd1a..bcb2d2467 100644 --- a/internal/clients/config/elasticsearch_test.go +++ b/internal/clients/config/elasticsearch_test.go @@ -43,7 +43,7 @@ func Test_newElasticsearchConfigFromSDK(t *testing.T) { } config := base.toElasticsearchConfig() - config.Addresses = []string{"localhost", "example.com"} + config.config.Addresses = []string{"localhost", "example.com"} tlsConfig := config.ensureTLSClientConfig() tlsConfig.InsecureSkipVerify = true @@ -70,7 +70,7 @@ func Test_newElasticsearchConfigFromSDK(t *testing.T) { } config := base.toElasticsearchConfig() - config.Addresses = []string{"127.0.0.1", "example.com/elastic"} + config.config.Addresses = []string{"127.0.0.1", "example.com/elastic"} tlsConfig := config.ensureTLSClientConfig() tlsConfig.InsecureSkipVerify = false @@ -98,6 +98,8 @@ func Test_newElasticsearchConfigFromSDK(t *testing.T) { t.Run(tt.name, func(t *testing.T) { os.Unsetenv("ELASTICSEARCH_ENDPOINTS") os.Unsetenv("ELASTICSEARCH_INSECURE") + os.Unsetenv("ELASTICSEARCH_BEARER_TOKEN") + os.Unsetenv("ELASTICSEARCH_ES_CLIENT_AUTHENTICATION") key := "elasticsearch" args := tt.args(key) @@ -146,7 +148,7 @@ func Test_newElasticsearchConfigFromFramework(t *testing.T) { } config := base.toElasticsearchConfig() - config.Addresses = []string{"localhost", "example.com"} + config.config.Addresses = []string{"localhost", "example.com"} tlsConfig := config.ensureTLSClientConfig() tlsConfig.InsecureSkipVerify = true @@ -179,7 +181,7 @@ func Test_newElasticsearchConfigFromFramework(t *testing.T) { } config := base.toElasticsearchConfig() - config.Addresses = []string{"127.0.0.1", "example.com/elastic"} + config.config.Addresses = []string{"127.0.0.1", "example.com/elastic"} tlsConfig := config.ensureTLSClientConfig() tlsConfig.InsecureSkipVerify = false @@ -213,6 +215,8 @@ func Test_newElasticsearchConfigFromFramework(t *testing.T) { t.Run(tt.name, func(t *testing.T) { os.Unsetenv("ELASTICSEARCH_ENDPOINTS") os.Unsetenv("ELASTICSEARCH_INSECURE") + os.Unsetenv("ELASTICSEARCH_BEARER_TOKEN") + os.Unsetenv("ELASTICSEARCH_ES_CLIENT_AUTHENTICATION") args := tt.args() diff --git a/internal/clients/config/env.go b/internal/clients/config/env.go index a01845350..7c4844414 100644 --- a/internal/clients/config/env.go +++ b/internal/clients/config/env.go @@ -1,15 +1,18 @@ package config import ( + "net/http" + "github.com/disaster37/go-kibana-rest/v8" - "github.com/elastic/go-elasticsearch/v7" "github.com/elastic/terraform-provider-elasticstack/internal/clients/fleet" "github.com/elastic/terraform-provider-elasticstack/internal/utils" ) func NewFromEnv(version string) Client { + ua := buildUserAgent(version) base := baseConfig{ - UserAgent: buildUserAgent(version), + UserAgent: ua, + Header: http.Header{"User-Agent": []string{ua}}, }.withEnvironmentOverrides() client := Client{ @@ -17,7 +20,7 @@ func NewFromEnv(version string) Client { } esCfg := base.toElasticsearchConfig().withEnvironmentOverrides() - client.Elasticsearch = utils.Pointer(elasticsearch.Config(esCfg)) + client.Elasticsearch = utils.Pointer(esCfg.toElasticsearchConfiguration()) kibanaCfg := base.toKibanaConfig().withEnvironmentOverrides() client.Kibana = (*kibana.Config)(&kibanaCfg) diff --git a/internal/clients/config/framework.go b/internal/clients/config/framework.go index 87540e97f..45fffdc63 100644 --- a/internal/clients/config/framework.go +++ b/internal/clients/config/framework.go @@ -4,7 +4,6 @@ import ( "context" "github.com/disaster37/go-kibana-rest/v8" - "github.com/elastic/go-elasticsearch/v7" "github.com/elastic/terraform-provider-elasticstack/internal/clients/fleet" "github.com/elastic/terraform-provider-elasticstack/internal/utils" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -22,7 +21,7 @@ func NewFromFramework(ctx context.Context, cfg ProviderConfiguration, version st } if esCfg != nil { - client.Elasticsearch = utils.Pointer(elasticsearch.Config(*esCfg)) + client.Elasticsearch = utils.Pointer(esCfg.toElasticsearchConfiguration()) } kibanaCfg, diags := newKibanaConfigFromFramework(ctx, cfg, base) diff --git a/internal/clients/config/sdk.go b/internal/clients/config/sdk.go index da7cf84e2..f1b879cdc 100644 --- a/internal/clients/config/sdk.go +++ b/internal/clients/config/sdk.go @@ -2,7 +2,6 @@ package config import ( "github.com/disaster37/go-kibana-rest/v8" - "github.com/elastic/go-elasticsearch/v7" "github.com/elastic/terraform-provider-elasticstack/internal/clients/fleet" "github.com/elastic/terraform-provider-elasticstack/internal/utils" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" @@ -39,7 +38,7 @@ func newFromSDK(d *schema.ResourceData, version, esConfigKey string) (Client, di } if esCfg != nil { - client.Elasticsearch = utils.Pointer(elasticsearch.Config(*esCfg)) + client.Elasticsearch = utils.Pointer(esCfg.toElasticsearchConfiguration()) } kibanaCfg, diags := newKibanaConfigFromSDK(d, base) diff --git a/provider/provider_test.go b/provider/provider_test.go index fdb7a9313..7eaaa2c03 100644 --- a/provider/provider_test.go +++ b/provider/provider_test.go @@ -79,6 +79,9 @@ func TestKibanaConfiguration(t *testing.T) { ProtoV6ProviderFactories: acctest.Providers, Steps: []resource.TestStep{ { + SkipFunc: func() (bool, error) { + return envConfig.Kibana.Username == "", nil + }, Config: testKibanaConfiguration(envConfig), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("elasticstack_kibana_space.acc_test", "name"), @@ -104,6 +107,9 @@ func TestKibanaConfiguration(t *testing.T) { ProtoV6ProviderFactories: acctest.Providers, Steps: []resource.TestStep{ { + SkipFunc: func() (bool, error) { + return os.Getenv("KIBANA_API_KEY") == "", nil + }, Config: testKibanaApiKeyConfiguration(envConfig), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("elasticstack_kibana_space.acc_test", "name"),