Skip to content

Commit 2746807

Browse files
authored
Merge pull request #1780 from splunk/feature/m1-secrets-redo2
CSPL-4186: Support splunk secret and make it available to Ansible via mount
2 parents cd24ddb + 61c18b5 commit 2746807

14 files changed

Lines changed: 477 additions & 30 deletions

pkg/splunk/common/names.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func GetNamespaceScopedSecretName(namespace string) string {
131131

132132
// GetSplunkSecretTokenTypes returns all types of Splunk secret tokens
133133
func GetSplunkSecretTokenTypes() []string {
134-
return []string{"hec_token", "password", "pass4SymmKey", "idxc_secret", "shc_secret"}
134+
return []string{"hec_token", "password", "pass4SymmKey", "splunk_secret", "idxc_secret", "shc_secret"}
135135
}
136136

137137
// GetLabelTypes returns a map of label types to strings

pkg/splunk/common/names_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func TestGetNamespaceScopedSecretName(t *testing.T) {
4040
}
4141

4242
func TestGetSplunkSecretTokenTypes(t *testing.T) {
43-
wantSecretTokens := []string{"hec_token", "password", "pass4SymmKey", "idxc_secret", "shc_secret"}
43+
wantSecretTokens := []string{"hec_token", "password", "pass4SymmKey", "splunk_secret", "idxc_secret", "shc_secret"}
4444
secretTokens := GetSplunkSecretTokenTypes()
4545
if !reflect.DeepEqual(secretTokens, wantSecretTokens) {
4646
t.Errorf("Incorrect secret tokens returned got %+v want %+v", secretTokens, wantSecretTokens)

pkg/splunk/util/secrets.go

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -355,28 +355,40 @@ func GetSplunkReadableNamespaceScopedSecretData(ctx context.Context, c splcommon
355355

356356
// Create individual token type data
357357
for _, tokenType := range splcommon.GetSplunkSecretTokenTypes() {
358-
splunkReadableData[tokenType] = namespaceScopedSecret.Data[tokenType]
358+
if _, exists := namespaceScopedSecret.Data[tokenType]; exists {
359+
splunkReadableData[tokenType] = namespaceScopedSecret.Data[tokenType]
360+
}
359361
}
360362

361-
// Create default.yml
362-
splunkReadableData["default.yml"] = []byte(fmt.Sprintf(`
363+
// Create default.yml with optional splunk_secret
364+
defaultYmlBuilder := fmt.Sprintf(`
363365
splunk:
364366
hec_disabled: 0
365367
hec_enableSSL: 0
366368
hec_token: "%s"
367369
password: "%s"
368-
pass4SymmKey: "%s"
370+
pass4SymmKey: "%s"`,
371+
namespaceScopedSecret.Data["hec_token"],
372+
namespaceScopedSecret.Data["password"],
373+
namespaceScopedSecret.Data["pass4SymmKey"])
374+
375+
// Add splunk_secret only if it exists
376+
if splunkSecret, exists := namespaceScopedSecret.Data["splunk_secret"]; exists {
377+
defaultYmlBuilder += fmt.Sprintf(`
378+
splunk_secret: "%s"`, splunkSecret)
379+
}
380+
381+
// Add idxc and shc sections
382+
defaultYmlBuilder += fmt.Sprintf(`
369383
idxc:
370384
secret: "%s"
371385
shc:
372386
secret: "%s"
373387
`,
374-
namespaceScopedSecret.Data["hec_token"],
375-
namespaceScopedSecret.Data["password"],
376-
namespaceScopedSecret.Data["pass4SymmKey"],
377388
namespaceScopedSecret.Data["idxc_secret"],
378-
namespaceScopedSecret.Data["shc_secret"]))
389+
namespaceScopedSecret.Data["shc_secret"])
379390

391+
splunkReadableData["default.yml"] = []byte(strings.TrimSpace(defaultYmlBuilder))
380392
return splunkReadableData, nil
381393
}
382394

@@ -451,9 +463,19 @@ func ApplyNamespaceScopedSecretObject(ctx context.Context, client splcommon.Cont
451463
namespacedName := types.NamespacedName{Namespace: namespace, Name: splcommon.GetNamespaceScopedSecretName(namespace)}
452464
err := client.Get(ctx, namespacedName, &current)
453465
if err == nil {
466+
// Validate existing secrets according to PasswordManagement documentation
467+
err = validateNamespaceScopedSecrets(scopedLog, &current)
468+
if err != nil {
469+
return nil, err
470+
}
471+
454472
// Generate values for only missing types of tokens them
455473
var updateNeeded bool = false
456474
for _, tokenType := range splcommon.GetSplunkSecretTokenTypes() {
475+
if tokenType == "splunk_secret" {
476+
// splunk_secret is optional, skip if not found
477+
continue
478+
}
457479
if _, ok := current.Data[tokenType]; !ok {
458480
scopedLog.Info("Namespace scoped secret exists, missing value for token", "missingTokenType", tokenType)
459481
if current.Data == nil || reflect.ValueOf(current.Data).Kind() != reflect.Map {
@@ -491,7 +513,7 @@ func ApplyNamespaceScopedSecretObject(ctx context.Context, client splcommon.Cont
491513
for _, tokenType := range splcommon.GetSplunkSecretTokenTypes() {
492514
if tokenType == "hec_token" {
493515
current.Data[tokenType] = generateHECToken()
494-
} else {
516+
} else if tokenType != "splunk_secret" {
495517
current.Data[tokenType] = splcommon.GenerateSecret(splcommon.SecretBytes, 24)
496518
}
497519
}
@@ -523,6 +545,40 @@ func ApplyNamespaceScopedSecretObject(ctx context.Context, client splcommon.Cont
523545
return &current, nil
524546
}
525547

548+
// validateNamespaceScopedSecrets validates that all Splunk secret tokens that exist are not empty
549+
// and meet their specific requirements
550+
// Validates secrets documented in PasswordManagement: hec_token, password, pass4SymmKey, idxc_secret, shc_secret
551+
func validateNamespaceScopedSecrets(scopedLog interface {
552+
Info(msg string, keysAndValues ...interface{})
553+
Error(err error, msg string, keysAndValues ...interface{})
554+
}, secret *corev1.Secret) error {
555+
if secret.Data == nil {
556+
scopedLog.Info("Secret data is nil for namespace scoped secret")
557+
return nil
558+
}
559+
560+
// Validate each documented secret token type
561+
for _, tokenType := range splcommon.GetSplunkSecretTokenTypes() {
562+
if secretValue, exists := secret.Data[tokenType]; exists {
563+
var err error
564+
if tokenType == "hec_token" {
565+
err = ValidateHECToken(secretValue)
566+
} else {
567+
err = ValidateSecret(secretValue)
568+
}
569+
570+
if err != nil {
571+
scopedLog.Error(err, "Validation failed for secret", "secret", tokenType)
572+
return fmt.Errorf("validation failed for secret %s: %w", tokenType, err)
573+
}
574+
575+
scopedLog.Info("Namespace scoped secret validation passed", "secret", tokenType)
576+
}
577+
}
578+
579+
return nil
580+
}
581+
526582
// GetSecretByName retrieves namespace scoped secret object for a given name
527583
func GetSecretByName(ctx context.Context, c splcommon.ControllerClient, namespace string, logHandle string, name string) (*corev1.Secret, error) {
528584
var namespaceScopedSecret corev1.Secret

0 commit comments

Comments
 (0)