package utils import ( "errors" "fmt" "strings" "unicode" "k8s.io/apimachinery/pkg/util/validation" ) var ( // allowedEnvSpecialCharacters a list of valid special characters for kubernetes environment variables. // taken from the k8s.io/apimachinery/pkg/util/validation Line 420 pkg. allowedEnvSpecialCharacters = map[string]bool{ "_": true, "-": true, ".": true, } ) // a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit func ToENVName(labelKey string) string { if IsValidEnvironmentName(labelKey) { return labelKey } // if it's not a valid environment name // we need to change it to conform to be an env name return toENVName(labelKey) } func ToK8sName(labelKey string) string { var k8sname strings.Builder labelKey = strings.Trim(labelKey, " ") for i := 0; i < len(labelKey); i++ { // if valid short circuit and continue if IsValidLabelValue(string(labelKey[i])) { k8sname.WriteString(string(labelKey[i])) continue } // if previous value was invalid and trimmed then do not set to _, instead convert to empty "" if i == 0 && !IsValidLabelValue(string(labelKey[i])) || i > 0 && !IsValidLabelValue(string(labelKey[i-1])) || i == len(labelKey)-1 && !IsValidLabel(string(labelKey[i])) { k8sname.WriteString("") continue } k8sname.WriteString("-") } return k8sname.String() } func ValuesValidation(values []string) error { var err error for _, val := range values { if validation.IsValidLabelValue(val) != nil { err = errors.Join(err, fmt.Errorf("invalid k8s label value: %s", val)) } } return err } func IsValidLabelValue(label string) bool { return validation.IsValidLabelValue(label) == nil } func IsValidLabel(label string) bool { return validation.IsDNS1123Label(label) == nil } // IsValidEnvironmentName verifies that the specified env name is a valid kubernetes environment name. func IsValidEnvironmentName(name string) bool { return len(validation.IsEnvVarName(name)) == 0 } // toENVName converts a string value to a valid environment variable name. // a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', // and must not start with a digit func toENVName(val string) string { var result strings.Builder // ensure that all white spaces are removed and trimmed. val = strings.TrimSpace(val) for index, valRune := range val { switch { case unicode.IsDigit(valRune) && index == 0: // if the first character in the env name is a digit // we need to ignore it continue case unicode.IsSpace(valRune): // if the character is a space and is not the first character // we convert it to an _ result.WriteString("_") case !unicode.IsLetter(valRune) && !unicode.IsDigit(valRune) && isNotAnAllowedSpecialChar(valRune): // if the character is not an alphabetic character // or a digit or an allowed special character. // we need to ignore it. continue default: result.WriteString(string(valRune)) } } resultString := result.String() if !IsValidEnvironmentName(resultString) && len(resultString) > 2 { resultString = toENVName(resultString) } return resultString } // isNotAnAllowedSpecialChar checks the allowedEnvSpecialCharacters to see if the specified character exists. func isNotAnAllowedSpecialChar(valRune rune) bool { _, exists := allowedEnvSpecialCharacters[string(valRune)] return !exists }