notif(elasticsearch): switch to address field and validate

This commit is contained in:
CrazyMax
2025-08-10 00:56:03 +02:00
parent f245869582
commit d6f79800e2
6 changed files with 27 additions and 38 deletions

View File

@@ -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
@@ -20,10 +18,8 @@ Send notifications to your Elasticsearch cluster as structured documents.
```
| Name | Default | Description |
| -------------------- | -------------------- | ------------------------------------------------------------------- |
| `scheme`[^1] | `http` | Elasticsearch scheme (`http` or `https`) |
| `host`[^1] | `localhost` | Elasticsearch host |
| `port`[^1] | `9200` | Elasticsearch port |
|----------------------|-------------------------|---------------------------------------------------------------------|
| `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 |
@@ -34,9 +30,7 @@ Send notifications to your Elasticsearch cluster as structured documents.
| `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
{

View File

@@ -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",

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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
}