Skip to content
This repository was archived by the owner on Jul 19, 2023. It is now read-only.

Commit ff18c68

Browse files
authored
Bring back the Pyroscope API (#591)
* Bring back the Pyroscope API * lint
1 parent 470ff35 commit ff18c68

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

pkg/phlare/modules.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ func (f *Phlare) initQuerier() (services.Service, error) {
205205
return nil, err
206206
}
207207

208+
f.Server.HTTP.Handle("/pyroscope/render", util.AuthenticateUser(f.Cfg.MultitenancyEnabled).Wrap(http.HandlerFunc(querierSvc.RenderHandler)))
209+
f.Server.HTTP.Handle("/pyroscope/label-values", util.AuthenticateUser(f.Cfg.MultitenancyEnabled).Wrap(http.HandlerFunc(querierSvc.LabelValuesHandler)))
210+
208211
sm, err := services.NewManager(querierSvc, worker)
209212
if err != nil {
210213
return nil, err

pkg/util/http.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import (
2525
"github.com/weaveworks/common/user"
2626
"golang.org/x/net/http2"
2727
"gopkg.in/yaml.v3"
28+
29+
"github.com/grafana/phlare/pkg/tenant"
2830
)
2931

3032
var defaultTransport http.RoundTripper = &http2.Transport{
@@ -348,3 +350,22 @@ func WriteJSONResponse(w http.ResponseWriter, v interface{}) {
348350
// Also this isn't internal error, but error communicating with client.
349351
_, _ = w.Write(data)
350352
}
353+
354+
// AuthenticateUser propagates the user ID from HTTP headers back to the request's context.
355+
// If on is false, it will inject the default tenant ID.
356+
func AuthenticateUser(on bool) middleware.Interface {
357+
return middleware.Func(func(next http.Handler) http.Handler {
358+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
359+
if !on {
360+
next.ServeHTTP(w, r.WithContext(user.InjectOrgID(r.Context(), tenant.DefaultTenantID)))
361+
return
362+
}
363+
_, ctx, err := user.ExtractOrgIDFromHTTPRequest(r)
364+
if err != nil {
365+
http.Error(w, err.Error(), http.StatusUnauthorized)
366+
return
367+
}
368+
next.ServeHTTP(w, r.WithContext(ctx))
369+
})
370+
})
371+
}

pkg/util/http_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package util_test
22

33
import (
4+
"net/http"
45
"net/http/httptest"
56
"testing"
67

78
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
810

11+
"github.com/grafana/phlare/pkg/tenant"
912
"github.com/grafana/phlare/pkg/util"
1013
)
1114

@@ -18,3 +21,32 @@ func TestWriteTextResponse(t *testing.T) {
1821
assert.Equal(t, "hello world", w.Body.String())
1922
assert.Equal(t, "text/plain", w.Header().Get("Content-Type"))
2023
}
24+
25+
func TestMultitenantMiddleware(t *testing.T) {
26+
w := httptest.NewRecorder()
27+
r := httptest.NewRequest("GET", "http://localhost:8080", nil)
28+
29+
// No org ID header.
30+
m := util.AuthenticateUser(true).Wrap(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
31+
id, err := tenant.ExtractTenantIDFromContext(r.Context())
32+
require.NoError(t, err)
33+
assert.Equal(t, "1", id)
34+
}))
35+
m.ServeHTTP(w, r)
36+
assert.Equal(t, http.StatusUnauthorized, w.Code)
37+
38+
w = httptest.NewRecorder()
39+
r.Header.Set("X-Scope-OrgID", "1")
40+
m.ServeHTTP(w, r)
41+
assert.Equal(t, http.StatusOK, w.Code)
42+
43+
// No org ID header without auth.
44+
r = httptest.NewRequest("GET", "http://localhost:8080", nil)
45+
m = util.AuthenticateUser(false).Wrap(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
46+
id, err := tenant.ExtractTenantIDFromContext(r.Context())
47+
require.NoError(t, err)
48+
assert.Equal(t, tenant.DefaultTenantID, id)
49+
}))
50+
m.ServeHTTP(w, r)
51+
assert.Equal(t, http.StatusOK, w.Code)
52+
}

0 commit comments

Comments
 (0)