Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

fix/sg: add lock to secrets.Store CRUD #64397

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions dev/sg/internal/secrets/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ type secretManagerClient interface {

// Store holds secrets regardless on their form, as long as they are marshallable in JSON.
type Store struct {
// All methods reading/writing from Store must claim this lock.
mux sync.Mutex

filepath string
// persistedData holds secrets that should be persisted to filepath.
persistedData map[string]json.RawMessage
Expand Down Expand Up @@ -154,6 +157,9 @@ func LoadFromFile(filepath string) (*Store, error) {

// Write serializes the store content in the given writer.
func (s *Store) Write(w io.Writer) error {
s.mux.Lock()
defer s.mux.Unlock()

enc := json.NewEncoder(w)
return enc.Encode(s.persistedData)
}
Expand All @@ -170,6 +176,9 @@ func (s *Store) SaveFile() error {

// Put stores serialized data in memory.
func (s *Store) Put(key string, data any) error {
s.mux.Lock()
defer s.mux.Unlock()

b, err := json.Marshal(data)
if err != nil {
return err
Expand All @@ -180,7 +189,9 @@ func (s *Store) Put(key string, data any) error {

// PutAndSave saves automatically after calling Put.
func (s *Store) PutAndSave(key string, data any) error {
s.mux.Lock()
err := s.Put(key, data)
s.mux.Unlock() // call explicitly here since s.SaveFile might lock as well
if err != nil {
return err
}
Expand All @@ -189,6 +200,9 @@ func (s *Store) PutAndSave(key string, data any) error {

// Get fetches a value from memory and uses the given target to deserialize it.
func (s *Store) Get(key string, target any) error {
s.mux.Lock()
defer s.mux.Unlock()

if v, ok := s.persistedData[key]; ok {
return json.Unmarshal(v, target)
}
Expand Down Expand Up @@ -261,13 +275,18 @@ func (s *Store) GetExternal(ctx context.Context, secret ExternalSecret, fallback
}

// Return and persist the fetched secret
s.mux.Lock()
defer s.mux.Unlock()
value.Fetched = time.Now()
s.externalData[secret.id()] = value
return value.Value, nil
}

// Remove deletes a value from memory.
func (s *Store) Remove(key string) error {
s.mux.Lock()
defer s.mux.Unlock()

if _, exists := s.persistedData[key]; exists {
delete(s.persistedData, key)
return nil
Expand All @@ -277,6 +296,9 @@ func (s *Store) Remove(key string) error {

// Keys returns out all keys
func (s *Store) Keys() []string {
s.mux.Lock()
defer s.mux.Unlock()

keys := make([]string, 0, len(s.persistedData))
for key := range s.persistedData {
keys = append(keys, key)
Expand Down
Loading