Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] why does it not preserve changes when invoke CreateThreeWayMergePatch function with nil annotations #171

Open
chengjingtao opened this issue Mar 29, 2024 · 0 comments

Comments

@chengjingtao
Copy link

When I using CreateThreeWayMergePatch to genernate patch, I found a strange behaviors

// original

{
  "kind": "Deployment",
  "apiVersion": "apps/v1",
  "metadata": {
    "name": "test",
    "namespace": "ns",
    "annotations": null
  }
}

// modified // same as original
{
  "kind": "Deployment",
  "apiVersion": "apps/v1",
  "metadata": {
    "name": "test",
    "namespace": "ns",
    "annotations": null
  }
}

// current  // do some change based on original
{
  "kind": "Deployment",
  "apiVersion": "apps/v1",
  "metadata": {
    "name": "test",
    "namespace": "ns",
    "annotations": {
         "a": "a1"
     }
  }
}

after invoke CreateThreeWayMergePatch, it will generate a patch like that {"metadata":{"annotations":null}}, just not preserve the change on annotations.

My Question is: "why does it not preserve annotations changes? is this expected?"
This seems to easily lead to the following conflicts

  • controller 1: reconcile resources as expected (same as original)
  • controller 2: add some annotations
  • controller 1: reconcile resources as expected (same as original) : clean all annotations.

the code is here

package main

import (
	"encoding/json"
	"k8s.io/api/apps/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/util/strategicpatch"
	"log"
)

func main() {
	patch := createPatch(nil)
	log.Printf("when expected annotations is nil:   patch: %s \n", string(patch))

	patch = createPatch(map[string]string{})
	log.Printf("when expected annotations is empty: patch: %s \n", string(patch))
}

func createPatch(annotations map[string]string) []byte {
	expected := &unstructured.Unstructured{
		Object: map[string]interface{}{
			"kind":       "Deployment",
			"apiVersion": "apps/v1",
			"metadata": map[string]interface{}{
				"name":        "test",
				"namespace":   "ns",
				"annotations": annotations,
			},
		},
	}

	versionedObject := &v1.Deployment{}
	bts, _ := json.Marshal(expected)
	_ = json.Unmarshal(bts, versionedObject)

	existing := &unstructured.Unstructured{
		Object: map[string]interface{}{
			"kind":       "Deployment",
			"apiVersion": "apps/v1",
			"metadata": map[string]interface{}{
				"name":      "test",
				"namespace": "ns",
				"annotations": map[string]string{
					"a": "a1",
					"b": "b1",
				},
			},
		},
	}

	patchMeta, err := strategicpatch.NewPatchMetaFromStruct(versionedObject)
	if err != nil {
		log.Fatal("new patch meta:" + err.Error())
	}

	expectedJSON, _ := json.Marshal(expected)
	existingJSON, _ := json.Marshal(existing)
	patch, err := strategicpatch.CreateThreeWayMergePatch(expectedJSON, expectedJSON, existingJSON, patchMeta, true)

	if err != nil {
		log.Fatal(err)
	}

	return patch
}

result is :

when expected annotations is nil:      patch: {"metadata":{"annotations":null}} 
when expected annotations is empty:    patch: {} 

@chengjingtao chengjingtao changed the title why does it not preserve changes when invoke CreateThreeWayMergePatch function with nil annotations [Question] why does it not preserve changes when invoke CreateThreeWayMergePatch function with nil annotations Mar 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant