-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add options to set headers on upstream http requests #154
base: main
Are you sure you want to change the base?
Add options to set headers on upstream http requests #154
Conversation
1b520e4
to
88275aa
Compare
2163b32
to
034166d
Compare
Does not seem to be alot of activity in this repo. @SuperQ could you have a look at this PR ? |
@simonpasquier are you able to look this PR ? |
injectproxy/routes.go
Outdated
@@ -262,6 +282,7 @@ func (sle StaticLabelEnforcer) ExtractLabel(next http.HandlerFunc) http.Handler | |||
} | |||
|
|||
func NewRoutes(upstream *url.URL, label string, extractLabeler ExtractLabeler, opts ...Option) (*routes, error) { | |||
//extraHttpHeaders []string, rewriteHostHeader string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to be removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed that
@@ -81,6 +83,8 @@ func main() { | |||
"This option is checked after Prometheus APIs, you cannot override enforced API endpoints to be not enforced with this option. Use carefully as it can easily cause a data leak if the provided path is an important "+ | |||
"API (like /api/v1/configuration) which isn't enforced by prom-label-proxy. NOTE: \"all\" matching paths like \"/\" or \"\" and regex are not allowed.") | |||
flagset.BoolVar(&errorOnReplace, "error-on-replace", false, "When specified, the proxy will return HTTP status code 400 if the query already contains a label matcher that differs from the one the proxy would inject.") | |||
flagset.Var(&extraHttpHeaders, "extra-http-header", "Additional HTTP headers to add to the upstream prometheus query in the format 'header: value'. Can be repeated multiple times for additional headers.") | |||
flagset.StringVar(&rewriteHostHeader, "rewrite-host-header-to", "", "Rewrite host header to supplied value when sending the query to the upstream URL.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we need a dedicated arg for the Host header or if we just handle it differently in the proxy? In the latter case, you'd do prom-label-proxy --extra-http-header "Host: foo.example.com" --extra-http-header "X-Scope-OrgID: 123"
. It would be one less argument to remember.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I lodged this PR a long time ago ... and I cannot remember if there was a valid reason for needing the separate argument/behaviour, or I just thought it was preferable to specify the simple rewrite-host-header argument than needing to know the internal mechanics and set the header manually. Regrardless - I primarily need just the extra http headers functionality to support Mimir so I am happy to resubmit this PR with just that option, and we can add the other option in a separate PR if it is required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@simonpasquier see my comment on line 293 above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So conceptually, "extra-http-headers" are user defined HTTP headers outside of the well known/mandatory headers such as host:. Thus the -extra-http-headers option only covers these headers in line with how the Go SDK handles these. Host is a specific use case of a mandatory/well known header that needs to be overridden in legitimate scenarios, so that has it's own flag. if we were to allow "Host:" to be overridden with the --extra-http-header flag, we would probably want to override all of the other mandatory http header edge cases as well, for very little or no benefit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reason to separate Host header come from lines 288-300 from routes.go
Rewrite: func(r *httputil.ProxyRequest) { | ||
r.SetURL(upstream) | ||
if opt.rewriteHostHeader == "" { | ||
r.Out.Host = r.In.Host |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I think this is the reason for the separate arguments. I do not think you can set well known mandatory headers like host using headers collection on the request, it has to be set using host property. You could technically scan for the key of "host" in the extra headers collection, then if found remove it from the collection and execute this logic .. but that feels hacky. I think the original implementation is the correct behaviour. @simonpasquier - Would you prefer I leave this as is or just remove the ability to set the host header all together ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As Host header is very specific, I think it's better to let it alone, and add some treatment (iterate all extra header and check if ...) on each query seems not very optimized
6d6e516
to
9d63218
Compare
…to prometheus Added option to set host header on upstream query to prometheus - addresses prometheus-community#135 Signed-off-by: Graeme Christie <gchristie@bunnings.com.au>
Signed-off-by: Graeme Christie <gchristie@bunnings.com.au>
Signed-off-by: Graeme Christie <gchristie@bunnings.com.au>
Signed-off-by: Graeme Christie <gchristie@bunnings.com.au>
Co-authored-by: Simon Pasquier <spasquie@redhat.com> Signed-off-by: Graeme Christie <gchristie@bunnings.com.au>
Co-authored-by: Simon Pasquier <spasquie@redhat.com> Signed-off-by: Graeme Christie <gchristie@bunnings.com.au>
Co-authored-by: Simon Pasquier <spasquie@redhat.com> Signed-off-by: Graeme Christie <gchristie@bunnings.com.au>
Co-authored-by: Simon Pasquier <spasquie@redhat.com> Signed-off-by: Graeme Christie <gchristie@bunnings.com.au>
Signed-off-by: Graeme Christie <gchristie@bunnings.com.au>
Signed-off-by: Graeme Christie <gchristie@bunnings.com.au>
9d63218
to
be913f2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All seems ok to me
I tested this on my own use case and it's working, I did'nt any issue
Rewrite: func(r *httputil.ProxyRequest) { | ||
r.SetURL(upstream) | ||
if opt.rewriteHostHeader == "" { | ||
r.Out.Host = r.In.Host |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As Host header is very specific, I think it's better to let it alone, and add some treatment (iterate all extra header and check if ...) on each query seems not very optimized
@@ -81,6 +83,8 @@ func main() { | |||
"This option is checked after Prometheus APIs, you cannot override enforced API endpoints to be not enforced with this option. Use carefully as it can easily cause a data leak if the provided path is an important "+ | |||
"API (like /api/v1/configuration) which isn't enforced by prom-label-proxy. NOTE: \"all\" matching paths like \"/\" or \"\" and regex are not allowed.") | |||
flagset.BoolVar(&errorOnReplace, "error-on-replace", false, "When specified, the proxy will return HTTP status code 400 if the query already contains a label matcher that differs from the one the proxy would inject.") | |||
flagset.Var(&extraHttpHeaders, "extra-http-header", "Additional HTTP headers to add to the upstream prometheus query in the format 'header: value'. Can be repeated multiple times for additional headers.") | |||
flagset.StringVar(&rewriteHostHeader, "rewrite-host-header-to", "", "Rewrite host header to supplied value when sending the query to the upstream URL.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reason to separate Host header come from lines 288-300 from routes.go
This PR adds the command line option extra-http-header, which facilitates setting arbitrary http headers on the upstream prometheus request. This is required to support queries to prometheus compatible endpoints like Grafana Mimir, which expect an "X-Scope-OrgID:" header in the request to specify the tenant to query the data for.
Additionally, I have added a rewrite-host-header-to parameter, which supports rewriting the host to a different value than the source request. This would be needed in the case where the upstream prometheus endpoint is an nginx proxy or simliar using host base proxying. This addresses the issue #135.