Skip to content

Commit 47921b8

Browse files
authored
[extension/sumologicextension] removing collector name from credential path for sumologic (#42453)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description This pr removes the collector name from the local credentials path that extension uses for authentication. This allows changing the name of the collector without registration. See #42511 **Changes** 1. Credential key (hashKeyV2) now derives only from InstallationToken and APIBaseURL. 2. collectorName no longer affects credential storage. 3. Added backward compatibility: falls back to old key (v1) if v2 not found. 4. On shutdown, v1 credentials are migrated to v2. 5. Updated tests to cover v1 → v2 migration and ensure correct credential usage. <!-- Issue number (e.g. #1234) or full URL to issue, if applicable. --> #### Link to tracking issue Resolves #42511 <!--Describe what testing was performed and which tests were added.--> #### Testing Testing on local are performed [link](https://gist.github.com/pankaj101A/c4d1ac11f9304efcc02fe92903979746) <!--Describe the documentation added.--> #### Documentation <!--Please delete paragraphs that you did not use before submitting.-->
1 parent 5f8b07f commit 47921b8

File tree

3 files changed

+147
-5
lines changed

3 files changed

+147
-5
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: extension/SumologicExtension
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: "removing collector name from credential path for sumologic extension"
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [42511]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: []

extension/sumologicextension/extension.go

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,11 @@ type SumologicExtension struct {
6161
stickySessionCookieLock sync.RWMutex
6262
stickySessionCookie string
6363

64-
closeChan chan struct{}
65-
closeOnce sync.Once
66-
backOff *backoff.ExponentialBackOff
67-
id component.ID
64+
closeChan chan struct{}
65+
closeOnce sync.Once
66+
backOff *backoff.ExponentialBackOff
67+
id component.ID
68+
collectorCredentials credentials.CollectorCredentials
6869
}
6970

7071
const (
@@ -129,7 +130,16 @@ func newSumologicExtension(conf *Config, logger *zap.Logger, id component.ID, bu
129130
var (
130131
collectorName string
131132
hashKey = createHashKey(conf)
133+
hashKeyV2 = createHashKeyV2(conf)
132134
)
135+
136+
_, err = credentialsStore.Get(hashKeyV2)
137+
if err != nil {
138+
logger.Info("credentials not found, trying legacy credentials", zap.Error(err))
139+
} else {
140+
logger.Debug("v2 credentials found")
141+
hashKey = hashKeyV2
142+
}
133143
if conf.CollectorName == "" {
134144
// If collector name is not set by the user, check if the collector was restarted
135145
// and that we can reuse collector name save in credentials store.
@@ -178,6 +188,13 @@ func createHashKey(conf *Config) string {
178188
)
179189
}
180190

191+
func createHashKeyV2(conf *Config) string {
192+
return fmt.Sprintf("%s%s",
193+
conf.Credentials.InstallationToken,
194+
strings.TrimSuffix(conf.APIBaseURL, "/"),
195+
)
196+
}
197+
181198
func (se *SumologicExtension) Start(ctx context.Context, host component.Host) error {
182199
var err error
183200
se.host = host
@@ -191,6 +208,7 @@ func (se *SumologicExtension) Start(ctx context.Context, host component.Host) er
191208
}
192209

193210
colCreds, err := se.getCredentials(ctx)
211+
se.collectorCredentials = colCreds
194212
if err != nil {
195213
return err
196214
}
@@ -218,9 +236,20 @@ func (se *SumologicExtension) Start(ctx context.Context, host component.Host) er
218236
return nil
219237
}
220238

221-
// Shutdown is invoked during service shutdown.
222239
func (se *SumologicExtension) Shutdown(ctx context.Context) error {
223240
se.closeOnce.Do(func() { close(se.closeChan) })
241+
242+
hashKeyV2 := createHashKeyV2(se.conf)
243+
_, err := se.credentialsStore.Get(hashKeyV2)
244+
se.logger.Debug("Shutting down Sumo Logic extension migrating to hashkeyV2 ")
245+
if err != nil {
246+
se.logger.Warn("Failed to get collector v2 credentials on shutdown, migrating to v2", zap.Error(err))
247+
err := se.credentialsStore.Store(hashKeyV2, se.collectorCredentials)
248+
if err != nil {
249+
se.logger.Warn("Failed to migrate collector credentials to v2 on shutdown", zap.Error(err))
250+
}
251+
}
252+
224253
select {
225254
case <-ctx.Done():
226255
return ctx.Err()

extension/sumologicextension/extension_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,92 @@ func TestStoreCredentials_PreexistingCredentialsAreUsed(t *testing.T) {
375375
require.EqualValues(t, 2, atomic.LoadInt32(&reqCount))
376376
}
377377

378+
func TestStoreCredentials_V2CredentialsAreUsed(t *testing.T) {
379+
t.Parallel()
380+
381+
getServer := func() *httptest.Server {
382+
return httptest.NewServer(http.HandlerFunc(
383+
func(w http.ResponseWriter, req *http.Request) {
384+
switch req.URL.Path {
385+
case heartbeatURL:
386+
w.WriteHeader(http.StatusNoContent)
387+
case metadataURL:
388+
w.WriteHeader(http.StatusOK)
389+
default:
390+
w.WriteHeader(http.StatusInternalServerError)
391+
}
392+
}))
393+
}
394+
395+
getConfig := func(url string) *Config {
396+
cfg := createDefaultConfig().(*Config)
397+
cfg.CollectorName = "collector_name"
398+
cfg.APIBaseURL = url
399+
cfg.Credentials.InstallationToken = "dummy_install_token"
400+
return cfg
401+
}
402+
403+
logger, err := zap.NewDevelopment()
404+
require.NoError(t, err)
405+
406+
dir := t.TempDir()
407+
t.Logf("Using dir: %s", dir)
408+
409+
store, err := credentials.NewLocalFsStore(
410+
credentials.WithCredentialsDirectory(dir),
411+
credentials.WithLogger(logger),
412+
)
413+
require.NoError(t, err)
414+
415+
srv := getServer()
416+
t.Cleanup(func() { srv.Close() })
417+
418+
cfg := getConfig(srv.URL)
419+
cfg.CollectorCredentialsDirectory = dir
420+
421+
hashKey := createHashKey(cfg)
422+
423+
require.NoError(t,
424+
store.Store(hashKey, credentials.CollectorCredentials{
425+
CollectorName: "collector_name",
426+
Credentials: api.OpenRegisterResponsePayload{
427+
CollectorCredentialID: "collectorId",
428+
CollectorCredentialKey: "collectorKey",
429+
CollectorID: "id",
430+
},
431+
}),
432+
)
433+
434+
se, err := newSumologicExtension(cfg, logger, component.NewID(metadata.Type), "1.0.0")
435+
require.NoError(t, err)
436+
437+
fileName, err := credentials.HashKeyToFilename(hashKey)
438+
require.NoError(t, err)
439+
credsPath := path.Join(dir, fileName)
440+
// Credentials file exists before starting the extension because we created
441+
// it directly via store.Store()
442+
require.FileExists(t, credsPath)
443+
444+
require.NoError(t, se.Start(t.Context(), componenttest.NewNopHost()))
445+
require.NoError(t, se.Shutdown(t.Context()))
446+
require.FileExists(t, credsPath)
447+
hashKeyV2 := createHashKeyV2(cfg)
448+
v2Creds, _ := store.Get(hashKeyV2)
449+
450+
fileName, err = credentials.HashKeyToFilename(hashKeyV2)
451+
require.NoError(t, err)
452+
credsPath = path.Join(dir, fileName)
453+
require.Equal(t, credentials.CollectorCredentials{
454+
CollectorName: "collector_name",
455+
Credentials: api.OpenRegisterResponsePayload{
456+
CollectorCredentialID: "collectorId",
457+
CollectorCredentialKey: "collectorKey",
458+
CollectorID: "id",
459+
},
460+
}, v2Creds)
461+
require.FileExists(t, credsPath)
462+
}
463+
378464
func TestLocalFSCredentialsStore_WorkCorrectlyForMultipleExtensions(t *testing.T) {
379465
t.Parallel()
380466

0 commit comments

Comments
 (0)