mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-11 17:12:51 +00:00
binary data nope
This commit is contained in:
@@ -23,6 +23,7 @@ const (
|
||||
KindField = "kind"
|
||||
MetadataField = "metadata"
|
||||
DataField = "data"
|
||||
BinaryDataField = "binaryData"
|
||||
NameField = "name"
|
||||
NamespaceField = "namespace"
|
||||
LabelsField = "labels"
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
package yaml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
)
|
||||
@@ -44,46 +40,6 @@ func ClearEmptyAnnotations(rn *RNode) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// k8sDataSetter place key value pairs in either a 'data' or 'binaryData' field.
|
||||
// Useful for creating ConfigMaps and Secrets.
|
||||
type k8sDataSetter struct {
|
||||
Key string `yaml:"key,omitempty"`
|
||||
Value string `yaml:"value,omitempty"`
|
||||
ProtectExisting bool `yaml:"protectExisting,omitempty"`
|
||||
}
|
||||
|
||||
func (s k8sDataSetter) Filter(rn *RNode) (*RNode, error) {
|
||||
if !utf8.Valid([]byte(s.Value)) {
|
||||
// Core k8s ConfigMaps store k,v pairs with 'v' passing the above utf8
|
||||
// test in a mapping field called "data" as a string. Pairs with a 'v'
|
||||
// failing this test go into a field called binaryData as a []byte.
|
||||
// TODO: support this distinction in kyaml with NodeTagBytes?
|
||||
return nil, errors.Errorf(
|
||||
"key '%s' appears to have non-utf8 data; "+
|
||||
"binaryData field not yet supported", s.Key)
|
||||
}
|
||||
keyNode, err := rn.Pipe(Lookup(DataField, s.Key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if keyNode != nil && s.ProtectExisting {
|
||||
return nil, fmt.Errorf(
|
||||
"protecting existing %s='%s' against attempt to add new value '%s'",
|
||||
s.Key, strings.TrimSpace(keyNode.MustString()), s.Value)
|
||||
}
|
||||
v := NewScalarRNode(s.Value)
|
||||
v.YNode().Tag = NodeTagString
|
||||
// TODO: use schema to determine node style and tag.
|
||||
// FormatNonStringStyle(v.YNode(), *k8sSch)
|
||||
_, err = rn.Pipe(
|
||||
LookupCreate(yaml.MappingNode, DataField), SetField(s.Key, v))
|
||||
return rn, err
|
||||
}
|
||||
|
||||
func SetK8sData(key, value string) k8sDataSetter {
|
||||
return k8sDataSetter{Key: key, Value: value, ProtectExisting: true}
|
||||
}
|
||||
|
||||
// k8sMetaSetter sets a name at metadata.{key}.
|
||||
// Creates metadata if does not exist.
|
||||
type k8sMetaSetter struct {
|
||||
@@ -92,11 +48,9 @@ type k8sMetaSetter struct {
|
||||
}
|
||||
|
||||
func (s k8sMetaSetter) Filter(rn *RNode) (*RNode, error) {
|
||||
v := NewScalarRNode(s.Value)
|
||||
v.YNode().Tag = NodeTagString
|
||||
_, err := rn.Pipe(
|
||||
PathGetter{Path: []string{MetadataField}, Create: yaml.MappingNode},
|
||||
FieldSetter{Name: s.Key, Value: v})
|
||||
FieldSetter{Name: s.Key, Value: NewStringRNode(s.Value)})
|
||||
return rn, err
|
||||
}
|
||||
|
||||
@@ -117,20 +71,13 @@ type AnnotationSetter struct {
|
||||
}
|
||||
|
||||
func (s AnnotationSetter) Filter(rn *RNode) (*RNode, error) {
|
||||
v := NewStringRNode(s.Value)
|
||||
// some tools get confused about the type if annotations are not quoted
|
||||
v := NewScalarRNode(s.Value)
|
||||
v.YNode().Tag = NodeTagString
|
||||
v.YNode().Style = yaml.SingleQuotedStyle
|
||||
|
||||
if err := ClearEmptyAnnotations(rn); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rn.Pipe(
|
||||
PathGetter{
|
||||
Path: []string{MetadataField, AnnotationsField},
|
||||
Create: yaml.MappingNode},
|
||||
FieldSetter{Name: s.Key, Value: v})
|
||||
return addMetadataNode(rn, AnnotationsField, s.Key, v)
|
||||
}
|
||||
|
||||
func SetAnnotation(key, value string) AnnotationSetter {
|
||||
@@ -172,14 +119,17 @@ type LabelSetter struct {
|
||||
}
|
||||
|
||||
func (s LabelSetter) Filter(rn *RNode) (*RNode, error) {
|
||||
v := NewStringRNode(s.Value)
|
||||
// some tools get confused about the type if labels are not quoted
|
||||
v := NewScalarRNode(s.Value)
|
||||
v.YNode().Tag = NodeTagString
|
||||
v.YNode().Style = yaml.SingleQuotedStyle
|
||||
return addMetadataNode(rn, LabelsField, s.Key, v)
|
||||
}
|
||||
|
||||
func addMetadataNode(rn *RNode, field, key string, v *RNode) (*RNode, error) {
|
||||
return rn.Pipe(
|
||||
PathGetter{
|
||||
Path: []string{MetadataField, LabelsField}, Create: yaml.MappingNode},
|
||||
FieldSetter{Name: s.Key, Value: v})
|
||||
Path: []string{MetadataField, field}, Create: yaml.MappingNode},
|
||||
FieldSetter{Name: key, Value: v})
|
||||
}
|
||||
|
||||
func SetLabel(key, value string) LabelSetter {
|
||||
|
||||
@@ -9,56 +9,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var input = `apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: the-map
|
||||
data:
|
||||
altGreeting: "Good Morning!"
|
||||
enableRisky: "false"
|
||||
`
|
||||
|
||||
func TestSetK8sData(t *testing.T) {
|
||||
rn := MustParse(`apiVersion: v1
|
||||
kind: ConfigMap
|
||||
data:
|
||||
altGreeting: "Good Morning!"
|
||||
`)
|
||||
_, err := rn.Pipe(
|
||||
SetK8sData("foo", "bar"),
|
||||
SetK8sData("fruit", "apple"),
|
||||
SetK8sData("veggie", "celery"))
|
||||
assert.NoError(t, err)
|
||||
output := rn.MustString()
|
||||
|
||||
expected := `apiVersion: v1
|
||||
kind: ConfigMap
|
||||
data:
|
||||
altGreeting: "Good Morning!"
|
||||
foo: bar
|
||||
fruit: apple
|
||||
veggie: celery
|
||||
`
|
||||
if !assert.Equal(t, expected, output) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetK8sDataForbidOverwrite(t *testing.T) {
|
||||
rn := MustParse(`apiVersion: v1
|
||||
kind: ConfigMap
|
||||
data:
|
||||
altGreeting: "Good Morning!"
|
||||
`)
|
||||
_, err := rn.Pipe(
|
||||
SetK8sData("foo", "bar"),
|
||||
SetK8sData("altGreeting", "hey"),
|
||||
SetK8sData("veggie", "celery"))
|
||||
assert.EqualError(
|
||||
t, err, "protecting existing altGreeting='\"Good Morning!\"' "+
|
||||
"against attempt to add new value 'hey'")
|
||||
}
|
||||
|
||||
func TestSetMeta(t *testing.T) {
|
||||
rn := MustParse(`apiVersion: v1
|
||||
kind: ConfigMap
|
||||
@@ -85,7 +35,14 @@ metadata:
|
||||
}
|
||||
|
||||
func TestSetLabel1(t *testing.T) {
|
||||
rn := MustParse(input)
|
||||
rn := MustParse(`apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: the-map
|
||||
data:
|
||||
altGreeting: "Good Morning!"
|
||||
enableRisky: "false"
|
||||
`)
|
||||
_, err := rn.Pipe(SetLabel("foo", "bar"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
@@ -133,7 +90,14 @@ metadata:
|
||||
}
|
||||
|
||||
func TestAnnotation(t *testing.T) {
|
||||
rn := MustParse(input)
|
||||
rn := MustParse(`apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: the-map
|
||||
data:
|
||||
altGreeting: "Good Morning!"
|
||||
enableRisky: "false"
|
||||
`)
|
||||
_, err := rn.Pipe(SetAnnotation("foo", "bar"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
|
||||
@@ -100,6 +100,15 @@ func NewScalarRNode(value string) *RNode {
|
||||
}}
|
||||
}
|
||||
|
||||
// NewStringRNode returns a new Scalar *RNode containing the provided string.
|
||||
// If the string is non-utf8, it will be base64 encoded, and the tag
|
||||
// will indicate binary data.
|
||||
func NewStringRNode(value string) *RNode {
|
||||
n := yaml.Node{Kind: yaml.ScalarNode}
|
||||
n.SetString(value)
|
||||
return NewRNode(&n)
|
||||
}
|
||||
|
||||
// NewListRNode returns a new List *RNode containing the provided scalar values.
|
||||
func NewListRNode(values ...string) *RNode {
|
||||
seq := &RNode{value: &yaml.Node{Kind: yaml.SequenceNode}}
|
||||
|
||||
@@ -90,6 +90,31 @@ func TestRNodeHasNilEntryInList(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRNodeNewStringRNodeText(t *testing.T) {
|
||||
rn := NewStringRNode("cat")
|
||||
if !assert.Equal(t, `cat
|
||||
`,
|
||||
rn.MustString()) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestRNodeNewStringRNodeBinary(t *testing.T) {
|
||||
rn := NewStringRNode(string([]byte{
|
||||
0xff, // non-utf8
|
||||
0x68, // h
|
||||
0x65, // e
|
||||
0x6c, // l
|
||||
0x6c, // l
|
||||
0x6f, // o
|
||||
}))
|
||||
if !assert.Equal(t, `!!binary /2hlbGxv
|
||||
`,
|
||||
rn.MustString()) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func TestRNodeGetValidatedMetadata(t *testing.T) {
|
||||
testConfigMap := map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
|
||||
Reference in New Issue
Block a user