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  }