mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Generate shorter UIDs (#79843)
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/bwmarrin/snowflake"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -42,24 +43,39 @@ func IsShortUIDTooLong(uid string) bool {
|
|||||||
return len(uid) > MaxUIDLength
|
return len(uid) > MaxUIDLength
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var node *snowflake.Node
|
||||||
|
|
||||||
// GenerateShortUID will generate a UUID that can also be a k8s name
|
// GenerateShortUID will generate a UUID that can also be a k8s name
|
||||||
// it is guaranteed to have a character as the first letter
|
// it is guaranteed to have a character as the first letter
|
||||||
// This UID will be a valid k8s name
|
// This UID will be a valid k8s name
|
||||||
func GenerateShortUID() string {
|
func GenerateShortUID() string {
|
||||||
mtx.Lock()
|
mtx.Lock()
|
||||||
defer mtx.Unlock()
|
defer mtx.Unlock()
|
||||||
uid, err := uuid.NewRandom()
|
|
||||||
if err != nil {
|
if node == nil {
|
||||||
// This should never happen... but this seems better than a panic
|
// ignoring the error happens when input outside 0-1023
|
||||||
for i := range uid {
|
node, _ = snowflake.NewNode(rand.Int63n(1024))
|
||||||
uid[i] = byte(uidrand.Intn(255))
|
}
|
||||||
|
|
||||||
|
// Use UUIDs if snowflake failed (should be never)
|
||||||
|
if node == nil {
|
||||||
|
uid, err := uuid.NewRandom()
|
||||||
|
if err != nil {
|
||||||
|
// This should never happen... but this seems better than a panic
|
||||||
|
for i := range uid {
|
||||||
|
uid[i] = byte(uidrand.Intn(255))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
uuid := uid.String()
|
||||||
|
if rune(uuid[0]) < rune('a') {
|
||||||
|
uuid = string(hexLetters[uidrand.Intn(len(hexLetters))]) + uuid[1:]
|
||||||
|
}
|
||||||
|
return uuid
|
||||||
}
|
}
|
||||||
uuid := uid.String()
|
|
||||||
if rune(uuid[0]) < rune('a') {
|
return string(hexLetters[uidrand.Intn(len(hexLetters))]) + // start with a letter
|
||||||
return string(hexLetters[uidrand.Intn(len(hexLetters))]) + uuid[1:]
|
node.Generate().Base36() +
|
||||||
}
|
string(hexLetters[uidrand.Intn(len(hexLetters))]) // a bit more entropy
|
||||||
return uuid
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateUID checks the format and length of the string and returns error if it does not pass the condition
|
// ValidateUID checks the format and length of the string and returns error if it does not pass the condition
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"cuelang.org/go/pkg/strings"
|
"cuelang.org/go/pkg/strings"
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/teris-io/shortid"
|
||||||
"k8s.io/apimachinery/pkg/util/validation"
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -48,14 +49,27 @@ func TestRandomUIDs(t *testing.T) {
|
|||||||
t.Fatalf("created invalid name: %v", validation)
|
t.Fatalf("created invalid name: %v", validation)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := uuid.Parse(v)
|
// fmt.Println(v)
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
//fmt.Println(v)
|
|
||||||
}
|
}
|
||||||
// t.FailNow()
|
// t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCaseInsensitiveCollisionsUIDs(t *testing.T) {
|
||||||
|
history := make(map[string]bool, 0)
|
||||||
|
for i := 0; i < 100000; i++ {
|
||||||
|
v := GenerateShortUID()
|
||||||
|
if false {
|
||||||
|
v, _ = shortid.Generate() // collides in less then 500 iterations
|
||||||
|
}
|
||||||
|
|
||||||
|
lower := strings.ToLower(v)
|
||||||
|
_, exists := history[lower]
|
||||||
|
require.False(t, exists, fmt.Sprintf("already found: %s (index:%d)", v, i))
|
||||||
|
|
||||||
|
history[lower] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestIsShortUIDTooLong(t *testing.T) {
|
func TestIsShortUIDTooLong(t *testing.T) {
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
Reference in New Issue
Block a user