Skip to content
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 header to ease tracking HTTP requests #624

Merged
merged 7 commits into from
Feb 24, 2024
Merged

Conversation

The-9880
Copy link
Contributor

Addressing #325.

The goal is to add a header x-sm-id with a value checkId-probeId so we can identify the owner of a check for anti-abuse purposes. This header gets added tohttp.Prober.config.

Happy to hear any suggestions on how to test this Go code better - testing NewProber() from http_test.go works to assert the resulting http config directly. but it'd be nicer to have a test server or something so I can add an HTTP check to a test Updater and validate the request headers sent.

@The-9880 The-9880 requested a review from a team as a code owner February 16, 2024 00:33
@The-9880
Copy link
Contributor Author

Re: the header we're adding to HTTP request, do we think there might be a risk that some users are monitoring endpoints with strict header policies (e.g. reject requests with unexpected headers) and we could bust their SM check with this change?

Might be a contrived corner case for most SM cases but just wondering if this wants a config to disable it?

Copy link
Contributor

@ka3de ka3de left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this @The-9880 !
Overall it looks good. I made a couple of comments on whether it makes sense to move the header definition "one level up" and accept a more generic argument in the HTTP probe implementation. Let me know what do you think.

@The-9880 The-9880 requested a review from ka3de February 21, 2024 19:21
Copy link
Contributor

@mem mem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good, thanks.

I think there's some minor reorg to be made, but otherwise it's nice!

for _, header := range check.Settings.Http.Headers {
name, _ := strToHeaderNameValue(header)

_, present := reservedHeaders[strings.ToLower(name)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of strings.ToLower (which is fine in this context), you can use http.CanonicalHeaderKey

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this also means that the keys in reservedHeaders should be in canonical form, too.

@@ -114,13 +114,14 @@ func (d *probeData) Tenant() model.GlobalID {
func New(ctx context.Context, check model.Check, publisher pusher.Publisher, probe sm.Probe, logger zerolog.Logger,
scrapeCounter Incrementer, errorCounter IncrementerVec, k6runner k6runner.Runner, labelsLimiter LabelsLimiter,
) (*Scraper, error) {
checkProbeIdentifier := fmt.Sprintf("%d-%d", check.Id, probe.Id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be check.GlobalID() (so that we can identify the region that the check belongs to)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See below, I think this logic should be part of prober.proberFactory.New

return NewWithOpts(ctx, check, ScraperOpts{
Probe: probe,
Publisher: publisher,
Logger: logger,
ScrapeCounter: scrapeCounter,
ErrorCounter: errorCounter,
ProbeFactory: prober.NewProberFactory(k6runner),
ProbeFactory: prober.NewProberFactory(k6runner, checkProbeIdentifier),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to remember hard why we had to add the runner here...

... and for that matter why a new factory needs to be created for each scraper, because the factory should be the same one for all scrapers, as it's stateless.

My gut feeling is that there's an existing mistake here and we shouldn't be compounding it. It's possibly true that scraper.New should take a factory as an argument, and that factory should be initialized with the runner and the probe's ID and other global information. (but that's a change for a different issue)

I think the factory constructor (prober.NewProberFactory) might take the probe ID as an argument, because that's independent of the check, and then the created factory should be able to take the check as an argument (as it does) and build the identifier for the check based on the probe ID and the check ID. The prober.proberFactory.New basically takes the check that is passed as an argument, and it can build an identifier with the information it has for the checks that support it (Http and MultiHttp right now, but scripted checks in the future, too -- we will need to inject headers there so that HTTP connections use them).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense! Thanks for read here, I'd be happy to take a look into that issue later

}

for header, values := range reservedHeaders {
headers = append(headers, fmt.Sprintf("%s:%s", header, strings.Join(values, ",")))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that it's OK to have the same header present multiple times

If reservedHeaders has multiple values for a single key, what should be done is add the header multiple times, e.g.

for key, values := range reservedHeaders {
   var b strings.Builder
   for _, value := range values {
       b.Reset()
       b.WriteString(key)
       b.WriteRune(':')
       b.WriteString(value)
       headers = append(headers, b.String())
   }
}

Comment on lines +101 to +103
for key, values := range reservedHeaders {
updatedHeaders = append(updatedHeaders, &sm.HttpHeader{Name: key, Value: strings.Join(values, ",")})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same comment about multiple values for the headers applies here

@The-9880 The-9880 force-pushed the check-origin-header branch from 43b336b to cc22a6f Compare February 23, 2024 18:14
@The-9880 The-9880 requested a review from mem February 23, 2024 18:20
@The-9880 The-9880 merged commit 466e550 into main Feb 24, 2024
4 checks passed
@The-9880 The-9880 deleted the check-origin-header branch February 24, 2024 05:47
ka3de added a commit that referenced this pull request Feb 26, 2024
* Add an option to log multihttp responses (#550)
* Update to grafana-build-tools v0.6.0
* Chore(deps): Bump golang.org/x/net from 0.20.0 to 0.21.0
* Chore(deps): Bump github.com/rs/zerolog from 1.31.0 to 1.32.0
* Chore(deps): Bump github.com/miekg/dns from 1.1.57 to 1.1.58
* Fix: add test for HTTP check with a long URL
* Add tenant label limits (#581)
* Release v0.20.0 (#613)
* Fix global tenant id usage for label limits query
* Release v0.20.1
* Feature: promote adhoc to permanent feature (#615)
* Update release script (#617)
* Chore(deps): Bump github.com/mccutchen/go-httpbin/v2 (#618)
* Fix: missing http check regex validations (#612)
* Release v0.20.2 (#620)
* Chore(deps): Bump github.com/mccutchen/go-httpbin/v2 (#626)
* change the name of the k6 check type to scripted (#622)
* Chore(deps): Bump github.com/prometheus/client_model from 0.5.0 to 0.6.0
* Chore(deps): Bump google.golang.org/grpc from 1.61.0 to 1.61.1
* Chore(deps): Bump github.com/prometheus/common from 0.46.0 to 0.47.0
* Chore(deps): Bump github.com/prometheus/prometheus from 0.49.1 to 0.50.0
* Add header to ease tracking HTTP requests (#624)
* Add telemetry protobuf definitions (#627)

Signed-off-by: ka3de <[email protected]>
@ka3de ka3de mentioned this pull request Feb 26, 2024
ka3de added a commit that referenced this pull request Feb 26, 2024
* Add an option to log multihttp responses (#550)
* Update to grafana-build-tools v0.6.0
* Chore(deps): Bump golang.org/x/net from 0.20.0 to 0.21.0
* Chore(deps): Bump github.com/rs/zerolog from 1.31.0 to 1.32.0
* Chore(deps): Bump github.com/miekg/dns from 1.1.57 to 1.1.58
* Fix: add test for HTTP check with a long URL
* Add tenant label limits (#581)
* Release v0.20.0 (#613)
* Fix global tenant id usage for label limits query
* Release v0.20.1
* Feature: promote adhoc to permanent feature (#615)
* Update release script (#617)
* Chore(deps): Bump github.com/mccutchen/go-httpbin/v2 (#618)
* Fix: missing http check regex validations (#612)
* Release v0.20.2 (#620)
* Chore(deps): Bump github.com/mccutchen/go-httpbin/v2 (#626)
* change the name of the k6 check type to scripted (#622)
* Chore(deps): Bump github.com/prometheus/client_model from 0.5.0 to 0.6.0
* Chore(deps): Bump google.golang.org/grpc from 1.61.0 to 1.61.1
* Chore(deps): Bump github.com/prometheus/common from 0.46.0 to 0.47.0
* Chore(deps): Bump github.com/prometheus/prometheus from 0.49.1 to 0.50.0
* Add header to ease tracking HTTP requests (#624)
* Add telemetry protobuf definitions (#627)

Signed-off-by: ka3de <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants