diff --git a/docs/notif/elasticsearch.md b/docs/notif/elasticsearch.md index 62e8663d..c7884f1a 100644 --- a/docs/notif/elasticsearch.md +++ b/docs/notif/elasticsearch.md @@ -8,9 +8,7 @@ Send notifications to your Elasticsearch cluster as structured documents. ```yaml notif: elasticsearch: - scheme: https - host: localhost - port: 9200 + address: http://localhost:9200 username: elastic password: password client: diun @@ -19,24 +17,20 @@ Send notifications to your Elasticsearch cluster as structured documents. insecureSkipVerify: false ``` -| Name | Default | Description | -| -------------------- | -------------------- | ------------------------------------------------------------------- | -| `scheme`[^1] | `http` | Elasticsearch scheme (`http` or `https`) | -| `host`[^1] | `localhost` | Elasticsearch host | -| `port`[^1] | `9200` | Elasticsearch port | -| `username` | | Elasticsearch username for authentication | -| `usernameFile` | | Use content of secret file as username if `username` is not defined | -| `password` | | Elasticsearch password for authentication | -| `passwordFile` | | Use content of secret file as password if `password` is not defined | -| `client`[^1] | `diun` | Client name to identify the source of notifications | -| `index`[^1] | `diun-notifications` | Elasticsearch index name where notifications will be stored | -| `timeout`[^1] | `10s` | Timeout specifies a time limit for the request to be made | -| `insecureSkipVerify` | `false` | Skip TLS certificate verification | +| Name | Default | Description | +|----------------------|-------------------------|---------------------------------------------------------------------| +| `address`[^1] | `http://localhost:9200` | Elasticsearch base URL | +| `username` | | Elasticsearch username for authentication | +| `usernameFile` | | Use content of secret file as username if `username` is not defined | +| `password` | | Elasticsearch password for authentication | +| `passwordFile` | | Use content of secret file as password if `password` is not defined | +| `client`[^1] | `diun` | Client name to identify the source of notifications | +| `index`[^1] | `diun-notifications` | Elasticsearch index name where notifications will be stored | +| `timeout`[^1] | `10s` | Timeout specifies a time limit for the request to be made | +| `insecureSkipVerify` | `false` | Skip TLS certificate verification | !!! abstract "Environment variables" - * `DIUN_NOTIF_ELASTICSEARCH_SCHEME` - * `DIUN_NOTIF_ELASTICSEARCH_HOST` - * `DIUN_NOTIF_ELASTICSEARCH_PORT` + * `DIUN_NOTIF_ELASTICSEARCH_ADDRESS` * `DIUN_NOTIF_ELASTICSEARCH_USERNAME` * `DIUN_NOTIF_ELASTICSEARCH_USERNAMEFILE` * `DIUN_NOTIF_ELASTICSEARCH_PASSWORD` @@ -48,7 +42,7 @@ Send notifications to your Elasticsearch cluster as structured documents. ## Document Structure -Each notification is stored as a JSON document with following structure: +Each notification is stored as a JSON document with the following structure: ```json { diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 07ee313e..c31a6861 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -95,9 +95,7 @@ func TestLoadFile(t *testing.T) { TemplateBody: model.NotifDefaultTemplateBody, }, Elasticsearch: &model.NotifElasticsearch{ - Scheme: "https", - Host: "localhost", - Port: 9200, + Address: "https://elastic.foo.com", Username: "elastic", Password: "password", Client: "diun", diff --git a/internal/config/fixtures/config.test.yml b/internal/config/fixtures/config.test.yml index 73052b54..bb305594 100644 --- a/internal/config/fixtures/config.test.yml +++ b/internal/config/fixtures/config.test.yml @@ -40,9 +40,7 @@ notif: renderFields: true timeout: 10s elasticsearch: - scheme: https - host: localhost - port: 9200 + address: https://elastic.foo.com username: elastic password: password client: diun diff --git a/internal/config/fixtures/config.validate.yml b/internal/config/fixtures/config.validate.yml index d6738dbe..7a6f3efa 100644 --- a/internal/config/fixtures/config.validate.yml +++ b/internal/config/fixtures/config.validate.yml @@ -29,9 +29,7 @@ notif: renderFields: true timeout: 10s elasticsearch: - scheme: https - host: localhost - port: 9200 + address: https://elastic.foo.com username: elastic password: password client: diun diff --git a/internal/model/notif_elasticsearch.go b/internal/model/notif_elasticsearch.go index 8872330f..3df60779 100644 --- a/internal/model/notif_elasticsearch.go +++ b/internal/model/notif_elasticsearch.go @@ -7,9 +7,7 @@ import ( ) type NotifElasticsearch struct { - Scheme string `yaml:"scheme,omitempty" json:"scheme,omitempty" validate:"required,oneof=http https"` - Host string `yaml:"host,omitempty" json:"host,omitempty" validate:"required"` - Port int `yaml:"port,omitempty" json:"port,omitempty" validate:"required,min=1"` + Address string `yaml:"address,omitempty" json:"address,omitempty" validate:"required"` Username string `yaml:"username,omitempty" json:"username,omitempty" validate:"omitempty"` UsernameFile string `yaml:"usernameFile,omitempty" json:"usernameFile,omitempty" validate:"omitempty,file"` Password string `yaml:"password,omitempty" json:"password,omitempty" validate:"omitempty"` @@ -29,9 +27,7 @@ func (s *NotifElasticsearch) GetDefaults() *NotifElasticsearch { // SetDefaults sets the default values func (s *NotifElasticsearch) SetDefaults() { - s.Scheme = "http" - s.Host = "localhost" - s.Port = 9200 + s.Address = "http://localhost:9200" s.Client = "diun" s.Index = "diun-notifications" s.Timeout = utl.NewDuration(10 * time.Second) diff --git a/internal/notif/elasticsearch/client.go b/internal/notif/elasticsearch/client.go index 929936c5..1b1cff77 100644 --- a/internal/notif/elasticsearch/client.go +++ b/internal/notif/elasticsearch/client.go @@ -5,8 +5,9 @@ import ( "context" "crypto/tls" "encoding/json" - "fmt" "net/http" + "net/url" + "path" "time" "github.com/crazy-max/diun/v4/internal/model" @@ -85,7 +86,11 @@ func (c *Client) Send(entry model.NotifEntry) error { // Build the Elasticsearch indexing URL // This uses the Index API (POST /{index}/_doc) to create a document with an auto-generated _id: // https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-create - url := fmt.Sprintf("%s://%s:%d/%s/_doc", c.cfg.Scheme, c.cfg.Host, c.cfg.Port, c.cfg.Index) + u, err := url.Parse(c.cfg.Address) + if err != nil { + return err + } + u.Path = path.Join(u.Path, c.cfg.Index, "_doc") cancelCtx, cancel := context.WithCancelCause(context.Background()) timeoutCtx, _ := context.WithTimeoutCause(cancelCtx, *c.cfg.Timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent @@ -99,7 +104,7 @@ func (c *Client) Send(entry model.NotifEntry) error { }, } - req, err := http.NewRequestWithContext(timeoutCtx, "POST", url, bytes.NewBuffer(body)) + req, err := http.NewRequestWithContext(timeoutCtx, "POST", u.String(), bytes.NewBuffer(body)) if err != nil { return err }