k3s/vendor/sigs.k8s.io/kustomize/kyaml/yaml/datamap.go
Brad Davidson e8381db778 Update Kubernetes to v1.21.0
* Update Kubernetes to v1.21.0
* Update to golang v1.16.2
* Update dependent modules to track with upstream
* Switch to upstream flannel
* Track changes to upstream cloud-controller-manager and FeatureGates

Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
2021-04-14 14:51:42 -07:00

122 lines
2.9 KiB
Go

// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package yaml
import (
"encoding/base64"
"sort"
"strings"
"unicode/utf8"
)
// SortedMapKeys returns a sorted slice of keys to the given map.
// Writing this function never gets old.
func SortedMapKeys(m map[string]string) []string {
keys := make([]string, len(m))
i := 0
for k := range m {
keys[i] = k
i++
}
sort.Strings(keys)
return keys
}
func (rn *RNode) LoadMapIntoConfigMapData(m map[string]string) error {
for _, k := range SortedMapKeys(m) {
fldName, vrN := makeConfigMapValueRNode(m[k])
if _, err := rn.Pipe(
LookupCreate(MappingNode, fldName),
SetField(k, vrN)); err != nil {
return err
}
}
return nil
}
func (rn *RNode) LoadMapIntoConfigMapBinaryData(m map[string]string) error {
for _, k := range SortedMapKeys(m) {
_, vrN := makeConfigMapValueRNode(m[k])
// we know this is binary data
fldName := BinaryDataField
if _, err := rn.Pipe(
LookupCreate(MappingNode, fldName),
SetField(k, vrN)); err != nil {
return err
}
}
return nil
}
func makeConfigMapValueRNode(s string) (field string, rN *RNode) {
yN := &Node{Kind: ScalarNode}
yN.Tag = NodeTagString
if utf8.ValidString(s) {
field = DataField
yN.Value = s
} else {
field = BinaryDataField
yN.Value = encodeBase64(s)
}
if strings.Contains(yN.Value, "\n") {
yN.Style = LiteralStyle
}
return field, NewRNode(yN)
}
func (rn *RNode) LoadMapIntoSecretData(m map[string]string) error {
mapNode, err := rn.Pipe(LookupCreate(MappingNode, DataField))
if err != nil {
return err
}
for _, k := range SortedMapKeys(m) {
vrN := makeSecretValueRNode(m[k])
if _, err := mapNode.Pipe(SetField(k, vrN)); err != nil {
return err
}
}
return nil
}
// In a secret, all data is base64 encoded, regardless of its conformance
// or lack thereof to UTF-8.
func makeSecretValueRNode(s string) *RNode {
yN := &Node{Kind: ScalarNode}
// Purposely don't use YAML tags to identify the data as being plain text or
// binary. It kubernetes Secrets the values in the `data` map are expected
// to be base64 encoded, and in ConfigMaps that same can be said for the
// values in the `binaryData` field.
yN.Tag = NodeTagString
yN.Value = encodeBase64(s)
if strings.Contains(yN.Value, "\n") {
yN.Style = LiteralStyle
}
return NewRNode(yN)
}
// encodeBase64 encodes s as base64 that is broken up into multiple lines
// as appropriate for the resulting length.
func encodeBase64(s string) string {
const lineLen = 70
encLen := base64.StdEncoding.EncodedLen(len(s))
lines := encLen/lineLen + 1
buf := make([]byte, encLen*2+lines)
in := buf[0:encLen]
out := buf[encLen:]
base64.StdEncoding.Encode(in, []byte(s))
k := 0
for i := 0; i < len(in); i += lineLen {
j := i + lineLen
if j > len(in) {
j = len(in)
}
k += copy(out[k:], in[i:j])
if lines > 1 {
out[k] = '\n'
k++
}
}
return string(out[:k])
}