Skip to content

Commit

Permalink
Make prefix trimming configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasz-sadura committed Nov 20, 2024
1 parent 8728bb1 commit 697f4a4
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 31 deletions.
17 changes: 8 additions & 9 deletions secrets/generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ import (
"github.com/tidwall/gjson"
)

// prefix used to reference secrets from external secret managers, to differentiate them from environment variables
const secretPrefix = "secrets."

type SecretAPI interface {
GetSecretValue(context.Context, string) (string, bool)
CheckSecretExists(context.Context, string) bool
Expand All @@ -33,7 +30,8 @@ type SecretProviderFn func(secretsManager SecretAPI, prefix string) (SecretAPI,

type secretProvider struct {
SecretAPI
prefix string
prefix string
trimPrefix string
}

func (s *secretProvider) GetSecretValue(ctx context.Context, key string) (string, bool) {
Expand Down Expand Up @@ -64,22 +62,23 @@ func (s *secretProvider) CheckSecretExists(ctx context.Context, key string) bool
}

// NewSecretProvider handles prefix trim and optional JSON field retrieval
func NewSecretProvider(secretsManager SecretAPI, prefix string) (SecretAPI, error) {
func NewSecretProvider(secretsManager SecretAPI, prefix string, trimPrefix string) (SecretAPI, error) {
secretProvider := &secretProvider{
SecretAPI: secretsManager,
prefix: prefix,
SecretAPI: secretsManager,
prefix: prefix,
trimPrefix: trimPrefix,
}

return secretProvider, nil
}

// trims the secret prefix and returns full secret ID with JSON field reference
func (s *secretProvider) trimPrefixAndSplit(key string) (string, string, bool) {
if !strings.HasPrefix(key, secretPrefix) {
if !strings.HasPrefix(key, s.trimPrefix) {
return "", "", false
}

key = strings.TrimPrefix(key, secretPrefix)
key = strings.TrimPrefix(key, s.trimPrefix)
if strings.Contains(key, ".") {
parts := strings.SplitN(key, ".", 2)
return s.prefix + parts[0], parts[1], true
Expand Down
62 changes: 40 additions & 22 deletions secrets/generic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ type fakeSecretManager struct {

func Test_secretManager_lookup(t *testing.T) {
type args struct {
secrets map[string]string
key string
prefix string
secrets map[string]string
key string
prefix string
trimPrefix string
}
tests := []struct {
name string
Expand All @@ -27,69 +28,86 @@ func Test_secretManager_lookup(t *testing.T) {
{
name: "should lookup existing secret",
args: args{
secrets: map[string]string{"prefix/SECRET": "secretValue"},
key: "secrets.SECRET",
prefix: "prefix/",
secrets: map[string]string{"prefix/SECRET": "secretValue"},
key: "secrets.SECRET",
prefix: "prefix/",
trimPrefix: "secrets.",
},
wantValue: "secretValue",
wantExists: true,
},
{
name: "should not lookup non-existing secret",
args: args{
secrets: map[string]string{"prefix/SECRET": "secretValue"},
key: "secrets.UNDEFINED",
prefix: "prefix/",
secrets: map[string]string{"prefix/SECRET": "secretValue"},
key: "secrets.UNDEFINED",
prefix: "prefix/",
trimPrefix: "secrets.",
},
wantValue: "",
wantExists: false,
},
{
name: "should not find secret with different prefix",
args: args{
secrets: map[string]string{"prefix/redpanda1/SECRET": "secretValue"},
key: "secrets.SECRET",
prefix: "prefix/redpanda2/",
secrets: map[string]string{"prefix/redpanda1/SECRET": "secretValue"},
key: "secrets.SECRET",
prefix: "prefix/redpanda2/",
trimPrefix: "secrets.",
},
wantValue: "",
wantExists: false,
},
{
name: "should require variable name prefix",
args: args{
secrets: map[string]string{"prefix/SECRET": "secretValue"},
key: "SECRET",
prefix: "prefix/",
secrets: map[string]string{"prefix/SECRET": "secretValue"},
key: "SECRET",
prefix: "prefix/",
trimPrefix: "secrets.",
},
wantValue: "",
wantExists: false,
},
{
name: "should extract JSON field",
args: args{
secrets: map[string]string{"prefix/SECRET": `{"name":"John", "age": 25, "address": {"city": "LA", "street": "Main St"}}`},
key: "secrets.SECRET.name",
prefix: "prefix/",
secrets: map[string]string{"prefix/SECRET": `{"name":"John", "age": 25, "address": {"city": "LA", "street": "Main St"}}`},
key: "secrets.SECRET.name",
prefix: "prefix/",
trimPrefix: "secrets.",
},
wantValue: "John",
wantExists: true,
},
{
name: "should extract nested JSON field",
args: args{
secrets: map[string]string{"prefix/SECRET": `{"name":"John", "age": 25, "address": {"city": "LA", "street": "Main St"}}`},
key: "secrets.SECRET.address.city",
prefix: "prefix/",
secrets: map[string]string{"prefix/SECRET": `{"name":"John", "age": 25, "address": {"city": "LA", "street": "Main St"}}`},
key: "secrets.SECRET.address.city",
prefix: "prefix/",
trimPrefix: "secrets.",
},
wantValue: "LA",
wantExists: true,
},
{
name: "should support empty trimPrefix",
args: args{
secrets: map[string]string{"prefix/SECRET": "secretValue"},
key: "SECRET",
prefix: "prefix/",
trimPrefix: "",
},
wantValue: "secretValue",
wantExists: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
secretsApi, err := NewSecretProvider(&fakeSecretManager{
secrets: tt.args.secrets,
}, tt.args.prefix)
}, tt.args.prefix, tt.args.trimPrefix)
require.NoError(t, err)

gotExists := secretsApi.CheckSecretExists(context.Background(), tt.args.key)
Expand Down

0 comments on commit 697f4a4

Please sign in to comment.