-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
enhancement(http provider): Add automatic bearer token acquisition in http-client [version 2] #21583
enhancement(http provider): Add automatic bearer token acquisition in http-client [version 2] #21583
Conversation
src/http.rs
Outdated
//should request for token influence upstream service latency ? | ||
if let Some(auth_extension) = auth_extension { | ||
let auth_span = tracing::info_span!("auth_extension"); | ||
let res = auth_extension.modify_request(&mut request) |
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 had no idea how to handle this
Box<dyn Error>
to some vector friendly error better 😞
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 was able to improve it a little bit with snafu
auth_extension.modify_request(&mut request)
.instrument(auth_span.clone().or_current())
.await
.inspect_err(|error| {
// Emit the error into the internal events system.
emit!(http_client::GotAuthExtensionError{error});
})
.context(ExtensionAuthenticationSnafu)?;
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.
Hi @KowalczykBartek thank you for this contribution!
I did a quick scan of the changes and left a few comments.
src/http.rs
Outdated
pub struct HttpClientAuthorizationConfig { | ||
/// Define how to authorize against an upstream. | ||
#[configurable] | ||
auth: HttpClientAuthorizationStrategy, |
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.
Can we flatten this to avoid repetition in configs, from:
http_client_authorization_strategy:
auth:
strategy: "o_auth2"
client_id: "your.clientid"
client_secret: "verysecretstring"
token_endpoint: "https://your.provider.com/oauth/token"
to
http_client_authorization_strategy:
strategy: "o_auth2"
client_id: "your.clientid"
client_secret: "verysecretstring"
token_endpoint: "https://your.provider.com/oauth/token"
I think this makes sense from a UX perspective cc @vectordotdev/ux-team
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.
Honestly I was unable to figure out this - @pront can you pls point me some example with flattened enum ?
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 took another look at this:
- We can replace
pub http_client_authorization_strategy: Option<HttpClientAuthorizationConfig>
withpub authorization_config: Option<AuthorizationConfig>
- Rename
auth
tostrategy
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.
then config will look like this
sinks:
my_sink_id:
authorization_config:
strategy:
strategy: "o_auth2"
client_id: "some.client.id"
client_secret: "ab!@#"
grace_period: 780
token_endpoint: "https://127.0.0.1:8091/oauth/token"
is this double strategy ok ? maybe I will change also tag from
/// Configuration of the authentication strategy for HTTP requests.
///
/// HTTP authentication should be used with HTTPS only, as the authentication credentials are passed as an
/// HTTP header without any additional encryption beyond what is provided by the transport itself.
#[configurable_component]
#[derive(Clone, Debug)]
#[serde(deny_unknown_fields, rename_all = "snake_case", tag = "strategy")]
#[configurable(metadata(docs::enum_tag_description = "The authentication strategy to use."))]
to 'protocol' ? maybe 'provider' ?
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.
together with fix for mtls extension I pushed renamed struct
#[configurable(derived)]
pub authorization_config: Option<AuthorizationConfig>,
I introduced grace_period property so, it can be adjusted - before it was hard coded for 1min. I also played around this feature more and found bug around grace calculation (overflow), so also fixed this. sinks:
my_sink_id:
http_client_authorization_strategy:
auth:
strategy: "o_auth2"
client_id: "clientid"
client_secret: "secret"
grace_period: 300
token_endpoint: "https://127.0.0.1:8091/oauth/token"
tls:
crt_path: /config/cert.pem
key_file: /config/server.key what I need still to do is test against more providers (I tested with UAA, its pretty common). Hi @singhbaljit, may I ask you to check if that integration works in your env ? if there will be any required change I could make an adjustments. |
src/http.rs
Outdated
pub struct HttpClientAuthorizationConfig { | ||
/// Define how to authorize against an upstream. | ||
#[configurable] | ||
auth: HttpClientAuthorizationStrategy, |
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 took another look at this:
- We can replace
pub http_client_authorization_strategy: Option<HttpClientAuthorizationConfig>
withpub authorization_config: Option<AuthorizationConfig>
- Rename
auth
tostrategy
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.
This is starting to look great. Left a few nits, these should improve config readability.
after testing on real environments I found another issue, oauth2 + mtls should be strict to the rfc https://datatracker.ietf.org/doc/html/rfc8705, so, speaking in cURL curl --cert cert.pem --key key.pem --request POST \
--url https://something/oauth/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'grant_type=client_credentials' \
--data 'client_id=abcdabcdabcd' this is oauth2 curl --request POST \
--url https://something/oauth/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data client_secret=abcdabcdabcd \
--data grant_type=client_credentials \
--data client_id=abcdabcdabcd I also updated a comment around HttpClientAuthorizationStrategy. With those changes I think I can say: it works :) |
Thank you @KowalczykBartek, I will do another review tomorrow. |
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.
👋 Left some comments. Most of them are nits but we should get rid of the unwraps.
Also, we lack tests here. We could mock the endpoint but we can also test some internal bits separately. Please see existing tests for inspiration.
Thank you again for this contribution!
just FYI (because I see some jobs running :D ) - I will provide tests, I just need few days more :) |
Thank you @KowalczykBartek, much appreciated. Also, I wanted to share a few notes to help with the CI checks:
|
Thank you again @KowalczykBartek for this great PR. You went above and beyond 👍 I enqueued it for merging. |
Thank you @pront for support and patience :) |
One more thing here, I noticed this failure: https://github.com/vectordotdev/vector/actions/runs/11728482979/job/32672282844?pr=21583. This might be helpful:
|
hmm, generate-component-docs fail with
|
I think that means you are using Ruby 2, that script requires Ruby 3 (that should really be clearer 😓 ). |
you are right, I have ruby 2, let me try to fix this :D |
Head branch was pushed to by a user without write access
I was able to run this command,
but this this is tricky, I am not sure what this http.cue is :) It looks, good, but is it good ? not sure :) btw, last time I saw ruby was like.. 6years ago when deploying database using bosh.io (not a drills company :)) :D |
.github/workflows/semantic.yml
Outdated
@@ -29,6 +29,7 @@ jobs: | |||
revert | |||
scopes: | | |||
http |
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.
http |
This change seems to affect the http
and axiom
sinks? Could we use those pre-existing scopes instead?
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 don't know :) I did this because it was one of the review comments #21583 (comment) :)
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 thought it is worth introducing a scope since this affects a lower level module used by multiple components. But I don't really have a strong opinion here.
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.
Aha gotcha, sorry for the run-around 😅 Maybe http provider
would be more consistent? We have other x providers
already as scopes to use for lower level changes that affect multiple components that share a "provider".
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 removed this http component from list as suggested
Windows has some differences across error messages, so, I just removed error msg expectation for connection refused and internal server errors, its too much library and platform dependent |
fb9c5c1
Chiming in a bit late... this is highly appreciated! I'll certainly test this feature and report any issues I find. Thank you very much! |
many thanks @KowalczykBartek for the great work! |
PR to solve a #20635 feature request.
This change brings new section in configuration for HttpSinkConfig :
this allows to explicit define a oauth2 server which will be used to acquire bearer token (also, this request allows to bring mtls via TlsConfig),
Some basic error handling is also on place, so invalid credentials will not crash a vector instance :) you can expect an event and error message with body from oauth server (unfortunately I over engineered this error handling a little bit, I have limited rust knowledge and was unable to fully understand all patterns - so, suggestions, how to improve this would be appreciated :) )
So, as discussed in #21023 (comment) - @pront I would be grateful for review :)