Skip to content

Commit 6be8c07

Browse files
tombrkgotjosh
andauthored
fix(ruler): properly read OrgID from context (#3343)
* fix(ruler): properly read OrgID from context Previously the `/prometheus/api/v1/{rules|alerts}` endpoints used `user.ExtractOrgIDFromHTTPRequest` to read the tenant id directly from the HTTP request headers. This however only works in multi-tenant mode. When auth is disabled, no such headers are needed to be set and above function returns no value. By directly reading from the request, the HTTP auth middleware which usually catches such cases is bypassed. This PR changes the behavior to always read from the context instead of the request, which always holds the correct org id as set by the middleware. Signed-off-by: sh0rez <[email protected]> * fix(alertmanager): read org id from context Ports fixes done to the ruler api also to alertmanager Signed-off-by: sh0rez <[email protected]> * doc: add CHANGELOG entry Signed-off-by: sh0rez <[email protected]> * Address review comments Signed-off-by: gotjosh <[email protected]> Co-authored-by: gotjosh <[email protected]>
1 parent 8994a7c commit 6be8c07

File tree

7 files changed

+17
-19
lines changed

7 files changed

+17
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
* [BUGFIX] Honor configured timeout in Azure and GCS object clients. #3285
109109
* [BUGFIX] Shuffle sharding: fixed max global series per user/metric limit when shuffle sharding and `-distributor.shard-by-all-labels=true` are both enabled in distributor. When using these global limits you should now set `-distributor.sharding-strategy` and `-distributor.zone-awareness-enabled` to ingesters too. #3369
110110
* [BUGFIX] Slow query logging: when using downstream server request parameters were not logged. #3276
111+
* [BUGFIX] Fixed tenant detection in the ruler and alertmanager API when running without auth. #3343
111112

112113
## 1.4.0 / 2020-10-02
113114

pkg/alertmanager/api.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ type UserConfig struct {
3636
func (am *MultitenantAlertmanager) GetUserConfig(w http.ResponseWriter, r *http.Request) {
3737
logger := util.WithContext(r.Context(), am.logger)
3838

39-
userID, _, err := user.ExtractOrgIDFromHTTPRequest(r)
39+
userID, err := user.ExtractOrgID(r.Context())
4040
if err != nil {
4141
level.Error(logger).Log("msg", errNoOrgID, "err", err.Error())
4242
http.Error(w, fmt.Sprintf("%s: %s", errNoOrgID, err.Error()), http.StatusUnauthorized)
@@ -73,7 +73,7 @@ func (am *MultitenantAlertmanager) GetUserConfig(w http.ResponseWriter, r *http.
7373

7474
func (am *MultitenantAlertmanager) SetUserConfig(w http.ResponseWriter, r *http.Request) {
7575
logger := util.WithContext(r.Context(), am.logger)
76-
userID, _, err := user.ExtractOrgIDFromHTTPRequest(r)
76+
userID, err := user.ExtractOrgID(r.Context())
7777
if err != nil {
7878
level.Error(logger).Log("msg", errNoOrgID, "err", err.Error())
7979
http.Error(w, fmt.Sprintf("%s: %s", errNoOrgID, err.Error()), http.StatusUnauthorized)
@@ -114,7 +114,7 @@ func (am *MultitenantAlertmanager) SetUserConfig(w http.ResponseWriter, r *http.
114114

115115
func (am *MultitenantAlertmanager) DeleteUserConfig(w http.ResponseWriter, r *http.Request) {
116116
logger := util.WithContext(r.Context(), am.logger)
117-
userID, _, err := user.ExtractOrgIDFromHTTPRequest(r)
117+
userID, err := user.ExtractOrgID(r.Context())
118118
if err != nil {
119119
level.Error(logger).Log("msg", errNoOrgID, "err", err.Error())
120120
http.Error(w, fmt.Sprintf("%s: %s", errNoOrgID, err.Error()), http.StatusUnauthorized)

pkg/alertmanager/api_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,9 @@ template_files:
131131
for _, tc := range testCases {
132132
t.Run(tc.name, func(t *testing.T) {
133133
req := httptest.NewRequest(http.MethodPost, "http://alertmanager/api/v1/alerts", bytes.NewReader([]byte(tc.cfg)))
134-
ctx := context.Background()
135-
ctx = user.InjectOrgID(ctx, "testing")
136-
require.NoError(t, user.InjectOrgIDIntoHTTPRequest(ctx, req))
134+
ctx := user.InjectOrgID(req.Context(), "testing")
137135
w := httptest.NewRecorder()
138-
am.SetUserConfig(w, req)
136+
am.SetUserConfig(w, req.WithContext(ctx))
139137
resp := w.Result()
140138

141139
body, err := ioutil.ReadAll(resp.Body)

pkg/alertmanager/multitenant.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ func (am *MultitenantAlertmanager) newAlertmanager(userID string, amConfig *amco
463463

464464
// ServeHTTP serves the Alertmanager's web UI and API.
465465
func (am *MultitenantAlertmanager) ServeHTTP(w http.ResponseWriter, req *http.Request) {
466-
userID, _, err := user.ExtractOrgIDFromHTTPRequest(req)
466+
userID, err := user.ExtractOrgID(req.Context())
467467
if err != nil {
468468
http.Error(w, err.Error(), http.StatusUnauthorized)
469469
return

pkg/alertmanager/multitenant_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,10 @@ func TestAlertmanager_ServeHTTP(t *testing.T) {
214214

215215
// Request when no user configuration is present.
216216
req := httptest.NewRequest("GET", externalURL.String(), nil)
217-
req.Header.Add(user.OrgIDHeaderName, "user1")
217+
ctx := user.InjectOrgID(req.Context(), "user1")
218218
w := httptest.NewRecorder()
219219

220-
am.ServeHTTP(w, req)
220+
am.ServeHTTP(w, req.WithContext(ctx))
221221

222222
resp := w.Result()
223223
body, _ := ioutil.ReadAll(resp.Body)
@@ -237,7 +237,7 @@ func TestAlertmanager_ServeHTTP(t *testing.T) {
237237

238238
// Request when user configuration is paused.
239239
w = httptest.NewRecorder()
240-
am.ServeHTTP(w, req)
240+
am.ServeHTTP(w, req.WithContext(ctx))
241241

242242
resp = w.Result()
243243
body, _ = ioutil.ReadAll(resp.Body)
@@ -278,10 +278,10 @@ receivers:
278278

279279
// Request when no user configuration is present.
280280
req := httptest.NewRequest("GET", externalURL.String()+"/api/v1/status", nil)
281-
req.Header.Add(user.OrgIDHeaderName, "user1")
281+
ctx := user.InjectOrgID(req.Context(), "user1")
282282
w := httptest.NewRecorder()
283283

284-
am.ServeHTTP(w, req)
284+
am.ServeHTTP(w, req.WithContext(ctx))
285285

286286
resp := w.Result()
287287

@@ -302,7 +302,7 @@ receivers:
302302

303303
// Request when user configuration is paused.
304304
w = httptest.NewRecorder()
305-
am.ServeHTTP(w, req)
305+
am.ServeHTTP(w, req.WithContext(ctx))
306306

307307
resp = w.Result()
308308
body, _ := ioutil.ReadAll(resp.Body)

pkg/ruler/api.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,15 @@ func NewAPI(r *Ruler, s rules.RuleStore) *API {
134134

135135
func (a *API) PrometheusRules(w http.ResponseWriter, req *http.Request) {
136136
logger := util.WithContext(req.Context(), util.Logger)
137-
userID, ctx, err := user.ExtractOrgIDFromHTTPRequest(req)
137+
userID, err := user.ExtractOrgID(req.Context())
138138
if err != nil || userID == "" {
139139
level.Error(logger).Log("msg", "error extracting org id from context", "err", err)
140140
respondError(logger, w, "no valid org id found")
141141
return
142142
}
143143

144144
w.Header().Set("Content-Type", "application/json")
145-
rgs, err := a.ruler.GetRules(ctx)
145+
rgs, err := a.ruler.GetRules(req.Context())
146146

147147
if err != nil {
148148
respondError(logger, w, err.Error())
@@ -226,15 +226,15 @@ func (a *API) PrometheusRules(w http.ResponseWriter, req *http.Request) {
226226

227227
func (a *API) PrometheusAlerts(w http.ResponseWriter, req *http.Request) {
228228
logger := util.WithContext(req.Context(), util.Logger)
229-
userID, ctx, err := user.ExtractOrgIDFromHTTPRequest(req)
229+
userID, err := user.ExtractOrgID(req.Context())
230230
if err != nil || userID == "" {
231231
level.Error(logger).Log("msg", "error extracting org id from context", "err", err)
232232
respondError(logger, w, "no valid org id found")
233233
return
234234
}
235235

236236
w.Header().Set("Content-Type", "application/json")
237-
rgs, err := a.ruler.GetRules(ctx)
237+
rgs, err := a.ruler.GetRules(req.Context())
238238

239239
if err != nil {
240240
respondError(logger, w, err.Error())

pkg/ruler/api_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,6 @@ func requestFor(t *testing.T, method string, url string, body io.Reader, userID
370370
t.Helper()
371371

372372
req := httptest.NewRequest(method, url, body)
373-
req.Header.Add(user.OrgIDHeaderName, userID)
374373
ctx := user.InjectOrgID(req.Context(), userID)
375374

376375
return req.WithContext(ctx)

0 commit comments

Comments
 (0)