-
Notifications
You must be signed in to change notification settings - Fork 80
/
checksum.go
90 lines (68 loc) · 1.92 KB
/
checksum.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright 2022 Clastix Labs
// SPDX-License-Identifier: Apache-2.0
package utilities
import (
"crypto/md5"
"encoding/hex"
"sort"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/clastix/kamaji/internal/constants"
)
// GetObjectChecksum returns the annotation checksum in case this is set,
// otherwise, an empty string.
func GetObjectChecksum(obj client.Object) string {
v, ok := obj.GetAnnotations()[constants.Checksum]
if !ok {
return ""
}
return v
}
// SetObjectChecksum calculates the checksum for the given map and store it in the object annotations.
func SetObjectChecksum(obj client.Object, data any) {
annotations := obj.GetAnnotations()
if annotations == nil {
annotations = make(map[string]string)
}
annotations[constants.Checksum] = CalculateMapChecksum(data)
obj.SetAnnotations(annotations)
}
// CalculateMapChecksum orders the map according to its key, and calculating the overall md5 of the values.
// It's expected to work with ConfigMap (map[string]string) and Secrets (map[string][]byte).
func CalculateMapChecksum(data any) string {
switch t := data.(type) {
case map[string]string:
return calculateMapStringString(t)
case map[string][]byte:
return calculateMapStringByte(t)
default:
return ""
}
}
func calculateMapStringString(data map[string]string) string {
keys := make([]string, 0, len(data))
for key := range data {
keys = append(keys, key)
}
sort.Strings(keys)
var checksum string
for _, key := range keys {
checksum += data[key]
}
return md5Checksum([]byte(checksum))
}
func calculateMapStringByte(data map[string][]byte) string {
keys := make([]string, 0, len(data))
for key := range data {
keys = append(keys, key)
}
sort.Strings(keys)
var checksum string
for _, key := range keys {
checksum += string(data[key])
}
return md5Checksum([]byte(checksum))
}
func md5Checksum(value []byte) string {
hash := md5.Sum(value)
return hex.EncodeToString(hash[:])
}