diff --git a/CHANGELOG.md b/CHANGELOG.md index b5acb9bffa..c24b3c09a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ We use *breaking* word for marking changes that are not backward compatible (rel - [#1712](https://github.com/thanos-io/thanos/pull/1712) Rename flag on bucket web component from `--listen` to `--http-address` to match other components. - [#1733](https://github.com/thanos-io/thanos/pull/1733) New metric `thanos_compactor_iterations_total` on Thanos Compactor which shows the number of successful iterations. - [#1758](https://github.com/thanos-io/thanos/pull/1758) `thanos bucket web` now supports `--web.external-prefix` for proxying on a subpath. +- [#1770](https://github.com/thanos-io/thanos/pull/1770) Add `--web.prefix-header` flags to allow for bucket UI to be accessible behind a reverse proxy. ### Fixed @@ -28,6 +29,7 @@ We use *breaking* word for marking changes that are not backward compatible (rel - [#1669](https://github.com/thanos-io/thanos/pull/1669) Fixed store sharding. Now it does not load excluded meta.jsons and load/fetch index-cache.json files. - [#1670](https://github.com/thanos-io/thanos/pull/1670) Fixed un-ordered blocks upload. Sidecar now uploads the oldest blocks first. - [#1568](https://github.com/thanos-io/thanos/pull/1709) Thanos Store now retains the first raw value of a chunk during downsampling to avoid losing some counter resets that occur on an aggregation boundary. +- [#1770](https://github.com/thanos-io/thanos/pull/1770) Fix `--web.external-prefix` 404s for static resources. ### Changed diff --git a/cmd/thanos/bucket.go b/cmd/thanos/bucket.go index 6581e154d5..0f7c43cc94 100644 --- a/cmd/thanos/bucket.go +++ b/cmd/thanos/bucket.go @@ -311,10 +311,11 @@ func registerBucketInspect(m map[string]setupFunc, root *kingpin.CmdClause, name func registerBucketWeb(m map[string]setupFunc, root *kingpin.CmdClause, name string, objStoreConfig *extflag.PathOrContent) { cmd := root.Command("web", "Web interface for remote storage bucket") httpBindAddr, httpGracePeriod := regHTTPFlags(cmd) + webExternalPrefix := cmd.Flag("web.external-prefix", "Static prefix for all HTML links and redirect URLs in the bucket web UI interface. Actual endpoints are still served on / or the web.route-prefix. This allows thanos bucket web UI to be served behind a reverse proxy that strips a URL sub-path.").Default("").String() + webPrefixHeaderName := cmd.Flag("web.prefix-header", "Name of HTTP request header used for dynamic prefixing of UI links and redirects. This option is ignored if web.external-prefix argument is set. Security risk: enable this option only if a reverse proxy in front of thanos is resetting the header. The --web.prefix-header=X-Forwarded-Prefix option can be useful, for example, if Thanos UI is served via Traefik reverse proxy with PathPrefixStrip option enabled, which sends the stripped prefix value in X-Forwarded-Prefix header. This allows thanos UI to be served on a sub-path.").Default("").String() interval := cmd.Flag("refresh", "Refresh interval to download metadata from remote storage").Default("30m").Duration() timeout := cmd.Flag("timeout", "Timeout to download metadata from remote storage").Default("5m").Duration() label := cmd.Flag("label", "Prometheus label to use as timeline title").String() - webExternalPrefix := cmd.Flag("web.external-prefix", "Static prefix for all HTML links and redirect URLs in the UI query web interface. Actual endpoints are still served on / or the web.route-prefix. This allows thanos UI to be served behind a reverse proxy that strips a URL sub-path.").Default("").String() m[name+" web"] = func(g *run.Group, logger log.Logger, reg *prometheus.Registry, _ opentracing.Tracer, _ bool) error { ctx, cancel := context.WithCancel(context.Background()) @@ -328,11 +329,13 @@ func registerBucketWeb(m map[string]setupFunc, root *kingpin.CmdClause, name str flagsMap := map[string]string{ "web.external-prefix": *webExternalPrefix, + "web.prefix-header": *webPrefixHeaderName, } router := route.New() + bucketUI := ui.NewBucketUI(logger, *label, flagsMap) - bucketUI.Register(router, extpromhttp.NewInstrumentationMiddleware(reg)) + bucketUI.Register(router.WithPrefix(*webExternalPrefix), extpromhttp.NewInstrumentationMiddleware(reg)) srv.Handle("/", router) if *interval < 5*time.Minute { diff --git a/docs/components/bucket.md b/docs/components/bucket.md index fb977744b0..b6fc2c9188 100644 --- a/docs/components/bucket.md +++ b/docs/components/bucket.md @@ -126,16 +126,29 @@ Flags: Listen host:port for HTTP endpoints. --http-grace-period=2m Time to wait after an interrupt received for HTTP Server. + --web.external-prefix="" Static prefix for all HTML links and redirect + URLs in the bucket web UI interface. Actual + endpoints are still served on / or the + web.route-prefix. This allows thanos bucket web + UI to be served behind a reverse proxy that + strips a URL sub-path. + --web.prefix-header="" Name of HTTP request header used for dynamic + prefixing of UI links and redirects. This option + is ignored if web.external-prefix argument is + set. Security risk: enable this option only if a + reverse proxy in front of thanos is resetting + the header. The + --web.prefix-header=X-Forwarded-Prefix option + can be useful, for example, if Thanos UI is + served via Traefik reverse proxy with + PathPrefixStrip option enabled, which sends the + stripped prefix value in X-Forwarded-Prefix + header. This allows thanos UI to be served on a + sub-path. --refresh=30m Refresh interval to download metadata from remote storage --timeout=5m Timeout to download metadata from remote storage --label=LABEL Prometheus label to use as timeline title - --web.external-prefix="" Static prefix for all HTML links and redirect - URLs in the UI query web interface. Actual - endpoints are still served on / or the - web.route-prefix. This allows thanos UI to be - served behind a reverse proxy that strips a URL - sub-path. ``` diff --git a/pkg/ui/bucket.go b/pkg/ui/bucket.go index ae9fb2ad41..e8fcbe6887 100644 --- a/pkg/ui/bucket.go +++ b/pkg/ui/bucket.go @@ -13,13 +13,13 @@ import ( // Bucket is a web UI representing state of buckets as a timeline. type Bucket struct { *BaseUI + flagsMap map[string]string // Unique Prometheus label that identifies each shard, used as the title. If // not present, all labels are displayed externally as a legend. Label string Blocks template.JS RefreshedAt time.Time Err error - flagsMap map[string]string } func NewBucketUI(logger log.Logger, label string, flagsMap map[string]string) *Bucket {