mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
added `unauthorized_user` field in vmauth users config (#4083) --------- Signed-off-by: Alexander Marshalov <_@marshalov.org>
This commit is contained in:
parent
77f76371d0
commit
73e22dcf81
4 changed files with 65 additions and 4 deletions
|
@ -62,6 +62,10 @@ The following [metrics](#monitoring) related to concurrency limits are exposed b
|
||||||
- `vmauth_user_concurrent_requests_current{username="..."}` - the current number of concurrent requests for the given `username`.
|
- `vmauth_user_concurrent_requests_current{username="..."}` - the current number of concurrent requests for the given `username`.
|
||||||
- `vmauth_user_concurrent_requests_limit_reached_total{username="foo"}` - the number of requests rejected with `429 Too Many Requests` error
|
- `vmauth_user_concurrent_requests_limit_reached_total{username="foo"}` - the number of requests rejected with `429 Too Many Requests` error
|
||||||
because of the concurrency limit has been reached for the given `username`.
|
because of the concurrency limit has been reached for the given `username`.
|
||||||
|
- `vmauth_unauthorized_user_concurrent_requests_capacity` - the limit on the number of concurrent requests for unauthorized users (if `unauthorized_user` section is used).
|
||||||
|
- `vmauth_unauthorized_user_concurrent_requests_current` - the current number of concurrent requests for unauthorized users (if `unauthorized_user` section is used).
|
||||||
|
- `vmauth_unauthorized_user_concurrent_requests_limit_reached_total` - the number of requests rejected with `429 Too Many Requests` error
|
||||||
|
because of the concurrency limit has been reached for unauthorized users (if `unauthorized_user` section is used).
|
||||||
|
|
||||||
|
|
||||||
## Auth config
|
## Auth config
|
||||||
|
@ -152,6 +156,18 @@ users:
|
||||||
url_prefix: "http://vminsert:8480/insert/42/prometheus"
|
url_prefix: "http://vminsert:8480/insert/42/prometheus"
|
||||||
headers:
|
headers:
|
||||||
- "X-Scope-OrgID: abc"
|
- "X-Scope-OrgID: abc"
|
||||||
|
|
||||||
|
# This requests will be executed for requests without Authorization header.
|
||||||
|
# For instance, http://vmauth:8427/api/v1/query will be proxied to http://vmselect1:8481/select/0/prometheus/api/v1/query
|
||||||
|
unauthorized_user:
|
||||||
|
url_map:
|
||||||
|
- src_paths:
|
||||||
|
- /health
|
||||||
|
- /api/v1/query/
|
||||||
|
- /api/v1/query_range
|
||||||
|
url_prefix:
|
||||||
|
- http://vmselect1:8481/select/0/prometheus
|
||||||
|
- http://vmselect2:8481/select/0/prometheus
|
||||||
```
|
```
|
||||||
|
|
||||||
The config may contain `%{ENV_VAR}` placeholders, which are substituted by the corresponding `ENV_VAR` environment variable values.
|
The config may contain `%{ENV_VAR}` placeholders, which are substituted by the corresponding `ENV_VAR` environment variable values.
|
||||||
|
@ -194,6 +210,8 @@ users:
|
||||||
# other config options here
|
# other config options here
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For unauthorized users `vmauth` exports `vmauth_unauthorized_user_requests_total` metric without label (if `unauthorized_user` section of config is used).
|
||||||
|
|
||||||
## How to build from sources
|
## How to build from sources
|
||||||
|
|
||||||
It is recommended using [binary releases](https://github.com/VictoriaMetrics/VictoriaMetrics/releases) - `vmauth` is located in `vmutils-*` archives there.
|
It is recommended using [binary releases](https://github.com/VictoriaMetrics/VictoriaMetrics/releases) - `vmauth` is located in `vmutils-*` archives there.
|
||||||
|
|
|
@ -32,6 +32,7 @@ var (
|
||||||
// AuthConfig represents auth config.
|
// AuthConfig represents auth config.
|
||||||
type AuthConfig struct {
|
type AuthConfig struct {
|
||||||
Users []UserInfo `yaml:"users,omitempty"`
|
Users []UserInfo `yaml:"users,omitempty"`
|
||||||
|
UnauthorizedUser *UserInfo `yaml:"unauthorized_user,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserInfo is user information read from authConfigPath
|
// UserInfo is user information read from authConfigPath
|
||||||
|
@ -374,6 +375,18 @@ func parseAuthConfig(data []byte) (*AuthConfig, error) {
|
||||||
if err = yaml.UnmarshalStrict(data, &ac); err != nil {
|
if err = yaml.UnmarshalStrict(data, &ac); err != nil {
|
||||||
return nil, fmt.Errorf("cannot unmarshal AuthConfig data: %w", err)
|
return nil, fmt.Errorf("cannot unmarshal AuthConfig data: %w", err)
|
||||||
}
|
}
|
||||||
|
ui := ac.UnauthorizedUser
|
||||||
|
if ui != nil {
|
||||||
|
ui.requests = metrics.GetOrCreateCounter(`vmauth_unauthorized_user_requests_total`)
|
||||||
|
ui.concurrencyLimitCh = make(chan struct{}, ui.getMaxConcurrentRequests())
|
||||||
|
ui.concurrencyLimitReached = metrics.GetOrCreateCounter(`vmauth_unauthorized_user_concurrent_requests_limit_reached_total`)
|
||||||
|
_ = metrics.GetOrCreateGauge(`vmauth_unauthorized_user_concurrent_requests_capacity`, func() float64 {
|
||||||
|
return float64(cap(ui.concurrencyLimitCh))
|
||||||
|
})
|
||||||
|
_ = metrics.GetOrCreateGauge(`vmauth_unauthorized_user_concurrent_requests_current`, func() float64 {
|
||||||
|
return float64(len(ui.concurrencyLimitCh))
|
||||||
|
})
|
||||||
|
}
|
||||||
return &ac, nil
|
return &ac, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,13 @@ func requestHandler(w http.ResponseWriter, r *http.Request) bool {
|
||||||
}
|
}
|
||||||
authToken := r.Header.Get("Authorization")
|
authToken := r.Header.Get("Authorization")
|
||||||
if authToken == "" {
|
if authToken == "" {
|
||||||
|
// Process requests for unauthorized users
|
||||||
|
ui := authConfig.Load().UnauthorizedUser
|
||||||
|
if ui != nil {
|
||||||
|
processUserRequest(w, r, ui)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||||
http.Error(w, "missing `Authorization` request header", http.StatusUnauthorized)
|
http.Error(w, "missing `Authorization` request header", http.StatusUnauthorized)
|
||||||
return true
|
return true
|
||||||
|
@ -110,6 +117,12 @@ func requestHandler(w http.ResponseWriter, r *http.Request) bool {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
processUserRequest(w, r, ui)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func processUserRequest(w http.ResponseWriter, r *http.Request, ui *UserInfo) {
|
||||||
ui.requests.Inc()
|
ui.requests.Inc()
|
||||||
|
|
||||||
// Limit the concurrency of requests to backends
|
// Limit the concurrency of requests to backends
|
||||||
|
@ -119,18 +132,17 @@ func requestHandler(w http.ResponseWriter, r *http.Request) bool {
|
||||||
if err := ui.beginConcurrencyLimit(); err != nil {
|
if err := ui.beginConcurrencyLimit(); err != nil {
|
||||||
handleConcurrencyLimitError(w, r, err)
|
handleConcurrencyLimitError(w, r, err)
|
||||||
<-concurrencyLimitCh
|
<-concurrencyLimitCh
|
||||||
return true
|
return
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
concurrentRequestsLimitReached.Inc()
|
concurrentRequestsLimitReached.Inc()
|
||||||
err := fmt.Errorf("cannot serve more than -maxConcurrentRequests=%d concurrent requests", cap(concurrencyLimitCh))
|
err := fmt.Errorf("cannot serve more than -maxConcurrentRequests=%d concurrent requests", cap(concurrencyLimitCh))
|
||||||
handleConcurrencyLimitError(w, r, err)
|
handleConcurrencyLimitError(w, r, err)
|
||||||
return true
|
return
|
||||||
}
|
}
|
||||||
processRequest(w, r, ui)
|
processRequest(w, r, ui)
|
||||||
ui.endConcurrencyLimit()
|
ui.endConcurrencyLimit()
|
||||||
<-concurrencyLimitCh
|
<-concurrencyLimitCh
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func processRequest(w http.ResponseWriter, r *http.Request, ui *UserInfo) {
|
func processRequest(w http.ResponseWriter, r *http.Request, ui *UserInfo) {
|
||||||
|
|
|
@ -66,6 +66,10 @@ The following [metrics](#monitoring) related to concurrency limits are exposed b
|
||||||
- `vmauth_user_concurrent_requests_current{username="..."}` - the current number of concurrent requests for the given `username`.
|
- `vmauth_user_concurrent_requests_current{username="..."}` - the current number of concurrent requests for the given `username`.
|
||||||
- `vmauth_user_concurrent_requests_limit_reached_total{username="foo"}` - the number of requests rejected with `429 Too Many Requests` error
|
- `vmauth_user_concurrent_requests_limit_reached_total{username="foo"}` - the number of requests rejected with `429 Too Many Requests` error
|
||||||
because of the concurrency limit has been reached for the given `username`.
|
because of the concurrency limit has been reached for the given `username`.
|
||||||
|
- `vmauth_unauthorized_user_concurrent_requests_capacity` - the limit on the number of concurrent requests for unauthorized users (if `unauthorized_user` section is used).
|
||||||
|
- `vmauth_unauthorized_user_concurrent_requests_current` - the current number of concurrent requests for unauthorized users (if `unauthorized_user` section is used).
|
||||||
|
- `vmauth_unauthorized_user_concurrent_requests_limit_reached_total` - the number of requests rejected with `429 Too Many Requests` error
|
||||||
|
because of the concurrency limit has been reached for unauthorized users (if `unauthorized_user` section is used).
|
||||||
|
|
||||||
|
|
||||||
## Auth config
|
## Auth config
|
||||||
|
@ -156,6 +160,18 @@ users:
|
||||||
url_prefix: "http://vminsert:8480/insert/42/prometheus"
|
url_prefix: "http://vminsert:8480/insert/42/prometheus"
|
||||||
headers:
|
headers:
|
||||||
- "X-Scope-OrgID: abc"
|
- "X-Scope-OrgID: abc"
|
||||||
|
|
||||||
|
# This requests will be executed for requests without Authorization header.
|
||||||
|
# For instance, http://vmauth:8427/api/v1/query will be proxied to http://vmselect1:8481/select/0/prometheus/api/v1/query
|
||||||
|
unauthorized_user:
|
||||||
|
url_map:
|
||||||
|
- src_paths:
|
||||||
|
- /health
|
||||||
|
- /api/v1/query/
|
||||||
|
- /api/v1/query_range
|
||||||
|
url_prefix:
|
||||||
|
- http://vmselect1:8481/select/0/prometheus
|
||||||
|
- http://vmselect2:8481/select/0/prometheus
|
||||||
```
|
```
|
||||||
|
|
||||||
The config may contain `%{ENV_VAR}` placeholders, which are substituted by the corresponding `ENV_VAR` environment variable values.
|
The config may contain `%{ENV_VAR}` placeholders, which are substituted by the corresponding `ENV_VAR` environment variable values.
|
||||||
|
@ -198,6 +214,8 @@ users:
|
||||||
# other config options here
|
# other config options here
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For unauthorized users `vmauth` exports `vmauth_unauthorized_user_requests_total` metric without label (if `unauthorized_user` section of config is used).
|
||||||
|
|
||||||
## How to build from sources
|
## How to build from sources
|
||||||
|
|
||||||
It is recommended using [binary releases](https://github.com/VictoriaMetrics/VictoriaMetrics/releases) - `vmauth` is located in `vmutils-*` archives there.
|
It is recommended using [binary releases](https://github.com/VictoriaMetrics/VictoriaMetrics/releases) - `vmauth` is located in `vmutils-*` archives there.
|
||||||
|
|
Loading…
Reference in a new issue