Skip to content

Commit

Permalink
feat(mimir/ruler/k8s): configurable path prefix for Mimir's Prometheu…
Browse files Browse the repository at this point in the history
…s API endpoint (#6168)

* feat(mimir/ruler/k8s): configurable path prefix for Mimir's Prometheus API endpoint

---------

Signed-off-by: hainenber <dotronghai96@gmail.com>
Co-authored-by: Paulin Todev <paulin.todev@gmail.com>
Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>
  • Loading branch information
3 people authored Jan 29, 2024
1 parent 2c4f3e1 commit 007070d
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 57 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ Main (unreleased)

- Increased clustering alert periods to 10 minutes to improve the
signal-to-noise ratio in Grafana Agent Mixin. (@thampiotr)

- `mimir.rules.kubernetes` has a new `prometheus_http_prefix` argument to configure
the HTTP endpoint on which to connect to Mimir's API. (@hainenber)

### Bugfixes

Expand Down
9 changes: 5 additions & 4 deletions component/mimir/rules/kubernetes/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,11 @@ func (c *Component) init() error {
httpClient := c.args.HTTPClientConfig.Convert()

c.mimirClient, err = mimirClient.New(c.log, mimirClient.Config{
ID: c.args.TenantID,
Address: c.args.Address,
UseLegacyRoutes: c.args.UseLegacyRoutes,
HTTPClientConfig: *httpClient,
ID: c.args.TenantID,
Address: c.args.Address,
UseLegacyRoutes: c.args.UseLegacyRoutes,
PrometheusHTTPPrefix: c.args.PrometheusHTTPPrefix,
HTTPClientConfig: *httpClient,
}, c.metrics.mimirClientTiming)
if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions component/mimir/rules/kubernetes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type Arguments struct {
Address string `river:"address,attr"`
TenantID string `river:"tenant_id,attr,optional"`
UseLegacyRoutes bool `river:"use_legacy_routes,attr,optional"`
PrometheusHTTPPrefix string `river:"prometheus_http_prefix,attr,optional"`
HTTPClientConfig config.HTTPClientConfig `river:",squash"`
SyncInterval time.Duration `river:"sync_interval,attr,optional"`
MimirNameSpacePrefix string `river:"mimir_namespace_prefix,attr,optional"`
Expand All @@ -23,6 +24,7 @@ var DefaultArguments = Arguments{
SyncInterval: 30 * time.Second,
MimirNameSpacePrefix: "agent",
HTTPClientConfig: config.DefaultHTTPClientConfig,
PrometheusHTTPPrefix: "/prometheus",
}

// SetToDefault implements river.Defaulter.
Expand Down
32 changes: 20 additions & 12 deletions docs/sources/flow/reference/components/mimir.rules.kubernetes.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,19 @@ mimir.rules.kubernetes "LABEL" {

`mimir.rules.kubernetes` supports the following arguments:

Name | Type | Description | Default | Required
-------------------------|------------|---------------------------------------------------------------------------------|---------|---------
`address` | `string` | URL of the Mimir ruler. | | yes
`tenant_id` | `string` | Mimir tenant ID. | | no
`use_legacy_routes` | `bool` | Whether to use deprecated ruler API endpoints. | false | no
`sync_interval` | `duration` | Amount of time between reconciliations with Mimir. | "30s" | no
`mimir_namespace_prefix` | `string` | Prefix used to differentiate multiple {{< param "PRODUCT_NAME" >}} deployments. | "agent" | no
`bearer_token` | `secret` | Bearer token to authenticate with. | | no
`bearer_token_file` | `string` | File containing a bearer token to authenticate with. | | no
`proxy_url` | `string` | HTTP proxy to proxy requests through. | | no
`follow_redirects` | `bool` | Whether redirects returned by the server should be followed. | `true` | no
`enable_http2` | `bool` | Whether HTTP2 is supported for requests. | `true` | no
| Name | Type | Description | Default | Required |
| ------------------------ | ---------- | ------------------------------------------------------------------------------- | ------------- | -------- |
| `address` | `string` | URL of the Mimir ruler. | | yes |
| `tenant_id` | `string` | Mimir tenant ID. | | no |
| `use_legacy_routes` | `bool` | Whether to use [deprecated][gem-2_2] ruler API endpoints. | false | no |
| `prometheus_http_prefix` | `string` | Path prefix for [Mimir's Prometheus endpoint][gem-path-prefix]. | `/prometheus` | no |
| `sync_interval` | `duration` | Amount of time between reconciliations with Mimir. | "30s" | no |
| `mimir_namespace_prefix` | `string` | Prefix used to differentiate multiple {{< param "PRODUCT_NAME" >}} deployments. | "agent" | no |
| `bearer_token` | `secret` | Bearer token to authenticate with. | | no |
| `bearer_token_file` | `string` | File containing a bearer token to authenticate with. | | no |
| `proxy_url` | `string` | HTTP proxy to proxy requests through. | | no |
| `follow_redirects` | `bool` | Whether redirects returned by the server should be followed. | `true` | no |
| `enable_http2` | `bool` | Whether HTTP2 is supported for requests. | `true` | no |

At most one of the following can be provided:
- [`bearer_token` argument](#arguments).
Expand All @@ -81,6 +82,13 @@ The `mimir_namespace_prefix` argument can be used to separate the rules managed
by multiple {{< param "PRODUCT_NAME" >}} deployments across your infrastructure. It should be set to a
unique value for each deployment.

If `use_legacy_routes` is set to `true`, `mimir.rules.kubernetes` contacts Mimir on a `/api/v1/rules` endpoint.

If `prometheus_http_prefix` is set to `/mimir`, `mimir.rules.kubernetes` contacts Mimir on a `/mimir/config/v1/rules` endpoint.
This is useful if you configure Mimir to use a different [prefix][gem-path-prefix] for its Prometheus endpoints than the default one.

`prometheus_http_prefix` is ignored if `use_legacy_routes` is set to `true`.

## Blocks

The following blocks are supported inside the definition of
Expand Down
23 changes: 11 additions & 12 deletions pkg/mimir/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,18 @@ import (
"github.com/prometheus/prometheus/model/rulefmt"
)

const (
rulerAPIPath = "/prometheus/config/v1/rules"
legacyAPIPath = "/api/v1/rules"
)

var (
ErrNoConfig = errors.New("No config exists for this user")
ErrNoConfig = errors.New("no config exists for this user")
ErrResourceNotFound = errors.New("requested resource not found")
)

// Config is used to configure a MimirClient.
type Config struct {
ID string
Address string
UseLegacyRoutes bool
HTTPClientConfig config.HTTPClientConfig
ID string
Address string
UseLegacyRoutes bool
HTTPClientConfig config.HTTPClientConfig
PrometheusHTTPPrefix string
}

type Interface interface {
Expand Down Expand Up @@ -65,9 +61,12 @@ func New(logger log.Logger, cfg Config, timingHistogram *prometheus.HistogramVec
return nil, err
}

path := rulerAPIPath
path, err := url.JoinPath(cfg.PrometheusHTTPPrefix, "/config/v1/rules")
if err != nil {
return nil, err
}
if cfg.UseLegacyRoutes {
path = legacyAPIPath
path = "/api/v1/rules"
}

collector := instrument.NewHistogramCollector(timingHistogram)
Expand Down
7 changes: 7 additions & 0 deletions pkg/mimir/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ func TestBuildURL(t *testing.T) {
url: "http://mimir.local/apathto",
resultURL: "http://mimir.local/apathto/prometheus/config/v1/rules/last-char-slash%2F",
},
{
name: "builds the correct URL with a customized prometheus_http_prefix",
path: "/mimir/config/v1/rules",
method: http.MethodPost,
url: "http://mimir.local/",
resultURL: "http://mimir.local/mimir/config/v1/rules",
},
}

for _, tt := range tc {
Expand Down
72 changes: 43 additions & 29 deletions pkg/mimir/client/rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,49 +22,63 @@ func TestMimirClient_X(t *testing.T) {
}))
defer ts.Close()

client, err := New(log.NewNopLogger(), Config{
Address: ts.URL,
}, prometheus.NewHistogramVec(prometheus.HistogramOpts{}, instrument.HistogramCollectorBuckets))
require.NoError(t, err)

for _, tc := range []struct {
test string
namespace string
name string
expURLPath string
test string
namespace string
name string
prometheusHTTPPrefix string
expURLPath string
}{
{
test: "regular-characters",
namespace: "my-namespace",
name: "my-name",
expURLPath: "/prometheus/config/v1/rules/my-namespace/my-name",
test: "regular-characters",
namespace: "my-namespace",
name: "my-name",
expURLPath: "/prometheus/config/v1/rules/my-namespace/my-name",
prometheusHTTPPrefix: "/prometheus",
},
{
test: "special-characters-spaces",
namespace: "My: Namespace",
name: "My: Name",
prometheusHTTPPrefix: "/prometheus",
expURLPath: "/prometheus/config/v1/rules/My:%20Namespace/My:%20Name",
},
{
test: "special-characters-spaces",
namespace: "My: Namespace",
name: "My: Name",
expURLPath: "/prometheus/config/v1/rules/My:%20Namespace/My:%20Name",
test: "special-characters-slashes",
namespace: "My/Namespace",
name: "My/Name",
prometheusHTTPPrefix: "/prometheus",
expURLPath: "/prometheus/config/v1/rules/My%2FNamespace/My%2FName",
},
{
test: "special-characters-slashes",
namespace: "My/Namespace",
name: "My/Name",
expURLPath: "/prometheus/config/v1/rules/My%2FNamespace/My%2FName",
test: "special-characters-slash-first",
namespace: "My/Namespace",
name: "/first-char-slash",
prometheusHTTPPrefix: "/prometheus",
expURLPath: "/prometheus/config/v1/rules/My%2FNamespace/%2Ffirst-char-slash",
},
{
test: "special-characters-slash-first",
namespace: "My/Namespace",
name: "/first-char-slash",
expURLPath: "/prometheus/config/v1/rules/My%2FNamespace/%2Ffirst-char-slash",
test: "special-characters-slash-last",
namespace: "My/Namespace",
name: "last-char-slash/",
prometheusHTTPPrefix: "/prometheus",
expURLPath: "/prometheus/config/v1/rules/My%2FNamespace/last-char-slash%2F",
},
{
test: "special-characters-slash-last",
namespace: "My/Namespace",
name: "last-char-slash/",
expURLPath: "/prometheus/config/v1/rules/My%2FNamespace/last-char-slash%2F",
test: "regular-characters-with-customized-prometheus-http-prefix",
namespace: "My/Namespace",
name: "last-char-slash/",
prometheusHTTPPrefix: "/mimir",
expURLPath: "/mimir/config/v1/rules/My%2FNamespace/last-char-slash%2F",
},
} {
t.Run(tc.test, func(t *testing.T) {
client, err := New(log.NewNopLogger(), Config{
Address: ts.URL,
PrometheusHTTPPrefix: tc.prometheusHTTPPrefix,
}, prometheus.NewHistogramVec(prometheus.HistogramOpts{}, instrument.HistogramCollectorBuckets))
require.NoError(t, err)

ctx := context.Background()
require.NoError(t, client.DeleteRuleGroup(ctx, tc.namespace, tc.name))

Expand Down

0 comments on commit 007070d

Please sign in to comment.