forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
uniquenamegenerator.go
86 lines (70 loc) · 2.3 KB
/
uniquenamegenerator.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
package app
import (
"fmt"
"regexp"
"strconv"
"strings"
"github.com/golang/glog"
kvalidation "k8s.io/apimachinery/pkg/util/validation"
"github.com/openshift/origin/pkg/util/namer"
)
// the opposite of kvalidation.DNS1123LabelFmt
var invalidNameCharactersRegexp = regexp.MustCompile("[^-a-z0-9]")
// A UniqueNameGenerator is able to generate unique names from a given original
// name.
type UniqueNameGenerator interface {
Generate(NameSuggester) (string, error)
}
// NewUniqueNameGenerator creates a new UniqueNameGenerator with the given
// original name.
func NewUniqueNameGenerator(name string) UniqueNameGenerator {
return &uniqueNameGenerator{name, map[string]int{}}
}
type uniqueNameGenerator struct {
originalName string
names map[string]int
}
// Generate returns a name that is unique within the set of names of this unique
// name generator. If the generator's original name is empty, a new name will be
// suggested.
func (ung *uniqueNameGenerator) Generate(suggester NameSuggester) (string, error) {
name := ung.originalName
if len(name) == 0 {
var ok bool
name, ok = suggester.SuggestName()
if !ok {
return "", ErrNameRequired
}
}
return ung.ensureValidName(name)
}
// ensureValidName returns a new name based on the name given that is unique in
// the set of names of this unique name generator.
func (ung *uniqueNameGenerator) ensureValidName(name string) (string, error) {
names := ung.names
// Ensure that name meets length requirements
if len(name) < 2 {
return "", fmt.Errorf("invalid name: %s", name)
}
if !IsParameterizableValue(name) {
// Make all names lowercase
name = strings.ToLower(name)
// Remove everything except [-0-9a-z]
name = invalidNameCharactersRegexp.ReplaceAllString(name, "")
// Remove leading hyphen(s) that may be introduced by the previous step
name = strings.TrimLeft(name, "-")
if len(name) > kvalidation.DNS1123SubdomainMaxLength {
glog.V(4).Infof("Trimming %s to maximum allowable length (%d)\n", name, kvalidation.DNS1123SubdomainMaxLength)
name = name[:kvalidation.DNS1123SubdomainMaxLength]
}
}
count, existing := names[name]
if !existing {
names[name] = 0
return name, nil
}
count++
names[name] = count
newName := namer.GetName(name, strconv.Itoa(count), kvalidation.DNS1123SubdomainMaxLength)
return newName, nil
}