From 6de6cd0a658509b397120ffdf2b412d9fdd2850d Mon Sep 17 00:00:00 2001 From: Alexander Zielenski Date: Sun, 23 Apr 2023 09:53:00 -0700 Subject: [PATCH] add integration test for nested $patch in SMP --- .../pkg/util/strategicpatch/patch_test.go | 2 - test/integration/apiserver/patch_test.go | 77 ++++++++++++++++++- 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch_test.go b/staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch_test.go index 1c6c26b6d2a..25424128ed7 100644 --- a/staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch_test.go @@ -1242,8 +1242,6 @@ $setElementOrder/mergingList: - name: doesntexist mergingList: - name: hello -- $patch: delete - name: doesntexist `), TwoWayResult: []byte(` name: hi diff --git a/test/integration/apiserver/patch_test.go b/test/integration/apiserver/patch_test.go index 7a1c09d8285..db4077e66aa 100644 --- a/test/integration/apiserver/patch_test.go +++ b/test/integration/apiserver/patch_test.go @@ -24,8 +24,10 @@ import ( "testing" "github.com/google/uuid" + "github.com/stretchr/testify/require" - v1 "k8s.io/api/core/v1" + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -56,7 +58,7 @@ func TestPatchConflicts(t *testing.T) { UID: uid, }) } - secret := &v1.Secret{ + secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "test", OwnerReferences: ownerRefs, @@ -136,3 +138,74 @@ func findOwnerRefByUID(ownerRefs []metav1.OwnerReference, uid types.UID) bool { } return false } + +// Shows that a strategic merge patch with a nested patch which is merged +// with an empty slice is handled property +// https://github.com/kubernetes/kubernetes/issues/117470 +func TestNestedStrategicMergePatchWithEmpty(t *testing.T) { + clientSet, _, tearDownFn := setup(t) + defer tearDownFn() + + url := "https://foo.com" + se := admissionregistrationv1.SideEffectClassNone + + _, err := clientSet. + AdmissionregistrationV1(). + ValidatingWebhookConfigurations(). + Create( + context.TODO(), + &admissionregistrationv1.ValidatingWebhookConfiguration{ + ObjectMeta: metav1.ObjectMeta{ + Name: "base-validation", + }, + Webhooks: []admissionregistrationv1.ValidatingWebhook{ + { + AdmissionReviewVersions: []string{"v1"}, + ClientConfig: admissionregistrationv1.WebhookClientConfig{URL: &url}, + Name: "foo.bar.com", + SideEffects: &se, + }, + }, + }, + metav1.CreateOptions{ + FieldManager: "kubectl-client-side-apply", + FieldValidation: metav1.FieldValidationStrict, + }, + ) + require.NoError(t, err) + + _, err = clientSet. + AdmissionregistrationV1(). + ValidatingWebhookConfigurations(). + Patch( + context.TODO(), + "base-validation", + types.StrategicMergePatchType, + []byte(` + { + "webhooks": null + } +`), + metav1.PatchOptions{ + FieldManager: "kubectl-edit", + FieldValidation: metav1.FieldValidationStrict, + }, + ) + require.NoError(t, err) + + // Try to apply a patch to the webhook + _, err = clientSet. + AdmissionregistrationV1(). + ValidatingWebhookConfigurations(). + Patch( + context.TODO(), + "base-validation", + types.StrategicMergePatchType, + []byte(`{"$setElementOrder/webhooks":[{"name":"new.foo.com"}],"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"admissionregistration.k8s.io/v1\",\"kind\":\"ValidatingWebhookConfiguration\",\"metadata\":{\"annotations\":{},\"name\":\"base-validation\"},\"webhooks\":[{\"admissionReviewVersions\":[\"v1\"],\"clientConfig\":{\"url\":\"https://foo.com\"},\"name\":\"new.foo.com\",\"sideEffects\":\"None\"}]}\n"}},"webhooks":[{"admissionReviewVersions":["v1"],"clientConfig":{"url":"https://foo.com"},"name":"new.foo.com","sideEffects":"None"},{"$patch":"delete","name":"foo.bar.com"}]}`), + metav1.PatchOptions{ + FieldManager: "kubectl-client-side-apply", + FieldValidation: metav1.FieldValidationStrict, + }, + ) + require.NoError(t, err) +}