diff --git a/kyaml/kio/byteio_reader.go b/kyaml/kio/byteio_reader.go index 65a46d822..18281a536 100644 --- a/kyaml/kio/byteio_reader.go +++ b/kyaml/kio/byteio_reader.go @@ -67,12 +67,12 @@ func (rw *ByteReadWriter) Read() ([]*yaml.RNode, error) { WrapBareSeqNode: rw.WrapBareSeqNode, } val, err := b.Read() + rw.Results = b.Results + if rw.FunctionConfig == nil { rw.FunctionConfig = b.FunctionConfig } - rw.Results = b.Results - - if !rw.NoWrap { + if !rw.NoWrap && rw.WrappingKind == "" { rw.WrappingAPIVersion = b.WrappingAPIVersion rw.WrappingKind = b.WrappingKind } @@ -80,15 +80,18 @@ func (rw *ByteReadWriter) Read() ([]*yaml.RNode, error) { } func (rw *ByteReadWriter) Write(nodes []*yaml.RNode) error { - return ByteWriter{ + w := ByteWriter{ Writer: rw.Writer, KeepReaderAnnotations: rw.KeepReaderAnnotations, Style: rw.Style, FunctionConfig: rw.FunctionConfig, Results: rw.Results, - WrappingAPIVersion: rw.WrappingAPIVersion, - WrappingKind: rw.WrappingKind, - }.Write(nodes) + } + if !rw.NoWrap { + w.WrappingAPIVersion = rw.WrappingAPIVersion + w.WrappingKind = rw.WrappingKind + } + return w.Write(nodes) } // ParseAll reads all of the inputs into resources diff --git a/kyaml/kio/byteio_readwriter_test.go b/kyaml/kio/byteio_readwriter_test.go index ce0c4e5c6..3f8d22c21 100644 --- a/kyaml/kio/byteio_readwriter_test.go +++ b/kyaml/kio/byteio_readwriter_test.go @@ -747,3 +747,122 @@ func TestByteReadWriter_WrapBareSeqNode(t *testing.T) { }) } } + +func TestByteReadWriter_ResourceListWrapping(t *testing.T) { + singleDeployment := `kind: Deployment +apiVersion: v1 +metadata: + name: tester + namespace: default +spec: + replicas: 0` + resourceList := `apiVersion: config.kubernetes.io/v1 +kind: ResourceList +items: +- kind: Deployment + apiVersion: v1 + metadata: + name: tester + namespace: default + spec: + replicas: 0` + resourceListWithError := `apiVersion: config.kubernetes.io/v1 +kind: ResourceList +items: +- kind: Deployment + apiVersion: v1 + metadata: + name: tester + namespace: default + spec: + replicas: 0 +results: +- message: some error + severity: error` + resourceListDifferentWrapper := strings.NewReplacer( + "kind: ResourceList", "kind: SomethingElse", + "apiVersion: config.kubernetes.io/v1", "apiVersion: fakeVersion", + ).Replace(resourceList) + + testCases := []struct { + desc string + noWrap bool + wrapKind string + wrapAPIVersion string + input string + want string + }{ + { + desc: "resource list", + input: resourceList, + want: resourceList, + }, + { + desc: "individual resources", + input: singleDeployment, + want: singleDeployment, + }, + { + desc: "no nested wrapping", + wrapKind: kio.ResourceListKind, + wrapAPIVersion: kio.ResourceListAPIVersion, + input: resourceList, + want: resourceList, + }, + { + desc: "unwrap resource list", + noWrap: true, + input: resourceList, + want: singleDeployment, + }, + { + desc: "wrap individual resources", + wrapKind: kio.ResourceListKind, + wrapAPIVersion: kio.ResourceListAPIVersion, + input: singleDeployment, + want: resourceList, + }, + { + desc: "NoWrap has precedence", + noWrap: true, + wrapKind: kio.ResourceListKind, + wrapAPIVersion: kio.ResourceListAPIVersion, + input: singleDeployment, + want: singleDeployment, + }, + { + desc: "honor specified wrapping kind", + wrapKind: "SomethingElse", + wrapAPIVersion: "fakeVersion", + input: resourceList, + want: resourceListDifferentWrapper, + }, + { + desc: "passthrough results", + input: resourceListWithError, + want: resourceListWithError, + }, + } + + for i := range testCases { + tc := testCases[i] + t.Run(tc.desc, func(t *testing.T) { + var got bytes.Buffer + rw := kio.ByteReadWriter{ + Reader: strings.NewReader(tc.input), + Writer: &got, + NoWrap: tc.noWrap, + WrappingAPIVersion: tc.wrapAPIVersion, + WrappingKind: tc.wrapKind, + } + + rnodes, err := rw.Read() + assert.NoError(t, err) + + err = rw.Write(rnodes) + assert.NoError(t, err) + + assert.Equal(t, tc.want, strings.TrimSpace(got.String())) + }) + } +}