pkg/controller/remotecluster/keystore/changes_tracker.go (77 lines of code) (raw):
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License 2.0;
// you may not use this file except in compliance with the Elastic License 2.0.
package keystore
import (
"sync"
)
// pendingChanges are changes which are expected to be eventually observed in the API keystore.
type pendingChanges struct {
// changes maps for each Alias (remote cluster name as defined in the client ES) the pending change.
changes map[string]pendingChange
mu sync.RWMutex
}
type pendingChange struct {
remoteClusterName, remoteClusterNamespace, alias string
key key
}
// key holds an expected key as generated by Elasticsearch, with its ID and its encoded value.
type key struct {
keyID, encodedValue string
}
// AddKey registers a key to be eventually persisted in the underlying Secret.
func (pc *pendingChanges) AddKey(remoteClusterName, remoteClusterNamespace, alias, keyID, encodedKeyValue string) {
if pc == nil {
return
}
pc.mu.Lock()
defer pc.mu.Unlock()
pc.changes[alias] = pendingChange{
remoteClusterName: remoteClusterName,
remoteClusterNamespace: remoteClusterNamespace,
alias: alias,
key: key{
keyID: keyID,
encodedValue: encodedKeyValue,
},
}
}
// ForgetChangeFor must be called once we know that the key added with AddKey or removed with DeleteAlias is reflected in the underlying Secret.
func (pc *pendingChanges) ForgetChangeFor(alias string) {
if pc == nil {
return
}
pc.mu.Lock()
defer pc.mu.Unlock()
delete(pc.changes, alias)
}
// DeleteAlias registers the deletion of the key for the provided alias.
func (pc *pendingChanges) DeleteAlias(alias string) {
if pc == nil {
return
}
pc.mu.Lock()
defer pc.mu.Unlock()
pc.changes[alias] = pendingChange{
alias: alias,
key: key{}, // an empty key means that this alias must be deleted
}
}
// Get returns all the pending changes.
func (pc *pendingChanges) Get() []pendingChange {
if pc == nil {
return nil
}
pc.mu.RLock()
defer pc.mu.RUnlock()
pendingChanges := make([]pendingChange, 0, len(pc.changes))
for alias, change := range pc.changes {
pendingChange := pendingChange{
remoteClusterName: change.remoteClusterName,
remoteClusterNamespace: change.remoteClusterNamespace,
alias: alias,
key: key{
keyID: change.key.keyID,
encodedValue: change.key.encodedValue,
},
}
pendingChanges = append(pendingChanges, pendingChange)
}
return pendingChanges
}
func (k *key) IsEmpty() bool {
if k == nil {
return true
}
return k.encodedValue == "" && k.keyID == ""
}