mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
e8381db778
* 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>
122 lines
2.9 KiB
Go
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])
|
|
}
|