Skip to content

Commit

Permalink
mimir-continuous-test tool: Add basic authentication and bearer token…
Browse files Browse the repository at this point in the history
… support (#2717)

Signed-off-by: Wilfried Roset <wilfriedroset@users.noreply.github.com>
  • Loading branch information
wilfriedroset committed Aug 16, 2022
1 parent b3bc0ab commit 4a12de2
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

### Mimir Continuous Test

* [ENHANCEMENT] Added basic authentication and bearer token support for when Mimir is behind a gateway authenticating the calls. #2717

### Documentation


Expand Down
7 changes: 5 additions & 2 deletions docs/sources/operators-guide/tools/mimir-continuous-test.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ chmod +x mimir-continuous-test

## Configure mimir-continuous-test

Mimir-continuous-test requires the endpoints of the backend Grafana Mimir clusters and the tenant ID for writing and querying testing metrics:
Mimir-continuous-test requires the endpoints of the backend Grafana Mimir clusters and the authentication for writing and querying testing metrics:

- Set `-tests.write-endpoint` to the base endpoint on the write path. Remove any trailing slash from the URL. The tool appends the specific API path to the URL, for example `/api/v1/push` for the remote-write API.
- Set `-tests.read-endpoint` to the base endpoint on the read path. Remove any trailing slash from the URL. The tool appends the specific API path to the URL, for example `/api/v1/query_range` for the range-query API.
- Set `-tests.tenant-id` to the tenant ID to use to write and read metrics in tests.
- Set the authentication means to use to write and read metrics in tests. By priority order:
- `-tests.bearer-token` for bearer token authentication.
- `-tests.basic-auth-user` and `-tests.basic-auth-password` for a basic authentication.
- `-tests.tenant-id` to the tenant ID, default to `anonymous`.
- Set `-tests.smoke-test` to run the test once and immediately exit. In this mode, the process exit code is non-zero when the test fails.

> **Note:** You can run `mimir-continuous-test -help` to list all available configuration options.
Expand Down
40 changes: 33 additions & 7 deletions pkg/continuoustest/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ type MimirClient interface {
}

type ClientConfig struct {
TenantID string
TenantID string
BasicAuthUser string
BasicAuthPassword string
BearerToken string

WriteBaseEndpoint flagext.URLValue
WriteBatchSize int
Expand All @@ -54,7 +57,10 @@ type ClientConfig struct {
}

func (cfg *ClientConfig) RegisterFlags(f *flag.FlagSet) {
f.StringVar(&cfg.TenantID, "tests.tenant-id", "anonymous", "The tenant ID to use to write and read metrics in tests.")
f.StringVar(&cfg.TenantID, "tests.tenant-id", "anonymous", "The tenant ID to use to write and read metrics in tests. (mutually exclusive with basic-auth or bearer-token flags)")
f.StringVar(&cfg.BasicAuthUser, "tests.basic-auth-user", "", "The username to use for HTTP bearer authentication. (mutually exclusive with tenant-id or bearer-token flags)")
f.StringVar(&cfg.BasicAuthPassword, "tests.basic-auth-password", "", "The password to use for HTTP bearer authentication. (mutually exclusive with tenant-id or bearer-token flags)")
f.StringVar(&cfg.BearerToken, "tests.bearer-token", "", "The bearer token to use for HTTP bearer authentication. (mutually exclusive with tenant-id flag or basic-auth flags)")

f.Var(&cfg.WriteBaseEndpoint, "tests.write-endpoint", "The base endpoint on the write path. The URL should have no trailing slash. The specific API path is appended by the tool to the URL, for example /api/v1/push for the remote write API endpoint, so the configured URL must not include it.")
f.IntVar(&cfg.WriteBatchSize, "tests.write-batch-size", 1000, "The maximum number of series to write in a single request.")
Expand All @@ -73,8 +79,11 @@ type Client struct {

func NewClient(cfg ClientConfig, logger log.Logger) (*Client, error) {
rt := &clientRoundTripper{
tenantID: cfg.TenantID,
rt: instrumentation.TracerTransport{},
tenantID: cfg.TenantID,
basicAuthUser: cfg.BasicAuthUser,
basicAuthPassword: cfg.BasicAuthPassword,
bearerToken: cfg.BearerToken,
rt: instrumentation.TracerTransport{},
}

// Ensure the required config has been set.
Expand All @@ -84,6 +93,14 @@ func NewClient(cfg ClientConfig, logger log.Logger) (*Client, error) {
if cfg.ReadBaseEndpoint.URL == nil {
return nil, errors.New("the read endpoint has not been set")
}
// Ensure not both tenant-id and basic-auth are used at the same time
// anonymous is the default value for TenantID.
if (cfg.TenantID != "anonymous" && cfg.BasicAuthUser != "" && cfg.BasicAuthPassword != "" && cfg.BearerToken != "") || // all authentication at once
(cfg.TenantID != "anonymous" && cfg.BasicAuthUser != "" && cfg.BasicAuthPassword != "") || // tenant-id and basic auth
(cfg.TenantID != "anonymous" && cfg.BearerToken != "") || // tenant-id and bearer token
(cfg.BasicAuthUser != "" && cfg.BasicAuthPassword != "" && cfg.BearerToken != "") { // basic auth and bearer token
return nil, errors.New("either set tests.tenant-id or tests.basic-auth-user/tests.basic-auth-password or tests.bearer-token")
}

apiCfg := api.Config{
Address: cfg.ReadBaseEndpoint.String(),
Expand Down Expand Up @@ -242,8 +259,11 @@ type key int
var requestOptionsKey key

type clientRoundTripper struct {
tenantID string
rt http.RoundTripper
tenantID string
basicAuthUser string
basicAuthPassword string
bearerToken string
rt http.RoundTripper
}

// RoundTrip add the tenant ID header required by Mimir.
Expand All @@ -254,6 +274,12 @@ func (rt *clientRoundTripper) RoundTrip(req *http.Request) (*http.Response, erro
req.Header.Set("Cache-Control", "no-store")
}

req.Header.Set("X-Scope-OrgID", rt.tenantID)
if rt.bearerToken != "" {
req.Header.Set("Authorization", "Bearer "+rt.bearerToken)
} else if rt.basicAuthUser != "" && rt.basicAuthPassword != "" {
req.SetBasicAuth(rt.basicAuthUser, rt.basicAuthPassword)
} else {
req.Header.Set("X-Scope-OrgID", rt.tenantID)
}
return rt.rt.RoundTrip(req)
}

0 comments on commit 4a12de2

Please sign in to comment.