Fix null YAML values being replaced by "null"

Related issues:

* https://github.com/kubernetes-sigs/kustomize/issues/5031
* https://github.com/kubernetes-sigs/kustomize/issues/5171

After noting this behaviour was not present in
d89b448c74 a `git bisect` pointed to the
change 1b7db20504. The issue with that
change is that upon seeing a `null` node it would replace it with a node
whose value was equivalent but without a `!!null` tag. This meant that
one application of a patch would have the desired approach: the result
would be `null` in the output, but on a second application of a similar
patch the field would be rendered as `"null"`.

To avoid this, define a new attribute on `RNode`s that is checked before
clearing any node we should keep. The added
`TestApplySmPatch_Idempotency` test verifies this behaviour.

See also https://github.com/kubernetes-sigs/kustomize/pull/5365 for an
alternative approach
This commit is contained in:
Matthew Hughes
2024-01-28 14:06:03 +00:00
parent 11704312be
commit 8aafbacd17
5 changed files with 80 additions and 4 deletions

View File

@@ -9,6 +9,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/provider"
. "sigs.k8s.io/kustomize/api/resource"
@@ -281,6 +282,43 @@ spec:
`, string(bytes))
}
// regression test for https://github.com/kubernetes-sigs/kustomize/issues/5031
func TestApplySmPatch_Idempotency(t *testing.T) {
// an arbitrary number of times to apply the patch
patchApplyCount := 4
resourceYaml := `apiVersion: v1
kind: Deployment
metadata:
creationTimestamp: null
labels: null
name: my-deployment
`
resource, err := factory.FromBytes([]byte(resourceYaml))
require.NoError(t, err)
noOpPatch, err := factory.FromBytes([]byte(`
apiVersion: v1
kind: Deployment
metadata:
name: my-deployment
`))
require.NoError(t, err)
for i := 0; i < patchApplyCount; i++ {
require.NoError(t, resource.ApplySmPatch(noOpPatch))
bytes, err := resource.AsYAML()
require.NoError(t, err)
require.Equal(
t,
resourceYaml,
string(bytes),
"resource should be unchanged after re-application of patch",
)
}
}
func TestApplySmPatchShouldOutputListItemsInCorrectOrder(t *testing.T) {
cases := []struct {
name string