Skip to content
Merged
Show file tree
Hide file tree
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
11 changes: 6 additions & 5 deletions pkg/controller/utils.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package controller

import (
"crypto/sha1"
"crypto/sha256"
"encoding/base32"
"reflect"
"strings"
Expand All @@ -10,15 +10,16 @@ import (
)

const (
maxLength int = 63
Base32EncodeStdLowerCase = "abcdefghijklmnopqrstuvwxyz234567"
Base32EncodeStdLowerCase = "abcdefghijklmnopqrstuvwxyz234567"
)

// K8sNameHash takes any number of string arguments and computes a hash out of it, which is then base32-encoded to be a valid k8s resource name.
// K8sNameHash takes any number of string arguments and computes a hash out of it, which is then base32-encoded to be a valid DNS1123Subdomain k8s resource name
// The arguments are joined with '/' before being hashed.
func K8sNameHash(ids ...string) string {
name := strings.Join(ids, "/")
h := sha1.New()
// since we are not worried about length-extension attacks (in fact we are not even using hashing for
// any security purposes), use sha2 for better performance compared to sha3
h := sha256.New()
_, _ = h.Write([]byte(name))
// we need base32 encoding as some base64 (even url safe base64) characters are not supported by k8s
// see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/
Expand Down
50 changes: 50 additions & 0 deletions pkg/controller/utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package controller

import (
"fmt"
"testing"

"k8s.io/apimachinery/pkg/util/validation"
)

func TestK8sNameHash(t *testing.T) {
tt := []struct {
input []string
expHash string
}{
{
[]string{"test1"},
"dnhq5gcrs4mzrzzsa6cujsllg3b5ahhn67fkgmrvtvxr3a2woaka",
},
{
// check that the same string produces the same hash
[]string{"test1"},
"dnhq5gcrs4mzrzzsa6cujsllg3b5ahhn67fkgmrvtvxr3a2woaka",
},
{
[]string{"bla"},
"jxz4h5upzsb3e7u5ileqimnhesm7c6dvzanftg2wnsmitoljm4bq",
},
{
[]string{"some other test", "this is a very, very long string"},
"rjphpfjbmwn6qqydv6xhtmj3kxrlzepn2tpwy4okw2ypoc3nlffq",
},
}

for _, tc := range tt {
t.Run(fmt.Sprint(tc.input), func(t *testing.T) {
res := K8sNameHash(tc.input...)

if res != tc.expHash {
t.Errorf("exp hash %q, got %q", tc.expHash, res)
}

// ensure the result is a valid DNS1123Subdomain
if errs := validation.IsDNS1123Subdomain(res); errs != nil {
t.Errorf("value %q is invalid: %v", res, errs)
}

})
}

}