mirror of
https://github.com/grafana/grafana.git
synced 2025-02-10 23:55:47 -06:00
Alerting: support basic auth for the state history loki client (#61696)
This commit is contained in:
parent
7f4b2fcb9c
commit
44b11d3228
@ -391,7 +391,12 @@ func configureHistorianBackend(cfg setting.UnifiedAlertingStateHistorySettings,
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse remote loki URL: %w", err)
|
||||
}
|
||||
backend := historian.NewRemoteLokiBackend(baseURL)
|
||||
backend := historian.NewRemoteLokiBackend(historian.LokiConfig{
|
||||
Url: baseURL,
|
||||
BasicAuthUser: cfg.LokiBasicAuthUsername,
|
||||
BasicAuthPassword: cfg.LokiBasicAuthPassword,
|
||||
TenantID: cfg.LokiTenantID,
|
||||
})
|
||||
if err := backend.TestConnection(); err != nil {
|
||||
return nil, fmt.Errorf("failed to ping the remote loki historian: %w", err)
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package historian
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
@ -18,10 +17,10 @@ type RemoteLokiBackend struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func NewRemoteLokiBackend(url *url.URL) *RemoteLokiBackend {
|
||||
func NewRemoteLokiBackend(cfg LokiConfig) *RemoteLokiBackend {
|
||||
logger := log.New("ngalert.state.historian", "backend", "loki")
|
||||
return &RemoteLokiBackend{
|
||||
client: newLokiClient(url, logger),
|
||||
client: newLokiClient(cfg, logger),
|
||||
log: logger,
|
||||
}
|
||||
}
|
||||
|
@ -11,25 +11,41 @@ import (
|
||||
|
||||
const defaultClientTimeout = 30 * time.Second
|
||||
|
||||
type LokiConfig struct {
|
||||
Url *url.URL
|
||||
BasicAuthUser string
|
||||
BasicAuthPassword string
|
||||
TenantID string
|
||||
}
|
||||
|
||||
type httpLokiClient struct {
|
||||
client http.Client
|
||||
url *url.URL
|
||||
cfg LokiConfig
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func newLokiClient(u *url.URL, logger log.Logger) *httpLokiClient {
|
||||
func newLokiClient(cfg LokiConfig, logger log.Logger) *httpLokiClient {
|
||||
return &httpLokiClient{
|
||||
client: http.Client{
|
||||
Timeout: defaultClientTimeout,
|
||||
},
|
||||
url: u,
|
||||
cfg: cfg,
|
||||
log: logger.New("protocol", "http"),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *httpLokiClient) ping() error {
|
||||
uri := c.url.JoinPath("/loki/api/v1/status/buildinfo")
|
||||
uri := c.cfg.Url.JoinPath("/loki/api/v1/labels")
|
||||
req, err := http.NewRequest(http.MethodGet, uri.String(), nil)
|
||||
|
||||
if c.cfg.BasicAuthUser != "" || c.cfg.BasicAuthPassword != "" {
|
||||
req.SetBasicAuth(c.cfg.BasicAuthUser, c.cfg.BasicAuthPassword)
|
||||
}
|
||||
|
||||
if c.cfg.TenantID != "" {
|
||||
req.Header.Add("X-Scope-OrgID", c.cfg.TenantID)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating request: %w", err)
|
||||
}
|
||||
@ -47,8 +63,8 @@ func (c *httpLokiClient) ping() error {
|
||||
}
|
||||
|
||||
if res.StatusCode < 200 || res.StatusCode >= 300 {
|
||||
return fmt.Errorf("request to the loki buildinfo endpoint returned a non-200 status code: %d", res.StatusCode)
|
||||
return fmt.Errorf("ping request to loki endpoint returned a non-200 status code: %d", res.StatusCode)
|
||||
}
|
||||
c.log.Debug("Request to Loki buildinfo endpoint succeeded", "status", res.StatusCode)
|
||||
c.log.Debug("Ping request to Loki endpoint succeeded", "status", res.StatusCode)
|
||||
return nil
|
||||
}
|
||||
|
36
pkg/services/ngalert/state/historian/loki_http_test.go
Normal file
36
pkg/services/ngalert/state/historian/loki_http_test.go
Normal file
@ -0,0 +1,36 @@
|
||||
package historian
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// This function can be used for local testing, just remove the skip call.
|
||||
func TestLokiHTTPClient(t *testing.T) {
|
||||
t.Skip()
|
||||
|
||||
url, err := url.Parse("https://logs-prod-eu-west-0.grafana.net")
|
||||
require.NoError(t, err)
|
||||
|
||||
client := newLokiClient(LokiConfig{
|
||||
Url: url,
|
||||
}, log.NewNopLogger())
|
||||
|
||||
// Unauthorized request should fail against Grafana Cloud.
|
||||
err = client.ping()
|
||||
require.Error(t, err)
|
||||
|
||||
client.cfg.BasicAuthUser = "<your_username>"
|
||||
client.cfg.BasicAuthPassword = "<your_password>"
|
||||
|
||||
// When running on prem, you might need to set the tenant id,
|
||||
// so the x-scope-orgid header is set.
|
||||
// client.cfg.TenantID = "<your_tenant_id>"
|
||||
|
||||
// Authorized request should fail against Grafana Cloud.
|
||||
err = client.ping()
|
||||
require.NoError(t, err)
|
||||
}
|
@ -104,6 +104,11 @@ type UnifiedAlertingStateHistorySettings struct {
|
||||
Enabled bool
|
||||
Backend string
|
||||
LokiRemoteURL string
|
||||
LokiTenantID string
|
||||
// LokiBasicAuthUsername and LokiBasicAuthPassword are used for basic auth
|
||||
// if one of them is set.
|
||||
LokiBasicAuthPassword string
|
||||
LokiBasicAuthUsername string
|
||||
}
|
||||
|
||||
// IsEnabled returns true if UnifiedAlertingSettings.Enabled is either nil or true.
|
||||
@ -314,9 +319,12 @@ func (cfg *Cfg) ReadUnifiedAlertingSettings(iniFile *ini.File) error {
|
||||
|
||||
stateHistory := iniFile.Section("unified_alerting.state_history")
|
||||
uaCfgStateHistory := UnifiedAlertingStateHistorySettings{
|
||||
Enabled: stateHistory.Key("enabled").MustBool(stateHistoryDefaultEnabled),
|
||||
Backend: stateHistory.Key("backend").MustString("annotations"),
|
||||
LokiRemoteURL: stateHistory.Key("loki_remote_url").MustString(""),
|
||||
Enabled: stateHistory.Key("enabled").MustBool(stateHistoryDefaultEnabled),
|
||||
Backend: stateHistory.Key("backend").MustString("annotations"),
|
||||
LokiRemoteURL: stateHistory.Key("loki_remote_url").MustString(""),
|
||||
LokiTenantID: stateHistory.Key("loki_tenant_id").MustString(""),
|
||||
LokiBasicAuthUsername: stateHistory.Key("loki_basic_auth_username").MustString(""),
|
||||
LokiBasicAuthPassword: stateHistory.Key("loki_basic_auth_password").MustString(""),
|
||||
}
|
||||
uaCfg.StateHistory = uaCfgStateHistory
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user