mirror of https://github.com/knative/client.git
89 lines
2.7 KiB
Go
89 lines
2.7 KiB
Go
/*
|
|
Copyright 2020 The Knative Authors
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package util
|
|
|
|
import (
|
|
"crypto/sha1" //nolint:gosec // Weak crypto is fine here, we use it for generating unique keys.
|
|
"fmt"
|
|
"strings"
|
|
"unicode"
|
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
)
|
|
|
|
// EnvToMap is an utility function to translate between the API list form of env vars, and the
|
|
// more convenient map form.
|
|
func EnvToMap(vars []corev1.EnvVar) (map[string]string, error) {
|
|
result := map[string]string{}
|
|
for _, envVar := range vars {
|
|
_, present := result[envVar.Name]
|
|
if present {
|
|
return nil, fmt.Errorf("env var name present more than once: %v", envVar.Name)
|
|
}
|
|
result[envVar.Name] = envVar.Value
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// GenerateVolumeName generates a volume name with respect to a given path string.
|
|
// Current implementation basically sanitizes the path string by replacing "/" with "-"
|
|
// To reduce any chance of duplication, a checksum part generated from the path string is appended to the sanitized string.
|
|
// The volume name must follow the DNS label standard as defined in RFC 1123. This means the name must:
|
|
// - contain at most 63 characters
|
|
// - contain only lowercase alphanumeric characters or '-'
|
|
// - start with an alphanumeric character
|
|
// - end with an alphanumeric character
|
|
func GenerateVolumeName(path string) string {
|
|
builder := &strings.Builder{}
|
|
for idx, r := range path {
|
|
switch {
|
|
case unicode.IsLower(r) || unicode.IsDigit(r) || r == '-':
|
|
builder.WriteRune(r)
|
|
case unicode.IsUpper(r):
|
|
builder.WriteRune(unicode.ToLower(r))
|
|
case r == '/':
|
|
if idx != 0 {
|
|
builder.WriteRune('-')
|
|
}
|
|
default:
|
|
builder.WriteRune('-')
|
|
}
|
|
}
|
|
|
|
vname := appendCheckSum(builder.String(), path)
|
|
|
|
// the name must start with an alphanumeric character
|
|
if !unicode.IsLetter(rune(vname[0])) && !unicode.IsNumber(rune(vname[0])) {
|
|
vname = "k-" + vname
|
|
}
|
|
|
|
// contain at most 63 characters
|
|
if len(vname) > 63 {
|
|
// must end with an alphanumeric character
|
|
vname = fmt.Sprintf("%s-n", vname[0:61])
|
|
}
|
|
|
|
return vname
|
|
}
|
|
|
|
func appendCheckSum(sanitizedString, path string) string {
|
|
//nolint:gosec // Weak crypto is fine here, we use it for generating unique keys.
|
|
checkSum := sha1.Sum([]byte(path))
|
|
shortCheckSum := checkSum[0:4]
|
|
return fmt.Sprintf("%s-%x", sanitizedString, shortCheckSum)
|
|
}
|