github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/kube/naming/names.go (about) 1 package naming 2 3 import ( 4 "bytes" 5 "fmt" 6 "math" 7 "strings" 8 "unicode" 9 10 "github.com/google/uuid" 11 ) 12 13 // ToValidImageName converts the given string into a valid docker image name 14 func ToValidImageName(name string) string { 15 return strings.ToLower(name) 16 } 17 18 // ToValidImageVersion converts the given string into a valid docker image version string 19 func ToValidImageVersion(version string) string { 20 return strings.Replace(version, ":", "", -1) 21 } 22 23 // ToValidName converts the given string into a valid Kubernetes resource name 24 func ToValidName(name string) string { 25 return toValidName(name, false, math.MaxInt32) 26 } 27 28 // ToValidNameWithDots converts the given string into a valid Kubernetes resource name 29 func ToValidNameWithDots(name string) string { 30 return toValidName(name, true, math.MaxInt32) 31 } 32 33 // ToValidNameTruncated converts the given string into a valid Kubernetes resource name, 34 // truncating the result if it is more than maxLength characters. 35 func ToValidNameTruncated(name string, maxLength int) string { 36 return toValidName(name, false, maxLength) 37 } 38 39 // ToValidNameWithDotsTruncated converts the given string into a valid Kubernetes resource name, 40 // truncating the result if it is more than maxLength characters. 41 func ToValidNameWithDotsTruncated(name string, maxLength int) string { 42 return toValidName(name, true, maxLength) 43 } 44 45 // ToValidGCPServiceAccount converts the given string into a valid GCP service account name, 46 // truncating the result if it is more than 30 characters. 47 func ToValidGCPServiceAccount(name string) string { 48 if len(name) < 6 { 49 uuid4 := uuid.New() 50 name = fmt.Sprintf("%s-jx-%s", name, uuid4.String()[:1]) 51 } 52 return toValidName(name, false, 30) 53 } 54 55 func toValidName(name string, allowDots bool, maxLength int) string { 56 if name == "" { 57 return "" 58 } 59 var buffer bytes.Buffer 60 first := true 61 lastCharDash := false 62 hasLetter := false 63 for _, ch := range name { 64 ch = unicode.ToLower(ch) 65 if ch >= 'a' && ch <= 'z' { 66 hasLetter = true 67 break 68 } 69 } 70 if !hasLetter { 71 name = fmt.Sprintf("x%s", name) 72 } 73 for _, ch := range name { 74 ch = unicode.ToLower(ch) 75 if buffer.Len()+1 > maxLength { 76 break 77 } 78 if first { 79 // strip non letters at start 80 if ch >= 'a' && ch <= 'z' { 81 buffer.WriteRune(ch) 82 first = false 83 } 84 } else { 85 if !allowDots && ch == '.' { 86 ch = '-' 87 } 88 if !(ch >= 'a' && ch <= 'z') && !(ch >= '0' && ch <= '9') && ch != '-' && ch != '.' { 89 ch = '-' 90 } 91 92 if ch != '-' || !lastCharDash { 93 buffer.WriteRune(ch) 94 } 95 lastCharDash = ch == '-' 96 } 97 } 98 answer := buffer.String() 99 for { 100 if strings.HasSuffix(answer, "-") { 101 answer = strings.TrimSuffix(answer, "-") 102 } else { 103 break 104 } 105 } 106 return answer 107 } 108 109 // ToValidValue validates a label value which can start with numbers 110 func ToValidValue(name string) string { 111 if name == "" { 112 return "" 113 } 114 var buffer bytes.Buffer 115 lastCharDash := false 116 for _, ch := range name { 117 if !(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') && !(ch >= '0' && ch <= '9') && ch != '-' && ch != '.' && ch != '/' { 118 ch = '-' 119 } 120 121 if ch != '-' || !lastCharDash { 122 buffer.WriteRune(ch) 123 } 124 lastCharDash = ch == '-' 125 } 126 answer := buffer.String() 127 for { 128 if strings.HasSuffix(answer, "-") { 129 answer = strings.TrimSuffix(answer, "-") 130 } else { 131 break 132 } 133 } 134 return answer 135 } 136 137 //EmailToK8sID converts the provided email address to a valid Kubernetes resource name, converting the @ to a . 138 func EmailToK8sID(email string) string { 139 return ToValidNameWithDots(strings.Replace(email, "@", ".", -1)) 140 }