mirror of
https://github.com/stakater/Reloader.git
synced 2026-08-23 22:16:45 +00:00
86 lines
2.4 KiB
Go
86 lines
2.4 KiB
Go
// Package reload provides core reload logic for ConfigMaps and Secrets.
|
|
package reload
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"io"
|
|
"sort"
|
|
"strings"
|
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
)
|
|
|
|
// Hasher computes content hashes for ConfigMaps and Secrets.
|
|
// The hash is used to detect changes and trigger workload reloads.
|
|
type Hasher struct{}
|
|
|
|
// NewHasher creates a new Hasher instance.
|
|
func NewHasher() *Hasher {
|
|
return &Hasher{}
|
|
}
|
|
|
|
// HashConfigMap computes a SHA1 hash of the ConfigMap's data and binaryData.
|
|
// The hash is deterministic - same content always produces the same hash.
|
|
func (h *Hasher) HashConfigMap(cm *corev1.ConfigMap) string {
|
|
if cm == nil {
|
|
return h.computeSHA("")
|
|
}
|
|
return h.hashConfigMapData(cm.Data, cm.BinaryData)
|
|
}
|
|
|
|
// HashSecret computes a SHA1 hash of the Secret's data.
|
|
// The hash is deterministic - same content always produces the same hash.
|
|
func (h *Hasher) HashSecret(secret *corev1.Secret) string {
|
|
if secret == nil {
|
|
return h.computeSHA("")
|
|
}
|
|
return h.hashSecretData(secret.Data)
|
|
}
|
|
|
|
// hashConfigMapData computes a hash from ConfigMap data and binary data.
|
|
// Keys are sorted to ensure deterministic output.
|
|
func (h *Hasher) hashConfigMapData(data map[string]string, binaryData map[string][]byte) string {
|
|
values := make([]string, 0, len(data)+len(binaryData))
|
|
|
|
for k, v := range data {
|
|
values = append(values, k+"="+v)
|
|
}
|
|
|
|
for k, v := range binaryData {
|
|
// Binary data is base64 encoded for consistent hashing
|
|
values = append(values, k+"="+base64.StdEncoding.EncodeToString(v))
|
|
}
|
|
|
|
sort.Strings(values)
|
|
return h.computeSHA(strings.Join(values, ";"))
|
|
}
|
|
|
|
// hashSecretData computes a hash from Secret data.
|
|
// Keys are sorted to ensure deterministic output.
|
|
func (h *Hasher) hashSecretData(data map[string][]byte) string {
|
|
values := make([]string, 0, len(data))
|
|
|
|
for k, v := range data {
|
|
// Secret data is stored as raw bytes, not base64 encoded
|
|
values = append(values, k+"="+string(v))
|
|
}
|
|
|
|
sort.Strings(values)
|
|
return h.computeSHA(strings.Join(values, ";"))
|
|
}
|
|
|
|
// computeSHA generates a SHA1 hash from a string.
|
|
func (h *Hasher) computeSHA(data string) string {
|
|
hasher := sha1.New()
|
|
_, _ = io.WriteString(hasher, data)
|
|
return fmt.Sprintf("%x", hasher.Sum(nil))
|
|
}
|
|
|
|
// EmptyHash returns an empty string to signal resource deletion.
|
|
// This triggers env var removal when using the env-vars strategy.
|
|
func (h *Hasher) EmptyHash() string {
|
|
return ""
|
|
}
|