Skip to content

Use common HTTPClientConfig for marathon_sd configuration#4009

Merged
brian-brazil merged 11 commits intoprometheus:masterfrom
plaflamme:marathon-http-client
Apr 5, 2018
Merged

Use common HTTPClientConfig for marathon_sd configuration#4009
brian-brazil merged 11 commits intoprometheus:masterfrom
plaflamme:marathon-http-client

Conversation

@plaflamme
Copy link
Contributor

This adds support for basic authentication which closes #3090

The support for specifying the client timeout was removed as discussed in prometheus/common#123. Marathon was the only sd mechanism doing this and configuring the timeout is done through Context.

@brian-brazil @fabxc this is another take on adding support for basic auth to marathon SD through the use of the standard HTTPClientConfig as mentioned in #3238

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think it's a good idea to override the behaviour of the common HTTP client, bearer token should mean bearer token. If there's a bespoke auth method that some SD uses I think it should have different configuration field names to avoid confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, that's reasonable. The DC/OS documentation uses the term "authentication token". So Perhaps auth_token / auth_token_file?

How should backwards compatibility be handled (because this is currently supported through the standard property names)?

  • no backwards compatibility, users will have to rename the configuration properties
  • support both the old and new property names and log a warning
  • ?

Copy link
Contributor

Choose a reason for hiding this comment

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

How should backwards compatibility be handled (because this is currently supported through the standard property names)?

Is basic auth supported by Marathon natively? I didn't see it in the docs, so the things to do might be to leave things as-is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Marathon itself only supports basic authentication as per its documentation here. Marathon deployed as part of DC/OS only supports token-based authentication (as you noticed in the other documentation).

So arguably, it is the token-based authentication that should be dropped from marathon_sd. I wouldn't suggest doing that, since that would break existing functionality and leave no workaround.

Another complication is that the DC/OS documentation says they will eventually support the Bearer authorization header. This would also be supported with this PR, but it also means that we cannot easily be backwards compatible and future compatible with a new DC/OS version.

Perhaps this PR is the best way to go forward?

  • supports basic auth for marathon itself
  • supports token-based authentication for DC/OS
  • supports future Bearer authentication for DC/OS

Existing DC/OS users will have to rename their configuration properties from bearer_token to auth_token when deploying the new version. Not doing so will simply fail authenticating...

Copy link
Contributor

Choose a reason for hiding this comment

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

That does seem like the best approach overall, even if it does involve a breaking change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good.

Is there anything else required to move this forward? Should this log a warning of some sort when bearer_token is set? Should I also make the changes to the documentation?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see a need for a warning. Docs should be updated in the same PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added 2 commits:

  • one that updates the documentation and updates configuration validation accordingly
  • another that updates CHANGELOG.md to document the breaking change

I'm not 100% sure what the process is around CHANGELOG.md, I can drop that commit if you prefer.

@plaflamme plaflamme force-pushed the marathon-http-client branch from cb5729d to 0538ff4 Compare March 25, 2018 20:35
This adds support for basic authentication which closes prometheus#3090

The support for specifying the client timeout was removed as discussed in prometheus/common#123. Marathon was the only sd mechanism doing this and configuring the timeout is done through `Context`.
…cation.

DC/OS uses a custom `Authorization` header for authenticating. This adds 2 new configuration properties to reflect this.

Existing configuration files that use the bearer token will no longer work. More work is required to make this backwards compatible.
@plaflamme plaflamme force-pushed the marathon-http-client branch from 0538ff4 to b90e216 Compare March 25, 2018 20:43
@plaflamme
Copy link
Contributor Author

@brian-brazil I've added a commit to address your concern. Marathon SD now uses custom configuration properties to configure the token-based authentication mechanism.

I also adjusted the original commit which was broken and failing tests.

Please let me know how backwards compatibility should be handled.

CHANGELOG.md Outdated
@@ -1,3 +1,8 @@
## next release

* [CHANGE] `marathon_sd`: (**breaking**) use `auth_token` and `auth_token_file` for token-based authentication instead of `bearer_token` and `bearer_token_file` respectively.
Copy link
Contributor

Choose a reason for hiding this comment

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

CHANGES by definition are breaking, so no need to have the breaking.

CHANGELOG.md Outdated
## next release

* [CHANGE] `marathon_sd`: (**breaking**) use `auth_token` and `auth_token_file` for token-based authentication instead of `bearer_token` and `bearer_token_file` respectively.
* [ENHANCEMENT] `marathon_sd`: adds support for basic authentication.
Copy link
Contributor

Choose a reason for hiding this comment

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

basic and bearer, plus all the other option the common http client provides

}
if len(c.BearerToken) > 0 && len(c.BearerTokenFile) > 0 {
return fmt.Errorf("at most one of bearer_token & bearer_token_file must be configured")
if len(c.AuthToken) > 0 && len(c.AuthTokenFile) > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should have unittests for these, see where we test bad configs already.

bf, err := ioutil.ReadFile(conf.BearerTokenFile)
authToken := conf.AuthToken
if len(authToken) == 0 && len(conf.AuthTokenFile) > 0 {
b, err := ioutil.ReadFile(conf.AuthTokenFile)
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs to be read on every request.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For this part, I did the same as what the http client does for the bearer_token_file configuration property here which doesn't seem to read the file on every request.

Perhaps I am mis-reading that code somehow? Or perhaps that change is in the works? I can certainly give it a stab if you feel strongly about supporting this now.

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, ok, I looked at the wrong http client. Alrighty, I'll take a stab at implementing this.

Copy link
Contributor

Choose a reason for hiding this comment

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

You're looking at the right one, it needs fixing.

Copy link
Contributor Author

@plaflamme plaflamme Mar 30, 2018

Choose a reason for hiding this comment

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

I may need a bit of guidance on this one. The approach I'm considering is to create a AuthTokenRoundTripper and then use that to wrap the RoundTripper that httputil creates. But to put that new rt on the client, I see 2 approaches:

  • create client using NewClientFromConfig and then override its RoundTripper member
  • create NewHTTPRoundTripperFromConfig in httputil (which is basically NewClientFromConfig minus the call to newClient)

Mutating the client seems like a bad idea to me, but it makes the change entirely local to marathon.go which perhaps is what we want in this case, I'm not sure.

Perhaps there's an alternative approach that you might suggest?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I took the second approach in 2a0e760 and 904902e. Please let me know if that's okay.

// According to https://dcos.io/docs/1.8/administration/id-and-access-mgt/managing-authentication
// According to https://docs.mesosphere.com/1.11/security/oss/managing-authentication/
// DC/OS wants with "token=" a different Authorization header than implemented in httputil/client.go
// so we set this implicitly here
Copy link
Contributor

Choose a reason for hiding this comment

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

explicitly


# Sets the `Authorization` header on every request with the
# configured username and password.
# This is mutually exclusive from other authentication mechanisms.
Copy link
Contributor

Choose a reason for hiding this comment

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

s/from/with/


# Sets the `Authorization` header on every request with
# the configured bearer token. It is mutually exclusive with `bearer_token_file` and other authentication mechanisms.
# NOTE: At this time, DC/OS marathon does not support standard Bearer token authentication. Use `auth_token` instead.
Copy link
Contributor

Choose a reason for hiding this comment

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

Mention a version number so this doesn't go stale

Also be more explicit about what new features are brought in by using the common HTTP client.
This delegates the handling of the `Authorization` header to the `http.RoundTripper`. This allows reading the `auth_token_file` on every request as well as isolating authentication in the http client itself (no need to pass the authentication token around).
@plaflamme
Copy link
Contributor Author

The travis-ci build failure looks like a flake in the k8s tests. Is there anything that I should do about that?

rt http.RoundTripper
}

// newAuthTokenRoundTripper adds the provided auth token to a request
Copy link
Contributor

Choose a reason for hiding this comment

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

Comments should end with a full stop.

@brian-brazil
Copy link
Contributor

You've got conflicts

@plaflamme
Copy link
Contributor Author

@brian-brazil resolved

@brian-brazil brian-brazil merged commit 2aba238 into prometheus:master Apr 5, 2018
@brian-brazil
Copy link
Contributor

Thanks!

gouthamve pushed a commit to gouthamve/prometheus that referenced this pull request Aug 1, 2018
…#4009)

This adds support for basic authentication which closes prometheus#3090

The support for specifying the client timeout was removed as discussed in prometheus/common#123. Marathon was the only sd mechanism doing this and configuring the timeout is done through `Context`.

DC/OS uses a custom `Authorization` header for authenticating. This adds 2 new configuration properties to reflect this.

Existing configuration files that use the bearer token will no longer work. More work is required to make this backwards compatible.
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.

basic_auth support in marathon_sd_config

2 participants