Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
* [BUGFIX] An index optimisation actually slows things down when using caching. Moved it to the right location. #2973
* [BUGFIX] Ingester: If push request contained both valid and invalid samples, valid samples were ingested but not stored to WAL of the chunks storage. This has been fixed. #3067
* [BUGFIX] Ruler: Config API would return both the `record` and `alert` in `YAML` response keys even when one of them must be empty. #3120
* [BUGFIX] Index page now uses configured HTTP path prefix when creating links. #3126

## 1.3.0 / 2020-08-21

Expand Down
4 changes: 2 additions & 2 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,9 @@ func (a *API) RegisterAlertmanager(am *alertmanager.MultitenantAlertmanager, tar
}

// RegisterAPI registers the standard endpoints associated with a running Cortex.
func (a *API) RegisterAPI(cfg interface{}) {
func (a *API) RegisterAPI(httpPathPrefix string, cfg interface{}) {
a.RegisterRoute("/config", configHandler(cfg), false)
a.RegisterRoute("/", http.HandlerFunc(indexHandler), false)
a.RegisterRoute("/", indexHandler(httpPathPrefix), false)
}

// RegisterDistributor registers the endpoints associated with the distributor.
Expand Down
46 changes: 29 additions & 17 deletions pkg/api/handlers.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package api

import (
"html/template"
"net/http"
"path"

"github.com/go-kit/kit/log/level"
"gopkg.in/yaml.v2"
Expand All @@ -10,7 +12,7 @@ import (
)

// TODO: Update this content to be a template that is dynamic based on how Cortex is run.
const indexPageContent = `
var indexPageContent = template.Must(template.New("main").Parse(`
<!DOCTYPE html>
<html>
<head>
Expand All @@ -21,29 +23,39 @@ const indexPageContent = `
<h1>Cortex</h1>
<p>Admin Endpoints:</p>
<ul>
<li><a href="/config">Current Config</a></li>
<li><a href="/distributor/all_user_stats">Usage Statistics</a></li>
<li><a href="/distributor/ha_tracker">HA Tracking Status</a></li>
<li><a href="/multitenant_alertmanager/status">Alertmanager Status</a></li>
<li><a href="/ingester/ring">Ingester Ring Status</a></li>
<li><a href="/ruler/ring">Ruler Ring Status</a></li>
<li><a href="/services">Service Status</a></li>
<li><a href="/compactor/ring">Compactor Ring Status (experimental blocks storage)</a></li
<li><a href="/store-gateway/ring">Store Gateway Ring (experimental blocks storage)</a></li>
<li><a href="{{ .AddPathPrefix "/config" }}">Current Config</a></li>
<li><a href="{{ .AddPathPrefix "/distributor/all_user_stats" }}">Usage Statistics</a></li>
<li><a href="{{ .AddPathPrefix "/distributor/ha_tracker" }}">HA Tracking Status</a></li>
<li><a href="{{ .AddPathPrefix "/multitenant_alertmanager/status" }}">Alertmanager Status</a></li>
<li><a href="{{ .AddPathPrefix "/ingester/ring" }}">Ingester Ring Status</a></li>
<li><a href="{{ .AddPathPrefix "/ruler/ring" }}">Ruler Ring Status</a></li>
<li><a href="{{ .AddPathPrefix "/services" }}">Service Status</a></li>
<li><a href="{{ .AddPathPrefix "/compactor/ring" }}">Compactor Ring Status (experimental blocks storage)</a></li>
<li><a href="{{ .AddPathPrefix "/store-gateway/ring" }}">Store Gateway Ring (experimental blocks storage)</a></li>
</ul>

<p>Dangerous:</p>
<ul>
<li><a href="/ingester/flush">Trigger a Flush</a></li>
<li><a href="/ingester/shutdown">Trigger Ingester Shutdown</a></li>
<li><a href="{{ .AddPathPrefix "/ingester/flush" }}">Trigger a Flush</a></li>
<li><a href="{{ .AddPathPrefix "/ingester/shutdown" }}">Trigger Ingester Shutdown</a></li>
</ul>
</body>
</html>`
</html>`))

func indexHandler(w http.ResponseWriter, _ *http.Request) {
if _, err := w.Write([]byte(indexPageContent)); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
type indexPageInput struct {
pathPrefix string
}

func (i indexPageInput) AddPathPrefix(p string) string {
return path.Join(i.pathPrefix, p)
}

func indexHandler(httpPathPrefix string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
err := indexPageContent.Execute(w, indexPageInput{pathPrefix: httpPathPrefix})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
}

Expand Down
31 changes: 31 additions & 0 deletions pkg/api/handlers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package api

import (
"net/http/httptest"
"strings"
"testing"

"github.com/stretchr/testify/require"
)

func TestIndexHandlerPrefix(t *testing.T) {
for _, tc := range []struct {
prefix string
toBeFound string
}{
{prefix: "", toBeFound: "<a href=\"/ingester/ring\">"},
{prefix: "/test", toBeFound: "<a href=\"/test/ingester/ring\">"},
// All the extra slashed are cleaned up in the result.
{prefix: "///test///", toBeFound: "<a href=\"/test/ingester/ring\">"},
} {
h := indexHandler(tc.prefix)

req := httptest.NewRequest("GET", "/", nil)
resp := httptest.NewRecorder()

h.ServeHTTP(resp, req)

require.Equal(t, 200, resp.Code)
require.True(t, strings.Contains(resp.Body.String(), tc.toBeFound))
}
}
2 changes: 1 addition & 1 deletion pkg/cortex/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (t *Cortex) initAPI() (services.Service, error) {

t.API = a

t.API.RegisterAPI(t.Cfg)
t.API.RegisterAPI(t.Cfg.Server.PathPrefix, t.Cfg)

return nil, nil
}
Expand Down