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

Adds authorization for sidecar-promclient #4104

Closed
wants to merge 22 commits into from

Conversation

someshkoli
Copy link
Contributor

@someshkoli someshkoli commented Apr 24, 2021

  • I added CHANGELOG entry for this change.
  • Change is not relevant to the end user.

Changes

Added new flag prometheus.http-client to sidecar to pass http client config via file or string(similar to alertmanager). Using this flag an instance of thanoshttp.Client is created and is passed to promclient.NewClient method which uses this client as base client instead of whole new client which then makes authorized api calls.
The same client is passed to reloader config which then makes authorized api calls to prom api.

There are some code duplication which has been duplicated from prometheus which can be easily removed by exposing one of the functions in prometheus http_config
🙌
Close: #3975

Verification

Added a e2e test:
Checks if query is able to query when prom uses auth

@someshkoli someshkoli changed the title Feature/promclient auth Authorization for sidecar-promclient Apr 24, 2021
@someshkoli someshkoli changed the title Authorization for sidecar-promclient Adds authorization for sidecar-promclient Apr 24, 2021
@someshkoli someshkoli marked this pull request as draft April 24, 2021 12:32
@@ -212,10 +231,13 @@ func runSidecar(
}

{
// todo(someshkoli): Not sure how to properly implement RoundTripper for these properties or
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Namanl2001 please have a look at this 🤔 I guess there's no clean way to set these properties. (might need to rewrite auth for promclient or make some changes thanoshttp for custom transporter)

Copy link
Member

Choose a reason for hiding this comment

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

I think we need some 'generic' transporter that we can re-use everywhere. I had the same 'issue': https://github.com/thanos-io/thanos/pull/3970/files/e34e60e2848f2233809d67d5398151b670341ea1#diff-95c18d923c79bf32e4f8b3370d9a925aa910643559d351fab6bc307691c8f672R119

The thanoshttp has one func which is:

// NewTransport creates a new http.Transport with default settings.

I guess we could add an other function that has httpConfig as argument for re-usability in the entire project.

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 think we need some 'generic' transporter that we can re-use everywhere. I had the same 'issue': https://github.com/thanos-io/thanos/pull/3970/files/e34e60e2848f2233809d67d5398151b670341ea1#diff-95c18d923c79bf32e4f8b3370d9a925aa910643559d351fab6bc307691c8f672R119

The thanoshttp has one func which is:

// NewTransport creates a new http.Transport with default settings.

I guess we could add an other function that has httpConfig as argument for re-usability in the entire project.

Agreed, this is being used at 2-3 i guess and making a generic one can improve reusablity. @wiardvanrij I hope the overall idea in implementation is correct ? I can move forward with fixing this transporter issue ?

Copy link
Member

Choose a reason for hiding this comment

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

I'm not the right person to make a definitive review. I miss the exact technical knowledge on it. However I was at the meeting and I think you made what was discussed. Also it looks logical and makes sense.

You could always wait for a review if you think you might invest a lot of time into a feature you are unsure about. However if you have a good feeling about it, go make awesome stuff and continue 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright thanks

Copy link
Member

Choose a reason for hiding this comment

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

I think this transport and connection flags

conf.connection.maxIdleConnsPerHost
conf.connection.maxIdleConns

Are colliding with out promethues.http-config flag. The idea would be to unify those? E.g Deprecating connection flags if that makes sense? Or reusing them?

The goal is to have one way of configuring HTTP configuration.

Copy link
Member

Choose a reason for hiding this comment

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

Let's remove

--receive.connection-pool-size=RECEIVE.CONNECTION-POOL-SIZE
Controls the http MaxIdleConns. Default is 0,
which is unlimited
--receive.connection-pool-size-per-host=100

And use our prometheus flags.

"",
)
}

// NewWithTracingClient returns client with tracing tripperware.
func NewWithTracingClient(logger log.Logger, userAgent string) *Client {
func NewWithTracingClient(logger log.Logger, httpClient http.Client, userAgent string) *Client {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
func NewWithTracingClient(logger log.Logger, httpClient http.Client, userAgent string) *Client {
func NewWithTracingClient(logger log.Logger, httpClient *http.Client, userAgent string) *Client {

@@ -212,10 +231,13 @@ func runSidecar(
}

{
// todo(someshkoli): Not sure how to properly implement RoundTripper for these properties or
Copy link
Member

Choose a reason for hiding this comment

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

I think this transport and connection flags

conf.connection.maxIdleConnsPerHost
conf.connection.maxIdleConns

Are colliding with out promethues.http-config flag. The idea would be to unify those? E.g Deprecating connection flags if that makes sense? Or reusing them?

The goal is to have one way of configuring HTTP configuration.

@@ -212,10 +231,13 @@ func runSidecar(
}

{
// todo(someshkoli): Not sure how to properly implement RoundTripper for these properties or
Copy link
Member

Choose a reason for hiding this comment

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

Let's remove

--receive.connection-pool-size=RECEIVE.CONNECTION-POOL-SIZE
Controls the http MaxIdleConns. Default is 0,
which is unlimited
--receive.connection-pool-size-per-host=100

And use our prometheus flags.

pkg/http/http.go Outdated Show resolved Hide resolved
cmd/thanos/sidecar.go Outdated Show resolved Hide resolved
pkg/http/http.go Outdated Show resolved Hide resolved
@someshkoli someshkoli marked this pull request as ready for review May 3, 2021 15:38
@someshkoli
Copy link
Contributor Author

someshkoli commented May 3, 2021

This implementation helps in providing a generic way to create http clients used across. There are still many instances where directly http library is used to create client which can be replaced with thanos http client instance and can be configured flexibly.
Also solves the issue mentined by @wiardvanrij is here.

One question, while updating docs, the ruler docs got updated too because the http.ClientConfig structure was modified. Is this healthy to do ?

pkg/http/http.go Outdated
MaxIdleConnsPerHost: opts.maxIdleConnsPerHost,
DisableKeepAlives: true,
TLSClientConfig: tlsConfig,
DisableCompression: true,
Copy link
Member

Choose a reason for hiding this comment

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

I think we default to this because there was 'something with it' for Thanos side (citation needed). As this is more a generic package we should default to false and explicitly set this too true on functionalities via arguments that require this to be disabled.

Tl;dr IMO: set 'defaults' to something that would be defaults for all packages, and override different cases when needed. Not the other way around. :)

Copy link
Contributor Author

@someshkoli someshkoli May 8, 2021

Choose a reason for hiding this comment

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

I think we default to this because there was 'something with it' for Thanos side (citation needed). As this is more a generic package we should default to false and explicitly set this too true on functionalities via arguments that require this to be disabled.

Tl;dr IMO: set 'defaults' to something that would be defaults for all packages, and override different cases when needed. Not the other way around. :)

Yes Yes, sounds fair. I wonder if we can use exthttp.NewTransport here and then override them with help of options 🤔 ?

Copy link
Member

Choose a reason for hiding this comment

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

We can, but we need to be aware who is using exthttp.NewTransport and how

Copy link
Member

@bwplotka bwplotka left a comment

Choose a reason for hiding this comment

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

Don't have time to review fully, but did part of it, looks good generally, some nits.

cmd/thanos/config.go Show resolved Hide resolved
pkg/http/http.go Outdated
"gopkg.in/yaml.v2"

"github.com/thanos-io/thanos/pkg/discovery/cache"
)

var defaultHTTPClientOptions = httpClientOptions{
maxIdleConns: 0,
Copy link
Member

Choose a reason for hiding this comment

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

0 feels wrong, see default Go impl:

// DefaultTransport is the default implementation of Transport and is
// used by DefaultClient. It establishes network connections as needed
// and caches them for reuse by subsequent calls. It uses HTTP proxies
// as directed by the $HTTP_PROXY and $NO_PROXY (or $http_proxy and
// $no_proxy) environment variables.
var DefaultTransport RoundTripper = &Transport{
	Proxy: ProxyFromEnvironment,
	DialContext: (&net.Dialer{
		Timeout:   30 * time.Second,
		KeepAlive: 30 * time.Second,
		DualStack: true,
	}).DialContext,
	ForceAttemptHTTP2:     true,
	MaxIdleConns:          100,
	IdleConnTimeout:       90 * time.Second,
	TLSHandshakeTimeout:   10 * time.Second,
	ExpectContinueTimeout: 1 * time.Second,
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

0 feels wrong, see default Go impl:

// DefaultTransport is the default implementation of Transport and is
// used by DefaultClient. It establishes network connections as needed
// and caches them for reuse by subsequent calls. It uses HTTP proxies
// as directed by the $HTTP_PROXY and $NO_PROXY (or $http_proxy and
// $no_proxy) environment variables.
var DefaultTransport RoundTripper = &Transport{
	Proxy: ProxyFromEnvironment,
	DialContext: (&net.Dialer{
		Timeout:   30 * time.Second,
		KeepAlive: 30 * time.Second,
		DualStack: true,
	}).DialContext,
	ForceAttemptHTTP2:     true,
	MaxIdleConns:          100,
	IdleConnTimeout:       90 * time.Second,
	TLSHandshakeTimeout:   10 * time.Second,
	ExpectContinueTimeout: 1 * time.Second,
}

Yes right

pkg/http/http.go Outdated
"gopkg.in/yaml.v2"

"github.com/thanos-io/thanos/pkg/discovery/cache"
)

var defaultHTTPClientOptions = httpClientOptions{
maxIdleConns: 0,
maxIdleConnsPerHost: 100, // see https://github.com/golang/go/issues/13801
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
maxIdleConnsPerHost: 100, // see https://github.com/golang/go/issues/13801
maxIdleConnsPerHost: 100, // See https://github.com/golang/go/issues/13801.

pkg/http/http.go Outdated
MaxIdleConnsPerHost: opts.maxIdleConnsPerHost,
DisableKeepAlives: true,
TLSClientConfig: tlsConfig,
DisableCompression: true,
Copy link
Member

Choose a reason for hiding this comment

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

We can, but we need to be aware who is using exthttp.NewTransport and how

pkg/http/http.go Outdated
client, err := config_util.NewClientFromConfig(httpClientConfig, name, config_util.WithHTTP2Disabled())
// see https://github.com/golang/go/issues/13801
if cfg.MaxIdleConns == 0 {
cfg.MaxIdleConns = 20000
Copy link
Member

Choose a reason for hiding this comment

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

I don't get it, why we don't use default? Also 0 means no limit, so 0 has meaning too, we should tolerate such option

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 don't get it, why we don't use default? Also 0 means no limit, so 0 has meaning too, we should tolerate such option

Actually, this value is picked from prometheus http which we were using before, so thought it would be better to keep it the same. Also yeah 0 does for this is acceptable, 'll fix it.

pkg/http/http.go Outdated
@@ -95,10 +212,23 @@ func NewHTTPClient(cfg ClientConfig, name string) (*http.Client, error) {
return nil, err
}

client, err := config_util.NewClientFromConfig(httpClientConfig, name, config_util.WithHTTP2Disabled())
// see https://github.com/golang/go/issues/13801
Copy link
Member

Choose a reason for hiding this comment

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

Weird haging comment (and not full sentence), can we remove it?

pkg/http/http.go Outdated
cfg.MaxIdleConns = 20000
}
if cfg.MaxIdleConnsPerHost == 0 {
cfg.MaxIdleConnsPerHost = 1000
Copy link
Member

Choose a reason for hiding this comment

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

Why those numbers?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Again from prometheus implementation.

pkg/http/http.go Show resolved Hide resolved
pkg/http/http.go Outdated
@@ -262,3 +392,151 @@ func (c *Client) Discover(ctx context.Context) {
func (c *Client) Resolve(ctx context.Context) error {
return c.provider.Resolve(ctx, append(c.fileSDCache.Addresses(), c.staticAddresses...))
}

// Duplicated from github.com/prometheus/common/config
// better option would be to expose config_util.newTLSRoundTripper function from prometheus
Copy link
Member

Choose a reason for hiding this comment

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

Yes, can we do that (you can contribute there, we are happy to review and merge it there)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great, I'll raise a PR there

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

@bwplotka bwplotka left a comment

Choose a reason for hiding this comment

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

LGTM generally, just small nits. Thanks.

cmd/thanos/sidecar.go Show resolved Hide resolved
pkg/http/http.go Show resolved Hide resolved
if err := httpClientConfig.Validate(); err != nil {
return nil, err
}

client, err := config_util.NewClientFromConfig(httpClientConfig, name, config_util.WithHTTP2Disabled())
Copy link
Member

Choose a reason for hiding this comment

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

Can we still use it? and append middleware we want on top?

func NewPrometheusAndSidecarWithBasicAuth(sharedDir string, netName string, name string, promConfig, webConfig, promImage string) (*e2e.HTTPService, *Service, error) {
dir := filepath.Join(sharedDir, "data", "prometheus", name)
container := filepath.Join(e2e.ContainerSharedDir, "data", "prometheus", name)
if err := os.MkdirAll(dir, 0777); err != nil {
Copy link

Choose a reason for hiding this comment

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

G301: Expect directory permissions to be 0750 or less
(at-me in a reply with help or ignore)

return nil, nil, errors.Wrap(err, "create prometheus dir")
}

if err := ioutil.WriteFile(filepath.Join(dir, "prometheus.yml"), []byte(promConfig), 0666); err != nil {
Copy link

Choose a reason for hiding this comment

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

G306: Expect WriteFile permissions to be 0600 or less
(at-me in a reply with help or ignore)

@bwplotka
Copy link
Member

Any update on this?

@someshkoli
Copy link
Contributor Author

someshkoli commented Jun 17, 2021

Any update on this?

Its ready for a review, I guess I forgot to put a review request :)

@yeya24
Copy link
Contributor

yeya24 commented Jun 26, 2021

@someshkoli Can you rebase on main and fix the conflicts? Thank you!

Added http-client flag to sidecar which takes yaml file or string as
input
Passed auth client to prom client to build new prom client instead of
using default http client

todo: check if this is the proper way to implement this
 - can we reuse thanoshttp for auth
 - if yes then how to add maxidelconns and maxidleconnsperhost
   properties to http client returned by thanoshttp.NewHTTPClient

Signed-off-by: someshkoli <[email protected]>
Signed-off-by: someshkoli <[email protected]>
merged maxidleconns flag to http-config
added additinal properties to ClientConfig

Signed-off-by: someshkoli <[email protected]>
Defines default TransportConfig and uses the same for yaml unmarshalling
Adds checks for bearer token auth

Signed-off-by: someshkoli <[email protected]>
Signed-off-by: someshkoli <[email protected]>
Signed-off-by: someshkoli <[email protected]>
Signed-off-by: someshkoli <[email protected]>
Signed-off-by: someshkoli <[email protected]>
Signed-off-by: someshkoli <[email protected]>
func NewPrometheusAndSidecarWithBasicAuth(sharedDir string, netName string, name string, promConfig, webConfig, promImage string) (*e2e.HTTPService, *Service, error) {
dir := filepath.Join(sharedDir, "data", "prometheus", name)
container := filepath.Join(e2e.ContainerSharedDir, "data", "prometheus", name)
if err := os.MkdirAll(dir, 0777); err != nil {
Copy link

Choose a reason for hiding this comment

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

G301: Expect directory permissions to be 0750 or less
(at-me in a reply with help or ignore)

return nil, nil, errors.Wrap(err, "create prometheus dir")
}

if err := ioutil.WriteFile(filepath.Join(dir, "prometheus.yml"), []byte(promConfig), 0666); err != nil {
Copy link

Choose a reason for hiding this comment

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

G306: Expect WriteFile permissions to be 0600 or less
(at-me in a reply with help or ignore)

@yeya24
Copy link
Contributor

yeya24 commented Aug 5, 2021

Hi, @someshkoli, sorry for the late reply. Can you fix the conflict and get CI passing? Your work is really amazing and we really want to have this feature!

@someshkoli
Copy link
Contributor Author

Hi, @someshkoli, sorry for the late reply. Can you fix the conflict and get CI passing? Your work is really amazing and we really want to have this feature!

will update it soon, have a lot to rebase :")

…s into feature/promclient-auth

Signed-off-by: someshkoli <[email protected]>
Signed-off-by: someshkoli <[email protected]>
Signed-off-by: someshkoli <[email protected]>
someshkoli added a commit to someshkoli/thanos that referenced this pull request Aug 30, 2021
Signed-off-by: someshkoli <[email protected]>
@someshkoli
Copy link
Contributor Author

someshkoli commented Aug 30, 2021

@yeya24 Moving this to #4612

@someshkoli
Copy link
Contributor Author

@yeya24 can you please take a look at #4612 ?

@yeya24
Copy link
Contributor

yeya24 commented Nov 8, 2021

Close in favor of #4612

@yeya24 yeya24 closed this Nov 8, 2021
yeya24 pushed a commit that referenced this pull request Nov 9, 2021
* pull work from #4104

Signed-off-by: someshkoli <[email protected]>

* update docs

Signed-off-by: someshkoli <[email protected]>

* fix fs perms

Signed-off-by: someshkoli <[email protected]>

* remove flags from exthttp, make prom http config configurable,

Signed-off-by: someshkoli <[email protected]>

* typo fix

Signed-off-by: someshkoli <[email protected]>

* adds method to set http client to realoder

Signed-off-by: someshkoli <[email protected]>

* Merge branch 'main' into feature/promclient-authorization

Signed-off-by: Ben Ye <[email protected]>

* fix format

Signed-off-by: Ben Ye <[email protected]>

* fix e2e

Signed-off-by: Ben Ye <[email protected]>

* fix prom e2e test

Signed-off-by: Ben Ye <[email protected]>

* update changelog

Signed-off-by: Ben Ye <[email protected]>

* update dependency

Signed-off-by: Ben Ye <[email protected]>

Co-authored-by: Ben Ye <[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.

sidecar support https and basic auth access to Prometheus
4 participants