From 6089a11072c63cc1d1344d48556aff02e4f04a8b Mon Sep 17 00:00:00 2001 From: Benedikt Bongartz Date: Tue, 20 Sep 2022 11:21:37 +0200 Subject: [PATCH 1/9] [extension/bearertokenauthextension] support reading tokens from file This commit extends the bearer token extension by the possibility to read tokens from a file. Signed-off-by: Benedikt Bongartz --- extension/bearertokenauthextension/README.md | 15 ++- .../bearertokenauth.go | 93 +++++++++++++++++-- .../bearertokenauth_test.go | 51 ++++++++++ extension/bearertokenauthextension/config.go | 3 + extension/bearertokenauthextension/go.mod | 2 +- extension/bearertokenauthextension/test.token | 1 + 6 files changed, 153 insertions(+), 12 deletions(-) create mode 100644 extension/bearertokenauthextension/test.token diff --git a/extension/bearertokenauthextension/README.md b/extension/bearertokenauthextension/README.md index 8cb9db1e055b..ea2968225359 100644 --- a/extension/bearertokenauthextension/README.md +++ b/extension/bearertokenauthextension/README.md @@ -13,19 +13,26 @@ The authenticator type has to be set to `bearertokenauth`. ## Configuration -The following is the only setting and is required: +One of the following two options is required. If a token **and** a tokenfile are specified, the token is **ignored**: - `token`: static authorization token that needs to be sent on every gRPC client call as metadata. This token is prepended by "Bearer " before being sent as a value of "authorization" key in RPC metadata. - - **Note**: bearertokenauth requires transport layer security enabled on the exporter. + +- `tokenfile`: filename of file that contains a authorization token that needs to be sent on every + gRPC client call as metadata. + This token is prepended by "Bearer " before being sent as a value of "authorization" key in + RPC metadata. + + +**Note**: bearertokenauth requires transport layer security enabled on the exporter. ```yaml extensions: bearertokenauth: token: "somerandomtoken" + token_filename: "file-containing.token" receivers: hostmetrics: @@ -58,4 +65,4 @@ service: [beta]:https://github.com/open-telemetry/opentelemetry-collector#beta -[contrib]:https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib \ No newline at end of file +[contrib]:https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/bearertokenauthextension/bearertokenauth.go b/extension/bearertokenauthextension/bearertokenauth.go index 44710ec65c23..46be69cde96a 100644 --- a/extension/bearertokenauthextension/bearertokenauth.go +++ b/extension/bearertokenauthextension/bearertokenauth.go @@ -18,7 +18,10 @@ import ( "context" "fmt" "net/http" + "os" + "sync" + "github.com/fsnotify/fsnotify" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configauth" "go.uber.org/zap" @@ -44,26 +47,99 @@ func (c *PerRPCAuth) RequireTransportSecurity() bool { // BearerTokenAuth is an implementation of configauth.GRPCClientAuthenticator. It embeds a static authorization "bearer" token in every rpc call. type BearerTokenAuth struct { - tokenString string - logger *zap.Logger + muTokenString sync.RWMutex + tokenString string + + shutdownCH chan struct{} + + tokenFilename string + logger *zap.Logger } var _ configauth.ClientAuthenticator = (*BearerTokenAuth)(nil) func newBearerTokenAuth(cfg *Config, logger *zap.Logger) *BearerTokenAuth { + if cfg.BearerTokenFilename != "" && cfg.BearerToken != "" { + logger.Warn("a filename is specified. Configured token is ignored!") + } return &BearerTokenAuth{ - tokenString: cfg.BearerToken, - logger: logger, + tokenString: cfg.BearerToken, + tokenFilename: cfg.BearerTokenFilename, + logger: logger, } } -// Start of BearerTokenAuth does nothing and returns nil +// Start of BearerTokenAuth does nothing and returns nil if no tokenFilename +// is specified. Otherwise a routine is started to monitor the file containing +// the token to be transferred. func (b *BearerTokenAuth) Start(ctx context.Context, host component.Host) error { - return nil + if b.tokenFilename == "" { + return nil + } + + if b.shutdownCH != nil { + return fmt.Errorf("bearerToken file monitoring is already running") + } + + // Read file once + tokenStr, err := os.ReadFile(b.tokenFilename) + if err != nil { + return err + } + b.muTokenString.Lock() + b.tokenString = string(tokenStr) + b.muTokenString.Unlock() + + b.shutdownCH = make(chan struct{}) + + watcher, err := fsnotify.NewWatcher() + if err != nil { + return err + } + + // start file watcher + go func(ctx context.Context) { + defer watcher.Close() + for { + select { + case _, ok := <-b.shutdownCH: + _ = ok + return + case <-ctx.Done(): + return + case event, ok := <-watcher.Events: + if !ok { + continue + } + if event.Op == fsnotify.Write { + token, err := os.ReadFile(b.tokenFilename) + if err != nil { + b.logger.Error(err.Error()) + continue + } + b.muTokenString.Lock() + b.tokenString = string(token) + b.muTokenString.Unlock() + } + } + } + }(ctx) + + return watcher.Add(b.tokenFilename) } // Shutdown of BearerTokenAuth does nothing and returns nil func (b *BearerTokenAuth) Shutdown(ctx context.Context) error { + if b.tokenFilename == "" { + return nil + } + + if b.shutdownCH == nil { + return fmt.Errorf("bearerToken file monitoring is not running") + } + b.shutdownCH <- struct{}{} + close(b.shutdownCH) + b.shutdownCH = nil return nil } @@ -75,7 +151,10 @@ func (b *BearerTokenAuth) PerRPCCredentials() (credentials.PerRPCCredentials, er } func (b *BearerTokenAuth) bearerToken() string { - return fmt.Sprintf("Bearer %s", b.tokenString) + b.muTokenString.RLock() + token := fmt.Sprintf("Bearer %s", b.tokenString) + b.muTokenString.RUnlock() + return token } // RoundTripper is not implemented by BearerTokenAuth diff --git a/extension/bearertokenauthextension/bearertokenauth_test.go b/extension/bearertokenauthextension/bearertokenauth_test.go index 99859225b153..83b38b46feb0 100644 --- a/extension/bearertokenauthextension/bearertokenauth_test.go +++ b/extension/bearertokenauthextension/bearertokenauth_test.go @@ -18,7 +18,9 @@ import ( "context" "fmt" "net/http" + "os" "testing" + "time" "github.com/stretchr/testify/assert" "go.opentelemetry.io/collector/component/componenttest" @@ -104,3 +106,52 @@ func TestBearerAuthenticator(t *testing.T) { assert.Equal(t, expectedHeaders, resp.Header) assert.Nil(t, bauth.Shutdown(context.Background())) } + +func TestBearerStartWatchStop(t *testing.T) { + cfg := createDefaultConfig().(*Config) + cfg.BearerTokenFilename = "test.token" + + bauth := newBearerTokenAuth(cfg, nil) + assert.NotNil(t, bauth) + + assert.Nil(t, bauth.Start(context.Background(), componenttest.NewNopHost())) + assert.Error(t, bauth.Start(context.Background(), componenttest.NewNopHost())) + + credential, err := bauth.PerRPCCredentials() + assert.NoError(t, err) + assert.NotNil(t, credential) + + token, err := os.ReadFile(bauth.tokenFilename) + assert.NoError(t, err) + + tokenStr := fmt.Sprintf("Bearer %s", token) + md, err := credential.GetRequestMetadata(context.Background()) + expectedMd := map[string]string{ + "authorization": tokenStr, + } + assert.Equal(t, md, expectedMd) + assert.NoError(t, err) + assert.True(t, credential.RequireTransportSecurity()) + + // change file content once + assert.Nil(t, os.WriteFile(bauth.tokenFilename, []byte(fmt.Sprintf("%stest", token)), 0600)) + time.Sleep(5 * time.Second) + credential, _ = bauth.PerRPCCredentials() + md, err = credential.GetRequestMetadata(context.Background()) + expectedMd["authorization"] = tokenStr + "test" + assert.Equal(t, md, expectedMd) + assert.NoError(t, err) + + // change file content back + assert.Nil(t, os.WriteFile(bauth.tokenFilename, token, 0600)) + time.Sleep(5 * time.Second) + credential, _ = bauth.PerRPCCredentials() + md, err = credential.GetRequestMetadata(context.Background()) + expectedMd["authorization"] = tokenStr + time.Sleep(5 * time.Second) + assert.Equal(t, md, expectedMd) + assert.NoError(t, err) + + assert.Nil(t, bauth.Shutdown(context.Background())) + assert.Nil(t, bauth.shutdownCH) +} diff --git a/extension/bearertokenauthextension/config.go b/extension/bearertokenauthextension/config.go index 4c9178d57ce8..19cedbdb6fef 100644 --- a/extension/bearertokenauthextension/config.go +++ b/extension/bearertokenauthextension/config.go @@ -26,6 +26,9 @@ type Config struct { // BearerToken specifies the bearer token to use for every RPC. BearerToken string `mapstructure:"token,omitempty"` + + // BearerTokenFile points to a file that contains the bearer token to use for every RPC. + BearerTokenFilename string `mapstructure:"tokenfile,omitempty"` } var _ config.Extension = (*Config)(nil) diff --git a/extension/bearertokenauthextension/go.mod b/extension/bearertokenauthextension/go.mod index 000080b21761..ceb38bc3738a 100644 --- a/extension/bearertokenauthextension/go.mod +++ b/extension/bearertokenauthextension/go.mod @@ -3,6 +3,7 @@ module github.com/open-telemetry/opentelemetry-collector-contrib/extension/beare go 1.18 require ( + github.com/fsnotify/fsnotify v1.5.4 github.com/stretchr/testify v1.8.0 go.opentelemetry.io/collector v0.60.1-0.20220916163348-84621e483dfb go.uber.org/zap v1.23.0 @@ -11,7 +12,6 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/json-iterator/go v1.1.12 // indirect diff --git a/extension/bearertokenauthextension/test.token b/extension/bearertokenauthextension/test.token new file mode 100644 index 000000000000..92ff978b0bf6 --- /dev/null +++ b/extension/bearertokenauthextension/test.token @@ -0,0 +1 @@ +eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...+file+ From 8545df299d8bf44335c5e6245f376e6f31cb52f1 Mon Sep 17 00:00:00 2001 From: Benedikt Bongartz Date: Tue, 20 Sep 2022 11:48:03 +0200 Subject: [PATCH 2/9] [extension/bearertokenauthextension] add changelog entry Signed-off-by: Benedikt Bongartz --- ...kenauthextension_support_token_from_file.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100755 unreleased/bearertokenauthextension_support_token_from_file.yaml diff --git a/unreleased/bearertokenauthextension_support_token_from_file.yaml b/unreleased/bearertokenauthextension_support_token_from_file.yaml new file mode 100755 index 000000000000..f2bf1ea57ca5 --- /dev/null +++ b/unreleased/bearertokenauthextension_support_token_from_file.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: bearertokenauthextension + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: support reading tokens from file + +# One or more tracking issues related to the change +issues: [14325] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: From ef05370eaadd6a144ccacdf81316918da9be838a Mon Sep 17 00:00:00 2001 From: Benedikt Bongartz Date: Tue, 27 Sep 2022 11:03:00 +0200 Subject: [PATCH 3/9] [extension/bearertokenauthextension] split filewatcher functionality Signed-off-by: Benedikt Bongartz --- .../bearertokenauth.go | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/extension/bearertokenauthextension/bearertokenauth.go b/extension/bearertokenauthextension/bearertokenauth.go index 46be69cde96a..27622425bc83 100644 --- a/extension/bearertokenauthextension/bearertokenauth.go +++ b/extension/bearertokenauthextension/bearertokenauth.go @@ -96,36 +96,37 @@ func (b *BearerTokenAuth) Start(ctx context.Context, host component.Host) error if err != nil { return err } - // start file watcher - go func(ctx context.Context) { - defer watcher.Close() - for { - select { - case _, ok := <-b.shutdownCH: - _ = ok - return - case <-ctx.Done(): - return - case event, ok := <-watcher.Events: - if !ok { + go b.startWatcher(ctx, watcher) + + return watcher.Add(b.tokenFilename) +} + +func (b *BearerTokenAuth) startWatcher(ctx context.Context, watcher *fsnotify.Watcher) { + defer watcher.Close() + for { + select { + case _, ok := <-b.shutdownCH: + _ = ok + return + case <-ctx.Done(): + return + case event, ok := <-watcher.Events: + if !ok { + continue + } + if event.Op == fsnotify.Write { + token, err := os.ReadFile(b.tokenFilename) + if err != nil { + b.logger.Error(err.Error()) continue } - if event.Op == fsnotify.Write { - token, err := os.ReadFile(b.tokenFilename) - if err != nil { - b.logger.Error(err.Error()) - continue - } - b.muTokenString.Lock() - b.tokenString = string(token) - b.muTokenString.Unlock() - } + b.muTokenString.Lock() + b.tokenString = string(token) + b.muTokenString.Unlock() } } - }(ctx) - - return watcher.Add(b.tokenFilename) + } } // Shutdown of BearerTokenAuth does nothing and returns nil From 195932a261d7e1fda96cdbbac38977069a592208 Mon Sep 17 00:00:00 2001 From: Benedikt Bongartz Date: Wed, 28 Sep 2022 13:48:24 +0200 Subject: [PATCH 4/9] [extension/bearertokenauthextension] rename token filename variable Signed-off-by: Benedikt Bongartz --- extension/bearertokenauthextension/README.md | 4 ++-- .../bearertokenauth.go | 24 +++++++++---------- .../bearertokenauth_test.go | 8 +++---- extension/bearertokenauthextension/config.go | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/extension/bearertokenauthextension/README.md b/extension/bearertokenauthextension/README.md index ea2968225359..aa0eb5c81c1e 100644 --- a/extension/bearertokenauthextension/README.md +++ b/extension/bearertokenauthextension/README.md @@ -19,7 +19,7 @@ One of the following two options is required. If a token **and** a tokenfile are This token is prepended by "Bearer " before being sent as a value of "authorization" key in RPC metadata. -- `tokenfile`: filename of file that contains a authorization token that needs to be sent on every +- `filename`: filename of file that contains a authorization token that needs to be sent on every gRPC client call as metadata. This token is prepended by "Bearer " before being sent as a value of "authorization" key in RPC metadata. @@ -32,7 +32,7 @@ One of the following two options is required. If a token **and** a tokenfile are extensions: bearertokenauth: token: "somerandomtoken" - token_filename: "file-containing.token" + filename: "file-containing.token" receivers: hostmetrics: diff --git a/extension/bearertokenauthextension/bearertokenauth.go b/extension/bearertokenauthextension/bearertokenauth.go index 27622425bc83..5556a72e04eb 100644 --- a/extension/bearertokenauthextension/bearertokenauth.go +++ b/extension/bearertokenauthextension/bearertokenauth.go @@ -52,28 +52,28 @@ type BearerTokenAuth struct { shutdownCH chan struct{} - tokenFilename string - logger *zap.Logger + filename string + logger *zap.Logger } var _ configauth.ClientAuthenticator = (*BearerTokenAuth)(nil) func newBearerTokenAuth(cfg *Config, logger *zap.Logger) *BearerTokenAuth { - if cfg.BearerTokenFilename != "" && cfg.BearerToken != "" { + if cfg.Filename != "" && cfg.BearerToken != "" { logger.Warn("a filename is specified. Configured token is ignored!") } return &BearerTokenAuth{ - tokenString: cfg.BearerToken, - tokenFilename: cfg.BearerTokenFilename, - logger: logger, + tokenString: cfg.BearerToken, + filename: cfg.Filename, + logger: logger, } } -// Start of BearerTokenAuth does nothing and returns nil if no tokenFilename +// Start of BearerTokenAuth does nothing and returns nil if no filename // is specified. Otherwise a routine is started to monitor the file containing // the token to be transferred. func (b *BearerTokenAuth) Start(ctx context.Context, host component.Host) error { - if b.tokenFilename == "" { + if b.filename == "" { return nil } @@ -82,7 +82,7 @@ func (b *BearerTokenAuth) Start(ctx context.Context, host component.Host) error } // Read file once - tokenStr, err := os.ReadFile(b.tokenFilename) + tokenStr, err := os.ReadFile(b.filename) if err != nil { return err } @@ -99,7 +99,7 @@ func (b *BearerTokenAuth) Start(ctx context.Context, host component.Host) error // start file watcher go b.startWatcher(ctx, watcher) - return watcher.Add(b.tokenFilename) + return watcher.Add(b.filename) } func (b *BearerTokenAuth) startWatcher(ctx context.Context, watcher *fsnotify.Watcher) { @@ -116,7 +116,7 @@ func (b *BearerTokenAuth) startWatcher(ctx context.Context, watcher *fsnotify.Wa continue } if event.Op == fsnotify.Write { - token, err := os.ReadFile(b.tokenFilename) + token, err := os.ReadFile(b.filename) if err != nil { b.logger.Error(err.Error()) continue @@ -131,7 +131,7 @@ func (b *BearerTokenAuth) startWatcher(ctx context.Context, watcher *fsnotify.Wa // Shutdown of BearerTokenAuth does nothing and returns nil func (b *BearerTokenAuth) Shutdown(ctx context.Context) error { - if b.tokenFilename == "" { + if b.filename == "" { return nil } diff --git a/extension/bearertokenauthextension/bearertokenauth_test.go b/extension/bearertokenauthextension/bearertokenauth_test.go index 83b38b46feb0..f765c8a7960a 100644 --- a/extension/bearertokenauthextension/bearertokenauth_test.go +++ b/extension/bearertokenauthextension/bearertokenauth_test.go @@ -109,7 +109,7 @@ func TestBearerAuthenticator(t *testing.T) { func TestBearerStartWatchStop(t *testing.T) { cfg := createDefaultConfig().(*Config) - cfg.BearerTokenFilename = "test.token" + cfg.Filename = "test.token" bauth := newBearerTokenAuth(cfg, nil) assert.NotNil(t, bauth) @@ -121,7 +121,7 @@ func TestBearerStartWatchStop(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, credential) - token, err := os.ReadFile(bauth.tokenFilename) + token, err := os.ReadFile(bauth.filename) assert.NoError(t, err) tokenStr := fmt.Sprintf("Bearer %s", token) @@ -134,7 +134,7 @@ func TestBearerStartWatchStop(t *testing.T) { assert.True(t, credential.RequireTransportSecurity()) // change file content once - assert.Nil(t, os.WriteFile(bauth.tokenFilename, []byte(fmt.Sprintf("%stest", token)), 0600)) + assert.Nil(t, os.WriteFile(bauth.filename, []byte(fmt.Sprintf("%stest", token)), 0600)) time.Sleep(5 * time.Second) credential, _ = bauth.PerRPCCredentials() md, err = credential.GetRequestMetadata(context.Background()) @@ -143,7 +143,7 @@ func TestBearerStartWatchStop(t *testing.T) { assert.NoError(t, err) // change file content back - assert.Nil(t, os.WriteFile(bauth.tokenFilename, token, 0600)) + assert.Nil(t, os.WriteFile(bauth.filename, token, 0600)) time.Sleep(5 * time.Second) credential, _ = bauth.PerRPCCredentials() md, err = credential.GetRequestMetadata(context.Background()) diff --git a/extension/bearertokenauthextension/config.go b/extension/bearertokenauthextension/config.go index 19cedbdb6fef..863e577204bc 100644 --- a/extension/bearertokenauthextension/config.go +++ b/extension/bearertokenauthextension/config.go @@ -27,8 +27,8 @@ type Config struct { // BearerToken specifies the bearer token to use for every RPC. BearerToken string `mapstructure:"token,omitempty"` - // BearerTokenFile points to a file that contains the bearer token to use for every RPC. - BearerTokenFilename string `mapstructure:"tokenfile,omitempty"` + // Filename points to a file that contains the bearer token to use for every RPC. + Filename string `mapstructure:"filename,omitempty"` } var _ config.Extension = (*Config)(nil) From 28cfea3b626b29c05d4bbd99ed1ed9358e051b90 Mon Sep 17 00:00:00 2001 From: Benedikt Bongartz Date: Wed, 28 Sep 2022 14:09:42 +0200 Subject: [PATCH 5/9] [extension/bearertokenauthextension] support configmap change on k8s Signed-off-by: Benedikt Bongartz --- .../bearertokenauth.go | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/extension/bearertokenauthextension/bearertokenauth.go b/extension/bearertokenauthextension/bearertokenauth.go index 5556a72e04eb..d1d3b9f7b1c7 100644 --- a/extension/bearertokenauthextension/bearertokenauth.go +++ b/extension/bearertokenauthextension/bearertokenauth.go @@ -115,20 +115,36 @@ func (b *BearerTokenAuth) startWatcher(ctx context.Context, watcher *fsnotify.Wa if !ok { continue } - if event.Op == fsnotify.Write { - token, err := os.ReadFile(b.filename) - if err != nil { - b.logger.Error(err.Error()) - continue - } - b.muTokenString.Lock() - b.tokenString = string(token) - b.muTokenString.Unlock() + + // NOTE: k8s configmaps uses symlinks, we need this workaround. + // original configmap file is removed. + // SEE: https://martensson.io/go-fsnotify-and-kubernetes-configmaps/ + if event.Op == fsnotify.Remove { + // remove the watcher since the file is removed + watcher.Remove(event.Name) + // add a new watcher pointing to the new symlink/file + watcher.Add(b.filename) + b.refreshToken() + } + // also allow normal files to be modified and reloaded. + if event.Op&fsnotify.Write == fsnotify.Write { + b.refreshToken() } } } } +func (b *BearerTokenAuth) refreshToken() { + token, err := os.ReadFile(b.filename) + if err != nil { + b.logger.Error(err.Error()) + return + } + b.muTokenString.Lock() + b.tokenString = string(token) + b.muTokenString.Unlock() +} + // Shutdown of BearerTokenAuth does nothing and returns nil func (b *BearerTokenAuth) Shutdown(ctx context.Context) error { if b.filename == "" { From a0a1d915b1b21d5788bf01b4e0b15b88135d982d Mon Sep 17 00:00:00 2001 From: Benedikt Bongartz Date: Wed, 28 Sep 2022 15:46:19 +0200 Subject: [PATCH 6/9] [extension/bearertokenauthextension] fix config validation Signed-off-by: Benedikt Bongartz --- extension/bearertokenauthextension/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extension/bearertokenauthextension/config.go b/extension/bearertokenauthextension/config.go index 863e577204bc..0ecc77c15a39 100644 --- a/extension/bearertokenauthextension/config.go +++ b/extension/bearertokenauthextension/config.go @@ -36,7 +36,7 @@ var errNoTokenProvided = errors.New("no bearer token provided") // Validate checks if the extension configuration is valid func (cfg *Config) Validate() error { - if cfg.BearerToken == "" { + if cfg.BearerToken == "" && cfg.Filename == "" { return errNoTokenProvided } return nil From 0373ecc8ca346bacb2e93ce801b81bc5ec8016ef Mon Sep 17 00:00:00 2001 From: Benedikt Bongartz Date: Wed, 28 Sep 2022 17:03:58 +0200 Subject: [PATCH 7/9] [extension/bearertokenauthextension] Print log line on file change Signed-off-by: Benedikt Bongartz --- extension/bearertokenauthextension/bearertokenauth.go | 1 + 1 file changed, 1 insertion(+) diff --git a/extension/bearertokenauthextension/bearertokenauth.go b/extension/bearertokenauthextension/bearertokenauth.go index d1d3b9f7b1c7..b7aaa9f0bec1 100644 --- a/extension/bearertokenauthextension/bearertokenauth.go +++ b/extension/bearertokenauthextension/bearertokenauth.go @@ -135,6 +135,7 @@ func (b *BearerTokenAuth) startWatcher(ctx context.Context, watcher *fsnotify.Wa } func (b *BearerTokenAuth) refreshToken() { + b.logger.Info("refresh token", zap.Field{Key: "filename", String: b.filename}) token, err := os.ReadFile(b.filename) if err != nil { b.logger.Error(err.Error()) From c0e2c3bec7d1778cca98e915d3db120a9c1a0696 Mon Sep 17 00:00:00 2001 From: Benedikt Bongartz Date: Wed, 28 Sep 2022 17:16:34 +0200 Subject: [PATCH 8/9] [extension/bearertokenauthextension] react to CHMOD and REMOVE events Signed-off-by: Benedikt Bongartz --- .../bearertokenauthextension/bearertokenauth.go | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/extension/bearertokenauthextension/bearertokenauth.go b/extension/bearertokenauthextension/bearertokenauth.go index b7aaa9f0bec1..1134369a2e3c 100644 --- a/extension/bearertokenauthextension/bearertokenauth.go +++ b/extension/bearertokenauthextension/bearertokenauth.go @@ -82,13 +82,7 @@ func (b *BearerTokenAuth) Start(ctx context.Context, host component.Host) error } // Read file once - tokenStr, err := os.ReadFile(b.filename) - if err != nil { - return err - } - b.muTokenString.Lock() - b.tokenString = string(tokenStr) - b.muTokenString.Unlock() + b.refreshToken() b.shutdownCH = make(chan struct{}) @@ -115,11 +109,10 @@ func (b *BearerTokenAuth) startWatcher(ctx context.Context, watcher *fsnotify.Wa if !ok { continue } - // NOTE: k8s configmaps uses symlinks, we need this workaround. // original configmap file is removed. // SEE: https://martensson.io/go-fsnotify-and-kubernetes-configmaps/ - if event.Op == fsnotify.Remove { + if event.Op == fsnotify.Remove || event.Op == fsnotify.Chmod { // remove the watcher since the file is removed watcher.Remove(event.Name) // add a new watcher pointing to the new symlink/file @@ -127,7 +120,7 @@ func (b *BearerTokenAuth) startWatcher(ctx context.Context, watcher *fsnotify.Wa b.refreshToken() } // also allow normal files to be modified and reloaded. - if event.Op&fsnotify.Write == fsnotify.Write { + if event.Op == fsnotify.Write { b.refreshToken() } } @@ -135,7 +128,7 @@ func (b *BearerTokenAuth) startWatcher(ctx context.Context, watcher *fsnotify.Wa } func (b *BearerTokenAuth) refreshToken() { - b.logger.Info("refresh token", zap.Field{Key: "filename", String: b.filename}) + b.logger.Info("refresh token", zap.String("filename", b.filename)) token, err := os.ReadFile(b.filename) if err != nil { b.logger.Error(err.Error()) From 7b7f712be2f2ed161de5b1d300a592ead357f3dd Mon Sep 17 00:00:00 2001 From: Benedikt Bongartz Date: Thu, 29 Sep 2022 10:57:51 +0200 Subject: [PATCH 9/9] [extension/bearertokenauthextension] fix unittest by adding zaptest logger Signed-off-by: Benedikt Bongartz --- extension/bearertokenauthextension/bearertokenauth.go | 8 ++++++-- .../bearertokenauthextension/bearertokenauth_test.go | 3 ++- extension/bearertokenauthextension/go.mod | 1 + extension/bearertokenauthextension/go.sum | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/extension/bearertokenauthextension/bearertokenauth.go b/extension/bearertokenauthextension/bearertokenauth.go index 1134369a2e3c..a9787dc75a9c 100644 --- a/extension/bearertokenauthextension/bearertokenauth.go +++ b/extension/bearertokenauthextension/bearertokenauth.go @@ -114,9 +114,13 @@ func (b *BearerTokenAuth) startWatcher(ctx context.Context, watcher *fsnotify.Wa // SEE: https://martensson.io/go-fsnotify-and-kubernetes-configmaps/ if event.Op == fsnotify.Remove || event.Op == fsnotify.Chmod { // remove the watcher since the file is removed - watcher.Remove(event.Name) + if err := watcher.Remove(event.Name); err != nil { + b.logger.Error(err.Error()) + } // add a new watcher pointing to the new symlink/file - watcher.Add(b.filename) + if err := watcher.Add(b.filename); err != nil { + b.logger.Error(err.Error()) + } b.refreshToken() } // also allow normal files to be modified and reloaded. diff --git a/extension/bearertokenauthextension/bearertokenauth_test.go b/extension/bearertokenauthextension/bearertokenauth_test.go index f765c8a7960a..989b4c316c41 100644 --- a/extension/bearertokenauthextension/bearertokenauth_test.go +++ b/extension/bearertokenauthextension/bearertokenauth_test.go @@ -24,6 +24,7 @@ import ( "github.com/stretchr/testify/assert" "go.opentelemetry.io/collector/component/componenttest" + "go.uber.org/zap/zaptest" ) func TestPerRPCAuth(t *testing.T) { @@ -111,7 +112,7 @@ func TestBearerStartWatchStop(t *testing.T) { cfg := createDefaultConfig().(*Config) cfg.Filename = "test.token" - bauth := newBearerTokenAuth(cfg, nil) + bauth := newBearerTokenAuth(cfg, zaptest.NewLogger(t)) assert.NotNil(t, bauth) assert.Nil(t, bauth.Start(context.Background(), componenttest.NewNopHost())) diff --git a/extension/bearertokenauthextension/go.mod b/extension/bearertokenauthextension/go.mod index ceb38bc3738a..99d8097bb52f 100644 --- a/extension/bearertokenauthextension/go.mod +++ b/extension/bearertokenauthextension/go.mod @@ -11,6 +11,7 @@ require ( ) require ( + github.com/benbjohnson/clock v1.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect diff --git a/extension/bearertokenauthextension/go.sum b/extension/bearertokenauthextension/go.sum index d2eece51b397..8607acf0a41d 100644 --- a/extension/bearertokenauthextension/go.sum +++ b/extension/bearertokenauthextension/go.sum @@ -23,6 +23,7 @@ github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+ github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g= github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=